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

Commit 82549387 authored by Ryan Mitchell's avatar Ryan Mitchell
Browse files

Do not update RM config with previous sequence

If an application info update is pending and
RM#applyConfigurationToResourcesLocked is called with a config
with an older sequence that RM's current global config, the application
info update should not be applied, nor should the global config be
updated with the older config.

Similarly, when an application is updated and there is a pending
application info change for the previous version of the package,
clear the currently pending application info updates for that package
to prevent the old overlays from being applied on top of the newly
updated application.

Bug: 189100984
Bug: 192449747
Test: toggle wallpaper and observe QS has correct colors
Change-Id: I4bab55960febdae16df7150ccac44e06245e8333
parent b827a8ac
Loading
Loading
Loading
Loading
+5 −7
Original line number Original line Diff line number Diff line
@@ -1169,7 +1169,7 @@ public final class ActivityThread extends ClientTransactionHandler
        }
        }


        public void scheduleApplicationInfoChanged(ApplicationInfo ai) {
        public void scheduleApplicationInfoChanged(ApplicationInfo ai) {
            mResourcesManager.updatePendingAppInfoUpdates(ai);
            mResourcesManager.appendPendingAppInfoUpdate(new String[]{ai.sourceDir}, ai);
            mH.removeMessages(H.APPLICATION_INFO_CHANGED, ai);
            mH.removeMessages(H.APPLICATION_INFO_CHANGED, ai);
            sendMessage(H.APPLICATION_INFO_CHANGED, ai);
            sendMessage(H.APPLICATION_INFO_CHANGED, ai);
        }
        }
@@ -6001,16 +6001,12 @@ public final class ActivityThread extends ClientTransactionHandler
            resApk = ref != null ? ref.get() : null;
            resApk = ref != null ? ref.get() : null;
        }
        }


        final String[] oldResDirs = new String[2];

        if (apk != null) {
        if (apk != null) {
            oldResDirs[0] = apk.getResDir();
            final ArrayList<String> oldPaths = new ArrayList<>();
            final ArrayList<String> oldPaths = new ArrayList<>();
            LoadedApk.makePaths(this, apk.getApplicationInfo(), oldPaths);
            LoadedApk.makePaths(this, apk.getApplicationInfo(), oldPaths);
            apk.updateApplicationInfo(ai, oldPaths);
            apk.updateApplicationInfo(ai, oldPaths);
        }
        }
        if (resApk != null) {
        if (resApk != null) {
            oldResDirs[1] = resApk.getResDir();
            final ArrayList<String> oldPaths = new ArrayList<>();
            final ArrayList<String> oldPaths = new ArrayList<>();
            LoadedApk.makePaths(this, resApk.getApplicationInfo(), oldPaths);
            LoadedApk.makePaths(this, resApk.getApplicationInfo(), oldPaths);
            resApk.updateApplicationInfo(ai, oldPaths);
            resApk.updateApplicationInfo(ai, oldPaths);
@@ -6018,7 +6014,7 @@ public final class ActivityThread extends ClientTransactionHandler


        synchronized (mResourcesManager) {
        synchronized (mResourcesManager) {
            // Update all affected Resources objects to use new ResourcesImpl
            // Update all affected Resources objects to use new ResourcesImpl
            mResourcesManager.applyNewResourceDirs(ai, oldResDirs);
            mResourcesManager.applyAllPendingAppInfoUpdates();
        }
        }
    }
    }


@@ -6274,7 +6270,9 @@ public final class ActivityThread extends ClientTransactionHandler


                                synchronized (mResourcesManager) {
                                synchronized (mResourcesManager) {
                                    // Update affected Resources objects to use new ResourcesImpl
                                    // Update affected Resources objects to use new ResourcesImpl
                                    mResourcesManager.applyNewResourceDirs(aInfo, oldResDirs);
                                    mResourcesManager.appendPendingAppInfoUpdate(oldResDirs,
                                            aInfo);
                                    mResourcesManager.applyAllPendingAppInfoUpdates();
                                }
                                }
                            } catch (RemoteException e) {
                            } catch (RemoteException e) {
                            }
                            }
+73 −65
Original line number Original line Diff line number Diff line
@@ -42,6 +42,7 @@ import android.util.ArrayMap;
import android.util.ArraySet;
import android.util.ArraySet;
import android.util.DisplayMetrics;
import android.util.DisplayMetrics;
import android.util.Log;
import android.util.Log;
import android.util.Pair;
import android.util.Slog;
import android.util.Slog;
import android.view.Display;
import android.view.Display;
import android.view.DisplayAdjustments;
import android.view.DisplayAdjustments;
@@ -101,7 +102,7 @@ public class ResourcesManager {
     * ApplicationInfo changes that need to be applied to Resources when the next configuration
     * ApplicationInfo changes that need to be applied to Resources when the next configuration
     * change occurs.
     * change occurs.
     */
     */
    private ArrayList<ApplicationInfo> mPendingAppInfoUpdates;
    private ArrayList<Pair<String[], ApplicationInfo>> mPendingAppInfoUpdates;


    /**
    /**
     * A mapping of ResourceImpls and their configurations. These are heavy weight objects
     * A mapping of ResourceImpls and their configurations. These are heavy weight objects
@@ -1273,19 +1274,33 @@ public class ResourcesManager {
        return newKey;
        return newKey;
    }
    }


    public void updatePendingAppInfoUpdates(@NonNull ApplicationInfo appInfo) {
    public void appendPendingAppInfoUpdate(@NonNull String[] oldSourceDirs,
            @NonNull ApplicationInfo appInfo) {
        synchronized (mLock) {
        synchronized (mLock) {
            if (mPendingAppInfoUpdates == null) {
            if (mPendingAppInfoUpdates == null) {
                mPendingAppInfoUpdates = new ArrayList<>();
                mPendingAppInfoUpdates = new ArrayList<>();
            }
            }
            // Clear previous app info changes for the package to prevent multiple ResourcesImpl
            // Clear previous app info changes for a package to prevent multiple ResourcesImpl
            // recreations when only the last recreation will be used.
            // recreations when the recreation caused by this update completely overrides the
            // previous pending changes.
            for (int i = mPendingAppInfoUpdates.size() - 1; i >= 0; i--) {
            for (int i = mPendingAppInfoUpdates.size() - 1; i >= 0; i--) {
                if (appInfo.sourceDir.equals(mPendingAppInfoUpdates.get(i).sourceDir)) {
                if (ArrayUtils.containsAll(oldSourceDirs, mPendingAppInfoUpdates.get(i).first)) {
                    mPendingAppInfoUpdates.remove(i);
                    mPendingAppInfoUpdates.remove(i);
                }
                }
            }
            }
            mPendingAppInfoUpdates.add(appInfo);
            mPendingAppInfoUpdates.add(new Pair<>(oldSourceDirs, appInfo));
        }
    }

    public final void applyAllPendingAppInfoUpdates() {
        synchronized (mLock) {
            if (mPendingAppInfoUpdates != null) {
                for (int i = 0, n = mPendingAppInfoUpdates.size(); i < n; i++) {
                    final Pair<String[], ApplicationInfo> appInfo = mPendingAppInfoUpdates.get(i);
                    applyNewResourceDirsLocked(appInfo.first, appInfo.second);
                }
                mPendingAppInfoUpdates = null;
            }
        }
        }
    }
    }


@@ -1302,18 +1317,7 @@ public class ResourcesManager {
                Trace.traceBegin(Trace.TRACE_TAG_RESOURCES,
                Trace.traceBegin(Trace.TRACE_TAG_RESOURCES,
                        "ResourcesManager#applyConfigurationToResources");
                        "ResourcesManager#applyConfigurationToResources");


                final boolean assetsUpdated = mPendingAppInfoUpdates != null
                if (!mResConfiguration.isOtherSeqNewer(config) && compat == null) {
                        && config.assetsSeq > mResConfiguration.assetsSeq;
                if (assetsUpdated) {
                    for (int i = 0, n = mPendingAppInfoUpdates.size(); i < n; i++) {
                        final ApplicationInfo appInfo = mPendingAppInfoUpdates.get(i);
                        applyNewResourceDirs(appInfo, new String[]{appInfo.sourceDir});
                    }
                    mPendingAppInfoUpdates = null;
                }

                if (!assetsUpdated && !mResConfiguration.isOtherSeqNewer(config)
                        && compat == null) {
                    if (DEBUG || DEBUG_CONFIGURATION) {
                    if (DEBUG || DEBUG_CONFIGURATION) {
                        Slog.v(TAG, "Skipping new config: curSeq="
                        Slog.v(TAG, "Skipping new config: curSeq="
                                + mResConfiguration.seq + ", newSeq=" + config.seq);
                                + mResConfiguration.seq + ", newSeq=" + config.seq);
@@ -1330,6 +1334,13 @@ public class ResourcesManager {
                            | ActivityInfo.CONFIG_SMALLEST_SCREEN_SIZE;
                            | ActivityInfo.CONFIG_SMALLEST_SCREEN_SIZE;
                }
                }


                // If a application info update was scheduled to occur in this process but has not
                // occurred yet, apply it now so the resources objects will have updated paths when
                // the assets sequence changes.
                if ((changes & ActivityInfo.CONFIG_ASSETS_PATHS) != 0) {
                    applyAllPendingAppInfoUpdates();
                }

                DisplayMetrics displayMetrics = getDisplayMetrics();
                DisplayMetrics displayMetrics = getDisplayMetrics();
                if (adjustments != null) {
                if (adjustments != null) {
                    // Currently the only case where the adjustment takes effect is to simulate
                    // Currently the only case where the adjustment takes effect is to simulate
@@ -1353,7 +1364,7 @@ public class ResourcesManager {
                    }
                    }
                }
                }


                return assetsUpdated || changes != 0;
                return changes != 0;
            } finally {
            } finally {
                Trace.traceEnd(Trace.TRACE_TAG_RESOURCES);
                Trace.traceEnd(Trace.TRACE_TAG_RESOURCES);
            }
            }
@@ -1440,10 +1451,8 @@ public class ResourcesManager {
        }
        }
    }
    }


    // TODO(adamlesinski): Make this accept more than just overlay directories.
    private void applyNewResourceDirsLocked(@Nullable final String[] oldSourceDirs,
    void applyNewResourceDirs(@NonNull final ApplicationInfo appInfo,
            @NonNull final ApplicationInfo appInfo) {
            @Nullable final String[] oldPaths) {
        synchronized (mLock) {
        try {
        try {
            Trace.traceBegin(Trace.TRACE_TAG_RESOURCES,
            Trace.traceBegin(Trace.TRACE_TAG_RESOURCES,
                    "ResourcesManager#applyNewResourceDirsLocked");
                    "ResourcesManager#applyNewResourceDirsLocked");
@@ -1477,7 +1486,7 @@ public class ResourcesManager {


                if (key.mResDir == null
                if (key.mResDir == null
                        || key.mResDir.equals(baseCodePath)
                        || key.mResDir.equals(baseCodePath)
                            || ArrayUtils.contains(oldPaths, key.mResDir)) {
                        || ArrayUtils.contains(oldSourceDirs, key.mResDir)) {
                    updatedResourceKeys.put(impl, new ResourcesKey(
                    updatedResourceKeys.put(impl, new ResourcesKey(
                            baseCodePath,
                            baseCodePath,
                            copiedSplitDirs,
                            copiedSplitDirs,
@@ -1496,7 +1505,6 @@ public class ResourcesManager {
            Trace.traceEnd(Trace.TRACE_TAG_RESOURCES);
            Trace.traceEnd(Trace.TRACE_TAG_RESOURCES);
        }
        }
    }
    }
    }


    /**
    /**
     * Creates an array with the contents of {@param overlayPaths} and the unique elements of
     * Creates an array with the contents of {@param overlayPaths} and the unique elements of