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