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