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