diff options
author | 2025-03-10 20:39:37 -0700 | |
---|---|---|
committer | 2025-03-10 20:39:37 -0700 | |
commit | 70de18e26ae4c7b409c19c78870a34d1c3ef2c46 (patch) | |
tree | d2e4e4838efe942c914776e48edc735c1db8d4d0 | |
parent | 403ea89a59588178fd9b06c640ef3fe53cb5ff64 (diff) | |
parent | 1eaeaadc3c723a1d47555dfe4b86f72663f77c6c (diff) |
Merge "Tighten requirements for status bar input layer." into main
12 files changed, 268 insertions, 92 deletions
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/freeform/FreeformTaskTransitionObserver.java b/libs/WindowManager/Shell/src/com/android/wm/shell/freeform/FreeformTaskTransitionObserver.java index f89ba0a168d1..0bf2ea61b0a4 100644 --- a/libs/WindowManager/Shell/src/com/android/wm/shell/freeform/FreeformTaskTransitionObserver.java +++ b/libs/WindowManager/Shell/src/com/android/wm/shell/freeform/FreeformTaskTransitionObserver.java @@ -174,7 +174,7 @@ public class FreeformTaskTransitionObserver implements Transitions.TransitionObs SurfaceControl.Transaction finishT) { mTaskChangeListener.ifPresent(listener -> listener.onTaskChanging(change.getTaskInfo())); mWindowDecorViewModel.onTaskChanging( - change.getTaskInfo(), change.getLeash(), startT, finishT); + change.getTaskInfo(), change.getLeash(), startT, finishT, change.getMode()); } private void onToFrontTransitionReady( @@ -184,7 +184,7 @@ public class FreeformTaskTransitionObserver implements Transitions.TransitionObs mTaskChangeListener.ifPresent( listener -> listener.onTaskMovingToFront(change.getTaskInfo())); mWindowDecorViewModel.onTaskChanging( - change.getTaskInfo(), change.getLeash(), startT, finishT); + change.getTaskInfo(), change.getLeash(), startT, finishT, change.getMode()); } private void onToBackTransitionReady( @@ -194,7 +194,7 @@ public class FreeformTaskTransitionObserver implements Transitions.TransitionObs mTaskChangeListener.ifPresent( listener -> listener.onTaskMovingToBack(change.getTaskInfo())); mWindowDecorViewModel.onTaskChanging( - change.getTaskInfo(), change.getLeash(), startT, finishT); + change.getTaskInfo(), change.getLeash(), startT, finishT, change.getMode()); } @Override diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/splitscreen/StageCoordinator.java b/libs/WindowManager/Shell/src/com/android/wm/shell/splitscreen/StageCoordinator.java index 75c09829e551..a7cba76ea91f 100644 --- a/libs/WindowManager/Shell/src/com/android/wm/shell/splitscreen/StageCoordinator.java +++ b/libs/WindowManager/Shell/src/com/android/wm/shell/splitscreen/StageCoordinator.java @@ -123,6 +123,7 @@ import android.view.SurfaceControl; import android.view.WindowManager; import android.widget.Toast; import android.window.DesktopExperienceFlags; +import android.window.DesktopModeFlags; import android.window.DisplayAreaInfo; import android.window.RemoteTransition; import android.window.TransitionInfo; @@ -675,7 +676,8 @@ public class StageCoordinator implements SplitLayout.SplitLayoutHandler, if (!enteredSplitSelect) { return null; } - if (!DesktopExperienceFlags.ENABLE_MULTIPLE_DESKTOPS_BACKEND.isTrue()) { + if (!DesktopExperienceFlags.ENABLE_MULTIPLE_DESKTOPS_BACKEND.isTrue() + && !DesktopModeFlags.ENABLE_INPUT_LAYER_TRANSITION_FIX.isTrue()) { mTaskOrganizer.applyTransaction(wct); return null; } diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/CaptionWindowDecorViewModel.java b/libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/CaptionWindowDecorViewModel.java index 7871179a50de..42321e56e72b 100644 --- a/libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/CaptionWindowDecorViewModel.java +++ b/libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/CaptionWindowDecorViewModel.java @@ -49,6 +49,7 @@ import android.view.SurfaceControl; import android.view.View; import android.view.ViewConfiguration; import android.window.DisplayAreaInfo; +import android.window.TransitionInfo; import android.window.WindowContainerToken; import android.window.WindowContainerTransaction; @@ -233,7 +234,8 @@ public class CaptionWindowDecorViewModel implements WindowDecorViewModel, FocusT RunningTaskInfo taskInfo, SurfaceControl taskSurface, SurfaceControl.Transaction startT, - SurfaceControl.Transaction finishT) { + SurfaceControl.Transaction finishT, + @TransitionInfo.TransitionMode int changeMode) { final CaptionWindowDecoration decoration = mWindowDecorByTaskId.get(taskInfo.taskId); if (!shouldShowWindowDecor(taskInfo)) { diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/CarWindowDecorViewModel.java b/libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/CarWindowDecorViewModel.java index 2b2cdf84005c..4511fbe10764 100644 --- a/libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/CarWindowDecorViewModel.java +++ b/libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/CarWindowDecorViewModel.java @@ -31,6 +31,7 @@ import android.view.KeyCharacterMap; import android.view.KeyEvent; import android.view.SurfaceControl; import android.view.View; +import android.window.TransitionInfo; import android.window.WindowContainerToken; import android.window.WindowContainerTransaction; @@ -159,7 +160,8 @@ public abstract class CarWindowDecorViewModel RunningTaskInfo taskInfo, SurfaceControl taskSurface, SurfaceControl.Transaction startT, - SurfaceControl.Transaction finishT) { + SurfaceControl.Transaction finishT, + @TransitionInfo.TransitionMode int changeMode) { final CarWindowDecoration decoration = mWindowDecorByTaskId.get(taskInfo.taskId); if (!shouldShowWindowDecor(taskInfo)) { 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 febb8850183d..f2ff39627362 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 @@ -27,6 +27,7 @@ import static android.view.MotionEvent.ACTION_HOVER_EXIT; import static android.view.MotionEvent.ACTION_MOVE; import static android.view.MotionEvent.ACTION_UP; import static android.view.WindowInsets.Type.statusBars; +import static android.view.WindowManager.TRANSIT_TO_BACK; import static com.android.internal.jank.Cuj.CUJ_DESKTOP_MODE_ENTER_MODE_APP_HANDLE_MENU; import static com.android.window.flags.Flags.enableDisplayFocusInShellTransitions; @@ -79,6 +80,7 @@ import android.view.ViewConfiguration; import android.view.ViewRootImpl; import android.window.DesktopModeFlags; import android.window.TaskSnapshot; +import android.window.TransitionInfo; import android.window.WindowContainerToken; import android.window.WindowContainerTransaction; @@ -150,18 +152,19 @@ import com.android.wm.shell.windowdecor.extension.InsetsStateKt; import com.android.wm.shell.windowdecor.extension.TaskInfoKt; import com.android.wm.shell.windowdecor.tiling.DesktopTilingDecorViewModel; import com.android.wm.shell.windowdecor.tiling.SnapEventHandler; +import com.android.wm.shell.windowdecor.viewholder.AppHandleViewHolder; import com.android.wm.shell.windowdecor.viewholder.AppHeaderViewHolder; import kotlin.Pair; import kotlin.Unit; import kotlin.jvm.functions.Function1; -import org.jetbrains.annotations.NotNull; - import kotlinx.coroutines.CoroutineScope; import kotlinx.coroutines.ExperimentalCoroutinesApi; import kotlinx.coroutines.MainCoroutineDispatcher; +import org.jetbrains.annotations.NotNull; + import java.io.PrintWriter; import java.util.ArrayList; import java.util.HashSet; @@ -206,6 +209,7 @@ public class DesktopModeWindowDecorViewModel implements WindowDecorViewModel, private final AppToWebEducationController mAppToWebEducationController; private final AppHandleAndHeaderVisibilityHelper mAppHandleAndHeaderVisibilityHelper; private final AppHeaderViewHolder.Factory mAppHeaderViewHolderFactory; + private final AppHandleViewHolder.Factory mAppHandleViewHolderFactory; private boolean mTransitionDragActive; private SparseArray<EventReceiver> mEventReceiversByDisplay = new SparseArray<>(); @@ -331,6 +335,7 @@ public class DesktopModeWindowDecorViewModel implements WindowDecorViewModel, new InputMonitorFactory(), SurfaceControl.Transaction::new, new AppHeaderViewHolder.Factory(), + new AppHandleViewHolder.Factory(), rootTaskDisplayAreaOrganizer, new SparseArray<>(), interactionJankMonitor, @@ -380,6 +385,7 @@ public class DesktopModeWindowDecorViewModel implements WindowDecorViewModel, InputMonitorFactory inputMonitorFactory, Supplier<SurfaceControl.Transaction> transactionFactory, AppHeaderViewHolder.Factory appHeaderViewHolderFactory, + AppHandleViewHolder.Factory appHandleViewHolderFactory, RootTaskDisplayAreaOrganizer rootTaskDisplayAreaOrganizer, SparseArray<DesktopModeWindowDecoration> windowDecorByTaskId, InteractionJankMonitor interactionJankMonitor, @@ -422,6 +428,7 @@ public class DesktopModeWindowDecorViewModel implements WindowDecorViewModel, mInputMonitorFactory = inputMonitorFactory; mTransactionFactory = transactionFactory; mAppHeaderViewHolderFactory = appHeaderViewHolderFactory; + mAppHandleViewHolderFactory = appHandleViewHolderFactory; mRootTaskDisplayAreaOrganizer = rootTaskDisplayAreaOrganizer; mGenericLinksParser = genericLinksParser; mInputManager = mContext.getSystemService(InputManager.class); @@ -486,7 +493,8 @@ public class DesktopModeWindowDecorViewModel implements WindowDecorViewModel, new DesktopModeOnTaskResizeAnimationListener()); mDesktopTasksController.setOnTaskRepositionAnimationListener( new DesktopModeOnTaskRepositionAnimationListener()); - if (DesktopModeFlags.ENABLE_DESKTOP_RECENTS_TRANSITIONS_CORNERS_BUGFIX.isTrue()) { + if (DesktopModeFlags.ENABLE_DESKTOP_RECENTS_TRANSITIONS_CORNERS_BUGFIX.isTrue() + || DesktopModeFlags.ENABLE_INPUT_LAYER_TRANSITION_FIX.isTrue()) { mRecentsTransitionHandler.addTransitionStateListener( new DesktopModeRecentsTransitionStateListener()); } @@ -587,7 +595,8 @@ public class DesktopModeWindowDecorViewModel implements WindowDecorViewModel, RunningTaskInfo taskInfo, SurfaceControl taskSurface, SurfaceControl.Transaction startT, - SurfaceControl.Transaction finishT) { + SurfaceControl.Transaction finishT, + @TransitionInfo.TransitionMode int changeMode) { final DesktopModeWindowDecoration decoration = mWindowDecorByTaskId.get(taskInfo.taskId); if (!shouldShowWindowDecor(taskInfo)) { if (decoration != null) { @@ -601,8 +610,8 @@ public class DesktopModeWindowDecorViewModel implements WindowDecorViewModel, } else { decoration.relayout(taskInfo, startT, finishT, false /* applyStartTransactionOnDraw */, false /* shouldSetTaskPositionAndCrop */, - mFocusTransitionObserver.hasGlobalFocus(taskInfo), - mExclusionRegion); + mFocusTransitionObserver.hasGlobalFocus(taskInfo), mExclusionRegion, + /*isMovingToBack= */ changeMode == TRANSIT_TO_BACK); } } @@ -617,7 +626,7 @@ public class DesktopModeWindowDecorViewModel implements WindowDecorViewModel, decoration.relayout(taskInfo, startT, finishT, false /* applyStartTransactionOnDraw */, false /* shouldSetTaskPositionAndCrop */, mFocusTransitionObserver.hasGlobalFocus(taskInfo), - mExclusionRegion); + mExclusionRegion, /* isMovingToBack= */ false); } @Override @@ -817,9 +826,6 @@ public class DesktopModeWindowDecorViewModel implements WindowDecorViewModel, return; } decoration.closeHandleMenu(); - // When the app enters split-select, the handle will no longer be visible, meaning - // we shouldn't receive input for it any longer. - decoration.disposeStatusBarInputLayer(); mDesktopTasksController.requestSplit(decoration.mTaskInfo, false /* leftOrTop */); mDesktopModeUiEventLogger.log(decoration.mTaskInfo, DesktopUiEventEnum.DESKTOP_WINDOW_APP_HANDLE_MENU_TAP_TO_SPLIT_SCREEN); @@ -1780,6 +1786,7 @@ public class DesktopModeWindowDecorViewModel implements WindowDecorViewModel, mMainChoreographer, mSyncQueue, mAppHeaderViewHolderFactory, + mAppHandleViewHolderFactory, mRootTaskDisplayAreaOrganizer, mGenericLinksParser, mAssistContentRequester, @@ -1871,12 +1878,13 @@ public class DesktopModeWindowDecorViewModel implements WindowDecorViewModel, windowDecoration.relayout(taskInfo, startT, finishT, false /* applyStartTransactionOnDraw */, false /* shouldSetTaskPositionAndCrop */, mFocusTransitionObserver.hasGlobalFocus(taskInfo), - mExclusionRegion); + mExclusionRegion, /* isMovingToBack= */ false); if (!DesktopModeFlags.ENABLE_HANDLE_INPUT_FIX.isTrue()) { incrementEventReceiverTasks(taskInfo.displayId); } } + @Nullable private RunningTaskInfo getOtherSplitTask(int taskId) { @SplitPosition int remainingTaskPosition = mSplitScreenController .getSplitPosition(taskId) == SPLIT_POSITION_BOTTOM_OR_RIGHT 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 5432f6f65afb..003baae29114 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 @@ -190,6 +190,7 @@ public class DesktopModeWindowDecoration extends WindowDecoration<WindowDecorLin private ExclusionRegionListener mExclusionRegionListener; private final AppHeaderViewHolder.Factory mAppHeaderViewHolderFactory; + private final AppHandleViewHolder.Factory mAppHandleViewHolderFactory; private final RootTaskDisplayAreaOrganizer mRootTaskDisplayAreaOrganizer; private final MaximizeMenuFactory mMaximizeMenuFactory; private final HandleMenuFactory mHandleMenuFactory; @@ -212,6 +213,7 @@ public class DesktopModeWindowDecoration extends WindowDecoration<WindowDecorLin private boolean mIsDragging = false; private Runnable mLoadAppInfoRunnable; private Runnable mSetAppInfoRunnable; + private boolean mIsMovingToBack; public DesktopModeWindowDecoration( Context context, @@ -231,6 +233,7 @@ public class DesktopModeWindowDecoration extends WindowDecoration<WindowDecorLin Choreographer choreographer, SyncTransactionQueue syncQueue, AppHeaderViewHolder.Factory appHeaderViewHolderFactory, + AppHandleViewHolder.Factory appHandleViewHolderFactory, RootTaskDisplayAreaOrganizer rootTaskDisplayAreaOrganizer, AppToWebGenericLinksParser genericLinksParser, AssistContentRequester assistContentRequester, @@ -242,10 +245,10 @@ public class DesktopModeWindowDecoration extends WindowDecoration<WindowDecorLin this (context, userContext, displayController, taskResourceLoader, splitScreenController, desktopUserRepositories, taskOrganizer, taskInfo, taskSurface, handler, mainExecutor, mainDispatcher, bgScope, bgExecutor, choreographer, syncQueue, - appHeaderViewHolderFactory, rootTaskDisplayAreaOrganizer, genericLinksParser, - assistContentRequester, SurfaceControl.Builder::new, - SurfaceControl.Transaction::new, WindowContainerTransaction::new, - SurfaceControl::new, new WindowManagerWrapper( + appHeaderViewHolderFactory, appHandleViewHolderFactory, + rootTaskDisplayAreaOrganizer, genericLinksParser, assistContentRequester, + SurfaceControl.Builder::new, SurfaceControl.Transaction::new, + WindowContainerTransaction::new, SurfaceControl::new, new WindowManagerWrapper( context.getSystemService(WindowManager.class)), new SurfaceControlViewHostFactory() {}, windowDecorViewHostSupplier, @@ -273,6 +276,7 @@ public class DesktopModeWindowDecoration extends WindowDecoration<WindowDecorLin Choreographer choreographer, SyncTransactionQueue syncQueue, AppHeaderViewHolder.Factory appHeaderViewHolderFactory, + AppHandleViewHolder.Factory appHandleViewHolderFactory, RootTaskDisplayAreaOrganizer rootTaskDisplayAreaOrganizer, AppToWebGenericLinksParser genericLinksParser, AssistContentRequester assistContentRequester, @@ -302,6 +306,7 @@ public class DesktopModeWindowDecoration extends WindowDecoration<WindowDecorLin mChoreographer = choreographer; mSyncQueue = syncQueue; mAppHeaderViewHolderFactory = appHeaderViewHolderFactory; + mAppHandleViewHolderFactory = appHandleViewHolderFactory; mRootTaskDisplayAreaOrganizer = rootTaskDisplayAreaOrganizer; mGenericLinksParser = genericLinksParser; mAssistContentRequester = assistContentRequester; @@ -462,7 +467,7 @@ public class DesktopModeWindowDecoration extends WindowDecoration<WindowDecorLin // causes flickering. See b/270202228. final boolean applyTransactionOnDraw = taskInfo.isFreeform(); relayout(taskInfo, t, t, applyTransactionOnDraw, shouldSetTaskVisibilityPositionAndCrop, - hasGlobalFocus, displayExclusionRegion); + hasGlobalFocus, displayExclusionRegion, mIsMovingToBack); if (!applyTransactionOnDraw) { t.apply(); } @@ -489,7 +494,8 @@ public class DesktopModeWindowDecoration extends WindowDecoration<WindowDecorLin void relayout(ActivityManager.RunningTaskInfo taskInfo, SurfaceControl.Transaction startT, SurfaceControl.Transaction finishT, boolean applyStartTransactionOnDraw, boolean shouldSetTaskVisibilityPositionAndCrop, - boolean hasGlobalFocus, @NonNull Region displayExclusionRegion) { + boolean hasGlobalFocus, @NonNull Region displayExclusionRegion, + boolean isMovingToBack) { Trace.beginSection("DesktopModeWindowDecoration#relayout"); if (DesktopModeFlags.ENABLE_DESKTOP_WINDOWING_APP_TO_WEB.isTrue()) { @@ -512,12 +518,17 @@ public class DesktopModeWindowDecoration extends WindowDecoration<WindowDecorLin final boolean inFullImmersive = mDesktopUserRepositories.getProfile(taskInfo.userId) .isTaskInFullImmersiveState(taskInfo.taskId); + mIsMovingToBack = isMovingToBack; updateRelayoutParams(mRelayoutParams, mContext, taskInfo, mSplitScreenController, applyStartTransactionOnDraw, shouldSetTaskVisibilityPositionAndCrop, mIsStatusBarVisible, mIsKeyguardVisibleAndOccluded, inFullImmersive, mIsDragging, mDisplayController.getInsetsState(taskInfo.displayId), hasGlobalFocus, - displayExclusionRegion, mIsRecentsTransitionRunning, - mDesktopModeCompatPolicy.shouldExcludeCaptionFromAppBounds(taskInfo)); + displayExclusionRegion, + /* shouldIgnoreCornerRadius= */ mIsRecentsTransitionRunning + && DesktopModeFlags + .ENABLE_DESKTOP_RECENTS_TRANSITIONS_CORNERS_BUGFIX.isTrue(), + mDesktopModeCompatPolicy.shouldExcludeCaptionFromAppBounds(taskInfo), + mIsRecentsTransitionRunning, mIsMovingToBack); final WindowDecorLinearLayout oldRootView = mResult.mRootView; final SurfaceControl oldDecorationSurface = mDecorationContainerSurface; @@ -558,29 +569,15 @@ public class DesktopModeWindowDecoration extends WindowDecoration<WindowDecorLin }); } - final Point position = new Point(); - if (isAppHandle(mWindowDecorViewHolder)) { - position.set(determineHandlePosition()); - } if (canEnterDesktopMode(mContext) && isEducationEnabled()) { notifyCaptionStateChanged(); } Trace.beginSection("DesktopModeWindowDecoration#relayout-bindData"); if (isAppHandle(mWindowDecorViewHolder)) { - mWindowDecorViewHolder.bindData(new AppHandleViewHolder.HandleData( - mTaskInfo, position, mResult.mCaptionWidth, mResult.mCaptionHeight, - isCaptionVisible() - )); + updateAppHandleViewHolder(); } else { - mWindowDecorViewHolder.bindData(new AppHeaderViewHolder.HeaderData( - mTaskInfo, - DesktopModeUtils.isTaskMaximized(mTaskInfo, mDisplayController), - inFullImmersive, - hasGlobalFocus, - /* maximizeHoverEnabled= */ canOpenMaximizeMenu( - /* animatingTaskResizeOrReposition= */ false) - )); + updateAppHeaderViewHolder(inFullImmersive, hasGlobalFocus); } Trace.endSection(); @@ -857,9 +854,31 @@ public class DesktopModeWindowDecoration extends WindowDecoration<WindowDecorLin asAppHandle(mWindowDecorViewHolder).disposeStatusBarInputLayer(); } + /** Update the view holder for app handle. */ + private void updateAppHandleViewHolder() { + if (!isAppHandle(mWindowDecorViewHolder)) return; + asAppHandle(mWindowDecorViewHolder).bindData(new AppHandleViewHolder.HandleData( + mTaskInfo, determineHandlePosition(), mResult.mCaptionWidth, + mResult.mCaptionHeight, isCaptionVisible() + )); + } + + /** Update the view holder for app header. */ + private void updateAppHeaderViewHolder(boolean inFullImmersive, boolean hasGlobalFocus) { + if (!isAppHeader(mWindowDecorViewHolder)) return; + asAppHeader(mWindowDecorViewHolder).bindData(new AppHeaderViewHolder.HeaderData( + mTaskInfo, + DesktopModeUtils.isTaskMaximized(mTaskInfo, mDisplayController), + inFullImmersive, + hasGlobalFocus, + /* maximizeHoverEnabled= */ canOpenMaximizeMenu( + /* animatingTaskResizeOrReposition= */ false) + )); + } + private WindowDecorationViewHolder createViewHolder() { if (mRelayoutParams.mLayoutResId == R.layout.desktop_mode_app_handle) { - return new AppHandleViewHolder( + return mAppHandleViewHolderFactory.create( mResult.mRootView, mOnCaptionTouchListener, mOnCaptionButtonClickListener, @@ -886,6 +905,10 @@ public class DesktopModeWindowDecoration extends WindowDecoration<WindowDecorLin return viewHolder instanceof AppHandleViewHolder; } + private boolean isAppHeader(WindowDecorationViewHolder viewHolder) { + return viewHolder instanceof AppHeaderViewHolder; + } + @Nullable private AppHandleViewHolder asAppHandle(WindowDecorationViewHolder viewHolder) { if (viewHolder instanceof AppHandleViewHolder) { @@ -918,7 +941,9 @@ public class DesktopModeWindowDecoration extends WindowDecoration<WindowDecorLin boolean hasGlobalFocus, @NonNull Region displayExclusionRegion, boolean shouldIgnoreCornerRadius, - boolean shouldExcludeCaptionFromAppBounds) { + boolean shouldExcludeCaptionFromAppBounds, + boolean isRecentsTransitionRunning, + boolean isMovingToBack) { final int captionLayoutId = getDesktopModeWindowDecorLayoutId(taskInfo.getWindowingMode()); final boolean isAppHeader = captionLayoutId == R.layout.desktop_mode_app_header; @@ -935,11 +960,20 @@ public class DesktopModeWindowDecoration extends WindowDecoration<WindowDecorLin // the first frame. relayoutParams.mAsyncViewHost = isAppHandle; - final boolean showCaption; - if (DesktopModeFlags.ENABLE_DESKTOP_IMMERSIVE_DRAG_BUGFIX.isTrue() && isDragging) { + boolean showCaption; + // If this relayout is occurring from an observed TRANSIT_TO_BACK transition, do not + // show caption (this includes split select transition). + if (DesktopModeFlags.ENABLE_INPUT_LAYER_TRANSITION_FIX.isTrue() + && isMovingToBack && !isDragging) { + showCaption = false; + } else if (DesktopModeFlags.ENABLE_DESKTOP_IMMERSIVE_DRAG_BUGFIX.isTrue() && isDragging) { // If the task is being dragged, the caption should not be hidden so that it continues // receiving input showCaption = true; + } else if (DesktopModeFlags.ENABLE_INPUT_LAYER_TRANSITION_FIX.isTrue() + && isRecentsTransitionRunning) { + // Caption should not be visible in recents. + showCaption = false; } else if (DesktopModeFlags.ENABLE_FULLY_IMMERSIVE_IN_DESKTOP.isTrue()) { if (inFullImmersiveMode) { showCaption = (isStatusBarVisible && !isKeyguardVisibleAndOccluded); @@ -1811,9 +1845,18 @@ public class DesktopModeWindowDecoration extends WindowDecoration<WindowDecorLin * <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. + * + * We should not allow input to reach the input layer during a Recents transition, so + * update the handle view holder accordingly if transition status changes. */ void setIsRecentsTransitionRunning(boolean isRecentsTransitionRunning) { - mIsRecentsTransitionRunning = isRecentsTransitionRunning; + if (mIsRecentsTransitionRunning != isRecentsTransitionRunning) { + mIsRecentsTransitionRunning = isRecentsTransitionRunning; + if (DesktopModeFlags.ENABLE_INPUT_LAYER_TRANSITION_FIX.isTrue()) { + // We don't relayout decor on recents transition, so we need to call it directly. + relayout(mTaskInfo, mHasGlobalFocus, mRelayoutParams.mDisplayExclusionRegion); + } + } } /** @@ -1878,6 +1921,7 @@ public class DesktopModeWindowDecoration extends WindowDecoration<WindowDecorLin Choreographer choreographer, SyncTransactionQueue syncQueue, AppHeaderViewHolder.Factory appHeaderViewHolderFactory, + AppHandleViewHolder.Factory appHandleViewHolderFactory, RootTaskDisplayAreaOrganizer rootTaskDisplayAreaOrganizer, AppToWebGenericLinksParser genericLinksParser, AssistContentRequester assistContentRequester, @@ -1905,6 +1949,7 @@ public class DesktopModeWindowDecoration extends WindowDecoration<WindowDecorLin choreographer, syncQueue, appHeaderViewHolderFactory, + appHandleViewHolderFactory, rootTaskDisplayAreaOrganizer, genericLinksParser, assistContentRequester, diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/WindowDecorViewModel.java b/libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/WindowDecorViewModel.java index 1563259f4a1a..5e4a0a5860f0 100644 --- a/libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/WindowDecorViewModel.java +++ b/libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/WindowDecorViewModel.java @@ -18,6 +18,7 @@ package com.android.wm.shell.windowdecor; import android.app.ActivityManager; import android.view.SurfaceControl; +import android.window.TransitionInfo; import com.android.wm.shell.freeform.FreeformTaskTransitionStarter; import com.android.wm.shell.splitscreen.SplitScreenController; @@ -83,12 +84,14 @@ public interface WindowDecorViewModel { * @param taskSurface the surface of the task * @param startT the start transaction to be applied before the transition * @param finishT the finish transaction to restore states after the transition + * @param changeMode the type of change to the task */ void onTaskChanging( ActivityManager.RunningTaskInfo taskInfo, SurfaceControl taskSurface, SurfaceControl.Transaction startT, - SurfaceControl.Transaction finishT); + SurfaceControl.Transaction finishT, + @TransitionInfo.TransitionMode int changeMode); /** * Notifies that the given task is about to close to give the window decoration a chance to diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/viewholder/AppHandleViewHolder.kt b/libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/viewholder/AppHandleViewHolder.kt index d9df899f8b40..0985587a330e 100644 --- a/libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/viewholder/AppHandleViewHolder.kt +++ b/libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/viewholder/AppHandleViewHolder.kt @@ -49,7 +49,7 @@ import com.android.wm.shell.windowdecor.additionalviewcontainer.AdditionalSystem * A desktop mode window decoration used when the window is in full "focus" (i.e. fullscreen/split). * It hosts a simple handle bar from which to initiate a drag motion to enter desktop mode. */ -internal class AppHandleViewHolder( +class AppHandleViewHolder( rootView: View, onCaptionTouchListener: View.OnTouchListener, onCaptionButtonClickListener: OnClickListener, @@ -66,7 +66,7 @@ internal class AppHandleViewHolder( val position: Point, val width: Int, val height: Int, - val isCaptionVisible: Boolean + val showInputLayer: Boolean ) : Data() private lateinit var taskInfo: RunningTaskInfo @@ -101,7 +101,7 @@ internal class AppHandleViewHolder( } override fun bindData(data: HandleData) { - bindData(data.taskInfo, data.position, data.width, data.height, data.isCaptionVisible) + bindData(data.taskInfo, data.position, data.width, data.height, data.showInputLayer) } private fun bindData( @@ -109,14 +109,13 @@ internal class AppHandleViewHolder( position: Point, width: Int, height: Int, - isCaptionVisible: Boolean + showInputLayer: Boolean ) { captionHandle.imageTintList = ColorStateList.valueOf(getCaptionHandleBarColor(taskInfo)) this.taskInfo = taskInfo // If handle is not in status bar region(i.e., bottom stage in vertical split), // do not create an input layer - if (position.y >= SystemBarUtils.getStatusBarHeight(context)) return - if (!isCaptionVisible) { + if (position.y >= SystemBarUtils.getStatusBarHeight(context) || !showInputLayer) { disposeStatusBarInputLayer() return } @@ -276,4 +275,25 @@ internal class AppHandleViewHolder( } override fun close() {} + + /** Factory class for creating [AppHandleViewHolder] objects. */ + class Factory { + /** + * Create a [AppHandleViewHolder] object to handle caption view and status bar + * input layer logic. + */ + fun create( + rootView: View, + onCaptionTouchListener: View.OnTouchListener, + onCaptionButtonClickListener: OnClickListener, + windowManagerWrapper: WindowManagerWrapper, + handler: Handler, + ): AppHandleViewHolder = AppHandleViewHolder( + rootView, + onCaptionTouchListener, + onCaptionButtonClickListener, + windowManagerWrapper, + handler, + ) + } } diff --git a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/windowdecor/DesktopModeWindowDecorViewModelAppHandleOnlyTest.kt b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/windowdecor/DesktopModeWindowDecorViewModelAppHandleOnlyTest.kt index 067dcec5d65d..b1f92411c5a3 100644 --- a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/windowdecor/DesktopModeWindowDecorViewModelAppHandleOnlyTest.kt +++ b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/windowdecor/DesktopModeWindowDecorViewModelAppHandleOnlyTest.kt @@ -28,6 +28,7 @@ import android.testing.TestableLooper.RunWithLooper import android.view.Display import android.view.Display.DEFAULT_DISPLAY import android.view.SurfaceControl +import android.view.WindowManager.TRANSIT_CHANGE import androidx.test.filters.SmallTest import com.android.dx.mockito.inline.extended.ExtendedMockito.anyBoolean import com.android.dx.mockito.inline.extended.ExtendedMockito.doReturn @@ -109,7 +110,7 @@ class DesktopModeWindowDecorViewModelAppHandleOnlyTest : onTaskOpening(task, taskSurface) assertTrue(windowDecorByTaskIdSpy.contains(task.taskId)) task.setActivityType(ACTIVITY_TYPE_UNDEFINED) - onTaskChanging(task, taskSurface) + onTaskChanging(task, taskSurface, TRANSIT_CHANGE) assertFalse(windowDecorByTaskIdSpy.contains(task.taskId)) verify(decoration).close() @@ -165,7 +166,7 @@ class DesktopModeWindowDecorViewModelAppHandleOnlyTest : setLargeScreen(false) setUpMockDecorationForTask(task) - onTaskChanging(task, taskSurface) + onTaskChanging(task, taskSurface, TRANSIT_CHANGE) assertFalse(windowDecorByTaskIdSpy.contains(task.taskId)) } 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 d69509faf4ec..ad3426e82805 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 @@ -51,6 +51,7 @@ import android.view.SurfaceView import android.view.View import android.view.ViewRootImpl import android.view.WindowInsets.Type.statusBars +import android.view.WindowManager.TRANSIT_CHANGE import android.window.WindowContainerTransaction import android.window.WindowContainerTransaction.HierarchyOp import androidx.test.filters.SmallTest @@ -134,7 +135,7 @@ class DesktopModeWindowDecorViewModelTests : DesktopModeWindowDecorViewModelTest task.setWindowingMode(WINDOWING_MODE_UNDEFINED) task.setActivityType(ACTIVITY_TYPE_UNDEFINED) - onTaskChanging(task, taskSurface) + onTaskChanging(task, taskSurface, TRANSIT_CHANGE) assertFalse(windowDecorByTaskIdSpy.contains(task.taskId)) verify(decoration).close() @@ -149,12 +150,12 @@ class DesktopModeWindowDecorViewModelTests : DesktopModeWindowDecorViewModelTest val taskSurface = SurfaceControl() setUpMockDecorationForTask(task) - onTaskChanging(task, taskSurface) + onTaskChanging(task, taskSurface, TRANSIT_CHANGE) assertFalse(windowDecorByTaskIdSpy.contains(task.taskId)) task.setWindowingMode(WINDOWING_MODE_FREEFORM) task.setActivityType(ACTIVITY_TYPE_STANDARD) - onTaskChanging(task, taskSurface) + onTaskChanging(task, taskSurface, TRANSIT_CHANGE) assertTrue(windowDecorByTaskIdSpy.contains(task.taskId)) } @@ -758,20 +759,6 @@ class DesktopModeWindowDecorViewModelTests : DesktopModeWindowDecorViewModelTest } @Test - fun testDecor_onClickToSplitScreen_disposesStatusBarInputLayer() { - val toSplitScreenListenerCaptor = forClass(Function0::class.java) - as ArgumentCaptor<Function0<Unit>> - val decor = createOpenTaskDecoration( - windowingMode = WINDOWING_MODE_MULTI_WINDOW, - onToSplitScreenClickListenerCaptor = toSplitScreenListenerCaptor - ) - - toSplitScreenListenerCaptor.value.invoke() - - verify(decor).disposeStatusBarInputLayer() - } - - @Test fun testDecor_onClickToOpenBrowser_closeMenus() { val openInBrowserListenerCaptor = forClass(Consumer::class.java) as ArgumentCaptor<Consumer<Intent>> 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 a1f40fdefee9..4c9c2f14d805 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 @@ -84,6 +84,7 @@ import com.android.wm.shell.windowdecor.common.WindowDecorTaskResourceLoader import com.android.wm.shell.windowdecor.common.viewhost.WindowDecorViewHost import com.android.wm.shell.windowdecor.common.viewhost.WindowDecorViewHostSupplier import com.android.wm.shell.windowdecor.tiling.DesktopTilingDecorViewModel +import com.android.wm.shell.windowdecor.viewholder.AppHandleViewHolder import com.android.wm.shell.windowdecor.viewholder.AppHeaderViewHolder import org.junit.After import org.mockito.Mockito @@ -125,6 +126,7 @@ open class DesktopModeWindowDecorViewModelTestsBase : ShellTestCase() { protected val mockShellController = mock<ShellController>() protected val testShellExecutor = TestShellExecutor() protected val mockAppHeaderViewHolderFactory = mock<AppHeaderViewHolder.Factory>() + protected val mockAppHandleViewHolderFactory = mock<AppHandleViewHolder.Factory>() protected val mockRootTaskDisplayAreaOrganizer = mock<RootTaskDisplayAreaOrganizer>() protected val mockShellCommandHandler = mock<ShellCommandHandler>() protected val mockWindowManager = mock<IWindowManager>() @@ -222,6 +224,7 @@ open class DesktopModeWindowDecorViewModelTestsBase : ShellTestCase() { mockInputMonitorFactory, transactionFactory, mockAppHeaderViewHolderFactory, + mockAppHandleViewHolderFactory, mockRootTaskDisplayAreaOrganizer, windowDecorByTaskIdSpy, mockInteractionJankMonitor, @@ -331,7 +334,7 @@ open class DesktopModeWindowDecorViewModelTestsBase : ShellTestCase() { mockDesktopModeWindowDecorFactory.create( any(), any(), any(), any(), any(), any(), any(), eq(task), any(), any(), any(), any(), any(), any(), any(), any(), any(), any(), any(), any(), any(), any(), - any(), any(), any()) + any(), any(), any(), any()) ).thenReturn(decoration) decoration.mTaskInfo = task whenever(decoration.user).thenReturn(mockUserHandle) @@ -353,12 +356,17 @@ open class DesktopModeWindowDecorViewModelTestsBase : ShellTestCase() { ) } - protected fun onTaskChanging(task: RunningTaskInfo, leash: SurfaceControl = SurfaceControl()) { + protected fun onTaskChanging( + task: RunningTaskInfo, + leash: SurfaceControl = SurfaceControl(), + changeMode: Int + ) { desktopModeWindowDecorViewModel.onTaskChanging( task, leash, StubTransaction(), - StubTransaction() + StubTransaction(), + changeMode ) } 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 878324937f1a..f37f2fb14bea 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 @@ -115,6 +115,7 @@ import com.android.wm.shell.windowdecor.WindowDecoration.RelayoutParams; import com.android.wm.shell.windowdecor.common.WindowDecorTaskResourceLoader; import com.android.wm.shell.windowdecor.common.viewhost.WindowDecorViewHost; import com.android.wm.shell.windowdecor.common.viewhost.WindowDecorViewHostSupplier; +import com.android.wm.shell.windowdecor.viewholder.AppHandleViewHolder; import com.android.wm.shell.windowdecor.viewholder.AppHeaderViewHolder; import kotlin.Unit; @@ -171,6 +172,9 @@ public class DesktopModeWindowDecorationTests extends ShellTestCase { private static final boolean DEFAULT_HAS_GLOBAL_FOCUS = true; private static final boolean DEFAULT_SHOULD_IGNORE_CORNER_RADIUS = false; private static final boolean DEFAULT_SHOULD_EXCLUDE_CAPTION_FROM_APP_BOUNDS = false; + private static final boolean DEFAULT_IS_RECENTS_TRANSITION_RUNNING = false; + private static final boolean DEFAULT_IS_MOVING_TO_BACK = false; + @Mock private DisplayController mMockDisplayController; @@ -191,8 +195,12 @@ public class DesktopModeWindowDecorationTests extends ShellTestCase { @Mock private AppHeaderViewHolder.Factory mMockAppHeaderViewHolderFactory; @Mock + private AppHandleViewHolder.Factory mMockAppHandleViewHolderFactory; + @Mock private AppHeaderViewHolder mMockAppHeaderViewHolder; @Mock + private AppHandleViewHolder mMockAppHandleViewHolder; + @Mock private RootTaskDisplayAreaOrganizer mMockRootTaskDisplayAreaOrganizer; @Mock private Supplier<SurfaceControl.Transaction> mMockTransactionSupplier; @@ -301,6 +309,9 @@ public class DesktopModeWindowDecorationTests extends ShellTestCase { when(mMockAppHeaderViewHolderFactory .create(any(), any(), any(), any(), any(), any(), any(), any(), any())) .thenReturn(mMockAppHeaderViewHolder); + when(mMockAppHandleViewHolderFactory + .create(any(), any(), any(), any(), any())) + .thenReturn(mMockAppHandleViewHolder); when(mMockDesktopUserRepositories.getCurrent()).thenReturn(mDesktopRepository); when(mMockDesktopUserRepositories.getProfile(anyInt())).thenReturn(mDesktopRepository); when(mMockWindowDecorViewHostSupplier.acquire(any(), eq(defaultDisplay))) @@ -421,7 +432,9 @@ public class DesktopModeWindowDecorationTests extends ShellTestCase { DEFAULT_HAS_GLOBAL_FOCUS, mExclusionRegion, /* shouldIgnoreCornerRadius= */ true, - DEFAULT_SHOULD_EXCLUDE_CAPTION_FROM_APP_BOUNDS); + DEFAULT_SHOULD_EXCLUDE_CAPTION_FROM_APP_BOUNDS, + DEFAULT_IS_RECENTS_TRANSITION_RUNNING, + DEFAULT_IS_MOVING_TO_BACK); assertThat(relayoutParams.mCornerRadius).isEqualTo(INVALID_CORNER_RADIUS); } @@ -623,7 +636,9 @@ public class DesktopModeWindowDecorationTests extends ShellTestCase { DEFAULT_HAS_GLOBAL_FOCUS, mExclusionRegion, DEFAULT_SHOULD_IGNORE_CORNER_RADIUS, - /* shouldExcludeCaptionFromAppBounds */ true); + /* shouldExcludeCaptionFromAppBounds */ true, + DEFAULT_IS_RECENTS_TRANSITION_RUNNING, + DEFAULT_IS_MOVING_TO_BACK); // Force consuming flags are disabled. assertThat((relayoutParams.mInsetSourceFlags & FLAG_FORCE_CONSUMING) == 0).isTrue(); @@ -658,7 +673,9 @@ public class DesktopModeWindowDecorationTests extends ShellTestCase { DEFAULT_HAS_GLOBAL_FOCUS, mExclusionRegion, DEFAULT_SHOULD_IGNORE_CORNER_RADIUS, - DEFAULT_SHOULD_EXCLUDE_CAPTION_FROM_APP_BOUNDS); + DEFAULT_SHOULD_EXCLUDE_CAPTION_FROM_APP_BOUNDS, + DEFAULT_IS_RECENTS_TRANSITION_RUNNING, + DEFAULT_IS_MOVING_TO_BACK); assertThat((relayoutParams.mInsetSourceFlags & FLAG_FORCE_CONSUMING) != 0).isTrue(); assertThat( @@ -737,7 +754,9 @@ public class DesktopModeWindowDecorationTests extends ShellTestCase { DEFAULT_HAS_GLOBAL_FOCUS, mExclusionRegion, DEFAULT_SHOULD_IGNORE_CORNER_RADIUS, - DEFAULT_SHOULD_EXCLUDE_CAPTION_FROM_APP_BOUNDS); + DEFAULT_SHOULD_EXCLUDE_CAPTION_FROM_APP_BOUNDS, + DEFAULT_IS_RECENTS_TRANSITION_RUNNING, + DEFAULT_IS_MOVING_TO_BACK); // Takes status bar inset as padding, ignores caption bar inset. assertThat(relayoutParams.mCaptionTopPadding).isEqualTo(50); @@ -765,7 +784,9 @@ public class DesktopModeWindowDecorationTests extends ShellTestCase { DEFAULT_HAS_GLOBAL_FOCUS, mExclusionRegion, DEFAULT_SHOULD_IGNORE_CORNER_RADIUS, - DEFAULT_SHOULD_EXCLUDE_CAPTION_FROM_APP_BOUNDS); + DEFAULT_SHOULD_EXCLUDE_CAPTION_FROM_APP_BOUNDS, + DEFAULT_IS_RECENTS_TRANSITION_RUNNING, + DEFAULT_IS_MOVING_TO_BACK); assertThat(relayoutParams.mIsInsetSource).isFalse(); } @@ -792,7 +813,9 @@ public class DesktopModeWindowDecorationTests extends ShellTestCase { DEFAULT_HAS_GLOBAL_FOCUS, mExclusionRegion, DEFAULT_SHOULD_IGNORE_CORNER_RADIUS, - DEFAULT_SHOULD_EXCLUDE_CAPTION_FROM_APP_BOUNDS); + DEFAULT_SHOULD_EXCLUDE_CAPTION_FROM_APP_BOUNDS, + DEFAULT_IS_RECENTS_TRANSITION_RUNNING, + DEFAULT_IS_MOVING_TO_BACK); // Header is always shown because it's assumed the status bar is always visible. assertThat(relayoutParams.mIsCaptionVisible).isTrue(); @@ -819,7 +842,9 @@ public class DesktopModeWindowDecorationTests extends ShellTestCase { DEFAULT_HAS_GLOBAL_FOCUS, mExclusionRegion, DEFAULT_SHOULD_IGNORE_CORNER_RADIUS, - DEFAULT_SHOULD_EXCLUDE_CAPTION_FROM_APP_BOUNDS); + DEFAULT_SHOULD_EXCLUDE_CAPTION_FROM_APP_BOUNDS, + DEFAULT_IS_RECENTS_TRANSITION_RUNNING, + DEFAULT_IS_MOVING_TO_BACK); assertThat(relayoutParams.mIsCaptionVisible).isTrue(); } @@ -845,7 +870,9 @@ public class DesktopModeWindowDecorationTests extends ShellTestCase { DEFAULT_HAS_GLOBAL_FOCUS, mExclusionRegion, DEFAULT_SHOULD_IGNORE_CORNER_RADIUS, - DEFAULT_SHOULD_EXCLUDE_CAPTION_FROM_APP_BOUNDS); + DEFAULT_SHOULD_EXCLUDE_CAPTION_FROM_APP_BOUNDS, + DEFAULT_IS_RECENTS_TRANSITION_RUNNING, + DEFAULT_IS_MOVING_TO_BACK); assertThat(relayoutParams.mIsCaptionVisible).isFalse(); } @@ -871,7 +898,9 @@ public class DesktopModeWindowDecorationTests extends ShellTestCase { DEFAULT_HAS_GLOBAL_FOCUS, mExclusionRegion, DEFAULT_SHOULD_IGNORE_CORNER_RADIUS, - DEFAULT_SHOULD_EXCLUDE_CAPTION_FROM_APP_BOUNDS); + DEFAULT_SHOULD_EXCLUDE_CAPTION_FROM_APP_BOUNDS, + DEFAULT_IS_RECENTS_TRANSITION_RUNNING, + DEFAULT_IS_MOVING_TO_BACK); assertThat(relayoutParams.mIsCaptionVisible).isFalse(); } @@ -898,7 +927,9 @@ public class DesktopModeWindowDecorationTests extends ShellTestCase { DEFAULT_HAS_GLOBAL_FOCUS, mExclusionRegion, DEFAULT_SHOULD_IGNORE_CORNER_RADIUS, - DEFAULT_SHOULD_EXCLUDE_CAPTION_FROM_APP_BOUNDS); + DEFAULT_SHOULD_EXCLUDE_CAPTION_FROM_APP_BOUNDS, + DEFAULT_IS_RECENTS_TRANSITION_RUNNING, + DEFAULT_IS_MOVING_TO_BACK); assertThat(relayoutParams.mIsCaptionVisible).isTrue(); @@ -917,7 +948,9 @@ public class DesktopModeWindowDecorationTests extends ShellTestCase { DEFAULT_HAS_GLOBAL_FOCUS, mExclusionRegion, DEFAULT_SHOULD_IGNORE_CORNER_RADIUS, - DEFAULT_SHOULD_EXCLUDE_CAPTION_FROM_APP_BOUNDS); + DEFAULT_SHOULD_EXCLUDE_CAPTION_FROM_APP_BOUNDS, + DEFAULT_IS_RECENTS_TRANSITION_RUNNING, + DEFAULT_IS_MOVING_TO_BACK); assertThat(relayoutParams.mIsCaptionVisible).isFalse(); } @@ -944,7 +977,9 @@ public class DesktopModeWindowDecorationTests extends ShellTestCase { DEFAULT_HAS_GLOBAL_FOCUS, mExclusionRegion, DEFAULT_SHOULD_IGNORE_CORNER_RADIUS, - DEFAULT_SHOULD_EXCLUDE_CAPTION_FROM_APP_BOUNDS); + DEFAULT_SHOULD_EXCLUDE_CAPTION_FROM_APP_BOUNDS, + DEFAULT_IS_RECENTS_TRANSITION_RUNNING, + DEFAULT_IS_MOVING_TO_BACK); assertThat(relayoutParams.mIsCaptionVisible).isTrue(); } @@ -971,7 +1006,9 @@ public class DesktopModeWindowDecorationTests extends ShellTestCase { DEFAULT_HAS_GLOBAL_FOCUS, mExclusionRegion, DEFAULT_SHOULD_IGNORE_CORNER_RADIUS, - DEFAULT_SHOULD_EXCLUDE_CAPTION_FROM_APP_BOUNDS); + DEFAULT_SHOULD_EXCLUDE_CAPTION_FROM_APP_BOUNDS, + DEFAULT_IS_RECENTS_TRANSITION_RUNNING, + DEFAULT_IS_MOVING_TO_BACK); assertThat(relayoutParams.mIsCaptionVisible).isFalse(); } @@ -1002,6 +1039,65 @@ public class DesktopModeWindowDecorationTests extends ShellTestCase { assertThat(relayoutParams.mAsyncViewHost).isFalse(); } + + @Test + @EnableFlags(Flags.FLAG_ENABLE_INPUT_LAYER_TRANSITION_FIX) + public void updateRelayoutParams_handle_movingToBack_captionNotVisible() { + final ActivityManager.RunningTaskInfo taskInfo = createTaskInfo(/* visible= */ true); + taskInfo.configuration.windowConfiguration.setWindowingMode(WINDOWING_MODE_FULLSCREEN); + final 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, + DEFAULT_IS_DRAGGING, + new InsetsState(), + DEFAULT_HAS_GLOBAL_FOCUS, + mExclusionRegion, + DEFAULT_SHOULD_IGNORE_CORNER_RADIUS, + DEFAULT_SHOULD_EXCLUDE_CAPTION_FROM_APP_BOUNDS, + DEFAULT_IS_RECENTS_TRANSITION_RUNNING, + /* isMovingToBack= */ true); + + assertThat(relayoutParams.mIsCaptionVisible).isFalse(); + } + + @Test + @EnableFlags(Flags.FLAG_ENABLE_INPUT_LAYER_TRANSITION_FIX) + public void updateRelayoutParams_handle_inRecentsTransition_captionNotVisible() { + final ActivityManager.RunningTaskInfo taskInfo = createTaskInfo(/* visible= */ true); + taskInfo.configuration.windowConfiguration.setWindowingMode(WINDOWING_MODE_FULLSCREEN); + final 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, + DEFAULT_IS_DRAGGING, + new InsetsState(), + DEFAULT_HAS_GLOBAL_FOCUS, + mExclusionRegion, + DEFAULT_SHOULD_IGNORE_CORNER_RADIUS, + DEFAULT_SHOULD_EXCLUDE_CAPTION_FROM_APP_BOUNDS, + /* isRecentsTransitionRunning= */ true, + DEFAULT_IS_MOVING_TO_BACK); + + assertThat(relayoutParams.mIsCaptionVisible).isFalse(); + } + @Test public void relayout_fullscreenTask_appliesTransactionImmediately() { final ActivityManager.RunningTaskInfo taskInfo = createTaskInfo(/* visible= */ true); @@ -1633,7 +1729,9 @@ public class DesktopModeWindowDecorationTests extends ShellTestCase { DEFAULT_HAS_GLOBAL_FOCUS, mExclusionRegion, DEFAULT_SHOULD_IGNORE_CORNER_RADIUS, - DEFAULT_SHOULD_EXCLUDE_CAPTION_FROM_APP_BOUNDS); + DEFAULT_SHOULD_EXCLUDE_CAPTION_FROM_APP_BOUNDS, + DEFAULT_IS_RECENTS_TRANSITION_RUNNING, + DEFAULT_IS_MOVING_TO_BACK); } private DesktopModeWindowDecoration createWindowDecoration( @@ -1676,9 +1774,9 @@ public class DesktopModeWindowDecorationTests extends ShellTestCase { taskInfo, mMockSurfaceControl, mMockHandler, mMainExecutor, mMockMainCoroutineDispatcher, mMockBgCoroutineScope, mBgExecutor, mMockChoreographer, mMockSyncQueue, mMockAppHeaderViewHolderFactory, - mMockRootTaskDisplayAreaOrganizer, mMockGenericLinksParser, - mMockAssistContentRequester, SurfaceControl.Builder::new, mMockTransactionSupplier, - WindowContainerTransaction::new, SurfaceControl::new, + mMockAppHandleViewHolderFactory, mMockRootTaskDisplayAreaOrganizer, + mMockGenericLinksParser, mMockAssistContentRequester, SurfaceControl.Builder::new, + mMockTransactionSupplier, WindowContainerTransaction::new, SurfaceControl::new, new WindowManagerWrapper(mMockWindowManager), mMockSurfaceControlViewHostFactory, mMockWindowDecorViewHostSupplier, maximizeMenuFactory, mMockHandleMenuFactory, mMockMultiInstanceHelper, mMockCaptionHandleRepository, mDesktopModeEventLogger, |