Loading services/core/java/com/android/server/wm/RecentsAnimationController.java +26 −11 Original line number Diff line number Diff line Loading @@ -20,8 +20,8 @@ import static android.app.WindowConfiguration.WINDOWING_MODE_FULLSCREEN; import static android.app.WindowConfiguration.WINDOWING_MODE_SPLIT_SCREEN_PRIMARY; import static android.app.WindowConfiguration.WINDOWING_MODE_UNDEFINED; import static android.view.RemoteAnimationTarget.MODE_CLOSING; import static android.view.RemoteAnimationTarget.MODE_OPENING; import static android.view.WindowManager.INPUT_CONSUMER_RECENTS_ANIMATION; import static com.android.server.policy.WindowManagerPolicy.FINISH_LAYOUT_REDO_WALLPAPER; import static com.android.server.wm.ActivityTaskManagerInternal.APP_TRANSITION_RECENTS_ANIM; import static com.android.server.wm.AnimationAdapterProto.REMOTE; Loading @@ -48,16 +48,13 @@ import android.view.IRecentsAnimationRunner; import android.view.RemoteAnimationTarget; import android.view.SurfaceControl; import android.view.SurfaceControl.Transaction; import com.android.internal.annotations.VisibleForTesting; import com.android.server.LocalServices; import com.android.server.input.InputWindowHandle; import com.android.server.inputmethod.InputMethodManagerInternal; import com.android.server.wm.SurfaceAnimator.OnAnimationFinishedCallback; import com.android.server.wm.utils.InsetUtils; import com.google.android.collect.Sets; import java.io.PrintWriter; import java.util.ArrayList; Loading Loading @@ -93,6 +90,7 @@ public class RecentsAnimationController implements DeathRecipient { // The recents component app token that is shown behind the visibile tasks private AppWindowToken mTargetAppToken; private int mTargetActivityType; private Rect mMinimizedHomeBounds = new Rect(); // We start the RecentsAnimationController in a pending-start state since we need to wait for Loading Loading @@ -259,23 +257,37 @@ public class RecentsAnimationController implements DeathRecipient { mDisplayId = displayId; } public void initialize(int targetActivityType, SparseBooleanArray recentTaskIds) { initialize(mService.mRoot.getDisplayContent(mDisplayId), targetActivityType, recentTaskIds); } /** * Initializes the recents animation controller. This is a separate call from the constructor * because it may call cancelAnimation() which needs to properly clean up the controller * in the window manager. */ public void initialize(int targetActivityType, SparseBooleanArray recentTaskIds) { // Make leashes for each of the visible tasks and add it to the recents animation to be // started final DisplayContent dc = mService.mRoot.getDisplayContent(mDisplayId); @VisibleForTesting void initialize(DisplayContent dc, int targetActivityType, SparseBooleanArray recentTaskIds) { mTargetActivityType = targetActivityType; // Make leashes for each of the visible/target tasks and add it to the recents animation to // be started final ArrayList<Task> visibleTasks = dc.getVisibleTasks(); final TaskStack targetStack = dc.getStack(WINDOWING_MODE_UNDEFINED, targetActivityType); if (targetStack != null) { for (int i = targetStack.getChildCount() - 1; i >= 0; i--) { final Task t = targetStack.getChildAt(i); if (!visibleTasks.contains(t)) { visibleTasks.add(t); } } } final int taskCount = visibleTasks.size(); for (int i = 0; i < taskCount; i++) { final Task task = visibleTasks.get(i); final WindowConfiguration config = task.getWindowConfiguration(); if (config.tasksAreFloating() || config.getWindowingMode() == WINDOWING_MODE_SPLIT_SCREEN_PRIMARY || config.getActivityType() == targetActivityType) { || config.getWindowingMode() == WINDOWING_MODE_SPLIT_SCREEN_PRIMARY) { continue; } addAnimation(task, !recentTaskIds.get(task.mTaskId)); Loading Loading @@ -586,7 +598,10 @@ public class RecentsAnimationController implements DeathRecipient { final Rect insets = new Rect(); mainWindow.getContentInsets(insets); InsetUtils.addInsets(insets, mainWindow.mAppToken.getLetterboxInsets()); mTarget = new RemoteAnimationTarget(mTask.mTaskId, MODE_CLOSING, mCapturedLeash, final int mode = topApp.getActivityType() == mTargetActivityType ? MODE_OPENING : MODE_CLOSING; mTarget = new RemoteAnimationTarget(mTask.mTaskId, mode, mCapturedLeash, !topApp.fillsParent(), mainWindow.mWinAnimator.mLastClipRect, insets, mTask.getPrefixOrderIndex(), mPosition, mBounds, mTask.getWindowConfiguration(), mIsRecentTaskInvisible); Loading services/core/java/com/android/server/wm/Task.java +4 −3 Original line number Diff line number Diff line Loading @@ -561,9 +561,10 @@ class Task extends WindowContainer<AppWindowToken> { @Override public SurfaceControl getAnimationLeashParent() { // Reparent to the animation layer so that we aren't clipped by the non-minimized // stack bounds, currently we only animate the task for the recents animation return getAppAnimationLayer(ANIMATION_LAYER_STANDARD); // Currently, only the recents animation will create animation leashes for tasks. In this // case, reparent the task to the home animation layer while it is being animated to allow // the home activity to reorder the app windows relative to its own. return getAppAnimationLayer(ANIMATION_LAYER_HOME); } boolean isTaskAnimating() { Loading services/core/java/com/android/server/wm/WindowContainer.java +2 −3 Original line number Diff line number Diff line Loading @@ -42,10 +42,8 @@ import android.view.MagnificationSpec; import android.view.SurfaceControl; import android.view.SurfaceControl.Builder; import android.view.SurfaceSession; import com.android.internal.util.ToBooleanFunction; import com.android.server.wm.SurfaceAnimator.Animatable; import java.io.PrintWriter; import java.util.Comparator; import java.util.LinkedList; Loading @@ -71,7 +69,8 @@ class WindowContainer<E extends WindowContainer> extends ConfigurationContainer< /** * Animation layer that is reserved for {@link WindowConfiguration#ACTIVITY_TYPE_HOME} * activities that happens below all {@link TaskStack}s. * activities and all activities that are being controlled by the recents animation. This * layer is generally below all {@link TaskStack}s. */ static final int ANIMATION_LAYER_HOME = 2; Loading services/core/java/com/android/server/wm/WindowManagerService.java +6 −0 Original line number Diff line number Diff line Loading @@ -227,6 +227,7 @@ import android.view.WindowManagerGlobal; import android.view.WindowManagerPolicyConstants.PointerEventListener; import com.android.internal.R; import com.android.internal.annotations.VisibleForTesting; import com.android.internal.os.IResultReceiver; import com.android.internal.policy.IKeyguardDismissCallback; import com.android.internal.policy.IShortcutService; Loading Loading @@ -2714,6 +2715,11 @@ public class WindowManagerService extends IWindowManager.Stub } } @VisibleForTesting void setRecentsAnimationController(RecentsAnimationController controller) { mRecentsAnimationController = controller; } public RecentsAnimationController getRecentsAnimationController() { return mRecentsAnimationController; } Loading services/tests/servicestests/src/com/android/server/wm/RecentsAnimationControllerTest.java +22 −0 Original line number Diff line number Diff line Loading @@ -16,6 +16,7 @@ package com.android.server.wm; import static android.app.WindowConfiguration.ACTIVITY_TYPE_HOME; import static android.app.WindowConfiguration.ACTIVITY_TYPE_STANDARD; import static android.app.WindowConfiguration.WINDOWING_MODE_FULLSCREEN; import static android.view.Display.DEFAULT_DISPLAY; Loading @@ -24,6 +25,8 @@ import static com.android.server.wm.RecentsAnimationController.REORDER_KEEP_IN_P import static com.android.server.wm.RecentsAnimationController.REORDER_MOVE_TO_ORIGINAL_POSITION; import static org.junit.Assert.fail; import static org.junit.Assert.assertFalse; import static org.junit.Assert.assertTrue; import static org.mockito.ArgumentMatchers.eq; import static org.mockito.Mockito.atLeast; import static org.mockito.Mockito.verify; Loading @@ -33,6 +36,7 @@ import static org.mockito.Mockito.when; import android.os.Binder; import android.os.IInterface; import android.platform.test.annotations.Presubmit; import android.util.SparseBooleanArray; import android.view.IRecentsAnimationRunner; import android.view.SurfaceControl; Loading Loading @@ -109,6 +113,24 @@ public class RecentsAnimationControllerTest extends WindowTestsBase { } } @Test public void testIncludedApps_expectTargetAndVisible() throws Exception { sWm.setRecentsAnimationController(mController); final AppWindowToken homeAppWindow = createAppWindowToken(mDisplayContent, WINDOWING_MODE_FULLSCREEN, ACTIVITY_TYPE_HOME); final AppWindowToken appWindow = createAppWindowToken(mDisplayContent, WINDOWING_MODE_FULLSCREEN, ACTIVITY_TYPE_STANDARD); final AppWindowToken hiddenAppWindow = createAppWindowToken(mDisplayContent, WINDOWING_MODE_FULLSCREEN, ACTIVITY_TYPE_STANDARD); hiddenAppWindow.setHidden(true); mController.initialize(mDisplayContent, ACTIVITY_TYPE_HOME, new SparseBooleanArray()); // Ensure that we are animating the target activity as well assertTrue(mController.isAnimatingTask(homeAppWindow.getTask())); assertTrue(mController.isAnimatingTask(appWindow.getTask())); assertFalse(mController.isAnimatingTask(hiddenAppWindow.getTask())); } private static void verifyNoMoreInteractionsExceptAsBinder(IInterface binder) { verify(binder, atLeast(0)).asBinder(); verifyNoMoreInteractions(binder); Loading Loading
services/core/java/com/android/server/wm/RecentsAnimationController.java +26 −11 Original line number Diff line number Diff line Loading @@ -20,8 +20,8 @@ import static android.app.WindowConfiguration.WINDOWING_MODE_FULLSCREEN; import static android.app.WindowConfiguration.WINDOWING_MODE_SPLIT_SCREEN_PRIMARY; import static android.app.WindowConfiguration.WINDOWING_MODE_UNDEFINED; import static android.view.RemoteAnimationTarget.MODE_CLOSING; import static android.view.RemoteAnimationTarget.MODE_OPENING; import static android.view.WindowManager.INPUT_CONSUMER_RECENTS_ANIMATION; import static com.android.server.policy.WindowManagerPolicy.FINISH_LAYOUT_REDO_WALLPAPER; import static com.android.server.wm.ActivityTaskManagerInternal.APP_TRANSITION_RECENTS_ANIM; import static com.android.server.wm.AnimationAdapterProto.REMOTE; Loading @@ -48,16 +48,13 @@ import android.view.IRecentsAnimationRunner; import android.view.RemoteAnimationTarget; import android.view.SurfaceControl; import android.view.SurfaceControl.Transaction; import com.android.internal.annotations.VisibleForTesting; import com.android.server.LocalServices; import com.android.server.input.InputWindowHandle; import com.android.server.inputmethod.InputMethodManagerInternal; import com.android.server.wm.SurfaceAnimator.OnAnimationFinishedCallback; import com.android.server.wm.utils.InsetUtils; import com.google.android.collect.Sets; import java.io.PrintWriter; import java.util.ArrayList; Loading Loading @@ -93,6 +90,7 @@ public class RecentsAnimationController implements DeathRecipient { // The recents component app token that is shown behind the visibile tasks private AppWindowToken mTargetAppToken; private int mTargetActivityType; private Rect mMinimizedHomeBounds = new Rect(); // We start the RecentsAnimationController in a pending-start state since we need to wait for Loading Loading @@ -259,23 +257,37 @@ public class RecentsAnimationController implements DeathRecipient { mDisplayId = displayId; } public void initialize(int targetActivityType, SparseBooleanArray recentTaskIds) { initialize(mService.mRoot.getDisplayContent(mDisplayId), targetActivityType, recentTaskIds); } /** * Initializes the recents animation controller. This is a separate call from the constructor * because it may call cancelAnimation() which needs to properly clean up the controller * in the window manager. */ public void initialize(int targetActivityType, SparseBooleanArray recentTaskIds) { // Make leashes for each of the visible tasks and add it to the recents animation to be // started final DisplayContent dc = mService.mRoot.getDisplayContent(mDisplayId); @VisibleForTesting void initialize(DisplayContent dc, int targetActivityType, SparseBooleanArray recentTaskIds) { mTargetActivityType = targetActivityType; // Make leashes for each of the visible/target tasks and add it to the recents animation to // be started final ArrayList<Task> visibleTasks = dc.getVisibleTasks(); final TaskStack targetStack = dc.getStack(WINDOWING_MODE_UNDEFINED, targetActivityType); if (targetStack != null) { for (int i = targetStack.getChildCount() - 1; i >= 0; i--) { final Task t = targetStack.getChildAt(i); if (!visibleTasks.contains(t)) { visibleTasks.add(t); } } } final int taskCount = visibleTasks.size(); for (int i = 0; i < taskCount; i++) { final Task task = visibleTasks.get(i); final WindowConfiguration config = task.getWindowConfiguration(); if (config.tasksAreFloating() || config.getWindowingMode() == WINDOWING_MODE_SPLIT_SCREEN_PRIMARY || config.getActivityType() == targetActivityType) { || config.getWindowingMode() == WINDOWING_MODE_SPLIT_SCREEN_PRIMARY) { continue; } addAnimation(task, !recentTaskIds.get(task.mTaskId)); Loading Loading @@ -586,7 +598,10 @@ public class RecentsAnimationController implements DeathRecipient { final Rect insets = new Rect(); mainWindow.getContentInsets(insets); InsetUtils.addInsets(insets, mainWindow.mAppToken.getLetterboxInsets()); mTarget = new RemoteAnimationTarget(mTask.mTaskId, MODE_CLOSING, mCapturedLeash, final int mode = topApp.getActivityType() == mTargetActivityType ? MODE_OPENING : MODE_CLOSING; mTarget = new RemoteAnimationTarget(mTask.mTaskId, mode, mCapturedLeash, !topApp.fillsParent(), mainWindow.mWinAnimator.mLastClipRect, insets, mTask.getPrefixOrderIndex(), mPosition, mBounds, mTask.getWindowConfiguration(), mIsRecentTaskInvisible); Loading
services/core/java/com/android/server/wm/Task.java +4 −3 Original line number Diff line number Diff line Loading @@ -561,9 +561,10 @@ class Task extends WindowContainer<AppWindowToken> { @Override public SurfaceControl getAnimationLeashParent() { // Reparent to the animation layer so that we aren't clipped by the non-minimized // stack bounds, currently we only animate the task for the recents animation return getAppAnimationLayer(ANIMATION_LAYER_STANDARD); // Currently, only the recents animation will create animation leashes for tasks. In this // case, reparent the task to the home animation layer while it is being animated to allow // the home activity to reorder the app windows relative to its own. return getAppAnimationLayer(ANIMATION_LAYER_HOME); } boolean isTaskAnimating() { Loading
services/core/java/com/android/server/wm/WindowContainer.java +2 −3 Original line number Diff line number Diff line Loading @@ -42,10 +42,8 @@ import android.view.MagnificationSpec; import android.view.SurfaceControl; import android.view.SurfaceControl.Builder; import android.view.SurfaceSession; import com.android.internal.util.ToBooleanFunction; import com.android.server.wm.SurfaceAnimator.Animatable; import java.io.PrintWriter; import java.util.Comparator; import java.util.LinkedList; Loading @@ -71,7 +69,8 @@ class WindowContainer<E extends WindowContainer> extends ConfigurationContainer< /** * Animation layer that is reserved for {@link WindowConfiguration#ACTIVITY_TYPE_HOME} * activities that happens below all {@link TaskStack}s. * activities and all activities that are being controlled by the recents animation. This * layer is generally below all {@link TaskStack}s. */ static final int ANIMATION_LAYER_HOME = 2; Loading
services/core/java/com/android/server/wm/WindowManagerService.java +6 −0 Original line number Diff line number Diff line Loading @@ -227,6 +227,7 @@ import android.view.WindowManagerGlobal; import android.view.WindowManagerPolicyConstants.PointerEventListener; import com.android.internal.R; import com.android.internal.annotations.VisibleForTesting; import com.android.internal.os.IResultReceiver; import com.android.internal.policy.IKeyguardDismissCallback; import com.android.internal.policy.IShortcutService; Loading Loading @@ -2714,6 +2715,11 @@ public class WindowManagerService extends IWindowManager.Stub } } @VisibleForTesting void setRecentsAnimationController(RecentsAnimationController controller) { mRecentsAnimationController = controller; } public RecentsAnimationController getRecentsAnimationController() { return mRecentsAnimationController; } Loading
services/tests/servicestests/src/com/android/server/wm/RecentsAnimationControllerTest.java +22 −0 Original line number Diff line number Diff line Loading @@ -16,6 +16,7 @@ package com.android.server.wm; import static android.app.WindowConfiguration.ACTIVITY_TYPE_HOME; import static android.app.WindowConfiguration.ACTIVITY_TYPE_STANDARD; import static android.app.WindowConfiguration.WINDOWING_MODE_FULLSCREEN; import static android.view.Display.DEFAULT_DISPLAY; Loading @@ -24,6 +25,8 @@ import static com.android.server.wm.RecentsAnimationController.REORDER_KEEP_IN_P import static com.android.server.wm.RecentsAnimationController.REORDER_MOVE_TO_ORIGINAL_POSITION; import static org.junit.Assert.fail; import static org.junit.Assert.assertFalse; import static org.junit.Assert.assertTrue; import static org.mockito.ArgumentMatchers.eq; import static org.mockito.Mockito.atLeast; import static org.mockito.Mockito.verify; Loading @@ -33,6 +36,7 @@ import static org.mockito.Mockito.when; import android.os.Binder; import android.os.IInterface; import android.platform.test.annotations.Presubmit; import android.util.SparseBooleanArray; import android.view.IRecentsAnimationRunner; import android.view.SurfaceControl; Loading Loading @@ -109,6 +113,24 @@ public class RecentsAnimationControllerTest extends WindowTestsBase { } } @Test public void testIncludedApps_expectTargetAndVisible() throws Exception { sWm.setRecentsAnimationController(mController); final AppWindowToken homeAppWindow = createAppWindowToken(mDisplayContent, WINDOWING_MODE_FULLSCREEN, ACTIVITY_TYPE_HOME); final AppWindowToken appWindow = createAppWindowToken(mDisplayContent, WINDOWING_MODE_FULLSCREEN, ACTIVITY_TYPE_STANDARD); final AppWindowToken hiddenAppWindow = createAppWindowToken(mDisplayContent, WINDOWING_MODE_FULLSCREEN, ACTIVITY_TYPE_STANDARD); hiddenAppWindow.setHidden(true); mController.initialize(mDisplayContent, ACTIVITY_TYPE_HOME, new SparseBooleanArray()); // Ensure that we are animating the target activity as well assertTrue(mController.isAnimatingTask(homeAppWindow.getTask())); assertTrue(mController.isAnimatingTask(appWindow.getTask())); assertFalse(mController.isAnimatingTask(hiddenAppWindow.getTask())); } private static void verifyNoMoreInteractionsExceptAsBinder(IInterface binder) { verify(binder, atLeast(0)).asBinder(); verifyNoMoreInteractions(binder); Loading