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 boolean 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 final PackageUserState.SuspendParams oldSuspendParams = 468 existingUserState.suspendParams.put(suspendingPackage, newSuspendParams); 469 existingUserState.suspended = true; 470 onChanged(); 471 return !Objects.equals(oldSuspendParams, newSuspendParams); 472 } 473 removeSuspension(String suspendingPackage, int userId)474 boolean removeSuspension(String suspendingPackage, int userId) { 475 boolean wasModified = false; 476 final PackageUserState existingUserState = modifyUserState(userId); 477 if (existingUserState.suspendParams != null) { 478 if (existingUserState.suspendParams.remove(suspendingPackage) != null) { 479 wasModified = true; 480 } 481 if (existingUserState.suspendParams.size() == 0) { 482 existingUserState.suspendParams = null; 483 } 484 } 485 existingUserState.suspended = (existingUserState.suspendParams != null); 486 onChanged(); 487 return wasModified; 488 } 489 removeSuspension(Predicate<String> suspendingPackagePredicate, int userId)490 void removeSuspension(Predicate<String> suspendingPackagePredicate, int userId) { 491 final PackageUserState existingUserState = modifyUserState(userId); 492 if (existingUserState.suspendParams != null) { 493 for (int i = existingUserState.suspendParams.size() - 1; i >= 0; i--) { 494 final String suspendingPackage = existingUserState.suspendParams.keyAt(i); 495 if (suspendingPackagePredicate.test(suspendingPackage)) { 496 existingUserState.suspendParams.removeAt(i); 497 } 498 } 499 if (existingUserState.suspendParams.size() == 0) { 500 existingUserState.suspendParams = null; 501 } 502 } 503 existingUserState.suspended = (existingUserState.suspendParams != null); 504 onChanged(); 505 } 506 getInstantApp(int userId)507 public boolean getInstantApp(int userId) { 508 return readUserState(userId).instantApp; 509 } 510 setInstantApp(boolean instantApp, int userId)511 void setInstantApp(boolean instantApp, int userId) { 512 modifyUserState(userId).instantApp = instantApp; 513 onChanged(); 514 } 515 getVirtulalPreload(int userId)516 boolean getVirtulalPreload(int userId) { 517 return readUserState(userId).virtualPreload; 518 } 519 setVirtualPreload(boolean virtualPreload, int userId)520 void setVirtualPreload(boolean virtualPreload, int userId) { 521 modifyUserState(userId).virtualPreload = virtualPreload; 522 onChanged(); 523 } 524 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)525 void setUserState(int userId, long ceDataInode, int enabled, boolean installed, boolean stopped, 526 boolean notLaunched, boolean hidden, int distractionFlags, boolean suspended, 527 ArrayMap<String, PackageUserState.SuspendParams> suspendParams, boolean instantApp, 528 boolean virtualPreload, String lastDisableAppCaller, 529 ArraySet<String> enabledComponents, ArraySet<String> disabledComponents, 530 int installReason, int uninstallReason, String harmfulAppWarning, 531 String splashScreenTheme) { 532 PackageUserState state = modifyUserState(userId); 533 state.ceDataInode = ceDataInode; 534 state.enabled = enabled; 535 state.installed = installed; 536 state.stopped = stopped; 537 state.notLaunched = notLaunched; 538 state.hidden = hidden; 539 state.distractionFlags = distractionFlags; 540 state.suspended = suspended; 541 state.suspendParams = suspendParams; 542 state.lastDisableAppCaller = lastDisableAppCaller; 543 state.enabledComponents = enabledComponents; 544 state.disabledComponents = disabledComponents; 545 state.installReason = installReason; 546 state.uninstallReason = uninstallReason; 547 state.instantApp = instantApp; 548 state.virtualPreload = virtualPreload; 549 state.harmfulAppWarning = harmfulAppWarning; 550 state.splashScreenTheme = splashScreenTheme; 551 onChanged(); 552 } 553 setUserState(int userId, PackageUserState otherState)554 void setUserState(int userId, PackageUserState otherState) { 555 setUserState(userId, otherState.ceDataInode, otherState.enabled, otherState.installed, 556 otherState.stopped, otherState.notLaunched, otherState.hidden, 557 otherState.distractionFlags, otherState.suspended, otherState.suspendParams, 558 otherState.instantApp, 559 otherState.virtualPreload, otherState.lastDisableAppCaller, 560 otherState.enabledComponents, otherState.disabledComponents, 561 otherState.installReason, otherState.uninstallReason, otherState.harmfulAppWarning, 562 otherState.splashScreenTheme); 563 } 564 getEnabledComponents(int userId)565 ArraySet<String> getEnabledComponents(int userId) { 566 return readUserState(userId).enabledComponents; 567 } 568 getDisabledComponents(int userId)569 ArraySet<String> getDisabledComponents(int userId) { 570 return readUserState(userId).disabledComponents; 571 } 572 setEnabledComponents(ArraySet<String> components, int userId)573 void setEnabledComponents(ArraySet<String> components, int userId) { 574 modifyUserState(userId).enabledComponents = components; 575 onChanged(); 576 } 577 setDisabledComponents(ArraySet<String> components, int userId)578 void setDisabledComponents(ArraySet<String> components, int userId) { 579 modifyUserState(userId).disabledComponents = components; 580 onChanged(); 581 } 582 setEnabledComponentsCopy(ArraySet<String> components, int userId)583 void setEnabledComponentsCopy(ArraySet<String> components, int userId) { 584 modifyUserState(userId).enabledComponents = components != null 585 ? new ArraySet<String>(components) : null; 586 onChanged(); 587 } 588 setDisabledComponentsCopy(ArraySet<String> components, int userId)589 void setDisabledComponentsCopy(ArraySet<String> components, int userId) { 590 modifyUserState(userId).disabledComponents = components != null 591 ? new ArraySet<String>(components) : null; 592 onChanged(); 593 } 594 modifyUserStateComponents(int userId, boolean disabled, boolean enabled)595 PackageUserState modifyUserStateComponents(int userId, boolean disabled, boolean enabled) { 596 PackageUserState state = modifyUserState(userId); 597 boolean changed = false; 598 if (disabled && state.disabledComponents == null) { 599 state.disabledComponents = new ArraySet<String>(1); 600 changed = true; 601 } 602 if (enabled && state.enabledComponents == null) { 603 state.enabledComponents = new ArraySet<String>(1); 604 changed = true; 605 } 606 if (changed) { 607 onChanged(); 608 } 609 return state; 610 } 611 addDisabledComponent(String componentClassName, int userId)612 void addDisabledComponent(String componentClassName, int userId) { 613 modifyUserStateComponents(userId, true, false).disabledComponents.add(componentClassName); 614 onChanged(); 615 } 616 addEnabledComponent(String componentClassName, int userId)617 void addEnabledComponent(String componentClassName, int userId) { 618 modifyUserStateComponents(userId, false, true).enabledComponents.add(componentClassName); 619 onChanged(); 620 } 621 enableComponentLPw(String componentClassName, int userId)622 boolean enableComponentLPw(String componentClassName, int userId) { 623 PackageUserState state = modifyUserStateComponents(userId, false, true); 624 boolean changed = state.disabledComponents != null 625 ? state.disabledComponents.remove(componentClassName) : false; 626 changed |= state.enabledComponents.add(componentClassName); 627 if (changed) { 628 onChanged(); 629 } 630 return changed; 631 } 632 disableComponentLPw(String componentClassName, int userId)633 boolean disableComponentLPw(String componentClassName, int userId) { 634 PackageUserState state = modifyUserStateComponents(userId, true, false); 635 boolean changed = state.enabledComponents != null 636 ? state.enabledComponents.remove(componentClassName) : false; 637 changed |= state.disabledComponents.add(componentClassName); 638 if (changed) { 639 onChanged(); 640 } 641 return changed; 642 } 643 restoreComponentLPw(String componentClassName, int userId)644 boolean restoreComponentLPw(String componentClassName, int userId) { 645 PackageUserState state = modifyUserStateComponents(userId, true, true); 646 boolean changed = state.disabledComponents != null 647 ? state.disabledComponents.remove(componentClassName) : false; 648 changed |= state.enabledComponents != null 649 ? state.enabledComponents.remove(componentClassName) : false; 650 if (changed) { 651 onChanged(); 652 } 653 return changed; 654 } 655 getCurrentEnabledStateLPr(String componentName, int userId)656 int getCurrentEnabledStateLPr(String componentName, int userId) { 657 PackageUserState state = readUserState(userId); 658 if (state.enabledComponents != null && state.enabledComponents.contains(componentName)) { 659 return COMPONENT_ENABLED_STATE_ENABLED; 660 } else if (state.disabledComponents != null 661 && state.disabledComponents.contains(componentName)) { 662 return COMPONENT_ENABLED_STATE_DISABLED; 663 } else { 664 return COMPONENT_ENABLED_STATE_DEFAULT; 665 } 666 } 667 removeUser(int userId)668 void removeUser(int userId) { 669 mUserState.delete(userId); 670 onChanged(); 671 } 672 getNotInstalledUserIds()673 public int[] getNotInstalledUserIds() { 674 int count = 0; 675 int userStateCount = mUserState.size(); 676 for (int i = 0; i < userStateCount; i++) { 677 if (!mUserState.valueAt(i).installed) { 678 count++; 679 } 680 } 681 if (count == 0) return EMPTY_INT_ARRAY; 682 int[] excludedUserIds = new int[count]; 683 int idx = 0; 684 for (int i = 0; i < userStateCount; i++) { 685 if (!mUserState.valueAt(i).installed) { 686 excludedUserIds[idx++] = mUserState.keyAt(i); 687 } 688 } 689 return excludedUserIds; 690 } 691 writeUsersInfoToProto(ProtoOutputStream proto, long fieldId)692 protected void writeUsersInfoToProto(ProtoOutputStream proto, long fieldId) { 693 int count = mUserState.size(); 694 for (int i = 0; i < count; i++) { 695 final long userToken = proto.start(fieldId); 696 final int userId = mUserState.keyAt(i); 697 final PackageUserState state = mUserState.valueAt(i); 698 proto.write(PackageProto.UserInfoProto.ID, userId); 699 final int installType; 700 if (state.instantApp) { 701 installType = PackageProto.UserInfoProto.INSTANT_APP_INSTALL; 702 } else if (state.installed) { 703 installType = PackageProto.UserInfoProto.FULL_APP_INSTALL; 704 } else { 705 installType = PackageProto.UserInfoProto.NOT_INSTALLED_FOR_USER; 706 } 707 proto.write(PackageProto.UserInfoProto.INSTALL_TYPE, installType); 708 proto.write(PackageProto.UserInfoProto.IS_HIDDEN, state.hidden); 709 proto.write(PackageProto.UserInfoProto.DISTRACTION_FLAGS, state.distractionFlags); 710 proto.write(PackageProto.UserInfoProto.IS_SUSPENDED, state.suspended); 711 if (state.suspended) { 712 for (int j = 0; j < state.suspendParams.size(); j++) { 713 proto.write(PackageProto.UserInfoProto.SUSPENDING_PACKAGE, 714 state.suspendParams.keyAt(j)); 715 } 716 } 717 proto.write(PackageProto.UserInfoProto.IS_STOPPED, state.stopped); 718 proto.write(PackageProto.UserInfoProto.IS_LAUNCHED, !state.notLaunched); 719 proto.write(PackageProto.UserInfoProto.ENABLED_STATE, state.enabled); 720 proto.write( 721 PackageProto.UserInfoProto.LAST_DISABLED_APP_CALLER, 722 state.lastDisableAppCaller); 723 proto.end(userToken); 724 } 725 } 726 setHarmfulAppWarning(int userId, String harmfulAppWarning)727 void setHarmfulAppWarning(int userId, String harmfulAppWarning) { 728 PackageUserState userState = modifyUserState(userId); 729 userState.harmfulAppWarning = harmfulAppWarning; 730 onChanged(); 731 } 732 getHarmfulAppWarning(int userId)733 String getHarmfulAppWarning(int userId) { 734 PackageUserState userState = readUserState(userId); 735 return userState.harmfulAppWarning; 736 } 737 738 /** 739 * @see #mPath 740 */ setPath(@onNull File path)741 PackageSettingBase setPath(@NonNull File path) { 742 this.mPath = path; 743 this.mPathString = path.toString(); 744 onChanged(); 745 return this; 746 } 747 748 /** @see #mPath */ getPath()749 File getPath() { 750 return mPath; 751 } 752 753 /** @see #mPath */ getPathString()754 String getPathString() { 755 return mPathString; 756 } 757 758 /** 759 * @see PackageUserState#overrideLabelAndIcon(ComponentName, String, Integer) 760 * 761 * @param userId the specific user to change the label/icon for 762 */ 763 @VisibleForTesting(visibility = VisibleForTesting.Visibility.PACKAGE) overrideNonLocalizedLabelAndIcon(@onNull ComponentName component, @Nullable String label, @Nullable Integer icon, @UserIdInt int userId)764 public boolean overrideNonLocalizedLabelAndIcon(@NonNull ComponentName component, 765 @Nullable String label, @Nullable Integer icon, @UserIdInt int userId) { 766 boolean returnValue = modifyUserState(userId).overrideLabelAndIcon(component, label, icon); 767 onChanged(); 768 return returnValue; 769 } 770 771 /** 772 * @see PackageUserState#resetOverrideComponentLabelIcon() 773 * 774 * @param userId the specific user to reset 775 */ resetOverrideComponentLabelIcon(@serIdInt int userId)776 public void resetOverrideComponentLabelIcon(@UserIdInt int userId) { 777 modifyUserState(userId).resetOverrideComponentLabelIcon(); 778 onChanged(); 779 } 780 781 /** 782 * @param userId the specified user to modify the theme for 783 * @param themeName the theme name to persist 784 * @see android.window.SplashScreen#setSplashScreenTheme(int) 785 */ setSplashScreenTheme(@serIdInt int userId, @Nullable String themeName)786 public void setSplashScreenTheme(@UserIdInt int userId, @Nullable String themeName) { 787 modifyUserState(userId).splashScreenTheme = themeName; 788 onChanged(); 789 } 790 791 /** 792 * @param userId the specified user to get the theme setting from 793 * @return the theme name previously persisted for the user or null 794 * if no splashscreen theme is persisted. 795 * @see android.window.SplashScreen#setSplashScreenTheme(int) 796 */ 797 @Nullable getSplashScreenTheme(@serIdInt int userId)798 public String getSplashScreenTheme(@UserIdInt int userId) { 799 return readUserState(userId).splashScreenTheme; 800 } 801 802 /** 803 * @return True if package is still being loaded, false if the package is fully loaded. 804 */ isPackageLoading()805 public boolean isPackageLoading() { 806 return getIncrementalStates().isLoading(); 807 } 808 809 /** 810 * @return all current states in a Parcelable. 811 */ getIncrementalStates()812 public IncrementalStatesInfo getIncrementalStates() { 813 return incrementalStates.getIncrementalStatesInfo(); 814 } 815 816 /** 817 * Called to indicate that the package installation has been committed. This will create a 818 * new loading state with default values. 819 * For a package installed on Incremental, the loading state is true. 820 * For non-Incremental packages, the loading state is false. 821 */ setStatesOnCommit()822 public void setStatesOnCommit() { 823 incrementalStates.onCommit(IncrementalManager.isIncrementalPath(getPathString())); 824 onChanged(); 825 } 826 827 /** 828 * Called to set the callback to listen for loading state changes. 829 */ setIncrementalStatesCallback(IncrementalStates.Callback callback)830 public void setIncrementalStatesCallback(IncrementalStates.Callback callback) { 831 incrementalStates.setCallback(callback); 832 onChanged(); 833 } 834 835 /** 836 * Called to report progress changes. This might trigger loading state change. 837 * @see IncrementalStates#setProgress(float) 838 */ setLoadingProgress(float progress)839 public void setLoadingProgress(float progress) { 840 incrementalStates.setProgress(progress); 841 onChanged(); 842 } 843 getFirstInstallTime()844 public long getFirstInstallTime() { 845 return firstInstallTime; 846 } 847 getName()848 public String getName() { 849 return name; 850 } 851 updateFrom(PackageSettingBase other)852 protected PackageSettingBase updateFrom(PackageSettingBase other) { 853 super.copyFrom(other); 854 setPath(other.getPath()); 855 this.usesStaticLibraries = other.usesStaticLibraries; 856 this.usesStaticLibrariesVersions = other.usesStaticLibrariesVersions; 857 this.legacyNativeLibraryPathString = other.legacyNativeLibraryPathString; 858 this.primaryCpuAbiString = other.primaryCpuAbiString; 859 this.secondaryCpuAbiString = other.secondaryCpuAbiString; 860 this.cpuAbiOverrideString = other.cpuAbiOverrideString; 861 this.timeStamp = other.timeStamp; 862 this.firstInstallTime = other.firstInstallTime; 863 this.lastUpdateTime = other.lastUpdateTime; 864 this.versionCode = other.versionCode; 865 this.uidError = other.uidError; 866 this.signatures = other.signatures; 867 this.installPermissionsFixed = other.installPermissionsFixed; 868 this.keySetData = other.keySetData; 869 this.installSource = other.installSource; 870 this.volumeUuid = other.volumeUuid; 871 this.categoryHint = other.categoryHint; 872 this.updateAvailable = other.updateAvailable; 873 this.forceQueryableOverride = other.forceQueryableOverride; 874 this.incrementalStates = other.incrementalStates; 875 876 if (mOldCodePaths != null) { 877 if (other.mOldCodePaths != null) { 878 mOldCodePaths.clear(); 879 mOldCodePaths.addAll(other.mOldCodePaths); 880 } else { 881 mOldCodePaths = null; 882 } 883 } 884 mUserState.clear(); 885 for (int i = 0; i < other.mUserState.size(); i++) { 886 mUserState.put(other.mUserState.keyAt(i), other.mUserState.valueAt(i)); 887 } 888 onChanged(); 889 return this; 890 } 891 } 892