diff options
| author | 2023-08-25 21:40:58 +0000 | |
|---|---|---|
| committer | 2023-08-25 21:40:58 +0000 | |
| commit | 6d37135ed7a665f0449b43e521f5d080f94bd19f (patch) | |
| tree | cc8d3a7c694b571ccb4b30b367a6475d7c93592e | |
| parent | 6e228244bd6db728d3779a032f2361413e3f576a (diff) | |
| parent | c4f6fac538960eeeab33b0884efd8700caddb391 (diff) | |
Merge "Show maximize menu when user long clicks maximize button on caption" into main
21 files changed, 638 insertions, 44 deletions
diff --git a/core/java/android/window/TaskConstants.java b/core/java/android/window/TaskConstants.java index 69d79b449615..44bb33db6347 100644 --- a/core/java/android/window/TaskConstants.java +++ b/core/java/android/window/TaskConstants.java @@ -81,6 +81,12 @@ public class TaskConstants { public static final int TASK_CHILD_LAYER_RESIZE_VEIL = 6 * TASK_CHILD_LAYER_REGION_SIZE; /** + * Floating menus belonging to a task (e.g. maximize menu). + * @hide + */ + public static final int TASK_CHILD_LAYER_FLOATING_MENU = 7 * TASK_CHILD_LAYER_REGION_SIZE; + + /** * Z-orders of task child layers other than activities, task fragments and layers interleaved * with them, e.g. IME windows. [-10000, 10000) is reserved for these layers. * @hide diff --git a/libs/WindowManager/Shell/res/color/desktop_mode_maximize_menu_button_color_selector.xml b/libs/WindowManager/Shell/res/color/desktop_mode_maximize_menu_button_color_selector.xml new file mode 100644 index 000000000000..65f5239737b2 --- /dev/null +++ b/libs/WindowManager/Shell/res/color/desktop_mode_maximize_menu_button_color_selector.xml @@ -0,0 +1,28 @@ +<?xml version="1.0" encoding="utf-8"?> +<!-- + ~ Copyright (C) 2023 The Android Open Source Project + ~ + ~ Licensed under the Apache License, Version 2.0 (the "License"); + ~ you may not use this file except in compliance with the License. + ~ You may obtain a copy of the License at + ~ + ~ http://www.apache.org/licenses/LICENSE-2.0 + ~ + ~ Unless required by applicable law or agreed to in writing, software + ~ distributed under the License is distributed on an "AS IS" BASIS, + ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + ~ See the License for the specific language governing permissions and + ~ limitations under the License +--> + +<selector xmlns:android="http://schemas.android.com/apk/res/android"> + <item android:state_pressed="true" + android:color="@color/desktop_mode_maximize_menu_button_on_hover"/> + <item android:state_hovered="true" + android:color="@color/desktop_mode_maximize_menu_button_on_hover"/> + <item android:state_focused="true" + android:color="@color/desktop_mode_maximize_menu_button_on_hover"/> + <item android:state_selected="true" + android:color="@color/desktop_mode_maximize_menu_button_on_hover"/> + <item android:color="@color/desktop_mode_maximize_menu_button"/> +</selector>
\ No newline at end of file diff --git a/libs/WindowManager/Shell/res/color/desktop_mode_maximize_menu_button_outline_color_selector.xml b/libs/WindowManager/Shell/res/color/desktop_mode_maximize_menu_button_outline_color_selector.xml new file mode 100644 index 000000000000..86679af5428b --- /dev/null +++ b/libs/WindowManager/Shell/res/color/desktop_mode_maximize_menu_button_outline_color_selector.xml @@ -0,0 +1,28 @@ +<?xml version="1.0" encoding="utf-8"?> +<!-- + ~ Copyright (C) 2023 The Android Open Source Project + ~ + ~ Licensed under the Apache License, Version 2.0 (the "License"); + ~ you may not use this file except in compliance with the License. + ~ You may obtain a copy of the License at + ~ + ~ http://www.apache.org/licenses/LICENSE-2.0 + ~ + ~ Unless required by applicable law or agreed to in writing, software + ~ distributed under the License is distributed on an "AS IS" BASIS, + ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + ~ See the License for the specific language governing permissions and + ~ limitations under the License +--> + +<selector xmlns:android="http://schemas.android.com/apk/res/android"> + <item android:state_pressed="true" + android:color="@color/desktop_mode_maximize_menu_button_outline_on_hover"/> + <item android:state_hovered="true" + android:color="@color/desktop_mode_maximize_menu_button_outline_on_hover"/> + <item android:state_focused="true" + android:color="@color/desktop_mode_maximize_menu_button_outline_on_hover"/> + <item android:state_selected="true" + android:color="@color/desktop_mode_maximize_menu_button_outline_on_hover"/> + <item android:color="@color/desktop_mode_maximize_menu_button_outline"/> +</selector>
\ No newline at end of file diff --git a/libs/WindowManager/Shell/res/drawable/desktop_mode_decor_menu_background.xml b/libs/WindowManager/Shell/res/drawable/desktop_mode_decor_handle_menu_background.xml index 4ee10f429b37..4ee10f429b37 100644 --- a/libs/WindowManager/Shell/res/drawable/desktop_mode_decor_menu_background.xml +++ b/libs/WindowManager/Shell/res/drawable/desktop_mode_decor_handle_menu_background.xml diff --git a/libs/WindowManager/Shell/res/drawable/desktop_mode_maximize_menu_background.xml b/libs/WindowManager/Shell/res/drawable/desktop_mode_maximize_menu_background.xml new file mode 100644 index 000000000000..5d9fe67e8bee --- /dev/null +++ b/libs/WindowManager/Shell/res/drawable/desktop_mode_maximize_menu_background.xml @@ -0,0 +1,21 @@ +<?xml version="1.0" encoding="utf-8"?> +<!-- + ~ Copyright (C) 2023 The Android Open Source Project + ~ + ~ Licensed under the Apache License, Version 2.0 (the "License"); + ~ you may not use this file except in compliance with the License. + ~ You may obtain a copy of the License at + ~ + ~ http://www.apache.org/licenses/LICENSE-2.0 + ~ + ~ Unless required by applicable law or agreed to in writing, software + ~ distributed under the License is distributed on an "AS IS" BASIS, + ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + ~ See the License for the specific language governing permissions and + ~ limitations under the License. + --> +<shape android:shape="rectangle" + xmlns:android="http://schemas.android.com/apk/res/android"> + <solid android:color="@android:color/white" /> + <corners android:radius="@dimen/desktop_mode_maximize_menu_corner_radius" /> +</shape> diff --git a/libs/WindowManager/Shell/res/drawable/desktop_mode_maximize_menu_maximize_button_background.xml b/libs/WindowManager/Shell/res/drawable/desktop_mode_maximize_menu_maximize_button_background.xml new file mode 100644 index 000000000000..bfb0dd7f3100 --- /dev/null +++ b/libs/WindowManager/Shell/res/drawable/desktop_mode_maximize_menu_maximize_button_background.xml @@ -0,0 +1,24 @@ +<?xml version="1.0" encoding="utf-8"?> +<!-- + ~ Copyright (C) 2023 The Android Open Source Project + ~ + ~ Licensed under the Apache License, Version 2.0 (the "License"); + ~ you may not use this file except in compliance with the License. + ~ You may obtain a copy of the License at + ~ + ~ http://www.apache.org/licenses/LICENSE-2.0 + ~ + ~ Unless required by applicable law or agreed to in writing, software + ~ distributed under the License is distributed on an "AS IS" BASIS, + ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + ~ See the License for the specific language governing permissions and + ~ limitations under the License +--> + +<shape xmlns:android="http://schemas.android.com/apk/res/android" + android:shape="rectangle"> + <solid android:color="@color/desktop_mode_maximize_menu_button_color_selector"/> + <corners + android:radius="@dimen/desktop_mode_maximize_menu_buttons_large_corner_radius"/> + <stroke android:width="1dp" android:color="@color/desktop_mode_maximize_menu_button_outline_color_selector"/> +</shape>
\ No newline at end of file diff --git a/libs/WindowManager/Shell/res/drawable/desktop_mode_maximize_menu_snap_left_button_background.xml b/libs/WindowManager/Shell/res/drawable/desktop_mode_maximize_menu_snap_left_button_background.xml new file mode 100644 index 000000000000..6630fcab4794 --- /dev/null +++ b/libs/WindowManager/Shell/res/drawable/desktop_mode_maximize_menu_snap_left_button_background.xml @@ -0,0 +1,28 @@ +<?xml version="1.0" encoding="utf-8"?> + +<!-- + ~ Copyright (C) 2023 The Android Open Source Project + ~ + ~ Licensed under the Apache License, Version 2.0 (the "License"); + ~ you may not use this file except in compliance with the License. + ~ You may obtain a copy of the License at + ~ + ~ http://www.apache.org/licenses/LICENSE-2.0 + ~ + ~ Unless required by applicable law or agreed to in writing, software + ~ distributed under the License is distributed on an "AS IS" BASIS, + ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + ~ See the License for the specific language governing permissions and + ~ limitations under the License +--> + +<shape xmlns:android="http://schemas.android.com/apk/res/android" + android:shape="rectangle"> + <solid android:color="@color/desktop_mode_maximize_menu_button_color_selector"/> + <corners + android:topLeftRadius="@dimen/desktop_mode_maximize_menu_buttons_large_corner_radius" + android:topRightRadius="@dimen/desktop_mode_maximize_menu_buttons_small_corner_radius" + android:bottomLeftRadius="@dimen/desktop_mode_maximize_menu_buttons_large_corner_radius" + android:bottomRightRadius="@dimen/desktop_mode_maximize_menu_buttons_small_corner_radius"/> + <stroke android:width="1dp" android:color="@color/desktop_mode_maximize_menu_button_outline_color_selector"/> +</shape>
\ No newline at end of file diff --git a/libs/WindowManager/Shell/res/drawable/desktop_mode_maximize_menu_snap_right_button_background.xml b/libs/WindowManager/Shell/res/drawable/desktop_mode_maximize_menu_snap_right_button_background.xml new file mode 100644 index 000000000000..7bd6e9981c12 --- /dev/null +++ b/libs/WindowManager/Shell/res/drawable/desktop_mode_maximize_menu_snap_right_button_background.xml @@ -0,0 +1,28 @@ +<?xml version="1.0" encoding="utf-8"?> + +<!-- + ~ Copyright (C) 2023 The Android Open Source Project + ~ + ~ Licensed under the Apache License, Version 2.0 (the "License"); + ~ you may not use this file except in compliance with the License. + ~ You may obtain a copy of the License at + ~ + ~ http://www.apache.org/licenses/LICENSE-2.0 + ~ + ~ Unless required by applicable law or agreed to in writing, software + ~ distributed under the License is distributed on an "AS IS" BASIS, + ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + ~ See the License for the specific language governing permissions and + ~ limitations under the License +--> + +<shape xmlns:android="http://schemas.android.com/apk/res/android" + android:shape="rectangle"> + <solid android:color="@color/desktop_mode_maximize_menu_button_color_selector"/> + <corners + android:topLeftRadius="@dimen/desktop_mode_maximize_menu_buttons_small_corner_radius" + android:topRightRadius="@dimen/desktop_mode_maximize_menu_buttons_large_corner_radius" + android:bottomLeftRadius="@dimen/desktop_mode_maximize_menu_buttons_small_corner_radius" + android:bottomRightRadius="@dimen/desktop_mode_maximize_menu_buttons_large_corner_radius"/> + <stroke android:width="1dp" android:color="@color/desktop_mode_maximize_menu_button_outline_color_selector"/> +</shape>
\ No newline at end of file diff --git a/libs/WindowManager/Shell/res/layout/desktop_mode_window_decor_handle_menu_app_info_pill.xml b/libs/WindowManager/Shell/res/layout/desktop_mode_window_decor_handle_menu_app_info_pill.xml index 167a003932d6..c03d240d59f2 100644 --- a/libs/WindowManager/Shell/res/layout/desktop_mode_window_decor_handle_menu_app_info_pill.xml +++ b/libs/WindowManager/Shell/res/layout/desktop_mode_window_decor_handle_menu_app_info_pill.xml @@ -19,7 +19,7 @@ android:layout_width="@dimen/desktop_mode_handle_menu_width" android:layout_height="@dimen/desktop_mode_handle_menu_app_info_pill_height" android:orientation="horizontal" - android:background="@drawable/desktop_mode_decor_menu_background" + android:background="@drawable/desktop_mode_decor_handle_menu_background" android:gravity="center_vertical"> <ImageView diff --git a/libs/WindowManager/Shell/res/layout/desktop_mode_window_decor_handle_menu_more_actions_pill.xml b/libs/WindowManager/Shell/res/layout/desktop_mode_window_decor_handle_menu_more_actions_pill.xml index 40a4b53f3e1d..cdf4937599c9 100644 --- a/libs/WindowManager/Shell/res/layout/desktop_mode_window_decor_handle_menu_more_actions_pill.xml +++ b/libs/WindowManager/Shell/res/layout/desktop_mode_window_decor_handle_menu_more_actions_pill.xml @@ -18,7 +18,7 @@ android:layout_width="@dimen/desktop_mode_handle_menu_width" android:layout_height="@dimen/desktop_mode_handle_menu_more_actions_pill_height" android:orientation="vertical" - android:background="@drawable/desktop_mode_decor_menu_background"> + android:background="@drawable/desktop_mode_decor_handle_menu_background"> <Button android:id="@+id/screenshot_button" diff --git a/libs/WindowManager/Shell/res/layout/desktop_mode_window_decor_handle_menu_windowing_pill.xml b/libs/WindowManager/Shell/res/layout/desktop_mode_window_decor_handle_menu_windowing_pill.xml index 95283b9e214a..08d91498b338 100644 --- a/libs/WindowManager/Shell/res/layout/desktop_mode_window_decor_handle_menu_windowing_pill.xml +++ b/libs/WindowManager/Shell/res/layout/desktop_mode_window_decor_handle_menu_windowing_pill.xml @@ -18,7 +18,7 @@ android:layout_width="@dimen/desktop_mode_handle_menu_width" android:layout_height="@dimen/desktop_mode_handle_menu_windowing_pill_height" android:orientation="horizontal" - android:background="@drawable/desktop_mode_decor_menu_background" + android:background="@drawable/desktop_mode_decor_handle_menu_background" android:gravity="center_vertical"> <ImageButton diff --git a/libs/WindowManager/Shell/res/layout/desktop_mode_window_decor_maximize_menu.xml b/libs/WindowManager/Shell/res/layout/desktop_mode_window_decor_maximize_menu.xml new file mode 100644 index 000000000000..0db72f7be8e6 --- /dev/null +++ b/libs/WindowManager/Shell/res/layout/desktop_mode_window_decor_maximize_menu.xml @@ -0,0 +1,54 @@ +<?xml version="1.0" encoding="utf-8"?> +<!-- + ~ Copyright (C) 2023 The Android Open Source Project + ~ + ~ Licensed under the Apache License, Version 2.0 (the "License"); + ~ you may not use this file except in compliance with the License. + ~ You may obtain a copy of the License at + ~ + ~ http://www.apache.org/licenses/LICENSE-2.0 + ~ + ~ Unless required by applicable law or agreed to in writing, software + ~ distributed under the License is distributed on an "AS IS" BASIS, + ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + ~ See the License for the specific language governing permissions and + ~ limitations under the License. + --> +<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" + style="?android:attr/buttonBarStyle" + android:layout_width="@dimen/desktop_mode_maximize_menu_width" + android:layout_height="@dimen/desktop_mode_maximize_menu_height" + android:orientation="horizontal" + android:gravity="center" + android:background="@drawable/desktop_mode_maximize_menu_background"> + + + <Button + android:id="@+id/maximize_menu_maximize_button" + style="?android:attr/buttonBarButtonStyle" + android:layout_width="120dp" + android:layout_height="80dp" + android:layout_marginRight="15dp" + android:color="@color/desktop_mode_maximize_menu_button" + android:background="@drawable/desktop_mode_maximize_menu_maximize_button_background" + android:stateListAnimator="@null"/> + + <Button + android:id="@+id/maximize_menu_snap_left_button" + style="?android:attr/buttonBarButtonStyle" + android:layout_width="58dp" + android:layout_height="80dp" + android:layout_marginRight="6dp" + android:color="@color/desktop_mode_maximize_menu_button" + android:background="@drawable/desktop_mode_maximize_menu_snap_left_button_background" + android:stateListAnimator="@null"/> + + <Button + android:id="@+id/maximize_menu_snap_right_button" + style="?android:attr/buttonBarButtonStyle" + android:layout_width="58dp" + android:layout_height="80dp" + android:color="@color/desktop_mode_maximize_menu_button" + android:background="@drawable/desktop_mode_maximize_menu_snap_right_button_background" + android:stateListAnimator="@null"/> +</LinearLayout>
\ No newline at end of file diff --git a/libs/WindowManager/Shell/res/values/colors.xml b/libs/WindowManager/Shell/res/values/colors.xml index b2ec98bc1b15..f76a346a8f5d 100644 --- a/libs/WindowManager/Shell/res/values/colors.xml +++ b/libs/WindowManager/Shell/res/values/colors.xml @@ -73,4 +73,8 @@ <color name="desktop_mode_caption_menu_buttons_color_active">#00677E</color> <color name="desktop_mode_resize_veil_light">#EFF1F2</color> <color name="desktop_mode_resize_veil_dark">#1C1C17</color> + <color name="desktop_mode_maximize_menu_button">#DDDACD</color> + <color name="desktop_mode_maximize_menu_button_outline">#797869</color> + <color name="desktop_mode_maximize_menu_button_outline_on_hover">#606219</color> + <color name="desktop_mode_maximize_menu_button_on_hover">#E7E790</color> </resources> diff --git a/libs/WindowManager/Shell/res/values/dimen.xml b/libs/WindowManager/Shell/res/values/dimen.xml index 20bf81da5561..d0c0c0296935 100644 --- a/libs/WindowManager/Shell/res/values/dimen.xml +++ b/libs/WindowManager/Shell/res/values/dimen.xml @@ -401,6 +401,24 @@ <!-- Height of button (32dp) + 2 * margin (5dp each). --> <dimen name="freeform_decor_caption_height">42dp</dimen> + <!-- The width of the maximize menu in desktop mode. --> + <dimen name="desktop_mode_maximize_menu_width">287dp</dimen> + + <!-- The height of the maximize menu in desktop mode. --> + <dimen name="desktop_mode_maximize_menu_height">112dp</dimen> + + <!-- The larger of the two corner radii of the maximize menu buttons. --> + <dimen name="desktop_mode_maximize_menu_buttons_large_corner_radius">4dp</dimen> + + <!-- The smaller of the two corner radii of the maximize menu buttons. --> + <dimen name="desktop_mode_maximize_menu_buttons_small_corner_radius">2dp</dimen> + + <!-- The corner radius of the maximize menu. --> + <dimen name="desktop_mode_maximize_menu_corner_radius">8dp</dimen> + + <!-- The radius of the Maximize menu shadow. --> + <dimen name="desktop_mode_maximize_menu_shadow_radius">8dp</dimen> + <!-- The width of the handle menu in desktop mode. --> <dimen name="desktop_mode_handle_menu_width">216dp</dimen> 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 36d2a706b88b..93ce91fa2d9c 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 @@ -196,7 +196,8 @@ public abstract class WMShellModule { SyncTransactionQueue syncQueue, Transitions transitions, Optional<DesktopModeController> desktopModeController, - Optional<DesktopTasksController> desktopTasksController) { + Optional<DesktopTasksController> desktopTasksController, + RootTaskDisplayAreaOrganizer rootTaskDisplayAreaOrganizer) { if (DesktopModeStatus.isAnyEnabled()) { return new DesktopModeWindowDecorViewModel( context, @@ -209,7 +210,8 @@ public abstract class WMShellModule { syncQueue, transitions, desktopModeController, - desktopTasksController); + desktopTasksController, + rootTaskDisplayAreaOrganizer); } return new CaptionWindowDecorViewModel( context, diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/desktopmode/DesktopTasksController.kt b/libs/WindowManager/Shell/src/com/android/wm/shell/desktopmode/DesktopTasksController.kt index b0f75c6a1e6d..4740a9d2e030 100644 --- a/libs/WindowManager/Shell/src/com/android/wm/shell/desktopmode/DesktopTasksController.kt +++ b/libs/WindowManager/Shell/src/com/android/wm/shell/desktopmode/DesktopTasksController.kt @@ -105,7 +105,8 @@ class DesktopTasksController( private val transitionAreaHeight get() = context.resources.getDimensionPixelSize( - com.android.wm.shell.R.dimen.desktop_mode_transition_area_height) + com.android.wm.shell.R.dimen.desktop_mode_transition_area_height + ) // This is public to avoid cyclic dependency; it is set by SplitScreenController lateinit var splitScreenController: SplitScreenController @@ -485,6 +486,55 @@ class DesktopTasksController( } } + /** + * Quick-resize to the right or left half of the stable bounds. + * + * @param position the portion of the screen (RIGHT or LEFT) we want to snap the task to. + */ + fun snapToHalfScreen( + taskInfo: RunningTaskInfo, + windowDecor: DesktopModeWindowDecoration, + position: SnapPosition + ) { + val displayLayout = displayController.getDisplayLayout(taskInfo.displayId) ?: return + + val stableBounds = Rect() + displayLayout.getStableBounds(stableBounds) + + val destinationWidth = stableBounds.width() / 2 + val destinationBounds = when (position) { + SnapPosition.LEFT -> { + Rect( + stableBounds.left, + stableBounds.top, + stableBounds.left + destinationWidth, + stableBounds.bottom + ) + } + SnapPosition.RIGHT -> { + Rect( + stableBounds.right - destinationWidth, + stableBounds.top, + stableBounds.right, + stableBounds.bottom + ) + } + } + + if (destinationBounds == taskInfo.configuration.windowConfiguration.bounds) return + + val wct = WindowContainerTransaction().setBounds(taskInfo.token, destinationBounds) + if (Transitions.ENABLE_SHELL_TRANSITIONS) { + toggleResizeDesktopTaskTransitionHandler.startTransition( + wct, + taskInfo.taskId, + windowDecor + ) + } else { + shellTaskOrganizer.applyTransaction(wct) + } + } + private fun getDefaultDesktopTaskBounds(density: Float, stableBounds: Rect, outBounds: Rect) { val width = (DESKTOP_MODE_DEFAULT_WIDTH_DP * density + 0.5f).toInt() val height = (DESKTOP_MODE_DEFAULT_HEIGHT_DP * density + 0.5f).toInt() @@ -1077,4 +1127,7 @@ class DesktopTasksController( return DESKTOP_DENSITY_OVERRIDE in DESKTOP_DENSITY_ALLOWED_RANGE } } + + /** The positions on a screen that a task can snap to. */ + enum class SnapPosition { RIGHT, LEFT } } 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 29fff03500a5..026e973f881a 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 @@ -63,6 +63,7 @@ import androidx.annotation.Nullable; import com.android.internal.annotations.VisibleForTesting; import com.android.wm.shell.R; +import com.android.wm.shell.RootTaskDisplayAreaOrganizer; import com.android.wm.shell.ShellTaskOrganizer; import com.android.wm.shell.common.DisplayController; import com.android.wm.shell.common.DisplayLayout; @@ -70,6 +71,7 @@ import com.android.wm.shell.common.SyncTransactionQueue; import com.android.wm.shell.desktopmode.DesktopModeController; import com.android.wm.shell.desktopmode.DesktopModeStatus; import com.android.wm.shell.desktopmode.DesktopTasksController; +import com.android.wm.shell.desktopmode.DesktopTasksController.SnapPosition; import com.android.wm.shell.freeform.FreeformTaskTransitionStarter; import com.android.wm.shell.splitscreen.SplitScreen; import com.android.wm.shell.splitscreen.SplitScreenController; @@ -120,6 +122,7 @@ public class DesktopModeWindowDecorViewModel implements WindowDecorViewModel { private MoveToDesktopAnimator mMoveToDesktopAnimator; private final Rect mDragToDesktopAnimationStartBounds = new Rect(); private final DesktopModeKeyguardChangeListener mDesktopModeKeyguardChangeListener; + private final RootTaskDisplayAreaOrganizer mRootTaskDisplayAreaOrganizer; public DesktopModeWindowDecorViewModel( Context context, @@ -132,7 +135,8 @@ public class DesktopModeWindowDecorViewModel implements WindowDecorViewModel { SyncTransactionQueue syncQueue, Transitions transitions, Optional<DesktopModeController> desktopModeController, - Optional<DesktopTasksController> desktopTasksController + Optional<DesktopTasksController> desktopTasksController, + RootTaskDisplayAreaOrganizer rootTaskDisplayAreaOrganizer ) { this( context, @@ -149,7 +153,8 @@ public class DesktopModeWindowDecorViewModel implements WindowDecorViewModel { new DesktopModeWindowDecoration.Factory(), new InputMonitorFactory(), SurfaceControl.Transaction::new, - new DesktopModeKeyguardChangeListener()); + new DesktopModeKeyguardChangeListener(), + rootTaskDisplayAreaOrganizer); } @VisibleForTesting @@ -168,7 +173,8 @@ public class DesktopModeWindowDecorViewModel implements WindowDecorViewModel { DesktopModeWindowDecoration.Factory desktopModeWindowDecorFactory, InputMonitorFactory inputMonitorFactory, Supplier<SurfaceControl.Transaction> transactionFactory, - DesktopModeKeyguardChangeListener desktopModeKeyguardChangeListener) { + DesktopModeKeyguardChangeListener desktopModeKeyguardChangeListener, + RootTaskDisplayAreaOrganizer rootTaskDisplayAreaOrganizer) { mContext = context; mMainHandler = mainHandler; mMainChoreographer = mainChoreographer; @@ -185,6 +191,7 @@ public class DesktopModeWindowDecorViewModel implements WindowDecorViewModel { mInputMonitorFactory = inputMonitorFactory; mTransactionFactory = transactionFactory; mDesktopModeKeyguardChangeListener = desktopModeKeyguardChangeListener; + mRootTaskDisplayAreaOrganizer = rootTaskDisplayAreaOrganizer; shellInit.addInitCallback(this::onInit, this); } @@ -318,7 +325,8 @@ public class DesktopModeWindowDecorViewModel implements WindowDecorViewModel { } private class DesktopModeTouchEventListener extends GestureDetector.SimpleOnGestureListener - implements View.OnClickListener, View.OnTouchListener, DragDetector.MotionEventHandler { + implements View.OnClickListener, View.OnTouchListener, View.OnLongClickListener, + DragDetector.MotionEventHandler{ private final int mTaskId; private final WindowContainerToken mTaskToken; @@ -355,9 +363,11 @@ public class DesktopModeWindowDecorViewModel implements WindowDecorViewModel { .getTaskInfo(remainingTaskPosition); mSplitScreenController.moveTaskToFullscreen(remainingTask.taskId); } + decoration.closeMaximizeMenu(); } else if (id == R.id.back_button) { mTaskOperations.injectBackKey(); } else if (id == R.id.caption_handle || id == R.id.open_menu_button) { + decoration.closeMaximizeMenu(); if (!decoration.isHandleMenuActive()) { moveTaskToFront(mTaskOrganizer.getRunningTaskInfo(mTaskId)); decoration.createHandleMenu(); @@ -391,13 +401,35 @@ public class DesktopModeWindowDecorViewModel implements WindowDecorViewModel { // TODO(b/278084491): dev option to enable display switching // remove when select is implemented mDesktopTasksController.ifPresent(c -> c.moveToNextDisplay(mTaskId)); - decoration.closeHandleMenu(); } } else if (id == R.id.maximize_window) { + moveTaskToFront(decoration.mTaskInfo); + if (decoration.isMaximizeMenuActive()) { + decoration.closeMaximizeMenu(); + return; + } final RunningTaskInfo taskInfo = decoration.mTaskInfo; mDesktopTasksController.ifPresent(c -> c.toggleDesktopTaskSize( taskInfo, decoration)); decoration.closeHandleMenu(); + } else if (id == R.id.maximize_menu_maximize_button) { + final RunningTaskInfo taskInfo = decoration.mTaskInfo; + mDesktopTasksController.ifPresent(c -> c.toggleDesktopTaskSize( + taskInfo, mWindowDecorByTaskId.get(taskInfo.taskId))); + decoration.closeHandleMenu(); + decoration.closeMaximizeMenu(); + } else if (id == R.id.maximize_menu_snap_left_button) { + final RunningTaskInfo taskInfo = decoration.mTaskInfo; + mDesktopTasksController.ifPresent(c -> c.snapToHalfScreen( + taskInfo, mWindowDecorByTaskId.get(taskInfo.taskId), SnapPosition.LEFT)); + decoration.closeHandleMenu(); + decoration.closeMaximizeMenu(); + } else if (id == R.id.maximize_menu_snap_right_button) { + final RunningTaskInfo taskInfo = decoration.mTaskInfo; + mDesktopTasksController.ifPresent(c -> c.snapToHalfScreen( + taskInfo, mWindowDecorByTaskId.get(taskInfo.taskId), SnapPosition.RIGHT)); + decoration.closeHandleMenu(); + decoration.closeMaximizeMenu(); } } @@ -412,6 +444,23 @@ public class DesktopModeWindowDecorViewModel implements WindowDecorViewModel { return mDragDetector.onMotionEvent(v, e); } + @Override + public boolean onLongClick(View v) { + final int id = v.getId(); + if (id == R.id.maximize_window) { + final DesktopModeWindowDecoration decoration = mWindowDecorByTaskId.get(mTaskId); + moveTaskToFront(decoration.mTaskInfo); + if (decoration.isMaximizeMenuActive()) { + decoration.closeMaximizeMenu(); + } else { + decoration.closeHandleMenu(); + decoration.createMaximizeMenu(); + } + return true; + } + return false; + } + private void moveTaskToFront(RunningTaskInfo taskInfo) { if (!taskInfo.isFocused) { mDesktopTasksController.ifPresent(c -> c.moveTaskToFront(taskInfo)); @@ -875,7 +924,8 @@ public class DesktopModeWindowDecorViewModel implements WindowDecorViewModel { taskSurface, mMainHandler, mMainChoreographer, - mSyncQueue); + mSyncQueue, + mRootTaskDisplayAreaOrganizer); mWindowDecorByTaskId.put(taskInfo.taskId, windowDecoration); windowDecoration.createResizeVeil(); @@ -884,7 +934,8 @@ public class DesktopModeWindowDecorViewModel implements WindowDecorViewModel { final DesktopModeTouchEventListener touchEventListener = new DesktopModeTouchEventListener(taskInfo, dragPositioningCallback); - windowDecoration.setCaptionListeners(touchEventListener, touchEventListener); + windowDecoration.setCaptionListeners( + touchEventListener, touchEventListener, touchEventListener); windowDecoration.setCornersListener(mCornersListener); windowDecoration.setDragPositioningCallback(dragPositioningCallback); windowDecoration.setDragDetector(touchEventListener.mDragDetector); @@ -911,7 +962,9 @@ public class DesktopModeWindowDecorViewModel implements WindowDecorViewModel { implements DragPositioningCallbackUtility.DragStartListener { @Override public void onDragStart(int taskId) { - mWindowDecorByTaskId.get(taskId).closeHandleMenu(); + final DesktopModeWindowDecoration decoration = mWindowDecorByTaskId.get(taskId); + decoration.closeHandleMenu(); + decoration.closeMaximizeMenu(); } } 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 a359395711e3..a75dce225624 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 @@ -23,6 +23,7 @@ import android.content.Context; import android.content.pm.ApplicationInfo; import android.content.pm.PackageManager; import android.content.res.Configuration; +import android.content.res.Resources; import android.graphics.Point; import android.graphics.PointF; import android.graphics.Rect; @@ -36,13 +37,16 @@ import android.view.MotionEvent; import android.view.SurfaceControl; import android.view.View; import android.view.ViewConfiguration; +import android.widget.ImageButton; import android.window.WindowContainerTransaction; import com.android.internal.policy.ScreenDecorationsUtils; import com.android.launcher3.icons.IconProvider; import com.android.wm.shell.R; +import com.android.wm.shell.RootTaskDisplayAreaOrganizer; import com.android.wm.shell.ShellTaskOrganizer; import com.android.wm.shell.common.DisplayController; +import com.android.wm.shell.common.DisplayLayout; import com.android.wm.shell.common.SyncTransactionQueue; import com.android.wm.shell.desktopmode.DesktopModeStatus; import com.android.wm.shell.desktopmode.DesktopTasksController; @@ -69,6 +73,7 @@ public class DesktopModeWindowDecoration extends WindowDecoration<WindowDecorLin private DesktopModeWindowDecorationViewHolder mWindowDecorViewHolder; private View.OnClickListener mOnCaptionButtonClickListener; private View.OnTouchListener mOnCaptionTouchListener; + private View.OnLongClickListener mOnCaptionLongClickListener; private DragPositioningCallback mDragPositioningCallback; private DragResizeInputListener mDragResizeListener; private DragDetector mDragDetector; @@ -80,6 +85,8 @@ public class DesktopModeWindowDecoration extends WindowDecoration<WindowDecorLin private final Point mPositionInParent = new Point(); private HandleMenu mHandleMenu; + private MaximizeMenu mMaximizeMenu; + private ResizeVeil mResizeVeil; private Drawable mAppIcon; @@ -89,6 +96,7 @@ public class DesktopModeWindowDecoration extends WindowDecoration<WindowDecorLin private final Set<IBinder> mTransitionsPausingRelayout = new HashSet<>(); private int mRelayoutBlock; + private final RootTaskDisplayAreaOrganizer mRootTaskDisplayAreaOrganizer; DesktopModeWindowDecoration( Context context, @@ -98,12 +106,14 @@ public class DesktopModeWindowDecoration extends WindowDecoration<WindowDecorLin SurfaceControl taskSurface, Handler handler, Choreographer choreographer, - SyncTransactionQueue syncQueue) { + SyncTransactionQueue syncQueue, + RootTaskDisplayAreaOrganizer rootTaskDisplayAreaOrganizer) { super(context, displayController, taskOrganizer, taskInfo, taskSurface); mHandler = handler; mChoreographer = choreographer; mSyncQueue = syncQueue; + mRootTaskDisplayAreaOrganizer = rootTaskDisplayAreaOrganizer; loadAppInfo(); } @@ -121,9 +131,11 @@ public class DesktopModeWindowDecoration extends WindowDecoration<WindowDecorLin void setCaptionListeners( View.OnClickListener onCaptionButtonClickListener, - View.OnTouchListener onCaptionTouchListener) { + View.OnTouchListener onCaptionTouchListener, + View.OnLongClickListener onLongClickListener) { mOnCaptionButtonClickListener = onCaptionButtonClickListener; mOnCaptionTouchListener = onCaptionTouchListener; + mOnCaptionLongClickListener = onLongClickListener; } void setCornersListener(TaskCornersListener cornersListener) { @@ -207,6 +219,7 @@ public class DesktopModeWindowDecoration extends WindowDecoration<WindowDecorLin mResult.mRootView, mOnCaptionTouchListener, mOnCaptionButtonClickListener, + mOnCaptionLongClickListener, mAppName, mAppIcon ); @@ -218,6 +231,7 @@ public class DesktopModeWindowDecoration extends WindowDecoration<WindowDecorLin if (!mTaskInfo.isFocused) { closeHandleMenu(); + closeMaximizeMenu(); } if (!isDragResizeable) { @@ -255,6 +269,52 @@ public class DesktopModeWindowDecoration extends WindowDecoration<WindowDecorLin mCornersListener.onTaskCornersChanged(mTaskInfo.taskId, getGlobalCornersRegion()); } mPositionInParent.set(mTaskInfo.positionInParent); + + if (isMaximizeMenuActive()) { + if (!mTaskInfo.isVisible()) { + closeMaximizeMenu(); + } else { + mMaximizeMenu.positionMenu(calculateMaximizeMenuPosition(), startT); + } + } + } + + private PointF calculateMaximizeMenuPosition() { + final PointF position = new PointF(); + final Resources resources = mContext.getResources(); + final DisplayLayout displayLayout = + mDisplayController.getDisplayLayout(mTaskInfo.displayId); + if (displayLayout == null) return position; + + final int displayWidth = displayLayout.width(); + final int displayHeight = displayLayout.height(); + final int captionHeight = loadDimensionPixelSize( + resources, R.dimen.freeform_decor_caption_height); + + final ImageButton maximizeWindowButton = + mResult.mRootView.findViewById(R.id.maximize_window); + final int[] maximizeButtonLocation = new int[2]; + maximizeWindowButton.getLocationInWindow(maximizeButtonLocation); + + final int menuWidth = loadDimensionPixelSize( + resources, R.dimen.desktop_mode_maximize_menu_width); + final int menuHeight = loadDimensionPixelSize( + resources, R.dimen.desktop_mode_maximize_menu_height); + + float menuLeft = (mPositionInParent.x + maximizeButtonLocation[0]); + float menuTop = (mPositionInParent.y + captionHeight); + final float menuRight = menuLeft + menuWidth; + final float menuBottom = menuTop + menuHeight; + + // If the menu is out of screen bounds, shift it up/left as needed + if (menuRight > displayWidth) { + menuLeft = (displayWidth - menuWidth); + } + if (menuBottom > displayHeight) { + menuTop = (displayHeight - menuHeight); + } + + return new PointF(menuLeft, menuTop); } boolean isHandleMenuActive() { @@ -335,6 +395,29 @@ public class DesktopModeWindowDecoration extends WindowDecoration<WindowDecorLin } /** + * Create and display maximize menu window + */ + void createMaximizeMenu() { + mMaximizeMenu = new MaximizeMenu(mSyncQueue, mRootTaskDisplayAreaOrganizer, + mDisplayController, mTaskInfo, mOnCaptionButtonClickListener, mContext, + calculateMaximizeMenuPosition(), mSurfaceControlTransactionSupplier); + mMaximizeMenu.show(); + } + + /** + * Close the maximize menu window + */ + void closeMaximizeMenu() { + if (!isMaximizeMenuActive()) return; + mMaximizeMenu.close(); + mMaximizeMenu = null; + } + + boolean isMaximizeMenuActive() { + return mMaximizeMenu != null; + } + + /** * Create and display handle menu window */ void createHandleMenu() { @@ -532,7 +615,8 @@ public class DesktopModeWindowDecoration extends WindowDecoration<WindowDecorLin SurfaceControl taskSurface, Handler handler, Choreographer choreographer, - SyncTransactionQueue syncQueue) { + SyncTransactionQueue syncQueue, + RootTaskDisplayAreaOrganizer rootTaskDisplayAreaOrganizer) { return new DesktopModeWindowDecoration( context, displayController, @@ -541,7 +625,8 @@ public class DesktopModeWindowDecoration extends WindowDecoration<WindowDecorLin taskSurface, handler, choreographer, - syncQueue); + syncQueue, + rootTaskDisplayAreaOrganizer); } } diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/MaximizeMenu.kt b/libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/MaximizeMenu.kt new file mode 100644 index 000000000000..4dc98e47ab45 --- /dev/null +++ b/libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/MaximizeMenu.kt @@ -0,0 +1,154 @@ +/* + * Copyright (C) 2023 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.android.wm.shell.windowdecor + +import android.app.ActivityManager.RunningTaskInfo +import android.content.Context +import android.content.res.Resources +import android.graphics.PixelFormat +import android.graphics.PointF +import android.view.LayoutInflater +import android.view.SurfaceControl +import android.view.SurfaceControl.Transaction +import android.view.SurfaceControlViewHost +import android.view.View.OnClickListener +import android.view.WindowManager +import android.view.WindowlessWindowManager +import android.widget.Button +import android.window.TaskConstants +import com.android.wm.shell.R +import com.android.wm.shell.RootTaskDisplayAreaOrganizer +import com.android.wm.shell.common.DisplayController +import com.android.wm.shell.common.SyncTransactionQueue +import com.android.wm.shell.windowdecor.WindowDecoration.AdditionalWindow +import java.util.function.Supplier + + +/** + * Menu that appears when user long clicks the maximize button. Gives the user the option to + * maximize the task or snap the task to the right or left half of the screen. + */ +class MaximizeMenu( + private val syncQueue: SyncTransactionQueue, + private val rootTdaOrganizer: RootTaskDisplayAreaOrganizer, + private val displayController: DisplayController, + private val taskInfo: RunningTaskInfo, + private val onClickListener: OnClickListener, + private val decorWindowContext: Context, + private val menuPosition: PointF, + private val transactionSupplier: Supplier<Transaction> = Supplier { Transaction() } +) { + private var maximizeMenu: AdditionalWindow? = null + private lateinit var viewHost: SurfaceControlViewHost + private lateinit var leash: SurfaceControl + private val shadowRadius = loadDimensionPixelSize( + R.dimen.desktop_mode_maximize_menu_shadow_radius + ).toFloat() + private val cornerRadius = loadDimensionPixelSize( + R.dimen.desktop_mode_maximize_menu_corner_radius + ).toFloat() + + /** Position the menu relative to the caption's position. */ + fun positionMenu(position: PointF, t: Transaction) { + menuPosition.set(position) + t.setPosition(leash, menuPosition.x, menuPosition.y) + } + + /** Creates and shows the maximize window. */ + fun show() { + if (maximizeMenu != null) return + createMaximizeMenu() + setupMaximizeMenu() + } + + /** Closes the maximize window and releases its view. */ + fun close() { + maximizeMenu?.releaseView() + maximizeMenu = null + } + + /** Create a maximize menu that is attached to the display area. */ + private fun createMaximizeMenu() { + val t = transactionSupplier.get() + val v = LayoutInflater.from(decorWindowContext).inflate( + R.layout.desktop_mode_window_decor_maximize_menu, + null // Root + ) + val builder = SurfaceControl.Builder() + rootTdaOrganizer.attachToDisplayArea(taskInfo.displayId, builder) + leash = builder + .setName("Maximize Menu") + .setContainerLayer() + .build() + val menuWidth = loadDimensionPixelSize(R.dimen.desktop_mode_maximize_menu_width) + val menuHeight = loadDimensionPixelSize(R.dimen.desktop_mode_maximize_menu_height) + val lp = WindowManager.LayoutParams( + menuWidth, + menuHeight, + WindowManager.LayoutParams.TYPE_APPLICATION, + WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE, + PixelFormat.TRANSPARENT + ) + lp.title = "Maximize Menu for Task=" + taskInfo.taskId + lp.setTrustedOverlay() + val windowManager = WindowlessWindowManager( + taskInfo.configuration, + leash, + null // HostInputToken + ) + viewHost = SurfaceControlViewHost(decorWindowContext, + displayController.getDisplay(taskInfo.displayId), windowManager, + "MaximizeMenu") + viewHost.setView(v, lp) + + // Bring menu to front when open + t.setLayer(leash, TaskConstants.TASK_CHILD_LAYER_FLOATING_MENU) + .setPosition(leash, menuPosition.x, menuPosition.y) + .setWindowCrop(leash, menuWidth, menuHeight) + .setShadowRadius(leash, shadowRadius) + .setCornerRadius(leash, cornerRadius) + .show(leash) + maximizeMenu = AdditionalWindow(leash, viewHost, transactionSupplier) + + syncQueue.runInSync { transaction -> + transaction.merge(t) + t.close() + } + } + + private fun loadDimensionPixelSize(resourceId: Int): Int { + return if (resourceId == Resources.ID_NULL) { + 0 + } else { + decorWindowContext.resources.getDimensionPixelSize(resourceId) + } + } + + private fun setupMaximizeMenu() { + val maximizeMenuView = maximizeMenu?.mWindowViewHost?.view ?: return + + maximizeMenuView.findViewById<Button>( + R.id.maximize_menu_maximize_button + ).setOnClickListener(onClickListener) + maximizeMenuView.findViewById<Button>( + R.id.maximize_menu_snap_right_button + ).setOnClickListener(onClickListener) + maximizeMenuView.findViewById<Button>( + R.id.maximize_menu_snap_left_button + ).setOnClickListener(onClickListener) + } +} diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/viewholder/DesktopModeAppControlsWindowDecorationViewHolder.kt b/libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/viewholder/DesktopModeAppControlsWindowDecorationViewHolder.kt index a9eb8829bd2c..6b59ccec5148 100644 --- a/libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/viewholder/DesktopModeAppControlsWindowDecorationViewHolder.kt +++ b/libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/viewholder/DesktopModeAppControlsWindowDecorationViewHolder.kt @@ -5,6 +5,7 @@ import android.content.res.ColorStateList import android.graphics.drawable.Drawable import android.graphics.drawable.GradientDrawable import android.view.View +import android.view.View.OnLongClickListener import android.widget.ImageButton import android.widget.ImageView import android.widget.TextView @@ -19,6 +20,7 @@ internal class DesktopModeAppControlsWindowDecorationViewHolder( rootView: View, onCaptionTouchListener: View.OnTouchListener, onCaptionButtonClickListener: View.OnClickListener, + onLongClickListener: OnLongClickListener, appName: CharSequence, appIcon: Drawable ) : DesktopModeWindowDecorationViewHolder(rootView) { @@ -39,6 +41,7 @@ internal class DesktopModeAppControlsWindowDecorationViewHolder( openMenuButton.setOnTouchListener(onCaptionTouchListener) closeWindowButton.setOnClickListener(onCaptionButtonClickListener) maximizeWindowButton.setOnClickListener(onCaptionButtonClickListener) + maximizeWindowButton.onLongClickListener = onLongClickListener closeWindowButton.setOnTouchListener(onCaptionTouchListener) appNameTextView.text = appName appIconImageView.setImageDrawable(appIcon) diff --git a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/windowdecor/DesktopModeWindowDecorViewModelTests.java b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/windowdecor/DesktopModeWindowDecorViewModelTests.java index 596d6dd3a3d2..7f0465a24a18 100644 --- a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/windowdecor/DesktopModeWindowDecorViewModelTests.java +++ b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/windowdecor/DesktopModeWindowDecorViewModelTests.java @@ -48,6 +48,7 @@ import android.view.SurfaceView; import androidx.test.filters.SmallTest; +import com.android.wm.shell.RootTaskDisplayAreaOrganizer; import com.android.wm.shell.ShellTaskOrganizer; import com.android.wm.shell.ShellTestCase; import com.android.wm.shell.TestRunningTaskInfoBuilder; @@ -100,6 +101,7 @@ public class DesktopModeWindowDecorViewModelTests extends ShellTestCase { @Mock private ShellInit mShellInit; @Mock private DesktopModeWindowDecorViewModel.DesktopModeKeyguardChangeListener mDesktopModeKeyguardChangeListener; + @Mock private RootTaskDisplayAreaOrganizer mRootTaskDisplayAreaOrganizer; private final List<InputManager> mMockInputManagers = new ArrayList<>(); private DesktopModeWindowDecorViewModel mDesktopModeWindowDecorViewModel; @@ -109,27 +111,28 @@ public class DesktopModeWindowDecorViewModelTests extends ShellTestCase { mMockInputManagers.add(mInputManager); mDesktopModeWindowDecorViewModel = - new DesktopModeWindowDecorViewModel( - mContext, - mMainHandler, - mMainChoreographer, - mShellInit, - mTaskOrganizer, - mDisplayController, - mShellController, - mSyncQueue, - mTransitions, - Optional.of(mDesktopModeController), - Optional.of(mDesktopTasksController), - mDesktopModeWindowDecorFactory, - mMockInputMonitorFactory, - mTransactionFactory, - mDesktopModeKeyguardChangeListener - ); + new DesktopModeWindowDecorViewModel( + mContext, + mMainHandler, + mMainChoreographer, + mShellInit, + mTaskOrganizer, + mDisplayController, + mShellController, + mSyncQueue, + mTransitions, + Optional.of(mDesktopModeController), + Optional.of(mDesktopTasksController), + mDesktopModeWindowDecorFactory, + mMockInputMonitorFactory, + mTransactionFactory, + mDesktopModeKeyguardChangeListener, + mRootTaskDisplayAreaOrganizer + ); doReturn(mDesktopModeWindowDecoration) - .when(mDesktopModeWindowDecorFactory) - .create(any(), any(), any(), any(), any(), any(), any(), any()); + .when(mDesktopModeWindowDecorFactory) + .create(any(), any(), any(), any(), any(), any(), any(), any(), any()); doReturn(mTransaction).when(mTransactionFactory).get(); doReturn(mDisplayLayout).when(mDisplayController).getDisplayLayout(anyInt()); doReturn(STABLE_INSETS).when(mDisplayLayout).stableInsets(); @@ -172,7 +175,8 @@ public class DesktopModeWindowDecorViewModelTests extends ShellTestCase { surfaceControl, mMainHandler, mMainChoreographer, - mSyncQueue); + mSyncQueue, + mRootTaskDisplayAreaOrganizer); verify(mDesktopModeWindowDecoration).close(); } @@ -205,7 +209,8 @@ public class DesktopModeWindowDecorViewModelTests extends ShellTestCase { surfaceControl, mMainHandler, mMainChoreographer, - mSyncQueue); + mSyncQueue, + mRootTaskDisplayAreaOrganizer); } @Test @@ -291,7 +296,7 @@ public class DesktopModeWindowDecorViewModelTests extends ShellTestCase { taskInfo, surfaceControl, startT, finishT); }); verify(mDesktopModeWindowDecorFactory, never()) - .create(any(), any(), any(), any(), any(), any(), any(), any()); + .create(any(), any(), any(), any(), any(), any(), any(), any(), any()); } private void runOnMainThread(Runnable r) throws Exception { @@ -307,10 +312,10 @@ public class DesktopModeWindowDecorViewModelTests extends ShellTestCase { private static ActivityManager.RunningTaskInfo createTaskInfo(int taskId, int displayId, @WindowConfiguration.WindowingMode int windowingMode) { ActivityManager.RunningTaskInfo taskInfo = - new TestRunningTaskInfoBuilder() - .setDisplayId(displayId) - .setVisible(true) - .build(); + new TestRunningTaskInfoBuilder() + .setDisplayId(displayId) + .setVisible(true) + .build(); taskInfo.taskId = taskId; taskInfo.configuration.windowConfiguration.setWindowingMode(windowingMode); return taskInfo; |