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