diff options
5 files changed, 107 insertions, 55 deletions
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/desktopmode/DesktopTasksController.kt b/libs/WindowManager/Shell/src/com/android/wm/shell/desktopmode/DesktopTasksController.kt index f8dd208f96db..09ba4f79326e 100644 --- a/libs/WindowManager/Shell/src/com/android/wm/shell/desktopmode/DesktopTasksController.kt +++ b/libs/WindowManager/Shell/src/com/android/wm/shell/desktopmode/DesktopTasksController.kt @@ -37,6 +37,7 @@ import android.view.WindowManager.TRANSIT_CHANGE import android.view.WindowManager.TRANSIT_NONE import android.view.WindowManager.TRANSIT_OPEN import android.view.WindowManager.TRANSIT_TO_FRONT +import android.window.RemoteTransition import android.window.TransitionInfo import android.window.TransitionRequestInfo import android.window.WindowContainerTransaction @@ -65,7 +66,9 @@ import com.android.wm.shell.sysui.ShellCommandHandler import com.android.wm.shell.sysui.ShellController import com.android.wm.shell.sysui.ShellInit import com.android.wm.shell.sysui.ShellSharedConstants +import com.android.wm.shell.transition.OneShotRemoteHandler import com.android.wm.shell.transition.Transitions +import com.android.wm.shell.transition.Transitions.TransitionHandler import com.android.wm.shell.util.KtProtoLog import com.android.wm.shell.windowdecor.DesktopModeWindowDecoration import com.android.wm.shell.windowdecor.MoveToDesktopAnimator @@ -139,20 +142,22 @@ class DesktopTasksController( } /** Show all tasks, that are part of the desktop, on top of launcher */ - fun showDesktopApps(displayId: Int) { + fun showDesktopApps(displayId: Int, remoteTransition: RemoteTransition? = null) { KtProtoLog.v(WM_SHELL_DESKTOP_MODE, "DesktopTasksController: showDesktopApps") val wct = WindowContainerTransaction() - // TODO(b/278084491): pass in display id bringDesktopAppsToFront(displayId, wct) - // Execute transaction if there are pending operations - if (!wct.isEmpty) { - if (Transitions.ENABLE_SHELL_TRANSITIONS) { - // TODO(b/268662477): add animation for the transition - transitions.startTransition(TRANSIT_NONE, wct, null /* handler */) - } else { - shellTaskOrganizer.applyTransaction(wct) + if (Transitions.ENABLE_SHELL_TRANSITIONS) { + // TODO(b/255649902): ensure remote transition is supplied once state is introduced + val transitionType = if (remoteTransition == null) TRANSIT_NONE else TRANSIT_TO_FRONT + val handler = remoteTransition?.let { + OneShotRemoteHandler(transitions.mainExecutor, remoteTransition) + } + transitions.startTransition(transitionType, wct, handler).also { t -> + handler?.setTransition(t) } + } else { + shellTaskOrganizer.applyTransaction(wct) } } @@ -1093,11 +1098,11 @@ class DesktopTasksController( controller = null } - override fun showDesktopApps(displayId: Int) { + override fun showDesktopApps(displayId: Int, remoteTransition: RemoteTransition?) { ExecutorUtils.executeRemoteCallWithTaskPermission( controller, "showDesktopApps" - ) { c -> c.showDesktopApps(displayId) } + ) { c -> c.showDesktopApps(displayId, remoteTransition) } } override fun stashDesktopApps(displayId: Int) { diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/desktopmode/IDesktopMode.aidl b/libs/WindowManager/Shell/src/com/android/wm/shell/desktopmode/IDesktopMode.aidl index 47edfd455f5a..6bdaf1eadb8a 100644 --- a/libs/WindowManager/Shell/src/com/android/wm/shell/desktopmode/IDesktopMode.aidl +++ b/libs/WindowManager/Shell/src/com/android/wm/shell/desktopmode/IDesktopMode.aidl @@ -17,6 +17,7 @@ package com.android.wm.shell.desktopmode; import android.app.ActivityManager.RunningTaskInfo; +import android.window.RemoteTransition; import com.android.wm.shell.desktopmode.IDesktopTaskListener; /** @@ -25,7 +26,7 @@ import com.android.wm.shell.desktopmode.IDesktopTaskListener; interface IDesktopMode { /** Show apps on the desktop on the given display */ - void showDesktopApps(int displayId); + void showDesktopApps(int displayId, in RemoteTransition remoteTransition); /** Stash apps on the desktop to allow launching another app from home screen */ void stashDesktopApps(int displayId); diff --git a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/TestRemoteTransition.java b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/TestRemoteTransition.java new file mode 100644 index 000000000000..0df42b3cc5e4 --- /dev/null +++ b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/TestRemoteTransition.java @@ -0,0 +1,59 @@ +/* + * Copyright (C) 2023 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package com.android.wm.shell; + +import android.os.IBinder; +import android.os.RemoteException; +import android.view.SurfaceControl; +import android.window.IRemoteTransition; +import android.window.IRemoteTransitionFinishedCallback; +import android.window.TransitionInfo; +import android.window.WindowContainerTransaction; + +/** + * {@link IRemoteTransition} for testing purposes. + * Stores info about + * {@link #startAnimation(IBinder, TransitionInfo, SurfaceControl.Transaction, + * IRemoteTransitionFinishedCallback)} being called. + */ +public class TestRemoteTransition extends IRemoteTransition.Stub { + private boolean mCalled = false; + final WindowContainerTransaction mRemoteFinishWCT = new WindowContainerTransaction(); + + @Override + public void startAnimation(IBinder transition, TransitionInfo info, + SurfaceControl.Transaction startTransaction, + IRemoteTransitionFinishedCallback finishCallback) + throws RemoteException { + mCalled = true; + finishCallback.onTransitionFinished(mRemoteFinishWCT, null /* sct */); + } + + @Override + public void mergeAnimation(IBinder transition, TransitionInfo info, + SurfaceControl.Transaction t, IBinder mergeTarget, + IRemoteTransitionFinishedCallback finishCallback) throws RemoteException { + } + + /** + * Check whether this remote transition + * {@link #startAnimation(IBinder, TransitionInfo, SurfaceControl.Transaction, + * IRemoteTransitionFinishedCallback)} is called + */ + public boolean isCalled() { + return mCalled; + } +} diff --git a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/desktopmode/DesktopTasksControllerTest.kt b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/desktopmode/DesktopTasksControllerTest.kt index c6cccc059e89..664fbb22b13b 100644 --- a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/desktopmode/DesktopTasksControllerTest.kt +++ b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/desktopmode/DesktopTasksControllerTest.kt @@ -28,10 +28,10 @@ import android.testing.AndroidTestingRunner import android.view.Display.DEFAULT_DISPLAY import android.view.WindowManager import android.view.WindowManager.TRANSIT_CHANGE -import android.view.WindowManager.TRANSIT_NONE import android.view.WindowManager.TRANSIT_OPEN import android.view.WindowManager.TRANSIT_TO_FRONT import android.window.DisplayAreaInfo +import android.window.RemoteTransition import android.window.TransitionRequestInfo import android.window.WindowContainerTransaction import android.window.WindowContainerTransaction.HierarchyOp.HIERARCHY_OP_TYPE_REORDER @@ -43,6 +43,7 @@ import com.android.wm.shell.MockToken import com.android.wm.shell.RootTaskDisplayAreaOrganizer import com.android.wm.shell.ShellTaskOrganizer import com.android.wm.shell.ShellTestCase +import com.android.wm.shell.TestRemoteTransition import com.android.wm.shell.TestRunningTaskInfoBuilder import com.android.wm.shell.TestShellExecutor import com.android.wm.shell.common.DisplayController @@ -57,8 +58,10 @@ import com.android.wm.shell.splitscreen.SplitScreenController import com.android.wm.shell.sysui.ShellCommandHandler import com.android.wm.shell.sysui.ShellController import com.android.wm.shell.sysui.ShellInit +import com.android.wm.shell.transition.OneShotRemoteHandler import com.android.wm.shell.transition.Transitions import com.android.wm.shell.transition.Transitions.ENABLE_SHELL_TRANSITIONS +import com.android.wm.shell.transition.Transitions.TransitionHandler import com.android.wm.shell.windowdecor.DesktopModeWindowDecoration import com.google.common.truth.Truth.assertThat import com.google.common.truth.Truth.assertWithMessage @@ -69,6 +72,7 @@ import org.junit.Test import org.junit.runner.RunWith import org.mockito.ArgumentCaptor import org.mockito.ArgumentMatchers.eq +import org.mockito.ArgumentMatchers.isA import org.mockito.ArgumentMatchers.isNull import org.mockito.Mock import org.mockito.Mockito @@ -174,9 +178,9 @@ class DesktopTasksControllerTest : ShellTestCase() { markTaskHidden(task1) markTaskHidden(task2) - controller.showDesktopApps(DEFAULT_DISPLAY) + controller.showDesktopApps(DEFAULT_DISPLAY, RemoteTransition(TestRemoteTransition())) - val wct = getLatestWct(expectTransition = TRANSIT_NONE) + val wct = getLatestWct(type = TRANSIT_OPEN, handlerClass = OneShotRemoteHandler::class.java) assertThat(wct.hierarchyOps).hasSize(3) // Expect order to be from bottom: home, task1, task2 wct.assertReorderAt(index = 0, homeTask) @@ -192,9 +196,9 @@ class DesktopTasksControllerTest : ShellTestCase() { markTaskVisible(task1) markTaskVisible(task2) - controller.showDesktopApps(DEFAULT_DISPLAY) + controller.showDesktopApps(DEFAULT_DISPLAY, RemoteTransition(TestRemoteTransition())) - val wct = getLatestWct(expectTransition = TRANSIT_NONE) + val wct = getLatestWct(type = TRANSIT_OPEN, handlerClass = OneShotRemoteHandler::class.java) assertThat(wct.hierarchyOps).hasSize(3) // Expect order to be from bottom: home, task1, task2 wct.assertReorderAt(index = 0, homeTask) @@ -210,9 +214,9 @@ class DesktopTasksControllerTest : ShellTestCase() { markTaskHidden(task1) markTaskVisible(task2) - controller.showDesktopApps(DEFAULT_DISPLAY) + controller.showDesktopApps(DEFAULT_DISPLAY, RemoteTransition(TestRemoteTransition())) - val wct = getLatestWct(expectTransition = TRANSIT_NONE) + val wct = getLatestWct(type = TRANSIT_OPEN, handlerClass = OneShotRemoteHandler::class.java) assertThat(wct.hierarchyOps).hasSize(3) // Expect order to be from bottom: home, task1, task2 wct.assertReorderAt(index = 0, homeTask) @@ -224,9 +228,9 @@ class DesktopTasksControllerTest : ShellTestCase() { fun showDesktopApps_noActiveTasks_reorderHomeToTop() { val homeTask = setUpHomeTask() - controller.showDesktopApps(DEFAULT_DISPLAY) + controller.showDesktopApps(DEFAULT_DISPLAY, RemoteTransition(TestRemoteTransition())) - val wct = getLatestWct(expectTransition = TRANSIT_NONE) + val wct = getLatestWct(type = TRANSIT_OPEN, handlerClass = OneShotRemoteHandler::class.java) assertThat(wct.hierarchyOps).hasSize(1) wct.assertReorderAt(index = 0, homeTask) } @@ -240,9 +244,9 @@ class DesktopTasksControllerTest : ShellTestCase() { markTaskHidden(taskDefaultDisplay) markTaskHidden(taskSecondDisplay) - controller.showDesktopApps(DEFAULT_DISPLAY) + controller.showDesktopApps(DEFAULT_DISPLAY, RemoteTransition(TestRemoteTransition())) - val wct = getLatestWct(expectTransition = TRANSIT_NONE) + val wct = getLatestWct(type = TRANSIT_OPEN, handlerClass = OneShotRemoteHandler::class.java) assertThat(wct.hierarchyOps).hasSize(2) // Expect order to be from bottom: home, task wct.assertReorderAt(index = 0, homeTaskDefaultDisplay) @@ -373,7 +377,7 @@ class DesktopTasksControllerTest : ShellTestCase() { val task = setUpFreeformTask() task.configuration.windowConfiguration.displayWindowingMode = WINDOWING_MODE_FULLSCREEN controller.moveToFullscreen(task) - val wct = getLatestWct(expectTransition = TRANSIT_CHANGE) + val wct = getLatestWct(type = TRANSIT_CHANGE) assertThat(wct.changes[task.token.asBinder()]?.windowingMode) .isEqualTo(WINDOWING_MODE_UNDEFINED) } @@ -383,7 +387,7 @@ class DesktopTasksControllerTest : ShellTestCase() { val task = setUpFreeformTask() task.configuration.windowConfiguration.displayWindowingMode = WINDOWING_MODE_FREEFORM controller.moveToFullscreen(task) - val wct = getLatestWct(expectTransition = TRANSIT_CHANGE) + val wct = getLatestWct(type = TRANSIT_CHANGE) assertThat(wct.changes[task.token.asBinder()]?.windowingMode) .isEqualTo(WINDOWING_MODE_FULLSCREEN) } @@ -401,7 +405,7 @@ class DesktopTasksControllerTest : ShellTestCase() { controller.moveToFullscreen(taskDefaultDisplay) - with(getLatestWct(expectTransition = TRANSIT_CHANGE)) { + with(getLatestWct(type = TRANSIT_CHANGE)) { assertThat(changes.keys).contains(taskDefaultDisplay.token.asBinder()) assertThat(changes.keys).doesNotContain(taskSecondDisplay.token.asBinder()) } @@ -414,7 +418,7 @@ class DesktopTasksControllerTest : ShellTestCase() { controller.moveTaskToFront(task1) - val wct = getLatestWct(expectTransition = TRANSIT_TO_FRONT) + val wct = getLatestWct(type = TRANSIT_TO_FRONT) assertThat(wct.hierarchyOps).hasSize(1) wct.assertReorderAt(index = 0, task1) } @@ -439,7 +443,7 @@ class DesktopTasksControllerTest : ShellTestCase() { val task = setUpFreeformTask(displayId = DEFAULT_DISPLAY) controller.moveToNextDisplay(task.taskId) - with(getLatestWct(expectTransition = TRANSIT_CHANGE)) { + with(getLatestWct(type = TRANSIT_CHANGE)) { assertThat(hierarchyOps).hasSize(1) assertThat(hierarchyOps[0].container).isEqualTo(task.token.asBinder()) assertThat(hierarchyOps[0].isReparent).isTrue() @@ -461,7 +465,7 @@ class DesktopTasksControllerTest : ShellTestCase() { val task = setUpFreeformTask(displayId = SECOND_DISPLAY) controller.moveToNextDisplay(task.taskId) - with(getLatestWct(expectTransition = TRANSIT_CHANGE)) { + with(getLatestWct(type = TRANSIT_CHANGE)) { assertThat(hierarchyOps).hasSize(1) assertThat(hierarchyOps[0].container).isEqualTo(task.token.asBinder()) assertThat(hierarchyOps[0].isReparent).isTrue() @@ -747,11 +751,16 @@ class DesktopTasksControllerTest : ShellTestCase() { } private fun getLatestWct( - @WindowManager.TransitionType expectTransition: Int = TRANSIT_OPEN + @WindowManager.TransitionType type: Int = TRANSIT_OPEN, + handlerClass: Class<out TransitionHandler>? = null ): WindowContainerTransaction { val arg = ArgumentCaptor.forClass(WindowContainerTransaction::class.java) if (ENABLE_SHELL_TRANSITIONS) { - verify(transitions).startTransition(eq(expectTransition), arg.capture(), isNull()) + if (handlerClass == null) { + verify(transitions).startTransition(eq(type), arg.capture(), isNull()) + } else { + verify(transitions).startTransition(eq(type), arg.capture(), isA(handlerClass)) + } } else { verify(shellTaskOrganizer).applyTransaction(arg.capture()) } diff --git a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/splitscreen/SplitTransitionTests.java b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/splitscreen/SplitTransitionTests.java index 5efd9ad97a3e..d542139ff9fd 100644 --- a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/splitscreen/SplitTransitionTests.java +++ b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/splitscreen/SplitTransitionTests.java @@ -47,11 +47,8 @@ import static org.mockito.Mockito.spy; import android.annotation.NonNull; import android.app.ActivityManager; import android.os.IBinder; -import android.os.RemoteException; import android.view.SurfaceControl; import android.view.SurfaceSession; -import android.window.IRemoteTransition; -import android.window.IRemoteTransitionFinishedCallback; import android.window.RemoteTransition; import android.window.TransitionInfo; import android.window.TransitionRequestInfo; @@ -65,6 +62,7 @@ import com.android.launcher3.icons.IconProvider; import com.android.wm.shell.RootTaskDisplayAreaOrganizer; import com.android.wm.shell.ShellTaskOrganizer; import com.android.wm.shell.ShellTestCase; +import com.android.wm.shell.TestRemoteTransition; import com.android.wm.shell.TestRunningTaskInfoBuilder; import com.android.wm.shell.TransitionInfoBuilder; import com.android.wm.shell.common.DisplayController; @@ -205,7 +203,7 @@ public class SplitTransitionTests extends ShellTestCase { // Make sure split-screen is now visible assertTrue(mStageCoordinator.isSplitScreenVisible()); - assertTrue(testRemote.mCalled); + assertTrue(testRemote.isCalled()); } @Test @@ -468,24 +466,4 @@ public class SplitTransitionTests extends ShellTestCase { return out; } - class TestRemoteTransition extends IRemoteTransition.Stub { - boolean mCalled = false; - final WindowContainerTransaction mRemoteFinishWCT = new WindowContainerTransaction(); - - @Override - public void startAnimation(IBinder transition, TransitionInfo info, - SurfaceControl.Transaction startTransaction, - IRemoteTransitionFinishedCallback finishCallback) - throws RemoteException { - mCalled = true; - finishCallback.onTransitionFinished(mRemoteFinishWCT, null /* sct */); - } - - @Override - public void mergeAnimation(IBinder transition, TransitionInfo info, - SurfaceControl.Transaction t, IBinder mergeTarget, - IRemoteTransitionFinishedCallback finishCallback) throws RemoteException { - } - } - } |