1 /*
2  * Copyright (C) 2011 The Android Open Source Project
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *      http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 
17 package com.android.server.pm;
18 
19 import static android.content.pm.PackageManager.COMPONENT_ENABLED_STATE_DEFAULT;
20 import static android.content.pm.PackageManager.COMPONENT_ENABLED_STATE_DISABLED;
21 import static android.content.pm.PackageManager.COMPONENT_ENABLED_STATE_ENABLED;
22 
23 import android.content.pm.IntentFilterVerificationInfo;
24 import android.content.pm.PackageManager;
25 import android.content.pm.PackageUserState;
26 import android.os.storage.VolumeInfo;
27 import android.util.ArraySet;
28 import android.util.SparseArray;
29 
30 import java.io.File;
31 
32 /**
33  * Settings base class for pending and resolved classes.
34  */
35 abstract class PackageSettingBase extends SettingBase {
36     /**
37      * Indicates the state of installation. Used by PackageManager to figure out
38      * incomplete installations. Say a package is being installed (the state is
39      * set to PKG_INSTALL_INCOMPLETE) and remains so till the package
40      * installation is successful or unsuccessful in which case the
41      * PackageManager will no longer maintain state information associated with
42      * the package. If some exception(like device freeze or battery being pulled
43      * out) occurs during installation of a package, the PackageManager needs
44      * this information to clean up the previously failed installation.
45      */
46     static final int PKG_INSTALL_COMPLETE = 1;
47     static final int PKG_INSTALL_INCOMPLETE = 0;
48 
49     final String name;
50     final String realName;
51 
52     /**
53      * Path where this package was found on disk. For monolithic packages
54      * this is path to single base APK file; for cluster packages this is
55      * path to the cluster directory.
56      */
57     File codePath;
58     String codePathString;
59     File resourcePath;
60     String resourcePathString;
61 
62     /**
63      * The path under which native libraries have been unpacked. This path is
64      * always derived at runtime, and is only stored here for cleanup when a
65      * package is uninstalled.
66      */
67     @Deprecated
68     String legacyNativeLibraryPathString;
69 
70     /**
71      * The primary CPU abi for this package. This value is regenerated at every
72      * boot scan.
73      */
74     String primaryCpuAbiString;
75 
76     /**
77      * The secondary CPU abi for this package. This value is regenerated at every
78      * boot scan.
79      */
80     String secondaryCpuAbiString;
81 
82     /**
83      * The install time CPU override, if any. This value is written at install time
84      * and doesn't change during the life of an install. If non-null,
85      * {@code primaryCpuAbiString} will contain the same value.
86      */
87     String cpuAbiOverrideString;
88 
89     long timeStamp;
90     long firstInstallTime;
91     long lastUpdateTime;
92     int versionCode;
93 
94     boolean uidError;
95 
96     PackageSignatures signatures = new PackageSignatures();
97 
98     boolean installPermissionsFixed;
99 
100     PackageKeySetData keySetData = new PackageKeySetData();
101 
102     private static final PackageUserState DEFAULT_USER_STATE = new PackageUserState();
103 
104     // Whether this package is currently stopped, thus can not be
105     // started until explicitly launched by the user.
106     private final SparseArray<PackageUserState> userState = new SparseArray<PackageUserState>();
107 
108     int installStatus = PKG_INSTALL_COMPLETE;
109 
110     /**
111      * Non-persisted value indicating this package has been temporarily frozen,
112      * usually during a critical section of the package update pipeline. The
113      * platform will refuse to launch packages in a frozen state.
114      */
115     boolean frozen = false;
116 
117     PackageSettingBase origPackage;
118 
119     /** Package name of the app that installed this package */
120     String installerPackageName;
121     /** UUID of {@link VolumeInfo} hosting this app */
122     String volumeUuid;
123 
124     IntentFilterVerificationInfo verificationInfo;
125 
PackageSettingBase(String name, String realName, File codePath, File resourcePath, String legacyNativeLibraryPathString, String primaryCpuAbiString, String secondaryCpuAbiString, String cpuAbiOverrideString, int pVersionCode, int pkgFlags, int pkgPrivateFlags)126     PackageSettingBase(String name, String realName, File codePath, File resourcePath,
127             String legacyNativeLibraryPathString, String primaryCpuAbiString,
128             String secondaryCpuAbiString, String cpuAbiOverrideString,
129             int pVersionCode, int pkgFlags, int pkgPrivateFlags) {
130         super(pkgFlags, pkgPrivateFlags);
131         this.name = name;
132         this.realName = realName;
133         init(codePath, resourcePath, legacyNativeLibraryPathString, primaryCpuAbiString,
134                 secondaryCpuAbiString, cpuAbiOverrideString, pVersionCode);
135     }
136 
137     /**
138      * New instance of PackageSetting with one-level-deep cloning.
139      */
140     @SuppressWarnings("unchecked")
PackageSettingBase(PackageSettingBase base)141     PackageSettingBase(PackageSettingBase base) {
142         super(base);
143 
144         name = base.name;
145         realName = base.realName;
146         codePath = base.codePath;
147         codePathString = base.codePathString;
148         resourcePath = base.resourcePath;
149         resourcePathString = base.resourcePathString;
150         legacyNativeLibraryPathString = base.legacyNativeLibraryPathString;
151         primaryCpuAbiString = base.primaryCpuAbiString;
152         secondaryCpuAbiString = base.secondaryCpuAbiString;
153         cpuAbiOverrideString = base.cpuAbiOverrideString;
154         timeStamp = base.timeStamp;
155         firstInstallTime = base.firstInstallTime;
156         lastUpdateTime = base.lastUpdateTime;
157         versionCode = base.versionCode;
158 
159         uidError = base.uidError;
160 
161         signatures = new PackageSignatures(base.signatures);
162 
163         installPermissionsFixed = base.installPermissionsFixed;
164         userState.clear();
165         for (int i=0; i<base.userState.size(); i++) {
166             userState.put(base.userState.keyAt(i),
167                     new PackageUserState(base.userState.valueAt(i)));
168         }
169         installStatus = base.installStatus;
170 
171         origPackage = base.origPackage;
172 
173         installerPackageName = base.installerPackageName;
174         volumeUuid = base.volumeUuid;
175 
176         keySetData = new PackageKeySetData(base.keySetData);
177     }
178 
init(File codePath, File resourcePath, String legacyNativeLibraryPathString, String primaryCpuAbiString, String secondaryCpuAbiString, String cpuAbiOverrideString, int pVersionCode)179     void init(File codePath, File resourcePath, String legacyNativeLibraryPathString,
180               String primaryCpuAbiString, String secondaryCpuAbiString,
181               String cpuAbiOverrideString, int pVersionCode) {
182         this.codePath = codePath;
183         this.codePathString = codePath.toString();
184         this.resourcePath = resourcePath;
185         this.resourcePathString = resourcePath.toString();
186         this.legacyNativeLibraryPathString = legacyNativeLibraryPathString;
187         this.primaryCpuAbiString = primaryCpuAbiString;
188         this.secondaryCpuAbiString = secondaryCpuAbiString;
189         this.cpuAbiOverrideString = cpuAbiOverrideString;
190         this.versionCode = pVersionCode;
191     }
192 
setInstallerPackageName(String packageName)193     public void setInstallerPackageName(String packageName) {
194         installerPackageName = packageName;
195     }
196 
getInstallerPackageName()197     public String getInstallerPackageName() {
198         return installerPackageName;
199     }
200 
setVolumeUuid(String volumeUuid)201     public void setVolumeUuid(String volumeUuid) {
202         this.volumeUuid = volumeUuid;
203     }
204 
getVolumeUuid()205     public String getVolumeUuid() {
206         return volumeUuid;
207     }
208 
setInstallStatus(int newStatus)209     public void setInstallStatus(int newStatus) {
210         installStatus = newStatus;
211     }
212 
getInstallStatus()213     public int getInstallStatus() {
214         return installStatus;
215     }
216 
setTimeStamp(long newStamp)217     public void setTimeStamp(long newStamp) {
218         timeStamp = newStamp;
219     }
220 
221     /**
222      * Make a shallow copy of this package settings.
223      */
copyFrom(PackageSettingBase base)224     public void copyFrom(PackageSettingBase base) {
225         mPermissionsState.copyFrom(base.mPermissionsState);
226         primaryCpuAbiString = base.primaryCpuAbiString;
227         secondaryCpuAbiString = base.secondaryCpuAbiString;
228         cpuAbiOverrideString = base.cpuAbiOverrideString;
229         timeStamp = base.timeStamp;
230         firstInstallTime = base.firstInstallTime;
231         lastUpdateTime = base.lastUpdateTime;
232         signatures = base.signatures;
233         installPermissionsFixed = base.installPermissionsFixed;
234         userState.clear();
235         for (int i=0; i<base.userState.size(); i++) {
236             userState.put(base.userState.keyAt(i), base.userState.valueAt(i));
237         }
238         installStatus = base.installStatus;
239         keySetData = base.keySetData;
240         verificationInfo = base.verificationInfo;
241         installerPackageName = base.installerPackageName;
242     }
243 
modifyUserState(int userId)244     private PackageUserState modifyUserState(int userId) {
245         PackageUserState state = userState.get(userId);
246         if (state == null) {
247             state = new PackageUserState();
248             userState.put(userId, state);
249         }
250         return state;
251     }
252 
readUserState(int userId)253     public PackageUserState readUserState(int userId) {
254         PackageUserState state = userState.get(userId);
255         if (state != null) {
256             return state;
257         }
258         return DEFAULT_USER_STATE;
259     }
260 
setEnabled(int state, int userId, String callingPackage)261     void setEnabled(int state, int userId, String callingPackage) {
262         PackageUserState st = modifyUserState(userId);
263         st.enabled = state;
264         st.lastDisableAppCaller = callingPackage;
265     }
266 
getEnabled(int userId)267     int getEnabled(int userId) {
268         return readUserState(userId).enabled;
269     }
270 
getLastDisabledAppCaller(int userId)271     String getLastDisabledAppCaller(int userId) {
272         return readUserState(userId).lastDisableAppCaller;
273     }
274 
setInstalled(boolean inst, int userId)275     void setInstalled(boolean inst, int userId) {
276         modifyUserState(userId).installed = inst;
277     }
278 
getInstalled(int userId)279     boolean getInstalled(int userId) {
280         return readUserState(userId).installed;
281     }
282 
isAnyInstalled(int[] users)283     boolean isAnyInstalled(int[] users) {
284         for (int user: users) {
285             if (readUserState(user).installed) {
286                 return true;
287             }
288         }
289         return false;
290     }
291 
queryInstalledUsers(int[] users, boolean installed)292     int[] queryInstalledUsers(int[] users, boolean installed) {
293         int num = 0;
294         for (int user : users) {
295             if (getInstalled(user) == installed) {
296                 num++;
297             }
298         }
299         int[] res = new int[num];
300         num = 0;
301         for (int user : users) {
302             if (getInstalled(user) == installed) {
303                 res[num] = user;
304                 num++;
305             }
306         }
307         return res;
308     }
309 
getStopped(int userId)310     boolean getStopped(int userId) {
311         return readUserState(userId).stopped;
312     }
313 
setStopped(boolean stop, int userId)314     void setStopped(boolean stop, int userId) {
315         modifyUserState(userId).stopped = stop;
316     }
317 
getNotLaunched(int userId)318     boolean getNotLaunched(int userId) {
319         return readUserState(userId).notLaunched;
320     }
321 
setNotLaunched(boolean stop, int userId)322     void setNotLaunched(boolean stop, int userId) {
323         modifyUserState(userId).notLaunched = stop;
324     }
325 
getHidden(int userId)326     boolean getHidden(int userId) {
327         return readUserState(userId).hidden;
328     }
329 
setHidden(boolean hidden, int userId)330     void setHidden(boolean hidden, int userId) {
331         modifyUserState(userId).hidden = hidden;
332     }
333 
getBlockUninstall(int userId)334     boolean getBlockUninstall(int userId) {
335         return readUserState(userId).blockUninstall;
336     }
337 
setBlockUninstall(boolean blockUninstall, int userId)338     void setBlockUninstall(boolean blockUninstall, int userId) {
339         modifyUserState(userId).blockUninstall = blockUninstall;
340     }
341 
setUserState(int userId, int enabled, boolean installed, boolean stopped, boolean notLaunched, boolean hidden, String lastDisableAppCaller, ArraySet<String> enabledComponents, ArraySet<String> disabledComponents, boolean blockUninstall, int domainVerifState, int linkGeneration)342     void setUserState(int userId, int enabled, boolean installed, boolean stopped,
343             boolean notLaunched, boolean hidden,
344             String lastDisableAppCaller, ArraySet<String> enabledComponents,
345             ArraySet<String> disabledComponents, boolean blockUninstall, int domainVerifState,
346             int linkGeneration) {
347         PackageUserState state = modifyUserState(userId);
348         state.enabled = enabled;
349         state.installed = installed;
350         state.stopped = stopped;
351         state.notLaunched = notLaunched;
352         state.hidden = hidden;
353         state.lastDisableAppCaller = lastDisableAppCaller;
354         state.enabledComponents = enabledComponents;
355         state.disabledComponents = disabledComponents;
356         state.blockUninstall = blockUninstall;
357         state.domainVerificationStatus = domainVerifState;
358         state.appLinkGeneration = linkGeneration;
359     }
360 
getEnabledComponents(int userId)361     ArraySet<String> getEnabledComponents(int userId) {
362         return readUserState(userId).enabledComponents;
363     }
364 
getDisabledComponents(int userId)365     ArraySet<String> getDisabledComponents(int userId) {
366         return readUserState(userId).disabledComponents;
367     }
368 
setEnabledComponents(ArraySet<String> components, int userId)369     void setEnabledComponents(ArraySet<String> components, int userId) {
370         modifyUserState(userId).enabledComponents = components;
371     }
372 
setDisabledComponents(ArraySet<String> components, int userId)373     void setDisabledComponents(ArraySet<String> components, int userId) {
374         modifyUserState(userId).disabledComponents = components;
375     }
376 
setEnabledComponentsCopy(ArraySet<String> components, int userId)377     void setEnabledComponentsCopy(ArraySet<String> components, int userId) {
378         modifyUserState(userId).enabledComponents = components != null
379                 ? new ArraySet<String>(components) : null;
380     }
381 
setDisabledComponentsCopy(ArraySet<String> components, int userId)382     void setDisabledComponentsCopy(ArraySet<String> components, int userId) {
383         modifyUserState(userId).disabledComponents = components != null
384                 ? new ArraySet<String>(components) : null;
385     }
386 
modifyUserStateComponents(int userId, boolean disabled, boolean enabled)387     PackageUserState modifyUserStateComponents(int userId, boolean disabled, boolean enabled) {
388         PackageUserState state = modifyUserState(userId);
389         if (disabled && state.disabledComponents == null) {
390             state.disabledComponents = new ArraySet<String>(1);
391         }
392         if (enabled && state.enabledComponents == null) {
393             state.enabledComponents = new ArraySet<String>(1);
394         }
395         return state;
396     }
397 
addDisabledComponent(String componentClassName, int userId)398     void addDisabledComponent(String componentClassName, int userId) {
399         modifyUserStateComponents(userId, true, false).disabledComponents.add(componentClassName);
400     }
401 
addEnabledComponent(String componentClassName, int userId)402     void addEnabledComponent(String componentClassName, int userId) {
403         modifyUserStateComponents(userId, false, true).enabledComponents.add(componentClassName);
404     }
405 
enableComponentLPw(String componentClassName, int userId)406     boolean enableComponentLPw(String componentClassName, int userId) {
407         PackageUserState state = modifyUserStateComponents(userId, false, true);
408         boolean changed = state.disabledComponents != null
409                 ? state.disabledComponents.remove(componentClassName) : false;
410         changed |= state.enabledComponents.add(componentClassName);
411         return changed;
412     }
413 
disableComponentLPw(String componentClassName, int userId)414     boolean disableComponentLPw(String componentClassName, int userId) {
415         PackageUserState state = modifyUserStateComponents(userId, true, false);
416         boolean changed = state.enabledComponents != null
417                 ? state.enabledComponents.remove(componentClassName) : false;
418         changed |= state.disabledComponents.add(componentClassName);
419         return changed;
420     }
421 
restoreComponentLPw(String componentClassName, int userId)422     boolean restoreComponentLPw(String componentClassName, int userId) {
423         PackageUserState state = modifyUserStateComponents(userId, true, true);
424         boolean changed = state.disabledComponents != null
425                 ? state.disabledComponents.remove(componentClassName) : false;
426         changed |= state.enabledComponents != null
427                 ? state.enabledComponents.remove(componentClassName) : false;
428         return changed;
429     }
430 
getCurrentEnabledStateLPr(String componentName, int userId)431     int getCurrentEnabledStateLPr(String componentName, int userId) {
432         PackageUserState state = readUserState(userId);
433         if (state.enabledComponents != null && state.enabledComponents.contains(componentName)) {
434             return COMPONENT_ENABLED_STATE_ENABLED;
435         } else if (state.disabledComponents != null
436                 && state.disabledComponents.contains(componentName)) {
437             return COMPONENT_ENABLED_STATE_DISABLED;
438         } else {
439             return COMPONENT_ENABLED_STATE_DEFAULT;
440         }
441     }
442 
removeUser(int userId)443     void removeUser(int userId) {
444         userState.delete(userId);
445     }
446 
getIntentFilterVerificationInfo()447     IntentFilterVerificationInfo getIntentFilterVerificationInfo() {
448         return verificationInfo;
449     }
450 
setIntentFilterVerificationInfo(IntentFilterVerificationInfo info)451     void setIntentFilterVerificationInfo(IntentFilterVerificationInfo info) {
452         verificationInfo = info;
453     }
454 
455     // Returns a packed value as a long:
456     //
457     // high 'int'-sized word: link status: undefined/ask/never/always.
458     // low 'int'-sized word: relative priority among 'always' results.
getDomainVerificationStatusForUser(int userId)459     long getDomainVerificationStatusForUser(int userId) {
460         PackageUserState state = readUserState(userId);
461         long result = (long) state.appLinkGeneration;
462         result |= ((long) state.domainVerificationStatus) << 32;
463         return result;
464     }
465 
setDomainVerificationStatusForUser(final int status, int generation, int userId)466     void setDomainVerificationStatusForUser(final int status, int generation, int userId) {
467         PackageUserState state = modifyUserState(userId);
468         state.domainVerificationStatus = status;
469         if (status == PackageManager.INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_ALWAYS) {
470             state.appLinkGeneration = generation;
471         }
472     }
473 
clearDomainVerificationStatusForUser(int userId)474     void clearDomainVerificationStatusForUser(int userId) {
475         modifyUserState(userId).domainVerificationStatus =
476                 PackageManager.INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_UNDEFINED;
477     }
478 }
479