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

Commit 83708c82 authored by Winson's avatar Winson
Browse files

Diff resource dirs when checking LoadedApk packageInfo cache in ActivityThread

Need to check the overlayDirs with the current appInfo passed into
getPackageInfo, otherwise it's possible to return an old, outdated
LoadedApk which hasn't loaded the correct resource dirs into its
AssetManager.

There is a separate issue with AssetManager2.isUpToDate not being
implemented correctly, but that will be moved to a different
changelist.

Bug: 124363683

Test: manually tested Wellbeing with repro steps in linked bug

Change-Id: Iace6e8aab322bdb7b5b93398a4f5e2c69fccc68e
parent e0b984e8
Loading
Loading
Loading
Loading
+53 −35
Original line number Diff line number Diff line
@@ -2100,6 +2100,16 @@ public final class ActivityThread extends ClientTransactionHandler {
    public final LoadedApk getPackageInfo(String packageName, CompatibilityInfo compatInfo,
            int flags, int userId) {
        final boolean differentUser = (UserHandle.myUserId() != userId);
        ApplicationInfo ai;
        try {
            ai = getPackageManager().getApplicationInfo(packageName,
                    PackageManager.GET_SHARED_LIBRARY_FILES
                            | PackageManager.MATCH_DEBUG_TRIAGED_MISSING,
                    (userId < 0) ? UserHandle.myUserId() : userId);
        } catch (RemoteException e) {
            throw e.rethrowFromSystemServer();
        }

        synchronized (mResourcesManager) {
            WeakReference<LoadedApk> ref;
            if (differentUser) {
@@ -2112,11 +2122,7 @@ public final class ActivityThread extends ClientTransactionHandler {
            }

            LoadedApk packageInfo = ref != null ? ref.get() : null;
            //Slog.i(TAG, "getPackageInfo " + packageName + ": " + packageInfo);
            //if (packageInfo != null) Slog.i(TAG, "isUptoDate " + packageInfo.mResDir
            //        + ": " + packageInfo.mResources.getAssets().isUpToDate());
            if (packageInfo != null && (packageInfo.mResources == null
                    || packageInfo.mResources.getAssets().isUpToDate())) {
            if (ai != null && packageInfo != null && isLoadedApkUpToDate(packageInfo, ai)) {
                if (packageInfo.isSecurityViolation()
                        && (flags&Context.CONTEXT_IGNORE_SECURITY) == 0) {
                    throw new SecurityException(
@@ -2129,16 +2135,6 @@ public final class ActivityThread extends ClientTransactionHandler {
            }
        }

        ApplicationInfo ai = null;
        try {
            ai = getPackageManager().getApplicationInfo(packageName,
                    PackageManager.GET_SHARED_LIBRARY_FILES
                            | PackageManager.MATCH_DEBUG_TRIAGED_MISSING,
                    (userId < 0) ? UserHandle.myUserId() : userId);
        } catch (RemoteException e) {
            throw e.rethrowFromSystemServer();
        }

        if (ai != null) {
            return getPackageInfo(ai, compatInfo, flags);
        }
@@ -2209,17 +2205,25 @@ public final class ActivityThread extends ClientTransactionHandler {
            }

            LoadedApk packageInfo = ref != null ? ref.get() : null;
            if (packageInfo == null || (packageInfo.mResources != null
                    && !packageInfo.mResources.getAssets().isUpToDate())) {
                if (localLOGV) Slog.v(TAG, (includeCode ? "Loading code package "

            boolean isUpToDate = packageInfo != null && isLoadedApkUpToDate(packageInfo, aInfo);

            if (isUpToDate) {
                return packageInfo;
            }

            if (localLOGV) {
                Slog.v(TAG, (includeCode ? "Loading code package "
                        : "Loading resource-only package ") + aInfo.packageName
                        + " (in " + (mBoundApplication != null
                        ? mBoundApplication.processName : null)
                        + ")");
            }

            packageInfo =
                    new LoadedApk(this, aInfo, compatInfo, baseLoader,
                            securityViolation, includeCode &&
                            (aInfo.flags&ApplicationInfo.FLAG_HAS_CODE) != 0, registerPackage);
                            securityViolation, includeCode
                            && (aInfo.flags & ApplicationInfo.FLAG_HAS_CODE) != 0, registerPackage);

            if (mSystemThread && "android".equals(aInfo.packageName)) {
                packageInfo.installSystemApplicationInfo(aInfo,
@@ -2235,11 +2239,25 @@ public final class ActivityThread extends ClientTransactionHandler {
                mResourcePackages.put(aInfo.packageName,
                        new WeakReference<LoadedApk>(packageInfo));
            }
            }

            return packageInfo;
        }
    }

    /**
     * Compares overlay/resource directories for a LoadedApk to determine if it's up to date
     * with the given ApplicationInfo.
     */
    private boolean isLoadedApkUpToDate(LoadedApk loadedApk, ApplicationInfo appInfo) {
        Resources packageResources = loadedApk.mResources;
        String[] overlayDirs = ArrayUtils.defeatNullable(loadedApk.getOverlayDirs());
        String[] resourceDirs = ArrayUtils.defeatNullable(appInfo.resourceDirs);

        return (packageResources == null || packageResources.getAssets().isUpToDate())
                && overlayDirs.length == resourceDirs.length
                && ArrayUtils.containsAll(overlayDirs, resourceDirs);
    }

    @UnsupportedAppUsage
    ActivityThread() {
        mResourcesManager = ResourcesManager.getInstance();