PackageSettingBase.java revision b274947dfb03f04872546774af0f8770ade5bed7
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.os.storage.VolumeInfo; 28import android.service.pm.PackageProto; 29import android.util.ArraySet; 30import android.util.SparseArray; 31import android.util.proto.ProtoOutputStream; 32 33import com.android.internal.annotations.VisibleForTesting; 34import com.google.android.collect.Lists; 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 */ 45abstract 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 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 int[] 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 int 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 PackageSettingBase origPackage; 136 137 /** Package name of the app that installed this package */ 138 String installerPackageName; 139 /** Indicates if the package that installed this app has been uninstalled */ 140 boolean isOrphaned; 141 /** UUID of {@link VolumeInfo} hosting this app */ 142 String volumeUuid; 143 /** The category of this app, as hinted by the installer */ 144 int categoryHint = ApplicationInfo.CATEGORY_UNDEFINED; 145 /** Whether or not an update is available. Ostensibly only for instant apps. */ 146 boolean updateAvailable; 147 148 IntentFilterVerificationInfo verificationInfo; 149 150 PackageSettingBase(String name, String realName, File codePath, File resourcePath, 151 String legacyNativeLibraryPathString, String primaryCpuAbiString, 152 String secondaryCpuAbiString, String cpuAbiOverrideString, 153 int pVersionCode, int pkgFlags, int pkgPrivateFlags, 154 String parentPackageName, List<String> childPackageNames, 155 String[] usesStaticLibraries, int[] usesStaticLibrariesVersions) { 156 super(pkgFlags, pkgPrivateFlags); 157 this.name = name; 158 this.realName = realName; 159 this.parentPackageName = parentPackageName; 160 this.childPackageNames = (childPackageNames != null) 161 ? new ArrayList<>(childPackageNames) : null; 162 this.usesStaticLibraries = usesStaticLibraries; 163 this.usesStaticLibrariesVersions = usesStaticLibrariesVersions; 164 init(codePath, resourcePath, legacyNativeLibraryPathString, primaryCpuAbiString, 165 secondaryCpuAbiString, cpuAbiOverrideString, pVersionCode); 166 } 167 168 /** 169 * New instance of PackageSetting with one-level-deep cloning. 170 * <p> 171 * IMPORTANT: With a shallow copy, we do NOT create new contained objects. 172 * This means, for example, changes to the user state of the original PackageSetting 173 * will also change the user state in its copy. 174 */ 175 PackageSettingBase(PackageSettingBase base, String realName) { 176 super(base); 177 name = base.name; 178 this.realName = realName; 179 doCopy(base); 180 } 181 182 void init(File codePath, File resourcePath, String legacyNativeLibraryPathString, 183 String primaryCpuAbiString, String secondaryCpuAbiString, 184 String cpuAbiOverrideString, int pVersionCode) { 185 this.codePath = codePath; 186 this.codePathString = codePath.toString(); 187 this.resourcePath = resourcePath; 188 this.resourcePathString = resourcePath.toString(); 189 this.legacyNativeLibraryPathString = legacyNativeLibraryPathString; 190 this.primaryCpuAbiString = primaryCpuAbiString; 191 this.secondaryCpuAbiString = secondaryCpuAbiString; 192 this.cpuAbiOverrideString = cpuAbiOverrideString; 193 this.versionCode = pVersionCode; 194 this.signatures = new PackageSignatures(); 195 } 196 197 public void setInstallerPackageName(String packageName) { 198 installerPackageName = packageName; 199 } 200 201 public String getInstallerPackageName() { 202 return installerPackageName; 203 } 204 205 public void setVolumeUuid(String volumeUuid) { 206 this.volumeUuid = volumeUuid; 207 } 208 209 public String getVolumeUuid() { 210 return volumeUuid; 211 } 212 213 public void setInstallStatus(int newStatus) { 214 installStatus = newStatus; 215 } 216 217 public int getInstallStatus() { 218 return installStatus; 219 } 220 221 public void setTimeStamp(long newStamp) { 222 timeStamp = newStamp; 223 } 224 225 public void setUpdateAvailable(boolean updateAvailable) { 226 this.updateAvailable = updateAvailable; 227 } 228 229 public boolean isUpdateAvailable() { 230 return updateAvailable; 231 } 232 233 /** 234 * Makes a shallow copy of the given package settings. 235 * 236 * NOTE: For some fields [such as keySetData, signatures, userState, verificationInfo, etc...], 237 * the original object is copied and a new one is not created. 238 */ 239 public void copyFrom(PackageSettingBase orig) { 240 super.copyFrom(orig); 241 doCopy(orig); 242 } 243 244 private void doCopy(PackageSettingBase orig) { 245 childPackageNames = (orig.childPackageNames != null) 246 ? new ArrayList<>(orig.childPackageNames) : null; 247 codePath = orig.codePath; 248 codePathString = orig.codePathString; 249 cpuAbiOverrideString = orig.cpuAbiOverrideString; 250 firstInstallTime = orig.firstInstallTime; 251 installPermissionsFixed = orig.installPermissionsFixed; 252 installStatus = orig.installStatus; 253 installerPackageName = orig.installerPackageName; 254 isOrphaned = orig.isOrphaned; 255 keySetData = orig.keySetData; 256 lastUpdateTime = orig.lastUpdateTime; 257 legacyNativeLibraryPathString = orig.legacyNativeLibraryPathString; 258 // Intentionally skip oldCodePaths; it's not relevant for copies 259 origPackage = orig.origPackage; 260 parentPackageName = orig.parentPackageName; 261 primaryCpuAbiString = orig.primaryCpuAbiString; 262 resourcePath = orig.resourcePath; 263 resourcePathString = orig.resourcePathString; 264 secondaryCpuAbiString = orig.secondaryCpuAbiString; 265 signatures = orig.signatures; 266 timeStamp = orig.timeStamp; 267 uidError = orig.uidError; 268 userState.clear(); 269 for (int i=0; i<orig.userState.size(); i++) { 270 userState.put(orig.userState.keyAt(i), orig.userState.valueAt(i)); 271 } 272 verificationInfo = orig.verificationInfo; 273 versionCode = orig.versionCode; 274 volumeUuid = orig.volumeUuid; 275 categoryHint = orig.categoryHint; 276 usesStaticLibraries = orig.usesStaticLibraries != null 277 ? Arrays.copyOf(orig.usesStaticLibraries, 278 orig.usesStaticLibraries.length) : null; 279 usesStaticLibrariesVersions = orig.usesStaticLibrariesVersions != null 280 ? Arrays.copyOf(orig.usesStaticLibrariesVersions, 281 orig.usesStaticLibrariesVersions.length) : null; 282 updateAvailable = orig.updateAvailable; 283 } 284 285 private PackageUserState modifyUserState(int userId) { 286 PackageUserState state = userState.get(userId); 287 if (state == null) { 288 state = new PackageUserState(); 289 userState.put(userId, state); 290 } 291 return state; 292 } 293 294 public PackageUserState readUserState(int userId) { 295 PackageUserState state = userState.get(userId); 296 if (state == null) { 297 return DEFAULT_USER_STATE; 298 } 299 state.categoryHint = categoryHint; 300 return state; 301 } 302 303 void setEnabled(int state, int userId, String callingPackage) { 304 PackageUserState st = modifyUserState(userId); 305 st.enabled = state; 306 st.lastDisableAppCaller = callingPackage; 307 } 308 309 int getEnabled(int userId) { 310 return readUserState(userId).enabled; 311 } 312 313 String getLastDisabledAppCaller(int userId) { 314 return readUserState(userId).lastDisableAppCaller; 315 } 316 317 void setInstalled(boolean inst, int userId) { 318 modifyUserState(userId).installed = inst; 319 } 320 321 boolean getInstalled(int userId) { 322 return readUserState(userId).installed; 323 } 324 325 int getInstallReason(int userId) { 326 return readUserState(userId).installReason; 327 } 328 329 void setInstallReason(int installReason, int userId) { 330 modifyUserState(userId).installReason = installReason; 331 } 332 333 void setOverlayPaths(List<String> overlayPaths, String[] frameworkOverlayPaths, int userId) { 334 if (overlayPaths == null && frameworkOverlayPaths == null) { 335 modifyUserState(userId).overlayPaths = null; 336 return; 337 } 338 final List<String> paths; 339 if (frameworkOverlayPaths == null) { 340 paths = overlayPaths; 341 } else { 342 paths = Lists.newArrayList(frameworkOverlayPaths); 343 if (overlayPaths != null) { 344 paths.addAll(overlayPaths); 345 } 346 } 347 modifyUserState(userId).overlayPaths = paths.toArray(new String[paths.size()]); 348 } 349 350 String[] getOverlayPaths(int userId) { 351 return readUserState(userId).overlayPaths; 352 } 353 354 /** Only use for testing. Do NOT use in production code. */ 355 @VisibleForTesting 356 SparseArray<PackageUserState> getUserState() { 357 return userState; 358 } 359 360 boolean isAnyInstalled(int[] users) { 361 for (int user: users) { 362 if (readUserState(user).installed) { 363 return true; 364 } 365 } 366 return false; 367 } 368 369 int[] queryInstalledUsers(int[] users, boolean installed) { 370 int num = 0; 371 for (int user : users) { 372 if (getInstalled(user) == installed) { 373 num++; 374 } 375 } 376 int[] res = new int[num]; 377 num = 0; 378 for (int user : users) { 379 if (getInstalled(user) == installed) { 380 res[num] = user; 381 num++; 382 } 383 } 384 return res; 385 } 386 387 long getCeDataInode(int userId) { 388 return readUserState(userId).ceDataInode; 389 } 390 391 void setCeDataInode(long ceDataInode, int userId) { 392 modifyUserState(userId).ceDataInode = ceDataInode; 393 } 394 395 boolean getStopped(int userId) { 396 return readUserState(userId).stopped; 397 } 398 399 void setStopped(boolean stop, int userId) { 400 modifyUserState(userId).stopped = stop; 401 } 402 403 boolean getNotLaunched(int userId) { 404 return readUserState(userId).notLaunched; 405 } 406 407 void setNotLaunched(boolean stop, int userId) { 408 modifyUserState(userId).notLaunched = stop; 409 } 410 411 boolean getHidden(int userId) { 412 return readUserState(userId).hidden; 413 } 414 415 void setHidden(boolean hidden, int userId) { 416 modifyUserState(userId).hidden = hidden; 417 } 418 419 boolean getSuspended(int userId) { 420 return readUserState(userId).suspended; 421 } 422 423 void setSuspended(boolean suspended, int userId) { 424 modifyUserState(userId).suspended = suspended; 425 } 426 427 boolean getInstantApp(int userId) { 428 return readUserState(userId).instantApp; 429 } 430 431 void setInstantApp(boolean instantApp, int userId) { 432 modifyUserState(userId).instantApp = instantApp; 433 } 434 435 void setUserState(int userId, long ceDataInode, int enabled, boolean installed, boolean stopped, 436 boolean notLaunched, boolean hidden, boolean suspended, boolean instantApp, 437 String lastDisableAppCaller, ArraySet<String> enabledComponents, 438 ArraySet<String> disabledComponents, int domainVerifState, 439 int linkGeneration, int installReason) { 440 PackageUserState state = modifyUserState(userId); 441 state.ceDataInode = ceDataInode; 442 state.enabled = enabled; 443 state.installed = installed; 444 state.stopped = stopped; 445 state.notLaunched = notLaunched; 446 state.hidden = hidden; 447 state.suspended = suspended; 448 state.lastDisableAppCaller = lastDisableAppCaller; 449 state.enabledComponents = enabledComponents; 450 state.disabledComponents = disabledComponents; 451 state.domainVerificationStatus = domainVerifState; 452 state.appLinkGeneration = linkGeneration; 453 state.installReason = installReason; 454 state.instantApp = instantApp; 455 } 456 457 ArraySet<String> getEnabledComponents(int userId) { 458 return readUserState(userId).enabledComponents; 459 } 460 461 ArraySet<String> getDisabledComponents(int userId) { 462 return readUserState(userId).disabledComponents; 463 } 464 465 void setEnabledComponents(ArraySet<String> components, int userId) { 466 modifyUserState(userId).enabledComponents = components; 467 } 468 469 void setDisabledComponents(ArraySet<String> components, int userId) { 470 modifyUserState(userId).disabledComponents = components; 471 } 472 473 void setEnabledComponentsCopy(ArraySet<String> components, int userId) { 474 modifyUserState(userId).enabledComponents = components != null 475 ? new ArraySet<String>(components) : null; 476 } 477 478 void setDisabledComponentsCopy(ArraySet<String> components, int userId) { 479 modifyUserState(userId).disabledComponents = components != null 480 ? new ArraySet<String>(components) : null; 481 } 482 483 PackageUserState modifyUserStateComponents(int userId, boolean disabled, boolean enabled) { 484 PackageUserState state = modifyUserState(userId); 485 if (disabled && state.disabledComponents == null) { 486 state.disabledComponents = new ArraySet<String>(1); 487 } 488 if (enabled && state.enabledComponents == null) { 489 state.enabledComponents = new ArraySet<String>(1); 490 } 491 return state; 492 } 493 494 void addDisabledComponent(String componentClassName, int userId) { 495 modifyUserStateComponents(userId, true, false).disabledComponents.add(componentClassName); 496 } 497 498 void addEnabledComponent(String componentClassName, int userId) { 499 modifyUserStateComponents(userId, false, true).enabledComponents.add(componentClassName); 500 } 501 502 boolean enableComponentLPw(String componentClassName, int userId) { 503 PackageUserState state = modifyUserStateComponents(userId, false, true); 504 boolean changed = state.disabledComponents != null 505 ? state.disabledComponents.remove(componentClassName) : false; 506 changed |= state.enabledComponents.add(componentClassName); 507 return changed; 508 } 509 510 boolean disableComponentLPw(String componentClassName, int userId) { 511 PackageUserState state = modifyUserStateComponents(userId, true, false); 512 boolean changed = state.enabledComponents != null 513 ? state.enabledComponents.remove(componentClassName) : false; 514 changed |= state.disabledComponents.add(componentClassName); 515 return changed; 516 } 517 518 boolean restoreComponentLPw(String componentClassName, int userId) { 519 PackageUserState state = modifyUserStateComponents(userId, true, true); 520 boolean changed = state.disabledComponents != null 521 ? state.disabledComponents.remove(componentClassName) : false; 522 changed |= state.enabledComponents != null 523 ? state.enabledComponents.remove(componentClassName) : false; 524 return changed; 525 } 526 527 int getCurrentEnabledStateLPr(String componentName, int userId) { 528 PackageUserState state = readUserState(userId); 529 if (state.enabledComponents != null && state.enabledComponents.contains(componentName)) { 530 return COMPONENT_ENABLED_STATE_ENABLED; 531 } else if (state.disabledComponents != null 532 && state.disabledComponents.contains(componentName)) { 533 return COMPONENT_ENABLED_STATE_DISABLED; 534 } else { 535 return COMPONENT_ENABLED_STATE_DEFAULT; 536 } 537 } 538 539 void removeUser(int userId) { 540 userState.delete(userId); 541 } 542 543 public int[] getNotInstalledUserIds() { 544 int count = 0; 545 int userStateCount = userState.size(); 546 for (int i = 0; i < userStateCount; i++) { 547 if (userState.valueAt(i).installed == false) { 548 count++; 549 } 550 } 551 if (count == 0) return EMPTY_INT_ARRAY; 552 int[] excludedUserIds = new int[count]; 553 int idx = 0; 554 for (int i = 0; i < userStateCount; i++) { 555 if (userState.valueAt(i).installed == false) { 556 excludedUserIds[idx++] = userState.keyAt(i); 557 } 558 } 559 return excludedUserIds; 560 } 561 562 IntentFilterVerificationInfo getIntentFilterVerificationInfo() { 563 return verificationInfo; 564 } 565 566 void setIntentFilterVerificationInfo(IntentFilterVerificationInfo info) { 567 verificationInfo = info; 568 } 569 570 // Returns a packed value as a long: 571 // 572 // high 'int'-sized word: link status: undefined/ask/never/always. 573 // low 'int'-sized word: relative priority among 'always' results. 574 long getDomainVerificationStatusForUser(int userId) { 575 PackageUserState state = readUserState(userId); 576 long result = (long) state.appLinkGeneration; 577 result |= ((long) state.domainVerificationStatus) << 32; 578 return result; 579 } 580 581 void setDomainVerificationStatusForUser(final int status, int generation, int userId) { 582 PackageUserState state = modifyUserState(userId); 583 state.domainVerificationStatus = status; 584 if (status == PackageManager.INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_ALWAYS) { 585 state.appLinkGeneration = generation; 586 } 587 } 588 589 void clearDomainVerificationStatusForUser(int userId) { 590 modifyUserState(userId).domainVerificationStatus = 591 PackageManager.INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_UNDEFINED; 592 } 593 594 protected void writeUsersInfoToProto(ProtoOutputStream proto, long fieldId) { 595 int count = userState.size(); 596 for (int i = 0; i < count; i++) { 597 final long userToken = proto.start(fieldId); 598 final int userId = userState.keyAt(i); 599 final PackageUserState state = userState.valueAt(i); 600 proto.write(PackageProto.UserInfoProto.ID, userId); 601 final int installType; 602 if (state.instantApp) { 603 installType = PackageProto.UserInfoProto.INSTANT_APP_INSTALL; 604 } else if (state.installed) { 605 installType = PackageProto.UserInfoProto.FULL_APP_INSTALL; 606 } else { 607 installType = PackageProto.UserInfoProto.NOT_INSTALLED_FOR_USER; 608 } 609 proto.write(PackageProto.UserInfoProto.INSTALL_TYPE, installType); 610 proto.write(PackageProto.UserInfoProto.IS_HIDDEN, state.hidden); 611 proto.write(PackageProto.UserInfoProto.IS_SUSPENDED, state.suspended); 612 proto.write(PackageProto.UserInfoProto.IS_STOPPED, state.stopped); 613 proto.write(PackageProto.UserInfoProto.IS_LAUNCHED, !state.notLaunched); 614 proto.write(PackageProto.UserInfoProto.ENABLED_STATE, state.enabled); 615 proto.write( 616 PackageProto.UserInfoProto.LAST_DISABLED_APP_CALLER, 617 state.lastDisableAppCaller); 618 proto.end(userToken); 619 } 620 } 621} 622