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.INSTALL_FAILED_INVALID_APK; 20 import static android.content.pm.PackageManager.INSTALL_FAILED_PROCESS_NOT_DEFINED; 21 import static android.content.pm.PackageManager.INSTALL_PARSE_FAILED_NO_CERTIFICATES; 22 import static android.os.Trace.TRACE_TAG_PACKAGE_MANAGER; 23 24 import static com.android.server.pm.PackageManagerService.DEBUG_ABI_SELECTION; 25 import static com.android.server.pm.PackageManagerService.DEBUG_PACKAGE_SCANNING; 26 import static com.android.server.pm.PackageManagerService.PLATFORM_PACKAGE_NAME; 27 import static com.android.server.pm.PackageManagerService.SCAN_AS_APEX; 28 import static com.android.server.pm.PackageManagerService.SCAN_AS_FULL_APP; 29 import static com.android.server.pm.PackageManagerService.SCAN_AS_INSTANT_APP; 30 import static com.android.server.pm.PackageManagerService.SCAN_AS_ODM; 31 import static com.android.server.pm.PackageManagerService.SCAN_AS_OEM; 32 import static com.android.server.pm.PackageManagerService.SCAN_AS_PRIVILEGED; 33 import static com.android.server.pm.PackageManagerService.SCAN_AS_PRODUCT; 34 import static com.android.server.pm.PackageManagerService.SCAN_AS_STOPPED_SYSTEM_APP; 35 import static com.android.server.pm.PackageManagerService.SCAN_AS_SYSTEM; 36 import static com.android.server.pm.PackageManagerService.SCAN_AS_SYSTEM_EXT; 37 import static com.android.server.pm.PackageManagerService.SCAN_AS_VENDOR; 38 import static com.android.server.pm.PackageManagerService.SCAN_AS_VIRTUAL_PRELOAD; 39 import static com.android.server.pm.PackageManagerService.SCAN_BOOTING; 40 import static com.android.server.pm.PackageManagerService.SCAN_DONT_KILL_APP; 41 import static com.android.server.pm.PackageManagerService.SCAN_FIRST_BOOT_OR_UPGRADE; 42 import static com.android.server.pm.PackageManagerService.SCAN_MOVE; 43 import static com.android.server.pm.PackageManagerService.SCAN_NEW_INSTALL; 44 import static com.android.server.pm.PackageManagerService.SCAN_NO_DEX; 45 import static com.android.server.pm.PackageManagerService.SCAN_UPDATE_TIME; 46 import static com.android.server.pm.PackageManagerService.TAG; 47 import static com.android.server.pm.PackageManagerServiceUtils.compareSignatures; 48 import static com.android.server.pm.PackageManagerServiceUtils.compressedFileExists; 49 import static com.android.server.pm.PackageManagerServiceUtils.deriveAbiOverride; 50 import static com.android.server.pm.PackageManagerServiceUtils.getLastModifiedTime; 51 52 import android.annotation.NonNull; 53 import android.annotation.Nullable; 54 import android.content.pm.ApplicationInfo; 55 import android.content.pm.PackageManager; 56 import android.content.pm.SharedLibraryInfo; 57 import android.content.pm.SigningDetails; 58 import android.content.pm.parsing.result.ParseResult; 59 import android.content.pm.parsing.result.ParseTypeImpl; 60 import android.os.Build; 61 import android.os.Environment; 62 import android.os.Process; 63 import android.os.SystemProperties; 64 import android.os.Trace; 65 import android.os.UserHandle; 66 import android.text.TextUtils; 67 import android.util.ArrayMap; 68 import android.util.ArraySet; 69 import android.util.Log; 70 import android.util.Pair; 71 import android.util.Slog; 72 import android.util.apk.ApkSignatureVerifier; 73 import android.util.jar.StrictJarFile; 74 75 import com.android.internal.annotations.GuardedBy; 76 import com.android.internal.annotations.VisibleForTesting; 77 import com.android.internal.pm.parsing.pkg.ParsedPackage; 78 import com.android.internal.pm.pkg.component.ComponentMutateUtils; 79 import com.android.internal.pm.pkg.component.ParsedActivity; 80 import com.android.internal.pm.pkg.component.ParsedMainComponent; 81 import com.android.internal.pm.pkg.component.ParsedProcess; 82 import com.android.internal.pm.pkg.component.ParsedProvider; 83 import com.android.internal.pm.pkg.component.ParsedService; 84 import com.android.internal.pm.pkg.parsing.ParsingPackageUtils; 85 import com.android.internal.util.ArrayUtils; 86 import com.android.server.SystemConfig; 87 import com.android.server.pm.parsing.PackageInfoUtils; 88 import com.android.server.pm.parsing.library.PackageBackwardCompatibility; 89 import com.android.server.pm.parsing.pkg.AndroidPackageUtils; 90 import com.android.server.pm.pkg.AndroidPackage; 91 import com.android.server.pm.pkg.PackageStateUtils; 92 import com.android.server.utils.WatchedArraySet; 93 94 import dalvik.system.VMRuntime; 95 96 import java.io.File; 97 import java.io.IOException; 98 import java.util.ArrayList; 99 import java.util.List; 100 import java.util.Map; 101 import java.util.Objects; 102 import java.util.UUID; 103 104 /** 105 * Helper class that handles package scanning logic 106 */ 107 final class ScanPackageUtils { 108 /** 109 * Just scans the package without any side effects. 110 * 111 * @param injector injector for acquiring dependencies 112 * @param request Information about the package to be scanned 113 * @param isUnderFactoryTest Whether or not the device is under factory test 114 * @param currentTime The current time, in millis 115 * @return The results of the scan 116 */ 117 @GuardedBy("mPm.mInstallLock") 118 @VisibleForTesting 119 @NonNull scanPackageOnlyLI(@onNull ScanRequest request, PackageManagerServiceInjector injector, boolean isUnderFactoryTest, long currentTime)120 public static ScanResult scanPackageOnlyLI(@NonNull ScanRequest request, 121 PackageManagerServiceInjector injector, 122 boolean isUnderFactoryTest, long currentTime) 123 throws PackageManagerException { 124 final PackageAbiHelper packageAbiHelper = injector.getAbiHelper(); 125 ParsedPackage parsedPackage = request.mParsedPackage; 126 PackageSetting pkgSetting = request.mPkgSetting; 127 final PackageSetting disabledPkgSetting = request.mDisabledPkgSetting; 128 final PackageSetting originalPkgSetting = request.mOriginalPkgSetting; 129 final @ParsingPackageUtils.ParseFlags int parseFlags = request.mParseFlags; 130 final @PackageManagerService.ScanFlags int scanFlags = request.mScanFlags; 131 final String realPkgName = request.mRealPkgName; 132 final SharedUserSetting oldSharedUserSetting = request.mOldSharedUserSetting; 133 final SharedUserSetting sharedUserSetting = request.mSharedUserSetting; 134 final UserHandle user = request.mUser; 135 final boolean isPlatformPackage = request.mIsPlatformPackage; 136 137 List<String> changedAbiCodePath = null; 138 139 if (DEBUG_PACKAGE_SCANNING) { 140 if ((parseFlags & ParsingPackageUtils.PARSE_CHATTY) != 0) { 141 Log.d(TAG, "Scanning package " + parsedPackage.getPackageName()); 142 } 143 } 144 145 // Initialize package source and resource directories 146 final File destCodeFile = new File(parsedPackage.getPath()); 147 148 // We keep references to the derived CPU Abis from settings in oder to reuse 149 // them in the case where we're not upgrading or booting for the first time. 150 String primaryCpuAbiFromSettings = null; 151 String secondaryCpuAbiFromSettings = null; 152 boolean needToDeriveAbi = (scanFlags & SCAN_FIRST_BOOT_OR_UPGRADE) != 0; 153 boolean isApex = (scanFlags & SCAN_AS_APEX) != 0; 154 155 if (!needToDeriveAbi) { 156 if (pkgSetting != null) { 157 // TODO(b/154610922): if it is not first boot or upgrade, we should directly use 158 // API info from existing package setting. However, stub packages currently do not 159 // preserve ABI info, thus the special condition check here. Remove the special 160 // check after we fix the stub generation. 161 if (pkgSetting.getPkg() != null && pkgSetting.getPkg().isStub()) { 162 needToDeriveAbi = true; 163 } else { 164 primaryCpuAbiFromSettings = pkgSetting.getPrimaryCpuAbiLegacy(); 165 secondaryCpuAbiFromSettings = pkgSetting.getSecondaryCpuAbiLegacy(); 166 } 167 } else { 168 // Re-scanning a system package after uninstalling updates; need to derive ABI 169 needToDeriveAbi = true; 170 } 171 } 172 173 boolean isPendingRestoreBefore = false; 174 if (pkgSetting != null && oldSharedUserSetting != sharedUserSetting) { 175 PackageManagerService.reportSettingsProblem(Log.WARN, 176 "Package " + parsedPackage.getPackageName() + " shared user changed from " 177 + (oldSharedUserSetting != null 178 ? oldSharedUserSetting.name : "<nothing>") 179 + " to " 180 + (sharedUserSetting != null ? sharedUserSetting.name : "<nothing>") 181 + "; replacing with new"); 182 // Preserve the value of isPendingRestore. We need to set it to the new PackageSetting 183 // if the value is true to restore the app 184 isPendingRestoreBefore = pkgSetting.isPendingRestore(); 185 pkgSetting = null; 186 } 187 188 String[] usesSdkLibraries = null; 189 if (!parsedPackage.getUsesSdkLibraries().isEmpty()) { 190 usesSdkLibraries = new String[parsedPackage.getUsesSdkLibraries().size()]; 191 parsedPackage.getUsesSdkLibraries().toArray(usesSdkLibraries); 192 } 193 194 String[] usesStaticLibraries = null; 195 if (!parsedPackage.getUsesStaticLibraries().isEmpty()) { 196 usesStaticLibraries = new String[parsedPackage.getUsesStaticLibraries().size()]; 197 parsedPackage.getUsesStaticLibraries().toArray(usesStaticLibraries); 198 } 199 200 final UUID newDomainSetId = injector.getDomainVerificationManagerInternal().generateNewId(); 201 202 // TODO(b/135203078): Remove appInfoFlag usage in favor of individually assigned booleans 203 // to avoid adding something that's unsupported due to lack of state, since it's called 204 // with null. 205 final boolean createNewPackage = (pkgSetting == null); 206 if (createNewPackage) { 207 final boolean instantApp = (scanFlags & SCAN_AS_INSTANT_APP) != 0; 208 final boolean virtualPreload = (scanFlags & SCAN_AS_VIRTUAL_PRELOAD) != 0; 209 final boolean isStoppedSystemApp = (scanFlags & SCAN_AS_STOPPED_SYSTEM_APP) != 0; 210 211 // Flags contain system values stored in the server variant of AndroidPackage, 212 // and so the server-side PackageInfoUtils is still called, even without a 213 // PackageSetting to pass in. 214 int pkgFlags = PackageInfoUtils.appInfoFlags(parsedPackage, null); 215 int pkgPrivateFlags = PackageInfoUtils.appInfoPrivateFlags(parsedPackage, null); 216 217 // REMOVE SharedUserSetting from method; update in a separate call 218 pkgSetting = Settings.createNewSetting(parsedPackage.getPackageName(), 219 originalPkgSetting, disabledPkgSetting, realPkgName, sharedUserSetting, 220 destCodeFile, parsedPackage.getNativeLibraryRootDir(), 221 AndroidPackageUtils.getRawPrimaryCpuAbi(parsedPackage), 222 AndroidPackageUtils.getRawSecondaryCpuAbi(parsedPackage), 223 parsedPackage.getLongVersionCode(), pkgFlags, pkgPrivateFlags, user, 224 true /*allowInstall*/, instantApp, virtualPreload, isStoppedSystemApp, 225 UserManagerService.getInstance(), usesSdkLibraries, 226 parsedPackage.getUsesSdkLibrariesVersionsMajor(), 227 parsedPackage.getUsesSdkLibrariesOptional(), usesStaticLibraries, 228 parsedPackage.getUsesStaticLibrariesVersions(), parsedPackage.getMimeGroups(), 229 newDomainSetId, 230 parsedPackage.getTargetSdkVersion(), parsedPackage.getRestrictUpdateHash()); 231 232 // If isPendingRestore is true before, set the value true to the PackageSetting 233 if (isPendingRestoreBefore) { 234 pkgSetting.setPendingRestore(true); 235 } 236 } else { 237 // make a deep copy to avoid modifying any existing system state. 238 pkgSetting = new PackageSetting(pkgSetting); 239 pkgSetting.setPkg(parsedPackage); 240 final boolean isDontKill = (scanFlags & SCAN_DONT_KILL_APP) != 0; 241 242 // REMOVE SharedUserSetting from method; update in a separate call. 243 // 244 // TODO(narayan): This update is bogus. nativeLibraryDir & primaryCpuAbi, 245 // secondaryCpuAbi are not known at this point so we always update them 246 // to null here, only to reset them at a later point. 247 Settings.updatePackageSetting(pkgSetting, disabledPkgSetting, oldSharedUserSetting, 248 sharedUserSetting, destCodeFile, parsedPackage.getNativeLibraryDir(), 249 pkgSetting.getPrimaryCpuAbi(), 250 pkgSetting.getSecondaryCpuAbi(), 251 PackageInfoUtils.appInfoFlags(parsedPackage, pkgSetting), 252 PackageInfoUtils.appInfoPrivateFlags(parsedPackage, pkgSetting), 253 UserManagerService.getInstance(), 254 usesSdkLibraries, parsedPackage.getUsesSdkLibrariesVersionsMajor(), 255 parsedPackage.getUsesSdkLibrariesOptional(), 256 usesStaticLibraries, parsedPackage.getUsesStaticLibrariesVersions(), 257 parsedPackage.getMimeGroups(), newDomainSetId, 258 parsedPackage.getTargetSdkVersion(), parsedPackage.getRestrictUpdateHash(), 259 isDontKill); 260 } 261 262 if (createNewPackage && originalPkgSetting != null) { 263 // This is the initial transition from the original package, so, 264 // fix up the new package's name now. We must do this after looking 265 // up the package under its new name, so getPackageLP takes care of 266 // fiddling things correctly. 267 parsedPackage.setPackageName(originalPkgSetting.getPackageName()); 268 269 // File a report about this. 270 String msg = "New package " + pkgSetting.getRealName() 271 + " renamed to replace old package " + pkgSetting.getPackageName(); 272 PackageManagerService.reportSettingsProblem(Log.WARN, msg); 273 } 274 275 final int userId = (user == null ? UserHandle.USER_SYSTEM : user.getIdentifier()); 276 // for existing packages, change the install state; but, only if it's explicitly specified 277 if (!createNewPackage) { 278 final boolean instantApp = (scanFlags & SCAN_AS_INSTANT_APP) != 0; 279 final boolean fullApp = (scanFlags & SCAN_AS_FULL_APP) != 0; 280 setInstantAppForUser(injector, pkgSetting, userId, instantApp, fullApp); 281 } 282 // TODO(patb): see if we can do away with disabled check here. 283 if (disabledPkgSetting != null 284 || (0 != (scanFlags & SCAN_NEW_INSTALL) 285 && pkgSetting != null && pkgSetting.isSystem())) { 286 pkgSetting.getPkgState().setUpdatedSystemApp(true); 287 } 288 289 pkgSetting.getTransientState().setSeInfo(SELinuxMMAC.getSeInfo(pkgSetting, parsedPackage, 290 sharedUserSetting, injector.getCompatibility())); 291 292 if (pkgSetting.isSystem()) { 293 configurePackageComponents(parsedPackage); 294 } 295 296 final String cpuAbiOverride = deriveAbiOverride(request.mCpuAbiOverride); 297 final boolean isSystemApp = pkgSetting.isSystem(); 298 final boolean isUpdatedSystemApp = pkgSetting.isUpdatedSystemApp(); 299 300 final File appLib32InstallDir = getAppLib32InstallDir(); 301 // The native libs of Apex is located in apex_payload.img, don't need to parse it from 302 // the original apex file 303 if (!isApex) { 304 if ((scanFlags & SCAN_NEW_INSTALL) == 0) { 305 if (needToDeriveAbi) { 306 Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "derivePackageAbi"); 307 try { 308 final Pair<PackageAbiHelper.Abis, PackageAbiHelper.NativeLibraryPaths> 309 derivedAbi = 310 packageAbiHelper.derivePackageAbi( 311 parsedPackage, 312 isSystemApp, 313 isUpdatedSystemApp, 314 cpuAbiOverride, 315 appLib32InstallDir); 316 derivedAbi.first.applyTo(parsedPackage); 317 derivedAbi.second.applyTo(parsedPackage); 318 } finally { 319 Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER); 320 } 321 322 // Some system apps still use directory structure for native libraries 323 // in which case we might end up not detecting abi solely based on apk 324 // structure. Try to detect abi based on directory structure. 325 326 String pkgRawPrimaryCpuAbi = AndroidPackageUtils.getRawPrimaryCpuAbi( 327 parsedPackage); 328 if (isSystemApp && !isUpdatedSystemApp && pkgRawPrimaryCpuAbi == null) { 329 final PackageAbiHelper.Abis abis = packageAbiHelper.getBundledAppAbis( 330 parsedPackage); 331 abis.applyTo(parsedPackage); 332 abis.applyTo(pkgSetting); 333 final PackageAbiHelper.NativeLibraryPaths nativeLibraryPaths = 334 packageAbiHelper.deriveNativeLibraryPaths(parsedPackage, 335 isSystemApp, isUpdatedSystemApp, appLib32InstallDir); 336 nativeLibraryPaths.applyTo(parsedPackage); 337 } 338 } else { 339 // This is not a first boot or an upgrade, don't bother deriving the 340 // ABI during the scan. Instead, trust the value that was stored in the 341 // package setting. 342 parsedPackage.setPrimaryCpuAbi(primaryCpuAbiFromSettings) 343 .setSecondaryCpuAbi(secondaryCpuAbiFromSettings); 344 345 final PackageAbiHelper.NativeLibraryPaths nativeLibraryPaths = 346 packageAbiHelper.deriveNativeLibraryPaths(parsedPackage, isSystemApp, 347 isUpdatedSystemApp, appLib32InstallDir); 348 nativeLibraryPaths.applyTo(parsedPackage); 349 350 if (DEBUG_ABI_SELECTION) { 351 Slog.i(TAG, "Using ABIS and native lib paths from settings : " 352 + parsedPackage.getPackageName() + " " 353 + AndroidPackageUtils.getRawPrimaryCpuAbi(parsedPackage) 354 + ", " 355 + AndroidPackageUtils.getRawSecondaryCpuAbi(parsedPackage)); 356 } 357 } 358 } else { 359 if ((scanFlags & SCAN_MOVE) != 0) { 360 // We haven't run dex-opt for this move (since we've moved the compiled output 361 // too) but we already have this packages package info in the PackageSetting. 362 // We just use that and derive the native library path based on the new code 363 // path. 364 parsedPackage.setPrimaryCpuAbi(pkgSetting.getPrimaryCpuAbiLegacy()) 365 .setSecondaryCpuAbi(pkgSetting.getSecondaryCpuAbiLegacy()); 366 } 367 368 // Set native library paths again. For moves, the path will be updated based on the 369 // ABIs we've determined above. For non-moves, the path will be updated based on the 370 // ABIs we determined during compilation, but the path will depend on the final 371 // package path (after the rename away from the stage path). 372 final PackageAbiHelper.NativeLibraryPaths nativeLibraryPaths = 373 packageAbiHelper.deriveNativeLibraryPaths(parsedPackage, isSystemApp, 374 isUpdatedSystemApp, appLib32InstallDir); 375 nativeLibraryPaths.applyTo(parsedPackage); 376 } 377 378 // This is a special case for the "system" package, where the ABI is 379 // dictated by the zygote configuration (and init.rc). We should keep track 380 // of this ABI so that we can deal with "normal" applications that run under 381 // the same UID correctly. 382 if (isPlatformPackage) { 383 parsedPackage.setPrimaryCpuAbi(VMRuntime.getRuntime().is64Bit() 384 ? Build.SUPPORTED_64_BIT_ABIS[0] : Build.SUPPORTED_32_BIT_ABIS[0]); 385 } 386 } 387 388 // If there's a mismatch between the abi-override in the package setting 389 // and the abiOverride specified for the install. Warn about this because we 390 // would've already compiled the app without taking the package setting into 391 // account. 392 if ((scanFlags & SCAN_NO_DEX) == 0 && (scanFlags & SCAN_NEW_INSTALL) != 0) { 393 if (cpuAbiOverride == null) { 394 Slog.w(TAG, "Ignoring persisted ABI override for package " 395 + parsedPackage.getPackageName()); 396 } 397 } 398 399 pkgSetting.setPrimaryCpuAbi(AndroidPackageUtils.getRawPrimaryCpuAbi(parsedPackage)) 400 .setSecondaryCpuAbi(AndroidPackageUtils.getRawSecondaryCpuAbi(parsedPackage)) 401 .setCpuAbiOverride(cpuAbiOverride); 402 403 if (DEBUG_ABI_SELECTION) { 404 Slog.d(TAG, "Resolved nativeLibraryRoot for " + parsedPackage.getPackageName() 405 + " to root=" + parsedPackage.getNativeLibraryRootDir() 406 + ", to dir=" + parsedPackage.getNativeLibraryDir() 407 + ", isa=" + parsedPackage.isNativeLibraryRootRequiresIsa()); 408 } 409 410 // Push the derived path down into PackageSettings so we know what to 411 // clean up at uninstall time. 412 pkgSetting.setLegacyNativeLibraryPath(parsedPackage.getNativeLibraryRootDir()); 413 414 if (DEBUG_ABI_SELECTION) { 415 Log.d(TAG, "Abis for package[" + parsedPackage.getPackageName() + "] are" 416 + " primary=" + pkgSetting.getPrimaryCpuAbiLegacy() 417 + " secondary=" + pkgSetting.getSecondaryCpuAbiLegacy() 418 + " abiOverride=" + pkgSetting.getCpuAbiOverride()); 419 } 420 421 if ((scanFlags & SCAN_BOOTING) == 0 && oldSharedUserSetting != null) { 422 // We don't do this here during boot because we can do it all 423 // at once after scanning all existing packages. 424 // 425 // We also do this *before* we perform dexopt on this package, so that 426 // we can avoid redundant dexopts, and also to make sure we've got the 427 // code and package path correct. 428 changedAbiCodePath = applyAdjustedAbiToSharedUser(oldSharedUserSetting, 429 parsedPackage, packageAbiHelper.getAdjustedAbiForSharedUser( 430 oldSharedUserSetting.getPackageStates(), parsedPackage)); 431 } 432 433 parsedPackage.setFactoryTest(isUnderFactoryTest && parsedPackage.getRequestedPermissions() 434 .contains(android.Manifest.permission.FACTORY_TEST)); 435 436 if (isSystemApp) { 437 pkgSetting.setIsOrphaned(true); 438 } 439 440 // Take care of first install / last update times. 441 final long scanFileTime = getLastModifiedTime(parsedPackage); 442 final long existingFirstInstallTime = userId == UserHandle.USER_ALL 443 ? PackageStateUtils.getEarliestFirstInstallTime(pkgSetting.getUserStates()) 444 : pkgSetting.readUserState(userId).getFirstInstallTimeMillis(); 445 if (currentTime != 0) { 446 if (existingFirstInstallTime == 0) { 447 pkgSetting.setFirstInstallTime(currentTime, userId) 448 .setLastUpdateTime(currentTime); 449 } else if ((scanFlags & SCAN_UPDATE_TIME) != 0) { 450 pkgSetting.setLastUpdateTime(currentTime); 451 } 452 } else if (existingFirstInstallTime == 0) { 453 // We need *something*. Take time stamp of the file. 454 pkgSetting.setFirstInstallTime(scanFileTime, userId) 455 .setLastUpdateTime(scanFileTime); 456 } else if ((parseFlags & ParsingPackageUtils.PARSE_IS_SYSTEM_DIR) != 0) { 457 if (scanFileTime != pkgSetting.getLastModifiedTime()) { 458 // A package on the system image has changed; consider this 459 // to be an update. 460 pkgSetting.setLastUpdateTime(scanFileTime); 461 } 462 } 463 pkgSetting.setLastModifiedTime(scanFileTime); 464 // TODO(b/135203078): Remove, move to constructor 465 pkgSetting.setPkg(parsedPackage) 466 .setFlags(PackageInfoUtils.appInfoFlags(parsedPackage, pkgSetting)) 467 .setPrivateFlags(PackageInfoUtils.appInfoPrivateFlags(parsedPackage, pkgSetting)); 468 if (parsedPackage.getLongVersionCode() != pkgSetting.getVersionCode()) { 469 pkgSetting.setLongVersionCode(parsedPackage.getLongVersionCode()); 470 } 471 // Update volume if needed 472 final String volumeUuid = parsedPackage.getVolumeUuid(); 473 if (!Objects.equals(volumeUuid, pkgSetting.getVolumeUuid())) { 474 Slog.i(PackageManagerService.TAG, 475 "Update" + (pkgSetting.isSystem() ? " system" : "") 476 + " package " + parsedPackage.getPackageName() 477 + " volume from " + pkgSetting.getVolumeUuid() 478 + " to " + volumeUuid); 479 pkgSetting.setVolumeUuid(volumeUuid); 480 } 481 482 SharedLibraryInfo sdkLibraryInfo = null; 483 if (!TextUtils.isEmpty(parsedPackage.getSdkLibraryName())) { 484 sdkLibraryInfo = AndroidPackageUtils.createSharedLibraryForSdk(parsedPackage); 485 } 486 SharedLibraryInfo staticSharedLibraryInfo = null; 487 if (!TextUtils.isEmpty(parsedPackage.getStaticSharedLibraryName())) { 488 staticSharedLibraryInfo = 489 AndroidPackageUtils.createSharedLibraryForStatic(parsedPackage); 490 } 491 List<SharedLibraryInfo> dynamicSharedLibraryInfos = null; 492 if (!ArrayUtils.isEmpty(parsedPackage.getLibraryNames())) { 493 dynamicSharedLibraryInfos = new ArrayList<>(parsedPackage.getLibraryNames().size()); 494 for (String name : parsedPackage.getLibraryNames()) { 495 dynamicSharedLibraryInfos.add( 496 AndroidPackageUtils.createSharedLibraryForDynamic(parsedPackage, name)); 497 } 498 } 499 500 return new ScanResult(request, pkgSetting, changedAbiCodePath, 501 !createNewPackage /* existingSettingCopied */, 502 Process.INVALID_UID /* previousAppId */ , sdkLibraryInfo, 503 staticSharedLibraryInfo, dynamicSharedLibraryInfos); 504 } 505 506 /** 507 * Returns the actual scan flags depending upon the state of the other settings. 508 * <p>Updated system applications will not have the following flags set 509 * by default and need to be adjusted after the fact: 510 * <ul> 511 * <li>{@link PackageManagerService.SCAN_AS_SYSTEM}</li> 512 * <li>{@link PackageManagerService.SCAN_AS_PRIVILEGED}</li> 513 * <li>{@link PackageManagerService.SCAN_AS_OEM}</li> 514 * <li>{@link PackageManagerService.SCAN_AS_VENDOR}</li> 515 * <li>{@link PackageManagerService.SCAN_AS_PRODUCT}</li> 516 * <li>{@link PackageManagerService.SCAN_AS_SYSTEM_EXT}</li> 517 * <li>{@link PackageManagerService.SCAN_AS_INSTANT_APP}</li> 518 * <li>{@link PackageManagerService.SCAN_AS_VIRTUAL_PRELOAD}</li> 519 * <li>{@link PackageManagerService.SCAN_AS_ODM}</li> 520 * </ul> 521 */ adjustScanFlagsWithPackageSetting( @ackageManagerService.ScanFlags int scanFlags, PackageSetting pkgSetting, PackageSetting disabledPkgSetting, UserHandle user)522 public static @PackageManagerService.ScanFlags int adjustScanFlagsWithPackageSetting( 523 @PackageManagerService.ScanFlags int scanFlags, 524 PackageSetting pkgSetting, PackageSetting disabledPkgSetting, UserHandle user) { 525 526 // TODO(patb): Do away entirely with disabledPkgSetting here. PkgSetting will always contain 527 // the correct isSystem value now that we don't disable system packages before scan. 528 final PackageSetting systemPkgSetting = 529 (scanFlags & SCAN_NEW_INSTALL) != 0 && disabledPkgSetting == null 530 && pkgSetting != null && pkgSetting.isSystem() 531 ? pkgSetting 532 : disabledPkgSetting; 533 if (systemPkgSetting != null) { 534 // updated system application, must at least have SCAN_AS_SYSTEM 535 scanFlags |= SCAN_AS_SYSTEM; 536 if ((systemPkgSetting.getPrivateFlags() 537 & ApplicationInfo.PRIVATE_FLAG_PRIVILEGED) != 0) { 538 scanFlags |= SCAN_AS_PRIVILEGED; 539 } 540 if ((systemPkgSetting.getPrivateFlags() 541 & ApplicationInfo.PRIVATE_FLAG_OEM) != 0) { 542 scanFlags |= SCAN_AS_OEM; 543 } 544 if ((systemPkgSetting.getPrivateFlags() 545 & ApplicationInfo.PRIVATE_FLAG_VENDOR) != 0) { 546 scanFlags |= SCAN_AS_VENDOR; 547 } 548 if ((systemPkgSetting.getPrivateFlags() 549 & ApplicationInfo.PRIVATE_FLAG_PRODUCT) != 0) { 550 scanFlags |= SCAN_AS_PRODUCT; 551 } 552 if ((systemPkgSetting.getPrivateFlags() 553 & ApplicationInfo.PRIVATE_FLAG_SYSTEM_EXT) != 0) { 554 scanFlags |= SCAN_AS_SYSTEM_EXT; 555 } 556 if ((systemPkgSetting.getPrivateFlags() 557 & ApplicationInfo.PRIVATE_FLAG_ODM) != 0) { 558 scanFlags |= SCAN_AS_ODM; 559 } 560 } 561 if (pkgSetting != null) { 562 final int userId = ((user == null) ? 0 : user.getIdentifier()); 563 if (pkgSetting.getInstantApp(userId)) { 564 scanFlags |= SCAN_AS_INSTANT_APP; 565 } 566 if (pkgSetting.getVirtualPreload(userId)) { 567 scanFlags |= SCAN_AS_VIRTUAL_PRELOAD; 568 } 569 } 570 571 return scanFlags; 572 } 573 574 /** 575 * Enforces code policy for the package. This ensures that if an APK has 576 * declared hasCode="true" in its manifest that the APK actually contains 577 * code. 578 * 579 * @throws PackageManagerException If bytecode could not be found when it should exist 580 */ assertCodePolicy(AndroidPackage pkg)581 public static void assertCodePolicy(AndroidPackage pkg) 582 throws PackageManagerException { 583 final boolean shouldHaveCode = pkg.isDeclaredHavingCode(); 584 if (shouldHaveCode && !apkHasCode(pkg.getBaseApkPath())) { 585 throw new PackageManagerException(INSTALL_FAILED_INVALID_APK, 586 "Package " + pkg.getBaseApkPath() + " code is missing"); 587 } 588 589 if (!ArrayUtils.isEmpty(pkg.getSplitCodePaths())) { 590 for (int i = 0; i < pkg.getSplitCodePaths().length; i++) { 591 final boolean splitShouldHaveCode = 592 (pkg.getSplitFlags()[i] & ApplicationInfo.FLAG_HAS_CODE) != 0; 593 if (splitShouldHaveCode && !apkHasCode(pkg.getSplitCodePaths()[i])) { 594 throw new PackageManagerException(INSTALL_FAILED_INVALID_APK, 595 "Package " + pkg.getSplitCodePaths()[i] + " code is missing"); 596 } 597 } 598 } 599 } 600 assertStaticSharedLibraryIsValid(AndroidPackage pkg, @PackageManagerService.ScanFlags int scanFlags)601 public static void assertStaticSharedLibraryIsValid(AndroidPackage pkg, 602 @PackageManagerService.ScanFlags int scanFlags) throws PackageManagerException { 603 // Static shared libraries should have at least O target SDK 604 if (pkg.getTargetSdkVersion() < Build.VERSION_CODES.O) { 605 throw PackageManagerException.ofInternalError( 606 "Packages declaring static-shared libs must target O SDK or higher", 607 PackageManagerException.INTERNAL_ERROR_STATIC_SHARED_LIB_LOW_SDK); 608 } 609 610 // Package declaring static a shared lib cannot be instant apps 611 if ((scanFlags & SCAN_AS_INSTANT_APP) != 0) { 612 throw PackageManagerException.ofInternalError( 613 "Packages declaring static-shared libs cannot be instant apps", 614 PackageManagerException.INTERNAL_ERROR_STATIC_SHARED_LIB_INSTANT); 615 } 616 617 // Package declaring static a shared lib cannot be renamed since the package 618 // name is synthetic and apps can't code around package manager internals. 619 if (!ArrayUtils.isEmpty(pkg.getOriginalPackages())) { 620 throw PackageManagerException.ofInternalError( 621 "Packages declaring static-shared libs cannot be renamed", 622 PackageManagerException.INTERNAL_ERROR_STATIC_SHARED_LIB_RENAMED); 623 } 624 625 // Package declaring static a shared lib cannot declare dynamic libs 626 if (!ArrayUtils.isEmpty(pkg.getLibraryNames())) { 627 throw PackageManagerException.ofInternalError( 628 "Packages declaring static-shared libs cannot declare dynamic libs", 629 PackageManagerException.INTERNAL_ERROR_STATIC_SHARED_LIB_DYNAMIC); 630 } 631 632 // Package declaring static a shared lib cannot declare shared users 633 if (pkg.getSharedUserId() != null) { 634 throw PackageManagerException.ofInternalError( 635 "Packages declaring static-shared libs cannot declare shared users", 636 PackageManagerException.INTERNAL_ERROR_STATIC_SHARED_LIB_SHARED_USER); 637 } 638 639 // Static shared libs cannot declare activities 640 if (!pkg.getActivities().isEmpty()) { 641 throw PackageManagerException.ofInternalError( 642 "Static shared libs cannot declare activities", 643 PackageManagerException.INTERNAL_ERROR_STATIC_SHARED_LIB_ACTIVITY); 644 } 645 646 // Static shared libs cannot declare services 647 if (!pkg.getServices().isEmpty()) { 648 throw PackageManagerException.ofInternalError( 649 "Static shared libs cannot declare services", 650 PackageManagerException.INTERNAL_ERROR_STATIC_SHARED_LIB_SERVICE); 651 } 652 653 // Static shared libs cannot declare providers 654 if (!pkg.getProviders().isEmpty()) { 655 throw PackageManagerException.ofInternalError( 656 "Static shared libs cannot declare content providers", 657 PackageManagerException.INTERNAL_ERROR_STATIC_SHARED_LIB_CONTENT_PROVIDER); 658 } 659 660 // Static shared libs cannot declare receivers 661 if (!pkg.getReceivers().isEmpty()) { 662 throw PackageManagerException.ofInternalError( 663 "Static shared libs cannot declare broadcast receivers", 664 PackageManagerException.INTERNAL_ERROR_STATIC_SHARED_LIB_BROADCAST_RECEIVER); 665 } 666 667 // Static shared libs cannot declare permission groups 668 if (!pkg.getPermissionGroups().isEmpty()) { 669 throw PackageManagerException.ofInternalError( 670 "Static shared libs cannot declare permission groups", 671 PackageManagerException.INTERNAL_ERROR_STATIC_SHARED_LIB_PERMISSION_GROUP); 672 } 673 674 // Static shared libs cannot declare attributions 675 if (!pkg.getAttributions().isEmpty()) { 676 throw PackageManagerException.ofInternalError( 677 "Static shared libs cannot declare features", 678 PackageManagerException.INTERNAL_ERROR_STATIC_SHARED_LIB_FEATURE); 679 } 680 681 // Static shared libs cannot declare permissions 682 if (!pkg.getPermissions().isEmpty()) { 683 throw PackageManagerException.ofInternalError( 684 "Static shared libs cannot declare permissions", 685 PackageManagerException.INTERNAL_ERROR_STATIC_SHARED_LIB_PERMISSION); 686 } 687 688 // Static shared libs cannot declare protected broadcasts 689 if (!pkg.getProtectedBroadcasts().isEmpty()) { 690 throw PackageManagerException.ofInternalError( 691 "Static shared libs cannot declare protected broadcasts", 692 PackageManagerException.INTERNAL_ERROR_STATIC_SHARED_LIB_PROTECTED_BROADCAST); 693 } 694 695 // Static shared libs cannot be overlay targets 696 if (pkg.getOverlayTarget() != null) { 697 throw PackageManagerException.ofInternalError( 698 "Static shared libs cannot be overlay targets", 699 PackageManagerException.INTERNAL_ERROR_STATIC_SHARED_LIB_OVERLAY_TARGETS); 700 } 701 } 702 assertProcessesAreValid(AndroidPackage pkg)703 public static void assertProcessesAreValid(AndroidPackage pkg) throws PackageManagerException { 704 final Map<String, ParsedProcess> procs = pkg.getProcesses(); 705 if (!procs.isEmpty()) { 706 if (!procs.containsKey(pkg.getProcessName())) { 707 throw new PackageManagerException( 708 INSTALL_FAILED_PROCESS_NOT_DEFINED, 709 "Can't install because application tag's process attribute " 710 + pkg.getProcessName() 711 + " (in package " + pkg.getPackageName() 712 + ") is not included in the <processes> list"); 713 } 714 assertPackageProcesses(pkg, pkg.getActivities(), procs, "activity"); 715 assertPackageProcesses(pkg, pkg.getServices(), procs, "service"); 716 assertPackageProcesses(pkg, pkg.getReceivers(), procs, "receiver"); 717 assertPackageProcesses(pkg, pkg.getProviders(), procs, "provider"); 718 } 719 } 720 assertPackageProcesses(AndroidPackage pkg, List<T> components, Map<String, ParsedProcess> procs, String compName)721 private static <T extends ParsedMainComponent> void assertPackageProcesses(AndroidPackage pkg, 722 List<T> components, Map<String, ParsedProcess> procs, String compName) 723 throws PackageManagerException { 724 if (components == null) { 725 return; 726 } 727 for (int i = components.size() - 1; i >= 0; i--) { 728 final ParsedMainComponent component = components.get(i); 729 if (!procs.containsKey(component.getProcessName())) { 730 throw new PackageManagerException( 731 INSTALL_FAILED_PROCESS_NOT_DEFINED, 732 "Can't install because " + compName + " " + component.getClassName() 733 + "'s process attribute " + component.getProcessName() 734 + " (in package " + pkg.getPackageName() 735 + ") is not included in the <processes> list"); 736 } 737 } 738 } 739 assertMinSignatureSchemeIsValid(AndroidPackage pkg, @ParsingPackageUtils.ParseFlags int parseFlags)740 public static void assertMinSignatureSchemeIsValid(AndroidPackage pkg, 741 @ParsingPackageUtils.ParseFlags int parseFlags) throws PackageManagerException { 742 int minSignatureSchemeVersion = 743 ApkSignatureVerifier.getMinimumSignatureSchemeVersionForTargetSdk( 744 pkg.getTargetSdkVersion()); 745 if (pkg.getSigningDetails().getSignatureSchemeVersion() 746 < minSignatureSchemeVersion) { 747 throw new PackageManagerException(INSTALL_PARSE_FAILED_NO_CERTIFICATES, 748 "No signature found in package of version " + minSignatureSchemeVersion 749 + " or newer for package " + pkg.getPackageName()); 750 } 751 } 752 753 /** 754 * Returns the "real" name of the package. 755 * <p>This may differ from the package's actual name if the application has already 756 * been installed under one of this package's original names. 757 */ getRealPackageName(@onNull AndroidPackage pkg, @Nullable String renamedPkgName, boolean isSystemApp)758 public static @Nullable String getRealPackageName(@NonNull AndroidPackage pkg, 759 @Nullable String renamedPkgName, boolean isSystemApp) { 760 if (isPackageRenamed(pkg, renamedPkgName)) { 761 return AndroidPackageUtils.getRealPackageOrNull(pkg, isSystemApp); 762 } 763 return null; 764 } 765 766 /** Returns {@code true} if the package has been renamed. Otherwise, {@code false}. */ isPackageRenamed(@onNull AndroidPackage pkg, @Nullable String renamedPkgName)767 public static boolean isPackageRenamed(@NonNull AndroidPackage pkg, 768 @Nullable String renamedPkgName) { 769 return pkg.getOriginalPackages().contains(renamedPkgName); 770 } 771 772 /** 773 * Renames the package if it was installed under a different name. 774 * <p>When we've already installed the package under an original name, update 775 * the new package so we can continue to have the old name. 776 */ ensurePackageRenamed(@onNull ParsedPackage parsedPackage, @NonNull String renamedPackageName)777 public static void ensurePackageRenamed(@NonNull ParsedPackage parsedPackage, 778 @NonNull String renamedPackageName) { 779 if (!parsedPackage.getOriginalPackages().contains(renamedPackageName) 780 || parsedPackage.getPackageName().equals(renamedPackageName)) { 781 return; 782 } 783 parsedPackage.setPackageName(renamedPackageName); 784 } 785 786 /** 787 * Returns {@code true} if the given file contains code. Otherwise {@code false}. 788 */ apkHasCode(String fileName)789 public static boolean apkHasCode(String fileName) { 790 StrictJarFile jarFile = null; 791 try { 792 jarFile = new StrictJarFile(fileName, 793 false /*verify*/, false /*signatureSchemeRollbackProtectionsEnforced*/); 794 return jarFile.findEntry("classes.dex") != null; 795 } catch (IOException ignore) { 796 } finally { 797 try { 798 if (jarFile != null) { 799 jarFile.close(); 800 } 801 } catch (IOException ignore) { 802 } 803 } 804 return false; 805 } 806 807 /** 808 * Sets the enabled state of components configured through {@link SystemConfig}. 809 * This modifies the {@link PackageSetting} object. 810 * 811 * TODO(b/135203078): Move this to package parsing 812 **/ configurePackageComponents(AndroidPackage pkg)813 public static void configurePackageComponents(AndroidPackage pkg) { 814 final ArrayMap<String, Boolean> componentsEnabledStates = SystemConfig.getInstance() 815 .getComponentsEnabledStates(pkg.getPackageName()); 816 if (componentsEnabledStates == null) { 817 return; 818 } 819 820 for (int i = ArrayUtils.size(pkg.getActivities()) - 1; i >= 0; i--) { 821 final ParsedActivity component = pkg.getActivities().get(i); 822 final Boolean enabled = componentsEnabledStates.get(component.getName()); 823 if (enabled != null) { 824 ComponentMutateUtils.setEnabled(component, enabled); 825 } 826 } 827 828 for (int i = ArrayUtils.size(pkg.getReceivers()) - 1; i >= 0; i--) { 829 final ParsedActivity component = pkg.getReceivers().get(i); 830 final Boolean enabled = componentsEnabledStates.get(component.getName()); 831 if (enabled != null) { 832 ComponentMutateUtils.setEnabled(component, enabled); 833 } 834 } 835 836 for (int i = ArrayUtils.size(pkg.getProviders()) - 1; i >= 0; i--) { 837 final ParsedProvider component = pkg.getProviders().get(i); 838 final Boolean enabled = componentsEnabledStates.get(component.getName()); 839 if (enabled != null) { 840 ComponentMutateUtils.setEnabled(component, enabled); 841 } 842 } 843 844 for (int i = ArrayUtils.size(pkg.getServices()) - 1; i >= 0; i--) { 845 final ParsedService component = pkg.getServices().get(i); 846 final Boolean enabled = componentsEnabledStates.get(component.getName()); 847 if (enabled != null) { 848 ComponentMutateUtils.setEnabled(component, enabled); 849 } 850 } 851 } 852 getVendorPartitionVersion()853 public static int getVendorPartitionVersion() { 854 final String version = SystemProperties.get("ro.vndk.version"); 855 if (!version.isEmpty()) { 856 try { 857 return Integer.parseInt(version); 858 } catch (NumberFormatException ignore) { 859 if (ArrayUtils.contains(Build.VERSION.ACTIVE_CODENAMES, version)) { 860 return Build.VERSION_CODES.CUR_DEVELOPMENT; 861 } 862 } 863 } 864 return Build.VERSION_CODES.P; 865 } 866 867 /** 868 * Applies policy to the parsed package based upon the given policy flags. 869 * Ensures the package is in a good state. 870 * <p> 871 * Implementation detail: This method must NOT have any side effect. It would 872 * ideally be static, but, it requires locks to read system state. 873 */ applyPolicy(ParsedPackage parsedPackage, final @PackageManagerService.ScanFlags int scanFlags, @Nullable AndroidPackage platformPkg, boolean isUpdatedSystemApp)874 public static void applyPolicy(ParsedPackage parsedPackage, 875 final @PackageManagerService.ScanFlags int scanFlags, 876 @Nullable AndroidPackage platformPkg, boolean isUpdatedSystemApp) { 877 // TODO: In the real APIs, an updated system app is always a system app, but that may not 878 // hold true during scan because PMS doesn't propagate the SCAN_AS_SYSTEM flag for the data 879 // directory. This tries to emulate that behavior by using either the flag or the boolean, 880 // but this logic is fragile. Specifically, it may affect the PackageBackwardCompatibility 881 // checker, which switches branches based on whether an app is a system app. When install 882 // is refactored, the scan policy flags should not be read this late and instead passed 883 // around in the PackageSetting or a temporary object which infers these values early, so 884 // that all further consumers agree on their values. 885 boolean isSystemApp = isUpdatedSystemApp; 886 if ((scanFlags & SCAN_AS_SYSTEM) != 0) { 887 isSystemApp = true; 888 parsedPackage.setSystem(true); 889 // TODO(b/135203078): Can this be done in PackageParser? Or just inferred when the flag 890 // is set during parse. 891 if (parsedPackage.isDirectBootAware()) { 892 parsedPackage.setAllComponentsDirectBootAware(true); 893 } 894 if (compressedFileExists(parsedPackage.getPath())) { 895 parsedPackage.setStub(true); 896 } 897 } else { 898 parsedPackage 899 // Non system apps cannot mark any broadcast as protected 900 .clearProtectedBroadcasts() 901 // non system apps can't be flagged as core 902 .setCoreApp(false) 903 // clear flags not applicable to regular apps 904 .setPersistent(false) 905 .setDefaultToDeviceProtectedStorage(false) 906 .setDirectBootAware(false) 907 // non system apps can't have permission priority 908 .capPermissionPriorities(); 909 } 910 if ((scanFlags & SCAN_AS_PRIVILEGED) == 0) { 911 parsedPackage 912 .markNotActivitiesAsNotExportedIfSingleUser(); 913 } 914 915 parsedPackage.setApex((scanFlags & SCAN_AS_APEX) != 0); 916 917 parsedPackage.setPrivileged((scanFlags & SCAN_AS_PRIVILEGED) != 0) 918 .setOem((scanFlags & SCAN_AS_OEM) != 0) 919 .setVendor((scanFlags & SCAN_AS_VENDOR) != 0) 920 .setProduct((scanFlags & SCAN_AS_PRODUCT) != 0) 921 .setSystemExt((scanFlags & SCAN_AS_SYSTEM_EXT) != 0) 922 .setOdm((scanFlags & SCAN_AS_ODM) != 0); 923 924 // Check if the package is signed with the same key as the platform package. 925 parsedPackage.setSignedWithPlatformKey( 926 (PLATFORM_PACKAGE_NAME.equals(parsedPackage.getPackageName()) 927 || (platformPkg != null && compareSignatures( 928 platformPkg.getSigningDetails(), 929 parsedPackage.getSigningDetails() 930 ) == PackageManager.SIGNATURE_MATCH)) 931 ); 932 933 if (!isSystemApp) { 934 // Only system apps can use these features. 935 parsedPackage.clearOriginalPackages() 936 .clearAdoptPermissions(); 937 } 938 939 PackageBackwardCompatibility.modifySharedLibraries(parsedPackage, isSystemApp, 940 isUpdatedSystemApp); 941 } 942 943 /** 944 * Applies the adjusted ABI calculated by 945 * {@link PackageAbiHelper#getAdjustedAbiForSharedUser(ArraySet, AndroidPackage)} to all 946 * relevant packages and settings. 947 * @param sharedUserSetting The {@code SharedUserSetting} to adjust 948 * @param scannedPackage the package being scanned or null 949 * @param adjustedAbi the adjusted ABI calculated by {@link PackageAbiHelper} 950 * @return the list of code paths that belong to packages that had their ABIs adjusted. 951 */ applyAdjustedAbiToSharedUser(SharedUserSetting sharedUserSetting, ParsedPackage scannedPackage, String adjustedAbi)952 public static List<String> applyAdjustedAbiToSharedUser(SharedUserSetting sharedUserSetting, 953 ParsedPackage scannedPackage, String adjustedAbi) { 954 if (scannedPackage != null) { 955 scannedPackage.setPrimaryCpuAbi(adjustedAbi); 956 } 957 List<String> changedAbiCodePath = null; 958 final WatchedArraySet<PackageSetting> sharedUserPackageSettings = 959 sharedUserSetting.getPackageSettings(); 960 for (int i = 0; i < sharedUserPackageSettings.size(); i++) { 961 PackageSetting ps = sharedUserPackageSettings.valueAt(i); 962 if (scannedPackage == null 963 || !scannedPackage.getPackageName().equals(ps.getPackageName())) { 964 if (ps.getPrimaryCpuAbiLegacy() != null) { 965 continue; 966 } 967 968 ps.setPrimaryCpuAbi(adjustedAbi); 969 ps.onChanged(); 970 if (ps.getPkg() != null) { 971 if (!TextUtils.equals(adjustedAbi, 972 AndroidPackageUtils.getRawPrimaryCpuAbi(ps.getPkg()))) { 973 if (DEBUG_ABI_SELECTION) { 974 Slog.i(TAG, 975 "Adjusting ABI for " + ps.getPackageName() + " to " 976 + adjustedAbi + " (scannedPackage=" 977 + (scannedPackage != null ? scannedPackage : "null") 978 + ")"); 979 } 980 if (changedAbiCodePath == null) { 981 changedAbiCodePath = new ArrayList<>(); 982 } 983 changedAbiCodePath.add(ps.getPathString()); 984 } 985 } 986 } 987 } 988 return changedAbiCodePath; 989 } 990 collectCertificatesLI(PackageSetting ps, ParsedPackage parsedPackage, Settings.VersionInfo settingsVersionForPackage, boolean forceCollect, boolean skipVerify, boolean isPreNMR1Upgrade)991 public static void collectCertificatesLI(PackageSetting ps, ParsedPackage parsedPackage, 992 Settings.VersionInfo settingsVersionForPackage, boolean forceCollect, 993 boolean skipVerify, boolean isPreNMR1Upgrade) 994 throws PackageManagerException { 995 // When upgrading from pre-N MR1, verify the package time stamp using the package 996 // directory and not the APK file. 997 final long lastModifiedTime = isPreNMR1Upgrade 998 ? new File(parsedPackage.getPath()).lastModified() 999 : getLastModifiedTime(parsedPackage); 1000 if (ps != null && !forceCollect 1001 && ps.getPathString().equals(parsedPackage.getPath()) 1002 && ps.getLastModifiedTime() == lastModifiedTime 1003 && !ReconcilePackageUtils.isCompatSignatureUpdateNeeded(settingsVersionForPackage) 1004 && !ReconcilePackageUtils.isRecoverSignatureUpdateNeeded( 1005 settingsVersionForPackage)) { 1006 if (ps.getSigningDetails().getSignatures() != null 1007 && ps.getSigningDetails().getSignatures().length != 0 1008 && ps.getSigningDetails().getSignatureSchemeVersion() 1009 != SigningDetails.SignatureSchemeVersion.UNKNOWN) { 1010 // Optimization: reuse the existing cached signing data 1011 // if the package appears to be unchanged. 1012 parsedPackage.setSigningDetails( 1013 new SigningDetails(ps.getSigningDetails())); 1014 return; 1015 } 1016 1017 Slog.w(TAG, "PackageSetting for " + ps.getPackageName() 1018 + " is missing signatures. Collecting certs again to recover them."); 1019 } else { 1020 Slog.i(TAG, parsedPackage.getPath() + " changed; collecting certs" 1021 + (forceCollect ? " (forced)" : "")); 1022 } 1023 1024 try { 1025 Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "collectCertificates"); 1026 final ParseTypeImpl input = ParseTypeImpl.forDefaultParsing(); 1027 final ParseResult<SigningDetails> result = ParsingPackageUtils.getSigningDetails( 1028 input, parsedPackage, skipVerify); 1029 if (result.isError()) { 1030 throw new PackageManagerException( 1031 result.getErrorCode(), result.getErrorMessage(), result.getException()); 1032 } 1033 parsedPackage.setSigningDetails(result.getResult()); 1034 } finally { 1035 Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER); 1036 } 1037 } 1038 setInstantAppForUser(PackageManagerServiceInjector injector, PackageSetting pkgSetting, int userId, boolean instantApp, boolean fullApp)1039 public static void setInstantAppForUser(PackageManagerServiceInjector injector, 1040 PackageSetting pkgSetting, int userId, boolean instantApp, boolean fullApp) { 1041 // no state specified; do nothing 1042 if (!instantApp && !fullApp) { 1043 return; 1044 } 1045 if (userId != UserHandle.USER_ALL) { 1046 if (instantApp && !pkgSetting.getInstantApp(userId)) { 1047 pkgSetting.setInstantApp(true /*instantApp*/, userId); 1048 } else if (fullApp && pkgSetting.getInstantApp(userId)) { 1049 pkgSetting.setInstantApp(false /*instantApp*/, userId); 1050 } 1051 } else { 1052 for (int currentUserId : injector.getUserManagerInternal().getUserIds()) { 1053 if (instantApp && !pkgSetting.getInstantApp(currentUserId)) { 1054 pkgSetting.setInstantApp(true /*instantApp*/, currentUserId); 1055 } else if (fullApp && pkgSetting.getInstantApp(currentUserId)) { 1056 pkgSetting.setInstantApp(false /*instantApp*/, currentUserId); 1057 } 1058 } 1059 } 1060 } 1061 1062 /** Directory where installed application's 32-bit native libraries are copied. */ getAppLib32InstallDir()1063 public static File getAppLib32InstallDir() { 1064 return new File(Environment.getDataDirectory(), "app-lib"); 1065 } 1066 } 1067