1 /* 2 * Copyright (C) 2021 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.INSTALL_FAILED_ALREADY_EXISTS; 22 import static android.content.pm.PackageManager.INSTALL_FAILED_BAD_PERMISSION_GROUP; 23 import static android.content.pm.PackageManager.INSTALL_FAILED_DUPLICATE_PACKAGE; 24 import static android.content.pm.PackageManager.INSTALL_FAILED_DUPLICATE_PERMISSION; 25 import static android.content.pm.PackageManager.INSTALL_FAILED_DUPLICATE_PERMISSION_GROUP; 26 import static android.content.pm.PackageManager.INSTALL_FAILED_INSUFFICIENT_STORAGE; 27 import static android.content.pm.PackageManager.INSTALL_FAILED_INTERNAL_ERROR; 28 import static android.content.pm.PackageManager.INSTALL_FAILED_INVALID_APK; 29 import static android.content.pm.PackageManager.INSTALL_FAILED_INVALID_INSTALL_LOCATION; 30 import static android.content.pm.PackageManager.INSTALL_FAILED_PACKAGE_CHANGED; 31 import static android.content.pm.PackageManager.INSTALL_FAILED_SESSION_INVALID; 32 import static android.content.pm.PackageManager.INSTALL_FAILED_TEST_ONLY; 33 import static android.content.pm.PackageManager.INSTALL_FAILED_UID_CHANGED; 34 import static android.content.pm.PackageManager.INSTALL_FAILED_UPDATE_INCOMPATIBLE; 35 import static android.content.pm.PackageManager.INSTALL_REASON_DEVICE_RESTORE; 36 import static android.content.pm.PackageManager.INSTALL_REASON_DEVICE_SETUP; 37 import static android.content.pm.PackageManager.INSTALL_SUCCEEDED; 38 import static android.content.pm.PackageManager.UNINSTALL_REASON_UNKNOWN; 39 import static android.content.pm.SigningDetails.SignatureSchemeVersion.SIGNING_BLOCK_V4; 40 import static android.content.pm.parsing.ApkLiteParseUtils.isApkFile; 41 import static android.os.PowerExemptionManager.REASON_PACKAGE_REPLACED; 42 import static android.os.Trace.TRACE_TAG_PACKAGE_MANAGER; 43 import static android.os.incremental.IncrementalManager.isIncrementalPath; 44 import static android.os.storage.StorageManager.FLAG_STORAGE_CE; 45 import static android.os.storage.StorageManager.FLAG_STORAGE_DE; 46 import static android.os.storage.StorageManager.FLAG_STORAGE_EXTERNAL; 47 48 import static com.android.server.pm.InstructionSets.getAppDexInstructionSets; 49 import static com.android.server.pm.InstructionSets.getDexCodeInstructionSet; 50 import static com.android.server.pm.InstructionSets.getPreferredInstructionSet; 51 import static com.android.server.pm.PackageManagerService.DEBUG_BACKUP; 52 import static com.android.server.pm.PackageManagerService.DEBUG_COMPRESSION; 53 import static com.android.server.pm.PackageManagerService.DEBUG_INSTALL; 54 import static com.android.server.pm.PackageManagerService.DEBUG_PACKAGE_SCANNING; 55 import static com.android.server.pm.PackageManagerService.DEBUG_REMOVE; 56 import static com.android.server.pm.PackageManagerService.DEBUG_UPGRADE; 57 import static com.android.server.pm.PackageManagerService.DEBUG_VERIFY; 58 import static com.android.server.pm.PackageManagerService.EMPTY_INT_ARRAY; 59 import static com.android.server.pm.PackageManagerService.PLATFORM_PACKAGE_NAME; 60 import static com.android.server.pm.PackageManagerService.POST_INSTALL; 61 import static com.android.server.pm.PackageManagerService.PRECOMPILE_LAYOUTS; 62 import static com.android.server.pm.PackageManagerService.SCAN_AS_APK_IN_APEX; 63 import static com.android.server.pm.PackageManagerService.SCAN_AS_FULL_APP; 64 import static com.android.server.pm.PackageManagerService.SCAN_AS_INSTANT_APP; 65 import static com.android.server.pm.PackageManagerService.SCAN_AS_ODM; 66 import static com.android.server.pm.PackageManagerService.SCAN_AS_OEM; 67 import static com.android.server.pm.PackageManagerService.SCAN_AS_PRIVILEGED; 68 import static com.android.server.pm.PackageManagerService.SCAN_AS_PRODUCT; 69 import static com.android.server.pm.PackageManagerService.SCAN_AS_SYSTEM; 70 import static com.android.server.pm.PackageManagerService.SCAN_AS_SYSTEM_EXT; 71 import static com.android.server.pm.PackageManagerService.SCAN_AS_VENDOR; 72 import static com.android.server.pm.PackageManagerService.SCAN_AS_VIRTUAL_PRELOAD; 73 import static com.android.server.pm.PackageManagerService.SCAN_BOOTING; 74 import static com.android.server.pm.PackageManagerService.SCAN_DONT_KILL_APP; 75 import static com.android.server.pm.PackageManagerService.SCAN_DROP_CACHE; 76 import static com.android.server.pm.PackageManagerService.SCAN_FIRST_BOOT_OR_UPGRADE; 77 import static com.android.server.pm.PackageManagerService.SCAN_IGNORE_FROZEN; 78 import static com.android.server.pm.PackageManagerService.SCAN_INITIAL; 79 import static com.android.server.pm.PackageManagerService.SCAN_MOVE; 80 import static com.android.server.pm.PackageManagerService.SCAN_NEW_INSTALL; 81 import static com.android.server.pm.PackageManagerService.SCAN_NO_DEX; 82 import static com.android.server.pm.PackageManagerService.SCAN_REQUIRE_KNOWN; 83 import static com.android.server.pm.PackageManagerService.SCAN_UPDATE_SIGNATURE; 84 import static com.android.server.pm.PackageManagerService.TAG; 85 import static com.android.server.pm.PackageManagerServiceUtils.comparePackageSignatures; 86 import static com.android.server.pm.PackageManagerServiceUtils.compareSignatures; 87 import static com.android.server.pm.PackageManagerServiceUtils.compressedFileExists; 88 import static com.android.server.pm.PackageManagerServiceUtils.deriveAbiOverride; 89 import static com.android.server.pm.PackageManagerServiceUtils.logCriticalInfo; 90 import static com.android.server.pm.SharedUidMigration.BEST_EFFORT; 91 92 import android.annotation.NonNull; 93 import android.annotation.Nullable; 94 import android.annotation.UserIdInt; 95 import android.app.AppOpsManager; 96 import android.app.ApplicationPackageManager; 97 import android.app.BroadcastOptions; 98 import android.app.backup.IBackupManager; 99 import android.content.ContentResolver; 100 import android.content.Context; 101 import android.content.Intent; 102 import android.content.IntentSender; 103 import android.content.pm.ApplicationInfo; 104 import android.content.pm.DataLoaderType; 105 import android.content.pm.IPackageInstallObserver2; 106 import android.content.pm.PackageChangeEvent; 107 import android.content.pm.PackageInfo; 108 import android.content.pm.PackageInfoLite; 109 import android.content.pm.PackageInstaller; 110 import android.content.pm.PackageManager; 111 import android.content.pm.PermissionGroupInfo; 112 import android.content.pm.PermissionInfo; 113 import android.content.pm.SharedLibraryInfo; 114 import android.content.pm.Signature; 115 import android.content.pm.SigningDetails; 116 import android.content.pm.VerifierInfo; 117 import android.content.pm.dex.DexMetadataHelper; 118 import android.content.pm.parsing.result.ParseResult; 119 import android.content.pm.parsing.result.ParseTypeImpl; 120 import android.net.Uri; 121 import android.os.Binder; 122 import android.os.Build; 123 import android.os.Bundle; 124 import android.os.Environment; 125 import android.os.Message; 126 import android.os.Process; 127 import android.os.RemoteException; 128 import android.os.SystemProperties; 129 import android.os.Trace; 130 import android.os.UserHandle; 131 import android.os.UserManager; 132 import android.os.incremental.IncrementalManager; 133 import android.os.incremental.IncrementalStorage; 134 import android.os.storage.StorageManager; 135 import android.os.storage.VolumeInfo; 136 import android.stats.storage.StorageEnums; 137 import android.util.ArrayMap; 138 import android.util.ArraySet; 139 import android.util.EventLog; 140 import android.util.Log; 141 import android.util.Pair; 142 import android.util.Slog; 143 import android.util.SparseArray; 144 145 import com.android.internal.annotations.GuardedBy; 146 import com.android.internal.content.F2fsUtils; 147 import com.android.internal.content.InstallLocationUtils; 148 import com.android.internal.security.VerityUtils; 149 import com.android.internal.util.ArrayUtils; 150 import com.android.internal.util.CollectionUtils; 151 import com.android.internal.util.FrameworkStatsLog; 152 import com.android.server.EventLogTags; 153 import com.android.server.pm.dex.ArtManagerService; 154 import com.android.server.pm.dex.DexManager; 155 import com.android.server.pm.dex.DexoptOptions; 156 import com.android.server.pm.dex.ViewCompiler; 157 import com.android.server.pm.parsing.PackageCacher; 158 import com.android.server.pm.parsing.PackageParser2; 159 import com.android.server.pm.parsing.pkg.AndroidPackage; 160 import com.android.server.pm.parsing.pkg.AndroidPackageUtils; 161 import com.android.server.pm.parsing.pkg.ParsedPackage; 162 import com.android.server.pm.permission.Permission; 163 import com.android.server.pm.permission.PermissionManagerServiceInternal; 164 import com.android.server.pm.pkg.PackageStateInternal; 165 import com.android.server.pm.pkg.component.ComponentMutateUtils; 166 import com.android.server.pm.pkg.component.ParsedInstrumentation; 167 import com.android.server.pm.pkg.component.ParsedPermission; 168 import com.android.server.pm.pkg.component.ParsedPermissionGroup; 169 import com.android.server.pm.pkg.parsing.ParsingPackageUtils; 170 import com.android.server.rollback.RollbackManagerInternal; 171 import com.android.server.utils.WatchedArrayMap; 172 import com.android.server.utils.WatchedLongSparseArray; 173 174 import dalvik.system.VMRuntime; 175 176 import java.io.File; 177 import java.io.FileInputStream; 178 import java.io.IOException; 179 import java.security.DigestException; 180 import java.security.DigestInputStream; 181 import java.security.MessageDigest; 182 import java.security.NoSuchAlgorithmException; 183 import java.security.PublicKey; 184 import java.security.cert.CertificateException; 185 import java.util.ArrayList; 186 import java.util.Arrays; 187 import java.util.Collections; 188 import java.util.List; 189 import java.util.Map; 190 import java.util.Set; 191 import java.util.concurrent.ExecutorService; 192 193 final class InstallPackageHelper { 194 private final PackageManagerService mPm; 195 private final AppDataHelper mAppDataHelper; 196 private final BroadcastHelper mBroadcastHelper; 197 private final RemovePackageHelper mRemovePackageHelper; 198 private final IncrementalManager mIncrementalManager; 199 private final ApexManager mApexManager; 200 private final DexManager mDexManager; 201 private final ArtManagerService mArtManagerService; 202 private final Context mContext; 203 private final PackageDexOptimizer mPackageDexOptimizer; 204 private final PackageAbiHelper mPackageAbiHelper; 205 private final ViewCompiler mViewCompiler; 206 private final SharedLibrariesImpl mSharedLibraries; 207 private final PackageManagerServiceInjector mInjector; 208 209 // TODO(b/198166813): remove PMS dependency InstallPackageHelper(PackageManagerService pm, AppDataHelper appDataHelper)210 InstallPackageHelper(PackageManagerService pm, AppDataHelper appDataHelper) { 211 mPm = pm; 212 mInjector = pm.mInjector; 213 mAppDataHelper = appDataHelper; 214 mBroadcastHelper = new BroadcastHelper(pm.mInjector); 215 mRemovePackageHelper = new RemovePackageHelper(pm); 216 mIncrementalManager = pm.mInjector.getIncrementalManager(); 217 mApexManager = pm.mInjector.getApexManager(); 218 mDexManager = pm.mInjector.getDexManager(); 219 mArtManagerService = pm.mInjector.getArtManagerService(); 220 mContext = pm.mInjector.getContext(); 221 mPackageDexOptimizer = pm.mInjector.getPackageDexOptimizer(); 222 mPackageAbiHelper = pm.mInjector.getAbiHelper(); 223 mViewCompiler = pm.mInjector.getViewCompiler(); 224 mSharedLibraries = pm.mInjector.getSharedLibrariesImpl(); 225 } 226 InstallPackageHelper(PackageManagerService pm)227 InstallPackageHelper(PackageManagerService pm) { 228 this(pm, new AppDataHelper(pm)); 229 } 230 231 /** 232 * Commits the package scan and modifies system state. 233 * <p><em>WARNING:</em> The method may throw an exception in the middle 234 * of committing the package, leaving the system in an inconsistent state. 235 * This needs to be fixed so, once we get to this point, no errors are 236 * possible and the system is not left in an inconsistent state. 237 */ 238 @GuardedBy({"mPm.mLock", "mPm.mInstallLock"}) commitReconciledScanResultLocked( @onNull ReconciledPackage reconciledPkg, int[] allUsers)239 public AndroidPackage commitReconciledScanResultLocked( 240 @NonNull ReconciledPackage reconciledPkg, int[] allUsers) { 241 final ScanResult result = reconciledPkg.mScanResult; 242 final ScanRequest request = result.mRequest; 243 // TODO(b/135203078): Move this even further away 244 ParsedPackage parsedPackage = request.mParsedPackage; 245 if ("android".equals(parsedPackage.getPackageName())) { 246 // TODO(b/135203078): Move this to initial parse 247 parsedPackage.setVersionCode(mPm.getSdkVersion()) 248 .setVersionCodeMajor(0); 249 } 250 251 final AndroidPackage oldPkg = request.mOldPkg; 252 final @ParsingPackageUtils.ParseFlags int parseFlags = request.mParseFlags; 253 final @PackageManagerService.ScanFlags int scanFlags = request.mScanFlags; 254 final PackageSetting oldPkgSetting = request.mOldPkgSetting; 255 final PackageSetting originalPkgSetting = request.mOriginalPkgSetting; 256 final UserHandle user = request.mUser; 257 final String realPkgName = request.mRealPkgName; 258 final List<String> changedAbiCodePath = result.mChangedAbiCodePath; 259 final PackageSetting pkgSetting; 260 if (request.mPkgSetting != null) { 261 SharedUserSetting requestSharedUserSetting = mPm.mSettings.getSharedUserSettingLPr( 262 request.mPkgSetting); 263 SharedUserSetting resultSharedUserSetting = mPm.mSettings.getSharedUserSettingLPr( 264 result.mPkgSetting); 265 if (requestSharedUserSetting != null 266 && requestSharedUserSetting != resultSharedUserSetting) { 267 // shared user changed, remove from old shared user 268 requestSharedUserSetting.removePackage(request.mPkgSetting); 269 // Prune unused SharedUserSetting 270 if (mPm.mSettings.checkAndPruneSharedUserLPw(requestSharedUserSetting, false)) { 271 // Set the app ID in removed info for UID_REMOVED broadcasts 272 if (reconciledPkg.mInstallResult != null 273 && reconciledPkg.mInstallResult.mRemovedInfo != null) { 274 reconciledPkg.mInstallResult.mRemovedInfo.mRemovedAppId = 275 requestSharedUserSetting.mAppId; 276 } 277 } 278 } 279 } 280 if (result.mExistingSettingCopied) { 281 pkgSetting = request.mPkgSetting; 282 pkgSetting.updateFrom(result.mPkgSetting); 283 } else { 284 pkgSetting = result.mPkgSetting; 285 if (originalPkgSetting != null) { 286 mPm.mSettings.addRenamedPackageLPw( 287 AndroidPackageUtils.getRealPackageOrNull(parsedPackage), 288 originalPkgSetting.getPackageName()); 289 mPm.mTransferredPackages.add(originalPkgSetting.getPackageName()); 290 } else { 291 mPm.mSettings.removeRenamedPackageLPw(parsedPackage.getPackageName()); 292 } 293 } 294 SharedUserSetting sharedUserSetting = mPm.mSettings.getSharedUserSettingLPr(pkgSetting); 295 if (sharedUserSetting != null) { 296 sharedUserSetting.addPackage(pkgSetting); 297 if (parsedPackage.isLeavingSharedUid() 298 && SharedUidMigration.applyStrategy(BEST_EFFORT) 299 && sharedUserSetting.isSingleUser()) { 300 // Attempt the transparent shared UID migration 301 mPm.mSettings.convertSharedUserSettingsLPw(sharedUserSetting); 302 } 303 } 304 if (reconciledPkg.mInstallArgs != null 305 && reconciledPkg.mInstallArgs.mForceQueryableOverride) { 306 pkgSetting.setForceQueryableOverride(true); 307 } 308 309 // If this is part of a standard install, set the initiating package name, else rely on 310 // previous device state. 311 if (reconciledPkg.mInstallArgs != null) { 312 InstallSource installSource = reconciledPkg.mInstallArgs.mInstallSource; 313 if (installSource.initiatingPackageName != null) { 314 final PackageSetting ips = mPm.mSettings.getPackageLPr( 315 installSource.initiatingPackageName); 316 if (ips != null) { 317 installSource = installSource.setInitiatingPackageSignatures( 318 ips.getSignatures()); 319 } 320 } 321 pkgSetting.setInstallSource(installSource); 322 } 323 324 // TODO(toddke): Consider a method specifically for modifying the Package object 325 // post scan; or, moving this stuff out of the Package object since it has nothing 326 // to do with the package on disk. 327 // We need to have this here because addUserToSettingLPw() is sometimes responsible 328 // for creating the application ID. If we did this earlier, we would be saving the 329 // correct ID. 330 parsedPackage.setUid(pkgSetting.getAppId()); 331 final AndroidPackage pkg = parsedPackage.hideAsFinal(); 332 333 mPm.mSettings.writeUserRestrictionsLPw(pkgSetting, oldPkgSetting); 334 335 if (realPkgName != null) { 336 mPm.mTransferredPackages.add(pkg.getPackageName()); 337 } 338 339 if (reconciledPkg.mCollectedSharedLibraryInfos != null 340 || (oldPkgSetting != null && oldPkgSetting.getUsesLibraryInfos() != null)) { 341 // Reconcile if the new package or the old package uses shared libraries. 342 // It is possible that the old package uses shared libraries but the new one doesn't. 343 mSharedLibraries.executeSharedLibrariesUpdateLPw(pkg, pkgSetting, null, null, 344 reconciledPkg.mCollectedSharedLibraryInfos, allUsers); 345 } 346 347 final KeySetManagerService ksms = mPm.mSettings.getKeySetManagerService(); 348 if (reconciledPkg.mRemoveAppKeySetData) { 349 ksms.removeAppKeySetDataLPw(pkg.getPackageName()); 350 } 351 if (reconciledPkg.mSharedUserSignaturesChanged) { 352 sharedUserSetting.signaturesChanged = Boolean.TRUE; 353 sharedUserSetting.signatures.mSigningDetails = reconciledPkg.mSigningDetails; 354 } 355 pkgSetting.setSigningDetails(reconciledPkg.mSigningDetails); 356 357 if (changedAbiCodePath != null && changedAbiCodePath.size() > 0) { 358 for (int i = changedAbiCodePath.size() - 1; i >= 0; --i) { 359 final String codePathString = changedAbiCodePath.get(i); 360 try { 361 mPm.mInstaller.rmdex(codePathString, 362 getDexCodeInstructionSet(getPreferredInstructionSet())); 363 } catch (Installer.InstallerException ignored) { 364 } 365 } 366 } 367 368 final int userId = user == null ? 0 : user.getIdentifier(); 369 // Modify state for the given package setting 370 commitPackageSettings(pkg, oldPkg, pkgSetting, oldPkgSetting, scanFlags, 371 (parseFlags & ParsingPackageUtils.PARSE_CHATTY) != 0 /*chatty*/, reconciledPkg); 372 if (pkgSetting.getInstantApp(userId)) { 373 mPm.mInstantAppRegistry.addInstantApp(userId, pkgSetting.getAppId()); 374 } 375 376 if (!IncrementalManager.isIncrementalPath(pkgSetting.getPathString())) { 377 pkgSetting.setLoadingProgress(1f); 378 } 379 380 return pkg; 381 } 382 383 /** 384 * Adds a scanned package to the system. When this method is finished, the package will 385 * be available for query, resolution, etc... 386 */ commitPackageSettings(@onNull AndroidPackage pkg, @Nullable AndroidPackage oldPkg, @NonNull PackageSetting pkgSetting, @Nullable PackageSetting oldPkgSetting, final @PackageManagerService.ScanFlags int scanFlags, boolean chatty, ReconciledPackage reconciledPkg)387 private void commitPackageSettings(@NonNull AndroidPackage pkg, @Nullable AndroidPackage oldPkg, 388 @NonNull PackageSetting pkgSetting, @Nullable PackageSetting oldPkgSetting, 389 final @PackageManagerService.ScanFlags int scanFlags, boolean chatty, 390 ReconciledPackage reconciledPkg) { 391 final String pkgName = pkg.getPackageName(); 392 if (mPm.mCustomResolverComponentName != null 393 && mPm.mCustomResolverComponentName.getPackageName().equals(pkg.getPackageName())) { 394 mPm.setUpCustomResolverActivity(pkg, pkgSetting); 395 } 396 397 if (pkg.getPackageName().equals("android")) { 398 mPm.setPlatformPackage(pkg, pkgSetting); 399 } 400 401 ArrayList<AndroidPackage> clientLibPkgs = null; 402 // writer 403 synchronized (mPm.mLock) { 404 if (!ArrayUtils.isEmpty(reconciledPkg.mAllowedSharedLibraryInfos)) { 405 for (SharedLibraryInfo info : reconciledPkg.mAllowedSharedLibraryInfos) { 406 mSharedLibraries.commitSharedLibraryInfoLPw(info); 407 } 408 final Map<String, AndroidPackage> combinedSigningDetails = 409 reconciledPkg.getCombinedAvailablePackages(); 410 try { 411 // Shared libraries for the package need to be updated. 412 mSharedLibraries.updateSharedLibrariesLPw(pkg, pkgSetting, null, null, 413 combinedSigningDetails); 414 } catch (PackageManagerException e) { 415 Slog.e(TAG, "updateSharedLibrariesLPr failed: ", e); 416 } 417 // Update all applications that use this library. Skip when booting 418 // since this will be done after all packages are scaned. 419 if ((scanFlags & SCAN_BOOTING) == 0) { 420 clientLibPkgs = mSharedLibraries.updateAllSharedLibrariesLPw(pkg, pkgSetting, 421 combinedSigningDetails); 422 } 423 } 424 } 425 if (reconciledPkg.mInstallResult != null) { 426 reconciledPkg.mInstallResult.mLibraryConsumers = clientLibPkgs; 427 } 428 429 if ((scanFlags & SCAN_BOOTING) != 0) { 430 // No apps can run during boot scan, so they don't need to be frozen 431 } else if ((scanFlags & SCAN_DONT_KILL_APP) != 0) { 432 // Caller asked to not kill app, so it's probably not frozen 433 } else if ((scanFlags & SCAN_IGNORE_FROZEN) != 0) { 434 // Caller asked us to ignore frozen check for some reason; they 435 // probably didn't know the package name 436 } else { 437 // We're doing major surgery on this package, so it better be frozen 438 // right now to keep it from launching 439 mPm.snapshotComputer().checkPackageFrozen(pkgName); 440 } 441 442 final boolean isReplace = 443 reconciledPkg.mPrepareResult != null && reconciledPkg.mPrepareResult.mReplace; 444 // Also need to kill any apps that are dependent on the library, except the case of 445 // installation of new version static shared library. 446 if (clientLibPkgs != null) { 447 if (pkg.getStaticSharedLibName() == null || isReplace) { 448 for (int i = 0; i < clientLibPkgs.size(); i++) { 449 AndroidPackage clientPkg = clientLibPkgs.get(i); 450 mPm.killApplication(clientPkg.getPackageName(), 451 clientPkg.getUid(), "update lib"); 452 } 453 } 454 } 455 456 // writer 457 Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "updateSettings"); 458 459 synchronized (mPm.mLock) { 460 // We don't expect installation to fail beyond this point 461 // Add the new setting to mSettings 462 mPm.mSettings.insertPackageSettingLPw(pkgSetting, pkg); 463 // Add the new setting to mPackages 464 mPm.mPackages.put(pkg.getPackageName(), pkg); 465 if ((scanFlags & SCAN_AS_APK_IN_APEX) != 0) { 466 mApexManager.registerApkInApex(pkg); 467 } 468 469 // Add the package's KeySets to the global KeySetManagerService 470 KeySetManagerService ksms = mPm.mSettings.getKeySetManagerService(); 471 ksms.addScannedPackageLPw(pkg); 472 473 final Computer snapshot = mPm.snapshotComputer(); 474 mPm.mComponentResolver.addAllComponents(pkg, chatty, mPm.mSetupWizardPackage, snapshot); 475 mPm.mAppsFilter.addPackage(snapshot, pkgSetting, isReplace); 476 mPm.addAllPackageProperties(pkg); 477 478 if (oldPkgSetting == null || oldPkgSetting.getPkg() == null) { 479 mPm.mDomainVerificationManager.addPackage(pkgSetting); 480 } else { 481 mPm.mDomainVerificationManager.migrateState(oldPkgSetting, pkgSetting); 482 } 483 484 int collectionSize = ArrayUtils.size(pkg.getInstrumentations()); 485 StringBuilder r = null; 486 int i; 487 for (i = 0; i < collectionSize; i++) { 488 ParsedInstrumentation a = pkg.getInstrumentations().get(i); 489 ComponentMutateUtils.setPackageName(a, pkg.getPackageName()); 490 mPm.addInstrumentation(a.getComponentName(), a); 491 if (chatty) { 492 if (r == null) { 493 r = new StringBuilder(256); 494 } else { 495 r.append(' '); 496 } 497 r.append(a.getName()); 498 } 499 } 500 if (r != null) { 501 if (DEBUG_PACKAGE_SCANNING) Log.d(TAG, " Instrumentation: " + r); 502 } 503 504 final List<String> protectedBroadcasts = pkg.getProtectedBroadcasts(); 505 if (!protectedBroadcasts.isEmpty()) { 506 synchronized (mPm.mProtectedBroadcasts) { 507 mPm.mProtectedBroadcasts.addAll(protectedBroadcasts); 508 } 509 } 510 511 mPm.mPermissionManager.onPackageAdded(pkg, 512 (scanFlags & SCAN_AS_INSTANT_APP) != 0, oldPkg); 513 } 514 515 Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER); 516 } 517 installExistingPackageAsUser(@ullable String packageName, @UserIdInt int userId, @PackageManager.InstallFlags int installFlags, @PackageManager.InstallReason int installReason, @Nullable List<String> allowlistedRestrictedPermissions, @Nullable IntentSender intentSender)518 public int installExistingPackageAsUser(@Nullable String packageName, @UserIdInt int userId, 519 @PackageManager.InstallFlags int installFlags, 520 @PackageManager.InstallReason int installReason, 521 @Nullable List<String> allowlistedRestrictedPermissions, 522 @Nullable IntentSender intentSender) { 523 if (DEBUG_INSTALL) { 524 Log.v(TAG, "installExistingPackageAsUser package=" + packageName + " userId=" + userId 525 + " installFlags=" + installFlags + " installReason=" + installReason 526 + " allowlistedRestrictedPermissions=" + allowlistedRestrictedPermissions); 527 } 528 529 final int callingUid = Binder.getCallingUid(); 530 if (mContext.checkCallingOrSelfPermission(android.Manifest.permission.INSTALL_PACKAGES) 531 != PackageManager.PERMISSION_GRANTED 532 && mContext.checkCallingOrSelfPermission( 533 android.Manifest.permission.INSTALL_EXISTING_PACKAGES) 534 != PackageManager.PERMISSION_GRANTED) { 535 throw new SecurityException("Neither user " + callingUid + " nor current process has " 536 + android.Manifest.permission.INSTALL_PACKAGES + "."); 537 } 538 PackageSetting pkgSetting; 539 final Computer preLockSnapshot = mPm.snapshotComputer(); 540 preLockSnapshot.enforceCrossUserPermission(callingUid, userId, 541 true /* requireFullPermission */, true /* checkShell */, 542 "installExistingPackage for user " + userId); 543 if (mPm.isUserRestricted(userId, UserManager.DISALLOW_INSTALL_APPS)) { 544 return PackageManager.INSTALL_FAILED_USER_RESTRICTED; 545 } 546 547 final long callingId = Binder.clearCallingIdentity(); 548 try { 549 boolean installed = false; 550 final boolean instantApp = 551 (installFlags & PackageManager.INSTALL_INSTANT_APP) != 0; 552 final boolean fullApp = 553 (installFlags & PackageManager.INSTALL_FULL_APP) != 0; 554 555 // writer 556 synchronized (mPm.mLock) { 557 final Computer snapshot = mPm.snapshotComputer(); 558 pkgSetting = mPm.mSettings.getPackageLPr(packageName); 559 if (pkgSetting == null) { 560 return PackageManager.INSTALL_FAILED_INVALID_URI; 561 } 562 if (!snapshot.canViewInstantApps(callingUid, UserHandle.getUserId(callingUid))) { 563 // only allow the existing package to be used if it's installed as a full 564 // application for at least one user 565 boolean installAllowed = false; 566 for (int checkUserId : mPm.mUserManager.getUserIds()) { 567 installAllowed = !pkgSetting.getInstantApp(checkUserId); 568 if (installAllowed) { 569 break; 570 } 571 } 572 if (!installAllowed) { 573 return PackageManager.INSTALL_FAILED_INVALID_URI; 574 } 575 } 576 if (!pkgSetting.getInstalled(userId)) { 577 pkgSetting.setInstalled(true, userId); 578 pkgSetting.setHidden(false, userId); 579 pkgSetting.setInstallReason(installReason, userId); 580 pkgSetting.setUninstallReason(PackageManager.UNINSTALL_REASON_UNKNOWN, userId); 581 pkgSetting.setFirstInstallTime(System.currentTimeMillis(), userId); 582 mPm.mSettings.writePackageRestrictionsLPr(userId); 583 mPm.mSettings.writeKernelMappingLPr(pkgSetting); 584 installed = true; 585 } else if (fullApp && pkgSetting.getInstantApp(userId)) { 586 // upgrade app from instant to full; we don't allow app downgrade 587 installed = true; 588 } 589 ScanPackageUtils.setInstantAppForUser(mPm.mInjector, pkgSetting, userId, instantApp, 590 fullApp); 591 } 592 593 if (installed) { 594 if (pkgSetting.getPkg() != null) { 595 final PermissionManagerServiceInternal.PackageInstalledParams.Builder 596 permissionParamsBuilder = 597 new PermissionManagerServiceInternal.PackageInstalledParams.Builder(); 598 if ((installFlags & PackageManager.INSTALL_ALL_WHITELIST_RESTRICTED_PERMISSIONS) 599 != 0) { 600 permissionParamsBuilder.setAllowlistedRestrictedPermissions( 601 pkgSetting.getPkg().getRequestedPermissions()); 602 } 603 mPm.mPermissionManager.onPackageInstalled(pkgSetting.getPkg(), 604 Process.INVALID_UID /* previousAppId */, 605 permissionParamsBuilder.build(), userId); 606 607 synchronized (mPm.mInstallLock) { 608 // We don't need to freeze for a brand new install 609 mAppDataHelper.prepareAppDataAfterInstallLIF(pkgSetting.getPkg()); 610 } 611 } 612 mPm.sendPackageAddedForUser(mPm.snapshotComputer(), packageName, pkgSetting, userId, 613 DataLoaderType.NONE); 614 synchronized (mPm.mLock) { 615 mPm.updateSequenceNumberLP(pkgSetting, new int[]{ userId }); 616 } 617 // start async restore with no post-install since we finish install here 618 PackageInstalledInfo res = new PackageInstalledInfo( 619 PackageManager.INSTALL_SUCCEEDED); 620 res.mPkg = pkgSetting.getPkg(); 621 res.mNewUsers = new int[]{ userId }; 622 623 PostInstallData postInstallData = 624 new PostInstallData(null, res, () -> { 625 mPm.restorePermissionsAndUpdateRolesForNewUserInstall(packageName, 626 userId); 627 if (intentSender != null) { 628 onRestoreComplete(res.mReturnCode, mContext, intentSender); 629 } 630 }); 631 restoreAndPostInstall(userId, res, postInstallData); 632 } 633 } finally { 634 Binder.restoreCallingIdentity(callingId); 635 } 636 637 return PackageManager.INSTALL_SUCCEEDED; 638 } 639 onRestoreComplete(int returnCode, Context context, IntentSender target)640 private static void onRestoreComplete(int returnCode, Context context, IntentSender target) { 641 Intent fillIn = new Intent(); 642 fillIn.putExtra(PackageInstaller.EXTRA_STATUS, 643 PackageManager.installStatusToPublicStatus(returnCode)); 644 try { 645 final BroadcastOptions options = BroadcastOptions.makeBasic(); 646 options.setPendingIntentBackgroundActivityLaunchAllowed(false); 647 target.sendIntent(context, 0, fillIn, null /* onFinished*/, null /* handler */, 648 null /* requiredPermission */, options.toBundle()); 649 } catch (IntentSender.SendIntentException ignored) { 650 } 651 } 652 653 /** @param data Post-install is performed only if this is non-null. */ restoreAndPostInstall( int userId, PackageInstalledInfo res, @Nullable PostInstallData data)654 public void restoreAndPostInstall( 655 int userId, PackageInstalledInfo res, @Nullable PostInstallData data) { 656 if (DEBUG_INSTALL) { 657 Log.v(TAG, "restoreAndPostInstall userId=" + userId + " package=" + res.mPkg); 658 } 659 660 // A restore should be requested at this point if (a) the install 661 // succeeded, (b) the operation is not an update. 662 final boolean update = res.mRemovedInfo != null 663 && res.mRemovedInfo.mRemovedPackage != null; 664 boolean doRestore = !update && res.mPkg != null; 665 666 // Set up the post-install work request bookkeeping. This will be used 667 // and cleaned up by the post-install event handling regardless of whether 668 // there's a restore pass performed. Token values are >= 1. 669 int token; 670 if (mPm.mNextInstallToken < 0) mPm.mNextInstallToken = 1; 671 token = mPm.mNextInstallToken++; 672 if (data != null) { 673 mPm.mRunningInstalls.put(token, data); 674 } else if (DEBUG_INSTALL) { 675 Log.v(TAG, "No post-install required for " + token); 676 } 677 678 if (DEBUG_INSTALL) Log.v(TAG, "+ starting restore round-trip " + token); 679 680 if (res.mReturnCode == PackageManager.INSTALL_SUCCEEDED && doRestore) { 681 // Pass responsibility to the Backup Manager. It will perform a 682 // restore if appropriate, then pass responsibility back to the 683 // Package Manager to run the post-install observer callbacks 684 // and broadcasts. 685 if (res.mFreezer != null) { 686 res.mFreezer.close(); 687 } 688 doRestore = performBackupManagerRestore(userId, token, res); 689 } 690 691 // If this is an update to a package that might be potentially downgraded, then we 692 // need to check with the rollback manager whether there's any userdata that might 693 // need to be snapshotted or restored for the package. 694 // 695 // TODO(narayan): Get this working for cases where userId == UserHandle.USER_ALL. 696 if (res.mReturnCode == PackageManager.INSTALL_SUCCEEDED && !doRestore && update) { 697 doRestore = performRollbackManagerRestore(userId, token, res, data); 698 } 699 700 if (!doRestore) { 701 // No restore possible, or the Backup Manager was mysteriously not 702 // available -- just fire the post-install work request directly. 703 if (DEBUG_INSTALL) Log.v(TAG, "No restore - queue post-install for " + token); 704 705 Trace.asyncTraceBegin(TRACE_TAG_PACKAGE_MANAGER, "postInstall", token); 706 707 Message msg = mPm.mHandler.obtainMessage(POST_INSTALL, token, 0); 708 mPm.mHandler.sendMessage(msg); 709 } 710 } 711 712 /** 713 * Perform Backup Manager restore for a given {@link PackageInstalledInfo}. 714 * Returns whether the restore successfully completed. 715 */ performBackupManagerRestore(int userId, int token, PackageInstalledInfo res)716 private boolean performBackupManagerRestore(int userId, int token, PackageInstalledInfo res) { 717 IBackupManager iBackupManager = mInjector.getIBackupManager(); 718 if (iBackupManager != null) { 719 // For backwards compatibility as USER_ALL previously routed directly to USER_SYSTEM 720 // in the BackupManager. USER_ALL is used in compatibility tests. 721 if (userId == UserHandle.USER_ALL) { 722 userId = UserHandle.USER_SYSTEM; 723 } 724 if (DEBUG_INSTALL) { 725 Log.v(TAG, "token " + token + " to BM for possible restore for user " + userId); 726 } 727 Trace.asyncTraceBegin(TRACE_TAG_PACKAGE_MANAGER, "restore", token); 728 try { 729 if (iBackupManager.isUserReadyForBackup(userId)) { 730 iBackupManager.restoreAtInstallForUser( 731 userId, res.mPkg.getPackageName(), token); 732 } else { 733 Slog.w(TAG, "User " + userId + " is not ready. Restore at install " 734 + "didn't take place."); 735 return false; 736 } 737 } catch (RemoteException e) { 738 // can't happen; the backup manager is local 739 } catch (Exception e) { 740 Slog.e(TAG, "Exception trying to enqueue restore", e); 741 return false; 742 } 743 } else { 744 Slog.e(TAG, "Backup Manager not found!"); 745 return false; 746 } 747 return true; 748 } 749 750 /** 751 * Perform Rollback Manager restore for a given {@link PackageInstalledInfo}. 752 * Returns whether the restore successfully completed. 753 */ performRollbackManagerRestore(int userId, int token, PackageInstalledInfo res, PostInstallData data)754 private boolean performRollbackManagerRestore(int userId, int token, PackageInstalledInfo res, 755 PostInstallData data) { 756 final String packageName = res.mPkg.getPackageName(); 757 final int[] allUsers = mPm.mUserManager.getUserIds(); 758 final int[] installedUsers; 759 760 final PackageSetting ps; 761 int appId = -1; 762 long ceDataInode = -1; 763 synchronized (mPm.mLock) { 764 ps = mPm.mSettings.getPackageLPr(packageName); 765 if (ps != null) { 766 appId = ps.getAppId(); 767 ceDataInode = ps.getCeDataInode(userId); 768 } 769 770 // NOTE: We ignore the user specified in the InstallParam because we know this is 771 // an update, and hence need to restore data for all installed users. 772 installedUsers = ps.queryInstalledUsers(allUsers, true); 773 } 774 775 boolean doSnapshotOrRestore = data != null && data.args != null 776 && ((data.args.mInstallFlags & PackageManager.INSTALL_ENABLE_ROLLBACK) != 0 777 || (data.args.mInstallFlags & PackageManager.INSTALL_REQUEST_DOWNGRADE) != 0); 778 779 if (ps != null && doSnapshotOrRestore) { 780 final String seInfo = AndroidPackageUtils.getSeInfo(res.mPkg, ps); 781 final RollbackManagerInternal rollbackManager = 782 mInjector.getLocalService(RollbackManagerInternal.class); 783 rollbackManager.snapshotAndRestoreUserData(packageName, 784 UserHandle.toUserHandles(installedUsers), appId, ceDataInode, seInfo, token); 785 return true; 786 } 787 return false; 788 } 789 processInstallRequests(boolean success, List<InstallRequest> installRequests)790 public void processInstallRequests(boolean success, List<InstallRequest> installRequests) { 791 List<InstallRequest> apexInstallRequests = new ArrayList<>(); 792 List<InstallRequest> apkInstallRequests = new ArrayList<>(); 793 for (InstallRequest request : installRequests) { 794 if ((request.mArgs.mInstallFlags & PackageManager.INSTALL_APEX) != 0) { 795 apexInstallRequests.add(request); 796 } else { 797 apkInstallRequests.add(request); 798 } 799 } 800 // Note: supporting multi package install of both APEXes and APKs might requir some 801 // thinking to ensure atomicity of the install. 802 if (!apexInstallRequests.isEmpty() && !apkInstallRequests.isEmpty()) { 803 // This should've been caught at the validation step, but for some reason wasn't. 804 throw new IllegalStateException( 805 "Attempted to do a multi package install of both APEXes and APKs"); 806 } 807 if (!apexInstallRequests.isEmpty()) { 808 if (success) { 809 // Since installApexPackages requires talking to external service (apexd), we 810 // schedule to run it async. Once it finishes, it will resume the install. 811 Thread t = new Thread(() -> installApexPackagesTraced(apexInstallRequests), 812 "installApexPackages"); 813 t.start(); 814 } else { 815 // Non-staged APEX installation failed somewhere before 816 // processInstallRequestAsync. In that case just notify the observer about the 817 // failure. 818 InstallRequest request = apexInstallRequests.get(0); 819 mPm.notifyInstallObserver(request.mInstallResult, 820 request.mArgs.mObserver); 821 } 822 return; 823 } 824 if (success) { 825 for (InstallRequest request : apkInstallRequests) { 826 request.mArgs.doPreInstall(request.mInstallResult.mReturnCode); 827 } 828 synchronized (mPm.mInstallLock) { 829 installPackagesTracedLI(apkInstallRequests); 830 } 831 for (InstallRequest request : apkInstallRequests) { 832 request.mArgs.doPostInstall( 833 request.mInstallResult.mReturnCode, request.mInstallResult.mUid); 834 } 835 } 836 for (InstallRequest request : apkInstallRequests) { 837 restoreAndPostInstall(request.mArgs.mUser.getIdentifier(), 838 request.mInstallResult, 839 new PostInstallData(request.mArgs, 840 request.mInstallResult, null)); 841 } 842 } 843 installApexPackagesTraced(List<InstallRequest> requests)844 private void installApexPackagesTraced(List<InstallRequest> requests) { 845 try { 846 Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "installApexPackages"); 847 installApexPackages(requests); 848 } finally { 849 Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER); 850 } 851 } 852 installApexPackages(List<InstallRequest> requests)853 private void installApexPackages(List<InstallRequest> requests) { 854 if (requests.isEmpty()) { 855 return; 856 } 857 if (requests.size() != 1) { 858 throw new IllegalStateException( 859 "Only a non-staged install of a single APEX is supported"); 860 } 861 InstallRequest request = requests.get(0); 862 try { 863 // Should directory scanning logic be moved to ApexManager for better test coverage? 864 final File dir = request.mArgs.mOriginInfo.mResolvedFile; 865 final File[] apexes = dir.listFiles(); 866 if (apexes == null) { 867 throw new PackageManagerException(INSTALL_FAILED_INTERNAL_ERROR, 868 dir.getAbsolutePath() + " is not a directory"); 869 } 870 if (apexes.length != 1) { 871 throw new PackageManagerException(INSTALL_FAILED_INTERNAL_ERROR, 872 "Expected exactly one .apex file under " + dir.getAbsolutePath() 873 + " got: " + apexes.length); 874 } 875 try (PackageParser2 packageParser = mPm.mInjector.getScanningPackageParser()) { 876 mApexManager.installPackage(apexes[0], packageParser); 877 } 878 } catch (PackageManagerException e) { 879 request.mInstallResult.setError("APEX installation failed", e); 880 } 881 PackageManagerService.invalidatePackageInfoCache(); 882 mPm.notifyInstallObserver(request.mInstallResult, request.mArgs.mObserver); 883 } 884 885 @GuardedBy("mPm.mInstallLock") installPackagesTracedLI(List<InstallRequest> requests)886 private void installPackagesTracedLI(List<InstallRequest> requests) { 887 try { 888 Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "installPackages"); 889 installPackagesLI(requests); 890 } finally { 891 Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER); 892 } 893 } 894 895 /** 896 * Installs one or more packages atomically. This operation is broken up into four phases: 897 * <ul> 898 * <li><b>Prepare</b> 899 * <br/>Analyzes any current install state, parses the package and does initial 900 * validation on it.</li> 901 * <li><b>Scan</b> 902 * <br/>Interrogates the parsed packages given the context collected in prepare.</li> 903 * <li><b>Reconcile</b> 904 * <br/>Validates scanned packages in the context of each other and the current system 905 * state to ensure that the install will be successful. 906 * <li><b>Commit</b> 907 * <br/>Commits all scanned packages and updates system state. This is the only place 908 * that system state may be modified in the install flow and all predictable errors 909 * must be determined before this phase.</li> 910 * </ul> 911 * 912 * Failure at any phase will result in a full failure to install all packages. 913 */ 914 @GuardedBy("mPm.mInstallLock") installPackagesLI(List<InstallRequest> requests)915 private void installPackagesLI(List<InstallRequest> requests) { 916 final Map<String, ScanResult> preparedScans = new ArrayMap<>(requests.size()); 917 final Map<String, InstallArgs> installArgs = new ArrayMap<>(requests.size()); 918 final Map<String, PackageInstalledInfo> installResults = new ArrayMap<>(requests.size()); 919 final Map<String, PrepareResult> prepareResults = new ArrayMap<>(requests.size()); 920 final Map<String, Settings.VersionInfo> versionInfos = new ArrayMap<>(requests.size()); 921 final Map<String, Boolean> createdAppId = new ArrayMap<>(requests.size()); 922 boolean success = false; 923 try { 924 Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "installPackagesLI"); 925 for (InstallRequest request : requests) { 926 // TODO(b/109941548): remove this once we've pulled everything from it and into 927 // scan, reconcile or commit. 928 final PrepareResult prepareResult; 929 try { 930 Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "preparePackage"); 931 prepareResult = 932 preparePackageLI(request.mArgs, request.mInstallResult); 933 } catch (PrepareFailure prepareFailure) { 934 request.mInstallResult.setError(prepareFailure.error, 935 prepareFailure.getMessage()); 936 request.mInstallResult.mOrigPackage = prepareFailure.mConflictingPackage; 937 request.mInstallResult.mOrigPermission = prepareFailure.mConflictingPermission; 938 return; 939 } finally { 940 Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER); 941 } 942 request.mInstallResult.setReturnCode(PackageManager.INSTALL_SUCCEEDED); 943 request.mInstallResult.mInstallerPackageName = 944 request.mArgs.mInstallSource.installerPackageName; 945 946 final String packageName = prepareResult.mPackageToScan.getPackageName(); 947 prepareResults.put(packageName, prepareResult); 948 installResults.put(packageName, request.mInstallResult); 949 installArgs.put(packageName, request.mArgs); 950 try { 951 final ScanResult result = scanPackageTracedLI( 952 prepareResult.mPackageToScan, prepareResult.mParseFlags, 953 prepareResult.mScanFlags, System.currentTimeMillis(), 954 request.mArgs.mUser, request.mArgs.mAbiOverride); 955 if (null != preparedScans.put(result.mPkgSetting.getPkg().getPackageName(), 956 result)) { 957 request.mInstallResult.setError( 958 PackageManager.INSTALL_FAILED_DUPLICATE_PACKAGE, 959 "Duplicate package " 960 + result.mPkgSetting.getPkg().getPackageName() 961 + " in multi-package install request."); 962 return; 963 } 964 if (!checkNoAppStorageIsConsistent( 965 result.mRequest.mOldPkg, result.mPkgSetting.getPkg())) { 966 // TODO: INSTALL_FAILED_UPDATE_INCOMPATIBLE is about incomptabible 967 // signatures. Is there a better error code? 968 request.mInstallResult.setError( 969 INSTALL_FAILED_UPDATE_INCOMPATIBLE, 970 "Update attempted to change value of " 971 + PackageManager.PROPERTY_NO_APP_DATA_STORAGE); 972 return; 973 } 974 createdAppId.put(packageName, optimisticallyRegisterAppId(result)); 975 versionInfos.put(result.mPkgSetting.getPkg().getPackageName(), 976 mPm.getSettingsVersionForPackage(result.mPkgSetting.getPkg())); 977 } catch (PackageManagerException e) { 978 request.mInstallResult.setError("Scanning Failed.", e); 979 return; 980 } 981 } 982 ReconcileRequest reconcileRequest = new ReconcileRequest(preparedScans, installArgs, 983 installResults, prepareResults, 984 Collections.unmodifiableMap(mPm.mPackages), versionInfos); 985 CommitRequest commitRequest = null; 986 synchronized (mPm.mLock) { 987 Map<String, ReconciledPackage> reconciledPackages; 988 try { 989 Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "reconcilePackages"); 990 reconciledPackages = ReconcilePackageUtils.reconcilePackages( 991 reconcileRequest, mSharedLibraries, 992 mPm.mSettings.getKeySetManagerService(), mPm.mSettings); 993 } catch (ReconcileFailure e) { 994 for (InstallRequest request : requests) { 995 request.mInstallResult.setError("Reconciliation failed...", e); 996 } 997 return; 998 } finally { 999 Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER); 1000 } 1001 try { 1002 Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "commitPackages"); 1003 commitRequest = new CommitRequest(reconciledPackages, 1004 mPm.mUserManager.getUserIds()); 1005 commitPackagesLocked(commitRequest); 1006 success = true; 1007 } finally { 1008 Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER); 1009 } 1010 } 1011 executePostCommitSteps(commitRequest); 1012 } finally { 1013 if (success) { 1014 for (InstallRequest request : requests) { 1015 final InstallArgs args = request.mArgs; 1016 if (args.mDataLoaderType != DataLoaderType.INCREMENTAL) { 1017 continue; 1018 } 1019 if (args.mSigningDetails.getSignatureSchemeVersion() != SIGNING_BLOCK_V4) { 1020 continue; 1021 } 1022 // For incremental installs, we bypass the verifier prior to install. Now 1023 // that we know the package is valid, send a notice to the verifier with 1024 // the root hash of the base.apk. 1025 final String baseCodePath = request.mInstallResult.mPkg.getBaseApkPath(); 1026 final String[] splitCodePaths = request.mInstallResult.mPkg.getSplitCodePaths(); 1027 final Uri originUri = Uri.fromFile(args.mOriginInfo.mResolvedFile); 1028 final int verificationId = mPm.mPendingVerificationToken++; 1029 final String rootHashString = PackageManagerServiceUtils 1030 .buildVerificationRootHashString(baseCodePath, splitCodePaths); 1031 VerificationUtils.broadcastPackageVerified(verificationId, originUri, 1032 PackageManager.VERIFICATION_ALLOW, rootHashString, 1033 args.mDataLoaderType, args.getUser(), mContext); 1034 } 1035 } else { 1036 for (ScanResult result : preparedScans.values()) { 1037 if (createdAppId.getOrDefault(result.mRequest.mParsedPackage.getPackageName(), 1038 false)) { 1039 cleanUpAppIdCreation(result); 1040 } 1041 } 1042 // TODO(b/194319951): create a more descriptive reason than unknown 1043 // mark all non-failure installs as UNKNOWN so we do not treat them as success 1044 for (InstallRequest request : requests) { 1045 if (request.mInstallResult.mFreezer != null) { 1046 request.mInstallResult.mFreezer.close(); 1047 } 1048 if (request.mInstallResult.mReturnCode == PackageManager.INSTALL_SUCCEEDED) { 1049 request.mInstallResult.mReturnCode = PackageManager.INSTALL_UNKNOWN; 1050 } 1051 } 1052 } 1053 Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER); 1054 } 1055 } 1056 1057 @GuardedBy("mPm.mInstallLock") checkNoAppStorageIsConsistent(AndroidPackage oldPkg, AndroidPackage newPkg)1058 private boolean checkNoAppStorageIsConsistent(AndroidPackage oldPkg, AndroidPackage newPkg) { 1059 if (oldPkg == null) { 1060 // New install, nothing to check against. 1061 return true; 1062 } 1063 final PackageManager.Property curProp = 1064 oldPkg.getProperties().get(PackageManager.PROPERTY_NO_APP_DATA_STORAGE); 1065 final PackageManager.Property newProp = 1066 newPkg.getProperties().get(PackageManager.PROPERTY_NO_APP_DATA_STORAGE); 1067 if (curProp == null || !curProp.getBoolean()) { 1068 return newProp == null || !newProp.getBoolean(); 1069 } 1070 return newProp != null && newProp.getBoolean(); 1071 } 1072 1073 @GuardedBy("mPm.mInstallLock") preparePackageLI(InstallArgs args, PackageInstalledInfo res)1074 private PrepareResult preparePackageLI(InstallArgs args, PackageInstalledInfo res) 1075 throws PrepareFailure { 1076 final int installFlags = args.mInstallFlags; 1077 final File tmpPackageFile = new File(args.getCodePath()); 1078 final boolean onExternal = args.mVolumeUuid != null; 1079 final boolean instantApp = ((installFlags & PackageManager.INSTALL_INSTANT_APP) != 0); 1080 final boolean fullApp = ((installFlags & PackageManager.INSTALL_FULL_APP) != 0); 1081 final boolean virtualPreload = 1082 ((installFlags & PackageManager.INSTALL_VIRTUAL_PRELOAD) != 0); 1083 final boolean isRollback = args.mInstallReason == PackageManager.INSTALL_REASON_ROLLBACK; 1084 @PackageManagerService.ScanFlags int scanFlags = SCAN_NEW_INSTALL | SCAN_UPDATE_SIGNATURE; 1085 if (args.mMoveInfo != null) { 1086 // moving a complete application; perform an initial scan on the new install location 1087 scanFlags |= SCAN_INITIAL; 1088 } 1089 if ((installFlags & PackageManager.INSTALL_DONT_KILL_APP) != 0) { 1090 scanFlags |= SCAN_DONT_KILL_APP; 1091 } 1092 if (instantApp) { 1093 scanFlags |= SCAN_AS_INSTANT_APP; 1094 } 1095 if (fullApp) { 1096 scanFlags |= SCAN_AS_FULL_APP; 1097 } 1098 if (virtualPreload) { 1099 scanFlags |= SCAN_AS_VIRTUAL_PRELOAD; 1100 } 1101 1102 if (DEBUG_INSTALL) Slog.d(TAG, "installPackageLI: path=" + tmpPackageFile); 1103 1104 // Validity check 1105 if (instantApp && onExternal) { 1106 Slog.i(TAG, "Incompatible ephemeral install; external=" + onExternal); 1107 throw new PrepareFailure(PackageManager.INSTALL_FAILED_SESSION_INVALID); 1108 } 1109 1110 // Retrieve PackageSettings and parse package 1111 @ParsingPackageUtils.ParseFlags final int parseFlags = 1112 mPm.getDefParseFlags() | ParsingPackageUtils.PARSE_CHATTY 1113 | ParsingPackageUtils.PARSE_ENFORCE_CODE 1114 | (onExternal ? ParsingPackageUtils.PARSE_EXTERNAL_STORAGE : 0); 1115 1116 Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "parsePackage"); 1117 final ParsedPackage parsedPackage; 1118 try (PackageParser2 pp = mPm.mInjector.getPreparingPackageParser()) { 1119 parsedPackage = pp.parsePackage(tmpPackageFile, parseFlags, false); 1120 AndroidPackageUtils.validatePackageDexMetadata(parsedPackage); 1121 } catch (PackageManagerException e) { 1122 throw new PrepareFailure("Failed parse during installPackageLI", e); 1123 } finally { 1124 Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER); 1125 } 1126 1127 // Instant apps have several additional install-time checks. 1128 if (instantApp) { 1129 if (parsedPackage.getTargetSdkVersion() < Build.VERSION_CODES.O) { 1130 Slog.w(TAG, "Instant app package " + parsedPackage.getPackageName() 1131 + " does not target at least O"); 1132 throw new PrepareFailure(INSTALL_FAILED_SESSION_INVALID, 1133 "Instant app package must target at least O"); 1134 } 1135 if (parsedPackage.getSharedUserId() != null) { 1136 Slog.w(TAG, "Instant app package " + parsedPackage.getPackageName() 1137 + " may not declare sharedUserId."); 1138 throw new PrepareFailure(INSTALL_FAILED_SESSION_INVALID, 1139 "Instant app package may not declare a sharedUserId"); 1140 } 1141 } 1142 1143 if (parsedPackage.isStaticSharedLibrary()) { 1144 // Static shared libraries have synthetic package names 1145 PackageManagerService.renameStaticSharedLibraryPackage(parsedPackage); 1146 1147 // No static shared libs on external storage 1148 if (onExternal) { 1149 Slog.i(TAG, "Static shared libs can only be installed on internal storage."); 1150 throw new PrepareFailure(INSTALL_FAILED_INVALID_INSTALL_LOCATION, 1151 "Packages declaring static-shared libs cannot be updated"); 1152 } 1153 } 1154 1155 String pkgName = res.mName = parsedPackage.getPackageName(); 1156 if (parsedPackage.isTestOnly()) { 1157 if ((installFlags & PackageManager.INSTALL_ALLOW_TEST) == 0) { 1158 throw new PrepareFailure(INSTALL_FAILED_TEST_ONLY, "installPackageLI"); 1159 } 1160 } 1161 1162 // either use what we've been given or parse directly from the APK 1163 if (args.mSigningDetails != SigningDetails.UNKNOWN) { 1164 parsedPackage.setSigningDetails(args.mSigningDetails); 1165 } else { 1166 final ParseTypeImpl input = ParseTypeImpl.forDefaultParsing(); 1167 final ParseResult<SigningDetails> result = ParsingPackageUtils.getSigningDetails( 1168 input, parsedPackage, false /*skipVerify*/); 1169 if (result.isError()) { 1170 throw new PrepareFailure("Failed collect during installPackageLI", 1171 result.getException()); 1172 } 1173 parsedPackage.setSigningDetails(result.getResult()); 1174 } 1175 1176 if (instantApp && parsedPackage.getSigningDetails().getSignatureSchemeVersion() 1177 < SigningDetails.SignatureSchemeVersion.SIGNING_BLOCK_V2) { 1178 Slog.w(TAG, "Instant app package " + parsedPackage.getPackageName() 1179 + " is not signed with at least APK Signature Scheme v2"); 1180 throw new PrepareFailure(INSTALL_FAILED_SESSION_INVALID, 1181 "Instant app package must be signed with APK Signature Scheme v2 or greater"); 1182 } 1183 1184 boolean systemApp = false; 1185 boolean replace = false; 1186 synchronized (mPm.mLock) { 1187 // Check if installing already existing package 1188 if ((installFlags & PackageManager.INSTALL_REPLACE_EXISTING) != 0) { 1189 String oldName = mPm.mSettings.getRenamedPackageLPr(pkgName); 1190 if (parsedPackage.getOriginalPackages().contains(oldName) 1191 && mPm.mPackages.containsKey(oldName)) { 1192 // This package is derived from an original package, 1193 // and this device has been updating from that original 1194 // name. We must continue using the original name, so 1195 // rename the new package here. 1196 parsedPackage.setPackageName(oldName); 1197 pkgName = parsedPackage.getPackageName(); 1198 replace = true; 1199 if (DEBUG_INSTALL) { 1200 Slog.d(TAG, "Replacing existing renamed package: oldName=" 1201 + oldName + " pkgName=" + pkgName); 1202 } 1203 } else if (mPm.mPackages.containsKey(pkgName)) { 1204 // This package, under its official name, already exists 1205 // on the device; we should replace it. 1206 replace = true; 1207 if (DEBUG_INSTALL) Slog.d(TAG, "Replace existing package: " + pkgName); 1208 } 1209 1210 if (replace) { 1211 // Prevent apps opting out from runtime permissions 1212 AndroidPackage oldPackage = mPm.mPackages.get(pkgName); 1213 final int oldTargetSdk = oldPackage.getTargetSdkVersion(); 1214 final int newTargetSdk = parsedPackage.getTargetSdkVersion(); 1215 if (oldTargetSdk > Build.VERSION_CODES.LOLLIPOP_MR1 1216 && newTargetSdk <= Build.VERSION_CODES.LOLLIPOP_MR1) { 1217 throw new PrepareFailure( 1218 PackageManager.INSTALL_FAILED_PERMISSION_MODEL_DOWNGRADE, 1219 "Package " + parsedPackage.getPackageName() 1220 + " new target SDK " + newTargetSdk 1221 + " doesn't support runtime permissions but the old" 1222 + " target SDK " + oldTargetSdk + " does."); 1223 } 1224 // Prevent persistent apps from being updated 1225 if (oldPackage.isPersistent() 1226 && ((installFlags & PackageManager.INSTALL_STAGED) == 0)) { 1227 throw new PrepareFailure(PackageManager.INSTALL_FAILED_INVALID_APK, 1228 "Package " + oldPackage.getPackageName() + " is a persistent app. " 1229 + "Persistent apps are not updateable."); 1230 } 1231 } 1232 } 1233 1234 PackageSetting ps = mPm.mSettings.getPackageLPr(pkgName); 1235 PackageSetting signatureCheckPs = ps; 1236 1237 // SDK libs can have other major versions with different package names. 1238 if (signatureCheckPs == null && parsedPackage.isSdkLibrary()) { 1239 WatchedLongSparseArray<SharedLibraryInfo> libraryInfos = 1240 mSharedLibraries.getSharedLibraryInfos( 1241 parsedPackage.getSdkLibName()); 1242 if (libraryInfos != null && libraryInfos.size() > 0) { 1243 // Any existing version would do. 1244 SharedLibraryInfo libraryInfo = libraryInfos.valueAt(0); 1245 signatureCheckPs = mPm.mSettings.getPackageLPr(libraryInfo.getPackageName()); 1246 } 1247 } 1248 1249 // Static shared libs have same package with different versions where 1250 // we internally use a synthetic package name to allow multiple versions 1251 // of the same package, therefore we need to compare signatures against 1252 // the package setting for the latest library version. 1253 if (parsedPackage.isStaticSharedLibrary()) { 1254 SharedLibraryInfo libraryInfo = 1255 mSharedLibraries.getLatestStaticSharedLibraVersionLPr(parsedPackage); 1256 if (libraryInfo != null) { 1257 signatureCheckPs = mPm.mSettings.getPackageLPr(libraryInfo.getPackageName()); 1258 } 1259 } 1260 1261 if (signatureCheckPs != null) { 1262 if (DEBUG_INSTALL) { 1263 Slog.d(TAG, 1264 "Existing package for signature checking: " + signatureCheckPs); 1265 } 1266 1267 // Quick validity check that we're signed correctly if updating; 1268 // we'll check this again later when scanning, but we want to 1269 // bail early here before tripping over redefined permissions. 1270 final KeySetManagerService ksms = mPm.mSettings.getKeySetManagerService(); 1271 final SharedUserSetting signatureCheckSus = mPm.mSettings.getSharedUserSettingLPr( 1272 signatureCheckPs); 1273 if (ksms.shouldCheckUpgradeKeySetLocked(signatureCheckPs, signatureCheckSus, 1274 scanFlags)) { 1275 if (!ksms.checkUpgradeKeySetLocked(signatureCheckPs, parsedPackage)) { 1276 throw new PrepareFailure(INSTALL_FAILED_UPDATE_INCOMPATIBLE, "Package " 1277 + parsedPackage.getPackageName() + " upgrade keys do not match the " 1278 + "previously installed version"); 1279 } 1280 } else { 1281 try { 1282 final boolean compareCompat = 1283 ReconcilePackageUtils.isCompatSignatureUpdateNeeded( 1284 mPm.getSettingsVersionForPackage(parsedPackage)); 1285 final boolean compareRecover = 1286 ReconcilePackageUtils.isRecoverSignatureUpdateNeeded( 1287 mPm.getSettingsVersionForPackage(parsedPackage)); 1288 // We don't care about disabledPkgSetting on install for now. 1289 final boolean compatMatch = 1290 PackageManagerServiceUtils.verifySignatures(signatureCheckPs, 1291 signatureCheckSus, null, 1292 parsedPackage.getSigningDetails(), compareCompat, compareRecover, 1293 isRollback); 1294 // The new KeySets will be re-added later in the scanning process. 1295 if (compatMatch) { 1296 synchronized (mPm.mLock) { 1297 ksms.removeAppKeySetDataLPw(parsedPackage.getPackageName()); 1298 } 1299 } 1300 } catch (PackageManagerException e) { 1301 throw new PrepareFailure(e.error, e.getMessage()); 1302 } 1303 } 1304 } 1305 1306 if (ps != null) { 1307 if (DEBUG_INSTALL) Slog.d(TAG, "Existing package: " + ps); 1308 1309 if (ps.getPkg() != null) { 1310 systemApp = ps.getPkg().isSystem(); 1311 } 1312 res.mOrigUsers = ps.queryInstalledUsers(mPm.mUserManager.getUserIds(), true); 1313 } 1314 1315 final int numGroups = ArrayUtils.size(parsedPackage.getPermissionGroups()); 1316 for (int groupNum = 0; groupNum < numGroups; groupNum++) { 1317 final ParsedPermissionGroup group = 1318 parsedPackage.getPermissionGroups().get(groupNum); 1319 final PermissionGroupInfo sourceGroup = mPm.getPermissionGroupInfo(group.getName(), 1320 0); 1321 1322 if (sourceGroup != null && cannotInstallWithBadPermissionGroups(parsedPackage)) { 1323 final String sourcePackageName = sourceGroup.packageName; 1324 1325 if ((replace || !parsedPackage.getPackageName().equals(sourcePackageName)) 1326 && !doesSignatureMatchForPermissions(sourcePackageName, parsedPackage, 1327 scanFlags)) { 1328 EventLog.writeEvent(0x534e4554, "146211400", -1, 1329 parsedPackage.getPackageName()); 1330 1331 throw new PrepareFailure(INSTALL_FAILED_DUPLICATE_PERMISSION_GROUP, 1332 "Package " 1333 + parsedPackage.getPackageName() 1334 + " attempting to redeclare permission group " 1335 + group.getName() + " already owned by " 1336 + sourcePackageName); 1337 } 1338 } 1339 } 1340 1341 // TODO: Move logic for checking permission compatibility into PermissionManagerService 1342 final int n = ArrayUtils.size(parsedPackage.getPermissions()); 1343 for (int i = n - 1; i >= 0; i--) { 1344 final ParsedPermission perm = parsedPackage.getPermissions().get(i); 1345 final Permission bp = mPm.mPermissionManager.getPermissionTEMP(perm.getName()); 1346 1347 // Don't allow anyone but the system to define ephemeral permissions. 1348 if ((perm.getProtectionLevel() & PermissionInfo.PROTECTION_FLAG_INSTANT) != 0 1349 && !systemApp) { 1350 Slog.w(TAG, "Non-System package " + parsedPackage.getPackageName() 1351 + " attempting to delcare ephemeral permission " 1352 + perm.getName() + "; Removing ephemeral."); 1353 ComponentMutateUtils.setProtectionLevel(perm, 1354 perm.getProtectionLevel() & ~PermissionInfo.PROTECTION_FLAG_INSTANT); 1355 } 1356 1357 // Check whether the newly-scanned package wants to define an already-defined perm 1358 if (bp != null) { 1359 final String sourcePackageName = bp.getPackageName(); 1360 1361 if (!doesSignatureMatchForPermissions(sourcePackageName, parsedPackage, 1362 scanFlags)) { 1363 // If the owning package is the system itself, we log but allow 1364 // install to proceed; we fail the install on all other permission 1365 // redefinitions. 1366 if (!sourcePackageName.equals("android")) { 1367 throw new PrepareFailure(INSTALL_FAILED_DUPLICATE_PERMISSION, 1368 "Package " 1369 + parsedPackage.getPackageName() 1370 + " attempting to redeclare permission " 1371 + perm.getName() + " already owned by " 1372 + sourcePackageName) 1373 .conflictsWithExistingPermission(perm.getName(), 1374 sourcePackageName); 1375 } else { 1376 Slog.w(TAG, "Package " + parsedPackage.getPackageName() 1377 + " attempting to redeclare system permission " 1378 + perm.getName() + "; ignoring new declaration"); 1379 parsedPackage.removePermission(i); 1380 } 1381 } else if (!PLATFORM_PACKAGE_NAME.equals(parsedPackage.getPackageName())) { 1382 // Prevent apps to change protection level to dangerous from any other 1383 // type as this would allow a privilege escalation where an app adds a 1384 // normal/signature permission in other app's group and later redefines 1385 // it as dangerous leading to the group auto-grant. 1386 if ((perm.getProtectionLevel() & PermissionInfo.PROTECTION_MASK_BASE) 1387 == PermissionInfo.PROTECTION_DANGEROUS) { 1388 if (bp != null && !bp.isRuntime()) { 1389 Slog.w(TAG, "Package " + parsedPackage.getPackageName() 1390 + " trying to change a non-runtime permission " 1391 + perm.getName() 1392 + " to runtime; keeping old protection level"); 1393 ComponentMutateUtils.setProtectionLevel(perm, 1394 bp.getProtectionLevel()); 1395 } 1396 } 1397 } 1398 } 1399 1400 if (perm.getGroup() != null 1401 && cannotInstallWithBadPermissionGroups(parsedPackage)) { 1402 boolean isPermGroupDefinedByPackage = false; 1403 for (int groupNum = 0; groupNum < numGroups; groupNum++) { 1404 if (parsedPackage.getPermissionGroups().get(groupNum).getName() 1405 .equals(perm.getGroup())) { 1406 isPermGroupDefinedByPackage = true; 1407 break; 1408 } 1409 } 1410 1411 if (!isPermGroupDefinedByPackage) { 1412 final PermissionGroupInfo sourceGroup = 1413 mPm.getPermissionGroupInfo(perm.getGroup(), 0); 1414 1415 if (sourceGroup == null) { 1416 EventLog.writeEvent(0x534e4554, "146211400", -1, 1417 parsedPackage.getPackageName()); 1418 1419 throw new PrepareFailure(INSTALL_FAILED_BAD_PERMISSION_GROUP, 1420 "Package " 1421 + parsedPackage.getPackageName() 1422 + " attempting to declare permission " 1423 + perm.getName() + " in non-existing group " 1424 + perm.getGroup()); 1425 } else { 1426 String groupSourcePackageName = sourceGroup.packageName; 1427 1428 if (!PLATFORM_PACKAGE_NAME.equals(groupSourcePackageName) 1429 && !doesSignatureMatchForPermissions(groupSourcePackageName, 1430 parsedPackage, scanFlags)) { 1431 EventLog.writeEvent(0x534e4554, "146211400", -1, 1432 parsedPackage.getPackageName()); 1433 1434 throw new PrepareFailure(INSTALL_FAILED_BAD_PERMISSION_GROUP, 1435 "Package " 1436 + parsedPackage.getPackageName() 1437 + " attempting to declare permission " 1438 + perm.getName() + " in group " 1439 + perm.getGroup() + " owned by package " 1440 + groupSourcePackageName 1441 + " with incompatible certificate"); 1442 } 1443 } 1444 } 1445 } 1446 } 1447 } 1448 1449 if (systemApp) { 1450 if (onExternal) { 1451 // Abort update; system app can't be replaced with app on sdcard 1452 throw new PrepareFailure(INSTALL_FAILED_INVALID_INSTALL_LOCATION, 1453 "Cannot install updates to system apps on sdcard"); 1454 } else if (instantApp) { 1455 // Abort update; system app can't be replaced with an instant app 1456 throw new PrepareFailure(INSTALL_FAILED_SESSION_INVALID, 1457 "Cannot update a system app with an instant app"); 1458 } 1459 } 1460 1461 if (args.mMoveInfo != null) { 1462 // We did an in-place move, so dex is ready to roll 1463 scanFlags |= SCAN_NO_DEX; 1464 scanFlags |= SCAN_MOVE; 1465 1466 synchronized (mPm.mLock) { 1467 final PackageSetting ps = mPm.mSettings.getPackageLPr(pkgName); 1468 if (ps == null) { 1469 res.setError(INSTALL_FAILED_INTERNAL_ERROR, 1470 "Missing settings for moved package " + pkgName); 1471 } 1472 1473 // We moved the entire application as-is, so bring over the 1474 // previously derived ABI information. 1475 parsedPackage.setPrimaryCpuAbi(ps.getPrimaryCpuAbi()) 1476 .setSecondaryCpuAbi(ps.getSecondaryCpuAbi()); 1477 } 1478 1479 } else { 1480 // Enable SCAN_NO_DEX flag to skip dexopt at a later stage 1481 scanFlags |= SCAN_NO_DEX; 1482 1483 try { 1484 PackageSetting pkgSetting; 1485 AndroidPackage oldPackage; 1486 synchronized (mPm.mLock) { 1487 pkgSetting = mPm.mSettings.getPackageLPr(pkgName); 1488 oldPackage = mPm.mPackages.get(pkgName); 1489 } 1490 boolean isUpdatedSystemAppFromExistingSetting = pkgSetting != null 1491 && pkgSetting.getPkgState().isUpdatedSystemApp(); 1492 final String abiOverride = deriveAbiOverride(args.mAbiOverride); 1493 boolean isUpdatedSystemAppInferred = oldPackage != null && oldPackage.isSystem(); 1494 final Pair<PackageAbiHelper.Abis, PackageAbiHelper.NativeLibraryPaths> 1495 derivedAbi = mPackageAbiHelper.derivePackageAbi(parsedPackage, 1496 isUpdatedSystemAppFromExistingSetting || isUpdatedSystemAppInferred, 1497 abiOverride, ScanPackageUtils.getAppLib32InstallDir()); 1498 derivedAbi.first.applyTo(parsedPackage); 1499 derivedAbi.second.applyTo(parsedPackage); 1500 } catch (PackageManagerException pme) { 1501 Slog.e(TAG, "Error deriving application ABI", pme); 1502 throw new PrepareFailure(INSTALL_FAILED_INTERNAL_ERROR, 1503 "Error deriving application ABI: " + pme.getMessage()); 1504 } 1505 } 1506 1507 if (!args.doRename(res.mReturnCode, parsedPackage)) { 1508 throw new PrepareFailure(INSTALL_FAILED_INSUFFICIENT_STORAGE, "Failed rename"); 1509 } 1510 1511 try { 1512 setUpFsVerityIfPossible(parsedPackage); 1513 } catch (Installer.InstallerException | IOException | DigestException 1514 | NoSuchAlgorithmException e) { 1515 throw new PrepareFailure(INSTALL_FAILED_INTERNAL_ERROR, 1516 "Failed to set up verity: " + e); 1517 } 1518 1519 final PackageFreezer freezer = 1520 freezePackageForInstall(pkgName, installFlags, "installPackageLI"); 1521 boolean shouldCloseFreezerBeforeReturn = true; 1522 try { 1523 final AndroidPackage oldPackage; 1524 String renamedPackage; 1525 boolean sysPkg = false; 1526 int targetScanFlags = scanFlags; 1527 int targetParseFlags = parseFlags; 1528 final PackageSetting ps; 1529 final PackageSetting disabledPs; 1530 final SharedUserSetting sharedUserSetting; 1531 if (replace) { 1532 final String pkgName11 = parsedPackage.getPackageName(); 1533 synchronized (mPm.mLock) { 1534 oldPackage = mPm.mPackages.get(pkgName11); 1535 } 1536 if (parsedPackage.isStaticSharedLibrary()) { 1537 // Static libs have a synthetic package name containing the version 1538 // and cannot be updated as an update would get a new package name, 1539 // unless this is installed from adb which is useful for development. 1540 if (oldPackage != null 1541 && (installFlags & PackageManager.INSTALL_FROM_ADB) == 0) { 1542 throw new PrepareFailure(INSTALL_FAILED_DUPLICATE_PACKAGE, 1543 "Packages declaring " 1544 + "static-shared libs cannot be updated"); 1545 } 1546 } 1547 1548 final boolean isInstantApp = (scanFlags & SCAN_AS_INSTANT_APP) != 0; 1549 1550 final int[] allUsers; 1551 final int[] installedUsers; 1552 final int[] uninstalledUsers; 1553 1554 synchronized (mPm.mLock) { 1555 if (DEBUG_INSTALL) { 1556 Slog.d(TAG, 1557 "replacePackageLI: new=" + parsedPackage + ", old=" + oldPackage); 1558 } 1559 1560 ps = mPm.mSettings.getPackageLPr(pkgName11); 1561 disabledPs = mPm.mSettings.getDisabledSystemPkgLPr(ps); 1562 sharedUserSetting = mPm.mSettings.getSharedUserSettingLPr(ps); 1563 1564 // verify signatures are valid 1565 final KeySetManagerService ksms = mPm.mSettings.getKeySetManagerService(); 1566 if (ksms.shouldCheckUpgradeKeySetLocked(ps, sharedUserSetting, scanFlags)) { 1567 if (!ksms.checkUpgradeKeySetLocked(ps, parsedPackage)) { 1568 throw new PrepareFailure(INSTALL_FAILED_UPDATE_INCOMPATIBLE, 1569 "New package not signed by keys specified by upgrade-keysets: " 1570 + pkgName11); 1571 } 1572 } else { 1573 SigningDetails parsedPkgSigningDetails = parsedPackage.getSigningDetails(); 1574 SigningDetails oldPkgSigningDetails = oldPackage.getSigningDetails(); 1575 // default to original signature matching 1576 if (!parsedPkgSigningDetails.checkCapability(oldPkgSigningDetails, 1577 SigningDetails.CertCapabilities.INSTALLED_DATA) 1578 && !oldPkgSigningDetails.checkCapability(parsedPkgSigningDetails, 1579 SigningDetails.CertCapabilities.ROLLBACK)) { 1580 // Allow the update to proceed if this is a rollback and the parsed 1581 // package's current signing key is the current signer or in the lineage 1582 // of the old package; this allows a rollback to a previously installed 1583 // version after an app's signing key has been rotated without requiring 1584 // the rollback capability on the previous signing key. 1585 if (!isRollback || !oldPkgSigningDetails.hasAncestorOrSelf( 1586 parsedPkgSigningDetails)) { 1587 throw new PrepareFailure(INSTALL_FAILED_UPDATE_INCOMPATIBLE, 1588 "New package has a different signature: " + pkgName11); 1589 } 1590 } 1591 } 1592 1593 // don't allow a system upgrade unless the upgrade hash matches 1594 if (oldPackage.getRestrictUpdateHash() != null && oldPackage.isSystem()) { 1595 final byte[] digestBytes; 1596 try { 1597 final MessageDigest digest = MessageDigest.getInstance("SHA-512"); 1598 updateDigest(digest, new File(parsedPackage.getBaseApkPath())); 1599 if (!ArrayUtils.isEmpty(parsedPackage.getSplitCodePaths())) { 1600 for (String path : parsedPackage.getSplitCodePaths()) { 1601 updateDigest(digest, new File(path)); 1602 } 1603 } 1604 digestBytes = digest.digest(); 1605 } catch (NoSuchAlgorithmException | IOException e) { 1606 throw new PrepareFailure(INSTALL_FAILED_INVALID_APK, 1607 "Could not compute hash: " + pkgName11); 1608 } 1609 if (!Arrays.equals(oldPackage.getRestrictUpdateHash(), digestBytes)) { 1610 throw new PrepareFailure(INSTALL_FAILED_INVALID_APK, 1611 "New package fails restrict-update check: " + pkgName11); 1612 } 1613 // retain upgrade restriction 1614 parsedPackage.setRestrictUpdateHash(oldPackage.getRestrictUpdateHash()); 1615 } 1616 1617 // APK should not change its sharedUserId declarations 1618 final var oldSharedUid = oldPackage.getSharedUserId() != null 1619 ? oldPackage.getSharedUserId() : "<nothing>"; 1620 final var newSharedUid = parsedPackage.getSharedUserId() != null 1621 ? parsedPackage.getSharedUserId() : "<nothing>"; 1622 if (!oldSharedUid.equals(newSharedUid)) { 1623 throw new PrepareFailure(INSTALL_FAILED_UID_CHANGED, 1624 "Package " + parsedPackage.getPackageName() 1625 + " shared user changed from " 1626 + oldSharedUid + " to " + newSharedUid); 1627 } 1628 1629 // APK should not re-join shared UID 1630 if (oldPackage.isLeavingSharedUid() && !parsedPackage.isLeavingSharedUid()) { 1631 throw new PrepareFailure(INSTALL_FAILED_UID_CHANGED, 1632 "Package " + parsedPackage.getPackageName() 1633 + " attempting to rejoin " + newSharedUid); 1634 } 1635 1636 // In case of rollback, remember per-user/profile install state 1637 allUsers = mPm.mUserManager.getUserIds(); 1638 installedUsers = ps.queryInstalledUsers(allUsers, true); 1639 uninstalledUsers = ps.queryInstalledUsers(allUsers, false); 1640 1641 1642 // don't allow an upgrade from full to ephemeral 1643 if (isInstantApp) { 1644 if (args.mUser == null 1645 || args.mUser.getIdentifier() == UserHandle.USER_ALL) { 1646 for (int currentUser : allUsers) { 1647 if (!ps.getInstantApp(currentUser)) { 1648 // can't downgrade from full to instant 1649 Slog.w(TAG, 1650 "Can't replace full app with instant app: " + pkgName11 1651 + " for user: " + currentUser); 1652 throw new PrepareFailure( 1653 PackageManager.INSTALL_FAILED_SESSION_INVALID); 1654 } 1655 } 1656 } else if (!ps.getInstantApp(args.mUser.getIdentifier())) { 1657 // can't downgrade from full to instant 1658 Slog.w(TAG, "Can't replace full app with instant app: " + pkgName11 1659 + " for user: " + args.mUser.getIdentifier()); 1660 throw new PrepareFailure( 1661 PackageManager.INSTALL_FAILED_SESSION_INVALID); 1662 } 1663 } 1664 } 1665 1666 // Update what is removed 1667 res.mRemovedInfo = new PackageRemovedInfo(mPm); 1668 res.mRemovedInfo.mUid = oldPackage.getUid(); 1669 res.mRemovedInfo.mRemovedPackage = oldPackage.getPackageName(); 1670 res.mRemovedInfo.mInstallerPackageName = ps.getInstallSource().installerPackageName; 1671 res.mRemovedInfo.mIsStaticSharedLib = 1672 parsedPackage.getStaticSharedLibName() != null; 1673 res.mRemovedInfo.mIsUpdate = true; 1674 res.mRemovedInfo.mOrigUsers = installedUsers; 1675 res.mRemovedInfo.mInstallReasons = new SparseArray<>(installedUsers.length); 1676 for (int i = 0; i < installedUsers.length; i++) { 1677 final int userId = installedUsers[i]; 1678 res.mRemovedInfo.mInstallReasons.put(userId, ps.getInstallReason(userId)); 1679 } 1680 res.mRemovedInfo.mUninstallReasons = new SparseArray<>(uninstalledUsers.length); 1681 for (int i = 0; i < uninstalledUsers.length; i++) { 1682 final int userId = uninstalledUsers[i]; 1683 res.mRemovedInfo.mUninstallReasons.put(userId, ps.getUninstallReason(userId)); 1684 } 1685 res.mRemovedInfo.mIsExternal = oldPackage.isExternalStorage(); 1686 1687 sysPkg = oldPackage.isSystem(); 1688 if (sysPkg) { 1689 // Set the system/privileged/oem/vendor/product flags as needed 1690 final boolean privileged = oldPackage.isPrivileged(); 1691 final boolean oem = oldPackage.isOem(); 1692 final boolean vendor = oldPackage.isVendor(); 1693 final boolean product = oldPackage.isProduct(); 1694 final boolean odm = oldPackage.isOdm(); 1695 final boolean systemExt = oldPackage.isSystemExt(); 1696 final @ParsingPackageUtils.ParseFlags int systemParseFlags = parseFlags; 1697 final @PackageManagerService.ScanFlags int systemScanFlags = scanFlags 1698 | SCAN_AS_SYSTEM 1699 | (privileged ? SCAN_AS_PRIVILEGED : 0) 1700 | (oem ? SCAN_AS_OEM : 0) 1701 | (vendor ? SCAN_AS_VENDOR : 0) 1702 | (product ? SCAN_AS_PRODUCT : 0) 1703 | (odm ? SCAN_AS_ODM : 0) 1704 | (systemExt ? SCAN_AS_SYSTEM_EXT : 0); 1705 1706 if (DEBUG_INSTALL) { 1707 Slog.d(TAG, "replaceSystemPackageLI: new=" + parsedPackage 1708 + ", old=" + oldPackage); 1709 } 1710 res.setReturnCode(PackageManager.INSTALL_SUCCEEDED); 1711 targetParseFlags = systemParseFlags; 1712 targetScanFlags = systemScanFlags; 1713 } else { // non system replace 1714 replace = true; 1715 if (DEBUG_INSTALL) { 1716 Slog.d(TAG, 1717 "replaceNonSystemPackageLI: new=" + parsedPackage + ", old=" 1718 + oldPackage); 1719 } 1720 } 1721 } else { // new package install 1722 ps = null; 1723 disabledPs = null; 1724 replace = false; 1725 oldPackage = null; 1726 // Remember this for later, in case we need to rollback this install 1727 String pkgName1 = parsedPackage.getPackageName(); 1728 1729 if (DEBUG_INSTALL) Slog.d(TAG, "installNewPackageLI: " + parsedPackage); 1730 1731 // TODO(b/194319951): MOVE TO RECONCILE 1732 synchronized (mPm.mLock) { 1733 renamedPackage = mPm.mSettings.getRenamedPackageLPr(pkgName1); 1734 if (renamedPackage != null) { 1735 // A package with the same name is already installed, though 1736 // it has been renamed to an older name. The package we 1737 // are trying to install should be installed as an update to 1738 // the existing one, but that has not been requested, so bail. 1739 throw new PrepareFailure(INSTALL_FAILED_ALREADY_EXISTS, 1740 "Attempt to re-install " + pkgName1 1741 + " without first uninstalling package running as " 1742 + renamedPackage); 1743 } 1744 if (mPm.mPackages.containsKey(pkgName1)) { 1745 // Don't allow installation over an existing package with the same name. 1746 throw new PrepareFailure(INSTALL_FAILED_ALREADY_EXISTS, 1747 "Attempt to re-install " + pkgName1 1748 + " without first uninstalling."); 1749 } 1750 } 1751 } 1752 // we're passing the freezer back to be closed in a later phase of install 1753 shouldCloseFreezerBeforeReturn = false; 1754 1755 return new PrepareResult(replace, targetScanFlags, targetParseFlags, 1756 oldPackage, parsedPackage, replace /* clearCodeCache */, sysPkg, 1757 ps, disabledPs); 1758 } finally { 1759 res.mFreezer = freezer; 1760 if (shouldCloseFreezerBeforeReturn) { 1761 freezer.close(); 1762 } 1763 } 1764 } 1765 1766 /* 1767 * Cannot properly check CANNOT_INSTALL_WITH_BAD_PERMISSION_GROUPS using CompatChanges 1768 * as this only works for packages that are installed 1769 * 1770 * TODO: Move logic for permission group compatibility into PermissionManagerService 1771 */ 1772 @SuppressWarnings("AndroidFrameworkCompatChange") cannotInstallWithBadPermissionGroups(ParsedPackage parsedPackage)1773 private static boolean cannotInstallWithBadPermissionGroups(ParsedPackage parsedPackage) { 1774 return parsedPackage.getTargetSdkVersion() >= Build.VERSION_CODES.S; 1775 } 1776 doesSignatureMatchForPermissions(@onNull String sourcePackageName, @NonNull ParsedPackage parsedPackage, int scanFlags)1777 private boolean doesSignatureMatchForPermissions(@NonNull String sourcePackageName, 1778 @NonNull ParsedPackage parsedPackage, int scanFlags) { 1779 // If the defining package is signed with our cert, it's okay. This 1780 // also includes the "updating the same package" case, of course. 1781 // "updating same package" could also involve key-rotation. 1782 1783 final PackageSetting sourcePackageSetting; 1784 final KeySetManagerService ksms; 1785 final SharedUserSetting sharedUserSetting; 1786 synchronized (mPm.mLock) { 1787 sourcePackageSetting = mPm.mSettings.getPackageLPr(sourcePackageName); 1788 ksms = mPm.mSettings.getKeySetManagerService(); 1789 sharedUserSetting = mPm.mSettings.getSharedUserSettingLPr(sourcePackageSetting); 1790 } 1791 1792 final SigningDetails sourceSigningDetails = (sourcePackageSetting == null 1793 ? SigningDetails.UNKNOWN : sourcePackageSetting.getSigningDetails()); 1794 if (sourcePackageName.equals(parsedPackage.getPackageName()) 1795 && (ksms.shouldCheckUpgradeKeySetLocked( 1796 sourcePackageSetting, sharedUserSetting, scanFlags))) { 1797 return ksms.checkUpgradeKeySetLocked(sourcePackageSetting, parsedPackage); 1798 } else { 1799 1800 // in the event of signing certificate rotation, we need to see if the 1801 // package's certificate has rotated from the current one, or if it is an 1802 // older certificate with which the current is ok with sharing permissions 1803 if (sourceSigningDetails.checkCapability( 1804 parsedPackage.getSigningDetails(), 1805 SigningDetails.CertCapabilities.PERMISSION)) { 1806 return true; 1807 } else if (parsedPackage.getSigningDetails().checkCapability( 1808 sourceSigningDetails, 1809 SigningDetails.CertCapabilities.PERMISSION)) { 1810 // the scanned package checks out, has signing certificate rotation 1811 // history, and is newer; bring it over 1812 synchronized (mPm.mLock) { 1813 sourcePackageSetting.setSigningDetails(parsedPackage.getSigningDetails()); 1814 } 1815 return true; 1816 } else { 1817 return false; 1818 } 1819 } 1820 } 1821 1822 /** 1823 * Set up fs-verity for the given package if possible. This requires a feature flag of system 1824 * property to be enabled only if the kernel supports fs-verity. 1825 * 1826 * <p>When the feature flag is set to legacy mode, only APK is supported (with some experimental 1827 * kernel patches). In normal mode, all file format can be supported. 1828 */ setUpFsVerityIfPossible(AndroidPackage pkg)1829 private void setUpFsVerityIfPossible(AndroidPackage pkg) throws Installer.InstallerException, 1830 PrepareFailure, IOException, DigestException, NoSuchAlgorithmException { 1831 if (!PackageManagerServiceUtils.isApkVerityEnabled()) { 1832 return; 1833 } 1834 1835 if (isIncrementalPath(pkg.getPath()) && IncrementalManager.getVersion() 1836 < IncrementalManager.MIN_VERSION_TO_SUPPORT_FSVERITY) { 1837 return; 1838 } 1839 1840 // Collect files we care for fs-verity setup. 1841 ArrayMap<String, String> fsverityCandidates = new ArrayMap<>(); 1842 // NB: These files will become only accessible if the signing key is loaded in kernel's 1843 // .fs-verity keyring. 1844 fsverityCandidates.put(pkg.getBaseApkPath(), 1845 VerityUtils.getFsveritySignatureFilePath(pkg.getBaseApkPath())); 1846 1847 final String dmPath = DexMetadataHelper.buildDexMetadataPathForApk( 1848 pkg.getBaseApkPath()); 1849 if (new File(dmPath).exists()) { 1850 fsverityCandidates.put(dmPath, VerityUtils.getFsveritySignatureFilePath(dmPath)); 1851 } 1852 1853 for (String path : pkg.getSplitCodePaths()) { 1854 fsverityCandidates.put(path, VerityUtils.getFsveritySignatureFilePath(path)); 1855 1856 final String splitDmPath = DexMetadataHelper.buildDexMetadataPathForApk(path); 1857 if (new File(splitDmPath).exists()) { 1858 fsverityCandidates.put(splitDmPath, 1859 VerityUtils.getFsveritySignatureFilePath(splitDmPath)); 1860 } 1861 } 1862 1863 final String packageName = pkg.getPackageName(); 1864 for (Map.Entry<String, String> entry : fsverityCandidates.entrySet()) { 1865 final String filePath = entry.getKey(); 1866 final String signaturePath = entry.getValue(); 1867 1868 // fs-verity is optional for now. Only set up if signature is provided. 1869 if (new File(signaturePath).exists() && !VerityUtils.hasFsverity(filePath)) { 1870 try { 1871 VerityUtils.setUpFsverity(filePath, signaturePath); 1872 } catch (IOException e) { 1873 throw new PrepareFailure(PackageManager.INSTALL_FAILED_BAD_SIGNATURE, 1874 "Failed to enable fs-verity: " + e); 1875 } 1876 } 1877 } 1878 } 1879 freezePackageForInstall(String packageName, int installFlags, String killReason)1880 private PackageFreezer freezePackageForInstall(String packageName, int installFlags, 1881 String killReason) { 1882 return freezePackageForInstall(packageName, UserHandle.USER_ALL, installFlags, killReason); 1883 } 1884 freezePackageForInstall(String packageName, int userId, int installFlags, String killReason)1885 private PackageFreezer freezePackageForInstall(String packageName, int userId, int installFlags, 1886 String killReason) { 1887 if ((installFlags & PackageManager.INSTALL_DONT_KILL_APP) != 0) { 1888 return new PackageFreezer(mPm); 1889 } else { 1890 return mPm.freezePackage(packageName, userId, killReason); 1891 } 1892 } 1893 updateDigest(MessageDigest digest, File file)1894 private static void updateDigest(MessageDigest digest, File file) throws IOException { 1895 try (DigestInputStream digestStream = 1896 new DigestInputStream(new FileInputStream(file), digest)) { 1897 int length, total = 0; 1898 while ((length = digestStream.read()) != -1) { 1899 total += length; 1900 } // just plow through the file 1901 } 1902 } 1903 1904 @GuardedBy("mPm.mLock") commitPackagesLocked(final CommitRequest request)1905 private void commitPackagesLocked(final CommitRequest request) { 1906 // TODO: remove any expected failures from this method; this should only be able to fail due 1907 // to unavoidable errors (I/O, etc.) 1908 for (ReconciledPackage reconciledPkg : request.mReconciledPackages.values()) { 1909 final ScanResult scanResult = reconciledPkg.mScanResult; 1910 final ScanRequest scanRequest = scanResult.mRequest; 1911 final ParsedPackage parsedPackage = scanRequest.mParsedPackage; 1912 final String packageName = parsedPackage.getPackageName(); 1913 final PackageInstalledInfo res = reconciledPkg.mInstallResult; 1914 final RemovePackageHelper removePackageHelper = new RemovePackageHelper(mPm); 1915 final DeletePackageHelper deletePackageHelper = new DeletePackageHelper(mPm); 1916 1917 if (reconciledPkg.mPrepareResult.mReplace) { 1918 AndroidPackage oldPackage = mPm.mPackages.get(packageName); 1919 1920 // Set the update and install times 1921 PackageStateInternal deletedPkgSetting = mPm.snapshotComputer() 1922 .getPackageStateInternal(oldPackage.getPackageName()); 1923 reconciledPkg.mPkgSetting 1924 .setFirstInstallTimeFromReplaced(deletedPkgSetting, request.mAllUsers) 1925 .setLastUpdateTime(System.currentTimeMillis()); 1926 1927 res.mRemovedInfo.mBroadcastAllowList = mPm.mAppsFilter.getVisibilityAllowList( 1928 mPm.snapshotComputer(), reconciledPkg.mPkgSetting, request.mAllUsers, 1929 mPm.mSettings.getPackagesLocked()); 1930 if (reconciledPkg.mPrepareResult.mSystem) { 1931 // Remove existing system package 1932 removePackageHelper.removePackageLI(oldPackage, true); 1933 if (!disableSystemPackageLPw(oldPackage)) { 1934 // We didn't need to disable the .apk as a current system package, 1935 // which means we are replacing another update that is already 1936 // installed. We need to make sure to delete the older one's .apk. 1937 res.mRemovedInfo.mArgs = new FileInstallArgs( 1938 oldPackage.getPath(), 1939 getAppDexInstructionSets( 1940 AndroidPackageUtils.getPrimaryCpuAbi(oldPackage, 1941 deletedPkgSetting), 1942 AndroidPackageUtils.getSecondaryCpuAbi(oldPackage, 1943 deletedPkgSetting)), mPm); 1944 } else { 1945 res.mRemovedInfo.mArgs = null; 1946 } 1947 } else { 1948 try { 1949 // Settings will be written during the call to updateSettingsLI(). 1950 deletePackageHelper.executeDeletePackageLIF( 1951 reconciledPkg.mDeletePackageAction, packageName, 1952 true, request.mAllUsers, false); 1953 } catch (SystemDeleteException e) { 1954 if (mPm.mIsEngBuild) { 1955 throw new RuntimeException("Unexpected failure", e); 1956 // ignore; not possible for non-system app 1957 } 1958 } 1959 // Successfully deleted the old package; proceed with replace. 1960 // Update the in-memory copy of the previous code paths. 1961 PackageSetting ps1 = mPm.mSettings.getPackageLPr( 1962 reconciledPkg.mPrepareResult.mExistingPackage.getPackageName()); 1963 if ((reconciledPkg.mInstallArgs.mInstallFlags & PackageManager.DONT_KILL_APP) 1964 == 0) { 1965 Set<String> oldCodePaths = ps1.getOldCodePaths(); 1966 if (oldCodePaths == null) { 1967 oldCodePaths = new ArraySet<>(); 1968 } 1969 Collections.addAll(oldCodePaths, oldPackage.getBaseApkPath()); 1970 Collections.addAll(oldCodePaths, oldPackage.getSplitCodePaths()); 1971 ps1.setOldCodePaths(oldCodePaths); 1972 } else { 1973 ps1.setOldCodePaths(null); 1974 } 1975 1976 if (reconciledPkg.mInstallResult.mReturnCode 1977 == PackageManager.INSTALL_SUCCEEDED) { 1978 PackageSetting ps2 = mPm.mSettings.getPackageLPr( 1979 parsedPackage.getPackageName()); 1980 if (ps2 != null) { 1981 res.mRemovedInfo.mRemovedForAllUsers = 1982 mPm.mPackages.get(ps2.getPackageName()) == null; 1983 } 1984 } 1985 } 1986 } 1987 1988 AndroidPackage pkg = commitReconciledScanResultLocked( 1989 reconciledPkg, request.mAllUsers); 1990 updateSettingsLI(pkg, reconciledPkg, request.mAllUsers, res); 1991 1992 final PackageSetting ps = mPm.mSettings.getPackageLPr(packageName); 1993 if (ps != null) { 1994 res.mNewUsers = ps.queryInstalledUsers(mPm.mUserManager.getUserIds(), true); 1995 ps.setUpdateAvailable(false /*updateAvailable*/); 1996 } 1997 if (res.mReturnCode == PackageManager.INSTALL_SUCCEEDED) { 1998 mPm.updateSequenceNumberLP(ps, res.mNewUsers); 1999 mPm.updateInstantAppInstallerLocked(packageName); 2000 } 2001 } 2002 ApplicationPackageManager.invalidateGetPackagesForUidCache(); 2003 } 2004 2005 @GuardedBy("mPm.mLock") disableSystemPackageLPw(AndroidPackage oldPkg)2006 private boolean disableSystemPackageLPw(AndroidPackage oldPkg) { 2007 return mPm.mSettings.disableSystemPackageLPw(oldPkg.getPackageName(), true); 2008 } 2009 updateSettingsLI(AndroidPackage newPackage, ReconciledPackage reconciledPkg, int[] allUsers, PackageInstalledInfo res)2010 private void updateSettingsLI(AndroidPackage newPackage, ReconciledPackage reconciledPkg, 2011 int[] allUsers, PackageInstalledInfo res) { 2012 updateSettingsInternalLI(newPackage, reconciledPkg, allUsers, res); 2013 } 2014 updateSettingsInternalLI(AndroidPackage pkg, ReconciledPackage reconciledPkg, int[] allUsers, PackageInstalledInfo res)2015 private void updateSettingsInternalLI(AndroidPackage pkg, ReconciledPackage reconciledPkg, 2016 int[] allUsers, PackageInstalledInfo res) { 2017 Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "updateSettings"); 2018 2019 final String pkgName = pkg.getPackageName(); 2020 final int[] installedForUsers = res.mOrigUsers; 2021 final InstallArgs installArgs = reconciledPkg.mInstallArgs; 2022 final int installReason = installArgs.mInstallReason; 2023 InstallSource installSource = installArgs.mInstallSource; 2024 final String installerPackageName = installSource.installerPackageName; 2025 2026 if (DEBUG_INSTALL) Slog.d(TAG, "New package installed in " + pkg.getPath()); 2027 synchronized (mPm.mLock) { 2028 // For system-bundled packages, we assume that installing an upgraded version 2029 // of the package implies that the user actually wants to run that new code, 2030 // so we enable the package. 2031 final PackageSetting ps = mPm.mSettings.getPackageLPr(pkgName); 2032 final int userId = installArgs.mUser.getIdentifier(); 2033 if (ps != null) { 2034 if (pkg.isSystem()) { 2035 if (DEBUG_INSTALL) { 2036 Slog.d(TAG, "Implicitly enabling system package on upgrade: " + pkgName); 2037 } 2038 // Enable system package for requested users 2039 if (res.mOrigUsers != null) { 2040 for (int origUserId : res.mOrigUsers) { 2041 if (userId == UserHandle.USER_ALL || userId == origUserId) { 2042 ps.setEnabled(COMPONENT_ENABLED_STATE_DEFAULT, 2043 origUserId, installerPackageName); 2044 } 2045 } 2046 } 2047 // Also convey the prior install/uninstall state 2048 if (allUsers != null && installedForUsers != null) { 2049 for (int currentUserId : allUsers) { 2050 final boolean installed = ArrayUtils.contains( 2051 installedForUsers, currentUserId); 2052 if (DEBUG_INSTALL) { 2053 Slog.d(TAG, " user " + currentUserId + " => " + installed); 2054 } 2055 ps.setInstalled(installed, currentUserId); 2056 } 2057 // these install state changes will be persisted in the 2058 // upcoming call to mSettings.writeLPr(). 2059 } 2060 2061 if (allUsers != null) { 2062 for (int currentUserId : allUsers) { 2063 ps.resetOverrideComponentLabelIcon(currentUserId); 2064 } 2065 } 2066 } 2067 2068 // Retrieve the overlays for shared libraries of the package. 2069 if (!ps.getPkgState().getUsesLibraryInfos().isEmpty()) { 2070 for (SharedLibraryInfo sharedLib : ps.getPkgState().getUsesLibraryInfos()) { 2071 for (int currentUserId : UserManagerService.getInstance().getUserIds()) { 2072 if (!sharedLib.isDynamic()) { 2073 // TODO(146804378): Support overlaying static shared libraries 2074 continue; 2075 } 2076 final PackageSetting libPs = mPm.mSettings.getPackageLPr( 2077 sharedLib.getPackageName()); 2078 if (libPs == null) { 2079 continue; 2080 } 2081 ps.setOverlayPathsForLibrary(sharedLib.getName(), 2082 libPs.getOverlayPaths(currentUserId), currentUserId); 2083 } 2084 } 2085 } 2086 2087 if (userId != UserHandle.USER_ALL) { 2088 // It's implied that when a user requests installation, they want the app to 2089 // be installed and enabled. 2090 ps.setInstalled(true, userId); 2091 ps.setEnabled(COMPONENT_ENABLED_STATE_DEFAULT, userId, installerPackageName); 2092 } else if (allUsers != null) { 2093 // The caller explicitly specified INSTALL_ALL_USERS flag. 2094 // Thus, updating the settings to install the app for all users. 2095 for (int currentUserId : allUsers) { 2096 // If the app is already installed for the currentUser, 2097 // keep it as installed as we might be updating the app at this place. 2098 // If not currently installed, check if the currentUser is restricted by 2099 // DISALLOW_INSTALL_APPS or DISALLOW_DEBUGGING_FEATURES device policy. 2100 // Install / update the app if the user isn't restricted. Skip otherwise. 2101 final boolean installedForCurrentUser = ArrayUtils.contains( 2102 installedForUsers, currentUserId); 2103 final boolean restrictedByPolicy = 2104 mPm.isUserRestricted(currentUserId, 2105 UserManager.DISALLOW_INSTALL_APPS) 2106 || mPm.isUserRestricted(currentUserId, 2107 UserManager.DISALLOW_DEBUGGING_FEATURES); 2108 if (installedForCurrentUser || !restrictedByPolicy) { 2109 ps.setInstalled(true, currentUserId); 2110 ps.setEnabled(COMPONENT_ENABLED_STATE_DEFAULT, currentUserId, 2111 installerPackageName); 2112 } else { 2113 ps.setInstalled(false, currentUserId); 2114 } 2115 } 2116 } 2117 2118 mPm.mSettings.addInstallerPackageNames(ps.getInstallSource()); 2119 2120 // When replacing an existing package, preserve the original install reason for all 2121 // users that had the package installed before. Similarly for uninstall reasons. 2122 final Set<Integer> previousUserIds = new ArraySet<>(); 2123 if (res.mRemovedInfo != null && res.mRemovedInfo.mInstallReasons != null) { 2124 final int installReasonCount = res.mRemovedInfo.mInstallReasons.size(); 2125 for (int i = 0; i < installReasonCount; i++) { 2126 final int previousUserId = res.mRemovedInfo.mInstallReasons.keyAt(i); 2127 final int previousInstallReason = 2128 res.mRemovedInfo.mInstallReasons.valueAt(i); 2129 ps.setInstallReason(previousInstallReason, previousUserId); 2130 previousUserIds.add(previousUserId); 2131 } 2132 } 2133 if (res.mRemovedInfo != null && res.mRemovedInfo.mUninstallReasons != null) { 2134 for (int i = 0; i < res.mRemovedInfo.mUninstallReasons.size(); i++) { 2135 final int previousUserId = res.mRemovedInfo.mUninstallReasons.keyAt(i); 2136 final int previousReason = res.mRemovedInfo.mUninstallReasons.valueAt(i); 2137 ps.setUninstallReason(previousReason, previousUserId); 2138 } 2139 } 2140 2141 // Set install reason for users that are having the package newly installed. 2142 final int[] allUsersList = mPm.mUserManager.getUserIds(); 2143 if (userId == UserHandle.USER_ALL) { 2144 for (int currentUserId : allUsersList) { 2145 if (!previousUserIds.contains(currentUserId) 2146 && ps.getInstalled(currentUserId)) { 2147 ps.setInstallReason(installReason, currentUserId); 2148 } 2149 } 2150 } else if (!previousUserIds.contains(userId)) { 2151 ps.setInstallReason(installReason, userId); 2152 } 2153 2154 // TODO(b/169721400): generalize Incremental States and create a Callback object 2155 // that can be used for all the packages. 2156 final String codePath = ps.getPathString(); 2157 if (IncrementalManager.isIncrementalPath(codePath) 2158 && mIncrementalManager != null) { 2159 mIncrementalManager.registerLoadingProgressCallback(codePath, 2160 new IncrementalProgressListener(ps.getPackageName(), mPm)); 2161 } 2162 2163 // Ensure that the uninstall reason is UNKNOWN for users with the package installed. 2164 for (int currentUserId : allUsersList) { 2165 if (ps.getInstalled(currentUserId)) { 2166 ps.setUninstallReason(UNINSTALL_REASON_UNKNOWN, currentUserId); 2167 } 2168 } 2169 2170 mPm.mSettings.writeKernelMappingLPr(ps); 2171 2172 final PermissionManagerServiceInternal.PackageInstalledParams.Builder 2173 permissionParamsBuilder = 2174 new PermissionManagerServiceInternal.PackageInstalledParams.Builder(); 2175 final boolean grantPermissions = (installArgs.mInstallFlags 2176 & PackageManager.INSTALL_GRANT_RUNTIME_PERMISSIONS) != 0; 2177 if (grantPermissions) { 2178 final List<String> grantedPermissions = 2179 installArgs.mInstallGrantPermissions != null 2180 ? Arrays.asList(installArgs.mInstallGrantPermissions) 2181 : pkg.getRequestedPermissions(); 2182 permissionParamsBuilder.setGrantedPermissions(grantedPermissions); 2183 } 2184 final boolean allowlistAllRestrictedPermissions = 2185 (installArgs.mInstallFlags 2186 & PackageManager.INSTALL_ALL_WHITELIST_RESTRICTED_PERMISSIONS) != 0; 2187 final List<String> allowlistedRestrictedPermissions = 2188 allowlistAllRestrictedPermissions ? pkg.getRequestedPermissions() 2189 : installArgs.mAllowlistedRestrictedPermissions; 2190 if (allowlistedRestrictedPermissions != null) { 2191 permissionParamsBuilder.setAllowlistedRestrictedPermissions( 2192 allowlistedRestrictedPermissions); 2193 } 2194 final int autoRevokePermissionsMode = installArgs.mAutoRevokePermissionsMode; 2195 permissionParamsBuilder.setAutoRevokePermissionsMode(autoRevokePermissionsMode); 2196 final ScanResult scanResult = reconciledPkg.mScanResult; 2197 mPm.mPermissionManager.onPackageInstalled(pkg, scanResult.mPreviousAppId, 2198 permissionParamsBuilder.build(), userId); 2199 // Apply restricted settings on potentially dangerous packages. 2200 if (installArgs.mPackageSource == PackageInstaller.PACKAGE_SOURCE_LOCAL_FILE 2201 || installArgs.mPackageSource 2202 == PackageInstaller.PACKAGE_SOURCE_DOWNLOADED_FILE) { 2203 enableRestrictedSettings(pkgName, pkg.getUid()); 2204 } 2205 } 2206 res.mName = pkgName; 2207 res.mUid = pkg.getUid(); 2208 res.mPkg = pkg; 2209 res.setReturnCode(PackageManager.INSTALL_SUCCEEDED); 2210 //to update install status 2211 Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "writeSettings"); 2212 mPm.writeSettingsLPrTEMP(); 2213 Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER); 2214 } 2215 2216 Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER); 2217 } 2218 enableRestrictedSettings(String pkgName, int appId)2219 private void enableRestrictedSettings(String pkgName, int appId) { 2220 final AppOpsManager appOpsManager = mPm.mContext.getSystemService(AppOpsManager.class); 2221 final int[] allUsersList = mPm.mUserManager.getUserIds(); 2222 for (int userId : allUsersList) { 2223 final int uid = UserHandle.getUid(userId, appId); 2224 appOpsManager.setMode(AppOpsManager.OP_ACCESS_RESTRICTED_SETTINGS, 2225 uid, 2226 pkgName, 2227 AppOpsManager.MODE_ERRORED); 2228 } 2229 } 2230 2231 /** 2232 * On successful install, executes remaining steps after commit completes and the package lock 2233 * is released. These are typically more expensive or require calls to installd, which often 2234 * locks on {@link com.android.server.pm.PackageManagerService.mLock}. 2235 */ executePostCommitSteps(CommitRequest commitRequest)2236 private void executePostCommitSteps(CommitRequest commitRequest) { 2237 final ArraySet<IncrementalStorage> incrementalStorages = new ArraySet<>(); 2238 for (ReconciledPackage reconciledPkg : commitRequest.mReconciledPackages.values()) { 2239 final boolean instantApp = ((reconciledPkg.mScanResult.mRequest.mScanFlags 2240 & SCAN_AS_INSTANT_APP) != 0); 2241 final AndroidPackage pkg = reconciledPkg.mPkgSetting.getPkg(); 2242 final String packageName = pkg.getPackageName(); 2243 final String codePath = pkg.getPath(); 2244 final boolean onIncremental = mIncrementalManager != null 2245 && isIncrementalPath(codePath); 2246 if (onIncremental) { 2247 IncrementalStorage storage = mIncrementalManager.openStorage(codePath); 2248 if (storage == null) { 2249 throw new IllegalArgumentException( 2250 "Install: null storage for incremental package " + packageName); 2251 } 2252 incrementalStorages.add(storage); 2253 } 2254 // Hardcode previousAppId to 0 to disable any data migration (http://b/221088088) 2255 mAppDataHelper.prepareAppDataPostCommitLIF(pkg, 0); 2256 if (reconciledPkg.mPrepareResult.mClearCodeCache) { 2257 mAppDataHelper.clearAppDataLIF(pkg, UserHandle.USER_ALL, 2258 FLAG_STORAGE_DE | FLAG_STORAGE_CE | FLAG_STORAGE_EXTERNAL 2259 | Installer.FLAG_CLEAR_CODE_CACHE_ONLY); 2260 } 2261 if (reconciledPkg.mPrepareResult.mReplace) { 2262 mDexManager.notifyPackageUpdated(pkg.getPackageName(), 2263 pkg.getBaseApkPath(), pkg.getSplitCodePaths()); 2264 } 2265 2266 // Prepare the application profiles for the new code paths. 2267 // This needs to be done before invoking dexopt so that any install-time profile 2268 // can be used for optimizations. 2269 mArtManagerService.prepareAppProfiles( 2270 pkg, 2271 mPm.resolveUserIds(reconciledPkg.mInstallArgs.mUser.getIdentifier()), 2272 /* updateReferenceProfileContent= */ true); 2273 2274 // Compute the compilation reason from the installation scenario. 2275 final int compilationReason = 2276 mDexManager.getCompilationReasonForInstallScenario( 2277 reconciledPkg.mInstallArgs.mInstallScenario); 2278 2279 // Construct the DexoptOptions early to see if we should skip running dexopt. 2280 // 2281 // Do not run PackageDexOptimizer through the local performDexOpt 2282 // method because `pkg` may not be in `mPackages` yet. 2283 // 2284 // Also, don't fail application installs if the dexopt step fails. 2285 final boolean isBackupOrRestore = 2286 reconciledPkg.mInstallArgs.mInstallReason == INSTALL_REASON_DEVICE_RESTORE 2287 || reconciledPkg.mInstallArgs.mInstallReason 2288 == INSTALL_REASON_DEVICE_SETUP; 2289 2290 final int dexoptFlags = DexoptOptions.DEXOPT_BOOT_COMPLETE 2291 | DexoptOptions.DEXOPT_INSTALL_WITH_DEX_METADATA_FILE 2292 | (isBackupOrRestore ? DexoptOptions.DEXOPT_FOR_RESTORE : 0); 2293 DexoptOptions dexoptOptions = 2294 new DexoptOptions(packageName, compilationReason, dexoptFlags); 2295 2296 // Check whether we need to dexopt the app. 2297 // 2298 // NOTE: it is IMPORTANT to call dexopt: 2299 // - after doRename which will sync the package data from AndroidPackage and 2300 // its corresponding ApplicationInfo. 2301 // - after installNewPackageLIF or replacePackageLIF which will update result with the 2302 // uid of the application (pkg.applicationInfo.uid). 2303 // This update happens in place! 2304 // 2305 // We only need to dexopt if the package meets ALL of the following conditions: 2306 // 1) it is not an instant app or if it is then dexopt is enabled via gservices. 2307 // 2) it is not debuggable. 2308 // 3) it is not on Incremental File System. 2309 // 2310 // Note that we do not dexopt instant apps by default. dexopt can take some time to 2311 // complete, so we skip this step during installation. Instead, we'll take extra time 2312 // the first time the instant app starts. It's preferred to do it this way to provide 2313 // continuous progress to the useur instead of mysteriously blocking somewhere in the 2314 // middle of running an instant app. The default behaviour can be overridden 2315 // via gservices. 2316 // 2317 // Furthermore, dexopt may be skipped, depending on the install scenario and current 2318 // state of the device. 2319 // 2320 // TODO(b/174695087): instantApp and onIncremental should be removed and their install 2321 // path moved to SCENARIO_FAST. 2322 final boolean performDexopt = 2323 (!instantApp || android.provider.Settings.Global.getInt( 2324 mContext.getContentResolver(), 2325 android.provider.Settings.Global.INSTANT_APP_DEXOPT_ENABLED, 0) != 0) 2326 && !pkg.isDebuggable() 2327 && (!onIncremental) 2328 && dexoptOptions.isCompilationEnabled(); 2329 2330 if (performDexopt) { 2331 // Compile the layout resources. 2332 if (SystemProperties.getBoolean(PRECOMPILE_LAYOUTS, false)) { 2333 Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "compileLayouts"); 2334 mViewCompiler.compileLayouts(pkg); 2335 Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER); 2336 } 2337 2338 Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "dexopt"); 2339 ScanResult result = reconciledPkg.mScanResult; 2340 2341 // This mirrors logic from commitReconciledScanResultLocked, where the library files 2342 // needed for dexopt are assigned. 2343 // TODO: Fix this to have 1 mutable PackageSetting for scan/install. If the previous 2344 // setting needs to be passed to have a comparison, hide it behind an immutable 2345 // interface. There's no good reason to have 3 different ways to access the real 2346 // PackageSetting object, only one of which is actually correct. 2347 PackageSetting realPkgSetting = result.mExistingSettingCopied 2348 ? result.mRequest.mPkgSetting : result.mPkgSetting; 2349 if (realPkgSetting == null) { 2350 realPkgSetting = reconciledPkg.mPkgSetting; 2351 } 2352 2353 // Unfortunately, the updated system app flag is only tracked on this PackageSetting 2354 boolean isUpdatedSystemApp = reconciledPkg.mPkgSetting.getPkgState() 2355 .isUpdatedSystemApp(); 2356 2357 realPkgSetting.getPkgState().setUpdatedSystemApp(isUpdatedSystemApp); 2358 2359 mPackageDexOptimizer.performDexOpt(pkg, realPkgSetting, 2360 null /* instructionSets */, 2361 mPm.getOrCreateCompilerPackageStats(pkg), 2362 mDexManager.getPackageUseInfoOrDefault(packageName), 2363 dexoptOptions); 2364 Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER); 2365 } 2366 2367 // Notify BackgroundDexOptService that the package has been changed. 2368 // If this is an update of a package which used to fail to compile, 2369 // BackgroundDexOptService will remove it from its denylist. 2370 // TODO: Layering violation 2371 BackgroundDexOptService.getService().notifyPackageChanged(packageName); 2372 2373 notifyPackageChangeObserversOnUpdate(reconciledPkg); 2374 } 2375 PackageManagerServiceUtils.waitForNativeBinariesExtractionForIncremental( 2376 incrementalStorages); 2377 } 2378 notifyPackageChangeObserversOnUpdate(ReconciledPackage reconciledPkg)2379 private void notifyPackageChangeObserversOnUpdate(ReconciledPackage reconciledPkg) { 2380 final PackageSetting pkgSetting = reconciledPkg.mPkgSetting; 2381 final PackageInstalledInfo pkgInstalledInfo = reconciledPkg.mInstallResult; 2382 final PackageRemovedInfo pkgRemovedInfo = pkgInstalledInfo.mRemovedInfo; 2383 2384 PackageChangeEvent pkgChangeEvent = new PackageChangeEvent(); 2385 pkgChangeEvent.packageName = pkgSetting.getPkg().getPackageName(); 2386 pkgChangeEvent.version = pkgSetting.getVersionCode(); 2387 pkgChangeEvent.lastUpdateTimeMillis = pkgSetting.getLastUpdateTime(); 2388 pkgChangeEvent.newInstalled = (pkgRemovedInfo == null || !pkgRemovedInfo.mIsUpdate); 2389 pkgChangeEvent.dataRemoved = (pkgRemovedInfo != null && pkgRemovedInfo.mDataRemoved); 2390 pkgChangeEvent.isDeleted = false; 2391 2392 mPm.notifyPackageChangeObservers(pkgChangeEvent); 2393 } 2394 installLocationPolicy(PackageInfoLite pkgLite, int installFlags)2395 public int installLocationPolicy(PackageInfoLite pkgLite, int installFlags) { 2396 String packageName = pkgLite.packageName; 2397 int installLocation = pkgLite.installLocation; 2398 // reader 2399 synchronized (mPm.mLock) { 2400 // Currently installed package which the new package is attempting to replace or 2401 // null if no such package is installed. 2402 AndroidPackage installedPkg = mPm.mPackages.get(packageName); 2403 2404 if (installedPkg != null) { 2405 if ((installFlags & PackageManager.INSTALL_REPLACE_EXISTING) != 0) { 2406 // Check for updated system application. 2407 if (installedPkg.isSystem()) { 2408 return InstallLocationUtils.RECOMMEND_INSTALL_INTERNAL; 2409 } else { 2410 // If current upgrade specifies particular preference 2411 if (installLocation == PackageInfo.INSTALL_LOCATION_INTERNAL_ONLY) { 2412 // Application explicitly specified internal. 2413 return InstallLocationUtils.RECOMMEND_INSTALL_INTERNAL; 2414 } else if ( 2415 installLocation == PackageInfo.INSTALL_LOCATION_PREFER_EXTERNAL) { 2416 // App explicitly prefers external. Let policy decide 2417 } else { 2418 // Prefer previous location 2419 if (installedPkg.isExternalStorage()) { 2420 return InstallLocationUtils.RECOMMEND_INSTALL_EXTERNAL; 2421 } 2422 return InstallLocationUtils.RECOMMEND_INSTALL_INTERNAL; 2423 } 2424 } 2425 } else { 2426 // Invalid install. Return error code 2427 return InstallLocationUtils.RECOMMEND_FAILED_ALREADY_EXISTS; 2428 } 2429 } 2430 } 2431 return pkgLite.recommendedInstallLocation; 2432 } 2433 verifyReplacingVersionCode(PackageInfoLite pkgLite, long requiredInstalledVersionCode, int installFlags)2434 Pair<Integer, String> verifyReplacingVersionCode(PackageInfoLite pkgLite, 2435 long requiredInstalledVersionCode, int installFlags) { 2436 if ((installFlags & PackageManager.INSTALL_APEX) != 0) { 2437 return verifyReplacingVersionCodeForApex( 2438 pkgLite, requiredInstalledVersionCode, installFlags); 2439 } 2440 2441 String packageName = pkgLite.packageName; 2442 synchronized (mPm.mLock) { 2443 // Package which currently owns the data that the new package will own if installed. 2444 // If an app is uninstalled while keeping data (e.g. adb uninstall -k), installedPkg 2445 // will be null whereas dataOwnerPkg will contain information about the package 2446 // which was uninstalled while keeping its data. 2447 AndroidPackage dataOwnerPkg = mPm.mPackages.get(packageName); 2448 PackageSetting dataOwnerPs = mPm.mSettings.getPackageLPr(packageName); 2449 if (dataOwnerPkg == null) { 2450 if (dataOwnerPs != null) { 2451 dataOwnerPkg = dataOwnerPs.getPkg(); 2452 } 2453 } 2454 2455 if (requiredInstalledVersionCode != PackageManager.VERSION_CODE_HIGHEST) { 2456 if (dataOwnerPkg == null) { 2457 String errorMsg = "Required installed version code was " 2458 + requiredInstalledVersionCode 2459 + " but package is not installed"; 2460 Slog.w(TAG, errorMsg); 2461 return Pair.create( 2462 PackageManager.INSTALL_FAILED_WRONG_INSTALLED_VERSION, errorMsg); 2463 } 2464 2465 if (dataOwnerPkg.getLongVersionCode() != requiredInstalledVersionCode) { 2466 String errorMsg = "Required installed version code was " 2467 + requiredInstalledVersionCode 2468 + " but actual installed version is " 2469 + dataOwnerPkg.getLongVersionCode(); 2470 Slog.w(TAG, errorMsg); 2471 return Pair.create( 2472 PackageManager.INSTALL_FAILED_WRONG_INSTALLED_VERSION, errorMsg); 2473 } 2474 } 2475 2476 if (dataOwnerPkg != null && !dataOwnerPkg.isSdkLibrary()) { 2477 if (!PackageManagerServiceUtils.isDowngradePermitted(installFlags, 2478 dataOwnerPkg.isDebuggable())) { 2479 // Downgrade is not permitted; a lower version of the app will not be allowed 2480 try { 2481 PackageManagerServiceUtils.checkDowngrade(dataOwnerPkg, pkgLite); 2482 } catch (PackageManagerException e) { 2483 String errorMsg = "Downgrade detected: " + e.getMessage(); 2484 Slog.w(TAG, errorMsg); 2485 return Pair.create( 2486 PackageManager.INSTALL_FAILED_VERSION_DOWNGRADE, errorMsg); 2487 } 2488 } else if (dataOwnerPs.isSystem()) { 2489 // Downgrade is permitted, but system apps can't be downgraded below 2490 // the version preloaded onto the system image 2491 final PackageSetting disabledPs = mPm.mSettings.getDisabledSystemPkgLPr( 2492 dataOwnerPs); 2493 if (disabledPs != null) { 2494 dataOwnerPkg = disabledPs.getPkg(); 2495 } 2496 if (!Build.IS_DEBUGGABLE && !dataOwnerPkg.isDebuggable()) { 2497 // Only restrict non-debuggable builds and non-debuggable version of the app 2498 try { 2499 PackageManagerServiceUtils.checkDowngrade(dataOwnerPkg, pkgLite); 2500 } catch (PackageManagerException e) { 2501 String errorMsg = 2502 "System app: " + packageName + " cannot be downgraded to" 2503 + " older than its preloaded version on the system" 2504 + " image. " + e.getMessage(); 2505 Slog.w(TAG, errorMsg); 2506 return Pair.create( 2507 PackageManager.INSTALL_FAILED_VERSION_DOWNGRADE, errorMsg); 2508 } 2509 } 2510 } 2511 } 2512 } 2513 return Pair.create(PackageManager.INSTALL_SUCCEEDED, null); 2514 } 2515 verifyReplacingVersionCodeForApex(PackageInfoLite pkgLite, long requiredInstalledVersionCode, int installFlags)2516 private Pair<Integer, String> verifyReplacingVersionCodeForApex(PackageInfoLite pkgLite, 2517 long requiredInstalledVersionCode, int installFlags) { 2518 String packageName = pkgLite.packageName; 2519 2520 final PackageInfo activePackage = mApexManager.getPackageInfo(packageName, 2521 ApexManager.MATCH_ACTIVE_PACKAGE); 2522 if (activePackage == null) { 2523 String errorMsg = "Attempting to install new APEX package " + packageName; 2524 Slog.w(TAG, errorMsg); 2525 return Pair.create(PackageManager.INSTALL_FAILED_PACKAGE_CHANGED, errorMsg); 2526 } 2527 2528 final long activeVersion = activePackage.getLongVersionCode(); 2529 if (requiredInstalledVersionCode != PackageManager.VERSION_CODE_HIGHEST 2530 && activeVersion != requiredInstalledVersionCode) { 2531 String errorMsg = "Installed version of APEX package " + packageName 2532 + " does not match required. Active version: " + activeVersion 2533 + " required: " + requiredInstalledVersionCode; 2534 Slog.w(TAG, errorMsg); 2535 return Pair.create(PackageManager.INSTALL_FAILED_WRONG_INSTALLED_VERSION, errorMsg); 2536 } 2537 2538 final boolean isAppDebuggable = (activePackage.applicationInfo.flags 2539 & ApplicationInfo.FLAG_DEBUGGABLE) != 0; 2540 final long newVersionCode = pkgLite.getLongVersionCode(); 2541 if (!PackageManagerServiceUtils.isDowngradePermitted(installFlags, isAppDebuggable) 2542 && newVersionCode < activeVersion) { 2543 String errorMsg = "Downgrade of APEX package " + packageName 2544 + " is not allowed. Active version: " + activeVersion 2545 + " attempted: " + newVersionCode; 2546 Slog.w(TAG, errorMsg); 2547 return Pair.create(PackageManager.INSTALL_FAILED_VERSION_DOWNGRADE, errorMsg); 2548 } 2549 2550 return Pair.create(PackageManager.INSTALL_SUCCEEDED, null); 2551 } 2552 getUidForVerifier(VerifierInfo verifierInfo)2553 int getUidForVerifier(VerifierInfo verifierInfo) { 2554 synchronized (mPm.mLock) { 2555 final AndroidPackage pkg = mPm.mPackages.get(verifierInfo.packageName); 2556 if (pkg == null) { 2557 return -1; 2558 } else if (pkg.getSigningDetails().getSignatures().length != 1) { 2559 Slog.i(TAG, "Verifier package " + verifierInfo.packageName 2560 + " has more than one signature; ignoring"); 2561 return -1; 2562 } 2563 2564 /* 2565 * If the public key of the package's signature does not match 2566 * our expected public key, then this is a different package and 2567 * we should skip. 2568 */ 2569 2570 final byte[] expectedPublicKey; 2571 try { 2572 final Signature verifierSig = pkg.getSigningDetails().getSignatures()[0]; 2573 final PublicKey publicKey = verifierSig.getPublicKey(); 2574 expectedPublicKey = publicKey.getEncoded(); 2575 } catch (CertificateException e) { 2576 return -1; 2577 } 2578 2579 final byte[] actualPublicKey = verifierInfo.publicKey.getEncoded(); 2580 2581 if (!Arrays.equals(actualPublicKey, expectedPublicKey)) { 2582 Slog.i(TAG, "Verifier package " + verifierInfo.packageName 2583 + " does not have the expected public key; ignoring"); 2584 return -1; 2585 } 2586 2587 return pkg.getUid(); 2588 } 2589 } 2590 sendPendingBroadcasts()2591 public void sendPendingBroadcasts() { 2592 String[] packages; 2593 ArrayList<String>[] components; 2594 int numBroadcasts = 0, numUsers; 2595 int[] uids; 2596 2597 synchronized (mPm.mLock) { 2598 final SparseArray<ArrayMap<String, ArrayList<String>>> userIdToPackagesToComponents = 2599 mPm.mPendingBroadcasts.copiedMap(); 2600 numUsers = userIdToPackagesToComponents.size(); 2601 for (int n = 0; n < numUsers; n++) { 2602 numBroadcasts += userIdToPackagesToComponents.valueAt(n).size(); 2603 } 2604 if (numBroadcasts == 0) { 2605 // Nothing to be done. Just return 2606 return; 2607 } 2608 packages = new String[numBroadcasts]; 2609 components = new ArrayList[numBroadcasts]; 2610 uids = new int[numBroadcasts]; 2611 int i = 0; // filling out the above arrays 2612 2613 for (int n = 0; n < numUsers; n++) { 2614 final int packageUserId = userIdToPackagesToComponents.keyAt(n); 2615 final ArrayMap<String, ArrayList<String>> componentsToBroadcast = 2616 userIdToPackagesToComponents.valueAt(n); 2617 final int numComponents = CollectionUtils.size(componentsToBroadcast); 2618 for (int index = 0; index < numComponents; index++) { 2619 packages[i] = componentsToBroadcast.keyAt(index); 2620 components[i] = componentsToBroadcast.valueAt(index); 2621 final PackageSetting ps = mPm.mSettings.getPackageLPr(packages[i]); 2622 uids[i] = (ps != null) 2623 ? UserHandle.getUid(packageUserId, ps.getAppId()) 2624 : -1; 2625 i++; 2626 } 2627 } 2628 numBroadcasts = i; 2629 mPm.mPendingBroadcasts.clear(); 2630 } 2631 final Computer snapshot = mPm.snapshotComputer(); 2632 // Send broadcasts 2633 for (int i = 0; i < numBroadcasts; i++) { 2634 mPm.sendPackageChangedBroadcast(snapshot, packages[i], true /* dontKillApp */, 2635 components[i], uids[i], null /* reason */); 2636 } 2637 } 2638 handlePackagePostInstall(PackageInstalledInfo res, InstallArgs installArgs, boolean launchedForRestore)2639 void handlePackagePostInstall(PackageInstalledInfo res, InstallArgs installArgs, 2640 boolean launchedForRestore) { 2641 final boolean killApp = 2642 (installArgs.mInstallFlags & PackageManager.INSTALL_DONT_KILL_APP) == 0; 2643 final boolean virtualPreload = 2644 ((installArgs.mInstallFlags & PackageManager.INSTALL_VIRTUAL_PRELOAD) != 0); 2645 final String installerPackage = installArgs.mInstallSource.installerPackageName; 2646 final IPackageInstallObserver2 installObserver = installArgs.mObserver; 2647 final int dataLoaderType = installArgs.mDataLoaderType; 2648 final boolean succeeded = res.mReturnCode == PackageManager.INSTALL_SUCCEEDED; 2649 final boolean update = res.mRemovedInfo != null && res.mRemovedInfo.mRemovedPackage != null; 2650 final String packageName = res.mName; 2651 final PackageStateInternal pkgSetting = 2652 succeeded ? mPm.snapshotComputer().getPackageStateInternal(packageName) : null; 2653 final boolean removedBeforeUpdate = (pkgSetting == null) 2654 || (pkgSetting.isSystem() && !pkgSetting.getPath().getPath().equals( 2655 res.mPkg.getPath())); 2656 if (succeeded && removedBeforeUpdate) { 2657 Slog.e(TAG, packageName + " was removed before handlePackagePostInstall " 2658 + "could be executed"); 2659 res.mReturnCode = INSTALL_FAILED_PACKAGE_CHANGED; 2660 res.mReturnMsg = "Package was removed before install could complete."; 2661 2662 // Remove the update failed package's older resources safely now 2663 InstallArgs args = res.mRemovedInfo != null ? res.mRemovedInfo.mArgs : null; 2664 if (args != null) { 2665 synchronized (mPm.mInstallLock) { 2666 args.doPostDeleteLI(true); 2667 } 2668 } 2669 mPm.notifyInstallObserver(res, installObserver); 2670 return; 2671 } 2672 2673 if (succeeded) { 2674 // Clear the uid cache after we installed a new package. 2675 mPm.mPerUidReadTimeoutsCache = null; 2676 2677 // Send the removed broadcasts 2678 if (res.mRemovedInfo != null) { 2679 if (res.mRemovedInfo.mIsExternal) { 2680 if (DEBUG_INSTALL) { 2681 Slog.i(TAG, "upgrading pkg " + res.mRemovedInfo.mRemovedPackage 2682 + " is ASEC-hosted -> UNAVAILABLE"); 2683 } 2684 final int[] uidArray = new int[]{res.mRemovedInfo.mUid}; 2685 final ArrayList<String> pkgList = new ArrayList<>(1); 2686 pkgList.add(res.mRemovedInfo.mRemovedPackage); 2687 mBroadcastHelper.sendResourcesChangedBroadcast( 2688 false, true, pkgList, uidArray, null); 2689 } 2690 res.mRemovedInfo.sendPackageRemovedBroadcasts(killApp, false /*removedBySystem*/); 2691 } 2692 2693 final String installerPackageName = 2694 res.mInstallerPackageName != null 2695 ? res.mInstallerPackageName 2696 : res.mRemovedInfo != null 2697 ? res.mRemovedInfo.mInstallerPackageName 2698 : null; 2699 2700 mPm.notifyInstantAppPackageInstalled(res.mPkg.getPackageName(), res.mNewUsers); 2701 2702 // Determine the set of users who are adding this package for 2703 // the first time vs. those who are seeing an update. 2704 int[] firstUserIds = EMPTY_INT_ARRAY; 2705 int[] firstInstantUserIds = EMPTY_INT_ARRAY; 2706 int[] updateUserIds = EMPTY_INT_ARRAY; 2707 int[] instantUserIds = EMPTY_INT_ARRAY; 2708 final boolean allNewUsers = res.mOrigUsers == null || res.mOrigUsers.length == 0; 2709 for (int newUser : res.mNewUsers) { 2710 final boolean isInstantApp = pkgSetting.getUserStateOrDefault(newUser) 2711 .isInstantApp(); 2712 if (allNewUsers) { 2713 if (isInstantApp) { 2714 firstInstantUserIds = ArrayUtils.appendInt(firstInstantUserIds, newUser); 2715 } else { 2716 firstUserIds = ArrayUtils.appendInt(firstUserIds, newUser); 2717 } 2718 continue; 2719 } 2720 boolean isNew = true; 2721 for (int origUser : res.mOrigUsers) { 2722 if (origUser == newUser) { 2723 isNew = false; 2724 break; 2725 } 2726 } 2727 if (isNew) { 2728 if (isInstantApp) { 2729 firstInstantUserIds = ArrayUtils.appendInt(firstInstantUserIds, newUser); 2730 } else { 2731 firstUserIds = ArrayUtils.appendInt(firstUserIds, newUser); 2732 } 2733 } else { 2734 if (isInstantApp) { 2735 instantUserIds = ArrayUtils.appendInt(instantUserIds, newUser); 2736 } else { 2737 updateUserIds = ArrayUtils.appendInt(updateUserIds, newUser); 2738 } 2739 } 2740 } 2741 2742 // Send installed broadcasts if the package is not a static shared lib. 2743 if (res.mPkg.getStaticSharedLibName() == null) { 2744 mPm.mProcessLoggingHandler.invalidateBaseApkHash(res.mPkg.getBaseApkPath()); 2745 2746 // Send added for users that see the package for the first time 2747 // sendPackageAddedForNewUsers also deals with system apps 2748 int appId = UserHandle.getAppId(res.mUid); 2749 boolean isSystem = res.mPkg.isSystem(); 2750 mPm.sendPackageAddedForNewUsers(mPm.snapshotComputer(), packageName, 2751 isSystem || virtualPreload, virtualPreload /*startReceiver*/, appId, 2752 firstUserIds, firstInstantUserIds, dataLoaderType); 2753 2754 // Send added for users that don't see the package for the first time 2755 Bundle extras = new Bundle(); 2756 extras.putInt(Intent.EXTRA_UID, res.mUid); 2757 if (update) { 2758 extras.putBoolean(Intent.EXTRA_REPLACING, true); 2759 } 2760 extras.putInt(PackageInstaller.EXTRA_DATA_LOADER_TYPE, dataLoaderType); 2761 // Send to all running apps. 2762 final SparseArray<int[]> newBroadcastAllowList; 2763 synchronized (mPm.mLock) { 2764 final Computer snapshot = mPm.snapshotComputer(); 2765 newBroadcastAllowList = mPm.mAppsFilter.getVisibilityAllowList(snapshot, 2766 snapshot.getPackageStateInternal(packageName, Process.SYSTEM_UID), 2767 updateUserIds, mPm.mSettings.getPackagesLocked()); 2768 } 2769 mPm.sendPackageBroadcast(Intent.ACTION_PACKAGE_ADDED, packageName, 2770 extras, 0 /*flags*/, 2771 null /*targetPackage*/, null /*finishedReceiver*/, 2772 updateUserIds, instantUserIds, newBroadcastAllowList, null); 2773 if (installerPackageName != null) { 2774 // Send to the installer, even if it's not running. 2775 mPm.sendPackageBroadcast(Intent.ACTION_PACKAGE_ADDED, packageName, 2776 extras, 0 /*flags*/, 2777 installerPackageName, null /*finishedReceiver*/, 2778 updateUserIds, instantUserIds, null /* broadcastAllowList */, null); 2779 } 2780 // if the required verifier is defined, but, is not the installer of record 2781 // for the package, it gets notified 2782 final boolean notifyVerifier = mPm.mRequiredVerifierPackage != null 2783 && !mPm.mRequiredVerifierPackage.equals(installerPackageName); 2784 if (notifyVerifier) { 2785 mPm.sendPackageBroadcast(Intent.ACTION_PACKAGE_ADDED, packageName, 2786 extras, 0 /*flags*/, 2787 mPm.mRequiredVerifierPackage, null /*finishedReceiver*/, 2788 updateUserIds, instantUserIds, null /* broadcastAllowList */, null); 2789 } 2790 // If package installer is defined, notify package installer about new 2791 // app installed 2792 if (mPm.mRequiredInstallerPackage != null) { 2793 mPm.sendPackageBroadcast(Intent.ACTION_PACKAGE_ADDED, packageName, 2794 extras, Intent.FLAG_RECEIVER_INCLUDE_BACKGROUND /*flags*/, 2795 mPm.mRequiredInstallerPackage, null /*finishedReceiver*/, 2796 firstUserIds, instantUserIds, null /* broadcastAllowList */, null); 2797 } 2798 2799 // Send replaced for users that don't see the package for the first time 2800 if (update) { 2801 mPm.sendPackageBroadcast(Intent.ACTION_PACKAGE_REPLACED, 2802 packageName, extras, 0 /*flags*/, 2803 null /*targetPackage*/, null /*finishedReceiver*/, 2804 updateUserIds, instantUserIds, res.mRemovedInfo.mBroadcastAllowList, 2805 null); 2806 if (installerPackageName != null) { 2807 mPm.sendPackageBroadcast(Intent.ACTION_PACKAGE_REPLACED, packageName, 2808 extras, 0 /*flags*/, 2809 installerPackageName, null /*finishedReceiver*/, 2810 updateUserIds, instantUserIds, null /*broadcastAllowList*/, 2811 null); 2812 } 2813 if (notifyVerifier) { 2814 mPm.sendPackageBroadcast(Intent.ACTION_PACKAGE_REPLACED, packageName, 2815 extras, 0 /*flags*/, 2816 mPm.mRequiredVerifierPackage, null /*finishedReceiver*/, 2817 updateUserIds, instantUserIds, null /*broadcastAllowList*/, 2818 null); 2819 } 2820 mPm.sendPackageBroadcast(Intent.ACTION_MY_PACKAGE_REPLACED, 2821 null /*package*/, null /*extras*/, 0 /*flags*/, 2822 packageName /*targetPackage*/, 2823 null /*finishedReceiver*/, updateUserIds, instantUserIds, 2824 null /*broadcastAllowList*/, 2825 mBroadcastHelper.getTemporaryAppAllowlistBroadcastOptions( 2826 REASON_PACKAGE_REPLACED).toBundle()); 2827 } else if (launchedForRestore && !res.mPkg.isSystem()) { 2828 // First-install and we did a restore, so we're responsible for the 2829 // first-launch broadcast. 2830 if (DEBUG_BACKUP) { 2831 Slog.i(TAG, "Post-restore of " + packageName 2832 + " sending FIRST_LAUNCH in " + Arrays.toString(firstUserIds)); 2833 } 2834 mBroadcastHelper.sendFirstLaunchBroadcast(packageName, installerPackage, 2835 firstUserIds, firstInstantUserIds); 2836 } 2837 2838 // Send broadcast package appeared if external for all users 2839 if (res.mPkg.isExternalStorage()) { 2840 if (!update) { 2841 final StorageManager storageManager = 2842 mInjector.getSystemService(StorageManager.class); 2843 VolumeInfo volume = 2844 storageManager.findVolumeByUuid( 2845 StorageManager.convert( 2846 res.mPkg.getVolumeUuid()).toString()); 2847 int packageExternalStorageType = 2848 PackageManagerServiceUtils.getPackageExternalStorageType(volume, 2849 res.mPkg.isExternalStorage()); 2850 // If the package was installed externally, log it. 2851 if (packageExternalStorageType != StorageEnums.UNKNOWN) { 2852 FrameworkStatsLog.write( 2853 FrameworkStatsLog.APP_INSTALL_ON_EXTERNAL_STORAGE_REPORTED, 2854 packageExternalStorageType, packageName); 2855 } 2856 } 2857 if (DEBUG_INSTALL) { 2858 Slog.i(TAG, "upgrading pkg " + res.mPkg + " is external"); 2859 } 2860 final int[] uidArray = new int[]{res.mPkg.getUid()}; 2861 ArrayList<String> pkgList = new ArrayList<>(1); 2862 pkgList.add(packageName); 2863 mBroadcastHelper.sendResourcesChangedBroadcast( 2864 true, true, pkgList, uidArray, null); 2865 } 2866 } else if (!ArrayUtils.isEmpty(res.mLibraryConsumers)) { // if static shared lib 2867 // No need to kill consumers if it's installation of new version static shared lib. 2868 final Computer snapshot = mPm.snapshotComputer(); 2869 final boolean dontKillApp = !update && res.mPkg.getStaticSharedLibName() != null; 2870 for (int i = 0; i < res.mLibraryConsumers.size(); i++) { 2871 AndroidPackage pkg = res.mLibraryConsumers.get(i); 2872 // send broadcast that all consumers of the static shared library have changed 2873 mPm.sendPackageChangedBroadcast(snapshot, pkg.getPackageName(), dontKillApp, 2874 new ArrayList<>(Collections.singletonList(pkg.getPackageName())), 2875 pkg.getUid(), null); 2876 } 2877 } 2878 2879 // Work that needs to happen on first install within each user 2880 if (firstUserIds.length > 0) { 2881 for (int userId : firstUserIds) { 2882 mPm.restorePermissionsAndUpdateRolesForNewUserInstall(packageName, 2883 userId); 2884 } 2885 } 2886 2887 if (allNewUsers && !update) { 2888 mPm.notifyPackageAdded(packageName, res.mUid); 2889 } else { 2890 mPm.notifyPackageChanged(packageName, res.mUid); 2891 } 2892 2893 // Log current value of "unknown sources" setting 2894 EventLog.writeEvent(EventLogTags.UNKNOWN_SOURCES_ENABLED, 2895 getUnknownSourcesSettings()); 2896 2897 // Remove the replaced package's older resources safely now 2898 InstallArgs args = res.mRemovedInfo != null ? res.mRemovedInfo.mArgs : null; 2899 if (args != null) { 2900 if (!killApp) { 2901 // If we didn't kill the app, defer the deletion of code/resource files, since 2902 // they may still be in use by the running application. This mitigates problems 2903 // in cases where resources or code is loaded by a new Activity before 2904 // ApplicationInfo changes have propagated to all application threads. 2905 mPm.scheduleDeferredNoKillPostDelete(args); 2906 } else { 2907 synchronized (mPm.mInstallLock) { 2908 args.doPostDeleteLI(true); 2909 } 2910 } 2911 } else { 2912 // Force a gc to clear up things. Ask for a background one, it's fine to go on 2913 // and not block here. 2914 VMRuntime.getRuntime().requestConcurrentGC(); 2915 } 2916 2917 final Computer snapshot = mPm.snapshotComputer(); 2918 // Notify DexManager that the package was installed for new users. 2919 // The updated users should already be indexed and the package code paths 2920 // should not change. 2921 // Don't notify the manager for ephemeral apps as they are not expected to 2922 // survive long enough to benefit of background optimizations. 2923 for (int userId : firstUserIds) { 2924 PackageInfo info = snapshot.getPackageInfo(packageName, /*flags*/ 0, userId); 2925 // There's a race currently where some install events may interleave with an 2926 // uninstall. This can lead to package info being null (b/36642664). 2927 if (info != null) { 2928 mDexManager.notifyPackageInstalled(info, userId); 2929 } 2930 } 2931 } 2932 2933 final boolean deferInstallObserver = succeeded && update; 2934 if (deferInstallObserver) { 2935 if (killApp) { 2936 mPm.scheduleDeferredPendingKillInstallObserver(res, installObserver); 2937 } else { 2938 mPm.scheduleDeferredNoKillInstallObserver(res, installObserver); 2939 } 2940 } else { 2941 mPm.notifyInstallObserver(res, installObserver); 2942 } 2943 2944 // Prune unused static shared libraries which have been cached a period of time 2945 mPm.schedulePruneUnusedStaticSharedLibraries(true /* delay */); 2946 2947 // Log tracing if needed 2948 if (installArgs.mTraceMethod != null) { 2949 Trace.asyncTraceEnd(TRACE_TAG_PACKAGE_MANAGER, installArgs.mTraceMethod, 2950 installArgs.mTraceCookie); 2951 } 2952 } 2953 2954 /** 2955 * Get the "allow unknown sources" setting. 2956 * 2957 * @return the current "allow unknown sources" setting 2958 */ getUnknownSourcesSettings()2959 private int getUnknownSourcesSettings() { 2960 return android.provider.Settings.Secure.getIntForUser(mContext.getContentResolver(), 2961 android.provider.Settings.Secure.INSTALL_NON_MARKET_APPS, 2962 -1, UserHandle.USER_SYSTEM); 2963 } 2964 2965 /** 2966 * Uncompress and install stub applications. 2967 * <p>In order to save space on the system partition, some applications are shipped in a 2968 * compressed form. In addition the compressed bits for the full application, the 2969 * system image contains a tiny stub comprised of only the Android manifest. 2970 * <p>During the first boot, attempt to uncompress and install the full application. If 2971 * the application can't be installed for any reason, disable the stub and prevent 2972 * uncompressing the full application during future boots. 2973 * <p>In order to forcefully attempt an installation of a full application, go to app 2974 * settings and enable the application. 2975 */ 2976 @GuardedBy({"mPm.mLock", "mPm.mInstallLock"}) installSystemStubPackages(@onNull List<String> systemStubPackageNames, @PackageManagerService.ScanFlags int scanFlags)2977 void installSystemStubPackages(@NonNull List<String> systemStubPackageNames, 2978 @PackageManagerService.ScanFlags int scanFlags) { 2979 for (int i = systemStubPackageNames.size() - 1; i >= 0; --i) { 2980 final String packageName = systemStubPackageNames.get(i); 2981 // skip if the system package is already disabled 2982 if (mPm.mSettings.isDisabledSystemPackageLPr(packageName)) { 2983 systemStubPackageNames.remove(i); 2984 continue; 2985 } 2986 // skip if the package isn't installed (?!); this should never happen 2987 final AndroidPackage pkg = mPm.mPackages.get(packageName); 2988 if (pkg == null) { 2989 systemStubPackageNames.remove(i); 2990 continue; 2991 } 2992 // skip if the package has been disabled by the user 2993 final PackageSetting ps = mPm.mSettings.getPackageLPr(packageName); 2994 if (ps != null) { 2995 final int enabledState = ps.getEnabled(UserHandle.USER_SYSTEM); 2996 if (enabledState == PackageManager.COMPONENT_ENABLED_STATE_DISABLED_USER) { 2997 systemStubPackageNames.remove(i); 2998 continue; 2999 } 3000 } 3001 3002 // install the package to replace the stub on /system 3003 try { 3004 installStubPackageLI(pkg, 0, scanFlags); 3005 ps.setEnabled(PackageManager.COMPONENT_ENABLED_STATE_DEFAULT, 3006 UserHandle.USER_SYSTEM, "android"); 3007 systemStubPackageNames.remove(i); 3008 } catch (PackageManagerException e) { 3009 Slog.e(TAG, "Failed to parse uncompressed system package: " + e.getMessage()); 3010 } 3011 3012 // any failed attempt to install the package will be cleaned up later 3013 } 3014 3015 // disable any stub still left; these failed to install the full application 3016 for (int i = systemStubPackageNames.size() - 1; i >= 0; --i) { 3017 final String pkgName = systemStubPackageNames.get(i); 3018 final PackageSetting ps = mPm.mSettings.getPackageLPr(pkgName); 3019 ps.setEnabled(PackageManager.COMPONENT_ENABLED_STATE_DISABLED, 3020 UserHandle.USER_SYSTEM, "android"); 3021 logCriticalInfo(Log.ERROR, "Stub disabled; pkg: " + pkgName); 3022 } 3023 } 3024 3025 /** 3026 * Extract, install and enable a stub package. 3027 * <p>If the compressed file can not be extracted / installed for any reason, the stub 3028 * APK will be installed and the package will be disabled. To recover from this situation, 3029 * the user will need to go into system settings and re-enable the package. 3030 */ enableCompressedPackage(AndroidPackage stubPkg, @NonNull PackageSetting stubPkgSetting)3031 boolean enableCompressedPackage(AndroidPackage stubPkg, 3032 @NonNull PackageSetting stubPkgSetting) { 3033 final int parseFlags = mPm.getDefParseFlags() | ParsingPackageUtils.PARSE_CHATTY 3034 | ParsingPackageUtils.PARSE_ENFORCE_CODE; 3035 synchronized (mPm.mInstallLock) { 3036 final AndroidPackage pkg; 3037 try (PackageFreezer freezer = 3038 mPm.freezePackage(stubPkg.getPackageName(), "setEnabledSetting")) { 3039 pkg = installStubPackageLI(stubPkg, parseFlags, 0 /*scanFlags*/); 3040 mAppDataHelper.prepareAppDataAfterInstallLIF(pkg); 3041 synchronized (mPm.mLock) { 3042 try { 3043 mSharedLibraries.updateSharedLibrariesLPw( 3044 pkg, stubPkgSetting, null, null, 3045 Collections.unmodifiableMap(mPm.mPackages)); 3046 } catch (PackageManagerException e) { 3047 Slog.w(TAG, "updateAllSharedLibrariesLPw failed: ", e); 3048 } 3049 mPm.mPermissionManager.onPackageInstalled(pkg, 3050 Process.INVALID_UID /* previousAppId */, 3051 PermissionManagerServiceInternal.PackageInstalledParams.DEFAULT, 3052 UserHandle.USER_ALL); 3053 mPm.writeSettingsLPrTEMP(); 3054 // Since compressed package can be system app only, we do not need to 3055 // set restricted settings on it. 3056 } 3057 } catch (PackageManagerException e) { 3058 // Whoops! Something went very wrong; roll back to the stub and disable the package 3059 try (PackageFreezer freezer = 3060 mPm.freezePackage(stubPkg.getPackageName(), "setEnabledSetting")) { 3061 synchronized (mPm.mLock) { 3062 // NOTE: Ensure the system package is enabled; even for a compressed stub. 3063 // If we don't, installing the system package fails during scan 3064 mPm.mSettings.enableSystemPackageLPw(stubPkg.getPackageName()); 3065 } 3066 installPackageFromSystemLIF(stubPkg.getPath(), 3067 mPm.mUserManager.getUserIds() /*allUserHandles*/, 3068 null /*origUserHandles*/, 3069 true /*writeSettings*/); 3070 } catch (PackageManagerException pme) { 3071 // Serious WTF; we have to be able to install the stub 3072 Slog.wtf(TAG, "Failed to restore system package:" + stubPkg.getPackageName(), 3073 pme); 3074 } finally { 3075 // Disable the package; the stub by itself is not runnable 3076 synchronized (mPm.mLock) { 3077 final PackageSetting stubPs = mPm.mSettings.getPackageLPr( 3078 stubPkg.getPackageName()); 3079 if (stubPs != null) { 3080 stubPs.setEnabled(COMPONENT_ENABLED_STATE_DISABLED, 3081 UserHandle.USER_SYSTEM, "android"); 3082 } 3083 mPm.writeSettingsLPrTEMP(); 3084 } 3085 } 3086 return false; 3087 } 3088 mAppDataHelper.clearAppDataLIF(pkg, UserHandle.USER_ALL, 3089 FLAG_STORAGE_DE | FLAG_STORAGE_CE | FLAG_STORAGE_EXTERNAL 3090 | Installer.FLAG_CLEAR_CODE_CACHE_ONLY); 3091 mDexManager.notifyPackageUpdated(pkg.getPackageName(), 3092 pkg.getBaseApkPath(), pkg.getSplitCodePaths()); 3093 } 3094 return true; 3095 } 3096 3097 @GuardedBy("mPm.mInstallLock") installStubPackageLI(AndroidPackage stubPkg, @ParsingPackageUtils.ParseFlags int parseFlags, @PackageManagerService.ScanFlags int scanFlags)3098 private AndroidPackage installStubPackageLI(AndroidPackage stubPkg, 3099 @ParsingPackageUtils.ParseFlags int parseFlags, 3100 @PackageManagerService.ScanFlags int scanFlags) 3101 throws PackageManagerException { 3102 if (DEBUG_COMPRESSION) { 3103 Slog.i(TAG, "Uncompressing system stub; pkg: " + stubPkg.getPackageName()); 3104 } 3105 // uncompress the binary to its eventual destination on /data 3106 final File scanFile = decompressPackage(stubPkg.getPackageName(), stubPkg.getPath()); 3107 if (scanFile == null) { 3108 throw new PackageManagerException( 3109 "Unable to decompress stub at " + stubPkg.getPath()); 3110 } 3111 synchronized (mPm.mLock) { 3112 mPm.mSettings.disableSystemPackageLPw(stubPkg.getPackageName(), true /*replaced*/); 3113 } 3114 final RemovePackageHelper removePackageHelper = new RemovePackageHelper(mPm); 3115 removePackageHelper.removePackageLI(stubPkg, true /*chatty*/); 3116 try { 3117 return scanSystemPackageTracedLI(scanFile, parseFlags, scanFlags, null); 3118 } catch (PackageManagerException e) { 3119 Slog.w(TAG, "Failed to install compressed system package:" + stubPkg.getPackageName(), 3120 e); 3121 // Remove the failed install 3122 removePackageHelper.removeCodePathLI(scanFile); 3123 throw e; 3124 } 3125 } 3126 3127 /** 3128 * Decompresses the given package on the system image onto 3129 * the /data partition. 3130 * @return The directory the package was decompressed into. Otherwise, {@code null}. 3131 */ 3132 @GuardedBy("mPm.mInstallLock") decompressPackage(String packageName, String codePath)3133 private File decompressPackage(String packageName, String codePath) { 3134 if (!compressedFileExists(codePath)) { 3135 if (DEBUG_COMPRESSION) { 3136 Slog.i(TAG, "No files to decompress at: " + codePath); 3137 } 3138 return null; 3139 } 3140 final File dstCodePath = 3141 PackageManagerServiceUtils.getNextCodePath(Environment.getDataAppDirectory(null), 3142 packageName); 3143 int ret = PackageManagerServiceUtils.decompressFiles(codePath, dstCodePath, packageName); 3144 if (ret == PackageManager.INSTALL_SUCCEEDED) { 3145 ret = PackageManagerServiceUtils.extractNativeBinaries(dstCodePath, packageName); 3146 } 3147 if (ret == PackageManager.INSTALL_SUCCEEDED) { 3148 // NOTE: During boot, we have to delay releasing cblocks for no other reason than 3149 // we cannot retrieve the setting {@link Secure#RELEASE_COMPRESS_BLOCKS_ON_INSTALL}. 3150 // When we no longer need to read that setting, cblock release can occur always 3151 // occur here directly 3152 if (!mPm.isSystemReady()) { 3153 if (mPm.mReleaseOnSystemReady == null) { 3154 mPm.mReleaseOnSystemReady = new ArrayList<>(); 3155 } 3156 mPm.mReleaseOnSystemReady.add(dstCodePath); 3157 } else { 3158 final ContentResolver resolver = mContext.getContentResolver(); 3159 F2fsUtils.releaseCompressedBlocks(resolver, dstCodePath); 3160 } 3161 } else { 3162 if (!dstCodePath.exists()) { 3163 return null; 3164 } 3165 new RemovePackageHelper(mPm).removeCodePathLI(dstCodePath); 3166 return null; 3167 } 3168 3169 return dstCodePath; 3170 } 3171 3172 /** 3173 * Tries to restore the disabled system package after an update has been deleted. 3174 */ restoreDisabledSystemPackageLIF(DeletePackageAction action, @NonNull int[] allUserHandles, boolean writeSettings)3175 public void restoreDisabledSystemPackageLIF(DeletePackageAction action, 3176 @NonNull int[] allUserHandles, boolean writeSettings) throws SystemDeleteException { 3177 final PackageSetting deletedPs = action.mDeletingPs; 3178 final PackageRemovedInfo outInfo = action.mRemovedInfo; 3179 final PackageSetting disabledPs = action.mDisabledPs; 3180 3181 synchronized (mPm.mLock) { 3182 // NOTE: The system package always needs to be enabled; even if it's for 3183 // a compressed stub. If we don't, installing the system package fails 3184 // during scan [scanning checks the disabled packages]. We will reverse 3185 // this later, after we've "installed" the stub. 3186 // Reinstate the old system package 3187 mPm.mSettings.enableSystemPackageLPw(disabledPs.getPkg().getPackageName()); 3188 // Remove any native libraries from the upgraded package. 3189 PackageManagerServiceUtils.removeNativeBinariesLI(deletedPs); 3190 } 3191 // Install the system package 3192 if (DEBUG_REMOVE) Slog.d(TAG, "Re-installing system package: " + disabledPs); 3193 try { 3194 synchronized (mPm.mInstallLock) { 3195 final int[] origUsers = outInfo == null ? null : outInfo.mOrigUsers; 3196 installPackageFromSystemLIF(disabledPs.getPathString(), allUserHandles, 3197 origUsers, writeSettings); 3198 } 3199 } catch (PackageManagerException e) { 3200 Slog.w(TAG, "Failed to restore system package:" + deletedPs.getPackageName() + ": " 3201 + e.getMessage()); 3202 // TODO(b/194319951): can we avoid this; throw would come from scan... 3203 throw new SystemDeleteException(e); 3204 } finally { 3205 if (disabledPs.getPkg().isStub()) { 3206 // We've re-installed the stub; make sure it's disabled here. If package was 3207 // originally enabled, we'll install the compressed version of the application 3208 // and re-enable it afterward. 3209 synchronized (mPm.mLock) { 3210 disableStubPackage(action, deletedPs, allUserHandles); 3211 } 3212 } 3213 } 3214 } 3215 3216 @GuardedBy("mPm.mLock") disableStubPackage(DeletePackageAction action, PackageSetting deletedPs, @NonNull int[] allUserHandles)3217 private void disableStubPackage(DeletePackageAction action, PackageSetting deletedPs, 3218 @NonNull int[] allUserHandles) { 3219 final PackageSetting stubPs = mPm.mSettings.getPackageLPr( 3220 deletedPs.getPackageName()); 3221 if (stubPs != null) { 3222 int userId = action.mUser == null 3223 ? UserHandle.USER_ALL : action.mUser.getIdentifier(); 3224 if (userId == UserHandle.USER_ALL) { 3225 for (int aUserId : allUserHandles) { 3226 stubPs.setEnabled(COMPONENT_ENABLED_STATE_DISABLED, aUserId, "android"); 3227 } 3228 } else if (userId >= UserHandle.USER_SYSTEM) { 3229 stubPs.setEnabled(COMPONENT_ENABLED_STATE_DISABLED, userId, "android"); 3230 } 3231 } 3232 } 3233 3234 /** 3235 * Installs a package that's already on the system partition. 3236 */ 3237 @GuardedBy("mPm.mInstallLock") installPackageFromSystemLIF(@onNull String codePathString, @NonNull int[] allUserHandles, @Nullable int[] origUserHandles, boolean writeSettings)3238 private void installPackageFromSystemLIF(@NonNull String codePathString, 3239 @NonNull int[] allUserHandles, @Nullable int[] origUserHandles, 3240 boolean writeSettings) 3241 throws PackageManagerException { 3242 final File codePath = new File(codePathString); 3243 @ParsingPackageUtils.ParseFlags int parseFlags = 3244 mPm.getDefParseFlags() 3245 | ParsingPackageUtils.PARSE_MUST_BE_APK 3246 | ParsingPackageUtils.PARSE_IS_SYSTEM_DIR; 3247 @PackageManagerService.ScanFlags int scanFlags = mPm.getSystemPackageScanFlags(codePath); 3248 final AndroidPackage pkg = scanSystemPackageTracedLI( 3249 codePath, parseFlags, scanFlags, null); 3250 3251 PackageSetting pkgSetting = mPm.mSettings.getPackageLPr(pkg.getPackageName()); 3252 3253 try { 3254 // update shared libraries for the newly re-installed system package 3255 mSharedLibraries.updateSharedLibrariesLPw(pkg, pkgSetting, null, null, 3256 Collections.unmodifiableMap(mPm.mPackages)); 3257 } catch (PackageManagerException e) { 3258 Slog.e(TAG, "updateAllSharedLibrariesLPw failed: " + e.getMessage()); 3259 } 3260 3261 mAppDataHelper.prepareAppDataAfterInstallLIF(pkg); 3262 3263 setPackageInstalledForSystemPackage(pkg, allUserHandles, origUserHandles, writeSettings); 3264 } 3265 setPackageInstalledForSystemPackage(@onNull AndroidPackage pkg, @NonNull int[] allUserHandles, @Nullable int[] origUserHandles, boolean writeSettings)3266 private void setPackageInstalledForSystemPackage(@NonNull AndroidPackage pkg, 3267 @NonNull int[] allUserHandles, @Nullable int[] origUserHandles, 3268 boolean writeSettings) { 3269 // writer 3270 synchronized (mPm.mLock) { 3271 PackageSetting ps = mPm.mSettings.getPackageLPr(pkg.getPackageName()); 3272 3273 final boolean applyUserRestrictions = origUserHandles != null; 3274 if (applyUserRestrictions) { 3275 boolean installedStateChanged = false; 3276 if (DEBUG_REMOVE) { 3277 Slog.d(TAG, "Propagating install state across reinstall"); 3278 } 3279 for (int userId : allUserHandles) { 3280 final boolean installed = ArrayUtils.contains(origUserHandles, userId); 3281 if (DEBUG_REMOVE) { 3282 Slog.d(TAG, " user " + userId + " => " + installed); 3283 } 3284 if (installed != ps.getInstalled(userId)) { 3285 installedStateChanged = true; 3286 } 3287 ps.setInstalled(installed, userId); 3288 if (installed) { 3289 ps.setUninstallReason(UNINSTALL_REASON_UNKNOWN, userId); 3290 } 3291 } 3292 // Regardless of writeSettings we need to ensure that this restriction 3293 // state propagation is persisted 3294 mPm.mSettings.writeAllUsersPackageRestrictionsLPr(); 3295 if (installedStateChanged) { 3296 mPm.mSettings.writeKernelMappingLPr(ps); 3297 } 3298 } 3299 3300 // The method below will take care of removing obsolete permissions and granting 3301 // install permissions. 3302 mPm.mPermissionManager.onPackageInstalled(pkg, Process.INVALID_UID, 3303 PermissionManagerServiceInternal.PackageInstalledParams.DEFAULT, 3304 UserHandle.USER_ALL); 3305 for (final int userId : allUserHandles) { 3306 if (applyUserRestrictions) { 3307 mPm.mSettings.writePermissionStateForUserLPr(userId, false); 3308 } 3309 } 3310 3311 // can downgrade to reader here 3312 if (writeSettings) { 3313 mPm.writeSettingsLPrTEMP(); 3314 } 3315 } 3316 } 3317 3318 @GuardedBy("mPm.mLock") prepareSystemPackageCleanUp( WatchedArrayMap<String, PackageSetting> packageSettings, List<String> possiblyDeletedUpdatedSystemApps, ArrayMap<String, File> expectingBetter, int[] userIds)3319 public void prepareSystemPackageCleanUp( 3320 WatchedArrayMap<String, PackageSetting> packageSettings, 3321 List<String> possiblyDeletedUpdatedSystemApps, 3322 ArrayMap<String, File> expectingBetter, int[] userIds) { 3323 // Iterates PackageSettings in reversed order because the item could be removed 3324 // during the iteration. 3325 for (int index = packageSettings.size() - 1; index >= 0; index--) { 3326 final PackageSetting ps = packageSettings.valueAt(index); 3327 final String packageName = ps.getPackageName(); 3328 /* 3329 * If this is not a system app, it can't be a 3330 * disable system app. 3331 */ 3332 if (!ps.isSystem()) { 3333 continue; 3334 } 3335 3336 /* 3337 * If the package is scanned, it's not erased. 3338 */ 3339 final AndroidPackage scannedPkg = mPm.mPackages.get(packageName); 3340 final PackageSetting disabledPs = 3341 mPm.mSettings.getDisabledSystemPkgLPr(packageName); 3342 if (scannedPkg != null) { 3343 /* 3344 * If the system app is both scanned and in the 3345 * disabled packages list, then it must have been 3346 * added via OTA. Remove it from the currently 3347 * scanned package so the previously user-installed 3348 * application can be scanned. 3349 */ 3350 if (disabledPs != null) { 3351 logCriticalInfo(Log.WARN, 3352 "Expecting better updated system app for " 3353 + packageName 3354 + "; removing system app. Last known" 3355 + " codePath=" + ps.getPathString() 3356 + ", versionCode=" + ps.getVersionCode() 3357 + "; scanned versionCode=" 3358 + scannedPkg.getLongVersionCode()); 3359 mRemovePackageHelper.removePackageLI(scannedPkg, true); 3360 expectingBetter.put(ps.getPackageName(), ps.getPath()); 3361 } 3362 3363 continue; 3364 } 3365 3366 if (disabledPs == null) { 3367 logCriticalInfo(Log.WARN, "System package " + packageName 3368 + " no longer exists; its data will be wiped"); 3369 mRemovePackageHelper.removePackageDataLIF(ps, userIds, null, 0, false); 3370 } else { 3371 // we still have a disabled system package, but, it still might have 3372 // been removed. check the code path still exists and check there's 3373 // still a package. the latter can happen if an OTA keeps the same 3374 // code path, but, changes the package name. 3375 if (disabledPs.getPath() == null || !disabledPs.getPath().exists() 3376 || disabledPs.getPkg() == null) { 3377 possiblyDeletedUpdatedSystemApps.add(packageName); 3378 } else { 3379 // We're expecting that the system app should remain disabled, but add 3380 // it to expecting better to recover in case the data version cannot 3381 // be scanned. 3382 expectingBetter.put(disabledPs.getPackageName(), disabledPs.getPath()); 3383 } 3384 } 3385 } 3386 } 3387 3388 @GuardedBy("mPm.mLock") 3389 // Remove disable package settings for updated system apps that were 3390 // removed via an OTA. If the update is no longer present, remove the 3391 // app completely. Otherwise, revoke their system privileges. cleanupDisabledPackageSettings(List<String> possiblyDeletedUpdatedSystemApps, int[] userIds, int scanFlags)3392 public void cleanupDisabledPackageSettings(List<String> possiblyDeletedUpdatedSystemApps, 3393 int[] userIds, int scanFlags) { 3394 for (int i = possiblyDeletedUpdatedSystemApps.size() - 1; i >= 0; --i) { 3395 final String packageName = possiblyDeletedUpdatedSystemApps.get(i); 3396 final AndroidPackage pkg = mPm.mPackages.get(packageName); 3397 final String msg; 3398 3399 // remove from the disabled system list; do this first so any future 3400 // scans of this package are performed without this state 3401 mPm.mSettings.removeDisabledSystemPackageLPw(packageName); 3402 3403 if (pkg == null) { 3404 // should have found an update, but, we didn't; remove everything 3405 msg = "Updated system package " + packageName 3406 + " no longer exists; removing its data"; 3407 // Actual deletion of code and data will be handled by later 3408 // reconciliation step 3409 } else { 3410 // found an update; revoke system privileges 3411 msg = "Updated system package " + packageName 3412 + " no longer exists; rescanning package on data"; 3413 3414 // NOTE: We don't do anything special if a stub is removed from the 3415 // system image. But, if we were [like removing the uncompressed 3416 // version from the /data partition], this is where it'd be done. 3417 3418 // remove the package from the system and re-scan it without any 3419 // special privileges 3420 mRemovePackageHelper.removePackageLI(pkg, true); 3421 try { 3422 final File codePath = new File(pkg.getPath()); 3423 scanSystemPackageTracedLI(codePath, 0, scanFlags, null); 3424 } catch (PackageManagerException e) { 3425 Slog.e(TAG, "Failed to parse updated, ex-system package: " 3426 + e.getMessage()); 3427 } 3428 } 3429 3430 // one final check. if we still have a package setting [ie. it was 3431 // previously scanned and known to the system], but, we don't have 3432 // a package [ie. there was an error scanning it from the /data 3433 // partition], completely remove the package data. 3434 final PackageSetting ps = mPm.mSettings.getPackageLPr(packageName); 3435 if (ps != null && mPm.mPackages.get(packageName) == null) { 3436 mRemovePackageHelper.removePackageDataLIF(ps, userIds, null, 0, false); 3437 } 3438 logCriticalInfo(Log.WARN, msg); 3439 } 3440 } 3441 3442 @GuardedBy({"mPm.mInstallLock", "mPm.mLock"}) installPackagesFromDir(File scanDir, List<File> frameworkSplits, int parseFlags, int scanFlags, PackageParser2 packageParser, ExecutorService executorService)3443 public void installPackagesFromDir(File scanDir, List<File> frameworkSplits, int parseFlags, 3444 int scanFlags, PackageParser2 packageParser, 3445 ExecutorService executorService) { 3446 final File[] files = scanDir.listFiles(); 3447 if (ArrayUtils.isEmpty(files)) { 3448 Log.d(TAG, "No files in app dir " + scanDir); 3449 return; 3450 } 3451 3452 if (DEBUG_PACKAGE_SCANNING) { 3453 Log.d(TAG, "Scanning app dir " + scanDir + " scanFlags=" + scanFlags 3454 + " flags=0x" + Integer.toHexString(parseFlags)); 3455 } 3456 ParallelPackageParser parallelPackageParser = 3457 new ParallelPackageParser(packageParser, executorService, frameworkSplits); 3458 3459 // Submit files for parsing in parallel 3460 int fileCount = 0; 3461 for (File file : files) { 3462 final boolean isPackage = (isApkFile(file) || file.isDirectory()) 3463 && !PackageInstallerService.isStageName(file.getName()); 3464 if (!isPackage) { 3465 // Ignore entries which are not packages 3466 continue; 3467 } 3468 if ((scanFlags & SCAN_DROP_CACHE) != 0) { 3469 final PackageCacher cacher = new PackageCacher(mPm.getCacheDir()); 3470 Log.w(TAG, "Dropping cache of " + file.getAbsolutePath()); 3471 cacher.cleanCachedResult(file); 3472 } 3473 parallelPackageParser.submit(file, parseFlags); 3474 fileCount++; 3475 } 3476 3477 // Process results one by one 3478 for (; fileCount > 0; fileCount--) { 3479 ParallelPackageParser.ParseResult parseResult = parallelPackageParser.take(); 3480 Throwable throwable = parseResult.throwable; 3481 int errorCode = PackageManager.INSTALL_SUCCEEDED; 3482 String errorMsg = null; 3483 3484 if (throwable == null) { 3485 // TODO(b/194319951): move lower in the scan chain 3486 // Static shared libraries have synthetic package names 3487 if (parseResult.parsedPackage.isStaticSharedLibrary()) { 3488 PackageManagerService.renameStaticSharedLibraryPackage( 3489 parseResult.parsedPackage); 3490 } 3491 try { 3492 addForInitLI(parseResult.parsedPackage, parseFlags, scanFlags, 3493 null); 3494 } catch (PackageManagerException e) { 3495 errorCode = e.error; 3496 errorMsg = "Failed to scan " + parseResult.scanFile + ": " + e.getMessage(); 3497 Slog.w(TAG, errorMsg); 3498 } 3499 } else if (throwable instanceof PackageManagerException) { 3500 PackageManagerException e = (PackageManagerException) throwable; 3501 errorCode = e.error; 3502 errorMsg = "Failed to parse " + parseResult.scanFile + ": " + e.getMessage(); 3503 Slog.w(TAG, errorMsg); 3504 } else { 3505 throw new IllegalStateException("Unexpected exception occurred while parsing " 3506 + parseResult.scanFile, throwable); 3507 } 3508 3509 if ((scanFlags & SCAN_AS_APK_IN_APEX) != 0 && errorCode != INSTALL_SUCCEEDED) { 3510 mApexManager.reportErrorWithApkInApex(scanDir.getAbsolutePath(), errorMsg); 3511 } 3512 3513 // Delete invalid userdata apps 3514 if ((scanFlags & SCAN_AS_SYSTEM) == 0 3515 && errorCode != PackageManager.INSTALL_SUCCEEDED) { 3516 logCriticalInfo(Log.WARN, 3517 "Deleting invalid package at " + parseResult.scanFile); 3518 mRemovePackageHelper.removeCodePathLI(parseResult.scanFile); 3519 } 3520 } 3521 } 3522 3523 /** 3524 * Make sure all system apps that we expected to appear on 3525 * the userdata partition actually showed up. If they never 3526 * appeared, crawl back and revive the system version. 3527 */ 3528 @GuardedBy("mPm.mLock") checkExistingBetterPackages(ArrayMap<String, File> expectingBetterPackages, List<String> stubSystemApps, int systemScanFlags, int systemParseFlags)3529 public void checkExistingBetterPackages(ArrayMap<String, File> expectingBetterPackages, 3530 List<String> stubSystemApps, int systemScanFlags, int systemParseFlags) { 3531 for (int i = 0; i < expectingBetterPackages.size(); i++) { 3532 final String packageName = expectingBetterPackages.keyAt(i); 3533 if (mPm.mPackages.containsKey(packageName)) { 3534 continue; 3535 } 3536 final File scanFile = expectingBetterPackages.valueAt(i); 3537 3538 logCriticalInfo(Log.WARN, "Expected better " + packageName 3539 + " but never showed up; reverting to system"); 3540 3541 final Pair<Integer, Integer> rescanAndReparseFlags = 3542 mPm.getSystemPackageRescanFlagsAndReparseFlags(scanFile, 3543 systemScanFlags, systemParseFlags); 3544 @PackageManagerService.ScanFlags int rescanFlags = rescanAndReparseFlags.first; 3545 @ParsingPackageUtils.ParseFlags int reparseFlags = rescanAndReparseFlags.second; 3546 3547 if (rescanFlags == 0) { 3548 Slog.e(TAG, "Ignoring unexpected fallback path " + scanFile); 3549 continue; 3550 } 3551 mPm.mSettings.enableSystemPackageLPw(packageName); 3552 3553 try { 3554 final AndroidPackage newPkg = scanSystemPackageTracedLI( 3555 scanFile, reparseFlags, rescanFlags, null); 3556 // We rescanned a stub, add it to the list of stubbed system packages 3557 if (newPkg.isStub()) { 3558 stubSystemApps.add(packageName); 3559 } 3560 } catch (PackageManagerException e) { 3561 Slog.e(TAG, "Failed to parse original system package: " 3562 + e.getMessage()); 3563 } 3564 } 3565 } 3566 3567 /** 3568 * Traces a package scan. 3569 * @see #scanSystemPackageLI(File, int, int, UserHandle) 3570 */ 3571 @GuardedBy({"mPm.mInstallLock", "mPm.mLock"}) scanSystemPackageTracedLI(File scanFile, final int parseFlags, int scanFlags, UserHandle user)3572 public AndroidPackage scanSystemPackageTracedLI(File scanFile, final int parseFlags, 3573 int scanFlags, UserHandle user) throws PackageManagerException { 3574 Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "scanPackage [" + scanFile.toString() + "]"); 3575 try { 3576 return scanSystemPackageLI(scanFile, parseFlags, scanFlags, user); 3577 } finally { 3578 Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER); 3579 } 3580 } 3581 3582 /** 3583 * Scans a package and returns the newly parsed package. 3584 * Returns {@code null} in case of errors and the error code is stored in mLastScanError 3585 */ 3586 @GuardedBy({"mPm.mInstallLock", "mPm.mLock"}) scanSystemPackageLI(File scanFile, int parseFlags, int scanFlags, UserHandle user)3587 private AndroidPackage scanSystemPackageLI(File scanFile, int parseFlags, int scanFlags, 3588 UserHandle user) throws PackageManagerException { 3589 if (DEBUG_INSTALL) Slog.d(TAG, "Parsing: " + scanFile); 3590 3591 Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "parsePackage"); 3592 final ParsedPackage parsedPackage; 3593 try (PackageParser2 pp = mPm.mInjector.getScanningPackageParser()) { 3594 parsedPackage = pp.parsePackage(scanFile, parseFlags, false); 3595 } finally { 3596 Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER); 3597 } 3598 3599 // Static shared libraries have synthetic package names 3600 if (parsedPackage.isStaticSharedLibrary()) { 3601 PackageManagerService.renameStaticSharedLibraryPackage(parsedPackage); 3602 } 3603 3604 return addForInitLI(parsedPackage, parseFlags, scanFlags, user); 3605 } 3606 3607 /** 3608 * Adds a new package to the internal data structures during platform initialization. 3609 * <p>After adding, the package is known to the system and available for querying. 3610 * <p>For packages located on the device ROM [eg. packages located in /system, /vendor, 3611 * etc...], additional checks are performed. Basic verification [such as ensuring 3612 * matching signatures, checking version codes, etc...] occurs if the package is 3613 * identical to a previously known package. If the package fails a signature check, 3614 * the version installed on /data will be removed. If the version of the new package 3615 * is less than or equal than the version on /data, it will be ignored. 3616 * <p>Regardless of the package location, the results are applied to the internal 3617 * structures and the package is made available to the rest of the system. 3618 * <p>NOTE: The return value should be removed. It's the passed in package object. 3619 */ 3620 @GuardedBy({"mPm.mLock", "mPm.mInstallLock"}) addForInitLI(ParsedPackage parsedPackage, @ParsingPackageUtils.ParseFlags int parseFlags, @PackageManagerService.ScanFlags int scanFlags, @Nullable UserHandle user)3621 private AndroidPackage addForInitLI(ParsedPackage parsedPackage, 3622 @ParsingPackageUtils.ParseFlags int parseFlags, 3623 @PackageManagerService.ScanFlags int scanFlags, 3624 @Nullable UserHandle user) throws PackageManagerException { 3625 3626 final Pair<ScanResult, Boolean> scanResultPair = scanSystemPackageLI( 3627 parsedPackage, parseFlags, scanFlags, user); 3628 final ScanResult scanResult = scanResultPair.first; 3629 boolean shouldHideSystemApp = scanResultPair.second; 3630 if (scanResult.mSuccess) { 3631 synchronized (mPm.mLock) { 3632 boolean appIdCreated = false; 3633 try { 3634 final String pkgName = scanResult.mPkgSetting.getPackageName(); 3635 final ReconcileRequest reconcileRequest = new ReconcileRequest( 3636 Collections.singletonMap(pkgName, scanResult), 3637 mPm.mPackages, 3638 Collections.singletonMap(pkgName, 3639 mPm.getSettingsVersionForPackage(parsedPackage))); 3640 final Map<String, ReconciledPackage> reconcileResult = 3641 ReconcilePackageUtils.reconcilePackages(reconcileRequest, 3642 mSharedLibraries, mPm.mSettings.getKeySetManagerService(), 3643 mPm.mSettings); 3644 appIdCreated = optimisticallyRegisterAppId(scanResult); 3645 commitReconciledScanResultLocked(reconcileResult.get(pkgName), 3646 mPm.mUserManager.getUserIds()); 3647 } catch (PackageManagerException e) { 3648 if (appIdCreated) { 3649 cleanUpAppIdCreation(scanResult); 3650 } 3651 throw e; 3652 } 3653 } 3654 } 3655 3656 if (shouldHideSystemApp) { 3657 synchronized (mPm.mLock) { 3658 mPm.mSettings.disableSystemPackageLPw(parsedPackage.getPackageName(), true); 3659 } 3660 } 3661 if (mIncrementalManager != null && isIncrementalPath(parsedPackage.getPath())) { 3662 if (scanResult.mPkgSetting != null && scanResult.mPkgSetting.isLoading()) { 3663 // Continue monitoring loading progress of active incremental packages 3664 mIncrementalManager.registerLoadingProgressCallback(parsedPackage.getPath(), 3665 new IncrementalProgressListener(parsedPackage.getPackageName(), mPm)); 3666 } 3667 } 3668 return scanResult.mPkgSetting.getPkg(); 3669 } 3670 3671 /** 3672 * Prepares the system to commit a {@link ScanResult} in a way that will not fail by registering 3673 * the app ID required for reconcile. 3674 * @return {@code true} if a new app ID was registered and will need to be cleaned up on 3675 * failure. 3676 */ optimisticallyRegisterAppId(@onNull ScanResult result)3677 private boolean optimisticallyRegisterAppId(@NonNull ScanResult result) 3678 throws PackageManagerException { 3679 if (!result.mExistingSettingCopied || result.needsNewAppId()) { 3680 synchronized (mPm.mLock) { 3681 // THROWS: when we can't allocate a user id. add call to check if there's 3682 // enough space to ensure we won't throw; otherwise, don't modify state 3683 return mPm.mSettings.registerAppIdLPw(result.mPkgSetting, result.needsNewAppId()); 3684 } 3685 } 3686 return false; 3687 } 3688 3689 /** 3690 * Reverts any app ID creation that were made by 3691 * {@link #optimisticallyRegisterAppId(ScanResult)}. Note: this is only necessary if the 3692 * referenced method returned true. 3693 */ cleanUpAppIdCreation(@onNull ScanResult result)3694 private void cleanUpAppIdCreation(@NonNull ScanResult result) { 3695 // iff we've acquired an app ID for a new package setting, remove it so that it can be 3696 // acquired by another request. 3697 if (result.mPkgSetting.getAppId() > 0) { 3698 mPm.mSettings.removeAppIdLPw(result.mPkgSetting.getAppId()); 3699 } 3700 } 3701 3702 @GuardedBy({"mPm.mInstallLock", "mPm.mLock"}) scanPackageTracedLI(ParsedPackage parsedPackage, final @ParsingPackageUtils.ParseFlags int parseFlags, @PackageManagerService.ScanFlags int scanFlags, long currentTime, @Nullable UserHandle user, String cpuAbiOverride)3703 private ScanResult scanPackageTracedLI(ParsedPackage parsedPackage, 3704 final @ParsingPackageUtils.ParseFlags int parseFlags, 3705 @PackageManagerService.ScanFlags int scanFlags, long currentTime, 3706 @Nullable UserHandle user, String cpuAbiOverride) throws PackageManagerException { 3707 Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "scanPackage"); 3708 try { 3709 return scanPackageNewLI(parsedPackage, parseFlags, scanFlags, currentTime, user, 3710 cpuAbiOverride); 3711 } finally { 3712 Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER); 3713 } 3714 } 3715 prepareInitialScanRequest(@onNull ParsedPackage parsedPackage, @ParsingPackageUtils.ParseFlags int parseFlags, @PackageManagerService.ScanFlags int scanFlags, @Nullable UserHandle user, String cpuAbiOverride)3716 private ScanRequest prepareInitialScanRequest(@NonNull ParsedPackage parsedPackage, 3717 @ParsingPackageUtils.ParseFlags int parseFlags, 3718 @PackageManagerService.ScanFlags int scanFlags, 3719 @Nullable UserHandle user, String cpuAbiOverride) 3720 throws PackageManagerException { 3721 final AndroidPackage platformPackage; 3722 final String realPkgName; 3723 final PackageSetting disabledPkgSetting; 3724 final PackageSetting installedPkgSetting; 3725 final PackageSetting originalPkgSetting; 3726 final SharedUserSetting sharedUserSetting; 3727 SharedUserSetting oldSharedUserSetting = null; 3728 3729 synchronized (mPm.mLock) { 3730 platformPackage = mPm.getPlatformPackage(); 3731 final String renamedPkgName = mPm.mSettings.getRenamedPackageLPr( 3732 AndroidPackageUtils.getRealPackageOrNull(parsedPackage)); 3733 realPkgName = ScanPackageUtils.getRealPackageName(parsedPackage, renamedPkgName); 3734 if (realPkgName != null) { 3735 ScanPackageUtils.ensurePackageRenamed(parsedPackage, renamedPkgName); 3736 } 3737 originalPkgSetting = getOriginalPackageLocked(parsedPackage, renamedPkgName); 3738 installedPkgSetting = mPm.mSettings.getPackageLPr(parsedPackage.getPackageName()); 3739 if (mPm.mTransferredPackages.contains(parsedPackage.getPackageName())) { 3740 Slog.w(TAG, "Package " + parsedPackage.getPackageName() 3741 + " was transferred to another, but its .apk remains"); 3742 } 3743 disabledPkgSetting = mPm.mSettings.getDisabledSystemPkgLPr( 3744 parsedPackage.getPackageName()); 3745 3746 boolean ignoreSharedUserId = false; 3747 if (installedPkgSetting == null || !installedPkgSetting.hasSharedUser()) { 3748 // Directly ignore sharedUserSetting for new installs, or if the app has 3749 // already left shared UID 3750 ignoreSharedUserId = parsedPackage.isLeavingSharedUid(); 3751 } 3752 3753 if (!ignoreSharedUserId && parsedPackage.getSharedUserId() != null) { 3754 sharedUserSetting = mPm.mSettings.getSharedUserLPw( 3755 parsedPackage.getSharedUserId(), 3756 0 /*pkgFlags*/, 0 /*pkgPrivateFlags*/, true /*create*/); 3757 } else { 3758 sharedUserSetting = null; 3759 } 3760 if (DEBUG_PACKAGE_SCANNING 3761 && (parseFlags & ParsingPackageUtils.PARSE_CHATTY) != 0 3762 && sharedUserSetting != null) { 3763 Log.d(TAG, "Shared UserID " + parsedPackage.getSharedUserId() 3764 + " (uid=" + sharedUserSetting.mAppId + "):" 3765 + " packages=" + sharedUserSetting.getPackageStates()); 3766 } 3767 if (installedPkgSetting != null) { 3768 oldSharedUserSetting = mPm.mSettings.getSharedUserSettingLPr(installedPkgSetting); 3769 } 3770 } 3771 3772 final boolean isPlatformPackage = platformPackage != null 3773 && platformPackage.getPackageName().equals(parsedPackage.getPackageName()); 3774 3775 return new ScanRequest(parsedPackage, oldSharedUserSetting, 3776 installedPkgSetting == null ? null : installedPkgSetting.getPkg() /* oldPkg */, 3777 installedPkgSetting /* packageSetting */, 3778 sharedUserSetting, 3779 disabledPkgSetting /* disabledPackageSetting */, 3780 originalPkgSetting /* originalPkgSetting */, 3781 realPkgName, parseFlags, scanFlags, isPlatformPackage, user, cpuAbiOverride); 3782 } 3783 3784 @GuardedBy({"mPm.mInstallLock", "mPm.mLock"}) scanPackageNewLI(@onNull ParsedPackage parsedPackage, final @ParsingPackageUtils.ParseFlags int parseFlags, @PackageManagerService.ScanFlags int scanFlags, long currentTime, @Nullable UserHandle user, String cpuAbiOverride)3785 private ScanResult scanPackageNewLI(@NonNull ParsedPackage parsedPackage, 3786 final @ParsingPackageUtils.ParseFlags int parseFlags, 3787 @PackageManagerService.ScanFlags int scanFlags, long currentTime, 3788 @Nullable UserHandle user, String cpuAbiOverride) 3789 throws PackageManagerException { 3790 final ScanRequest initialScanRequest = prepareInitialScanRequest(parsedPackage, parseFlags, 3791 scanFlags, user, cpuAbiOverride); 3792 final PackageSetting installedPkgSetting = initialScanRequest.mPkgSetting; 3793 final PackageSetting disabledPkgSetting = initialScanRequest.mDisabledPkgSetting; 3794 3795 boolean isUpdatedSystemApp; 3796 if (installedPkgSetting != null) { 3797 isUpdatedSystemApp = installedPkgSetting.getPkgState().isUpdatedSystemApp(); 3798 } else { 3799 isUpdatedSystemApp = disabledPkgSetting != null; 3800 } 3801 3802 final int newScanFlags = adjustScanFlags(scanFlags, installedPkgSetting, disabledPkgSetting, 3803 user, parsedPackage); 3804 ScanPackageUtils.applyPolicy(parsedPackage, newScanFlags, 3805 mPm.getPlatformPackage(), isUpdatedSystemApp); 3806 3807 synchronized (mPm.mLock) { 3808 assertPackageIsValid(parsedPackage, parseFlags, newScanFlags); 3809 final ScanRequest request = new ScanRequest(parsedPackage, 3810 initialScanRequest.mOldSharedUserSetting, 3811 initialScanRequest.mOldPkg, installedPkgSetting, 3812 initialScanRequest.mSharedUserSetting, disabledPkgSetting, 3813 initialScanRequest.mOriginalPkgSetting, initialScanRequest.mRealPkgName, 3814 parseFlags, scanFlags, initialScanRequest.mIsPlatformPackage, user, 3815 cpuAbiOverride); 3816 return ScanPackageUtils.scanPackageOnlyLI(request, mPm.mInjector, mPm.mFactoryTest, 3817 currentTime); 3818 } 3819 } 3820 scanSystemPackageLI(ParsedPackage parsedPackage, @ParsingPackageUtils.ParseFlags int parseFlags, @PackageManagerService.ScanFlags int scanFlags, @Nullable UserHandle user)3821 private Pair<ScanResult, Boolean> scanSystemPackageLI(ParsedPackage parsedPackage, 3822 @ParsingPackageUtils.ParseFlags int parseFlags, 3823 @PackageManagerService.ScanFlags int scanFlags, 3824 @Nullable UserHandle user) throws PackageManagerException { 3825 final boolean scanSystemPartition = 3826 (parseFlags & ParsingPackageUtils.PARSE_IS_SYSTEM_DIR) != 0; 3827 final ScanRequest initialScanRequest = prepareInitialScanRequest(parsedPackage, parseFlags, 3828 scanFlags, user, null); 3829 final PackageSetting installedPkgSetting = initialScanRequest.mPkgSetting; 3830 final PackageSetting originalPkgSetting = initialScanRequest.mOriginalPkgSetting; 3831 final PackageSetting pkgSetting = 3832 originalPkgSetting == null ? installedPkgSetting : originalPkgSetting; 3833 final boolean pkgAlreadyExists = pkgSetting != null; 3834 final String disabledPkgName = pkgAlreadyExists 3835 ? pkgSetting.getPackageName() : parsedPackage.getPackageName(); 3836 final boolean isSystemPkgUpdated; 3837 final boolean isUpgrade; 3838 synchronized (mPm.mLock) { 3839 isUpgrade = mPm.isDeviceUpgrading(); 3840 if (scanSystemPartition && !pkgAlreadyExists 3841 && mPm.mSettings.getDisabledSystemPkgLPr(disabledPkgName) != null) { 3842 // The updated-package data for /system apk remains inconsistently 3843 // after the package data for /data apk is lost accidentally. 3844 // To recover it, enable /system apk and install it as non-updated system app. 3845 Slog.w(TAG, "Inconsistent package setting of updated system app for " 3846 + disabledPkgName + ". To recover it, enable the system app " 3847 + "and install it as non-updated system app."); 3848 mPm.mSettings.removeDisabledSystemPackageLPw(disabledPkgName); 3849 } 3850 final PackageSetting disabledPkgSetting = 3851 mPm.mSettings.getDisabledSystemPkgLPr(disabledPkgName); 3852 isSystemPkgUpdated = disabledPkgSetting != null; 3853 3854 if (DEBUG_INSTALL && isSystemPkgUpdated) { 3855 Slog.d(TAG, "updatedPkg = " + disabledPkgSetting); 3856 } 3857 3858 if (scanSystemPartition && isSystemPkgUpdated) { 3859 // we're updating the disabled package, so, scan it as the package setting 3860 final ScanRequest request = new ScanRequest(parsedPackage, 3861 mPm.mSettings.getSharedUserSettingLPr(disabledPkgSetting), 3862 null, disabledPkgSetting /* pkgSetting */, 3863 initialScanRequest.mSharedUserSetting, 3864 null /* disabledPkgSetting */, null /* originalPkgSetting */, 3865 null, parseFlags, scanFlags, 3866 initialScanRequest.mIsPlatformPackage, user, null); 3867 ScanPackageUtils.applyPolicy(parsedPackage, scanFlags, 3868 mPm.getPlatformPackage(), true); 3869 final ScanResult scanResult = 3870 ScanPackageUtils.scanPackageOnlyLI(request, mPm.mInjector, 3871 mPm.mFactoryTest, -1L); 3872 if (scanResult.mExistingSettingCopied 3873 && scanResult.mRequest.mPkgSetting != null) { 3874 scanResult.mRequest.mPkgSetting.updateFrom(scanResult.mPkgSetting); 3875 } 3876 } 3877 } // End of mLock 3878 3879 final boolean newPkgChangedPaths = pkgAlreadyExists 3880 && !pkgSetting.getPathString().equals(parsedPackage.getPath()); 3881 final boolean newPkgVersionGreater = pkgAlreadyExists 3882 && parsedPackage.getLongVersionCode() > pkgSetting.getVersionCode(); 3883 final boolean isSystemPkgBetter = scanSystemPartition && isSystemPkgUpdated 3884 && newPkgChangedPaths && newPkgVersionGreater; 3885 if (isSystemPkgBetter) { 3886 // The version of the application on /system is greater than the version on 3887 // /data. Switch back to the application on /system. 3888 // It's safe to assume the application on /system will correctly scan. If not, 3889 // there won't be a working copy of the application. 3890 synchronized (mPm.mLock) { 3891 // just remove the loaded entries from package lists 3892 mPm.mPackages.remove(pkgSetting.getPackageName()); 3893 } 3894 3895 logCriticalInfo(Log.WARN, 3896 "System package updated;" 3897 + " name: " + pkgSetting.getPackageName() 3898 + "; " + pkgSetting.getVersionCode() + " --> " 3899 + parsedPackage.getLongVersionCode() 3900 + "; " + pkgSetting.getPathString() 3901 + " --> " + parsedPackage.getPath()); 3902 3903 final InstallArgs args = new FileInstallArgs( 3904 pkgSetting.getPathString(), getAppDexInstructionSets( 3905 pkgSetting.getPrimaryCpuAbi(), pkgSetting.getSecondaryCpuAbi()), mPm); 3906 args.cleanUpResourcesLI(); 3907 synchronized (mPm.mLock) { 3908 mPm.mSettings.enableSystemPackageLPw(pkgSetting.getPackageName()); 3909 } 3910 } 3911 3912 // The version of the application on the /system partition is less than or 3913 // equal to the version on the /data partition. Throw an exception and use 3914 // the application already installed on the /data partition. 3915 if (scanSystemPartition && isSystemPkgUpdated && !isSystemPkgBetter) { 3916 // In the case of a skipped package, commitReconciledScanResultLocked is not called to 3917 // add the object to the "live" data structures, so this is the final mutation step 3918 // for the package. Which means it needs to be finalized here to cache derived fields. 3919 // This is relevant for cases where the disabled system package is used for flags or 3920 // other metadata. 3921 parsedPackage.hideAsFinal(); 3922 throw new PackageManagerException(Log.WARN, "Package " + parsedPackage.getPackageName() 3923 + " at " + parsedPackage.getPath() + " ignored: updated version " 3924 + (pkgAlreadyExists ? String.valueOf(pkgSetting.getVersionCode()) : "unknown") 3925 + " better than this " + parsedPackage.getLongVersionCode()); 3926 } 3927 3928 // Verify certificates against what was last scanned. Force re-collecting certificate in two 3929 // special cases: 3930 // 1) when scanning system, force re-collect only if system is upgrading. 3931 // 2) when scanning /data, force re-collect only if the app is privileged (updated from 3932 // preinstall, or treated as privileged, e.g. due to shared user ID). 3933 final boolean forceCollect = scanSystemPartition ? isUpgrade 3934 : PackageManagerServiceUtils.isApkVerificationForced(pkgSetting); 3935 if (DEBUG_VERIFY && forceCollect) { 3936 Slog.d(TAG, "Force collect certificate of " + parsedPackage.getPackageName()); 3937 } 3938 3939 // Full APK verification can be skipped during certificate collection, only if the file is 3940 // in verified partition, or can be verified on access (when apk verity is enabled). In both 3941 // cases, only data in Signing Block is verified instead of the whole file. 3942 final boolean skipVerify = scanSystemPartition 3943 || (forceCollect && canSkipForcedPackageVerification(parsedPackage)); 3944 ScanPackageUtils.collectCertificatesLI(pkgSetting, parsedPackage, 3945 mPm.getSettingsVersionForPackage(parsedPackage), forceCollect, skipVerify, 3946 mPm.isPreNMR1Upgrade()); 3947 3948 // Reset profile if the application version is changed 3949 maybeClearProfilesForUpgradesLI(pkgSetting, parsedPackage); 3950 3951 /* 3952 * A new system app appeared, but we already had a non-system one of the 3953 * same name installed earlier. 3954 */ 3955 boolean shouldHideSystemApp = false; 3956 // A new application appeared on /system, but, we already have a copy of 3957 // the application installed on /data. 3958 if (scanSystemPartition && !isSystemPkgUpdated && pkgAlreadyExists 3959 && !pkgSetting.isSystem()) { 3960 3961 if (!parsedPackage.getSigningDetails() 3962 .checkCapability(pkgSetting.getSigningDetails(), 3963 SigningDetails.CertCapabilities.INSTALLED_DATA) 3964 && !pkgSetting.getSigningDetails().checkCapability( 3965 parsedPackage.getSigningDetails(), 3966 SigningDetails.CertCapabilities.ROLLBACK)) { 3967 logCriticalInfo(Log.WARN, 3968 "System package signature mismatch;" 3969 + " name: " + pkgSetting.getPackageName()); 3970 try (@SuppressWarnings("unused") PackageFreezer freezer = mPm.freezePackage( 3971 parsedPackage.getPackageName(), 3972 "scanPackageInternalLI")) { 3973 DeletePackageHelper deletePackageHelper = new DeletePackageHelper(mPm); 3974 deletePackageHelper.deletePackageLIF(parsedPackage.getPackageName(), null, true, 3975 mPm.mUserManager.getUserIds(), 0, null, false); 3976 } 3977 } else if (newPkgVersionGreater) { 3978 // The application on /system is newer than the application on /data. 3979 // Simply remove the application on /data [keeping application data] 3980 // and replace it with the version on /system. 3981 logCriticalInfo(Log.WARN, 3982 "System package enabled;" 3983 + " name: " + pkgSetting.getPackageName() 3984 + "; " + pkgSetting.getVersionCode() + " --> " 3985 + parsedPackage.getLongVersionCode() 3986 + "; " + pkgSetting.getPathString() + " --> " 3987 + parsedPackage.getPath()); 3988 InstallArgs args = new FileInstallArgs( 3989 pkgSetting.getPathString(), getAppDexInstructionSets( 3990 pkgSetting.getPrimaryCpuAbi(), pkgSetting.getSecondaryCpuAbi()), 3991 mPm); 3992 synchronized (mPm.mInstallLock) { 3993 args.cleanUpResourcesLI(); 3994 } 3995 } else { 3996 // The application on /system is older than the application on /data. Hide 3997 // the application on /system and the version on /data will be scanned later 3998 // and re-added like an update. 3999 shouldHideSystemApp = true; 4000 logCriticalInfo(Log.INFO, 4001 "System package disabled;" 4002 + " name: " + pkgSetting.getPackageName() 4003 + "; old: " + pkgSetting.getPathString() + " @ " 4004 + pkgSetting.getVersionCode() 4005 + "; new: " + parsedPackage.getPath() + " @ " 4006 + parsedPackage.getPath()); 4007 } 4008 } 4009 4010 final ScanResult scanResult = scanPackageNewLI(parsedPackage, parseFlags, 4011 scanFlags | SCAN_UPDATE_SIGNATURE, 0 /* currentTime */, user, null); 4012 return new Pair<>(scanResult, shouldHideSystemApp); 4013 } 4014 4015 /** 4016 * Returns if forced apk verification can be skipped for the whole package, including splits. 4017 */ canSkipForcedPackageVerification(AndroidPackage pkg)4018 private boolean canSkipForcedPackageVerification(AndroidPackage pkg) { 4019 final String packageName = pkg.getPackageName(); 4020 if (!VerityUtils.hasFsverity(pkg.getBaseApkPath())) { 4021 return false; 4022 } 4023 // TODO: Allow base and splits to be verified individually. 4024 String[] splitCodePaths = pkg.getSplitCodePaths(); 4025 if (!ArrayUtils.isEmpty(splitCodePaths)) { 4026 for (int i = 0; i < splitCodePaths.length; i++) { 4027 if (!VerityUtils.hasFsverity(splitCodePaths[i])) { 4028 return false; 4029 } 4030 } 4031 } 4032 return true; 4033 } 4034 4035 /** 4036 * Clear the package profile if this was an upgrade and the package 4037 * version was updated. 4038 */ maybeClearProfilesForUpgradesLI( @ullable PackageSetting originalPkgSetting, @NonNull AndroidPackage pkg)4039 private void maybeClearProfilesForUpgradesLI( 4040 @Nullable PackageSetting originalPkgSetting, 4041 @NonNull AndroidPackage pkg) { 4042 if (originalPkgSetting == null || !mPm.isDeviceUpgrading()) { 4043 return; 4044 } 4045 if (originalPkgSetting.getVersionCode() == pkg.getLongVersionCode()) { 4046 return; 4047 } 4048 4049 mAppDataHelper.clearAppProfilesLIF(pkg); 4050 if (DEBUG_INSTALL) { 4051 Slog.d(TAG, originalPkgSetting.getPackageName() 4052 + " clear profile due to version change " 4053 + originalPkgSetting.getVersionCode() + " != " 4054 + pkg.getLongVersionCode()); 4055 } 4056 } 4057 4058 /** 4059 * Returns the original package setting. 4060 * <p>A package can migrate its name during an update. In this scenario, a package 4061 * designates a set of names that it considers as one of its original names. 4062 * <p>An original package must be signed identically and it must have the same 4063 * shared user [if any]. 4064 */ 4065 @GuardedBy("mPm.mLock") 4066 @Nullable getOriginalPackageLocked(@onNull AndroidPackage pkg, @Nullable String renamedPkgName)4067 private PackageSetting getOriginalPackageLocked(@NonNull AndroidPackage pkg, 4068 @Nullable String renamedPkgName) { 4069 if (ScanPackageUtils.isPackageRenamed(pkg, renamedPkgName)) { 4070 return null; 4071 } 4072 for (int i = ArrayUtils.size(pkg.getOriginalPackages()) - 1; i >= 0; --i) { 4073 final PackageSetting originalPs = 4074 mPm.mSettings.getPackageLPr(pkg.getOriginalPackages().get(i)); 4075 if (originalPs != null) { 4076 // the package is already installed under its original name... 4077 // but, should we use it? 4078 if (!verifyPackageUpdateLPr(originalPs, pkg)) { 4079 // the new package is incompatible with the original 4080 continue; 4081 } else if (mPm.mSettings.getSharedUserSettingLPr(originalPs) != null) { 4082 final String sharedUserSettingsName = 4083 mPm.mSettings.getSharedUserSettingLPr(originalPs).name; 4084 if (!sharedUserSettingsName.equals(pkg.getSharedUserId())) { 4085 // the shared user id is incompatible with the original 4086 Slog.w(TAG, "Unable to migrate data from " + originalPs.getPackageName() 4087 + " to " + pkg.getPackageName() + ": old shared user settings name " 4088 + sharedUserSettingsName 4089 + " differs from " + pkg.getSharedUserId()); 4090 continue; 4091 } 4092 // TODO: Add case when shared user id is added [b/28144775] 4093 } else { 4094 if (DEBUG_UPGRADE) { 4095 Log.v(TAG, "Renaming new package " 4096 + pkg.getPackageName() + " to old name " 4097 + originalPs.getPackageName()); 4098 } 4099 } 4100 return originalPs; 4101 } 4102 } 4103 return null; 4104 } 4105 4106 @GuardedBy("mPm.mLock") verifyPackageUpdateLPr(PackageSetting oldPkg, AndroidPackage newPkg)4107 private boolean verifyPackageUpdateLPr(PackageSetting oldPkg, AndroidPackage newPkg) { 4108 if ((oldPkg.getFlags() & ApplicationInfo.FLAG_SYSTEM) == 0) { 4109 Slog.w(TAG, "Unable to update from " + oldPkg.getPackageName() 4110 + " to " + newPkg.getPackageName() 4111 + ": old package not in system partition"); 4112 return false; 4113 } else if (mPm.mPackages.get(oldPkg.getPackageName()) != null) { 4114 Slog.w(TAG, "Unable to update from " + oldPkg.getPackageName() 4115 + " to " + newPkg.getPackageName() 4116 + ": old package still exists"); 4117 return false; 4118 } 4119 return true; 4120 } 4121 4122 /** 4123 * Asserts the parsed package is valid according to the given policy. If the 4124 * package is invalid, for whatever reason, throws {@link PackageManagerException}. 4125 * <p> 4126 * Implementation detail: This method must NOT have any side effects. It would 4127 * ideally be static, but, it requires locks to read system state. 4128 * 4129 * @throws PackageManagerException If the package fails any of the validation checks 4130 */ assertPackageIsValid(AndroidPackage pkg, final @ParsingPackageUtils.ParseFlags int parseFlags, final @PackageManagerService.ScanFlags int scanFlags)4131 private void assertPackageIsValid(AndroidPackage pkg, 4132 final @ParsingPackageUtils.ParseFlags int parseFlags, 4133 final @PackageManagerService.ScanFlags int scanFlags) 4134 throws PackageManagerException { 4135 if ((parseFlags & ParsingPackageUtils.PARSE_ENFORCE_CODE) != 0) { 4136 ScanPackageUtils.assertCodePolicy(pkg); 4137 } 4138 4139 if (pkg.getPath() == null) { 4140 // Bail out. The resource and code paths haven't been set. 4141 throw new PackageManagerException(INSTALL_FAILED_INVALID_APK, 4142 "Code and resource paths haven't been set correctly"); 4143 } 4144 4145 // Check that there is an APEX package with the same name only during install/first boot 4146 // after OTA. 4147 final boolean isUserInstall = (scanFlags & SCAN_BOOTING) == 0; 4148 final boolean isFirstBootOrUpgrade = (scanFlags & SCAN_FIRST_BOOT_OR_UPGRADE) != 0; 4149 if ((isUserInstall || isFirstBootOrUpgrade) 4150 && mApexManager.isApexPackage(pkg.getPackageName())) { 4151 throw new PackageManagerException(INSTALL_FAILED_DUPLICATE_PACKAGE, 4152 pkg.getPackageName() 4153 + " is an APEX package and can't be installed as an APK."); 4154 } 4155 4156 // Make sure we're not adding any bogus keyset info 4157 final KeySetManagerService ksms = mPm.mSettings.getKeySetManagerService(); 4158 ksms.assertScannedPackageValid(pkg); 4159 4160 synchronized (mPm.mLock) { 4161 // The special "android" package can only be defined once 4162 if (pkg.getPackageName().equals("android")) { 4163 if (mPm.getCoreAndroidApplication() != null) { 4164 Slog.w(TAG, "*************************************************"); 4165 Slog.w(TAG, "Core android package being redefined. Skipping."); 4166 Slog.w(TAG, " codePath=" + pkg.getPath()); 4167 Slog.w(TAG, "*************************************************"); 4168 throw new PackageManagerException(INSTALL_FAILED_DUPLICATE_PACKAGE, 4169 "Core android package being redefined. Skipping."); 4170 } 4171 } 4172 4173 // A package name must be unique; don't allow duplicates 4174 if ((scanFlags & SCAN_NEW_INSTALL) == 0 4175 && mPm.mPackages.containsKey(pkg.getPackageName())) { 4176 throw new PackageManagerException(INSTALL_FAILED_DUPLICATE_PACKAGE, 4177 "Application package " + pkg.getPackageName() 4178 + " already installed. Skipping duplicate."); 4179 } 4180 4181 if (pkg.isStaticSharedLibrary()) { 4182 // Static libs have a synthetic package name containing the version 4183 // but we still want the base name to be unique. 4184 if ((scanFlags & SCAN_NEW_INSTALL) == 0 4185 && mPm.mPackages.containsKey(pkg.getManifestPackageName())) { 4186 throw new PackageManagerException( 4187 "Duplicate static shared lib provider package"); 4188 } 4189 ScanPackageUtils.assertStaticSharedLibraryIsValid(pkg, scanFlags); 4190 assertStaticSharedLibraryVersionCodeIsValid(pkg); 4191 } 4192 4193 // If we're only installing presumed-existing packages, require that the 4194 // scanned APK is both already known and at the path previously established 4195 // for it. Previously unknown packages we pick up normally, but if we have an 4196 // a priori expectation about this package's install presence, enforce it. 4197 // With a singular exception for new system packages. When an OTA contains 4198 // a new system package, we allow the codepath to change from a system location 4199 // to the user-installed location. If we don't allow this change, any newer, 4200 // user-installed version of the application will be ignored. 4201 if ((scanFlags & SCAN_REQUIRE_KNOWN) != 0) { 4202 if (mPm.isExpectingBetter(pkg.getPackageName())) { 4203 Slog.w(TAG, "Relax SCAN_REQUIRE_KNOWN requirement for package " 4204 + pkg.getPackageName()); 4205 } else { 4206 PackageSetting known = mPm.mSettings.getPackageLPr(pkg.getPackageName()); 4207 if (known != null) { 4208 if (DEBUG_PACKAGE_SCANNING) { 4209 Log.d(TAG, "Examining " + pkg.getPath() 4210 + " and requiring known path " + known.getPathString()); 4211 } 4212 if (!pkg.getPath().equals(known.getPathString())) { 4213 throw new PackageManagerException(INSTALL_FAILED_PACKAGE_CHANGED, 4214 "Application package " + pkg.getPackageName() 4215 + " found at " + pkg.getPath() 4216 + " but expected at " + known.getPathString() 4217 + "; ignoring."); 4218 } 4219 } else { 4220 throw new PackageManagerException(INSTALL_FAILED_INVALID_INSTALL_LOCATION, 4221 "Application package " + pkg.getPackageName() 4222 + " not found; ignoring."); 4223 } 4224 } 4225 } 4226 4227 // Verify that this new package doesn't have any content providers 4228 // that conflict with existing packages. Only do this if the 4229 // package isn't already installed, since we don't want to break 4230 // things that are installed. 4231 if ((scanFlags & SCAN_NEW_INSTALL) != 0) { 4232 mPm.mComponentResolver.assertProvidersNotDefined(pkg); 4233 } 4234 4235 // If this package has defined explicit processes, then ensure that these are 4236 // the only processes used by its components. 4237 ScanPackageUtils.assertProcessesAreValid(pkg); 4238 4239 // Verify that packages sharing a user with a privileged app are marked as privileged. 4240 assertPackageWithSharedUserIdIsPrivileged(pkg); 4241 4242 // Apply policies specific for runtime resource overlays (RROs). 4243 if (pkg.getOverlayTarget() != null) { 4244 assertOverlayIsValid(pkg, parseFlags, scanFlags); 4245 } 4246 4247 // Ensure the package is signed with at least the minimum signature scheme version 4248 // required for its target SDK. 4249 ScanPackageUtils.assertMinSignatureSchemeIsValid(pkg, parseFlags); 4250 } 4251 } 4252 assertStaticSharedLibraryVersionCodeIsValid(AndroidPackage pkg)4253 private void assertStaticSharedLibraryVersionCodeIsValid(AndroidPackage pkg) 4254 throws PackageManagerException { 4255 // The version codes must be ordered as lib versions 4256 long minVersionCode = Long.MIN_VALUE; 4257 long maxVersionCode = Long.MAX_VALUE; 4258 4259 WatchedLongSparseArray<SharedLibraryInfo> versionedLib = 4260 mSharedLibraries.getSharedLibraryInfos(pkg.getStaticSharedLibName()); 4261 if (versionedLib != null) { 4262 final int versionCount = versionedLib.size(); 4263 for (int i = 0; i < versionCount; i++) { 4264 SharedLibraryInfo libInfo = versionedLib.valueAt(i); 4265 final long libVersionCode = libInfo.getDeclaringPackage() 4266 .getLongVersionCode(); 4267 if (libInfo.getLongVersion() < pkg.getStaticSharedLibVersion()) { 4268 minVersionCode = Math.max(minVersionCode, libVersionCode + 1); 4269 } else if (libInfo.getLongVersion() 4270 > pkg.getStaticSharedLibVersion()) { 4271 maxVersionCode = Math.min(maxVersionCode, libVersionCode - 1); 4272 } else { 4273 minVersionCode = maxVersionCode = libVersionCode; 4274 break; 4275 } 4276 } 4277 } 4278 if (pkg.getLongVersionCode() < minVersionCode 4279 || pkg.getLongVersionCode() > maxVersionCode) { 4280 throw new PackageManagerException("Static shared" 4281 + " lib version codes must be ordered as lib versions"); 4282 } 4283 } 4284 assertOverlayIsValid(AndroidPackage pkg, @ParsingPackageUtils.ParseFlags int parseFlags, @PackageManagerService.ScanFlags int scanFlags)4285 private void assertOverlayIsValid(AndroidPackage pkg, 4286 @ParsingPackageUtils.ParseFlags int parseFlags, 4287 @PackageManagerService.ScanFlags int scanFlags) throws PackageManagerException { 4288 // System overlays have some restrictions on their use of the 'static' state. 4289 if ((scanFlags & SCAN_AS_SYSTEM) != 0) { 4290 // We are scanning a system overlay. This can be the first scan of the 4291 // system/vendor/oem partition, or an update to the system overlay. 4292 if ((parseFlags & ParsingPackageUtils.PARSE_IS_SYSTEM_DIR) == 0) { 4293 // This must be an update to a system overlay. Immutable overlays cannot be 4294 // upgraded. 4295 if (!mPm.isOverlayMutable(pkg.getPackageName())) { 4296 throw new PackageManagerException("Overlay " 4297 + pkg.getPackageName() 4298 + " is static and cannot be upgraded."); 4299 } 4300 } else { 4301 if ((scanFlags & SCAN_AS_VENDOR) != 0) { 4302 if (pkg.getTargetSdkVersion() < ScanPackageUtils.getVendorPartitionVersion()) { 4303 Slog.w(TAG, "System overlay " + pkg.getPackageName() 4304 + " targets an SDK below the required SDK level of vendor" 4305 + " overlays (" 4306 + ScanPackageUtils.getVendorPartitionVersion() 4307 + ")." 4308 + " This will become an install error in a future release"); 4309 } 4310 } else if (pkg.getTargetSdkVersion() < Build.VERSION.SDK_INT) { 4311 Slog.w(TAG, "System overlay " + pkg.getPackageName() 4312 + " targets an SDK below the required SDK level of system" 4313 + " overlays (" + Build.VERSION.SDK_INT + ")." 4314 + " This will become an install error in a future release"); 4315 } 4316 } 4317 } else { 4318 // A non-preloaded overlay packages must have targetSdkVersion >= Q, or be 4319 // signed with the platform certificate. Check this in increasing order of 4320 // computational cost. 4321 if (pkg.getTargetSdkVersion() < Build.VERSION_CODES.Q) { 4322 final PackageSetting platformPkgSetting = 4323 mPm.mSettings.getPackageLPr("android"); 4324 if (!comparePackageSignatures(platformPkgSetting, 4325 pkg.getSigningDetails().getSignatures())) { 4326 throw new PackageManagerException("Overlay " 4327 + pkg.getPackageName() 4328 + " must target Q or later, " 4329 + "or be signed with the platform certificate"); 4330 } 4331 } 4332 4333 // A non-preloaded overlay package, without <overlay android:targetName>, will 4334 // only be used if it is signed with the same certificate as its target OR if 4335 // it is signed with the same certificate as a reference package declared 4336 // in 'overlay-config-signature' tag of SystemConfig. 4337 // If the target is already installed or 'overlay-config-signature' tag in 4338 // SystemConfig is set, check this here to augment the last line of defense 4339 // which is OMS. 4340 if (pkg.getOverlayTargetOverlayableName() == null) { 4341 final PackageSetting targetPkgSetting = 4342 mPm.mSettings.getPackageLPr(pkg.getOverlayTarget()); 4343 if (targetPkgSetting != null) { 4344 if (!comparePackageSignatures(targetPkgSetting, 4345 pkg.getSigningDetails().getSignatures())) { 4346 // check reference signature 4347 if (mPm.mOverlayConfigSignaturePackage == null) { 4348 throw new PackageManagerException("Overlay " 4349 + pkg.getPackageName() + " and target " 4350 + pkg.getOverlayTarget() + " signed with" 4351 + " different certificates, and the overlay lacks" 4352 + " <overlay android:targetName>"); 4353 } 4354 final PackageSetting refPkgSetting = 4355 mPm.mSettings.getPackageLPr( 4356 mPm.mOverlayConfigSignaturePackage); 4357 if (!comparePackageSignatures(refPkgSetting, 4358 pkg.getSigningDetails().getSignatures())) { 4359 throw new PackageManagerException("Overlay " 4360 + pkg.getPackageName() + " signed with a different " 4361 + "certificate than both the reference package and " 4362 + "target " + pkg.getOverlayTarget() + ", and the " 4363 + "overlay lacks <overlay android:targetName>"); 4364 } 4365 } 4366 } 4367 } 4368 } 4369 } 4370 assertPackageWithSharedUserIdIsPrivileged(AndroidPackage pkg)4371 private void assertPackageWithSharedUserIdIsPrivileged(AndroidPackage pkg) 4372 throws PackageManagerException { 4373 if (!pkg.isPrivileged() && (pkg.getSharedUserId() != null)) { 4374 SharedUserSetting sharedUserSetting = null; 4375 try { 4376 sharedUserSetting = mPm.mSettings.getSharedUserLPw(pkg.getSharedUserId(), 4377 0, 0, false); 4378 } catch (PackageManagerException ignore) { 4379 } 4380 if (sharedUserSetting != null && sharedUserSetting.isPrivileged()) { 4381 // Exempt SharedUsers signed with the platform key. 4382 PackageSetting platformPkgSetting = mPm.mSettings.getPackageLPr("android"); 4383 if (!comparePackageSignatures(platformPkgSetting, 4384 pkg.getSigningDetails().getSignatures())) { 4385 throw new PackageManagerException("Apps that share a user with a " 4386 + "privileged app must themselves be marked as privileged. " 4387 + pkg.getPackageName() + " shares privileged user " 4388 + pkg.getSharedUserId() + "."); 4389 } 4390 } 4391 } 4392 } 4393 adjustScanFlags( @ackageManagerService.ScanFlags int scanFlags, PackageSetting pkgSetting, PackageSetting disabledPkgSetting, UserHandle user, AndroidPackage pkg)4394 private @PackageManagerService.ScanFlags int adjustScanFlags( 4395 @PackageManagerService.ScanFlags int scanFlags, 4396 PackageSetting pkgSetting, PackageSetting disabledPkgSetting, UserHandle user, 4397 AndroidPackage pkg) { 4398 scanFlags = ScanPackageUtils.adjustScanFlagsWithPackageSetting(scanFlags, pkgSetting, 4399 disabledPkgSetting, user); 4400 4401 // Exception for privileged apps that share a user with a priv-app. 4402 final boolean skipVendorPrivilegeScan = ((scanFlags & SCAN_AS_VENDOR) != 0) 4403 && ScanPackageUtils.getVendorPartitionVersion() < 28; 4404 if (((scanFlags & SCAN_AS_PRIVILEGED) == 0) 4405 && !pkg.isPrivileged() 4406 && (pkg.getSharedUserId() != null) 4407 && !skipVendorPrivilegeScan) { 4408 SharedUserSetting sharedUserSetting = null; 4409 synchronized (mPm.mLock) { 4410 try { 4411 sharedUserSetting = mPm.mSettings.getSharedUserLPw(pkg.getSharedUserId(), 0, 4412 0, false); 4413 } catch (PackageManagerException ignore) { 4414 } 4415 if (sharedUserSetting != null && sharedUserSetting.isPrivileged()) { 4416 // Exempt SharedUsers signed with the platform key. 4417 // TODO(b/72378145) Fix this exemption. Force signature apps 4418 // to allowlist their privileged permissions just like other 4419 // priv-apps. 4420 PackageSetting platformPkgSetting = mPm.mSettings.getPackageLPr("android"); 4421 if ((compareSignatures( 4422 platformPkgSetting.getSigningDetails().getSignatures(), 4423 pkg.getSigningDetails().getSignatures()) 4424 != PackageManager.SIGNATURE_MATCH)) { 4425 scanFlags |= SCAN_AS_PRIVILEGED; 4426 } 4427 } 4428 } 4429 } 4430 4431 return scanFlags; 4432 } 4433 } 4434