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

Commit b6d75f30 authored by Wale Ogunwale's avatar Wale Ogunwale
Browse files

Ignore stopped state when becoming visible and ensuring configuration.

We normally don't ensure configuration for activities in the stopped
state since it doesn't make sense to be relaunching something that isn't
visible. However, if the activity is becoming visible, then ignore the
stopped state allowing the configuration to be ensured and the activity
relaunched if needed.

Change-Id: If953b624105c8c522f01cfb8fc68ded4fb18698d
Fixes: 73696401
Test: atest ActivityLifecycleTests#testRelaunchConfigurationChangedWhileBecomingVisible
parent a72cab84
Loading
Loading
Loading
Loading
+2 −2
Original line number Diff line number Diff line
@@ -22355,7 +22355,7 @@ public class ActivityManagerService extends IActivityManager.Stub
        // Update the configuration with WM first and check if any of the stacks need to be resized
        // due to the configuration change. If so, resize the stacks now and do any relaunches if
        // necessary. This way we don't need to relaunch again afterwards in
        // ensureActivityConfigurationLocked().
        // ensureActivityConfiguration().
        if (mWindowManager != null) {
            final int[] resizedStacks =
                    mWindowManager.setNewDisplayOverrideConfiguration(mTempConfig, displayId);
@@ -22383,7 +22383,7 @@ public class ActivityManagerService extends IActivityManager.Stub
            }
            if (starting != null) {
                kept = starting.ensureActivityConfigurationLocked(changes,
                kept = starting.ensureActivityConfiguration(changes,
                        false /* preserveWindow */);
                // And we need to make sure at this point that all other activities
                // are made visible with the correct configuration.
+21 −8
Original line number Diff line number Diff line
@@ -361,7 +361,7 @@ final class ActivityRecord extends ConfigurationContainer implements AppWindowCo
    private boolean mTurnScreenOn;

    /**
     * Temp configs used in {@link #ensureActivityConfigurationLocked(int, boolean)}
     * Temp configs used in {@link #ensureActivityConfiguration(int, boolean)}
     */
    private final Configuration mTmpConfig = new Configuration();
    private final Rect mTmpBounds = new Rect();
@@ -2365,13 +2365,27 @@ final class ActivityRecord extends ConfigurationContainer implements AppWindowCo
        outBounds.offsetTo(left, 0 /* top */);
    }

    boolean ensureActivityConfiguration(int globalChanges, boolean preserveWindow) {
        return ensureActivityConfiguration(globalChanges, preserveWindow,
                false /* ignoreStopState */);
    }

    /**
     * Make sure the given activity matches the current configuration. Returns false if the activity
     * had to be destroyed.  Returns true if the configuration is the same, or the activity will
     * remain running as-is for whatever reason. Ensures the HistoryRecord is updated with the
     * correct configuration and all other bookkeeping is handled.
     * Make sure the given activity matches the current configuration. Ensures the HistoryRecord
     * is updated with the correct configuration and all other bookkeeping is handled.
     *
     * @param globalChanges The changes to the global configuration.
     * @param preserveWindow If the activity window should be preserved on screen if the activity
     *                       is relaunched.
     * @param ignoreStopState If we should try to relaunch the activity even if it is in the stopped
     *                        state. This is useful for the case where we know the activity will be
     *                        visible soon and we want to ensure its configuration before we make it
     *                        visible.
     * @return True if the activity was relaunched and false if it wasn't relaunched because we
     *         can't or the app handles the specific configuration that is changing.
     */
    boolean ensureActivityConfigurationLocked(int globalChanges, boolean preserveWindow) {
    boolean ensureActivityConfiguration(int globalChanges, boolean preserveWindow,
            boolean ignoreStopState) {
        final ActivityStack stack = getStack();
        if (stack.mConfigWillChange) {
            if (DEBUG_SWITCH || DEBUG_CONFIGURATION) Slog.v(TAG_CONFIGURATION,
@@ -2387,8 +2401,7 @@ final class ActivityRecord extends ConfigurationContainer implements AppWindowCo
            return true;
        }

        // Skip updating configuration for activity that are stopping or stopped.
        if (mState == STOPPING || mState == STOPPED) {
        if (!ignoreStopState && (mState == STOPPING || mState == STOPPED)) {
            if (DEBUG_SWITCH || DEBUG_CONFIGURATION) Slog.v(TAG_CONFIGURATION,
                    "Skipping config check stopped or stopping: " + this);
            return true;
+5 −3
Original line number Diff line number Diff line
@@ -123,7 +123,6 @@ import android.content.res.Configuration;
import android.graphics.Rect;
import android.net.Uri;
import android.os.Binder;
import android.os.Bundle;
import android.os.Debug;
import android.os.Handler;
import android.os.IBinder;
@@ -1851,7 +1850,10 @@ class ActivityStack<T extends StackWindowController> extends ConfigurationContai
                        // First: if this is not the current activity being started, make
                        // sure it matches the current configuration.
                        if (r != starting) {
                            r.ensureActivityConfigurationLocked(0 /* globalChanges */, preserveWindows);
                            // Ensure activity configuration ignoring stop state since we are
                            // becoming visible.
                            r.ensureActivityConfiguration(0 /* globalChanges */, preserveWindows,
                                    true /* ignoreStopState */);
                        }

                        if (r.app == null || r.app.thread == null) {
@@ -4627,7 +4629,7 @@ class ActivityStack<T extends StackWindowController> extends ConfigurationContai
                    (start.getTask() == task) ? activities.indexOf(start) : activities.size() - 1;
            for (; activityIndex >= 0; --activityIndex) {
                final ActivityRecord r = activities.get(activityIndex);
                updatedConfig |= r.ensureActivityConfigurationLocked(0 /* globalChanges */,
                updatedConfig |= r.ensureActivityConfiguration(0 /* globalChanges */,
                        preserveWindow);
                if (r.fullscreen) {
                    behindFullscreen = true;
+1 −1
Original line number Diff line number Diff line
@@ -369,7 +369,7 @@ public final class CompatModePackages {
            }

            if (starting != null) {
                starting.ensureActivityConfigurationLocked(0 /* globalChanges */,
                starting.ensureActivityConfiguration(0 /* globalChanges */,
                        false /* preserveWindow */);
                // And we need to make sure at this point that all other activities
                // are made visible with the correct configuration.
+1 −1
Original line number Diff line number Diff line
@@ -537,7 +537,7 @@ class TaskRecord extends ConfigurationContainer implements TaskWindowContainerLi
            if (updatedConfig) {
                final ActivityRecord r = topRunningActivityLocked();
                if (r != null && !deferResume) {
                    kept = r.ensureActivityConfigurationLocked(0 /* globalChanges */,
                    kept = r.ensureActivityConfiguration(0 /* globalChanges */,
                            preserveWindow);
                    mService.mStackSupervisor.ensureActivitiesVisibleLocked(r, 0,
                            !PRESERVE_WINDOWS);
Loading