PackageSettingBase.java revision ab53289c593aad60eddbe1ffc73402ac1f92c112
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; 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 */ 44abstract 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 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 int[] 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 int 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 PackageSettingBase origPackage; 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 int pVersionCode, int pkgFlags, int pkgPrivateFlags, 153 String parentPackageName, List<String> childPackageNames, 154 String[] usesStaticLibraries, int[] 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, int 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 /** 233 * Makes a shallow copy of the given package settings. 234 * 235 * NOTE: For some fields [such as keySetData, signatures, userState, verificationInfo, etc...], 236 * the original object is copied and a new one is not created. 237 */ 238 public void copyFrom(PackageSettingBase orig) { 239 super.copyFrom(orig); 240 doCopy(orig); 241 } 242 243 private void doCopy(PackageSettingBase orig) { 244 childPackageNames = (orig.childPackageNames != null) 245 ? new ArrayList<>(orig.childPackageNames) : null; 246 codePath = orig.codePath; 247 codePathString = orig.codePathString; 248 cpuAbiOverrideString = orig.cpuAbiOverrideString; 249 firstInstallTime = orig.firstInstallTime; 250 installPermissionsFixed = orig.installPermissionsFixed; 251 installStatus = orig.installStatus; 252 installerPackageName = orig.installerPackageName; 253 isOrphaned = orig.isOrphaned; 254 keySetData = orig.keySetData; 255 lastUpdateTime = orig.lastUpdateTime; 256 legacyNativeLibraryPathString = orig.legacyNativeLibraryPathString; 257 // Intentionally skip oldCodePaths; it's not relevant for copies 258 origPackage = orig.origPackage; 259 parentPackageName = orig.parentPackageName; 260 primaryCpuAbiString = orig.primaryCpuAbiString; 261 resourcePath = orig.resourcePath; 262 resourcePathString = orig.resourcePathString; 263 secondaryCpuAbiString = orig.secondaryCpuAbiString; 264 signatures = orig.signatures; 265 timeStamp = orig.timeStamp; 266 uidError = orig.uidError; 267 userState.clear(); 268 for (int i=0; i<orig.userState.size(); i++) { 269 userState.put(orig.userState.keyAt(i), orig.userState.valueAt(i)); 270 } 271 verificationInfo = orig.verificationInfo; 272 versionCode = orig.versionCode; 273 volumeUuid = orig.volumeUuid; 274 categoryHint = orig.categoryHint; 275 usesStaticLibraries = orig.usesStaticLibraries != null 276 ? Arrays.copyOf(orig.usesStaticLibraries, 277 orig.usesStaticLibraries.length) : null; 278 usesStaticLibrariesVersions = orig.usesStaticLibrariesVersions != null 279 ? Arrays.copyOf(orig.usesStaticLibrariesVersions, 280 orig.usesStaticLibrariesVersions.length) : null; 281 updateAvailable = orig.updateAvailable; 282 } 283 284 private PackageUserState modifyUserState(int userId) { 285 PackageUserState state = userState.get(userId); 286 if (state == null) { 287 state = new PackageUserState(); 288 userState.put(userId, state); 289 } 290 return state; 291 } 292 293 public PackageUserState readUserState(int userId) { 294 PackageUserState state = userState.get(userId); 295 if (state == null) { 296 return DEFAULT_USER_STATE; 297 } 298 state.categoryHint = categoryHint; 299 return state; 300 } 301 302 void setEnabled(int state, int userId, String callingPackage) { 303 PackageUserState st = modifyUserState(userId); 304 st.enabled = state; 305 st.lastDisableAppCaller = callingPackage; 306 } 307 308 int getEnabled(int userId) { 309 return readUserState(userId).enabled; 310 } 311 312 String getLastDisabledAppCaller(int userId) { 313 return readUserState(userId).lastDisableAppCaller; 314 } 315 316 void setInstalled(boolean inst, int userId) { 317 modifyUserState(userId).installed = inst; 318 } 319 320 boolean getInstalled(int userId) { 321 return readUserState(userId).installed; 322 } 323 324 int getInstallReason(int userId) { 325 return readUserState(userId).installReason; 326 } 327 328 void setInstallReason(int installReason, int userId) { 329 modifyUserState(userId).installReason = installReason; 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, int userId) { 402 modifyUserState(userId).suspended = suspended; 403 } 404 405 boolean getBlockUninstall(int userId) { 406 return readUserState(userId).blockUninstall; 407 } 408 409 void setBlockUninstall(boolean blockUninstall, int userId) { 410 modifyUserState(userId).blockUninstall = blockUninstall; 411 } 412 413 boolean getInstantApp(int userId) { 414 return readUserState(userId).instantApp; 415 } 416 417 void setInstantApp(boolean instantApp, int userId) { 418 modifyUserState(userId).instantApp = instantApp; 419 } 420 421 void setUserState(int userId, long ceDataInode, int enabled, boolean installed, boolean stopped, 422 boolean notLaunched, boolean hidden, boolean suspended, boolean instantApp, 423 String lastDisableAppCaller, ArraySet<String> enabledComponents, 424 ArraySet<String> disabledComponents, boolean blockUninstall, 425 int domainVerifState, int linkGeneration, int installReason) { 426 PackageUserState state = modifyUserState(userId); 427 state.ceDataInode = ceDataInode; 428 state.enabled = enabled; 429 state.installed = installed; 430 state.stopped = stopped; 431 state.notLaunched = notLaunched; 432 state.hidden = hidden; 433 state.suspended = suspended; 434 state.lastDisableAppCaller = lastDisableAppCaller; 435 state.enabledComponents = enabledComponents; 436 state.disabledComponents = disabledComponents; 437 state.blockUninstall = blockUninstall; 438 state.domainVerificationStatus = domainVerifState; 439 state.appLinkGeneration = linkGeneration; 440 state.installReason = installReason; 441 state.instantApp = instantApp; 442 } 443 444 ArraySet<String> getEnabledComponents(int userId) { 445 return readUserState(userId).enabledComponents; 446 } 447 448 ArraySet<String> getDisabledComponents(int userId) { 449 return readUserState(userId).disabledComponents; 450 } 451 452 void setEnabledComponents(ArraySet<String> components, int userId) { 453 modifyUserState(userId).enabledComponents = components; 454 } 455 456 void setDisabledComponents(ArraySet<String> components, int userId) { 457 modifyUserState(userId).disabledComponents = components; 458 } 459 460 void setEnabledComponentsCopy(ArraySet<String> components, int userId) { 461 modifyUserState(userId).enabledComponents = components != null 462 ? new ArraySet<String>(components) : null; 463 } 464 465 void setDisabledComponentsCopy(ArraySet<String> components, int userId) { 466 modifyUserState(userId).disabledComponents = components != null 467 ? new ArraySet<String>(components) : null; 468 } 469 470 PackageUserState modifyUserStateComponents(int userId, boolean disabled, boolean enabled) { 471 PackageUserState state = modifyUserState(userId); 472 if (disabled && state.disabledComponents == null) { 473 state.disabledComponents = new ArraySet<String>(1); 474 } 475 if (enabled && state.enabledComponents == null) { 476 state.enabledComponents = new ArraySet<String>(1); 477 } 478 return state; 479 } 480 481 void addDisabledComponent(String componentClassName, int userId) { 482 modifyUserStateComponents(userId, true, false).disabledComponents.add(componentClassName); 483 } 484 485 void addEnabledComponent(String componentClassName, int userId) { 486 modifyUserStateComponents(userId, false, true).enabledComponents.add(componentClassName); 487 } 488 489 boolean enableComponentLPw(String componentClassName, int userId) { 490 PackageUserState state = modifyUserStateComponents(userId, false, true); 491 boolean changed = state.disabledComponents != null 492 ? state.disabledComponents.remove(componentClassName) : false; 493 changed |= state.enabledComponents.add(componentClassName); 494 return changed; 495 } 496 497 boolean disableComponentLPw(String componentClassName, int userId) { 498 PackageUserState state = modifyUserStateComponents(userId, true, false); 499 boolean changed = state.enabledComponents != null 500 ? state.enabledComponents.remove(componentClassName) : false; 501 changed |= state.disabledComponents.add(componentClassName); 502 return changed; 503 } 504 505 boolean restoreComponentLPw(String componentClassName, int userId) { 506 PackageUserState state = modifyUserStateComponents(userId, true, true); 507 boolean changed = state.disabledComponents != null 508 ? state.disabledComponents.remove(componentClassName) : false; 509 changed |= state.enabledComponents != null 510 ? state.enabledComponents.remove(componentClassName) : false; 511 return changed; 512 } 513 514 int getCurrentEnabledStateLPr(String componentName, int userId) { 515 PackageUserState state = readUserState(userId); 516 if (state.enabledComponents != null && state.enabledComponents.contains(componentName)) { 517 return COMPONENT_ENABLED_STATE_ENABLED; 518 } else if (state.disabledComponents != null 519 && state.disabledComponents.contains(componentName)) { 520 return COMPONENT_ENABLED_STATE_DISABLED; 521 } else { 522 return COMPONENT_ENABLED_STATE_DEFAULT; 523 } 524 } 525 526 void removeUser(int userId) { 527 userState.delete(userId); 528 } 529 530 public int[] getNotInstalledUserIds() { 531 int count = 0; 532 int userStateCount = userState.size(); 533 for (int i = 0; i < userStateCount; i++) { 534 if (userState.valueAt(i).installed == false) { 535 count++; 536 } 537 } 538 if (count == 0) return EMPTY_INT_ARRAY; 539 int[] excludedUserIds = new int[count]; 540 int idx = 0; 541 for (int i = 0; i < userStateCount; i++) { 542 if (userState.valueAt(i).installed == false) { 543 excludedUserIds[idx++] = userState.keyAt(i); 544 } 545 } 546 return excludedUserIds; 547 } 548 549 IntentFilterVerificationInfo getIntentFilterVerificationInfo() { 550 return verificationInfo; 551 } 552 553 void setIntentFilterVerificationInfo(IntentFilterVerificationInfo info) { 554 verificationInfo = info; 555 } 556 557 // Returns a packed value as a long: 558 // 559 // high 'int'-sized word: link status: undefined/ask/never/always. 560 // low 'int'-sized word: relative priority among 'always' results. 561 long getDomainVerificationStatusForUser(int userId) { 562 PackageUserState state = readUserState(userId); 563 long result = (long) state.appLinkGeneration; 564 result |= ((long) state.domainVerificationStatus) << 32; 565 return result; 566 } 567 568 void setDomainVerificationStatusForUser(final int status, int generation, int userId) { 569 PackageUserState state = modifyUserState(userId); 570 state.domainVerificationStatus = status; 571 if (status == PackageManager.INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_ALWAYS) { 572 state.appLinkGeneration = generation; 573 } 574 } 575 576 void clearDomainVerificationStatusForUser(int userId) { 577 modifyUserState(userId).domainVerificationStatus = 578 PackageManager.INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_UNDEFINED; 579 } 580 581 protected void writeUsersInfoToProto(ProtoOutputStream proto, long fieldId) { 582 int count = userState.size(); 583 for (int i = 0; i < count; i++) { 584 final long userToken = proto.start(fieldId); 585 final int userId = userState.keyAt(i); 586 final PackageUserState state = userState.valueAt(i); 587 proto.write(PackageProto.UserInfoProto.ID, userId); 588 final int installType; 589 if (state.instantApp) { 590 installType = PackageProto.UserInfoProto.INSTANT_APP_INSTALL; 591 } else if (state.installed) { 592 installType = PackageProto.UserInfoProto.FULL_APP_INSTALL; 593 } else { 594 installType = PackageProto.UserInfoProto.NOT_INSTALLED_FOR_USER; 595 } 596 proto.write(PackageProto.UserInfoProto.INSTALL_TYPE, installType); 597 proto.write(PackageProto.UserInfoProto.IS_HIDDEN, state.hidden); 598 proto.write(PackageProto.UserInfoProto.IS_SUSPENDED, state.suspended); 599 proto.write(PackageProto.UserInfoProto.IS_STOPPED, state.stopped); 600 proto.write(PackageProto.UserInfoProto.IS_LAUNCHED, !state.notLaunched); 601 proto.write(PackageProto.UserInfoProto.ENABLED_STATE, state.enabled); 602 proto.write( 603 PackageProto.UserInfoProto.LAST_DISABLED_APP_CALLER, 604 state.lastDisableAppCaller); 605 proto.end(userToken); 606 } 607 } 608} 609