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

Commit e267f46e authored by Issei Suzuki's avatar Issei Suzuki
Browse files

Use visible activity for remote animation target if available.

When creating a remote animation target for recents animation, the old
logic choose an activity which becomes visible soon (i.e.
ActivityRecord#mVisibleRequested=true). However, in the following
scenario, activity_b is to-be-visible soon, but doesn't have window yet.

1. activity_a launches activity_b
2. immediately after this, a user starts recents.

In this case, we should use activity_a whose window is already displayed
on the screen even though the activity is to-be-invisible soon.

Bug: 223499269
Bug: 231711212
Test: atest RecentsAnimationControllerTest
Change-Id: Ifeb0a18fe386d1d604e3092728e660ffaf0e6f27
parent d49b5d44
Loading
Loading
Loading
Loading
+4 −1
Original line number Diff line number Diff line
@@ -1197,7 +1197,10 @@ public class RecentsAnimationController implements DeathRecipient {
         *                     this is the target task, CLOSING otherwise).
         */
        RemoteAnimationTarget createRemoteAnimationTarget(int overrideTaskId, int overrideMode) {
            final ActivityRecord topApp = mTask.getTopVisibleActivity();
            ActivityRecord topApp = mTask.getTopRealVisibleActivity();
            if (topApp == null) {
                topApp = mTask.getTopVisibleActivity();
            }
            final WindowState mainWindow = topApp != null
                    ? topApp.findMainWindow()
                    : null;
+15 −4
Original line number Diff line number Diff line
@@ -3070,11 +3070,22 @@ class Task extends TaskFragment {
        });
    }

    /**
     * Return the top visible requested activity. The activity has been requested to be visible,
     * but it's possible that the activity has just been created, so no window is yet attached to
     * this activity.
     */
    ActivityRecord getTopVisibleActivity() {
        return getActivity((r) -> {
            // skip hidden (or about to hide) apps
            return !r.mIsExiting && r.isClientVisible() && r.mVisibleRequested;
        });
        return getActivity((r) -> !r.mIsExiting && r.isClientVisible() && r.mVisibleRequested);
    }

    /**
     * Return the top visible activity. The activity has a window on which contents are drawn.
     * However it's possible that the activity has already been requested to be invisible, but the
     * visibility is not yet committed.
     */
    ActivityRecord getTopRealVisibleActivity() {
        return getActivity((r) -> !r.mIsExiting && r.isClientVisible() && r.isVisible());
    }

    ActivityRecord getTopWaitSplashScreenActivity() {
+25 −0
Original line number Diff line number Diff line
@@ -61,6 +61,7 @@ import android.platform.test.annotations.Presubmit;
import android.util.SparseBooleanArray;
import android.view.IRecentsAnimationRunner;
import android.view.SurfaceControl;
import android.view.WindowManager.LayoutParams;
import android.window.TaskSnapshot;

import androidx.test.filters.SmallTest;
@@ -161,6 +162,30 @@ public class RecentsAnimationControllerTest extends WindowTestsBase {
        assertFalse(mController.isAnimatingTask(hiddenActivity.getTask()));
    }

    @Test
    public void testLaunchAndStartRecents_expectTargetAndVisible() throws Exception {
        mWm.setRecentsAnimationController(mController);
        final ActivityRecord homeActivity = createHomeActivity();
        final Task task = createTask(mDefaultDisplay);
        // Emulate that activity1 has just launched activity2, but app transition has not yet been
        // executed.
        final ActivityRecord activity1 = createActivityRecord(task);
        activity1.setVisible(true);
        activity1.mVisibleRequested = false;
        activity1.addWindow(createWindowState(new LayoutParams(TYPE_BASE_APPLICATION), activity1));

        final ActivityRecord activity2 = createActivityRecord(task);
        activity2.setVisible(false);
        activity2.mVisibleRequested = true;

        mDefaultDisplay.getConfiguration().windowConfiguration.setRotation(
                mDefaultDisplay.getRotation());
        initializeRecentsAnimationController(mController, homeActivity);
        mController.startAnimation();
        verify(mMockRunner, never()).onAnimationCanceled(null /* taskIds */,
                null /* taskSnapshots */);
    }

    @Test
    public void testWallpaperIncluded_expectTarget() throws Exception {
        mWm.setRecentsAnimationController(mController);