PackageSettingBase.java revision d4041db120d7500e73e0132b03dfeffb84d402f5
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 private 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 /** UUID of {@link VolumeInfo} hosting this app */ 129 String volumeUuid; 130 131 IntentFilterVerificationInfo verificationInfo; 132 133 PackageSettingBase(String name, String realName, File codePath, File resourcePath, 134 String legacyNativeLibraryPathString, String primaryCpuAbiString, 135 String secondaryCpuAbiString, String cpuAbiOverrideString, 136 int pVersionCode, int pkgFlags, int pkgPrivateFlags, 137 String parentPackageName, List<String> childPackageNames) { 138 super(pkgFlags, pkgPrivateFlags); 139 this.name = name; 140 this.realName = realName; 141 this.parentPackageName = parentPackageName; 142 this.childPackageNames = (childPackageNames != null) 143 ? new ArrayList<>(childPackageNames) : null; 144 init(codePath, resourcePath, legacyNativeLibraryPathString, primaryCpuAbiString, 145 secondaryCpuAbiString, cpuAbiOverrideString, pVersionCode); 146 } 147 148 /** 149 * New instance of PackageSetting with one-level-deep cloning. 150 */ 151 @SuppressWarnings("unchecked") 152 PackageSettingBase(PackageSettingBase base) { 153 super(base); 154 155 name = base.name; 156 realName = base.realName; 157 codePath = base.codePath; 158 codePathString = base.codePathString; 159 resourcePath = base.resourcePath; 160 resourcePathString = base.resourcePathString; 161 legacyNativeLibraryPathString = base.legacyNativeLibraryPathString; 162 primaryCpuAbiString = base.primaryCpuAbiString; 163 secondaryCpuAbiString = base.secondaryCpuAbiString; 164 cpuAbiOverrideString = base.cpuAbiOverrideString; 165 timeStamp = base.timeStamp; 166 firstInstallTime = base.firstInstallTime; 167 lastUpdateTime = base.lastUpdateTime; 168 versionCode = base.versionCode; 169 170 uidError = base.uidError; 171 172 signatures = new PackageSignatures(base.signatures); 173 174 installPermissionsFixed = base.installPermissionsFixed; 175 userState.clear(); 176 for (int i=0; i<base.userState.size(); i++) { 177 userState.put(base.userState.keyAt(i), 178 new PackageUserState(base.userState.valueAt(i))); 179 } 180 installStatus = base.installStatus; 181 182 origPackage = base.origPackage; 183 184 installerPackageName = base.installerPackageName; 185 volumeUuid = base.volumeUuid; 186 187 keySetData = new PackageKeySetData(base.keySetData); 188 189 parentPackageName = base.parentPackageName; 190 childPackageNames = (base.childPackageNames != null) 191 ? new ArrayList<>(base.childPackageNames) : null; 192 } 193 194 void init(File codePath, File resourcePath, String legacyNativeLibraryPathString, 195 String primaryCpuAbiString, String secondaryCpuAbiString, 196 String cpuAbiOverrideString, int pVersionCode) { 197 this.codePath = codePath; 198 this.codePathString = codePath.toString(); 199 this.resourcePath = resourcePath; 200 this.resourcePathString = resourcePath.toString(); 201 this.legacyNativeLibraryPathString = legacyNativeLibraryPathString; 202 this.primaryCpuAbiString = primaryCpuAbiString; 203 this.secondaryCpuAbiString = secondaryCpuAbiString; 204 this.cpuAbiOverrideString = cpuAbiOverrideString; 205 this.versionCode = pVersionCode; 206 } 207 208 public void setInstallerPackageName(String packageName) { 209 installerPackageName = packageName; 210 } 211 212 public String getInstallerPackageName() { 213 return installerPackageName; 214 } 215 216 public void setVolumeUuid(String volumeUuid) { 217 this.volumeUuid = volumeUuid; 218 } 219 220 public String getVolumeUuid() { 221 return volumeUuid; 222 } 223 224 public void setInstallStatus(int newStatus) { 225 installStatus = newStatus; 226 } 227 228 public int getInstallStatus() { 229 return installStatus; 230 } 231 232 public void setTimeStamp(long newStamp) { 233 timeStamp = newStamp; 234 } 235 236 /** 237 * Make a shallow copy of this package settings. 238 */ 239 public void copyFrom(PackageSettingBase base) { 240 mPermissionsState.copyFrom(base.mPermissionsState); 241 primaryCpuAbiString = base.primaryCpuAbiString; 242 secondaryCpuAbiString = base.secondaryCpuAbiString; 243 cpuAbiOverrideString = base.cpuAbiOverrideString; 244 timeStamp = base.timeStamp; 245 firstInstallTime = base.firstInstallTime; 246 lastUpdateTime = base.lastUpdateTime; 247 signatures = base.signatures; 248 installPermissionsFixed = base.installPermissionsFixed; 249 userState.clear(); 250 for (int i=0; i<base.userState.size(); i++) { 251 userState.put(base.userState.keyAt(i), base.userState.valueAt(i)); 252 } 253 installStatus = base.installStatus; 254 keySetData = base.keySetData; 255 verificationInfo = base.verificationInfo; 256 installerPackageName = base.installerPackageName; 257 volumeUuid = base.volumeUuid; 258 } 259 260 private PackageUserState modifyUserState(int userId) { 261 PackageUserState state = userState.get(userId); 262 if (state == null) { 263 state = new PackageUserState(); 264 userState.put(userId, state); 265 } 266 return state; 267 } 268 269 public PackageUserState readUserState(int userId) { 270 PackageUserState state = userState.get(userId); 271 if (state != null) { 272 return state; 273 } 274 return DEFAULT_USER_STATE; 275 } 276 277 void setEnabled(int state, int userId, String callingPackage) { 278 PackageUserState st = modifyUserState(userId); 279 st.enabled = state; 280 st.lastDisableAppCaller = callingPackage; 281 } 282 283 int getEnabled(int userId) { 284 return readUserState(userId).enabled; 285 } 286 287 String getLastDisabledAppCaller(int userId) { 288 return readUserState(userId).lastDisableAppCaller; 289 } 290 291 void setInstalled(boolean inst, int userId) { 292 modifyUserState(userId).installed = inst; 293 } 294 295 boolean getInstalled(int userId) { 296 return readUserState(userId).installed; 297 } 298 299 boolean isAnyInstalled(int[] users) { 300 for (int user: users) { 301 if (readUserState(user).installed) { 302 return true; 303 } 304 } 305 return false; 306 } 307 308 int[] queryInstalledUsers(int[] users, boolean installed) { 309 int num = 0; 310 for (int user : users) { 311 if (getInstalled(user) == installed) { 312 num++; 313 } 314 } 315 int[] res = new int[num]; 316 num = 0; 317 for (int user : users) { 318 if (getInstalled(user) == installed) { 319 res[num] = user; 320 num++; 321 } 322 } 323 return res; 324 } 325 326 boolean getStopped(int userId) { 327 return readUserState(userId).stopped; 328 } 329 330 void setStopped(boolean stop, int userId) { 331 modifyUserState(userId).stopped = stop; 332 } 333 334 boolean getNotLaunched(int userId) { 335 return readUserState(userId).notLaunched; 336 } 337 338 void setNotLaunched(boolean stop, int userId) { 339 modifyUserState(userId).notLaunched = stop; 340 } 341 342 boolean getHidden(int userId) { 343 return readUserState(userId).hidden; 344 } 345 346 void setHidden(boolean hidden, int userId) { 347 modifyUserState(userId).hidden = hidden; 348 } 349 350 boolean getSuspended(int userId) { 351 return readUserState(userId).suspended; 352 } 353 354 void setSuspended(boolean suspended, int userId) { 355 modifyUserState(userId).suspended = suspended; 356 } 357 358 boolean getBlockUninstall(int userId) { 359 return readUserState(userId).blockUninstall; 360 } 361 362 void setBlockUninstall(boolean blockUninstall, int userId) { 363 modifyUserState(userId).blockUninstall = blockUninstall; 364 } 365 366 void setUserState(int userId, int enabled, boolean installed, boolean stopped, 367 boolean notLaunched, boolean hidden, boolean suspended, 368 String lastDisableAppCaller, ArraySet<String> enabledComponents, 369 ArraySet<String> disabledComponents, boolean blockUninstall, int domainVerifState, 370 int linkGeneration) { 371 PackageUserState state = modifyUserState(userId); 372 state.enabled = enabled; 373 state.installed = installed; 374 state.stopped = stopped; 375 state.notLaunched = notLaunched; 376 state.hidden = hidden; 377 state.suspended = suspended; 378 state.lastDisableAppCaller = lastDisableAppCaller; 379 state.enabledComponents = enabledComponents; 380 state.disabledComponents = disabledComponents; 381 state.blockUninstall = blockUninstall; 382 state.domainVerificationStatus = domainVerifState; 383 state.appLinkGeneration = linkGeneration; 384 } 385 386 ArraySet<String> getEnabledComponents(int userId) { 387 return readUserState(userId).enabledComponents; 388 } 389 390 ArraySet<String> getDisabledComponents(int userId) { 391 return readUserState(userId).disabledComponents; 392 } 393 394 void setEnabledComponents(ArraySet<String> components, int userId) { 395 modifyUserState(userId).enabledComponents = components; 396 } 397 398 void setDisabledComponents(ArraySet<String> components, int userId) { 399 modifyUserState(userId).disabledComponents = components; 400 } 401 402 void setEnabledComponentsCopy(ArraySet<String> components, int userId) { 403 modifyUserState(userId).enabledComponents = components != null 404 ? new ArraySet<String>(components) : null; 405 } 406 407 void setDisabledComponentsCopy(ArraySet<String> components, int userId) { 408 modifyUserState(userId).disabledComponents = components != null 409 ? new ArraySet<String>(components) : null; 410 } 411 412 PackageUserState modifyUserStateComponents(int userId, boolean disabled, boolean enabled) { 413 PackageUserState state = modifyUserState(userId); 414 if (disabled && state.disabledComponents == null) { 415 state.disabledComponents = new ArraySet<String>(1); 416 } 417 if (enabled && state.enabledComponents == null) { 418 state.enabledComponents = new ArraySet<String>(1); 419 } 420 return state; 421 } 422 423 void addDisabledComponent(String componentClassName, int userId) { 424 modifyUserStateComponents(userId, true, false).disabledComponents.add(componentClassName); 425 } 426 427 void addEnabledComponent(String componentClassName, int userId) { 428 modifyUserStateComponents(userId, false, true).enabledComponents.add(componentClassName); 429 } 430 431 boolean enableComponentLPw(String componentClassName, int userId) { 432 PackageUserState state = modifyUserStateComponents(userId, false, true); 433 boolean changed = state.disabledComponents != null 434 ? state.disabledComponents.remove(componentClassName) : false; 435 changed |= state.enabledComponents.add(componentClassName); 436 return changed; 437 } 438 439 boolean disableComponentLPw(String componentClassName, int userId) { 440 PackageUserState state = modifyUserStateComponents(userId, true, false); 441 boolean changed = state.enabledComponents != null 442 ? state.enabledComponents.remove(componentClassName) : false; 443 changed |= state.disabledComponents.add(componentClassName); 444 return changed; 445 } 446 447 boolean restoreComponentLPw(String componentClassName, int userId) { 448 PackageUserState state = modifyUserStateComponents(userId, true, true); 449 boolean changed = state.disabledComponents != null 450 ? state.disabledComponents.remove(componentClassName) : false; 451 changed |= state.enabledComponents != null 452 ? state.enabledComponents.remove(componentClassName) : false; 453 return changed; 454 } 455 456 int getCurrentEnabledStateLPr(String componentName, int userId) { 457 PackageUserState state = readUserState(userId); 458 if (state.enabledComponents != null && state.enabledComponents.contains(componentName)) { 459 return COMPONENT_ENABLED_STATE_ENABLED; 460 } else if (state.disabledComponents != null 461 && state.disabledComponents.contains(componentName)) { 462 return COMPONENT_ENABLED_STATE_DISABLED; 463 } else { 464 return COMPONENT_ENABLED_STATE_DEFAULT; 465 } 466 } 467 468 void removeUser(int userId) { 469 userState.delete(userId); 470 } 471 472 IntentFilterVerificationInfo getIntentFilterVerificationInfo() { 473 return verificationInfo; 474 } 475 476 void setIntentFilterVerificationInfo(IntentFilterVerificationInfo info) { 477 verificationInfo = info; 478 } 479 480 // Returns a packed value as a long: 481 // 482 // high 'int'-sized word: link status: undefined/ask/never/always. 483 // low 'int'-sized word: relative priority among 'always' results. 484 long getDomainVerificationStatusForUser(int userId) { 485 PackageUserState state = readUserState(userId); 486 long result = (long) state.appLinkGeneration; 487 result |= ((long) state.domainVerificationStatus) << 32; 488 return result; 489 } 490 491 void setDomainVerificationStatusForUser(final int status, int generation, int userId) { 492 PackageUserState state = modifyUserState(userId); 493 state.domainVerificationStatus = status; 494 if (status == PackageManager.INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_ALWAYS) { 495 state.appLinkGeneration = generation; 496 } 497 } 498 499 void clearDomainVerificationStatusForUser(int userId) { 500 modifyUserState(userId).domainVerificationStatus = 501 PackageManager.INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_UNDEFINED; 502 } 503} 504