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

Commit f4479eef authored by Andrii Kulian's avatar Andrii Kulian
Browse files

Update visibility and config at the same time

Update visibility, orientation and config together to ensure that
only activities that are actually visible can affect the orientation.

Bug: 76011287
Test: ActivityManagerAppConfigurationTests
Change-Id: Icdafedf540391d186f5dbe250b2b69d36742a26c
parent 3dcdf64c
Loading
Loading
Loading
Loading
+28 −25
Original line number Diff line number Diff line
@@ -1360,7 +1360,9 @@ class ActivityStack<T extends StackWindowController> extends ConfigurationContai
    }

    void goToSleep() {
        ensureActivitiesVisibleLocked(null, 0, !PRESERVE_WINDOWS);
        // Ensure visibility without updating configuration, as activities are about to sleep.
        ensureActivitiesVisibleLocked(null /* starting */, 0 /* configChanges */, !PRESERVE_WINDOWS,
                false /* updateConfiguration */);

        // Make sure any paused or stopped but visible activities are now sleeping.
        // This ensures that the activity's onStop() is called.
@@ -1829,12 +1831,23 @@ class ActivityStack<T extends StackWindowController> extends ConfigurationContai
    }

    /**
     * Make sure that all activities that need to be visible (that is, they
     * currently can be seen by the user) actually are.
     * Make sure that all activities that need to be visible in the stack (that is, they
     * currently can be seen by the user) actually are and update their configuration.
     */
    // TODO: Should be re-worked based on the fact that each task as a stack in most cases.
    final void ensureActivitiesVisibleLocked(ActivityRecord starting, int configChanges,
            boolean preserveWindows) {
        ensureActivitiesVisibleLocked(starting, configChanges, preserveWindows,
                true /* updateConfiguration */);
    }

    /**
     * Ensure visibility with an option to also update the configuration of visible activities.
     * @see #ensureActivitiesVisibleLocked(ActivityRecord, int, boolean)
     * @see ActivityStackSupervisor#ensureActivitiesVisibleLocked(ActivityRecord, int, boolean)
     */
    // TODO: Should be re-worked based on the fact that each task as a stack in most cases.
    final void ensureActivitiesVisibleLocked(ActivityRecord starting, int configChanges,
            boolean preserveWindows, boolean updateConfiguration) {
        mTopActivityOccludesKeyguard = false;
        mTopDismissingKeyguardActivity = null;
        mStackSupervisor.getKeyguardController().beginActivityVisibilityUpdate();
@@ -1886,9 +1899,7 @@ class ActivityStack<T extends StackWindowController> extends ConfigurationContai
                                + " finishing=" + r.finishing + " state=" + r.getState());
                        // First: if this is not the current activity being started, make
                        // sure it matches the current configuration.
                        if (r != starting) {
                            // Ensure activity configuration ignoring stop state since we are
                            // becoming visible.
                        if (r != starting && updateConfiguration) {
                            r.ensureActivityConfiguration(0 /* globalChanges */, preserveWindows,
                                    true /* ignoreStopState */);
                        }
@@ -2608,25 +2619,16 @@ class ActivityStack<T extends StackWindowController> extends ConfigurationContai
                boolean notUpdated = true;

                if (mStackSupervisor.isFocusedStack(this)) {

                    // We have special rotation behavior when Keyguard is locked. Make sure all
                    // activity visibilities are set correctly as well as the transition is updated
                    // if needed to get the correct rotation behavior.
                    // We have special rotation behavior when here is some active activity that
                    // requests specific orientation or Keyguard is locked. Make sure all activity
                    // visibilities are set correctly as well as the transition is updated if needed
                    // to get the correct rotation behavior. Otherwise the following call to update
                    // the orientation may cause incorrect configurations delivered to client as a
                    // result of invisible window resize.
                    // TODO: Remove this once visibilities are set correctly immediately when
                    // starting an activity.
                    if (mStackSupervisor.getKeyguardController().isKeyguardLocked()) {
                        mStackSupervisor.ensureActivitiesVisibleLocked(null /* starting */,
                                0 /* configChanges */, false /* preserveWindows */);
                    }
                    final Configuration config = mWindowManager.updateOrientationFromAppTokens(
                            mStackSupervisor.getDisplayOverrideConfiguration(mDisplayId),
                            next.mayFreezeScreenLocked(next.app) ? next.appToken : null,
                                    mDisplayId);
                    if (config != null) {
                        next.frozenBeforeDestroy = true;
                    }
                    notUpdated = !mService.updateDisplayOverrideConfigurationLocked(config, next,
                            false /* deferResume */, mDisplayId);
                    notUpdated = !mStackSupervisor.ensureVisibilityAndConfig(next, mDisplayId,
                            true /* markFrozenIfConfigChanged */, false /* deferResume */);
                }

                if (notUpdated) {
@@ -3834,7 +3836,8 @@ class ActivityStack<T extends StackWindowController> extends ConfigurationContai
            if (finishingActivityInNonFocusedStack) {
                // Finishing activity that was in paused state and it was in not currently focused
                // stack, need to make something visible in its place.
                mStackSupervisor.ensureActivitiesVisibleLocked(null, 0, !PRESERVE_WINDOWS);
                mStackSupervisor.ensureVisibilityAndConfig(null, mDisplayId,
                        false /* markFrozenIfConfigChanged */, true /* deferResume */);
            }
            if (activityRemoved) {
                mStackSupervisor.resumeFocusedStackTopActivityLocked();
+42 −7
Original line number Diff line number Diff line
@@ -1409,15 +1409,11 @@ public class ActivityStackSupervisor extends ConfigurationContainer implements D
            // manager with a new orientation.  We don't care about that, because the activity is
            // not currently running so we are just restarting it anyway.
            if (checkConfig) {
                final int displayId = r.getDisplayId();
                final Configuration config = mWindowManager.updateOrientationFromAppTokens(
                        getDisplayOverrideConfiguration(displayId),
                        r.mayFreezeScreenLocked(app) ? r.appToken : null, displayId);
                // Deferring resume here because we're going to launch new activity shortly.
                // We don't want to perform a redundant launch of the same record while ensuring
                // configurations and trying to resume top activity of focused stack.
                mService.updateDisplayOverrideConfigurationLocked(config, r, true /* deferResume */,
                        displayId);
                ensureVisibilityAndConfig(r, r.getDisplayId(),
                        false /* markFrozenIfConfigChanged */, true /* deferResume */);
            }

            if (r.getStack().checkKeyguardVisibility(r, true /* shouldBeVisible */,
@@ -1630,6 +1626,31 @@ public class ActivityStackSupervisor extends ConfigurationContainer implements D
        return true;
    }

    /**
     * Ensure all activities visibility, update orientation and configuration.
     */
    boolean ensureVisibilityAndConfig(ActivityRecord r, int displayId,
            boolean markFrozenIfConfigChanged, boolean deferResume) {
        // First ensure visibility without updating the config just yet. We need this to know what
        // activities are affecting configuration now.
        ensureActivitiesVisibleLocked(null /* starting */, 0 /* configChanges */,
                false /* preserveWindows */, false /* updateConfiguration */);

        // Force-update the orientation from the WindowManager, since we need the true configuration
        // to send to the client now.
        final Configuration config = mWindowManager.updateOrientationFromAppTokens(
                getDisplayOverrideConfiguration(displayId),
                r != null && r.mayFreezeScreenLocked(r.app) ? r.appToken : null,
                displayId);
        if (r != null && markFrozenIfConfigChanged && config != null) {
            r.frozenBeforeDestroy = true;
        }

        // Update the configuration of the activities on the display.
        return mService.updateDisplayOverrideConfigurationLocked(config, r,
                deferResume, displayId);
    }

    private void logIfTransactionTooLarge(Intent intent, Bundle icicle) {
        int extrasSize = 0;
        if (intent != null) {
@@ -3647,8 +3668,21 @@ public class ActivityStackSupervisor extends ConfigurationContainer implements D
        mHandler.obtainMessage(LAUNCH_TASK_BEHIND_COMPLETE, token).sendToTarget();
    }

    /**
     * Make sure that all activities that need to be visible in the system actually are and update
     * their configuration.
     */
    void ensureActivitiesVisibleLocked(ActivityRecord starting, int configChanges,
            boolean preserveWindows) {
        ensureActivitiesVisibleLocked(starting, configChanges, preserveWindows,
                true /* updateConfiguration */);
    }

    /**
     * @see #ensureActivitiesVisibleLocked(ActivityRecord, int, boolean)
     */
    void ensureActivitiesVisibleLocked(ActivityRecord starting, int configChanges,
            boolean preserveWindows, boolean updateConfiguration) {
        getKeyguardController().beginActivityVisibilityUpdate();
        try {
            // First the front stacks. In case any are not fullscreen and are in front of home.
@@ -3656,7 +3690,8 @@ public class ActivityStackSupervisor extends ConfigurationContainer implements D
                final ActivityDisplay display = mActivityDisplays.valueAt(displayNdx);
                for (int stackNdx = display.getChildCount() - 1; stackNdx >= 0; --stackNdx) {
                    final ActivityStack stack = display.getChildAt(stackNdx);
                    stack.ensureActivitiesVisibleLocked(starting, configChanges, preserveWindows);
                    stack.ensureActivitiesVisibleLocked(starting, configChanges, preserveWindows,
                            updateConfiguration);
                }
            }
        } finally {