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