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