diff options
| author | 2025-01-15 07:02:10 -0800 | |
|---|---|---|
| committer | 2025-01-15 07:02:10 -0800 | |
| commit | b7cdebf4575d0c6a82f3bf9362fa0a700bc79f25 (patch) | |
| tree | 86f53a5232161b2db5fa4b624162e2a051f37233 | |
| parent | a91957d8fe1f601d3d3cfebda0193ccacffde12d (diff) | |
| parent | 7df1f96d0fac39d51f615765acd403257ac6a5ee (diff) | |
Merge "Reland "Swipe-up Recents transition: override desktop tasks corner..."" into main
11 files changed, 198 insertions, 34 deletions
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/dagger/WMShellModule.java b/libs/WindowManager/Shell/src/com/android/wm/shell/dagger/WMShellModule.java index ac510f89b905..e8add56619c4 100644 --- a/libs/WindowManager/Shell/src/com/android/wm/shell/dagger/WMShellModule.java +++ b/libs/WindowManager/Shell/src/com/android/wm/shell/dagger/WMShellModule.java @@ -946,7 +946,8 @@ public abstract class WMShellModule { FocusTransitionObserver focusTransitionObserver, DesktopModeEventLogger desktopModeEventLogger, DesktopModeUiEventLogger desktopModeUiEventLogger, - WindowDecorTaskResourceLoader taskResourceLoader + WindowDecorTaskResourceLoader taskResourceLoader, + RecentsTransitionHandler recentsTransitionHandler ) { if (!DesktopModeStatus.canEnterDesktopModeOrShowAppHandle(context)) { return Optional.empty(); @@ -962,7 +963,7 @@ public abstract class WMShellModule { desktopTasksLimiter, appHandleEducationController, appToWebEducationController, windowDecorCaptionHandleRepository, activityOrientationChangeHandler, focusTransitionObserver, desktopModeEventLogger, desktopModeUiEventLogger, - taskResourceLoader)); + taskResourceLoader, recentsTransitionHandler)); } @WMSingleton diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/recents/IRecentsAnimationRunner.aidl b/libs/WindowManager/Shell/src/com/android/wm/shell/recents/IRecentsAnimationRunner.aidl index 32c79a2d02de..8cdb8c4512a9 100644 --- a/libs/WindowManager/Shell/src/com/android/wm/shell/recents/IRecentsAnimationRunner.aidl +++ b/libs/WindowManager/Shell/src/com/android/wm/shell/recents/IRecentsAnimationRunner.aidl @@ -17,9 +17,10 @@ package com.android.wm.shell.recents; import android.graphics.Rect; +import android.os.Bundle; import android.view.RemoteAnimationTarget; import android.window.TaskSnapshot; -import android.os.Bundle; +import android.window.TransitionInfo; import com.android.wm.shell.recents.IRecentsAnimationController; @@ -57,7 +58,8 @@ oneway interface IRecentsAnimationRunner { */ void onAnimationStart(in IRecentsAnimationController controller, in RemoteAnimationTarget[] apps, in RemoteAnimationTarget[] wallpapers, - in Rect homeContentInsets, in Rect minimizedHomeBounds, in Bundle extras) = 2; + in Rect homeContentInsets, in Rect minimizedHomeBounds, in Bundle extras, + in TransitionInfo info) = 2; /** * Called when the task of an activity that has been started while the recents animation diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/recents/RecentsTransitionHandler.java b/libs/WindowManager/Shell/src/com/android/wm/shell/recents/RecentsTransitionHandler.java index db582aa30f6a..aeccd86e122c 100644 --- a/libs/WindowManager/Shell/src/com/android/wm/shell/recents/RecentsTransitionHandler.java +++ b/libs/WindowManager/Shell/src/com/android/wm/shell/recents/RecentsTransitionHandler.java @@ -587,7 +587,8 @@ public class RecentsTransitionHandler implements Transitions.TransitionHandler, mListener.onAnimationStart(this, apps.toArray(new RemoteAnimationTarget[apps.size()]), new RemoteAnimationTarget[0], - new Rect(0, 0, 0, 0), new Rect(), new Bundle()); + new Rect(0, 0, 0, 0), new Rect(), new Bundle(), + null); for (int i = 0; i < mStateListeners.size(); i++) { mStateListeners.get(i).onTransitionStateChanged(TRANSITION_STATE_ANIMATING); } @@ -818,7 +819,7 @@ public class RecentsTransitionHandler implements Transitions.TransitionHandler, mListener.onAnimationStart(this, apps.toArray(new RemoteAnimationTarget[apps.size()]), wallpapers.toArray(new RemoteAnimationTarget[wallpapers.size()]), - new Rect(0, 0, 0, 0), new Rect(), b); + new Rect(0, 0, 0, 0), new Rect(), b, info); for (int i = 0; i < mStateListeners.size(); i++) { mStateListeners.get(i).onTransitionStateChanged(TRANSITION_STATE_ANIMATING); } diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/DesktopModeWindowDecorViewModel.java b/libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/DesktopModeWindowDecorViewModel.java index 67dae283345a..055bc8f5f092 100644 --- a/libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/DesktopModeWindowDecorViewModel.java +++ b/libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/DesktopModeWindowDecorViewModel.java @@ -126,6 +126,8 @@ import com.android.wm.shell.desktopmode.common.ToggleTaskSizeUtilsKt; import com.android.wm.shell.desktopmode.education.AppHandleEducationController; import com.android.wm.shell.desktopmode.education.AppToWebEducationController; import com.android.wm.shell.freeform.FreeformTaskTransitionStarter; +import com.android.wm.shell.recents.RecentsTransitionHandler; +import com.android.wm.shell.recents.RecentsTransitionStateListener; import com.android.wm.shell.shared.FocusTransitionListener; import com.android.wm.shell.shared.annotations.ShellBackgroundThread; import com.android.wm.shell.shared.annotations.ShellMainThread; @@ -157,8 +159,10 @@ import kotlinx.coroutines.MainCoroutineDispatcher; import java.io.PrintWriter; import java.util.ArrayList; +import java.util.HashSet; import java.util.List; import java.util.Optional; +import java.util.Set; import java.util.function.Supplier; /** @@ -247,6 +251,7 @@ public class DesktopModeWindowDecorViewModel implements WindowDecorViewModel, private final DesktopModeEventLogger mDesktopModeEventLogger; private final DesktopModeUiEventLogger mDesktopModeUiEventLogger; private final WindowDecorTaskResourceLoader mTaskResourceLoader; + private final RecentsTransitionHandler mRecentsTransitionHandler; public DesktopModeWindowDecorViewModel( Context context, @@ -282,7 +287,8 @@ public class DesktopModeWindowDecorViewModel implements WindowDecorViewModel, FocusTransitionObserver focusTransitionObserver, DesktopModeEventLogger desktopModeEventLogger, DesktopModeUiEventLogger desktopModeUiEventLogger, - WindowDecorTaskResourceLoader taskResourceLoader) { + WindowDecorTaskResourceLoader taskResourceLoader, + RecentsTransitionHandler recentsTransitionHandler) { this( context, shellExecutor, @@ -323,7 +329,8 @@ public class DesktopModeWindowDecorViewModel implements WindowDecorViewModel, focusTransitionObserver, desktopModeEventLogger, desktopModeUiEventLogger, - taskResourceLoader); + taskResourceLoader, + recentsTransitionHandler); } @VisibleForTesting @@ -367,7 +374,8 @@ public class DesktopModeWindowDecorViewModel implements WindowDecorViewModel, FocusTransitionObserver focusTransitionObserver, DesktopModeEventLogger desktopModeEventLogger, DesktopModeUiEventLogger desktopModeUiEventLogger, - WindowDecorTaskResourceLoader taskResourceLoader) { + WindowDecorTaskResourceLoader taskResourceLoader, + RecentsTransitionHandler recentsTransitionHandler) { mContext = context; mMainExecutor = shellExecutor; mMainHandler = mainHandler; @@ -436,6 +444,7 @@ public class DesktopModeWindowDecorViewModel implements WindowDecorViewModel, mDesktopModeEventLogger = desktopModeEventLogger; mDesktopModeUiEventLogger = desktopModeUiEventLogger; mTaskResourceLoader = taskResourceLoader; + mRecentsTransitionHandler = recentsTransitionHandler; shellInit.addInitCallback(this::onInit, this); } @@ -450,6 +459,10 @@ public class DesktopModeWindowDecorViewModel implements WindowDecorViewModel, new DesktopModeOnTaskResizeAnimationListener()); mDesktopTasksController.setOnTaskRepositionAnimationListener( new DesktopModeOnTaskRepositionAnimationListener()); + if (Flags.enableDesktopRecentsTransitionsCornersBugfix()) { + mRecentsTransitionHandler.addTransitionStateListener( + new DesktopModeRecentsTransitionStateListener()); + } mDisplayController.addDisplayChangingController(mOnDisplayChangingListener); try { mWindowManager.registerSystemGestureExclusionListener(mGestureExclusionListener, @@ -1859,6 +1872,38 @@ public class DesktopModeWindowDecorViewModel implements WindowDecorViewModel, } } + private class DesktopModeRecentsTransitionStateListener + implements RecentsTransitionStateListener { + final Set<Integer> mAnimatingTaskIds = new HashSet<>(); + + @Override + public void onTransitionStateChanged(int state) { + switch (state) { + case RecentsTransitionStateListener.TRANSITION_STATE_REQUESTED: + for (int n = 0; n < mWindowDecorByTaskId.size(); n++) { + int taskId = mWindowDecorByTaskId.keyAt(n); + mAnimatingTaskIds.add(taskId); + setIsRecentsTransitionRunningForTask(taskId, true); + } + return; + case RecentsTransitionStateListener.TRANSITION_STATE_NOT_RUNNING: + // No Recents transition running - clean up window decorations + for (int taskId : mAnimatingTaskIds) { + setIsRecentsTransitionRunningForTask(taskId, false); + } + mAnimatingTaskIds.clear(); + return; + default: + } + } + + private void setIsRecentsTransitionRunningForTask(int taskId, boolean isRecentsRunning) { + final DesktopModeWindowDecoration decoration = mWindowDecorByTaskId.get(taskId); + if (decoration == null) return; + decoration.setIsRecentsTransitionRunning(isRecentsRunning); + } + } + private class DragEventListenerImpl implements DragPositioningCallbackUtility.DragEventListener { @Override diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/DesktopModeWindowDecoration.java b/libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/DesktopModeWindowDecoration.java index 4ac89546c9c7..39a989ce7c7f 100644 --- a/libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/DesktopModeWindowDecoration.java +++ b/libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/DesktopModeWindowDecoration.java @@ -204,6 +204,7 @@ public class DesktopModeWindowDecoration extends WindowDecoration<WindowDecorLin private final MultiInstanceHelper mMultiInstanceHelper; private final WindowDecorCaptionHandleRepository mWindowDecorCaptionHandleRepository; private final DesktopUserRepositories mDesktopUserRepositories; + private boolean mIsRecentsTransitionRunning = false; private Runnable mLoadAppInfoRunnable; private Runnable mSetAppInfoRunnable; @@ -498,7 +499,7 @@ public class DesktopModeWindowDecoration extends WindowDecoration<WindowDecorLin applyStartTransactionOnDraw, shouldSetTaskVisibilityPositionAndCrop, mIsStatusBarVisible, mIsKeyguardVisibleAndOccluded, inFullImmersive, mDisplayController.getInsetsState(taskInfo.displayId), hasGlobalFocus, - displayExclusionRegion); + displayExclusionRegion, mIsRecentsTransitionRunning); final WindowDecorLinearLayout oldRootView = mResult.mRootView; final SurfaceControl oldDecorationSurface = mDecorationContainerSurface; @@ -869,7 +870,8 @@ public class DesktopModeWindowDecoration extends WindowDecoration<WindowDecorLin boolean inFullImmersiveMode, @NonNull InsetsState displayInsetsState, boolean hasGlobalFocus, - @NonNull Region displayExclusionRegion) { + @NonNull Region displayExclusionRegion, + boolean shouldIgnoreCornerRadius) { final int captionLayoutId = getDesktopModeWindowDecorLayoutId(taskInfo.getWindowingMode()); final boolean isAppHeader = captionLayoutId == R.layout.desktop_mode_app_header; @@ -1006,13 +1008,19 @@ public class DesktopModeWindowDecoration extends WindowDecoration<WindowDecorLin relayoutParams.mWindowDecorConfig = windowDecorConfig; if (DesktopModeStatus.useRoundedCorners()) { - relayoutParams.mCornerRadius = taskInfo.getWindowingMode() == WINDOWING_MODE_FREEFORM - ? loadDimensionPixelSize(context.getResources(), - R.dimen.desktop_windowing_freeform_rounded_corner_radius) - : INVALID_CORNER_RADIUS; + relayoutParams.mCornerRadius = shouldIgnoreCornerRadius ? INVALID_CORNER_RADIUS : + getCornerRadius(context, relayoutParams.mLayoutResId); } } + private static int getCornerRadius(@NonNull Context context, int layoutResId) { + if (layoutResId == R.layout.desktop_mode_app_header) { + return loadDimensionPixelSize(context.getResources(), + R.dimen.desktop_windowing_freeform_rounded_corner_radius); + } + return INVALID_CORNER_RADIUS; + } + /** * If task has focused window decor, return the caption id of the fullscreen caption size * resource. Otherwise, return ID_NULL and caption width be set to task width. @@ -1740,6 +1748,17 @@ public class DesktopModeWindowDecoration extends WindowDecoration<WindowDecorLin } /** + * Declares whether a Recents transition is currently active. + * + * <p> When a Recents transition is active we allow that transition to take ownership of the + * corner radius of its task surfaces, so each window decoration should stop updating the corner + * radius of its task surface during that time. + */ + void setIsRecentsTransitionRunning(boolean isRecentsTransitionRunning) { + mIsRecentsTransitionRunning = isRecentsTransitionRunning; + } + + /** * Called when there is a {@link MotionEvent#ACTION_HOVER_EXIT} on the maximize window button. */ void onMaximizeButtonHoverExit() { diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/WindowDecoration.java b/libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/WindowDecoration.java index 5d1bedb85b5e..fa7183ad0fd8 100644 --- a/libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/WindowDecoration.java +++ b/libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/WindowDecoration.java @@ -967,4 +967,4 @@ public abstract class WindowDecoration<T extends View & TaskFocusStateConsumer> return Objects.hash(mToken, mOwner, mFrame, Arrays.hashCode(mBoundingRects), mFlags); } } -}
\ No newline at end of file +} diff --git a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/recents/RecentsTransitionHandlerTest.java b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/recents/RecentsTransitionHandlerTest.java index 894d238b7e15..ab43119b14c0 100644 --- a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/recents/RecentsTransitionHandlerTest.java +++ b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/recents/RecentsTransitionHandlerTest.java @@ -169,7 +169,7 @@ public class RecentsTransitionHandlerTest extends ShellTestCase { final IResultReceiver finishCallback = mock(IResultReceiver.class); final IBinder transition = startRecentsTransition(/* synthetic= */ true, runner); - verify(runner).onAnimationStart(any(), any(), any(), any(), any(), any()); + verify(runner).onAnimationStart(any(), any(), any(), any(), any(), any(), any()); // Finish and verify no transition remains and that the provided finish callback is called mRecentsTransitionHandler.findController(transition).finish(true /* toHome */, @@ -184,7 +184,7 @@ public class RecentsTransitionHandlerTest extends ShellTestCase { final IRecentsAnimationRunner runner = mock(IRecentsAnimationRunner.class); final IBinder transition = startRecentsTransition(/* synthetic= */ true, runner); - verify(runner).onAnimationStart(any(), any(), any(), any(), any(), any()); + verify(runner).onAnimationStart(any(), any(), any(), any(), any(), any(), any()); mRecentsTransitionHandler.findController(transition).cancel("test"); mMainExecutor.flushAll(); diff --git a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/windowdecor/DesktopModeWindowDecorViewModelTests.kt b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/windowdecor/DesktopModeWindowDecorViewModelTests.kt index ffe8e7135513..79e9b9c8cd77 100644 --- a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/windowdecor/DesktopModeWindowDecorViewModelTests.kt +++ b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/windowdecor/DesktopModeWindowDecorViewModelTests.kt @@ -59,11 +59,12 @@ import com.android.dx.mockito.inline.extended.ExtendedMockito.doReturn import com.android.dx.mockito.inline.extended.ExtendedMockito.mockitoSession import com.android.window.flags.Flags import com.android.wm.shell.R -import com.android.wm.shell.desktopmode.common.ToggleTaskSizeInteraction import com.android.wm.shell.desktopmode.DesktopImmersiveController import com.android.wm.shell.desktopmode.DesktopModeEventLogger.Companion.InputMethod import com.android.wm.shell.desktopmode.DesktopModeEventLogger.Companion.ResizeTrigger import com.android.wm.shell.desktopmode.DesktopTasksController.SnapPosition +import com.android.wm.shell.desktopmode.common.ToggleTaskSizeInteraction +import com.android.wm.shell.recents.RecentsTransitionStateListener import com.android.wm.shell.shared.desktopmode.DesktopModeStatus import com.android.wm.shell.shared.desktopmode.DesktopModeTransitionSource import com.android.wm.shell.splitscreen.SplitScreenController @@ -539,7 +540,8 @@ class DesktopModeWindowDecorViewModelTests : DesktopModeWindowDecorViewModelTest onLeftSnapClickListenerCaptor.value.invoke() verify(mockDesktopTasksController, never()) - .snapToHalfScreen(eq(decor.mTaskInfo), any(), eq(currentBounds), eq(SnapPosition.LEFT), + .snapToHalfScreen( + eq(decor.mTaskInfo), any(), eq(currentBounds), eq(SnapPosition.LEFT), eq(ResizeTrigger.MAXIMIZE_BUTTON), eq(InputMethod.UNKNOWN_INPUT_METHOD), eq(decor), @@ -616,11 +618,12 @@ class DesktopModeWindowDecorViewModelTests : DesktopModeWindowDecorViewModelTest onRightSnapClickListenerCaptor.value.invoke() verify(mockDesktopTasksController, never()) - .snapToHalfScreen(eq(decor.mTaskInfo), any(), eq(currentBounds), eq(SnapPosition.RIGHT), + .snapToHalfScreen( + eq(decor.mTaskInfo), any(), eq(currentBounds), eq(SnapPosition.RIGHT), eq(ResizeTrigger.MAXIMIZE_BUTTON), eq(InputMethod.UNKNOWN_INPUT_METHOD), eq(decor), - ) + ) } @Test @@ -1223,6 +1226,49 @@ class DesktopModeWindowDecorViewModelTests : DesktopModeWindowDecorViewModelTest verify(task2, never()).onExclusionRegionChanged(newRegion) } + @Test + @EnableFlags(Flags.FLAG_ENABLE_DESKTOP_RECENTS_TRANSITIONS_CORNERS_BUGFIX) + fun testRecentsTransitionStateListener_requestedState_setsTransitionRunning() { + val task = createTask(windowingMode = WINDOWING_MODE_FREEFORM) + val decoration = setUpMockDecorationForTask(task) + onTaskOpening(task, SurfaceControl()) + + desktopModeRecentsTransitionStateListener.onTransitionStateChanged( + RecentsTransitionStateListener.TRANSITION_STATE_REQUESTED) + + verify(decoration).setIsRecentsTransitionRunning(true) + } + + @Test + @EnableFlags(Flags.FLAG_ENABLE_DESKTOP_RECENTS_TRANSITIONS_CORNERS_BUGFIX) + fun testRecentsTransitionStateListener_nonRunningState_setsTransitionNotRunning() { + val task = createTask(windowingMode = WINDOWING_MODE_FREEFORM) + val decoration = setUpMockDecorationForTask(task) + onTaskOpening(task, SurfaceControl()) + desktopModeRecentsTransitionStateListener.onTransitionStateChanged( + RecentsTransitionStateListener.TRANSITION_STATE_REQUESTED) + + desktopModeRecentsTransitionStateListener.onTransitionStateChanged( + RecentsTransitionStateListener.TRANSITION_STATE_NOT_RUNNING) + + verify(decoration).setIsRecentsTransitionRunning(false) + } + + @Test + @EnableFlags(Flags.FLAG_ENABLE_DESKTOP_RECENTS_TRANSITIONS_CORNERS_BUGFIX) + fun testRecentsTransitionStateListener_requestedAndAnimating_setsTransitionRunningOnce() { + val task = createTask(windowingMode = WINDOWING_MODE_FREEFORM) + val decoration = setUpMockDecorationForTask(task) + onTaskOpening(task, SurfaceControl()) + + desktopModeRecentsTransitionStateListener.onTransitionStateChanged( + RecentsTransitionStateListener.TRANSITION_STATE_REQUESTED) + desktopModeRecentsTransitionStateListener.onTransitionStateChanged( + RecentsTransitionStateListener.TRANSITION_STATE_ANIMATING) + + verify(decoration, times(1)).setIsRecentsTransitionRunning(true) + } + private fun createOpenTaskDecoration( @WindowingMode windowingMode: Int, taskSurface: SurfaceControl = SurfaceControl(), diff --git a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/windowdecor/DesktopModeWindowDecorViewModelTestsBase.kt b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/windowdecor/DesktopModeWindowDecorViewModelTestsBase.kt index 40015eece15c..b44af4733fd2 100644 --- a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/windowdecor/DesktopModeWindowDecorViewModelTestsBase.kt +++ b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/windowdecor/DesktopModeWindowDecorViewModelTestsBase.kt @@ -40,6 +40,7 @@ import android.view.SurfaceControl import android.view.WindowInsets.Type.statusBars import com.android.dx.mockito.inline.extended.StaticMockitoSession import com.android.internal.jank.InteractionJankMonitor +import com.android.window.flags.Flags import com.android.wm.shell.RootTaskDisplayAreaOrganizer import com.android.wm.shell.ShellTaskOrganizer import com.android.wm.shell.ShellTestCase @@ -65,6 +66,8 @@ import com.android.wm.shell.desktopmode.WindowDecorCaptionHandleRepository import com.android.wm.shell.desktopmode.education.AppHandleEducationController import com.android.wm.shell.desktopmode.education.AppToWebEducationController import com.android.wm.shell.freeform.FreeformTaskTransitionStarter +import com.android.wm.shell.recents.RecentsTransitionHandler +import com.android.wm.shell.recents.RecentsTransitionStateListener import com.android.wm.shell.splitscreen.SplitScreenController import com.android.wm.shell.sysui.ShellCommandHandler import com.android.wm.shell.sysui.ShellController @@ -151,6 +154,7 @@ open class DesktopModeWindowDecorViewModelTestsBase : ShellTestCase() { protected val mockFocusTransitionObserver = mock<FocusTransitionObserver>() protected val mockCaptionHandleRepository = mock<WindowDecorCaptionHandleRepository>() protected val mockDesktopRepository: DesktopRepository = mock<DesktopRepository>() + protected val mockRecentsTransitionHandler = mock<RecentsTransitionHandler>() protected val motionEvent = mock<MotionEvent>() val displayLayout = mock<DisplayLayout>() protected lateinit var spyContext: TestableContext @@ -164,6 +168,7 @@ open class DesktopModeWindowDecorViewModelTestsBase : ShellTestCase() { protected lateinit var mockitoSession: StaticMockitoSession protected lateinit var shellInit: ShellInit internal lateinit var desktopModeOnInsetsChangedListener: DesktopModeOnInsetsChangedListener + protected lateinit var desktopModeRecentsTransitionStateListener: RecentsTransitionStateListener protected lateinit var displayChangingListener: DisplayChangeController.OnDisplayChangingListener internal lateinit var desktopModeOnKeyguardChangedListener: DesktopModeKeyguardChangeListener @@ -220,7 +225,8 @@ open class DesktopModeWindowDecorViewModelTestsBase : ShellTestCase() { mockFocusTransitionObserver, desktopModeEventLogger, mock<DesktopModeUiEventLogger>(), - mock<WindowDecorTaskResourceLoader>() + mock<WindowDecorTaskResourceLoader>(), + mockRecentsTransitionHandler, ) desktopModeWindowDecorViewModel.setSplitScreenController(mockSplitScreenController) whenever(mockDisplayController.getDisplayLayout(any())).thenReturn(mockDisplayLayout) @@ -257,6 +263,13 @@ open class DesktopModeWindowDecorViewModelTestsBase : ShellTestCase() { verify(displayInsetsController) .addGlobalInsetsChangedListener(insetsChangedCaptor.capture()) desktopModeOnInsetsChangedListener = insetsChangedCaptor.firstValue + val recentsTransitionStateListenerCaptor = argumentCaptor<RecentsTransitionStateListener>() + if (Flags.enableDesktopRecentsTransitionsCornersBugfix()) { + verify(mockRecentsTransitionHandler) + .addTransitionStateListener(recentsTransitionStateListenerCaptor.capture()) + desktopModeRecentsTransitionStateListener = + recentsTransitionStateListenerCaptor.firstValue + } val keyguardChangedCaptor = argumentCaptor<DesktopModeKeyguardChangeListener>() verify(mockShellController).addKeyguardChangeListener(keyguardChangedCaptor.capture()) diff --git a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/windowdecor/DesktopModeWindowDecorationTests.java b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/windowdecor/DesktopModeWindowDecorationTests.java index 6b02aeffd42a..9ea5fd6e1abe 100644 --- a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/windowdecor/DesktopModeWindowDecorationTests.java +++ b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/windowdecor/DesktopModeWindowDecorationTests.java @@ -169,6 +169,7 @@ public class DesktopModeWindowDecorationTests extends ShellTestCase { private static final boolean DEFAULT_IS_KEYGUARD_VISIBLE_AND_OCCLUDED = false; private static final boolean DEFAULT_IS_IN_FULL_IMMERSIVE_MODE = false; private static final boolean DEFAULT_HAS_GLOBAL_FOCUS = true; + private static final boolean DEFAULT_SHOULD_IGNORE_CORNER_RADIUS = false; @Rule public final SetFlagsRule mSetFlagsRule = new SetFlagsRule(DEVICE_DEFAULT); @@ -396,6 +397,31 @@ public class DesktopModeWindowDecorationTests extends ShellTestCase { } @Test + public void updateRelayoutParams_shouldIgnoreCornerRadius_roundedCornersNotSet() { + final ActivityManager.RunningTaskInfo taskInfo = createTaskInfo(/* visible= */ true); + taskInfo.configuration.windowConfiguration.setWindowingMode(WINDOWING_MODE_FREEFORM); + fillRoundedCornersResources(/* fillValue= */ 30); + RelayoutParams relayoutParams = new RelayoutParams(); + + DesktopModeWindowDecoration.updateRelayoutParams( + relayoutParams, + mTestableContext, + taskInfo, + mMockSplitScreenController, + DEFAULT_APPLY_START_TRANSACTION_ON_DRAW, + DEFAULT_SHOULD_SET_TASK_POSITIONING_AND_CROP, + DEFAULT_IS_STATUSBAR_VISIBLE, + DEFAULT_IS_KEYGUARD_VISIBLE_AND_OCCLUDED, + DEFAULT_IS_IN_FULL_IMMERSIVE_MODE, + new InsetsState(), + DEFAULT_HAS_GLOBAL_FOCUS, + mExclusionRegion, + /* shouldIgnoreCornerRadius= */ true); + + assertThat(relayoutParams.mCornerRadius).isEqualTo(INVALID_CORNER_RADIUS); + } + + @Test @EnableFlags(Flags.FLAG_ENABLE_APP_HEADER_WITH_TASK_DENSITY) public void updateRelayoutParams_appHeader_usesTaskDensity() { final int systemDensity = mTestableContext.getOrCreateTestableResources().getResources() @@ -634,7 +660,8 @@ public class DesktopModeWindowDecorationTests extends ShellTestCase { /* inFullImmersiveMode */ true, insetsState, DEFAULT_HAS_GLOBAL_FOCUS, - mExclusionRegion); + mExclusionRegion, + DEFAULT_SHOULD_IGNORE_CORNER_RADIUS); // Takes status bar inset as padding, ignores caption bar inset. assertThat(relayoutParams.mCaptionTopPadding).isEqualTo(50); @@ -659,7 +686,8 @@ public class DesktopModeWindowDecorationTests extends ShellTestCase { /* inFullImmersiveMode */ true, new InsetsState(), DEFAULT_HAS_GLOBAL_FOCUS, - mExclusionRegion); + mExclusionRegion, + DEFAULT_SHOULD_IGNORE_CORNER_RADIUS); assertThat(relayoutParams.mIsInsetSource).isFalse(); } @@ -683,7 +711,8 @@ public class DesktopModeWindowDecorationTests extends ShellTestCase { DEFAULT_IS_IN_FULL_IMMERSIVE_MODE, new InsetsState(), DEFAULT_HAS_GLOBAL_FOCUS, - mExclusionRegion); + mExclusionRegion, + DEFAULT_SHOULD_IGNORE_CORNER_RADIUS); // Header is always shown because it's assumed the status bar is always visible. assertThat(relayoutParams.mIsCaptionVisible).isTrue(); @@ -707,7 +736,8 @@ public class DesktopModeWindowDecorationTests extends ShellTestCase { DEFAULT_IS_IN_FULL_IMMERSIVE_MODE, new InsetsState(), DEFAULT_HAS_GLOBAL_FOCUS, - mExclusionRegion); + mExclusionRegion, + DEFAULT_SHOULD_IGNORE_CORNER_RADIUS); assertThat(relayoutParams.mIsCaptionVisible).isTrue(); } @@ -730,7 +760,8 @@ public class DesktopModeWindowDecorationTests extends ShellTestCase { DEFAULT_IS_IN_FULL_IMMERSIVE_MODE, new InsetsState(), DEFAULT_HAS_GLOBAL_FOCUS, - mExclusionRegion); + mExclusionRegion, + DEFAULT_SHOULD_IGNORE_CORNER_RADIUS); assertThat(relayoutParams.mIsCaptionVisible).isFalse(); } @@ -753,7 +784,8 @@ public class DesktopModeWindowDecorationTests extends ShellTestCase { DEFAULT_IS_IN_FULL_IMMERSIVE_MODE, new InsetsState(), DEFAULT_HAS_GLOBAL_FOCUS, - mExclusionRegion); + mExclusionRegion, + DEFAULT_SHOULD_IGNORE_CORNER_RADIUS); assertThat(relayoutParams.mIsCaptionVisible).isFalse(); } @@ -777,7 +809,8 @@ public class DesktopModeWindowDecorationTests extends ShellTestCase { /* inFullImmersiveMode */ true, new InsetsState(), DEFAULT_HAS_GLOBAL_FOCUS, - mExclusionRegion); + mExclusionRegion, + DEFAULT_SHOULD_IGNORE_CORNER_RADIUS); assertThat(relayoutParams.mIsCaptionVisible).isTrue(); @@ -793,7 +826,8 @@ public class DesktopModeWindowDecorationTests extends ShellTestCase { /* inFullImmersiveMode */ true, new InsetsState(), DEFAULT_HAS_GLOBAL_FOCUS, - mExclusionRegion); + mExclusionRegion, + DEFAULT_SHOULD_IGNORE_CORNER_RADIUS); assertThat(relayoutParams.mIsCaptionVisible).isFalse(); } @@ -817,7 +851,8 @@ public class DesktopModeWindowDecorationTests extends ShellTestCase { /* inFullImmersiveMode */ true, new InsetsState(), DEFAULT_HAS_GLOBAL_FOCUS, - mExclusionRegion); + mExclusionRegion, + DEFAULT_SHOULD_IGNORE_CORNER_RADIUS); assertThat(relayoutParams.mIsCaptionVisible).isFalse(); } @@ -1480,7 +1515,8 @@ public class DesktopModeWindowDecorationTests extends ShellTestCase { DEFAULT_IS_IN_FULL_IMMERSIVE_MODE, new InsetsState(), DEFAULT_HAS_GLOBAL_FOCUS, - mExclusionRegion); + mExclusionRegion, + DEFAULT_SHOULD_IGNORE_CORNER_RADIUS); } private DesktopModeWindowDecoration createWindowDecoration( diff --git a/packages/SystemUI/shared/src/com/android/systemui/shared/system/RecentsAnimationListener.java b/packages/SystemUI/shared/src/com/android/systemui/shared/system/RecentsAnimationListener.java index 51892aac606a..ff6bcdb150f8 100644 --- a/packages/SystemUI/shared/src/com/android/systemui/shared/system/RecentsAnimationListener.java +++ b/packages/SystemUI/shared/src/com/android/systemui/shared/system/RecentsAnimationListener.java @@ -19,6 +19,7 @@ package com.android.systemui.shared.system; import android.graphics.Rect; import android.os.Bundle; import android.view.RemoteAnimationTarget; +import android.window.TransitionInfo; import com.android.systemui.shared.recents.model.ThumbnailData; @@ -30,7 +31,7 @@ public interface RecentsAnimationListener { */ void onAnimationStart(RecentsAnimationControllerCompat controller, RemoteAnimationTarget[] apps, RemoteAnimationTarget[] wallpapers, - Rect homeContentInsets, Rect minimizedHomeBounds, Bundle extras); + Rect homeContentInsets, Rect minimizedHomeBounds, Bundle extras, TransitionInfo info); /** * Called when the animation into Recents was canceled. This call is made on the binder thread. |