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