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

Commit 65d66d3e authored by Winson Chung's avatar Winson Chung
Browse files

Only cancel the recents anim upon visible stack order change

- We previously canceled the animation for all stack order changes,
  but if we keep an activity running while in Recents, then there
  are transparent changes (ie. when a task is dismissed) where we
  don't want to trigger the current recents animation to be canceled.

  If the change is from a stack that is not visible, then keep the
  current animation running.

Bug: 120426277
Test: atest WmTests:RecentsAnimationTest

Change-Id: I7d57999cc5f249ccfcc2f9d0a198385524024a67
parent ccb3c070
Loading
Loading
Loading
Loading
+9 −5
Original line number Diff line number Diff line
@@ -212,7 +212,7 @@ class ActivityDisplay extends ConfigurationContainer<ActivityStack>
        removeStackReferenceIfNeeded(stack);
        releaseSelfIfNeeded();
        mService.updateSleepIfNeededLocked();
        onStackOrderChanged();
        onStackOrderChanged(stack);
    }

    void positionChildAtTop(ActivityStack stack, boolean includingParents) {
@@ -280,7 +280,7 @@ class ActivityDisplay extends ConfigurationContainer<ActivityStack>
        if (!wasContained) {
            stack.setParent(this);
        }
        onStackOrderChanged();
        onStackOrderChanged(stack);
    }

    private int getTopInsertPosition(ActivityStack stack, int candidatePosition) {
@@ -1309,9 +1309,13 @@ class ActivityDisplay extends ConfigurationContainer<ActivityStack>
        mStackOrderChangedCallbacks.remove(listener);
    }

    private void onStackOrderChanged() {
    /**
     * Notifies of a stack order change
     * @param stack The stack which triggered the order change
     */
    private void onStackOrderChanged(ActivityStack stack) {
        for (int i = mStackOrderChangedCallbacks.size() - 1; i >= 0; i--) {
            mStackOrderChangedCallbacks.get(i).onStackOrderChanged();
            mStackOrderChangedCallbacks.get(i).onStackOrderChanged(stack);
        }
    }

@@ -1390,6 +1394,6 @@ class ActivityDisplay extends ConfigurationContainer<ActivityStack>
     * Callback for when the order of the stacks in the display changes.
     */
    interface OnStackOrderChangedListener {
        void onStackOrderChanged();
        void onStackOrderChanged(ActivityStack stack);
    }
}
+8 −2
Original line number Diff line number Diff line
@@ -387,7 +387,13 @@ class RecentsAnimation implements RecentsAnimationCallbacks,
    }

    @Override
    public void onStackOrderChanged() {
    public void onStackOrderChanged(ActivityStack stack) {
        if (DEBUG) Slog.d(TAG, "onStackOrderChanged(): stack=" + stack);
        if (mDefaultDisplay.getIndexOf(stack) == -1 || !stack.shouldBeVisible(null)) {
            // The stack is not visible, so ignore this change
            return;
        }

        // If the activity display stack order changes, cancel any running recents animation in
        // place
        mWindowManager.cancelRecentsAnimationSynchronously(REORDER_KEEP_IN_PLACE,
@@ -429,7 +435,7 @@ class RecentsAnimation implements RecentsAnimationCallbacks,
        }

        for (int i = targetStack.getChildCount() - 1; i >= 0; i--) {
            final TaskRecord task = (TaskRecord) targetStack.getChildAt(i);
            final TaskRecord task = targetStack.getChildAt(i);
            if (task.getBaseIntent().getComponent().equals(component)) {
                return task.getTopActivity();
            }
+1 −1
Original line number Diff line number Diff line
@@ -797,7 +797,7 @@ public class ActivityStackTests extends ActivityTestsBase {
        public boolean mChanged = false;

        @Override
        public void onStackOrderChanged() {
        public void onStackOrderChanged(ActivityStack stack) {
            mChanged = true;
        }
    }
+54 −13
Original line number Diff line number Diff line
@@ -24,7 +24,6 @@ import static com.android.dx.mockito.inline.extended.ExtendedMockito.any;
import static com.android.dx.mockito.inline.extended.ExtendedMockito.doReturn;
import static com.android.dx.mockito.inline.extended.ExtendedMockito.eq;
import static com.android.dx.mockito.inline.extended.ExtendedMockito.mock;
import static com.android.dx.mockito.inline.extended.ExtendedMockito.spy;
import static com.android.dx.mockito.inline.extended.ExtendedMockito.spyOn;
import static com.android.dx.mockito.inline.extended.ExtendedMockito.times;
import static com.android.dx.mockito.inline.extended.ExtendedMockito.verify;
@@ -65,22 +64,26 @@ public class RecentsAnimationTest extends ActivityTestsBase {
    }

    @Test
    public void testCancelAnimationOnStackOrderChange() {
        ActivityStack fullscreenStack =
                mService.mRootActivityContainer.getDefaultDisplay().createStack(
                        WINDOWING_MODE_FULLSCREEN, ACTIVITY_TYPE_STANDARD, true /* onTop */);
        ActivityStack recentsStack = mService.mRootActivityContainer.getDefaultDisplay().createStack(
                WINDOWING_MODE_FULLSCREEN, ACTIVITY_TYPE_RECENTS, true /* onTop */);
        ActivityRecord recentsActivity = new ActivityBuilder(mService)
    public void testCancelAnimationOnVisibleStackOrderChange() {
        ActivityDisplay display = mService.mRootActivityContainer.getDefaultDisplay();
        ActivityStack fullscreenStack = display.createStack(WINDOWING_MODE_FULLSCREEN,
                ACTIVITY_TYPE_STANDARD, true /* onTop */);
        new ActivityBuilder(mService)
                .setComponent(new ComponentName(mContext.getPackageName(), "App1"))
                .setCreateTask(true)
                .setStack(fullscreenStack)
                .build();
        ActivityStack recentsStack = display.createStack(WINDOWING_MODE_FULLSCREEN,
                ACTIVITY_TYPE_RECENTS, true /* onTop */);
        new ActivityBuilder(mService)
                .setComponent(mRecentsComponent)
                .setCreateTask(true)
                .setStack(recentsStack)
                .build();
        ActivityStack fullscreenStack2 =
                mService.mRootActivityContainer.getDefaultDisplay().createStack(
                        WINDOWING_MODE_FULLSCREEN, ACTIVITY_TYPE_STANDARD, true /* onTop */);
        ActivityRecord fsActivity = new ActivityBuilder(mService)
                .setComponent(new ComponentName(mContext.getPackageName(), "App1"))
        ActivityStack fullscreenStack2 = display.createStack(WINDOWING_MODE_FULLSCREEN,
                ACTIVITY_TYPE_STANDARD, true /* onTop */);
        new ActivityBuilder(mService)
                .setComponent(new ComponentName(mContext.getPackageName(), "App2"))
                .setCreateTask(true)
                .setStack(fullscreenStack2)
                .build();
@@ -97,4 +100,42 @@ public class RecentsAnimationTest extends ActivityTestsBase {
        verify(mService.mWindowManager, times(1)).cancelRecentsAnimationSynchronously(
                eq(REORDER_KEEP_IN_PLACE), any());
    }

    @Test
    public void testKeepAnimationOnHiddenStackOrderChange() {
        ActivityDisplay display = mService.mRootActivityContainer.getDefaultDisplay();
        ActivityStack fullscreenStack = display.createStack(WINDOWING_MODE_FULLSCREEN,
                ACTIVITY_TYPE_STANDARD, true /* onTop */);
        new ActivityBuilder(mService)
                .setComponent(new ComponentName(mContext.getPackageName(), "App1"))
                .setCreateTask(true)
                .setStack(fullscreenStack)
                .build();
        ActivityStack recentsStack = display.createStack(WINDOWING_MODE_FULLSCREEN,
                ACTIVITY_TYPE_RECENTS, true /* onTop */);
        new ActivityBuilder(mService)
                .setComponent(mRecentsComponent)
                .setCreateTask(true)
                .setStack(recentsStack)
                .build();
        ActivityStack fullscreenStack2 = display.createStack(WINDOWING_MODE_FULLSCREEN,
                ACTIVITY_TYPE_STANDARD, true /* onTop */);
        new ActivityBuilder(mService)
                .setComponent(new ComponentName(mContext.getPackageName(), "App2"))
                .setCreateTask(true)
                .setStack(fullscreenStack2)
                .build();
        doReturn(true).when(mService.mWindowManager).canStartRecentsAnimation();

        // Start the recents animation
        Intent recentsIntent = new Intent();
        recentsIntent.setComponent(mRecentsComponent);
        mService.startRecentsActivity(recentsIntent, null, mock(IRecentsAnimationRunner.class));

        fullscreenStack.remove();

        // Ensure that the recents animation was NOT canceled
        verify(mService.mWindowManager, times(0)).cancelRecentsAnimationSynchronously(
                eq(REORDER_KEEP_IN_PLACE), any());
    }
}