From b539b72475fa3ca5620af2583b63f9837c201366 Mon Sep 17 00:00:00 2001 From: Chun-Wei Wang Date: Thu, 26 May 2022 05:59:18 +0000 Subject: [PATCH] Revert "Revert "Migrate APEX package info from ApexPackageInfo to PMS"" This reverts commit d0bbad5854ed5ade0b45d3386b5d7404ad2c0765. Reason for revert: ag/18601046 will fix b/233872653 Change-Id: I71e01ce7936a61f73f102a40780750405bd26b21 --- core/java/android/os/UserHandle.java | 2 +- .../android/server/pm/ApexPackageInfo.java | 9 +- .../com/android/server/pm/ComputerEngine.java | 149 +++++++++++++++--- .../com/android/server/pm/InitAppsHelper.java | 1 - .../server/pm/InstallPackageHelper.java | 123 ++++++++++++--- .../server/pm/PackageInstalledInfo.java | 4 + .../java/com/android/server/pm/Settings.java | 16 ++ 7 files changed, 245 insertions(+), 59 deletions(-) diff --git a/core/java/android/os/UserHandle.java b/core/java/android/os/UserHandle.java index 3d5abb3b8a2f3..d831ecb5e8160 100644 --- a/core/java/android/os/UserHandle.java +++ b/core/java/android/os/UserHandle.java @@ -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; diff --git a/services/core/java/com/android/server/pm/ApexPackageInfo.java b/services/core/java/com/android/server/pm/ApexPackageInfo.java index 07f2fd3e1d1f2..f959a52f03749 100644 --- a/services/core/java/com/android/server/pm/ApexPackageInfo.java +++ b/services/core/java/com/android/server/pm/ApexPackageInfo.java @@ -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; @@ -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") @@ -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 packagesCache, + static void dumpPackages(List packagesCache, @Nullable String packageName, IndentingPrintWriter ipw) { ipw.println(); ipw.increaseIndent(); diff --git a/services/core/java/com/android/server/pm/ComputerEngine.java b/services/core/java/com/android/server/pm/ComputerEngine.java index c545e7d731dc7..fed128557db65 100644 --- a/services/core/java/com/android/server/pm/ComputerEngine.java +++ b/services/core/java/com/android/server/pm/ComputerEngine.java @@ -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; } @@ -1001,20 +1007,22 @@ public class ComputerEngine implements Computer { } return ai; } - if ((flags & PackageManager.MATCH_APEX) != 0) { - // For APKs, PackageInfo.applicationInfo is not exactly the same as ApplicationInfo - // returned from getApplicationInfo, but for APEX packages difference shouldn't be - // very big. - // TODO(b/155328545): generate proper application info for APEXes as well. - int apexFlags = ApexManager.MATCH_ACTIVE_PACKAGE; - if ((flags & PackageManager.MATCH_SYSTEM_ONLY) != 0) { - apexFlags = ApexManager.MATCH_FACTORY_PACKAGE; + 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. + // TODO(b/155328545): generate proper application info for APEXes as well. + int apexFlags = ApexManager.MATCH_ACTIVE_PACKAGE; + if ((flags & PackageManager.MATCH_SYSTEM_ONLY) != 0) { + apexFlags = ApexManager.MATCH_FACTORY_PACKAGE; + } + final PackageInfo pi = mApexPackageInfo.getPackageInfo(packageName, apexFlags); + if (pi == null) { + return null; + } + return pi.applicationInfo; } - final PackageInfo pi = mApexPackageInfo.getPackageInfo(packageName, apexFlags); - if (pi == null) { - return null; - } - return pi.applicationInfo; } if ("android".equals(packageName) || "system".equals(packageName)) { return androidApplication(); @@ -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) { - return mApexPackageInfo.getPackageInfo(packageName, - ApexManager.MATCH_FACTORY_PACKAGE); + 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; } @@ -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; } @@ -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; } @@ -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; } @@ -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; } @@ -1846,11 +1880,13 @@ public class ComputerEngine implements Computer { } } } - if (listApex) { - if (listFactory) { - list.addAll(mApexPackageInfo.getFactoryPackages()); - } else { - list.addAll(mApexPackageInfo.getActivePackages()); + if (!ApexPackageInfo.ENABLE_FEATURE_SCAN_APEX) { + if (listApex) { + if (listFactory) { + list.addAll(mApexPackageInfo.getFactoryPackages()); + } else { + list.addAll(mApexPackageInfo.getActivePackages()); + } } } return new ParceledListSlice<>(list); @@ -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 activePackages, + List inactivePackages, List 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 activePackages = new ArrayList<>(); + List inactivePackages = new ArrayList<>(); + List 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, @@ -3721,7 +3802,12 @@ public class ComputerEngine implements Computer { @Override public boolean isApexPackage(String packageName) { - return mApexPackageInfo.isApexPackage(packageName); + if (!ApexPackageInfo.ENABLE_FEATURE_SCAN_APEX) { + return mApexPackageInfo.isApexPackage(packageName); + } else { + final AndroidPackage pkg = mPackages.get(packageName); + return pkg != null && pkg.isApex(); + } } @Override @@ -4707,6 +4793,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, @@ -4727,6 +4814,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; } @@ -4755,6 +4847,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; } @@ -5105,7 +5202,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; } diff --git a/services/core/java/com/android/server/pm/InitAppsHelper.java b/services/core/java/com/android/server/pm/InitAppsHelper.java index 4019c15ee5504..b142ba6822d94 100644 --- a/services/core/java/com/android/server/pm/InitAppsHelper.java +++ b/services/core/java/com/android/server/pm/InitAppsHelper.java @@ -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); diff --git a/services/core/java/com/android/server/pm/InstallPackageHelper.java b/services/core/java/com/android/server/pm/InstallPackageHelper.java index c6e421b286a01..45b3255938627 100644 --- a/services/core/java/com/android/server/pm/InstallPackageHelper.java +++ b/services/core/java/com/android/server/pm/InstallPackageHelper.java @@ -826,19 +826,24 @@ final class InstallPackageHelper { } return; } + + processApkInstallRequests(success, installRequests); + } + + private void processApkInstallRequests(boolean success, List 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, @@ -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); } @@ -985,7 +994,12 @@ final class InstallPackageHelper { + PackageManager.PROPERTY_NO_APP_DATA_STORAGE); return; } - createdAppId.put(packageName, optimisticallyRegisterAppId(result)); + 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) { @@ -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) { @@ -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 @@ -1518,16 +1537,22 @@ final class InstallPackageHelper { } } - if (!args.doRename(res.mReturnCode, parsedPackage)) { - throw new PrepareFailure(INSTALL_FAILED_INSUFFICIENT_STORAGE, "Failed rename"); - } + if (!isApex) { + if (!args.doRename(res.mReturnCode, parsedPackage)) { + throw new PrepareFailure(INSTALL_FAILED_INSUFFICIENT_STORAGE, "Failed rename"); + } - try { - setUpFsVerityIfPossible(parsedPackage); - } catch (Installer.InstallerException | IOException | DigestException - | NoSuchAlgorithmException e) { - throw new PrepareFailure(INSTALL_FAILED_INTERNAL_ERROR, - "Failed to set up verity: " + e); + try { + setUpFsVerityIfPossible(parsedPackage); + } catch (Installer.InstallerException | IOException | DigestException + | NoSuchAlgorithmException e) { + 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 = @@ -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()); @@ -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(); @@ -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. @@ -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 @@ -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 scanApexPackages(ApexInfo[] allPackages, int parseFlags, int scanFlags, PackageParser2 packageParser, ExecutorService executorService) { if (allPackages == null) { @@ -3408,18 +3454,39 @@ final class InstallPackageHelper { parsingApexInfo.put(apexFile, ai); } - // Process results one by one - List results = new ArrayList<>(parsingApexInfo.size()); + List 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 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); @@ -3638,7 +3705,11 @@ final class InstallPackageHelper { ReconcilePackageUtils.reconcilePackages(reconcileRequest, mSharedLibraries, mPm.mSettings.getKeySetManagerService(), mPm.mSettings); - appIdCreated = optimisticallyRegisterAppId(scanResult); + 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) { diff --git a/services/core/java/com/android/server/pm/PackageInstalledInfo.java b/services/core/java/com/android/server/pm/PackageInstalledInfo.java index d0ca9d845560e..1c25dbbfa3137 100644 --- a/services/core/java/com/android/server/pm/PackageInstalledInfo.java +++ b/services/core/java/com/android/server/pm/PackageInstalledInfo.java @@ -18,6 +18,7 @@ package com.android.server.pm; import static com.android.server.pm.PackageManagerService.TAG; +import android.apex.ApexInfo; import android.util.ExceptionUtils; import android.util.Slog; @@ -45,6 +46,9 @@ final class PackageInstalledInfo { String mOrigPackage; String mOrigPermission; + // The ApexInfo returned by ApexManager#installPackage, used by rebootless APEX install + ApexInfo mApexInfo; + PackageInstalledInfo(int currentStatus) { mReturnCode = currentStatus; mUid = -1; diff --git a/services/core/java/com/android/server/pm/Settings.java b/services/core/java/com/android/server/pm/Settings.java index a4db628d72909..ad303311b1c59 100644 --- a/services/core/java/com/android/server/pm/Settings.java +++ b/services/core/java/com/android/server/pm/Settings.java @@ -2468,10 +2468,18 @@ public final class Settings implements Watchable, Snappable { serializer.endTag(null, "permissions"); for (final PackageSetting pkg : mPackages.values()) { + if (pkg.getPkg() != null && pkg.getPkg().isApex()) { + // Don't persist APEX which doesn't have a valid app id and will fail to load + continue; + } writePackageLPr(serializer, pkg); } for (final PackageSetting pkg : mDisabledSysPackages.values()) { + if (pkg.getPkg() != null && pkg.getPkg().isApex()) { + // Don't persist APEX which doesn't have a valid app id and will fail to load + continue; + } writeDisabledSysPackageLPr(serializer, pkg); } @@ -4968,6 +4976,10 @@ public final class Settings implements Watchable, Snappable { && !packageName.equals(ps.getPackageName())) { continue; } + if (ps.getPkg() != null && ps.getPkg().isApex()) { + // Filter APEX packages which will be dumped in the APEX section + continue; + } final LegacyPermissionState permissionsState = mPermissionDataProvider.getLegacyPermissionState(ps.getAppId()); if (permissionNames != null @@ -5020,6 +5032,10 @@ public final class Settings implements Watchable, Snappable { && !packageName.equals(ps.getPackageName())) { continue; } + if (ps.getPkg() != null && ps.getPkg().isApex()) { + // Filter APEX packages which will be dumped in the APEX section + continue; + } if (!checkin && !printedSomething) { if (dumpState.onTitlePrinted()) pw.println();