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