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

Commit 0f3698c8 authored by Winson Chung's avatar Winson Chung Committed by Android (Google) Code Review
Browse files

Merge "Cancel any recents animation whenever a display's stack order changes" into pi-dev

parents 70c9a791 0f7ec96b
Loading
Loading
Loading
Loading
+39 −2
Original line number Diff line number Diff line
@@ -78,9 +78,13 @@ class ActivityDisplay extends ConfigurationContainer<ActivityStack>
    int mDisplayId;
    Display mDisplay;

    /** All of the stacks on this display. Order matters, topmost stack is in front of all other
     * stacks, bottommost behind. Accessed directly by ActivityManager package classes */
    /**
     * All of the stacks on this display. Order matters, topmost stack is in front of all other
     * stacks, bottommost behind. Accessed directly by ActivityManager package classes. Any calls
     * changing the list should also call {@link #onStackOrderChanged()}.
     */
    private final ArrayList<ActivityStack> mStacks = new ArrayList<>();
    private ArrayList<OnStackOrderChangedListener> mStackOrderChangedCallbacks = new ArrayList<>();

    /** Array of all UIDs that are present on the display. */
    private IntArray mDisplayAccessUIDs = new IntArray();
@@ -145,6 +149,7 @@ class ActivityDisplay extends ConfigurationContainer<ActivityStack>
        mStacks.remove(stack);
        removeStackReferenceIfNeeded(stack);
        mSupervisor.mService.updateSleepIfNeededLocked();
        onStackOrderChanged();
    }

    void positionChildAtTop(ActivityStack stack) {
@@ -163,6 +168,7 @@ class ActivityDisplay extends ConfigurationContainer<ActivityStack>
        mStacks.add(insertPosition, stack);
        mWindowContainerController.positionChildAt(stack.getWindowContainerController(),
                insertPosition);
        onStackOrderChanged();
    }

    private int getTopInsertPosition(ActivityStack stack, int candidatePosition) {
@@ -770,6 +776,30 @@ class ActivityDisplay extends ConfigurationContainer<ActivityStack>
        mSleeping = asleep;
    }

    /**
     * Adds a listener to be notified whenever the stack order in the display changes. Currently
     * only used by the {@link RecentsAnimation} to determine whether to interrupt and cancel the
     * current animation when the system state changes.
     */
    void registerStackOrderChangedListener(OnStackOrderChangedListener listener) {
        if (!mStackOrderChangedCallbacks.contains(listener)) {
            mStackOrderChangedCallbacks.add(listener);
        }
    }

    /**
     * Removes a previously registered stack order change listener.
     */
    void unregisterStackOrderChangedListener(OnStackOrderChangedListener listener) {
        mStackOrderChangedCallbacks.remove(listener);
    }

    private void onStackOrderChanged() {
        for (int i = mStackOrderChangedCallbacks.size() - 1; i >= 0; i--) {
            mStackOrderChangedCallbacks.get(i).onStackOrderChanged();
        }
    }

    public void dump(PrintWriter pw, String prefix) {
        pw.println(prefix + "displayId=" + mDisplayId + " stacks=" + mStacks.size());
        final String myPrefix = prefix + " ";
@@ -806,4 +836,11 @@ class ActivityDisplay extends ConfigurationContainer<ActivityStack>
        }
        proto.end(token);
    }

    /**
     * Callback for when the order of the stacks in the display changes.
     */
    interface OnStackOrderChangedListener {
        void onStackOrderChanged();
    }
}
+3 −7
Original line number Diff line number Diff line
@@ -5291,14 +5291,9 @@ public class ActivityManagerService extends IActivityManager.Stub
        final int callingPid = Binder.getCallingPid();
        final long origId = Binder.clearCallingIdentity();
        try {
            final int recentsUid;
            final String recentsPackage;
            final List<IBinder> topVisibleActivities;
            synchronized (this) {
                final ComponentName recentsComponent = mRecentTasks.getRecentsComponent();
                recentsPackage = recentsComponent.getPackageName();
                recentsUid = mRecentTasks.getRecentsComponentUid();
                topVisibleActivities = mStackSupervisor.getTopVisibleActivities();
                final int recentsUid = mRecentTasks.getRecentsComponentUid();
                // Start a new recents animation
                final RecentsAnimation anim = new RecentsAnimation(this, mStackSupervisor,
@@ -5314,13 +5309,14 @@ public class ActivityManagerService extends IActivityManager.Stub
    @Override
    public void cancelRecentsAnimation(boolean restoreHomeStackPosition) {
        enforceCallerIsRecentsOrHasPermission(MANAGE_ACTIVITY_STACKS, "cancelRecentsAnimation()");
        final long callingUid = Binder.getCallingUid();
        final long origId = Binder.clearCallingIdentity();
        try {
            synchronized (this) {
                // Cancel the recents animation synchronously (do not hold the WM lock)
                mWindowManager.cancelRecentsAnimationSynchronously(restoreHomeStackPosition
                        ? REORDER_MOVE_TO_ORIGINAL_POSITION
                        : REORDER_KEEP_IN_PLACE, "cancelRecentsAnimation");
                        : REORDER_KEEP_IN_PLACE, "cancelRecentsAnimation/uid=" + callingUid);
            }
        } finally {
            Binder.restoreCallingIdentity(origId);
+20 −7
Original line number Diff line number Diff line
@@ -49,7 +49,8 @@ import com.android.server.wm.WindowManagerService;
 * Manages the recents animation, including the reordering of the stacks for the transition and
 * cleanup. See {@link com.android.server.wm.RecentsAnimationController}.
 */
class RecentsAnimation implements RecentsAnimationCallbacks {
class RecentsAnimation implements RecentsAnimationCallbacks,
        ActivityDisplay.OnStackOrderChangedListener {
    private static final String TAG = RecentsAnimation.class.getSimpleName();
    // TODO (b/73188263): Reset debugging flags
    private static final boolean DEBUG = true;
@@ -140,13 +141,11 @@ class RecentsAnimation implements RecentsAnimationCallbacks {
                        recentsUid, recentsComponent.getPackageName());
            }

            final ActivityDisplay display;
            if (hasExistingActivity) {
                // Move the recents activity into place for the animation if it is not top most
                display = targetActivity.getDisplay();
                display.moveStackBehindBottomMostVisibleStack(targetStack);
                mDefaultDisplay.moveStackBehindBottomMostVisibleStack(targetStack);
                if (DEBUG) Slog.d(TAG, "Moved stack=" + targetStack + " behind stack="
                            + display.getStackAbove(targetStack));
                            + mDefaultDisplay.getStackAbove(targetStack));

                // If there are multiple tasks in the target stack (ie. the home stack, with 3p
                // and default launchers coexisting), then move the task to the top as a part of
@@ -173,7 +172,6 @@ class RecentsAnimation implements RecentsAnimationCallbacks {

                targetActivity = mDefaultDisplay.getStack(WINDOWING_MODE_UNDEFINED,
                        mTargetActivityType).getTopActivity();
                display = targetActivity.getDisplay();

                // TODO: Maybe wait for app to draw in this particular case?

@@ -190,7 +188,8 @@ class RecentsAnimation implements RecentsAnimationCallbacks {
            mWindowManager.cancelRecentsAnimationSynchronously(REORDER_MOVE_TO_ORIGINAL_POSITION,
                    "startRecentsActivity");
            mWindowManager.initializeRecentsAnimation(mTargetActivityType, recentsAnimationRunner,
                    this, display.mDisplayId, mStackSupervisor.mRecentTasks.getRecentTaskIds());
                    this, mDefaultDisplay.mDisplayId,
                    mStackSupervisor.mRecentTasks.getRecentTaskIds());

            // If we updated the launch-behind state, update the visibility of the activities after
            // we fetch the visible tasks to be controlled by the animation
@@ -198,6 +197,9 @@ class RecentsAnimation implements RecentsAnimationCallbacks {

            mStackSupervisor.getActivityMetricsLogger().notifyActivityLaunched(START_TASK_TO_FRONT,
                    targetActivity);

            // Register for stack order changes
            mDefaultDisplay.registerStackOrderChangedListener(this);
        } catch (Exception e) {
            Slog.e(TAG, "Failed to start recents activity", e);
            throw e;
@@ -219,6 +221,9 @@ class RecentsAnimation implements RecentsAnimationCallbacks {
                mAssistDataRequester = null;
            }

            // Unregister for stack order changes
            mDefaultDisplay.unregisterStackOrderChangedListener(this);

            if (mWindowManager.getRecentsAnimationController() == null) return;

            // Just to be sure end the launch hint in case the target activity was never launched.
@@ -316,6 +321,14 @@ class RecentsAnimation implements RecentsAnimationCallbacks {
        }
    }

    @Override
    public void onStackOrderChanged() {
        // If the activity display stack order changes, cancel any running recents animation in
        // place
        mWindowManager.cancelRecentsAnimationSynchronously(REORDER_KEEP_IN_PLACE,
                "stackOrderChanged");
    }

    /**
     * Called only when the animation should be canceled prior to starting.
     */
+0 −8
Original line number Diff line number Diff line
@@ -6092,14 +6092,6 @@ public class PhoneWindowManager implements WindowManagerPolicy {
                && (!isNavBarVirtKey || mNavBarVirtualKeyHapticFeedbackEnabled)
                && event.getRepeatCount() == 0;

        // Cancel any pending remote recents animations before handling the button itself. In the
        // case where we are going home and the recents animation has already started, just cancel
        // the recents animation, leaving the home stack in place for the pending start activity
        if (isNavBarVirtKey && !down && !canceled) {
            boolean isHomeKey = keyCode == KeyEvent.KEYCODE_HOME;
            mActivityManagerInternal.cancelRecentsAnimation(!isHomeKey);
        }

        // Handle special keys.
        switch (keyCode) {
            case KeyEvent.KEYCODE_BACK: {
+50 −0
Original line number Diff line number Diff line
@@ -565,6 +565,47 @@ public class ActivityStackTests extends ActivityTestsBase {
                false /* displaySleeping */, false /* expected*/);
    }

    @Test
    public void testStackOrderChangedOnRemoveStack() throws Exception {
        StackOrderChangedListener listener = new StackOrderChangedListener();
        mDefaultDisplay.registerStackOrderChangedListener(listener);
        try {
            mDefaultDisplay.removeChild(mStack);
        } finally {
            mDefaultDisplay.unregisterStackOrderChangedListener(listener);
        }
        assertTrue(listener.changed);
    }

    @Test
    public void testStackOrderChangedOnAddPositionStack() throws Exception {
        mDefaultDisplay.removeChild(mStack);

        StackOrderChangedListener listener = new StackOrderChangedListener();
        mDefaultDisplay.registerStackOrderChangedListener(listener);
        try {
            mDefaultDisplay.addChild(mStack, 0);
        } finally {
            mDefaultDisplay.unregisterStackOrderChangedListener(listener);
        }
        assertTrue(listener.changed);
    }

    @Test
    public void testStackOrderChangedOnPositionStack() throws Exception {
        StackOrderChangedListener listener = new StackOrderChangedListener();
        try {
            final TestActivityStack fullscreenStack1 = createStackForShouldBeVisibleTest(
                    mDefaultDisplay, WINDOWING_MODE_FULLSCREEN, ACTIVITY_TYPE_STANDARD,
                    true /* onTop */);
            mDefaultDisplay.registerStackOrderChangedListener(listener);
            mDefaultDisplay.positionChildAtBottom(fullscreenStack1);
        } finally {
            mDefaultDisplay.unregisterStackOrderChangedListener(listener);
        }
        assertTrue(listener.changed);
    }

    private void verifyShouldSleepActivities(boolean focusedStack,
            boolean keyguardGoingAway, boolean displaySleeping, boolean expected) {
        mSupervisor.mFocusedStack = focusedStack ? mStack : null;
@@ -578,4 +619,13 @@ public class ActivityStackTests extends ActivityTestsBase {

        assertEquals(expected, mStack.shouldSleepActivities());
    }

    private class StackOrderChangedListener implements ActivityDisplay.OnStackOrderChangedListener {
        boolean changed = false;

        @Override
        public void onStackOrderChanged() {
            changed = true;
        }
    }
}
Loading