Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit bd95a76f authored by Chun-Wei Wang's avatar Chun-Wei Wang Committed by Android (Google) Code Review
Browse files

Merge changes from topic "225756739_fix_run_as"

* changes:
  Don't persist APEX
  Revert "Revert "Migrate APEX package info from ApexPackageInfo to PMS""
parents 6bd3385f 97e150f8
Loading
Loading
Loading
Loading
+1 −1
Original line number Diff line number Diff line
@@ -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;
+4 −5
Original line number Diff line number Diff line
@@ -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<PackageInfo> packagesCache,
    static void dumpPackages(List<PackageInfo> packagesCache,
            @Nullable String packageName, IndentingPrintWriter ipw) {
        ipw.println();
        ipw.increaseIndent();
+123 −26
Original line number Diff line number Diff line
@@ -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,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.
@@ -1016,6 +1023,7 @@ public class ComputerEngine implements Computer {
                }
                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) {
            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,6 +1880,7 @@ public class ComputerEngine implements Computer {
                }
            }
        }
        if (!ApexPackageInfo.ENABLE_FEATURE_SCAN_APEX) {
            if (listApex) {
                if (listFactory) {
                    list.addAll(mApexPackageInfo.getFactoryPackages());
@@ -1853,6 +1888,7 @@ public class ComputerEngine implements Computer {
                    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<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,
@@ -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
@@ -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,
@@ -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;
                    }
@@ -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;
                }
@@ -5113,7 +5210,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;
        }

+0 −1
Original line number Diff line number Diff line
@@ -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);
+97 −26
Original line number Diff line number Diff line
@@ -829,19 +829,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,
@@ -883,11 +888,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);
                }
@@ -988,7 +997,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) {
@@ -1091,12 +1105,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) {
@@ -1115,7 +1129,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
@@ -1521,6 +1540,7 @@ final class InstallPackageHelper {
            }
        }

        if (!isApex) {
            if (!args.doRename(res.mReturnCode, parsedPackage)) {
                throw new PrepareFailure(INSTALL_FAILED_INSUFFICIENT_STORAGE, "Failed rename");
            }
@@ -1532,6 +1552,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");
@@ -1937,6 +1962,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());
@@ -2239,6 +2266,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();
@@ -2326,7 +2355,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.
@@ -3295,6 +3325,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
@@ -3394,6 +3428,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) {
@@ -3411,18 +3457,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);
@@ -3641,7 +3708,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