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