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

Commit f0e2c8bd authored by Andrii Kulian's avatar Andrii Kulian Committed by Android (Google) Code Review
Browse files

Merge "Defer client visibility update when calculating new config" into pi-dev

parents 492457e9 a39ae3ea
Loading
Loading
Loading
Loading
+20 −8
Original line number Original line Diff line number Diff line
@@ -313,6 +313,7 @@ final class ActivityRecord extends ConfigurationContainer implements AppWindowCo
                                        // process that it is hidden.
                                        // process that it is hidden.
    boolean sleeping;       // have we told the activity to sleep?
    boolean sleeping;       // have we told the activity to sleep?
    boolean nowVisible;     // is this activity's window visible?
    boolean nowVisible;     // is this activity's window visible?
    boolean mClientVisibilityDeferred;// was the visibility change message to client deferred?
    boolean idle;           // has the activity gone idle?
    boolean idle;           // has the activity gone idle?
    boolean hasBeenLaunched;// has this activity ever been launched?
    boolean hasBeenLaunched;// has this activity ever been launched?
    boolean frozenBeforeDestroy;// has been frozen but not yet destroyed.
    boolean frozenBeforeDestroy;// has been frozen but not yet destroyed.
@@ -1716,7 +1717,7 @@ final class ActivityRecord extends ConfigurationContainer implements AppWindowCo
        return !behindFullscreenActivity || mLaunchTaskBehind;
        return !behindFullscreenActivity || mLaunchTaskBehind;
    }
    }


    void makeVisibleIfNeeded(ActivityRecord starting) {
    void makeVisibleIfNeeded(ActivityRecord starting, boolean reportToClient) {
        // This activity is not currently visible, but is running. Tell it to become visible.
        // This activity is not currently visible, but is running. Tell it to become visible.
        if (mState == RESUMED || this == starting) {
        if (mState == RESUMED || this == starting) {
            if (DEBUG_VISIBILITY) Slog.d(TAG_VISIBILITY,
            if (DEBUG_VISIBILITY) Slog.d(TAG_VISIBILITY,
@@ -1736,15 +1737,28 @@ final class ActivityRecord extends ConfigurationContainer implements AppWindowCo
            setVisible(true);
            setVisible(true);
            sleeping = false;
            sleeping = false;
            app.pendingUiClean = true;
            app.pendingUiClean = true;
            service.getLifecycleManager().scheduleTransaction(app.thread, appToken,
            if (reportToClient) {
                    WindowVisibilityItem.obtain(true /* showWindow */));
                makeClientVisible();
            } else {
                mClientVisibilityDeferred = true;
            }
            // The activity may be waiting for stop, but that is no longer appropriate for it.
            // The activity may be waiting for stop, but that is no longer appropriate for it.
            mStackSupervisor.mStoppingActivities.remove(this);
            mStackSupervisor.mStoppingActivities.remove(this);
            mStackSupervisor.mGoingToSleepActivities.remove(this);
            mStackSupervisor.mGoingToSleepActivities.remove(this);
        } catch (Exception e) {
            // Just skip on any failure; we'll make it visible when it next restarts.
            Slog.w(TAG, "Exception thrown making visible: " + intent.getComponent(), e);
        }
        handleAlreadyVisible();
    }


    /** Send visibility change message to the client and pause if needed. */
    void makeClientVisible() {
        mClientVisibilityDeferred = false;
        try {
            service.getLifecycleManager().scheduleTransaction(app.thread, appToken,
                    WindowVisibilityItem.obtain(true /* showWindow */));
            if (shouldPauseWhenBecomingVisible()) {
            if (shouldPauseWhenBecomingVisible()) {
                // Capture reason before state change

                // An activity must be in the {@link PAUSING} state for the system to validate
                // An activity must be in the {@link PAUSING} state for the system to validate
                // the move to {@link PAUSED}.
                // the move to {@link PAUSED}.
                setState(PAUSING, "makeVisibleIfNeeded");
                setState(PAUSING, "makeVisibleIfNeeded");
@@ -1753,10 +1767,8 @@ final class ActivityRecord extends ConfigurationContainer implements AppWindowCo
                                configChangeFlags, false /* dontReport */));
                                configChangeFlags, false /* dontReport */));
            }
            }
        } catch (Exception e) {
        } catch (Exception e) {
            // Just skip on any failure; we'll make it visible when it next restarts.
            Slog.w(TAG, "Exception thrown sending visibility update: " + intent.getComponent(), e);
            Slog.w(TAG, "Exception thrown making visible: " + intent.getComponent(), e);
        }
        }
        handleAlreadyVisible();
    }
    }


    /** Check if activity should be moved to PAUSED state when it becomes visible. */
    /** Check if activity should be moved to PAUSED state when it becomes visible. */
+11 −7
Original line number Original line Diff line number Diff line
@@ -1360,8 +1360,8 @@ class ActivityStack<T extends StackWindowController> extends ConfigurationContai


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


        // Make sure any paused or stopped but visible activities are now sleeping.
        // Make sure any paused or stopped but visible activities are now sleeping.
        // This ensures that the activity's onStop() is called.
        // This ensures that the activity's onStop() is called.
@@ -1836,7 +1836,7 @@ class ActivityStack<T extends StackWindowController> extends ConfigurationContai
    final void ensureActivitiesVisibleLocked(ActivityRecord starting, int configChanges,
    final void ensureActivitiesVisibleLocked(ActivityRecord starting, int configChanges,
            boolean preserveWindows) {
            boolean preserveWindows) {
        ensureActivitiesVisibleLocked(starting, configChanges, preserveWindows,
        ensureActivitiesVisibleLocked(starting, configChanges, preserveWindows,
                true /* updateConfiguration */);
                true /* notifyClients */);
    }
    }


    /**
    /**
@@ -1846,7 +1846,7 @@ class ActivityStack<T extends StackWindowController> extends ConfigurationContai
     */
     */
    // TODO: Should be re-worked based on the fact that each task as a stack in most cases.
    // 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,
    final void ensureActivitiesVisibleLocked(ActivityRecord starting, int configChanges,
            boolean preserveWindows, boolean updateConfiguration) {
            boolean preserveWindows, boolean notifyClients) {
        mTopActivityOccludesKeyguard = false;
        mTopActivityOccludesKeyguard = false;
        mTopDismissingKeyguardActivity = null;
        mTopDismissingKeyguardActivity = null;
        mStackSupervisor.getKeyguardController().beginActivityVisibilityUpdate();
        mStackSupervisor.getKeyguardController().beginActivityVisibilityUpdate();
@@ -1898,7 +1898,7 @@ class ActivityStack<T extends StackWindowController> extends ConfigurationContai
                                + " finishing=" + r.finishing + " state=" + r.getState());
                                + " finishing=" + r.finishing + " state=" + r.getState());
                        // First: if this is not the current activity being started, make
                        // First: if this is not the current activity being started, make
                        // sure it matches the current configuration.
                        // sure it matches the current configuration.
                        if (r != starting && updateConfiguration) {
                        if (r != starting && notifyClients) {
                            r.ensureActivityConfiguration(0 /* globalChanges */, preserveWindows,
                            r.ensureActivityConfiguration(0 /* globalChanges */, preserveWindows,
                                    true /* ignoreStopState */);
                                    true /* ignoreStopState */);
                        }
                        }
@@ -1918,11 +1918,15 @@ class ActivityStack<T extends StackWindowController> extends ConfigurationContai
                            if (DEBUG_VISIBILITY) Slog.v(TAG_VISIBILITY,
                            if (DEBUG_VISIBILITY) Slog.v(TAG_VISIBILITY,
                                    "Skipping: already visible at " + r);
                                    "Skipping: already visible at " + r);


                            if (r.mClientVisibilityDeferred && notifyClients) {
                                r.makeClientVisible();
                            }

                            if (r.handleAlreadyVisible()) {
                            if (r.handleAlreadyVisible()) {
                                resumeNextActivity = false;
                                resumeNextActivity = false;
                            }
                            }
                        } else {
                        } else {
                            r.makeVisibleIfNeeded(starting);
                            r.makeVisibleIfNeeded(starting, notifyClients);
                        }
                        }
                        // Aggregate current change flags.
                        // Aggregate current change flags.
                        configChanges |= r.configChangeFlags;
                        configChanges |= r.configChangeFlags;
@@ -3835,7 +3839,7 @@ class ActivityStack<T extends StackWindowController> extends ConfigurationContai
            if (finishingActivityInNonFocusedStack) {
            if (finishingActivityInNonFocusedStack) {
                // Finishing activity that was in paused state and it was in not currently focused
                // Finishing activity that was in paused state and it was in not currently focused
                // stack, need to make something visible in its place.
                // stack, need to make something visible in its place.
                mStackSupervisor.ensureVisibilityAndConfig(null, mDisplayId,
                mStackSupervisor.ensureVisibilityAndConfig(next, mDisplayId,
                        false /* markFrozenIfConfigChanged */, true /* deferResume */);
                        false /* markFrozenIfConfigChanged */, true /* deferResume */);
            }
            }
            if (activityRemoved) {
            if (activityRemoved) {
+19 −10
Original line number Original line Diff line number Diff line
@@ -1628,27 +1628,36 @@ public class ActivityStackSupervisor extends ConfigurationContainer implements D


    /**
    /**
     * Ensure all activities visibility, update orientation and configuration.
     * Ensure all activities visibility, update orientation and configuration.
     *
     * @param starting The currently starting activity or {@code null} if there is none.
     * @param displayId The id of the display where operation is executed.
     * @param markFrozenIfConfigChanged Whether to set {@link ActivityRecord#frozenBeforeDestroy} to
     *                                  {@code true} if config changed.
     * @param deferResume Whether to defer resume while updating config.
     */
     */
    boolean ensureVisibilityAndConfig(ActivityRecord r, int displayId,
    boolean ensureVisibilityAndConfig(ActivityRecord starting, int displayId,
            boolean markFrozenIfConfigChanged, boolean deferResume) {
            boolean markFrozenIfConfigChanged, boolean deferResume) {
        // First ensure visibility without updating the config just yet. We need this to know what
        // First ensure visibility without updating the config just yet. We need this to know what
        // activities are affecting configuration now.
        // activities are affecting configuration now.
        // Passing null here for 'starting' param value, so that visibility of actual starting
        // activity will be properly updated.
        ensureActivitiesVisibleLocked(null /* starting */, 0 /* configChanges */,
        ensureActivitiesVisibleLocked(null /* starting */, 0 /* configChanges */,
                false /* preserveWindows */, false /* updateConfiguration */);
                false /* preserveWindows */, false /* notifyClients */);


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


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


    private void logIfTransactionTooLarge(Intent intent, Bundle icicle) {
    private void logIfTransactionTooLarge(Intent intent, Bundle icicle) {
@@ -3681,14 +3690,14 @@ public class ActivityStackSupervisor extends ConfigurationContainer implements D
    void ensureActivitiesVisibleLocked(ActivityRecord starting, int configChanges,
    void ensureActivitiesVisibleLocked(ActivityRecord starting, int configChanges,
            boolean preserveWindows) {
            boolean preserveWindows) {
        ensureActivitiesVisibleLocked(starting, configChanges, preserveWindows,
        ensureActivitiesVisibleLocked(starting, configChanges, preserveWindows,
                true /* updateConfiguration */);
                true /* notifyClients */);
    }
    }


    /**
    /**
     * @see #ensureActivitiesVisibleLocked(ActivityRecord, int, boolean)
     * @see #ensureActivitiesVisibleLocked(ActivityRecord, int, boolean)
     */
     */
    void ensureActivitiesVisibleLocked(ActivityRecord starting, int configChanges,
    void ensureActivitiesVisibleLocked(ActivityRecord starting, int configChanges,
            boolean preserveWindows, boolean updateConfiguration) {
            boolean preserveWindows, boolean notifyClients) {
        getKeyguardController().beginActivityVisibilityUpdate();
        getKeyguardController().beginActivityVisibilityUpdate();
        try {
        try {
            // First the front stacks. In case any are not fullscreen and are in front of home.
            // First the front stacks. In case any are not fullscreen and are in front of home.
@@ -3697,7 +3706,7 @@ public class ActivityStackSupervisor extends ConfigurationContainer implements D
                for (int stackNdx = display.getChildCount() - 1; stackNdx >= 0; --stackNdx) {
                for (int stackNdx = display.getChildCount() - 1; stackNdx >= 0; --stackNdx) {
                    final ActivityStack stack = display.getChildAt(stackNdx);
                    final ActivityStack stack = display.getChildAt(stackNdx);
                    stack.ensureActivitiesVisibleLocked(starting, configChanges, preserveWindows,
                    stack.ensureActivitiesVisibleLocked(starting, configChanges, preserveWindows,
                            updateConfiguration);
                            notifyClients);
                }
                }
            }
            }
        } finally {
        } finally {
+4 −4
Original line number Original line Diff line number Diff line
@@ -131,7 +131,7 @@ public class ActivityRecordTests extends ActivityTestsBase {
        mActivity.setState(STOPPED, "testPausingWhenVisibleFromStopped");
        mActivity.setState(STOPPED, "testPausingWhenVisibleFromStopped");


        // The activity is in the focused stack so it should not move to paused.
        // The activity is in the focused stack so it should not move to paused.
        mActivity.makeVisibleIfNeeded(null /* starting */);
        mActivity.makeVisibleIfNeeded(null /* starting */, true /* reportToClient */);
        assertTrue(mActivity.isState(STOPPED));
        assertTrue(mActivity.isState(STOPPED));
        assertFalse(pauseFound.value);
        assertFalse(pauseFound.value);


@@ -139,14 +139,14 @@ public class ActivityRecordTests extends ActivityTestsBase {
        mActivity.mStackSupervisor.mFocusedStack = null;
        mActivity.mStackSupervisor.mFocusedStack = null;


        // In the unfocused stack, the activity should move to paused.
        // In the unfocused stack, the activity should move to paused.
        mActivity.makeVisibleIfNeeded(null /* starting */);
        mActivity.makeVisibleIfNeeded(null /* starting */, true /* reportToClient */);
        assertTrue(mActivity.isState(PAUSING));
        assertTrue(mActivity.isState(PAUSING));
        assertTrue(pauseFound.value);
        assertTrue(pauseFound.value);


        // Make sure that the state does not change for current non-stopping states.
        // Make sure that the state does not change for current non-stopping states.
        mActivity.setState(INITIALIZING, "testPausingWhenVisibleFromStopped");
        mActivity.setState(INITIALIZING, "testPausingWhenVisibleFromStopped");


        mActivity.makeVisibleIfNeeded(null /* starting */);
        mActivity.makeVisibleIfNeeded(null /* starting */, true /* reportToClient */);


        assertTrue(mActivity.isState(INITIALIZING));
        assertTrue(mActivity.isState(INITIALIZING));


@@ -156,7 +156,7 @@ public class ActivityRecordTests extends ActivityTestsBase {
        // Make sure that the state does not change when we have an activity becoming translucent
        // Make sure that the state does not change when we have an activity becoming translucent
        final ActivityRecord topActivity = new ActivityBuilder(mService).setTask(mTask).build();
        final ActivityRecord topActivity = new ActivityBuilder(mService).setTask(mTask).build();
        mStack.mTranslucentActivityWaiting = topActivity;
        mStack.mTranslucentActivityWaiting = topActivity;
        mActivity.makeVisibleIfNeeded(null /* starting */);
        mActivity.makeVisibleIfNeeded(null /* starting */, true /* reportToClient */);


        assertTrue(mActivity.isState(STOPPED));
        assertTrue(mActivity.isState(STOPPED));
    }
    }