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