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