Loading core/java/android/os/UserHandle.java +1 −1 Original line number Diff line number Diff line Loading @@ -368,7 +368,7 @@ public final class UserHandle implements Parcelable { @UnsupportedAppUsage @TestApi public static int getUid(@UserIdInt int userId, @AppIdInt int appId) { if (MU_ENABLED) { if (MU_ENABLED && appId >= 0) { return userId * PER_USER_RANGE + (appId % PER_USER_RANGE); } else { return appId; Loading services/core/java/com/android/server/pm/ApexPackageInfo.java +4 −5 Original line number Diff line number Diff line Loading @@ -27,7 +27,6 @@ import android.content.pm.PackageInfo; import android.content.pm.PackageManager; import android.util.ArrayMap; import android.util.PrintWriterPrinter; import android.util.Slog; import com.android.internal.annotations.GuardedBy; import com.android.internal.util.IndentingPrintWriter; Loading Loading @@ -271,11 +270,11 @@ class ApexPackageInfo { } } ipw.println("Active APEX packages:"); dumpFromPackagesCache(getActivePackages(), packageName, ipw); dumpPackages(getActivePackages(), packageName, ipw); ipw.println("Inactive APEX packages:"); dumpFromPackagesCache(getInactivePackages(), packageName, ipw); dumpPackages(getInactivePackages(), packageName, ipw); ipw.println("Factory APEX packages:"); dumpFromPackagesCache(getFactoryPackages(), packageName, ipw); dumpPackages(getFactoryPackages(), packageName, ipw); } @GuardedBy("mLock") Loading Loading @@ -370,7 +369,7 @@ class ApexPackageInfo { * only information about that specific package will be dumped. * @param ipw the {@link IndentingPrintWriter} object to send information to. */ private static void dumpFromPackagesCache(List<PackageInfo> packagesCache, static void dumpPackages(List<PackageInfo> packagesCache, @Nullable String packageName, IndentingPrintWriter ipw) { ipw.println(); ipw.increaseIndent(); Loading services/core/java/com/android/server/pm/ComputerEngine.java +123 −26 Original line number Diff line number Diff line Loading @@ -984,9 +984,15 @@ public class ComputerEngine implements Computer { TAG, "getApplicationInfo " + packageName + ": " + p); } final boolean matchApex = (flags & MATCH_APEX) != 0; if (p != null) { PackageStateInternal ps = mSettings.getPackage(packageName); if (ps == null) return null; if (ApexPackageInfo.ENABLE_FEATURE_SCAN_APEX) { if (!matchApex && p.isApex()) { return null; } } if (filterSharedLibPackage(ps, filterCallingUid, userId, flags)) { return null; } Loading @@ -1001,7 +1007,8 @@ public class ComputerEngine implements Computer { } return ai; } if ((flags & PackageManager.MATCH_APEX) != 0) { if (!ApexPackageInfo.ENABLE_FEATURE_SCAN_APEX) { if (matchApex) { // For APKs, PackageInfo.applicationInfo is not exactly the same as ApplicationInfo // returned from getApplicationInfo, but for APEX packages difference shouldn't be // very big. Loading @@ -1016,6 +1023,7 @@ public class ComputerEngine implements Computer { } return pi.applicationInfo; } } if ("android".equals(packageName) || "system".equals(packageName)) { return androidApplication(); } Loading Loading @@ -1704,14 +1712,22 @@ public class ComputerEngine implements Computer { packageName = resolveInternalPackageName(packageName, versionCode); final boolean matchFactoryOnly = (flags & MATCH_FACTORY_ONLY) != 0; final boolean matchApex = (flags & MATCH_APEX) != 0; if (matchFactoryOnly) { // Instant app filtering for APEX modules is ignored if ((flags & MATCH_APEX) != 0) { if (!ApexPackageInfo.ENABLE_FEATURE_SCAN_APEX) { if (matchApex) { return mApexPackageInfo.getPackageInfo(packageName, ApexManager.MATCH_FACTORY_PACKAGE); } } final PackageStateInternal ps = mSettings.getDisabledSystemPkg(packageName); if (ps != null) { if (ApexPackageInfo.ENABLE_FEATURE_SCAN_APEX) { if (!matchApex && ps.getPkg() != null && ps.getPkg().isApex()) { return null; } } if (filterSharedLibPackage(ps, filterCallingUid, userId, flags)) { return null; } Loading @@ -1731,6 +1747,11 @@ public class ComputerEngine implements Computer { } if (p != null) { final PackageStateInternal ps = getPackageStateInternal(p.getPackageName()); if (ApexPackageInfo.ENABLE_FEATURE_SCAN_APEX) { if (!matchApex && p.isApex()) { return null; } } if (filterSharedLibPackage(ps, filterCallingUid, userId, flags)) { return null; } Loading @@ -1751,8 +1772,11 @@ public class ComputerEngine implements Computer { } return generatePackageInfo(ps, flags, userId); } if ((flags & MATCH_APEX) != 0) { return mApexPackageInfo.getPackageInfo(packageName, ApexManager.MATCH_ACTIVE_PACKAGE); if (!ApexPackageInfo.ENABLE_FEATURE_SCAN_APEX) { if (matchApex) { return mApexPackageInfo.getPackageInfo(packageName, ApexManager.MATCH_ACTIVE_PACKAGE); } } return null; } Loading Loading @@ -1809,6 +1833,11 @@ public class ComputerEngine implements Computer { ps = psDisabled; } } if (ApexPackageInfo.ENABLE_FEATURE_SCAN_APEX) { if (!listApex && ps.getPkg() != null && ps.getPkg().isApex()) { continue; } } if (filterSharedLibPackage(ps, callingUid, userId, flags)) { continue; } Loading @@ -1834,6 +1863,11 @@ public class ComputerEngine implements Computer { ps = psDisabled; } } if (ApexPackageInfo.ENABLE_FEATURE_SCAN_APEX) { if (!listApex && p.isApex()) { continue; } } if (filterSharedLibPackage(ps, callingUid, userId, flags)) { continue; } Loading @@ -1846,6 +1880,7 @@ public class ComputerEngine implements Computer { } } } if (!ApexPackageInfo.ENABLE_FEATURE_SCAN_APEX) { if (listApex) { if (listFactory) { list.addAll(mApexPackageInfo.getFactoryPackages()); Loading @@ -1853,6 +1888,7 @@ public class ComputerEngine implements Computer { list.addAll(mApexPackageInfo.getActivePackages()); } } } return new ParceledListSlice<>(list); } Loading Loading @@ -3338,13 +3374,58 @@ public class ComputerEngine implements Computer { case DumpState.DUMP_APEX: { if (packageName == null || isApexPackage(packageName)) { mApexManager.dump(pw); mApexPackageInfo.dump(pw, packageName); dumpApex(pw, packageName); } break; } } // switch } private void generateApexPackageInfo(List<PackageInfo> activePackages, List<PackageInfo> inactivePackages, List<PackageInfo> factoryPackages) { for (AndroidPackage p : mPackages.values()) { final String packageName = p.getPackageName(); PackageStateInternal ps = mSettings.getPackage(packageName); if (!p.isApex() || ps == null) { continue; } PackageInfo pi = generatePackageInfo(ps, 0, 0); if (pi == null) { continue; } pi.isActiveApex = true; activePackages.add(pi); if (!ps.isUpdatedSystemApp()) { factoryPackages.add(pi); } else { PackageStateInternal psDisabled = mSettings.getDisabledSystemPkg(packageName); pi = generatePackageInfo(psDisabled, 0, 0); if (pi != null) { factoryPackages.add(pi); inactivePackages.add(pi); } } } } private void dumpApex(PrintWriter pw, String packageName) { if (ApexPackageInfo.ENABLE_FEATURE_SCAN_APEX) { final IndentingPrintWriter ipw = new IndentingPrintWriter(pw, " ", 120); List<PackageInfo> activePackages = new ArrayList<>(); List<PackageInfo> inactivePackages = new ArrayList<>(); List<PackageInfo> factoryPackages = new ArrayList<>(); generateApexPackageInfo(activePackages, inactivePackages, factoryPackages); ipw.println("Active APEX packages:"); ApexPackageInfo.dumpPackages(activePackages, packageName, ipw); ipw.println("Inactive APEX packages:"); ApexPackageInfo.dumpPackages(inactivePackages, packageName, ipw); ipw.println("Factory APEX packages:"); ApexPackageInfo.dumpPackages(factoryPackages, packageName, ipw); } else { mApexPackageInfo.dump(pw, packageName); } } // The body of findPreferredActivity. protected PackageManagerService.FindPreferredActivityBodyResult findPreferredActivityBody( Intent intent, String resolvedType, @PackageManager.ResolveInfoFlagsBits long flags, Loading Loading @@ -3721,7 +3802,12 @@ public class ComputerEngine implements Computer { @Override public boolean isApexPackage(String packageName) { if (!ApexPackageInfo.ENABLE_FEATURE_SCAN_APEX) { return mApexPackageInfo.isApexPackage(packageName); } else { final AndroidPackage pkg = mPackages.get(packageName); return pkg != null && pkg.isApex(); } } @Override Loading Loading @@ -4710,6 +4796,7 @@ public class ComputerEngine implements Computer { if (!mUserManager.exists(userId)) return Collections.emptyList(); flags = updateFlagsForApplication(flags, userId); final boolean listUninstalled = (flags & MATCH_KNOWN_PACKAGES) != 0; final boolean listApex = (flags & MATCH_APEX) != 0; enforceCrossUserPermission( callingUid, Loading @@ -4730,6 +4817,11 @@ public class ComputerEngine implements Computer { effectiveFlags |= PackageManager.MATCH_ANY_USER; } if (ps.getPkg() != null) { if (ApexPackageInfo.ENABLE_FEATURE_SCAN_APEX) { if (!listApex && ps.getPkg().isApex()) { continue; } } if (filterSharedLibPackage(ps, callingUid, userId, flags)) { continue; } Loading Loading @@ -4758,6 +4850,11 @@ public class ComputerEngine implements Computer { if (pkg == null) { continue; } if (ApexPackageInfo.ENABLE_FEATURE_SCAN_APEX) { if (!listApex && pkg.isApex()) { continue; } } if (filterSharedLibPackage(packageState, Binder.getCallingUid(), userId, flags)) { continue; } Loading Loading @@ -5109,7 +5206,7 @@ public class ComputerEngine implements Computer { final PackageStateInternal ps = mSettings.getPackage(packageName); // Installer info for Apex is not stored in PackageManager if (ps == null && mApexPackageInfo.isApexPackage(packageName)) { if (isApexPackage(packageName)) { return InstallSource.EMPTY; } Loading services/core/java/com/android/server/pm/InitAppsHelper.java +0 −1 Original line number Diff line number Diff line Loading @@ -194,7 +194,6 @@ final class InitAppsHelper { apexScanResults = mInstallPackageHelper.scanApexPackages( mApexManager.getAllApexInfos(), mSystemParseFlags, mSystemScanFlags, packageParser, mExecutorService); mApexPackageInfo.notifyScanResult(apexScanResults); } else { apexScanResults = mApexPackageInfo.scanApexPackages( mApexManager.getAllApexInfos(), packageParser, mExecutorService); Loading services/core/java/com/android/server/pm/InstallPackageHelper.java +97 −26 Original line number Diff line number Diff line Loading @@ -826,19 +826,24 @@ final class InstallPackageHelper { } return; } processApkInstallRequests(success, installRequests); } private void processApkInstallRequests(boolean success, List<InstallRequest> installRequests) { if (success) { for (InstallRequest request : apkInstallRequests) { for (InstallRequest request : installRequests) { request.mArgs.doPreInstall(request.mInstallResult.mReturnCode); } synchronized (mPm.mInstallLock) { installPackagesTracedLI(apkInstallRequests); installPackagesTracedLI(installRequests); } for (InstallRequest request : apkInstallRequests) { for (InstallRequest request : installRequests) { request.mArgs.doPostInstall( request.mInstallResult.mReturnCode, request.mInstallResult.mUid); } } for (InstallRequest request : apkInstallRequests) { for (InstallRequest request : installRequests) { restoreAndPostInstall(request.mArgs.mUser.getIdentifier(), request.mInstallResult, new PostInstallData(request.mArgs, Loading Loading @@ -880,11 +885,15 @@ final class InstallPackageHelper { try (PackageParser2 packageParser = mPm.mInjector.getScanningPackageParser()) { ApexInfo apexInfo = mApexManager.installPackage(apexes[0]); if (ApexPackageInfo.ENABLE_FEATURE_SCAN_APEX) { ParsedPackage parsedPackage = packageParser.parsePackage( new File(apexInfo.modulePath), 0, /* useCaches= */ false); scanSystemPackageLI(parsedPackage, 0, SCAN_AS_APEX, null); mPm.mApexPackageInfo.notifyPackageInstalled( apexInfo, parsedPackage.hideAsFinal()); // APEX has been handled successfully by apexd. Let's continue the install flow // so it will be scanned and registered with the system. // TODO(b/225756739): Improve atomicity of rebootless APEX install. // The newly installed APEX will not be reverted even if // processApkInstallRequests() fails. Need a way to keep info stored in apexd // and PMS in sync in the face of install failures. request.mInstallResult.mApexInfo = apexInfo; mPm.mHandler.post(() -> processApkInstallRequests(true, requests)); return; } else { mPm.mApexPackageInfo.notifyPackageInstalled(apexInfo, packageParser); } Loading Loading @@ -985,7 +994,12 @@ final class InstallPackageHelper { + PackageManager.PROPERTY_NO_APP_DATA_STORAGE); return; } final boolean isApex = (result.mRequest.mScanFlags & SCAN_AS_APEX) != 0; if (!isApex) { createdAppId.put(packageName, optimisticallyRegisterAppId(result)); } else { result.mPkgSetting.setAppId(Process.INVALID_UID); } versionInfos.put(result.mPkgSetting.getPkg().getPackageName(), mPm.getSettingsVersionForPackage(result.mPkgSetting.getPkg())); } catch (PackageManagerException e) { Loading Loading @@ -1088,12 +1102,12 @@ final class InstallPackageHelper { private PrepareResult preparePackageLI(InstallArgs args, PackageInstalledInfo res) throws PrepareFailure { final int installFlags = args.mInstallFlags; final File tmpPackageFile = new File(args.getCodePath()); final boolean onExternal = args.mVolumeUuid != null; final boolean instantApp = ((installFlags & PackageManager.INSTALL_INSTANT_APP) != 0); final boolean fullApp = ((installFlags & PackageManager.INSTALL_FULL_APP) != 0); final boolean virtualPreload = ((installFlags & PackageManager.INSTALL_VIRTUAL_PRELOAD) != 0); final boolean isApex = ((installFlags & PackageManager.INSTALL_APEX) != 0); final boolean isRollback = args.mInstallReason == PackageManager.INSTALL_REASON_ROLLBACK; @PackageManagerService.ScanFlags int scanFlags = SCAN_NEW_INSTALL | SCAN_UPDATE_SIGNATURE; if (args.mMoveInfo != null) { Loading @@ -1112,7 +1126,12 @@ final class InstallPackageHelper { if (virtualPreload) { scanFlags |= SCAN_AS_VIRTUAL_PRELOAD; } if (isApex) { scanFlags |= SCAN_AS_APEX; } final File tmpPackageFile = new File( isApex ? res.mApexInfo.modulePath : args.getCodePath()); if (DEBUG_INSTALL) Slog.d(TAG, "installPackageLI: path=" + tmpPackageFile); // Validity check Loading Loading @@ -1518,6 +1537,7 @@ final class InstallPackageHelper { } } if (!isApex) { if (!args.doRename(res.mReturnCode, parsedPackage)) { throw new PrepareFailure(INSTALL_FAILED_INSUFFICIENT_STORAGE, "Failed rename"); } Loading @@ -1529,6 +1549,11 @@ final class InstallPackageHelper { throw new PrepareFailure(INSTALL_FAILED_INTERNAL_ERROR, "Failed to set up verity: " + e); } } else { // Use the path returned by apexd parsedPackage.setPath(res.mApexInfo.modulePath); parsedPackage.setBaseApkPath(res.mApexInfo.modulePath); } final PackageFreezer freezer = freezePackageForInstall(pkgName, installFlags, "installPackageLI"); Loading Loading @@ -1934,6 +1959,8 @@ final class InstallPackageHelper { // Set the update and install times PackageStateInternal deletedPkgSetting = mPm.snapshotComputer() .getPackageStateInternal(oldPackage.getPackageName()); // TODO(b/225756739): For rebootless APEX, consider using lastUpdateMillis provided // by apexd to be more accurate. reconciledPkg.mPkgSetting .setFirstInstallTimeFromReplaced(deletedPkgSetting, request.mAllUsers) .setLastUpdateTime(System.currentTimeMillis()); Loading Loading @@ -2236,6 +2263,8 @@ final class InstallPackageHelper { for (ReconciledPackage reconciledPkg : commitRequest.mReconciledPackages.values()) { final boolean instantApp = ((reconciledPkg.mScanResult.mRequest.mScanFlags & SCAN_AS_INSTANT_APP) != 0); final boolean isApex = ((reconciledPkg.mScanResult.mRequest.mScanFlags & SCAN_AS_APEX) != 0); final AndroidPackage pkg = reconciledPkg.mPkgSetting.getPkg(); final String packageName = pkg.getPackageName(); final String codePath = pkg.getPath(); Loading Loading @@ -2323,7 +2352,8 @@ final class InstallPackageHelper { android.provider.Settings.Global.INSTANT_APP_DEXOPT_ENABLED, 0) != 0) && !pkg.isDebuggable() && (!onIncremental) && dexoptOptions.isCompilationEnabled(); && dexoptOptions.isCompilationEnabled() && !isApex; if (performDexopt) { // Compile the layout resources. Loading Loading @@ -3292,6 +3322,10 @@ final class InstallPackageHelper { final PackageSetting disabledPs = mPm.mSettings.getDisabledSystemPkgLPr(packageName); if (scannedPkg != null) { if (scannedPkg.isApex()) { // APEX on /data has been scanned. No need to expect better. continue; } /* * If the system app is both scanned and in the * disabled packages list, then it must have been Loading Loading @@ -3391,6 +3425,18 @@ final class InstallPackageHelper { } } /** * Scans APEX packages and registers them with the system. * * apexd has its own policy to decide which APEX to activate and which not. The policy might * conflicts that of PMS. The APEX package info stored in PMS is a mirror of that managed by * apexd. To keep things simple and keep activation status in sync for both apexd and PMS, we * don't persist APEX in settings and always scan APEX from scratch during boot. However, some * data like lastUpdateTime will be lost if PackageSetting is not persisted for APEX. * * TODO(b/225756739): Read lastUpdateTime from ApexInfoList to populate PackageSetting correctly */ @GuardedBy({"mPm.mInstallLock", "mPm.mLock"}) public List<ApexManager.ScanResult> scanApexPackages(ApexInfo[] allPackages, int parseFlags, int scanFlags, PackageParser2 packageParser, ExecutorService executorService) { if (allPackages == null) { Loading @@ -3408,18 +3454,39 @@ final class InstallPackageHelper { parsingApexInfo.put(apexFile, ai); } // Process results one by one List<ApexManager.ScanResult> results = new ArrayList<>(parsingApexInfo.size()); List<ParallelPackageParser.ParseResult> parseResults = new ArrayList<>(parsingApexInfo.size()); for (int i = 0; i < parsingApexInfo.size(); i++) { ParallelPackageParser.ParseResult parseResult = parallelPackageParser.take(); parseResults.add(parseResult); } // Sort the list to ensure we always process factory packages first Collections.sort(parseResults, (a, b) -> { ApexInfo ai = parsingApexInfo.get(a.scanFile); return ai.isFactory ? -1 : 1; }); // Process results one by one List<ApexManager.ScanResult> results = new ArrayList<>(parsingApexInfo.size()); for (int i = 0; i < parseResults.size(); i++) { ParallelPackageParser.ParseResult parseResult = parseResults.get(i); Throwable throwable = parseResult.throwable; ApexInfo ai = parsingApexInfo.get(parseResult.scanFile); int newParseFlags = parseFlags; int newScanFlags = scanFlags | SCAN_AS_APEX; if (!ai.isFactory) { newParseFlags &= ~ParsingPackageUtils.PARSE_IS_SYSTEM_DIR; newScanFlags |= SCAN_NEW_INSTALL; } if (throwable == null) { try { scanSystemPackageLI(parseResult.parsedPackage, parseFlags, newScanFlags, null); AndroidPackage pkg = parseResult.parsedPackage.hideAsFinal(); AndroidPackage pkg = addForInitLI( parseResult.parsedPackage, newParseFlags, newScanFlags, null); if (ai.isFactory && !ai.isActive) { disableSystemPackageLPw(pkg); } results.add(new ApexManager.ScanResult(ai, pkg, pkg.getPackageName())); } catch (PackageManagerException e) { throw new IllegalStateException("Failed to scan: " + ai.modulePath, e); Loading Loading @@ -3638,7 +3705,11 @@ final class InstallPackageHelper { ReconcilePackageUtils.reconcilePackages(reconcileRequest, mSharedLibraries, mPm.mSettings.getKeySetManagerService(), mPm.mSettings); if ((scanFlags & SCAN_AS_APEX) == 0) { appIdCreated = optimisticallyRegisterAppId(scanResult); } else { scanResult.mPkgSetting.setAppId(Process.INVALID_UID); } commitReconciledScanResultLocked(reconcileResult.get(pkgName), mPm.mUserManager.getUserIds()); } catch (PackageManagerException e) { Loading Loading
core/java/android/os/UserHandle.java +1 −1 Original line number Diff line number Diff line Loading @@ -368,7 +368,7 @@ public final class UserHandle implements Parcelable { @UnsupportedAppUsage @TestApi public static int getUid(@UserIdInt int userId, @AppIdInt int appId) { if (MU_ENABLED) { if (MU_ENABLED && appId >= 0) { return userId * PER_USER_RANGE + (appId % PER_USER_RANGE); } else { return appId; Loading
services/core/java/com/android/server/pm/ApexPackageInfo.java +4 −5 Original line number Diff line number Diff line Loading @@ -27,7 +27,6 @@ import android.content.pm.PackageInfo; import android.content.pm.PackageManager; import android.util.ArrayMap; import android.util.PrintWriterPrinter; import android.util.Slog; import com.android.internal.annotations.GuardedBy; import com.android.internal.util.IndentingPrintWriter; Loading Loading @@ -271,11 +270,11 @@ class ApexPackageInfo { } } ipw.println("Active APEX packages:"); dumpFromPackagesCache(getActivePackages(), packageName, ipw); dumpPackages(getActivePackages(), packageName, ipw); ipw.println("Inactive APEX packages:"); dumpFromPackagesCache(getInactivePackages(), packageName, ipw); dumpPackages(getInactivePackages(), packageName, ipw); ipw.println("Factory APEX packages:"); dumpFromPackagesCache(getFactoryPackages(), packageName, ipw); dumpPackages(getFactoryPackages(), packageName, ipw); } @GuardedBy("mLock") Loading Loading @@ -370,7 +369,7 @@ class ApexPackageInfo { * only information about that specific package will be dumped. * @param ipw the {@link IndentingPrintWriter} object to send information to. */ private static void dumpFromPackagesCache(List<PackageInfo> packagesCache, static void dumpPackages(List<PackageInfo> packagesCache, @Nullable String packageName, IndentingPrintWriter ipw) { ipw.println(); ipw.increaseIndent(); Loading
services/core/java/com/android/server/pm/ComputerEngine.java +123 −26 Original line number Diff line number Diff line Loading @@ -984,9 +984,15 @@ public class ComputerEngine implements Computer { TAG, "getApplicationInfo " + packageName + ": " + p); } final boolean matchApex = (flags & MATCH_APEX) != 0; if (p != null) { PackageStateInternal ps = mSettings.getPackage(packageName); if (ps == null) return null; if (ApexPackageInfo.ENABLE_FEATURE_SCAN_APEX) { if (!matchApex && p.isApex()) { return null; } } if (filterSharedLibPackage(ps, filterCallingUid, userId, flags)) { return null; } Loading @@ -1001,7 +1007,8 @@ public class ComputerEngine implements Computer { } return ai; } if ((flags & PackageManager.MATCH_APEX) != 0) { if (!ApexPackageInfo.ENABLE_FEATURE_SCAN_APEX) { if (matchApex) { // For APKs, PackageInfo.applicationInfo is not exactly the same as ApplicationInfo // returned from getApplicationInfo, but for APEX packages difference shouldn't be // very big. Loading @@ -1016,6 +1023,7 @@ public class ComputerEngine implements Computer { } return pi.applicationInfo; } } if ("android".equals(packageName) || "system".equals(packageName)) { return androidApplication(); } Loading Loading @@ -1704,14 +1712,22 @@ public class ComputerEngine implements Computer { packageName = resolveInternalPackageName(packageName, versionCode); final boolean matchFactoryOnly = (flags & MATCH_FACTORY_ONLY) != 0; final boolean matchApex = (flags & MATCH_APEX) != 0; if (matchFactoryOnly) { // Instant app filtering for APEX modules is ignored if ((flags & MATCH_APEX) != 0) { if (!ApexPackageInfo.ENABLE_FEATURE_SCAN_APEX) { if (matchApex) { return mApexPackageInfo.getPackageInfo(packageName, ApexManager.MATCH_FACTORY_PACKAGE); } } final PackageStateInternal ps = mSettings.getDisabledSystemPkg(packageName); if (ps != null) { if (ApexPackageInfo.ENABLE_FEATURE_SCAN_APEX) { if (!matchApex && ps.getPkg() != null && ps.getPkg().isApex()) { return null; } } if (filterSharedLibPackage(ps, filterCallingUid, userId, flags)) { return null; } Loading @@ -1731,6 +1747,11 @@ public class ComputerEngine implements Computer { } if (p != null) { final PackageStateInternal ps = getPackageStateInternal(p.getPackageName()); if (ApexPackageInfo.ENABLE_FEATURE_SCAN_APEX) { if (!matchApex && p.isApex()) { return null; } } if (filterSharedLibPackage(ps, filterCallingUid, userId, flags)) { return null; } Loading @@ -1751,8 +1772,11 @@ public class ComputerEngine implements Computer { } return generatePackageInfo(ps, flags, userId); } if ((flags & MATCH_APEX) != 0) { return mApexPackageInfo.getPackageInfo(packageName, ApexManager.MATCH_ACTIVE_PACKAGE); if (!ApexPackageInfo.ENABLE_FEATURE_SCAN_APEX) { if (matchApex) { return mApexPackageInfo.getPackageInfo(packageName, ApexManager.MATCH_ACTIVE_PACKAGE); } } return null; } Loading Loading @@ -1809,6 +1833,11 @@ public class ComputerEngine implements Computer { ps = psDisabled; } } if (ApexPackageInfo.ENABLE_FEATURE_SCAN_APEX) { if (!listApex && ps.getPkg() != null && ps.getPkg().isApex()) { continue; } } if (filterSharedLibPackage(ps, callingUid, userId, flags)) { continue; } Loading @@ -1834,6 +1863,11 @@ public class ComputerEngine implements Computer { ps = psDisabled; } } if (ApexPackageInfo.ENABLE_FEATURE_SCAN_APEX) { if (!listApex && p.isApex()) { continue; } } if (filterSharedLibPackage(ps, callingUid, userId, flags)) { continue; } Loading @@ -1846,6 +1880,7 @@ public class ComputerEngine implements Computer { } } } if (!ApexPackageInfo.ENABLE_FEATURE_SCAN_APEX) { if (listApex) { if (listFactory) { list.addAll(mApexPackageInfo.getFactoryPackages()); Loading @@ -1853,6 +1888,7 @@ public class ComputerEngine implements Computer { list.addAll(mApexPackageInfo.getActivePackages()); } } } return new ParceledListSlice<>(list); } Loading Loading @@ -3338,13 +3374,58 @@ public class ComputerEngine implements Computer { case DumpState.DUMP_APEX: { if (packageName == null || isApexPackage(packageName)) { mApexManager.dump(pw); mApexPackageInfo.dump(pw, packageName); dumpApex(pw, packageName); } break; } } // switch } private void generateApexPackageInfo(List<PackageInfo> activePackages, List<PackageInfo> inactivePackages, List<PackageInfo> factoryPackages) { for (AndroidPackage p : mPackages.values()) { final String packageName = p.getPackageName(); PackageStateInternal ps = mSettings.getPackage(packageName); if (!p.isApex() || ps == null) { continue; } PackageInfo pi = generatePackageInfo(ps, 0, 0); if (pi == null) { continue; } pi.isActiveApex = true; activePackages.add(pi); if (!ps.isUpdatedSystemApp()) { factoryPackages.add(pi); } else { PackageStateInternal psDisabled = mSettings.getDisabledSystemPkg(packageName); pi = generatePackageInfo(psDisabled, 0, 0); if (pi != null) { factoryPackages.add(pi); inactivePackages.add(pi); } } } } private void dumpApex(PrintWriter pw, String packageName) { if (ApexPackageInfo.ENABLE_FEATURE_SCAN_APEX) { final IndentingPrintWriter ipw = new IndentingPrintWriter(pw, " ", 120); List<PackageInfo> activePackages = new ArrayList<>(); List<PackageInfo> inactivePackages = new ArrayList<>(); List<PackageInfo> factoryPackages = new ArrayList<>(); generateApexPackageInfo(activePackages, inactivePackages, factoryPackages); ipw.println("Active APEX packages:"); ApexPackageInfo.dumpPackages(activePackages, packageName, ipw); ipw.println("Inactive APEX packages:"); ApexPackageInfo.dumpPackages(inactivePackages, packageName, ipw); ipw.println("Factory APEX packages:"); ApexPackageInfo.dumpPackages(factoryPackages, packageName, ipw); } else { mApexPackageInfo.dump(pw, packageName); } } // The body of findPreferredActivity. protected PackageManagerService.FindPreferredActivityBodyResult findPreferredActivityBody( Intent intent, String resolvedType, @PackageManager.ResolveInfoFlagsBits long flags, Loading Loading @@ -3721,7 +3802,12 @@ public class ComputerEngine implements Computer { @Override public boolean isApexPackage(String packageName) { if (!ApexPackageInfo.ENABLE_FEATURE_SCAN_APEX) { return mApexPackageInfo.isApexPackage(packageName); } else { final AndroidPackage pkg = mPackages.get(packageName); return pkg != null && pkg.isApex(); } } @Override Loading Loading @@ -4710,6 +4796,7 @@ public class ComputerEngine implements Computer { if (!mUserManager.exists(userId)) return Collections.emptyList(); flags = updateFlagsForApplication(flags, userId); final boolean listUninstalled = (flags & MATCH_KNOWN_PACKAGES) != 0; final boolean listApex = (flags & MATCH_APEX) != 0; enforceCrossUserPermission( callingUid, Loading @@ -4730,6 +4817,11 @@ public class ComputerEngine implements Computer { effectiveFlags |= PackageManager.MATCH_ANY_USER; } if (ps.getPkg() != null) { if (ApexPackageInfo.ENABLE_FEATURE_SCAN_APEX) { if (!listApex && ps.getPkg().isApex()) { continue; } } if (filterSharedLibPackage(ps, callingUid, userId, flags)) { continue; } Loading Loading @@ -4758,6 +4850,11 @@ public class ComputerEngine implements Computer { if (pkg == null) { continue; } if (ApexPackageInfo.ENABLE_FEATURE_SCAN_APEX) { if (!listApex && pkg.isApex()) { continue; } } if (filterSharedLibPackage(packageState, Binder.getCallingUid(), userId, flags)) { continue; } Loading Loading @@ -5109,7 +5206,7 @@ public class ComputerEngine implements Computer { final PackageStateInternal ps = mSettings.getPackage(packageName); // Installer info for Apex is not stored in PackageManager if (ps == null && mApexPackageInfo.isApexPackage(packageName)) { if (isApexPackage(packageName)) { return InstallSource.EMPTY; } Loading
services/core/java/com/android/server/pm/InitAppsHelper.java +0 −1 Original line number Diff line number Diff line Loading @@ -194,7 +194,6 @@ final class InitAppsHelper { apexScanResults = mInstallPackageHelper.scanApexPackages( mApexManager.getAllApexInfos(), mSystemParseFlags, mSystemScanFlags, packageParser, mExecutorService); mApexPackageInfo.notifyScanResult(apexScanResults); } else { apexScanResults = mApexPackageInfo.scanApexPackages( mApexManager.getAllApexInfos(), packageParser, mExecutorService); Loading
services/core/java/com/android/server/pm/InstallPackageHelper.java +97 −26 Original line number Diff line number Diff line Loading @@ -826,19 +826,24 @@ final class InstallPackageHelper { } return; } processApkInstallRequests(success, installRequests); } private void processApkInstallRequests(boolean success, List<InstallRequest> installRequests) { if (success) { for (InstallRequest request : apkInstallRequests) { for (InstallRequest request : installRequests) { request.mArgs.doPreInstall(request.mInstallResult.mReturnCode); } synchronized (mPm.mInstallLock) { installPackagesTracedLI(apkInstallRequests); installPackagesTracedLI(installRequests); } for (InstallRequest request : apkInstallRequests) { for (InstallRequest request : installRequests) { request.mArgs.doPostInstall( request.mInstallResult.mReturnCode, request.mInstallResult.mUid); } } for (InstallRequest request : apkInstallRequests) { for (InstallRequest request : installRequests) { restoreAndPostInstall(request.mArgs.mUser.getIdentifier(), request.mInstallResult, new PostInstallData(request.mArgs, Loading Loading @@ -880,11 +885,15 @@ final class InstallPackageHelper { try (PackageParser2 packageParser = mPm.mInjector.getScanningPackageParser()) { ApexInfo apexInfo = mApexManager.installPackage(apexes[0]); if (ApexPackageInfo.ENABLE_FEATURE_SCAN_APEX) { ParsedPackage parsedPackage = packageParser.parsePackage( new File(apexInfo.modulePath), 0, /* useCaches= */ false); scanSystemPackageLI(parsedPackage, 0, SCAN_AS_APEX, null); mPm.mApexPackageInfo.notifyPackageInstalled( apexInfo, parsedPackage.hideAsFinal()); // APEX has been handled successfully by apexd. Let's continue the install flow // so it will be scanned and registered with the system. // TODO(b/225756739): Improve atomicity of rebootless APEX install. // The newly installed APEX will not be reverted even if // processApkInstallRequests() fails. Need a way to keep info stored in apexd // and PMS in sync in the face of install failures. request.mInstallResult.mApexInfo = apexInfo; mPm.mHandler.post(() -> processApkInstallRequests(true, requests)); return; } else { mPm.mApexPackageInfo.notifyPackageInstalled(apexInfo, packageParser); } Loading Loading @@ -985,7 +994,12 @@ final class InstallPackageHelper { + PackageManager.PROPERTY_NO_APP_DATA_STORAGE); return; } final boolean isApex = (result.mRequest.mScanFlags & SCAN_AS_APEX) != 0; if (!isApex) { createdAppId.put(packageName, optimisticallyRegisterAppId(result)); } else { result.mPkgSetting.setAppId(Process.INVALID_UID); } versionInfos.put(result.mPkgSetting.getPkg().getPackageName(), mPm.getSettingsVersionForPackage(result.mPkgSetting.getPkg())); } catch (PackageManagerException e) { Loading Loading @@ -1088,12 +1102,12 @@ final class InstallPackageHelper { private PrepareResult preparePackageLI(InstallArgs args, PackageInstalledInfo res) throws PrepareFailure { final int installFlags = args.mInstallFlags; final File tmpPackageFile = new File(args.getCodePath()); final boolean onExternal = args.mVolumeUuid != null; final boolean instantApp = ((installFlags & PackageManager.INSTALL_INSTANT_APP) != 0); final boolean fullApp = ((installFlags & PackageManager.INSTALL_FULL_APP) != 0); final boolean virtualPreload = ((installFlags & PackageManager.INSTALL_VIRTUAL_PRELOAD) != 0); final boolean isApex = ((installFlags & PackageManager.INSTALL_APEX) != 0); final boolean isRollback = args.mInstallReason == PackageManager.INSTALL_REASON_ROLLBACK; @PackageManagerService.ScanFlags int scanFlags = SCAN_NEW_INSTALL | SCAN_UPDATE_SIGNATURE; if (args.mMoveInfo != null) { Loading @@ -1112,7 +1126,12 @@ final class InstallPackageHelper { if (virtualPreload) { scanFlags |= SCAN_AS_VIRTUAL_PRELOAD; } if (isApex) { scanFlags |= SCAN_AS_APEX; } final File tmpPackageFile = new File( isApex ? res.mApexInfo.modulePath : args.getCodePath()); if (DEBUG_INSTALL) Slog.d(TAG, "installPackageLI: path=" + tmpPackageFile); // Validity check Loading Loading @@ -1518,6 +1537,7 @@ final class InstallPackageHelper { } } if (!isApex) { if (!args.doRename(res.mReturnCode, parsedPackage)) { throw new PrepareFailure(INSTALL_FAILED_INSUFFICIENT_STORAGE, "Failed rename"); } Loading @@ -1529,6 +1549,11 @@ final class InstallPackageHelper { throw new PrepareFailure(INSTALL_FAILED_INTERNAL_ERROR, "Failed to set up verity: " + e); } } else { // Use the path returned by apexd parsedPackage.setPath(res.mApexInfo.modulePath); parsedPackage.setBaseApkPath(res.mApexInfo.modulePath); } final PackageFreezer freezer = freezePackageForInstall(pkgName, installFlags, "installPackageLI"); Loading Loading @@ -1934,6 +1959,8 @@ final class InstallPackageHelper { // Set the update and install times PackageStateInternal deletedPkgSetting = mPm.snapshotComputer() .getPackageStateInternal(oldPackage.getPackageName()); // TODO(b/225756739): For rebootless APEX, consider using lastUpdateMillis provided // by apexd to be more accurate. reconciledPkg.mPkgSetting .setFirstInstallTimeFromReplaced(deletedPkgSetting, request.mAllUsers) .setLastUpdateTime(System.currentTimeMillis()); Loading Loading @@ -2236,6 +2263,8 @@ final class InstallPackageHelper { for (ReconciledPackage reconciledPkg : commitRequest.mReconciledPackages.values()) { final boolean instantApp = ((reconciledPkg.mScanResult.mRequest.mScanFlags & SCAN_AS_INSTANT_APP) != 0); final boolean isApex = ((reconciledPkg.mScanResult.mRequest.mScanFlags & SCAN_AS_APEX) != 0); final AndroidPackage pkg = reconciledPkg.mPkgSetting.getPkg(); final String packageName = pkg.getPackageName(); final String codePath = pkg.getPath(); Loading Loading @@ -2323,7 +2352,8 @@ final class InstallPackageHelper { android.provider.Settings.Global.INSTANT_APP_DEXOPT_ENABLED, 0) != 0) && !pkg.isDebuggable() && (!onIncremental) && dexoptOptions.isCompilationEnabled(); && dexoptOptions.isCompilationEnabled() && !isApex; if (performDexopt) { // Compile the layout resources. Loading Loading @@ -3292,6 +3322,10 @@ final class InstallPackageHelper { final PackageSetting disabledPs = mPm.mSettings.getDisabledSystemPkgLPr(packageName); if (scannedPkg != null) { if (scannedPkg.isApex()) { // APEX on /data has been scanned. No need to expect better. continue; } /* * If the system app is both scanned and in the * disabled packages list, then it must have been Loading Loading @@ -3391,6 +3425,18 @@ final class InstallPackageHelper { } } /** * Scans APEX packages and registers them with the system. * * apexd has its own policy to decide which APEX to activate and which not. The policy might * conflicts that of PMS. The APEX package info stored in PMS is a mirror of that managed by * apexd. To keep things simple and keep activation status in sync for both apexd and PMS, we * don't persist APEX in settings and always scan APEX from scratch during boot. However, some * data like lastUpdateTime will be lost if PackageSetting is not persisted for APEX. * * TODO(b/225756739): Read lastUpdateTime from ApexInfoList to populate PackageSetting correctly */ @GuardedBy({"mPm.mInstallLock", "mPm.mLock"}) public List<ApexManager.ScanResult> scanApexPackages(ApexInfo[] allPackages, int parseFlags, int scanFlags, PackageParser2 packageParser, ExecutorService executorService) { if (allPackages == null) { Loading @@ -3408,18 +3454,39 @@ final class InstallPackageHelper { parsingApexInfo.put(apexFile, ai); } // Process results one by one List<ApexManager.ScanResult> results = new ArrayList<>(parsingApexInfo.size()); List<ParallelPackageParser.ParseResult> parseResults = new ArrayList<>(parsingApexInfo.size()); for (int i = 0; i < parsingApexInfo.size(); i++) { ParallelPackageParser.ParseResult parseResult = parallelPackageParser.take(); parseResults.add(parseResult); } // Sort the list to ensure we always process factory packages first Collections.sort(parseResults, (a, b) -> { ApexInfo ai = parsingApexInfo.get(a.scanFile); return ai.isFactory ? -1 : 1; }); // Process results one by one List<ApexManager.ScanResult> results = new ArrayList<>(parsingApexInfo.size()); for (int i = 0; i < parseResults.size(); i++) { ParallelPackageParser.ParseResult parseResult = parseResults.get(i); Throwable throwable = parseResult.throwable; ApexInfo ai = parsingApexInfo.get(parseResult.scanFile); int newParseFlags = parseFlags; int newScanFlags = scanFlags | SCAN_AS_APEX; if (!ai.isFactory) { newParseFlags &= ~ParsingPackageUtils.PARSE_IS_SYSTEM_DIR; newScanFlags |= SCAN_NEW_INSTALL; } if (throwable == null) { try { scanSystemPackageLI(parseResult.parsedPackage, parseFlags, newScanFlags, null); AndroidPackage pkg = parseResult.parsedPackage.hideAsFinal(); AndroidPackage pkg = addForInitLI( parseResult.parsedPackage, newParseFlags, newScanFlags, null); if (ai.isFactory && !ai.isActive) { disableSystemPackageLPw(pkg); } results.add(new ApexManager.ScanResult(ai, pkg, pkg.getPackageName())); } catch (PackageManagerException e) { throw new IllegalStateException("Failed to scan: " + ai.modulePath, e); Loading Loading @@ -3638,7 +3705,11 @@ final class InstallPackageHelper { ReconcilePackageUtils.reconcilePackages(reconcileRequest, mSharedLibraries, mPm.mSettings.getKeySetManagerService(), mPm.mSettings); if ((scanFlags & SCAN_AS_APEX) == 0) { appIdCreated = optimisticallyRegisterAppId(scanResult); } else { scanResult.mPkgSetting.setAppId(Process.INVALID_UID); } commitReconciledScanResultLocked(reconcileResult.get(pkgName), mPm.mUserManager.getUserIds()); } catch (PackageManagerException e) { Loading