Loading libs/WindowManager/Shell/src/com/android/wm/shell/dagger/WMShellModule.java +4 −0 Original line number Diff line number Diff line Loading @@ -203,8 +203,10 @@ public abstract class WMShellModule { Context context, @ShellMainThread Handler mainHandler, @ShellMainThread Choreographer mainChoreographer, ShellInit shellInit, ShellTaskOrganizer taskOrganizer, DisplayController displayController, ShellController shellController, SyncTransactionQueue syncQueue, Transitions transitions, Optional<DesktopModeController> desktopModeController, Loading @@ -214,8 +216,10 @@ public abstract class WMShellModule { context, mainHandler, mainChoreographer, shellInit, taskOrganizer, displayController, shellController, syncQueue, transitions, desktopModeController, Loading libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/DesktopModeWindowDecorViewModel.java +45 −3 Original line number Diff line number Diff line Loading @@ -72,6 +72,9 @@ import com.android.wm.shell.desktopmode.DesktopModeStatus; import com.android.wm.shell.desktopmode.DesktopTasksController; import com.android.wm.shell.freeform.FreeformTaskTransitionStarter; import com.android.wm.shell.splitscreen.SplitScreenController; import com.android.wm.shell.sysui.KeyguardChangeListener; import com.android.wm.shell.sysui.ShellController; import com.android.wm.shell.sysui.ShellInit; import com.android.wm.shell.transition.Transitions; import com.android.wm.shell.windowdecor.DesktopModeWindowDecoration.TaskCornersListener; Loading @@ -89,6 +92,7 @@ public class DesktopModeWindowDecorViewModel implements WindowDecorViewModel { private final DesktopModeWindowDecoration.Factory mDesktopModeWindowDecorFactory; private final ActivityTaskManager mActivityTaskManager; private final ShellTaskOrganizer mTaskOrganizer; private final ShellController mShellController; private final Context mContext; private final Handler mMainHandler; private final Choreographer mMainChoreographer; Loading @@ -114,30 +118,37 @@ public class DesktopModeWindowDecorViewModel implements WindowDecorViewModel { private MoveToDesktopAnimator mMoveToDesktopAnimator; private final Rect mDragToDesktopAnimationStartBounds = new Rect(); private final DesktopModeKeyguardChangeListener mDesktopModeKeyguardChangeListener; public DesktopModeWindowDecorViewModel( Context context, Handler mainHandler, Choreographer mainChoreographer, ShellInit shellInit, ShellTaskOrganizer taskOrganizer, DisplayController displayController, ShellController shellController, SyncTransactionQueue syncQueue, Transitions transitions, Optional<DesktopModeController> desktopModeController, Optional<DesktopTasksController> desktopTasksController) { Optional<DesktopTasksController> desktopTasksController ) { this( context, mainHandler, mainChoreographer, shellInit, taskOrganizer, displayController, shellController, syncQueue, transitions, desktopModeController, desktopTasksController, new DesktopModeWindowDecoration.Factory(), new InputMonitorFactory(), SurfaceControl.Transaction::new); SurfaceControl.Transaction::new, new DesktopModeKeyguardChangeListener()); } @VisibleForTesting Loading @@ -145,20 +156,24 @@ public class DesktopModeWindowDecorViewModel implements WindowDecorViewModel { Context context, Handler mainHandler, Choreographer mainChoreographer, ShellInit shellInit, ShellTaskOrganizer taskOrganizer, DisplayController displayController, ShellController shellController, SyncTransactionQueue syncQueue, Transitions transitions, Optional<DesktopModeController> desktopModeController, Optional<DesktopTasksController> desktopTasksController, DesktopModeWindowDecoration.Factory desktopModeWindowDecorFactory, InputMonitorFactory inputMonitorFactory, Supplier<SurfaceControl.Transaction> transactionFactory) { Supplier<SurfaceControl.Transaction> transactionFactory, DesktopModeKeyguardChangeListener desktopModeKeyguardChangeListener) { mContext = context; mMainHandler = mainHandler; mMainChoreographer = mainChoreographer; mActivityTaskManager = mContext.getSystemService(ActivityTaskManager.class); mTaskOrganizer = taskOrganizer; mShellController = shellController; mDisplayController = displayController; mSyncQueue = syncQueue; mTransitions = transitions; Loading @@ -168,6 +183,13 @@ public class DesktopModeWindowDecorViewModel implements WindowDecorViewModel { mDesktopModeWindowDecorFactory = desktopModeWindowDecorFactory; mInputMonitorFactory = inputMonitorFactory; mTransactionFactory = transactionFactory; mDesktopModeKeyguardChangeListener = desktopModeKeyguardChangeListener; shellInit.addInitCallback(this::onInit, this); } private void onInit() { mShellController.addKeyguardChangeListener(mDesktopModeKeyguardChangeListener); } @Override Loading Loading @@ -796,6 +818,10 @@ public class DesktopModeWindowDecorViewModel implements WindowDecorViewModel { && mSplitScreenController.isTaskRootOrStageRoot(taskInfo.taskId)) { return false; } if (mDesktopModeKeyguardChangeListener.isKeyguardVisibleAndOccluded() && taskInfo.isFocused) { return false; } return DesktopModeStatus.isProto2Enabled() && taskInfo.getWindowingMode() != WINDOWING_MODE_PINNED && taskInfo.getActivityType() == ACTIVITY_TYPE_STANDARD Loading Loading @@ -884,6 +910,22 @@ public class DesktopModeWindowDecorViewModel implements WindowDecorViewModel { mDesktopTasksController.ifPresent(d -> d.removeCornersForTask(taskId)); } } static class DesktopModeKeyguardChangeListener implements KeyguardChangeListener { private boolean mIsKeyguardVisible; private boolean mIsKeyguardOccluded; @Override public void onKeyguardVisibilityChanged(boolean visible, boolean occluded, boolean animatingDismiss) { mIsKeyguardVisible = visible; mIsKeyguardOccluded = occluded; } public boolean isKeyguardVisibleAndOccluded() { return mIsKeyguardVisible && mIsKeyguardOccluded; } } } libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/windowdecor/DesktopModeWindowDecorViewModelTests.java +40 −1 Original line number Diff line number Diff line Loading @@ -18,12 +18,15 @@ package com.android.wm.shell.windowdecor; import static android.app.WindowConfiguration.ACTIVITY_TYPE_STANDARD; import static android.app.WindowConfiguration.ACTIVITY_TYPE_UNDEFINED; import static android.app.WindowConfiguration.WINDOWING_MODE_FREEFORM; import static android.app.WindowConfiguration.WINDOWING_MODE_FULLSCREEN; import static android.app.WindowConfiguration.WINDOWING_MODE_UNDEFINED; import static org.mockito.ArgumentMatchers.anyInt; import static org.mockito.Mockito.any; import static org.mockito.Mockito.doNothing; import static org.mockito.Mockito.doReturn; import static org.mockito.Mockito.mock; import static org.mockito.Mockito.never; import static org.mockito.Mockito.times; import static org.mockito.Mockito.verify; import static org.mockito.Mockito.when; Loading Loading @@ -53,6 +56,8 @@ import com.android.wm.shell.common.DisplayLayout; import com.android.wm.shell.common.SyncTransactionQueue; import com.android.wm.shell.desktopmode.DesktopModeController; import com.android.wm.shell.desktopmode.DesktopTasksController; import com.android.wm.shell.sysui.ShellController; import com.android.wm.shell.sysui.ShellInit; import com.android.wm.shell.transition.Transitions; import org.junit.Before; Loading Loading @@ -91,6 +96,10 @@ public class DesktopModeWindowDecorViewModelTests extends ShellTestCase { @Mock private Supplier<SurfaceControl.Transaction> mTransactionFactory; @Mock private SurfaceControl.Transaction mTransaction; @Mock private Display mDisplay; @Mock private ShellController mShellController; @Mock private ShellInit mShellInit; @Mock private DesktopModeWindowDecorViewModel.DesktopModeKeyguardChangeListener mDesktopModeKeyguardChangeListener; private final List<InputManager> mMockInputManagers = new ArrayList<>(); private DesktopModeWindowDecorViewModel mDesktopModeWindowDecorViewModel; Loading @@ -104,15 +113,18 @@ public class DesktopModeWindowDecorViewModelTests extends ShellTestCase { mContext, mMainHandler, mMainChoreographer, mShellInit, mTaskOrganizer, mDisplayController, mShellController, mSyncQueue, mTransitions, Optional.of(mDesktopModeController), Optional.of(mDesktopTasksController), mDesktopModeWindowDecorFactory, mMockInputMonitorFactory, mTransactionFactory mTransactionFactory, mDesktopModeKeyguardChangeListener ); doReturn(mDesktopModeWindowDecoration) Loading @@ -121,6 +133,7 @@ public class DesktopModeWindowDecorViewModelTests extends ShellTestCase { doReturn(mTransaction).when(mTransactionFactory).get(); doReturn(mDisplayLayout).when(mDisplayController).getDisplayLayout(anyInt()); doReturn(STABLE_INSETS).when(mDisplayLayout).stableInsets(); doNothing().when(mShellController).addKeyguardChangeListener(any()); when(mMockInputMonitorFactory.create(any(), any())).thenReturn(mInputMonitor); // InputChannel cannot be mocked because it passes to InputEventReceiver. Loading Loading @@ -255,6 +268,32 @@ public class DesktopModeWindowDecorViewModelTests extends ShellTestCase { verify(mInputMonitor, times(1)).dispose(); } @Test public void testCaptionIsNotCreatedWhenKeyguardIsVisible() throws Exception { doReturn(true).when( mDesktopModeKeyguardChangeListener).isKeyguardVisibleAndOccluded(); final int taskId = 1; final ActivityManager.RunningTaskInfo taskInfo = createTaskInfo(taskId, Display.DEFAULT_DISPLAY, WINDOWING_MODE_FULLSCREEN); taskInfo.isFocused = true; SurfaceControl surfaceControl = mock(SurfaceControl.class); runOnMainThread(() -> { final SurfaceControl.Transaction startT = mock(SurfaceControl.Transaction.class); final SurfaceControl.Transaction finishT = mock(SurfaceControl.Transaction.class); mDesktopModeWindowDecorViewModel.onTaskOpening( taskInfo, surfaceControl, startT, finishT); taskInfo.configuration.windowConfiguration.setWindowingMode(WINDOWING_MODE_UNDEFINED); taskInfo.configuration.windowConfiguration.setActivityType(ACTIVITY_TYPE_UNDEFINED); mDesktopModeWindowDecorViewModel.onTaskChanging( taskInfo, surfaceControl, startT, finishT); }); verify(mDesktopModeWindowDecorFactory, never()) .create(any(), any(), any(), any(), any(), any(), any(), any()); } private void runOnMainThread(Runnable r) throws Exception { final Handler mainHandler = new Handler(Looper.getMainLooper()); final CountDownLatch latch = new CountDownLatch(1); Loading Loading
libs/WindowManager/Shell/src/com/android/wm/shell/dagger/WMShellModule.java +4 −0 Original line number Diff line number Diff line Loading @@ -203,8 +203,10 @@ public abstract class WMShellModule { Context context, @ShellMainThread Handler mainHandler, @ShellMainThread Choreographer mainChoreographer, ShellInit shellInit, ShellTaskOrganizer taskOrganizer, DisplayController displayController, ShellController shellController, SyncTransactionQueue syncQueue, Transitions transitions, Optional<DesktopModeController> desktopModeController, Loading @@ -214,8 +216,10 @@ public abstract class WMShellModule { context, mainHandler, mainChoreographer, shellInit, taskOrganizer, displayController, shellController, syncQueue, transitions, desktopModeController, Loading
libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/DesktopModeWindowDecorViewModel.java +45 −3 Original line number Diff line number Diff line Loading @@ -72,6 +72,9 @@ import com.android.wm.shell.desktopmode.DesktopModeStatus; import com.android.wm.shell.desktopmode.DesktopTasksController; import com.android.wm.shell.freeform.FreeformTaskTransitionStarter; import com.android.wm.shell.splitscreen.SplitScreenController; import com.android.wm.shell.sysui.KeyguardChangeListener; import com.android.wm.shell.sysui.ShellController; import com.android.wm.shell.sysui.ShellInit; import com.android.wm.shell.transition.Transitions; import com.android.wm.shell.windowdecor.DesktopModeWindowDecoration.TaskCornersListener; Loading @@ -89,6 +92,7 @@ public class DesktopModeWindowDecorViewModel implements WindowDecorViewModel { private final DesktopModeWindowDecoration.Factory mDesktopModeWindowDecorFactory; private final ActivityTaskManager mActivityTaskManager; private final ShellTaskOrganizer mTaskOrganizer; private final ShellController mShellController; private final Context mContext; private final Handler mMainHandler; private final Choreographer mMainChoreographer; Loading @@ -114,30 +118,37 @@ public class DesktopModeWindowDecorViewModel implements WindowDecorViewModel { private MoveToDesktopAnimator mMoveToDesktopAnimator; private final Rect mDragToDesktopAnimationStartBounds = new Rect(); private final DesktopModeKeyguardChangeListener mDesktopModeKeyguardChangeListener; public DesktopModeWindowDecorViewModel( Context context, Handler mainHandler, Choreographer mainChoreographer, ShellInit shellInit, ShellTaskOrganizer taskOrganizer, DisplayController displayController, ShellController shellController, SyncTransactionQueue syncQueue, Transitions transitions, Optional<DesktopModeController> desktopModeController, Optional<DesktopTasksController> desktopTasksController) { Optional<DesktopTasksController> desktopTasksController ) { this( context, mainHandler, mainChoreographer, shellInit, taskOrganizer, displayController, shellController, syncQueue, transitions, desktopModeController, desktopTasksController, new DesktopModeWindowDecoration.Factory(), new InputMonitorFactory(), SurfaceControl.Transaction::new); SurfaceControl.Transaction::new, new DesktopModeKeyguardChangeListener()); } @VisibleForTesting Loading @@ -145,20 +156,24 @@ public class DesktopModeWindowDecorViewModel implements WindowDecorViewModel { Context context, Handler mainHandler, Choreographer mainChoreographer, ShellInit shellInit, ShellTaskOrganizer taskOrganizer, DisplayController displayController, ShellController shellController, SyncTransactionQueue syncQueue, Transitions transitions, Optional<DesktopModeController> desktopModeController, Optional<DesktopTasksController> desktopTasksController, DesktopModeWindowDecoration.Factory desktopModeWindowDecorFactory, InputMonitorFactory inputMonitorFactory, Supplier<SurfaceControl.Transaction> transactionFactory) { Supplier<SurfaceControl.Transaction> transactionFactory, DesktopModeKeyguardChangeListener desktopModeKeyguardChangeListener) { mContext = context; mMainHandler = mainHandler; mMainChoreographer = mainChoreographer; mActivityTaskManager = mContext.getSystemService(ActivityTaskManager.class); mTaskOrganizer = taskOrganizer; mShellController = shellController; mDisplayController = displayController; mSyncQueue = syncQueue; mTransitions = transitions; Loading @@ -168,6 +183,13 @@ public class DesktopModeWindowDecorViewModel implements WindowDecorViewModel { mDesktopModeWindowDecorFactory = desktopModeWindowDecorFactory; mInputMonitorFactory = inputMonitorFactory; mTransactionFactory = transactionFactory; mDesktopModeKeyguardChangeListener = desktopModeKeyguardChangeListener; shellInit.addInitCallback(this::onInit, this); } private void onInit() { mShellController.addKeyguardChangeListener(mDesktopModeKeyguardChangeListener); } @Override Loading Loading @@ -796,6 +818,10 @@ public class DesktopModeWindowDecorViewModel implements WindowDecorViewModel { && mSplitScreenController.isTaskRootOrStageRoot(taskInfo.taskId)) { return false; } if (mDesktopModeKeyguardChangeListener.isKeyguardVisibleAndOccluded() && taskInfo.isFocused) { return false; } return DesktopModeStatus.isProto2Enabled() && taskInfo.getWindowingMode() != WINDOWING_MODE_PINNED && taskInfo.getActivityType() == ACTIVITY_TYPE_STANDARD Loading Loading @@ -884,6 +910,22 @@ public class DesktopModeWindowDecorViewModel implements WindowDecorViewModel { mDesktopTasksController.ifPresent(d -> d.removeCornersForTask(taskId)); } } static class DesktopModeKeyguardChangeListener implements KeyguardChangeListener { private boolean mIsKeyguardVisible; private boolean mIsKeyguardOccluded; @Override public void onKeyguardVisibilityChanged(boolean visible, boolean occluded, boolean animatingDismiss) { mIsKeyguardVisible = visible; mIsKeyguardOccluded = occluded; } public boolean isKeyguardVisibleAndOccluded() { return mIsKeyguardVisible && mIsKeyguardOccluded; } } }
libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/windowdecor/DesktopModeWindowDecorViewModelTests.java +40 −1 Original line number Diff line number Diff line Loading @@ -18,12 +18,15 @@ package com.android.wm.shell.windowdecor; import static android.app.WindowConfiguration.ACTIVITY_TYPE_STANDARD; import static android.app.WindowConfiguration.ACTIVITY_TYPE_UNDEFINED; import static android.app.WindowConfiguration.WINDOWING_MODE_FREEFORM; import static android.app.WindowConfiguration.WINDOWING_MODE_FULLSCREEN; import static android.app.WindowConfiguration.WINDOWING_MODE_UNDEFINED; import static org.mockito.ArgumentMatchers.anyInt; import static org.mockito.Mockito.any; import static org.mockito.Mockito.doNothing; import static org.mockito.Mockito.doReturn; import static org.mockito.Mockito.mock; import static org.mockito.Mockito.never; import static org.mockito.Mockito.times; import static org.mockito.Mockito.verify; import static org.mockito.Mockito.when; Loading Loading @@ -53,6 +56,8 @@ import com.android.wm.shell.common.DisplayLayout; import com.android.wm.shell.common.SyncTransactionQueue; import com.android.wm.shell.desktopmode.DesktopModeController; import com.android.wm.shell.desktopmode.DesktopTasksController; import com.android.wm.shell.sysui.ShellController; import com.android.wm.shell.sysui.ShellInit; import com.android.wm.shell.transition.Transitions; import org.junit.Before; Loading Loading @@ -91,6 +96,10 @@ public class DesktopModeWindowDecorViewModelTests extends ShellTestCase { @Mock private Supplier<SurfaceControl.Transaction> mTransactionFactory; @Mock private SurfaceControl.Transaction mTransaction; @Mock private Display mDisplay; @Mock private ShellController mShellController; @Mock private ShellInit mShellInit; @Mock private DesktopModeWindowDecorViewModel.DesktopModeKeyguardChangeListener mDesktopModeKeyguardChangeListener; private final List<InputManager> mMockInputManagers = new ArrayList<>(); private DesktopModeWindowDecorViewModel mDesktopModeWindowDecorViewModel; Loading @@ -104,15 +113,18 @@ public class DesktopModeWindowDecorViewModelTests extends ShellTestCase { mContext, mMainHandler, mMainChoreographer, mShellInit, mTaskOrganizer, mDisplayController, mShellController, mSyncQueue, mTransitions, Optional.of(mDesktopModeController), Optional.of(mDesktopTasksController), mDesktopModeWindowDecorFactory, mMockInputMonitorFactory, mTransactionFactory mTransactionFactory, mDesktopModeKeyguardChangeListener ); doReturn(mDesktopModeWindowDecoration) Loading @@ -121,6 +133,7 @@ public class DesktopModeWindowDecorViewModelTests extends ShellTestCase { doReturn(mTransaction).when(mTransactionFactory).get(); doReturn(mDisplayLayout).when(mDisplayController).getDisplayLayout(anyInt()); doReturn(STABLE_INSETS).when(mDisplayLayout).stableInsets(); doNothing().when(mShellController).addKeyguardChangeListener(any()); when(mMockInputMonitorFactory.create(any(), any())).thenReturn(mInputMonitor); // InputChannel cannot be mocked because it passes to InputEventReceiver. Loading Loading @@ -255,6 +268,32 @@ public class DesktopModeWindowDecorViewModelTests extends ShellTestCase { verify(mInputMonitor, times(1)).dispose(); } @Test public void testCaptionIsNotCreatedWhenKeyguardIsVisible() throws Exception { doReturn(true).when( mDesktopModeKeyguardChangeListener).isKeyguardVisibleAndOccluded(); final int taskId = 1; final ActivityManager.RunningTaskInfo taskInfo = createTaskInfo(taskId, Display.DEFAULT_DISPLAY, WINDOWING_MODE_FULLSCREEN); taskInfo.isFocused = true; SurfaceControl surfaceControl = mock(SurfaceControl.class); runOnMainThread(() -> { final SurfaceControl.Transaction startT = mock(SurfaceControl.Transaction.class); final SurfaceControl.Transaction finishT = mock(SurfaceControl.Transaction.class); mDesktopModeWindowDecorViewModel.onTaskOpening( taskInfo, surfaceControl, startT, finishT); taskInfo.configuration.windowConfiguration.setWindowingMode(WINDOWING_MODE_UNDEFINED); taskInfo.configuration.windowConfiguration.setActivityType(ACTIVITY_TYPE_UNDEFINED); mDesktopModeWindowDecorViewModel.onTaskChanging( taskInfo, surfaceControl, startT, finishT); }); verify(mDesktopModeWindowDecorFactory, never()) .create(any(), any(), any(), any(), any(), any(), any(), any()); } private void runOnMainThread(Runnable r) throws Exception { final Handler mainHandler = new Handler(Looper.getMainLooper()); final CountDownLatch latch = new CountDownLatch(1); Loading