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