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