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