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

Commit 8a9a7061 authored by Ryan Mitchell's avatar Ryan Mitchell
Browse files

Apply overlay changes with config change

In R, when overlay changes a configuration change event is triggered
within the app process affected by the overlay change immediately
after updating the overlay paths of resources objects. All activities
would be relaunched after the configuration changed occurred resulting
in activity life-cycle events occurring for activities running in the
background. Apps may assume that onResume is invoked while they are in
the foreground so we made a fix that triggered the activities to be
relaunched when they are brought to the foreground.

The fix involved storing the asset sequence in the AMS and triggering
a configuration change from the AMS for each process affected by the
overlay change. This created problems where the app may receive a
configuration from the AMS with an updated asset sequence before the
event to handle the application info changing actually updated
resources objects. This resulted in reinflating views with the updated
configuration before the overlays were updated in the underlying
resources objects.

This change allows allows RM to apply changes to application infos when
it sees the asset sequence increase during a configuration change,
rather than having to wait for handleApplicationInfoChanged to run.

Bug: 189100984
Test: toggle wallpaper and observe QS has correct colors
Test: launch an app, navigate away from the app, change wallpapers, and
      observe app is relaunched and has correct colors when resumed
Change-Id: Icf81845da9890cda0fb38cf6fe51d1d66e5ea840
parent 25360a2f
Loading
Loading
Loading
Loading
+1 −0
Original line number Diff line number Diff line
@@ -1182,6 +1182,7 @@ public final class ActivityThread extends ClientTransactionHandler
        }

        public void scheduleApplicationInfoChanged(ApplicationInfo ai) {
            mResourcesManager.updatePendingAppInfoUpdates(ai);
            mH.removeMessages(H.APPLICATION_INFO_CHANGED, ai);
            sendMessage(H.APPLICATION_INFO_CHANGED, ai);
        }
+38 −5
Original line number Diff line number Diff line
@@ -98,6 +98,12 @@ public class ResourcesManager {
     */
    private int mResDisplayId = DEFAULT_DISPLAY;

    /**
     * ApplicationInfo changes that need to be applied to Resources when the next configuration
     * change occurs.
     */
    private ArrayList<ApplicationInfo> mPendingAppInfoUpdates;

    /**
     * A mapping of ResourceImpls and their configurations. These are heavy weight objects
     * which should be reused as much as possible.
@@ -1032,7 +1038,7 @@ public class ResourcesManager {
     * @param classLoader The classloader to use for the Resources object.
     *                    If null, {@link ClassLoader#getSystemClassLoader()} is used.
     * @return A Resources object that gets updated when
     *         {@link #applyConfigurationToResourcesLocked(Configuration, CompatibilityInfo)}
     *         {@link #applyConfigurationToResources(Configuration, CompatibilityInfo)}
     *         is called.
     */
    @Nullable
@@ -1159,8 +1165,8 @@ public class ResourcesManager {
    /**
     * Updates an Activity's Resources object with overrideConfig. The Resources object
     * that was previously returned by {@link #getResources(IBinder, String, String[], String[],
     * String[], Integer, Configuration, CompatibilityInfo, ClassLoader, List)} is still valid and
     * will have the updated configuration.
     * String[], String[], Integer, Configuration, CompatibilityInfo, ClassLoader, List)} is still
     * valid and will have the updated configuration.
     *
     * @param activityToken The Activity token.
     * @param overrideConfig The configuration override to update.
@@ -1311,6 +1317,22 @@ public class ResourcesManager {
        return newKey;
    }

    public void updatePendingAppInfoUpdates(@NonNull ApplicationInfo appInfo) {
        synchronized (mLock) {
            if (mPendingAppInfoUpdates == null) {
                mPendingAppInfoUpdates = new ArrayList<>();
            }
            // Clear previous app info changes for the package to prevent multiple ResourcesImpl
            // recreations when only the last recreation will be used.
            for (int i = mPendingAppInfoUpdates.size() - 1; i >= 0; i--) {
                if (appInfo.sourceDir.equals(mPendingAppInfoUpdates.get(i).sourceDir)) {
                    mPendingAppInfoUpdates.remove(i);
                }
            }
            mPendingAppInfoUpdates.add(appInfo);
        }
    }

    public final boolean applyConfigurationToResources(@NonNull Configuration config,
            @Nullable CompatibilityInfo compat) {
        return applyConfigurationToResources(config, compat, null /* adjustments */);
@@ -1324,7 +1346,18 @@ public class ResourcesManager {
                Trace.traceBegin(Trace.TRACE_TAG_RESOURCES,
                        "ResourcesManager#applyConfigurationToResources");

                if (!mResConfiguration.isOtherSeqNewer(config) && compat == null) {
                final boolean assetsUpdated = mPendingAppInfoUpdates != 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) {
                        Slog.v(TAG, "Skipping new config: curSeq="
                                + mResConfiguration.seq + ", newSeq=" + config.seq);
@@ -1367,7 +1400,7 @@ public class ResourcesManager {
                    }
                }

                return changes != 0;
                return assetsUpdated || changes != 0;
            } finally {
                Trace.traceEnd(Trace.TRACE_TAG_RESOURCES);
            }
+2 −3
Original line number Diff line number Diff line
@@ -4698,10 +4698,10 @@ public final class ProcessList {
                        final ApplicationInfo ai = AppGlobals.getPackageManager()
                                .getApplicationInfo(packageName, STOCK_PM_FLAGS, app.userId);
                        if (ai != null) {
                            app.getThread().scheduleApplicationInfoChanged(ai);
                            if (ai.packageName.equals(app.info.packageName)) {
                                app.info = ai;
                            }
                            app.getThread().scheduleApplicationInfoChanged(ai);
                            targetProcesses.add(app.getWindowProcessController());
                        }
                    } catch (RemoteException e) {
@@ -4712,8 +4712,7 @@ public final class ProcessList {
            });
        }

        mService.mActivityTaskManager.updateAssetConfiguration(
                updateFrameworkRes ? null : targetProcesses);
        mService.mActivityTaskManager.updateAssetConfiguration(targetProcesses, updateFrameworkRes);
    }

    @GuardedBy("mService")
+6 −6
Original line number Diff line number Diff line
@@ -4146,21 +4146,21 @@ public class ActivityTaskManagerService extends IActivityTaskManager.Stub {

    /**
     * Update the asset configuration and increase the assets sequence number.
     * @param processes the processes that needs to update the asset configuration, if none
     *                  updates the global configuration for all processes.
     * @param processes the processes that needs to update the asset configuration
     */
    public void updateAssetConfiguration(List<WindowProcessController> processes) {
    public void updateAssetConfiguration(List<WindowProcessController> processes,
            boolean updateFrameworkRes) {
        synchronized (mGlobalLock) {
            final int assetSeq = increaseAssetConfigurationSeq();

            // Update the global configuration if the no target processes
            if (processes == null) {
            if (updateFrameworkRes) {
                Configuration newConfig = new Configuration();
                newConfig.assetsSeq = assetSeq;
                updateConfiguration(newConfig);
                return;
            }

            // Always update the override of every process so the asset sequence of the process is
            // always greater than or equal to the global configuration.
            for (int i = processes.size() - 1; i >= 0; i--) {
                final WindowProcessController wpc = processes.get(i);
                wpc.updateAssetConfiguration(assetSeq);