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