Loading libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/BubbleExpandedView.java +12 −9 Original line number Diff line number Diff line Loading @@ -312,9 +312,13 @@ public class BubbleExpandedView extends LinearLayout { + " bubble=" + getBubbleKey()); } if (mBubble != null) { // Must post because this is called from a binder thread. post(() -> mController.removeBubble( mBubble.getKey(), Bubbles.DISMISS_TASK_FINISHED)); mController.removeBubble(mBubble.getKey(), Bubbles.DISMISS_TASK_FINISHED); } if (mTaskView != null) { // Release the surface mTaskView.release(); removeView(mTaskView); mTaskView = null; } } Loading Loading @@ -1058,8 +1062,10 @@ public class BubbleExpandedView extends LinearLayout { } /** * Cleans up anything related to the task and {@code TaskView}. If this view should be reused * after this method is called, then * Cleans up anything related to the task. The TaskView itself is released after the task * has been removed. * * If this view should be reused after this method is called, then * {@link #initialize(BubbleController, BubbleStackView, boolean)} must be invoked first. */ public void cleanUpExpandedState() { Loading @@ -1081,10 +1087,7 @@ public class BubbleExpandedView extends LinearLayout { } } if (mTaskView != null) { // Release the surface & other task view related things mTaskView.release(); removeView(mTaskView); mTaskView = null; mTaskView.setVisibility(GONE); } } Loading libs/WindowManager/Shell/src/com/android/wm/shell/taskview/TaskViewTaskController.java +21 −28 Original line number Diff line number Diff line Loading @@ -317,18 +317,12 @@ public class TaskViewTaskController implements ShellTaskOrganizer.TaskListener { // we know about -- so leave clean-up here even if shell transitions are enabled. if (mTaskToken == null || !mTaskToken.equals(taskInfo.token)) return; if (mListener != null) { final int taskId = taskInfo.taskId; mListenerExecutor.execute(() -> { mListener.onTaskRemovalStarted(taskId); }); } mTaskOrganizer.setInterceptBackPressedOnTaskRoot(mTaskToken, false); final SurfaceControl taskLeash = mTaskLeash; handleAndNotifyTaskRemoval(mTaskInfo); // Unparent the task when this surface is destroyed mTransaction.reparent(mTaskLeash, null).apply(); mTransaction.reparent(taskLeash, null).apply(); resetTaskInfo(); mTaskViewBase.onTaskVanished(taskInfo); } @Override Loading Loading @@ -498,6 +492,20 @@ public class TaskViewTaskController implements ShellTaskOrganizer.TaskListener { } } /** Notifies listeners of a task being removed and stops intercepting back presses on it. */ private void handleAndNotifyTaskRemoval(ActivityManager.RunningTaskInfo taskInfo) { if (taskInfo != null) { if (mListener != null) { final int taskId = taskInfo.taskId; mListenerExecutor.execute(() -> { mListener.onTaskRemovalStarted(taskId); }); } mTaskViewBase.onTaskVanished(taskInfo); mTaskOrganizer.setInterceptBackPressedOnTaskRoot(taskInfo.token, false); } } /** Returns the task info for the task in the TaskView. */ @Nullable public ActivityManager.RunningTaskInfo getTaskInfo() { Loading @@ -523,18 +531,12 @@ public class TaskViewTaskController implements ShellTaskOrganizer.TaskListener { */ 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); final ActivityManager.RunningTaskInfo pendingInfo = mPendingInfo; handleAndNotifyTaskRemoval(pendingInfo); // Make sure the task is removed WindowContainerTransaction wct = new WindowContainerTransaction(); wct.removeTask(mPendingInfo.token); wct.removeTask(pendingInfo.token); mTaskViewTransitions.closeTaskView(wct, this); } resetTaskInfo(); Loading @@ -559,16 +561,7 @@ public class TaskViewTaskController implements ShellTaskOrganizer.TaskListener { * is used instead. */ void prepareCloseAnimation() { if (mTaskToken != null) { if (mListener != null) { final int taskId = mTaskInfo.taskId; mListenerExecutor.execute(() -> { mListener.onTaskRemovalStarted(taskId); }); } mTaskViewBase.onTaskVanished(mTaskInfo); mTaskOrganizer.setInterceptBackPressedOnTaskRoot(mTaskToken, false); } handleAndNotifyTaskRemoval(mTaskInfo); resetTaskInfo(); } Loading libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/taskview/TaskViewTest.java +25 −0 Original line number Diff line number Diff line Loading @@ -607,4 +607,29 @@ public class TaskViewTest extends ShellTestCase { verify(mTaskViewTaskController).applyCaptionInsetsIfNeeded(); verify(mOrganizer).applyTransaction(any()); } @Test public void testReleaseInOnTaskRemoval_noNPE() { mTaskViewTaskController = spy(new TaskViewTaskController(mContext, mOrganizer, mTaskViewTransitions, mSyncQueue)); mTaskView = new TaskView(mContext, mTaskViewTaskController); mTaskView.setListener(mExecutor, new TaskView.Listener() { @Override public void onTaskRemovalStarted(int taskId) { mTaskView.release(); } }); WindowContainerTransaction wct = new WindowContainerTransaction(); mTaskViewTaskController.prepareOpenAnimation(true /* newTask */, new SurfaceControl.Transaction(), new SurfaceControl.Transaction(), mTaskInfo, mLeash, wct); mTaskView.surfaceCreated(mock(SurfaceHolder.class)); assertThat(mTaskViewTaskController.getTaskInfo()).isEqualTo(mTaskInfo); mTaskViewTaskController.prepareCloseAnimation(); assertThat(mTaskViewTaskController.getTaskInfo()).isNull(); } } Loading
libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/BubbleExpandedView.java +12 −9 Original line number Diff line number Diff line Loading @@ -312,9 +312,13 @@ public class BubbleExpandedView extends LinearLayout { + " bubble=" + getBubbleKey()); } if (mBubble != null) { // Must post because this is called from a binder thread. post(() -> mController.removeBubble( mBubble.getKey(), Bubbles.DISMISS_TASK_FINISHED)); mController.removeBubble(mBubble.getKey(), Bubbles.DISMISS_TASK_FINISHED); } if (mTaskView != null) { // Release the surface mTaskView.release(); removeView(mTaskView); mTaskView = null; } } Loading Loading @@ -1058,8 +1062,10 @@ public class BubbleExpandedView extends LinearLayout { } /** * Cleans up anything related to the task and {@code TaskView}. If this view should be reused * after this method is called, then * Cleans up anything related to the task. The TaskView itself is released after the task * has been removed. * * If this view should be reused after this method is called, then * {@link #initialize(BubbleController, BubbleStackView, boolean)} must be invoked first. */ public void cleanUpExpandedState() { Loading @@ -1081,10 +1087,7 @@ public class BubbleExpandedView extends LinearLayout { } } if (mTaskView != null) { // Release the surface & other task view related things mTaskView.release(); removeView(mTaskView); mTaskView = null; mTaskView.setVisibility(GONE); } } Loading
libs/WindowManager/Shell/src/com/android/wm/shell/taskview/TaskViewTaskController.java +21 −28 Original line number Diff line number Diff line Loading @@ -317,18 +317,12 @@ public class TaskViewTaskController implements ShellTaskOrganizer.TaskListener { // we know about -- so leave clean-up here even if shell transitions are enabled. if (mTaskToken == null || !mTaskToken.equals(taskInfo.token)) return; if (mListener != null) { final int taskId = taskInfo.taskId; mListenerExecutor.execute(() -> { mListener.onTaskRemovalStarted(taskId); }); } mTaskOrganizer.setInterceptBackPressedOnTaskRoot(mTaskToken, false); final SurfaceControl taskLeash = mTaskLeash; handleAndNotifyTaskRemoval(mTaskInfo); // Unparent the task when this surface is destroyed mTransaction.reparent(mTaskLeash, null).apply(); mTransaction.reparent(taskLeash, null).apply(); resetTaskInfo(); mTaskViewBase.onTaskVanished(taskInfo); } @Override Loading Loading @@ -498,6 +492,20 @@ public class TaskViewTaskController implements ShellTaskOrganizer.TaskListener { } } /** Notifies listeners of a task being removed and stops intercepting back presses on it. */ private void handleAndNotifyTaskRemoval(ActivityManager.RunningTaskInfo taskInfo) { if (taskInfo != null) { if (mListener != null) { final int taskId = taskInfo.taskId; mListenerExecutor.execute(() -> { mListener.onTaskRemovalStarted(taskId); }); } mTaskViewBase.onTaskVanished(taskInfo); mTaskOrganizer.setInterceptBackPressedOnTaskRoot(taskInfo.token, false); } } /** Returns the task info for the task in the TaskView. */ @Nullable public ActivityManager.RunningTaskInfo getTaskInfo() { Loading @@ -523,18 +531,12 @@ public class TaskViewTaskController implements ShellTaskOrganizer.TaskListener { */ 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); final ActivityManager.RunningTaskInfo pendingInfo = mPendingInfo; handleAndNotifyTaskRemoval(pendingInfo); // Make sure the task is removed WindowContainerTransaction wct = new WindowContainerTransaction(); wct.removeTask(mPendingInfo.token); wct.removeTask(pendingInfo.token); mTaskViewTransitions.closeTaskView(wct, this); } resetTaskInfo(); Loading @@ -559,16 +561,7 @@ public class TaskViewTaskController implements ShellTaskOrganizer.TaskListener { * is used instead. */ void prepareCloseAnimation() { if (mTaskToken != null) { if (mListener != null) { final int taskId = mTaskInfo.taskId; mListenerExecutor.execute(() -> { mListener.onTaskRemovalStarted(taskId); }); } mTaskViewBase.onTaskVanished(mTaskInfo); mTaskOrganizer.setInterceptBackPressedOnTaskRoot(mTaskToken, false); } handleAndNotifyTaskRemoval(mTaskInfo); resetTaskInfo(); } Loading
libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/taskview/TaskViewTest.java +25 −0 Original line number Diff line number Diff line Loading @@ -607,4 +607,29 @@ public class TaskViewTest extends ShellTestCase { verify(mTaskViewTaskController).applyCaptionInsetsIfNeeded(); verify(mOrganizer).applyTransaction(any()); } @Test public void testReleaseInOnTaskRemoval_noNPE() { mTaskViewTaskController = spy(new TaskViewTaskController(mContext, mOrganizer, mTaskViewTransitions, mSyncQueue)); mTaskView = new TaskView(mContext, mTaskViewTaskController); mTaskView.setListener(mExecutor, new TaskView.Listener() { @Override public void onTaskRemovalStarted(int taskId) { mTaskView.release(); } }); WindowContainerTransaction wct = new WindowContainerTransaction(); mTaskViewTaskController.prepareOpenAnimation(true /* newTask */, new SurfaceControl.Transaction(), new SurfaceControl.Transaction(), mTaskInfo, mLeash, wct); mTaskView.surfaceCreated(mock(SurfaceHolder.class)); assertThat(mTaskViewTaskController.getTaskInfo()).isEqualTo(mTaskInfo); mTaskViewTaskController.prepareCloseAnimation(); assertThat(mTaskViewTaskController.getTaskInfo()).isNull(); } }