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