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