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

Commit 3293cda2 authored by Mady Mellor's avatar Mady Mellor Committed by Automerger Merge Worker
Browse files

Merge "Track pending task info & if the task doesn't launch clean it up" into...

Merge "Track pending task info & if the task doesn't launch clean it up" into udc-dev am: b541d4cd

Original change: https://googleplex-android-review.googlesource.com/c/platform/frameworks/base/+/23482784



Change-Id: I9706dce8de573af6366ae1a913e47875e537a8be
Signed-off-by: default avatarAutomerger Merge Worker <android-build-automerger-merge-worker@system.gserviceaccount.com>
parents e6ed6c50 b541d4cd
Loading
Loading
Loading
Loading
+55 −0
Original line number Diff line number Diff line
@@ -61,6 +61,16 @@ public class TaskViewTaskController implements ShellTaskOrganizer.TaskListener {
    private TaskViewBase mTaskViewBase;
    private final Context mContext;

    /**
     * There could be a situation where we have task info and receive
     * {@link #onTaskAppeared(ActivityManager.RunningTaskInfo, SurfaceControl)}, however, the
     * activity might fail to open, and in this case we need to clean up the task view / notify
     * listeners of a task removal. This requires task info, so we save the info from onTaskAppeared
     * in this situation to allow us to notify listeners correctly if the task failed to open.
     */
    private ActivityManager.RunningTaskInfo mPendingInfo;
    /* Indicates that the task we attempted to launch in the task view failed to launch. */
    private boolean mTaskNotFound;
    protected ActivityManager.RunningTaskInfo mTaskInfo;
    private WindowContainerToken mTaskToken;
    private SurfaceControl mTaskLeash;
@@ -236,6 +246,8 @@ public class TaskViewTaskController implements ShellTaskOrganizer.TaskListener {
        mTaskInfo = null;
        mTaskToken = null;
        mTaskLeash = null;
        mPendingInfo = null;
        mTaskNotFound = false;
    }

    private void updateTaskVisibility() {
@@ -257,6 +269,12 @@ public class TaskViewTaskController implements ShellTaskOrganizer.TaskListener {
    public void onTaskAppeared(ActivityManager.RunningTaskInfo taskInfo,
            SurfaceControl leash) {
        if (isUsingShellTransitions()) {
            mPendingInfo = taskInfo;
            if (mTaskNotFound) {
                // If we were already notified by shell transit that we don't have the
                // the task, clean it up now.
                cleanUpPendingTask();
            }
            // Everything else handled by enter transition.
            return;
        }
@@ -455,6 +473,42 @@ public class TaskViewTaskController implements ShellTaskOrganizer.TaskListener {
        return mTaskInfo;
    }

    /**
     * Indicates that the task was not found in the start animation for the transition.
     * In this case we should clean up the task if we have the pending info. If we don't
     * have the pending info, we'll do it when we receive it in
     * {@link #onTaskAppeared(ActivityManager.RunningTaskInfo, SurfaceControl)}.
     */
    void setTaskNotFound() {
        mTaskNotFound = true;
        if (mPendingInfo != null) {
            cleanUpPendingTask();
        }
    }

    /**
     * Called when a task failed to open and we need to clean up task view /
     * notify users of task view.
     */
    void cleanUpPendingTask() {
        if (mPendingInfo != null) {
            if (mListener != null) {
                final int taskId = mPendingInfo.taskId;
                mListenerExecutor.execute(() -> {
                    mListener.onTaskRemovalStarted(taskId);
                });
            }
            mTaskViewBase.onTaskVanished(mPendingInfo);
            mTaskOrganizer.setInterceptBackPressedOnTaskRoot(mPendingInfo.token, false);

            // Make sure the task is removed
            WindowContainerTransaction wct = new WindowContainerTransaction();
            wct.removeTask(mPendingInfo.token);
            mTaskViewTransitions.closeTaskView(wct, this);
        }
        resetTaskInfo();
    }

    void prepareHideAnimation(@NonNull SurfaceControl.Transaction finishTransaction) {
        if (mTaskToken == null) {
            // Nothing to update, task is not yet available
@@ -492,6 +546,7 @@ public class TaskViewTaskController implements ShellTaskOrganizer.TaskListener {
            @NonNull SurfaceControl.Transaction finishTransaction,
            ActivityManager.RunningTaskInfo taskInfo, SurfaceControl leash,
            WindowContainerTransaction wct) {
        mPendingInfo = null;
        mTaskInfo = taskInfo;
        mTaskToken = mTaskInfo.token;
        mTaskLeash = leash;
+7 −5
Original line number Diff line number Diff line
@@ -139,7 +139,8 @@ public class TaskViewTransitions implements Transitions.TransitionHandler {
     * `taskView`.
     * @param taskView the pending transition should be for this.
     */
    private PendingTransition findPendingOpeningTransition(TaskViewTaskController taskView) {
    @VisibleForTesting
    PendingTransition findPendingOpeningTransition(TaskViewTaskController taskView) {
        for (int i = mPending.size() - 1; i >= 0; --i) {
            if (mPending.get(i).mTaskView != taskView) continue;
            if (TransitionUtil.isOpeningType(mPending.get(i).mType)) {
@@ -398,10 +399,11 @@ public class TaskViewTransitions implements Transitions.TransitionHandler {
            }
        }
        if (stillNeedsMatchingLaunch) {
            throw new IllegalStateException("Expected a TaskView launch in this transition but"
                    + " didn't get one.");
        }
        if (wct == null && pending == null && changesHandled != info.getChanges().size()) {
            Slog.w(TAG, "Expected a TaskView launch in this transition but didn't get one, "
                    + "cleaning up the task view");
            // Didn't find a task so the task must have never launched
            pending.mTaskView.setTaskNotFound();
        } else if (wct == null && pending == null && changesHandled != info.getChanges().size()) {
            // Just some house-keeping, let another handler animate.
            return false;
        }
+21 −2
Original line number Diff line number Diff line
@@ -128,8 +128,8 @@ public class TaskViewTest extends ShellTestCase {
            doReturn(true).when(mTransitions).isRegistered();
        }
        mTaskViewTransitions = spy(new TaskViewTransitions(mTransitions));
        mTaskViewTaskController = new TaskViewTaskController(mContext, mOrganizer,
                mTaskViewTransitions, mSyncQueue);
        mTaskViewTaskController = spy(new TaskViewTaskController(mContext, mOrganizer,
                mTaskViewTransitions, mSyncQueue));
        mTaskView = new TaskView(mContext, mTaskViewTaskController);
        mTaskView.setListener(mExecutor, mViewListener);
    }
@@ -544,4 +544,23 @@ public class TaskViewTest extends ShellTestCase {
        mTaskView.removeTask();
        verify(mTaskViewTransitions).closeTaskView(any(), eq(mTaskViewTaskController));
    }

    @Test
    public void testOnTaskAppearedWithTaskNotFound() {
        assumeTrue(Transitions.ENABLE_SHELL_TRANSITIONS);

        mTaskViewTaskController.setTaskNotFound();
        mTaskViewTaskController.onTaskAppeared(mTaskInfo, mLeash);

        verify(mTaskViewTaskController).cleanUpPendingTask();
        verify(mTaskViewTransitions).closeTaskView(any(), eq(mTaskViewTaskController));
    }

    @Test
    public void testOnTaskAppeared_withoutTaskNotFound() {
        assumeTrue(Transitions.ENABLE_SHELL_TRANSITIONS);

        mTaskViewTaskController.onTaskAppeared(mTaskInfo, mLeash);
        verify(mTaskViewTaskController, never()).cleanUpPendingTask();
    }
}
+35 −0
Original line number Diff line number Diff line
@@ -17,6 +17,7 @@
package com.android.wm.shell.taskview;

import static android.view.WindowManager.TRANSIT_CHANGE;
import static android.view.WindowManager.TRANSIT_OPEN;
import static android.view.WindowManager.TRANSIT_TO_FRONT;

import static com.google.common.truth.Truth.assertThat;
@@ -25,16 +26,19 @@ import static org.junit.Assume.assumeTrue;
import static org.mockito.Mockito.doReturn;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.spy;
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.when;

import android.app.ActivityManager;
import android.graphics.Rect;
import android.os.IBinder;
import android.test.suitebuilder.annotation.SmallTest;
import android.testing.AndroidTestingRunner;
import android.testing.TestableLooper;
import android.view.SurfaceControl;
import android.window.TransitionInfo;
import android.window.WindowContainerToken;
import android.window.WindowContainerTransaction;

import com.android.wm.shell.ShellTestCase;
import com.android.wm.shell.transition.Transitions;
@@ -45,6 +49,7 @@ import org.junit.runner.RunWith;
import org.mockito.Mock;
import org.mockito.MockitoAnnotations;

import java.util.ArrayList;
import java.util.List;

@SmallTest
@@ -295,4 +300,34 @@ public class TaskViewTransitionsTest extends ShellTestCase {
        mTaskViewTransitions.setTaskBounds(mTaskViewTaskController,
                new Rect(0, 0, 100, 100));
    }

    @Test
    public void test_startAnimation_setsTaskNotFound() {
        assumeTrue(Transitions.ENABLE_SHELL_TRANSITIONS);

        TransitionInfo.Change change = mock(TransitionInfo.Change.class);
        when(change.getTaskInfo()).thenReturn(mTaskInfo);
        when(change.getMode()).thenReturn(TRANSIT_OPEN);

        List<TransitionInfo.Change> changes = new ArrayList<>();
        changes.add(change);

        TransitionInfo info = mock(TransitionInfo.class);
        when(info.getChanges()).thenReturn(changes);

        mTaskViewTransitions.startTaskView(new WindowContainerTransaction(),
                mTaskViewTaskController,
                mock(IBinder.class));

        TaskViewTransitions.PendingTransition pending =
                mTaskViewTransitions.findPendingOpeningTransition(mTaskViewTaskController);

        mTaskViewTransitions.startAnimation(pending.mClaimed,
                info,
                new SurfaceControl.Transaction(),
                new SurfaceControl.Transaction(),
                mock(Transitions.TransitionFinishCallback.class));

        verify(mTaskViewTaskController).setTaskNotFound();
    }
}