Merge "Track pending task info & if the task doesn't launch clean it up" into udc-dev
This commit is contained in:
@@ -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;
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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();
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user