• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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.annotation.NonNull;
24 import android.annotation.Nullable;
25 import android.annotation.UserIdInt;
26 import android.content.ComponentName;
27 import android.content.pm.ApplicationInfo;
28 import android.content.pm.IncrementalStatesInfo;
29 import android.content.pm.PackageManager.UninstallReason;
30 import android.content.pm.PackageParser;
31 import android.content.pm.PackageUserState;
32 import android.content.pm.Signature;
33 import android.content.pm.SuspendDialogInfo;
34 import android.content.pm.overlay.OverlayPaths;
35 import android.os.PersistableBundle;
36 import android.os.incremental.IncrementalManager;
37 import android.service.pm.PackageProto;
38 import android.util.ArrayMap;
39 import android.util.ArraySet;
40 import android.util.SparseArray;
41 import android.util.proto.ProtoOutputStream;
42 
43 import com.android.internal.annotations.VisibleForTesting;
44 import com.android.server.pm.parsing.pkg.AndroidPackage;
45 
46 import java.io.File;
47 import java.util.Arrays;
48 import java.util.Map;
49 import java.util.Objects;
50 import java.util.Set;
51 import java.util.function.Predicate;
52 
53 /**
54  * Settings base class for pending and resolved classes.
55  */
56 public abstract class PackageSettingBase extends SettingBase {
57 
58     private static final int[] EMPTY_INT_ARRAY = new int[0];
59 
60     public final String name;
61     final String realName;
62 
63     /** @see AndroidPackage#getPath() */
64     private File mPath;
65     private String mPathString;
66 
67     String[] usesStaticLibraries;
68     long[] usesStaticLibrariesVersions;
69 
70     /**
71      * The path under which native libraries have been unpacked. This path is
72      * always derived at runtime, and is only stored here for cleanup when a
73      * package is uninstalled.
74      */
75     @Deprecated
76     String legacyNativeLibraryPathString;
77 
78     /**
79      * The primary CPU abi for this package.
80      */
81     public String primaryCpuAbiString;
82 
83     /**
84      * The secondary CPU abi for this package.
85      */
86     public 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     long versionCode;
99 
100     boolean uidError;
101 
102     PackageSignatures signatures;
103 
104     boolean installPermissionsFixed;
105 
106     PackageKeySetData keySetData = new PackageKeySetData();
107 
108     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> mUserState = new SparseArray<>();
113 
114     /**
115      * Non-persisted value. During an "upgrade without restart", we need the set
116      * of all previous code paths so we can surgically add the new APKs to the
117      * active classloader. If at any point an application is upgraded with a
118      * restart, this field will be cleared since the classloader would be created
119      * using the full set of code paths when the package's process is started.
120      */
121     Set<String> mOldCodePaths;
122 
123     /** Information about how this package was installed/updated. */
124     @NonNull InstallSource installSource;
125     /** UUID of {@link VolumeInfo} hosting this app */
126     String volumeUuid;
127     /** The category of this app, as hinted by the installer */
128     int categoryHint = ApplicationInfo.CATEGORY_UNDEFINED;
129     /** Whether or not an update is available. Ostensibly only for instant apps. */
130     boolean updateAvailable;
131 
132     boolean forceQueryableOverride;
133 
134     @NonNull
135     public IncrementalStates incrementalStates;
136 
PackageSettingBase(String name, String realName, @NonNull File path, String legacyNativeLibraryPathString, String primaryCpuAbiString, String secondaryCpuAbiString, String cpuAbiOverrideString, long pVersionCode, int pkgFlags, int pkgPrivateFlags, String[] usesStaticLibraries, long[] usesStaticLibrariesVersions)137     PackageSettingBase(String name, String realName, @NonNull File path,
138             String legacyNativeLibraryPathString, String primaryCpuAbiString,
139             String secondaryCpuAbiString, String cpuAbiOverrideString,
140             long pVersionCode, int pkgFlags, int pkgPrivateFlags,
141             String[] usesStaticLibraries, long[] usesStaticLibrariesVersions) {
142         super(pkgFlags, pkgPrivateFlags);
143         this.name = name;
144         this.realName = realName;
145         this.usesStaticLibraries = usesStaticLibraries;
146         this.usesStaticLibrariesVersions = usesStaticLibrariesVersions;
147         setPath(path);
148         this.legacyNativeLibraryPathString = legacyNativeLibraryPathString;
149         this.primaryCpuAbiString = primaryCpuAbiString;
150         this.secondaryCpuAbiString = secondaryCpuAbiString;
151         this.cpuAbiOverrideString = cpuAbiOverrideString;
152         this.versionCode = pVersionCode;
153         this.signatures = new PackageSignatures();
154         this.installSource = InstallSource.EMPTY;
155         this.incrementalStates = new IncrementalStates();
156     }
157 
158     /**
159      * New instance of PackageSetting with one-level-deep cloning.
160      * <p>
161      * IMPORTANT: With a shallow copy, we do NOT create new contained objects.
162      * This means, for example, changes to the user state of the original PackageSetting
163      * will also change the user state in its copy.
164      */
PackageSettingBase(PackageSettingBase base, String realName)165     PackageSettingBase(PackageSettingBase base, String realName) {
166         super(base);
167         name = base.name;
168         this.realName = realName;
169         doCopy(base);
170     }
171 
172     // A copy constructor used to create snapshots.  The boolean is present only to
173     // match up with the constructor in PackageSetting.
PackageSettingBase(PackageSettingBase orig, boolean snapshot)174     PackageSettingBase(PackageSettingBase orig, boolean snapshot) {
175         super(orig);
176         name = orig.name;
177         realName = orig.realName;
178         doCopy(orig);
179         // Clone the user states.
180         for (int i = 0; i < mUserState.size(); i++) {
181             mUserState.put(mUserState.keyAt(i), new PackageUserState(mUserState.valueAt(i)));
182         }
183     }
184 
setInstallerPackageName(String packageName)185     public void setInstallerPackageName(String packageName) {
186         installSource = installSource.setInstallerPackage(packageName);
187         onChanged();
188     }
189 
setInstallSource(InstallSource installSource)190     public void setInstallSource(InstallSource installSource) {
191         this.installSource = Objects.requireNonNull(installSource);
192         onChanged();
193     }
194 
removeInstallerPackage(String packageName)195     void removeInstallerPackage(String packageName) {
196         installSource = installSource.removeInstallerPackage(packageName);
197         onChanged();
198     }
199 
setIsOrphaned(boolean isOrphaned)200     public void setIsOrphaned(boolean isOrphaned) {
201         installSource = installSource.setIsOrphaned(isOrphaned);
202         onChanged();
203     }
204 
setVolumeUuid(String volumeUuid)205     public void setVolumeUuid(String volumeUuid) {
206         this.volumeUuid = volumeUuid;
207         onChanged();
208     }
209 
getVolumeUuid()210     public String getVolumeUuid() {
211         return volumeUuid;
212     }
213 
setTimeStamp(long newStamp)214     public void setTimeStamp(long newStamp) {
215         timeStamp = newStamp;
216         onChanged();
217     }
218 
setUpdateAvailable(boolean updateAvailable)219     public void setUpdateAvailable(boolean updateAvailable) {
220         this.updateAvailable = updateAvailable;
221         onChanged();
222     }
223 
isUpdateAvailable()224     public boolean isUpdateAvailable() {
225         return updateAvailable;
226     }
227 
isSharedUser()228     public boolean isSharedUser() {
229         return false;
230     }
231 
getSignatures()232     public Signature[] getSignatures() {
233         return signatures.mSigningDetails.signatures;
234     }
235 
getSigningDetails()236     public PackageParser.SigningDetails getSigningDetails() {
237         return signatures.mSigningDetails;
238     }
239 
240     /**
241      * Makes a shallow copy of the given package settings.
242      *
243      * NOTE: For some fields [such as keySetData, signatures, mUserState, verificationInfo, etc...],
244      * the original object is copied and a new one is not created.
245      */
copyFrom(PackageSettingBase orig)246     public void copyFrom(PackageSettingBase orig) {
247         super.copyFrom(orig);
248         doCopy(orig);
249     }
250 
doCopy(PackageSettingBase orig)251     private void doCopy(PackageSettingBase orig) {
252         setPath(orig.getPath());
253         cpuAbiOverrideString = orig.cpuAbiOverrideString;
254         firstInstallTime = orig.firstInstallTime;
255         installPermissionsFixed = orig.installPermissionsFixed;
256         installSource = orig.installSource;
257         keySetData = orig.keySetData;
258         lastUpdateTime = orig.lastUpdateTime;
259         legacyNativeLibraryPathString = orig.legacyNativeLibraryPathString;
260         // Intentionally skip mOldCodePaths; it's not relevant for copies
261         primaryCpuAbiString = orig.primaryCpuAbiString;
262         secondaryCpuAbiString = orig.secondaryCpuAbiString;
263         signatures = orig.signatures;
264         timeStamp = orig.timeStamp;
265         uidError = orig.uidError;
266         mUserState.clear();
267         for (int i = 0; i < orig.mUserState.size(); i++) {
268             mUserState.put(orig.mUserState.keyAt(i), orig.mUserState.valueAt(i));
269         }
270         versionCode = orig.versionCode;
271         volumeUuid = orig.volumeUuid;
272         categoryHint = orig.categoryHint;
273         usesStaticLibraries = orig.usesStaticLibraries != null
274                 ? Arrays.copyOf(orig.usesStaticLibraries,
275                         orig.usesStaticLibraries.length) : null;
276         usesStaticLibrariesVersions = orig.usesStaticLibrariesVersions != null
277                 ? Arrays.copyOf(orig.usesStaticLibrariesVersions,
278                        orig.usesStaticLibrariesVersions.length) : null;
279         updateAvailable = orig.updateAvailable;
280         forceQueryableOverride = orig.forceQueryableOverride;
281         incrementalStates = orig.incrementalStates;
282     }
283 
284     @VisibleForTesting
modifyUserState(int userId)285     PackageUserState modifyUserState(int userId) {
286         PackageUserState state = mUserState.get(userId);
287         if (state == null) {
288             state = new PackageUserState();
289             mUserState.put(userId, state);
290             onChanged();
291         }
292         return state;
293     }
294 
readUserState(int userId)295     public PackageUserState readUserState(int userId) {
296         PackageUserState state = mUserState.get(userId);
297         if (state == null) {
298             return DEFAULT_USER_STATE;
299         }
300         state.categoryHint = categoryHint;
301         return state;
302     }
303 
setEnabled(int state, int userId, String callingPackage)304     void setEnabled(int state, int userId, String callingPackage) {
305         PackageUserState st = modifyUserState(userId);
306         st.enabled = state;
307         st.lastDisableAppCaller = callingPackage;
308         onChanged();
309     }
310 
getEnabled(int userId)311     int getEnabled(int userId) {
312         return readUserState(userId).enabled;
313     }
314 
getLastDisabledAppCaller(int userId)315     String getLastDisabledAppCaller(int userId) {
316         return readUserState(userId).lastDisableAppCaller;
317     }
318 
setInstalled(boolean inst, int userId)319     void setInstalled(boolean inst, int userId) {
320         modifyUserState(userId).installed = inst;
321         onChanged();
322     }
323 
getInstalled(int userId)324     boolean getInstalled(int userId) {
325         return readUserState(userId).installed;
326     }
327 
getInstallReason(int userId)328     int getInstallReason(int userId) {
329         return readUserState(userId).installReason;
330     }
331 
setInstallReason(int installReason, int userId)332     void setInstallReason(int installReason, int userId) {
333         modifyUserState(userId).installReason = installReason;
334         onChanged();
335     }
336 
getUninstallReason(int userId)337     int getUninstallReason(int userId) {
338         return readUserState(userId).uninstallReason;
339     }
340 
setUninstallReason(@ninstallReason int uninstallReason, int userId)341     void setUninstallReason(@UninstallReason int uninstallReason, int userId) {
342         modifyUserState(userId).uninstallReason = uninstallReason;
343         onChanged();
344     }
345 
setOverlayPaths(OverlayPaths overlayPaths, int userId)346     boolean setOverlayPaths(OverlayPaths overlayPaths, int userId) {
347         boolean returnValue = modifyUserState(userId).setOverlayPaths(overlayPaths);
348         onChanged();
349         return returnValue;
350     }
351 
getOverlayPaths(int userId)352     OverlayPaths getOverlayPaths(int userId) {
353         return readUserState(userId).getOverlayPaths();
354     }
355 
setOverlayPathsForLibrary(String libName, OverlayPaths overlayPaths, int userId)356     boolean setOverlayPathsForLibrary(String libName, OverlayPaths overlayPaths,
357             int userId) {
358         boolean returnValue =  modifyUserState(userId)
359                 .setSharedLibraryOverlayPaths(libName, overlayPaths);
360         onChanged();
361         return returnValue;
362     }
363 
getOverlayPathsForLibrary(int userId)364     Map<String, OverlayPaths> getOverlayPathsForLibrary(int userId) {
365         return readUserState(userId).getSharedLibraryOverlayPaths();
366     }
367 
368     /**
369      * Only use for testing. Do NOT use in production code.
370      */
371     @VisibleForTesting
372     @Deprecated
getUserState()373     public SparseArray<PackageUserState> getUserState() {
374         return mUserState;
375     }
376 
isAnyInstalled(int[] users)377     boolean isAnyInstalled(int[] users) {
378         for (int user: users) {
379             if (readUserState(user).installed) {
380                 return true;
381             }
382         }
383         return false;
384     }
385 
queryInstalledUsers(int[] users, boolean installed)386     int[] queryInstalledUsers(int[] users, boolean installed) {
387         int num = 0;
388         for (int user : users) {
389             if (getInstalled(user) == installed) {
390                 num++;
391             }
392         }
393         int[] res = new int[num];
394         num = 0;
395         for (int user : users) {
396             if (getInstalled(user) == installed) {
397                 res[num] = user;
398                 num++;
399             }
400         }
401         return res;
402     }
403 
getCeDataInode(int userId)404     long getCeDataInode(int userId) {
405         return readUserState(userId).ceDataInode;
406     }
407 
setCeDataInode(long ceDataInode, int userId)408     void setCeDataInode(long ceDataInode, int userId) {
409         modifyUserState(userId).ceDataInode = ceDataInode;
410         onChanged();
411     }
412 
getStopped(int userId)413     boolean getStopped(int userId) {
414         return readUserState(userId).stopped;
415     }
416 
setStopped(boolean stop, int userId)417     void setStopped(boolean stop, int userId) {
418         modifyUserState(userId).stopped = stop;
419         onChanged();
420     }
421 
getNotLaunched(int userId)422     boolean getNotLaunched(int userId) {
423         return readUserState(userId).notLaunched;
424     }
425 
setNotLaunched(boolean stop, int userId)426     void setNotLaunched(boolean stop, int userId) {
427         modifyUserState(userId).notLaunched = stop;
428         onChanged();
429     }
430 
getHidden(int userId)431     boolean getHidden(int userId) {
432         return readUserState(userId).hidden;
433     }
434 
setHidden(boolean hidden, int userId)435     void setHidden(boolean hidden, int userId) {
436         modifyUserState(userId).hidden = hidden;
437         onChanged();
438     }
439 
getDistractionFlags(int userId)440     int getDistractionFlags(int userId) {
441         return readUserState(userId).distractionFlags;
442     }
443 
setDistractionFlags(int distractionFlags, int userId)444     void setDistractionFlags(int distractionFlags, int userId) {
445         modifyUserState(userId).distractionFlags = distractionFlags;
446         onChanged();
447     }
448 
getSuspended(int userId)449     boolean getSuspended(int userId) {
450         return readUserState(userId).suspended;
451     }
452 
isSuspendedBy(String suspendingPackage, int userId)453     boolean isSuspendedBy(String suspendingPackage, int userId) {
454         final PackageUserState state = readUserState(userId);
455         return state.suspendParams != null && state.suspendParams.containsKey(suspendingPackage);
456     }
457 
addOrUpdateSuspension(String suspendingPackage, SuspendDialogInfo dialogInfo, PersistableBundle appExtras, PersistableBundle launcherExtras, int userId)458     void addOrUpdateSuspension(String suspendingPackage, SuspendDialogInfo dialogInfo,
459             PersistableBundle appExtras, PersistableBundle launcherExtras, int userId) {
460         final PackageUserState existingUserState = modifyUserState(userId);
461         final PackageUserState.SuspendParams newSuspendParams =
462                 PackageUserState.SuspendParams.getInstanceOrNull(dialogInfo, appExtras,
463                         launcherExtras);
464         if (existingUserState.suspendParams == null) {
465             existingUserState.suspendParams = new ArrayMap<>();
466         }
467         existingUserState.suspendParams.put(suspendingPackage, newSuspendParams);
468         existingUserState.suspended = true;
469         onChanged();
470     }
471 
removeSuspension(String suspendingPackage, int userId)472     void removeSuspension(String suspendingPackage, int userId) {
473         final PackageUserState existingUserState = modifyUserState(userId);
474         if (existingUserState.suspendParams != null) {
475             existingUserState.suspendParams.remove(suspendingPackage);
476             if (existingUserState.suspendParams.size() == 0) {
477                 existingUserState.suspendParams = null;
478             }
479         }
480         existingUserState.suspended = (existingUserState.suspendParams != null);
481         onChanged();
482     }
483 
removeSuspension(Predicate<String> suspendingPackagePredicate, int userId)484     void removeSuspension(Predicate<String> suspendingPackagePredicate, int userId) {
485         final PackageUserState existingUserState = modifyUserState(userId);
486         if (existingUserState.suspendParams != null) {
487             for (int i = existingUserState.suspendParams.size() - 1; i >= 0; i--) {
488                 final String suspendingPackage = existingUserState.suspendParams.keyAt(i);
489                 if (suspendingPackagePredicate.test(suspendingPackage)) {
490                     existingUserState.suspendParams.removeAt(i);
491                 }
492             }
493             if (existingUserState.suspendParams.size() == 0) {
494                 existingUserState.suspendParams = null;
495             }
496         }
497         existingUserState.suspended = (existingUserState.suspendParams != null);
498         onChanged();
499     }
500 
getInstantApp(int userId)501     public boolean getInstantApp(int userId) {
502         return readUserState(userId).instantApp;
503     }
504 
setInstantApp(boolean instantApp, int userId)505     void setInstantApp(boolean instantApp, int userId) {
506         modifyUserState(userId).instantApp = instantApp;
507         onChanged();
508     }
509 
getVirtulalPreload(int userId)510     boolean getVirtulalPreload(int userId) {
511         return readUserState(userId).virtualPreload;
512     }
513 
setVirtualPreload(boolean virtualPreload, int userId)514     void setVirtualPreload(boolean virtualPreload, int userId) {
515         modifyUserState(userId).virtualPreload = virtualPreload;
516         onChanged();
517     }
518 
setUserState(int userId, long ceDataInode, int enabled, boolean installed, boolean stopped, boolean notLaunched, boolean hidden, int distractionFlags, boolean suspended, ArrayMap<String, PackageUserState.SuspendParams> suspendParams, boolean instantApp, boolean virtualPreload, String lastDisableAppCaller, ArraySet<String> enabledComponents, ArraySet<String> disabledComponents, int installReason, int uninstallReason, String harmfulAppWarning, String splashScreenTheme)519     void setUserState(int userId, long ceDataInode, int enabled, boolean installed, boolean stopped,
520             boolean notLaunched, boolean hidden, int distractionFlags, boolean suspended,
521             ArrayMap<String, PackageUserState.SuspendParams> suspendParams, boolean instantApp,
522             boolean virtualPreload, String lastDisableAppCaller,
523             ArraySet<String> enabledComponents, ArraySet<String> disabledComponents,
524             int installReason, int uninstallReason, String harmfulAppWarning,
525             String splashScreenTheme) {
526         PackageUserState state = modifyUserState(userId);
527         state.ceDataInode = ceDataInode;
528         state.enabled = enabled;
529         state.installed = installed;
530         state.stopped = stopped;
531         state.notLaunched = notLaunched;
532         state.hidden = hidden;
533         state.distractionFlags = distractionFlags;
534         state.suspended = suspended;
535         state.suspendParams = suspendParams;
536         state.lastDisableAppCaller = lastDisableAppCaller;
537         state.enabledComponents = enabledComponents;
538         state.disabledComponents = disabledComponents;
539         state.installReason = installReason;
540         state.uninstallReason = uninstallReason;
541         state.instantApp = instantApp;
542         state.virtualPreload = virtualPreload;
543         state.harmfulAppWarning = harmfulAppWarning;
544         state.splashScreenTheme = splashScreenTheme;
545         onChanged();
546     }
547 
setUserState(int userId, PackageUserState otherState)548     void setUserState(int userId, PackageUserState otherState) {
549         setUserState(userId, otherState.ceDataInode, otherState.enabled, otherState.installed,
550                 otherState.stopped, otherState.notLaunched, otherState.hidden,
551                 otherState.distractionFlags, otherState.suspended, otherState.suspendParams,
552                 otherState.instantApp,
553                 otherState.virtualPreload, otherState.lastDisableAppCaller,
554                 otherState.enabledComponents, otherState.disabledComponents,
555                 otherState.installReason, otherState.uninstallReason, otherState.harmfulAppWarning,
556                 otherState.splashScreenTheme);
557     }
558 
getEnabledComponents(int userId)559     ArraySet<String> getEnabledComponents(int userId) {
560         return readUserState(userId).enabledComponents;
561     }
562 
getDisabledComponents(int userId)563     ArraySet<String> getDisabledComponents(int userId) {
564         return readUserState(userId).disabledComponents;
565     }
566 
setEnabledComponents(ArraySet<String> components, int userId)567     void setEnabledComponents(ArraySet<String> components, int userId) {
568         modifyUserState(userId).enabledComponents = components;
569         onChanged();
570     }
571 
setDisabledComponents(ArraySet<String> components, int userId)572     void setDisabledComponents(ArraySet<String> components, int userId) {
573         modifyUserState(userId).disabledComponents = components;
574         onChanged();
575     }
576 
setEnabledComponentsCopy(ArraySet<String> components, int userId)577     void setEnabledComponentsCopy(ArraySet<String> components, int userId) {
578         modifyUserState(userId).enabledComponents = components != null
579                 ? new ArraySet<String>(components) : null;
580         onChanged();
581     }
582 
setDisabledComponentsCopy(ArraySet<String> components, int userId)583     void setDisabledComponentsCopy(ArraySet<String> components, int userId) {
584         modifyUserState(userId).disabledComponents = components != null
585                 ? new ArraySet<String>(components) : null;
586         onChanged();
587     }
588 
modifyUserStateComponents(int userId, boolean disabled, boolean enabled)589     PackageUserState modifyUserStateComponents(int userId, boolean disabled, boolean enabled) {
590         PackageUserState state = modifyUserState(userId);
591         boolean changed = false;
592         if (disabled && state.disabledComponents == null) {
593             state.disabledComponents = new ArraySet<String>(1);
594             changed = true;
595         }
596         if (enabled && state.enabledComponents == null) {
597             state.enabledComponents = new ArraySet<String>(1);
598             changed = true;
599         }
600         if (changed) {
601             onChanged();
602         }
603         return state;
604     }
605 
addDisabledComponent(String componentClassName, int userId)606     void addDisabledComponent(String componentClassName, int userId) {
607         modifyUserStateComponents(userId, true, false).disabledComponents.add(componentClassName);
608         onChanged();
609     }
610 
addEnabledComponent(String componentClassName, int userId)611     void addEnabledComponent(String componentClassName, int userId) {
612         modifyUserStateComponents(userId, false, true).enabledComponents.add(componentClassName);
613         onChanged();
614     }
615 
enableComponentLPw(String componentClassName, int userId)616     boolean enableComponentLPw(String componentClassName, int userId) {
617         PackageUserState state = modifyUserStateComponents(userId, false, true);
618         boolean changed = state.disabledComponents != null
619                 ? state.disabledComponents.remove(componentClassName) : false;
620         changed |= state.enabledComponents.add(componentClassName);
621         if (changed) {
622             onChanged();
623         }
624         return changed;
625     }
626 
disableComponentLPw(String componentClassName, int userId)627     boolean disableComponentLPw(String componentClassName, int userId) {
628         PackageUserState state = modifyUserStateComponents(userId, true, false);
629         boolean changed = state.enabledComponents != null
630                 ? state.enabledComponents.remove(componentClassName) : false;
631         changed |= state.disabledComponents.add(componentClassName);
632         if (changed) {
633             onChanged();
634         }
635         return changed;
636     }
637 
restoreComponentLPw(String componentClassName, int userId)638     boolean restoreComponentLPw(String componentClassName, int userId) {
639         PackageUserState state = modifyUserStateComponents(userId, true, true);
640         boolean changed = state.disabledComponents != null
641                 ? state.disabledComponents.remove(componentClassName) : false;
642         changed |= state.enabledComponents != null
643                 ? state.enabledComponents.remove(componentClassName) : false;
644         if (changed) {
645             onChanged();
646         }
647         return changed;
648     }
649 
getCurrentEnabledStateLPr(String componentName, int userId)650     int getCurrentEnabledStateLPr(String componentName, int userId) {
651         PackageUserState state = readUserState(userId);
652         if (state.enabledComponents != null && state.enabledComponents.contains(componentName)) {
653             return COMPONENT_ENABLED_STATE_ENABLED;
654         } else if (state.disabledComponents != null
655                 && state.disabledComponents.contains(componentName)) {
656             return COMPONENT_ENABLED_STATE_DISABLED;
657         } else {
658             return COMPONENT_ENABLED_STATE_DEFAULT;
659         }
660     }
661 
removeUser(int userId)662     void removeUser(int userId) {
663         mUserState.delete(userId);
664         onChanged();
665     }
666 
getNotInstalledUserIds()667     public int[] getNotInstalledUserIds() {
668         int count = 0;
669         int userStateCount = mUserState.size();
670         for (int i = 0; i < userStateCount; i++) {
671             if (!mUserState.valueAt(i).installed) {
672                 count++;
673             }
674         }
675         if (count == 0) return EMPTY_INT_ARRAY;
676         int[] excludedUserIds = new int[count];
677         int idx = 0;
678         for (int i = 0; i < userStateCount; i++) {
679             if (!mUserState.valueAt(i).installed) {
680                 excludedUserIds[idx++] = mUserState.keyAt(i);
681             }
682         }
683         return excludedUserIds;
684     }
685 
writeUsersInfoToProto(ProtoOutputStream proto, long fieldId)686     protected void writeUsersInfoToProto(ProtoOutputStream proto, long fieldId) {
687         int count = mUserState.size();
688         for (int i = 0; i < count; i++) {
689             final long userToken = proto.start(fieldId);
690             final int userId = mUserState.keyAt(i);
691             final PackageUserState state = mUserState.valueAt(i);
692             proto.write(PackageProto.UserInfoProto.ID, userId);
693             final int installType;
694             if (state.instantApp) {
695                 installType = PackageProto.UserInfoProto.INSTANT_APP_INSTALL;
696             } else if (state.installed) {
697                 installType = PackageProto.UserInfoProto.FULL_APP_INSTALL;
698             } else {
699                 installType = PackageProto.UserInfoProto.NOT_INSTALLED_FOR_USER;
700             }
701             proto.write(PackageProto.UserInfoProto.INSTALL_TYPE, installType);
702             proto.write(PackageProto.UserInfoProto.IS_HIDDEN, state.hidden);
703             proto.write(PackageProto.UserInfoProto.DISTRACTION_FLAGS, state.distractionFlags);
704             proto.write(PackageProto.UserInfoProto.IS_SUSPENDED, state.suspended);
705             if (state.suspended) {
706                 for (int j = 0; j < state.suspendParams.size(); j++) {
707                     proto.write(PackageProto.UserInfoProto.SUSPENDING_PACKAGE,
708                             state.suspendParams.keyAt(j));
709                 }
710             }
711             proto.write(PackageProto.UserInfoProto.IS_STOPPED, state.stopped);
712             proto.write(PackageProto.UserInfoProto.IS_LAUNCHED, !state.notLaunched);
713             proto.write(PackageProto.UserInfoProto.ENABLED_STATE, state.enabled);
714             proto.write(
715                     PackageProto.UserInfoProto.LAST_DISABLED_APP_CALLER,
716                     state.lastDisableAppCaller);
717             proto.end(userToken);
718         }
719     }
720 
setHarmfulAppWarning(int userId, String harmfulAppWarning)721     void setHarmfulAppWarning(int userId, String harmfulAppWarning) {
722         PackageUserState userState = modifyUserState(userId);
723         userState.harmfulAppWarning = harmfulAppWarning;
724         onChanged();
725     }
726 
getHarmfulAppWarning(int userId)727     String getHarmfulAppWarning(int userId) {
728         PackageUserState userState = readUserState(userId);
729         return userState.harmfulAppWarning;
730     }
731 
732     /**
733      * @see #mPath
734      */
setPath(@onNull File path)735     PackageSettingBase setPath(@NonNull File path) {
736         this.mPath = path;
737         this.mPathString = path.toString();
738         onChanged();
739         return this;
740     }
741 
742     /** @see #mPath */
getPath()743     File getPath() {
744         return mPath;
745     }
746 
747     /** @see #mPath */
getPathString()748     String getPathString() {
749         return mPathString;
750     }
751 
752     /**
753      * @see PackageUserState#overrideLabelAndIcon(ComponentName, String, Integer)
754      *
755      * @param userId the specific user to change the label/icon for
756      */
757     @VisibleForTesting(visibility = VisibleForTesting.Visibility.PACKAGE)
overrideNonLocalizedLabelAndIcon(@onNull ComponentName component, @Nullable String label, @Nullable Integer icon, @UserIdInt int userId)758     public boolean overrideNonLocalizedLabelAndIcon(@NonNull ComponentName component,
759             @Nullable String label, @Nullable Integer icon, @UserIdInt int userId) {
760         boolean returnValue = modifyUserState(userId).overrideLabelAndIcon(component, label, icon);
761         onChanged();
762         return returnValue;
763     }
764 
765     /**
766      * @see PackageUserState#resetOverrideComponentLabelIcon()
767      *
768      * @param userId the specific user to reset
769      */
resetOverrideComponentLabelIcon(@serIdInt int userId)770     public void resetOverrideComponentLabelIcon(@UserIdInt int userId) {
771         modifyUserState(userId).resetOverrideComponentLabelIcon();
772         onChanged();
773     }
774 
775     /**
776      * @param userId    the specified user to modify the theme for
777      * @param themeName the theme name to persist
778      * @see android.window.SplashScreen#setSplashScreenTheme(int)
779      */
setSplashScreenTheme(@serIdInt int userId, @Nullable String themeName)780     public void setSplashScreenTheme(@UserIdInt int userId, @Nullable String themeName) {
781         modifyUserState(userId).splashScreenTheme = themeName;
782         onChanged();
783     }
784 
785     /**
786      * @param userId the specified user to get the theme setting from
787      * @return the theme name previously persisted for the user or null
788      * if no splashscreen theme is persisted.
789      * @see android.window.SplashScreen#setSplashScreenTheme(int)
790      */
791     @Nullable
getSplashScreenTheme(@serIdInt int userId)792     public String getSplashScreenTheme(@UserIdInt int userId) {
793         return readUserState(userId).splashScreenTheme;
794     }
795 
796     /**
797      * @return True if package is still being loaded, false if the package is fully loaded.
798      */
isPackageLoading()799     public boolean isPackageLoading() {
800         return getIncrementalStates().isLoading();
801     }
802 
803     /**
804      * @return all current states in a Parcelable.
805      */
getIncrementalStates()806     public IncrementalStatesInfo getIncrementalStates() {
807         return incrementalStates.getIncrementalStatesInfo();
808     }
809 
810     /**
811      * Called to indicate that the package installation has been committed. This will create a
812      * new loading state with default values.
813      * For a package installed on Incremental, the loading state is true.
814      * For non-Incremental packages, the loading state is false.
815      */
setStatesOnCommit()816     public void setStatesOnCommit() {
817         incrementalStates.onCommit(IncrementalManager.isIncrementalPath(getPathString()));
818         onChanged();
819     }
820 
821     /**
822      * Called to set the callback to listen for loading state changes.
823      */
setIncrementalStatesCallback(IncrementalStates.Callback callback)824     public void setIncrementalStatesCallback(IncrementalStates.Callback callback) {
825         incrementalStates.setCallback(callback);
826         onChanged();
827     }
828 
829     /**
830      * Called to report progress changes. This might trigger loading state change.
831      * @see IncrementalStates#setProgress(float)
832      */
setLoadingProgress(float progress)833     public void setLoadingProgress(float progress) {
834         incrementalStates.setProgress(progress);
835         onChanged();
836     }
837 
getFirstInstallTime()838     public long getFirstInstallTime() {
839         return firstInstallTime;
840     }
841 
getName()842     public String getName() {
843         return name;
844     }
845 
updateFrom(PackageSettingBase other)846     protected PackageSettingBase updateFrom(PackageSettingBase other) {
847         super.copyFrom(other);
848         setPath(other.getPath());
849         this.usesStaticLibraries = other.usesStaticLibraries;
850         this.usesStaticLibrariesVersions = other.usesStaticLibrariesVersions;
851         this.legacyNativeLibraryPathString = other.legacyNativeLibraryPathString;
852         this.primaryCpuAbiString = other.primaryCpuAbiString;
853         this.secondaryCpuAbiString = other.secondaryCpuAbiString;
854         this.cpuAbiOverrideString = other.cpuAbiOverrideString;
855         this.timeStamp = other.timeStamp;
856         this.firstInstallTime = other.firstInstallTime;
857         this.lastUpdateTime = other.lastUpdateTime;
858         this.versionCode = other.versionCode;
859         this.uidError = other.uidError;
860         this.signatures = other.signatures;
861         this.installPermissionsFixed = other.installPermissionsFixed;
862         this.keySetData = other.keySetData;
863         this.installSource = other.installSource;
864         this.volumeUuid = other.volumeUuid;
865         this.categoryHint = other.categoryHint;
866         this.updateAvailable = other.updateAvailable;
867         this.forceQueryableOverride = other.forceQueryableOverride;
868         this.incrementalStates = other.incrementalStates;
869 
870         if (mOldCodePaths != null) {
871             if (other.mOldCodePaths != null) {
872                 mOldCodePaths.clear();
873                 mOldCodePaths.addAll(other.mOldCodePaths);
874             } else {
875                 mOldCodePaths = null;
876             }
877         }
878         mUserState.clear();
879         for (int i = 0; i < other.mUserState.size(); i++) {
880             mUserState.put(other.mUserState.keyAt(i), other.mUserState.valueAt(i));
881         }
882         onChanged();
883         return this;
884     }
885 }
886