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