diff options
5 files changed, 88 insertions, 95 deletions
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 index 8d7e5fd95957..d50a14cf5dae 100644 --- 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 @@ -18,23 +18,28 @@ xmlns:androidprv="http://schemas.android.com/apk/prv/res/android" android:id="@+id/maximize_menu" android:layout_width="wrap_content" - android:layout_height="@dimen/desktop_mode_maximize_menu_height" + android:layout_height="wrap_content" android:background="@drawable/desktop_mode_maximize_menu_background" android:elevation="1dp"> <LinearLayout android:id="@+id/container" android:layout_width="wrap_content" - android:layout_height="@dimen/desktop_mode_maximize_menu_height" + android:layout_height="wrap_content" android:orientation="horizontal" - android:padding="16dp" + android:paddingHorizontal="12dp" + android:paddingVertical="16dp" + android:measureWithLargestChild="true" android:gravity="center"> <LinearLayout android:id="@+id/maximize_menu_immersive_toggle_container" android:layout_width="wrap_content" android:layout_height="wrap_content" - android:orientation="vertical"> + android:layout_weight="1" + android:orientation="vertical" + android:layout_marginStart="4dp" + android:layout_marginEnd="4dp"> <Button android:layout_width="94dp" @@ -44,21 +49,22 @@ android:stateListAnimator="@null" android:importantForAccessibility="yes" android:contentDescription="@string/desktop_mode_maximize_menu_immersive_button_text" - android:layout_marginEnd="8dp" android:layout_marginBottom="4dp" android:alpha="0"/> <TextView android:id="@+id/maximize_menu_immersive_toggle_button_text" - android:layout_width="94dp" - android:layout_height="18dp" + android:layout_width="wrap_content" + android:layout_height="wrap_content" android:textSize="11sp" - android:layout_marginBottom="76dp" + android:lineHeight="16sp" android:gravity="center" android:fontFamily="google-sans-text" + android:textFontWeight="500" android:importantForAccessibility="no" android:text="@string/desktop_mode_maximize_menu_immersive_button_text" android:textColor="@androidprv:color/materialColorOnSurface" + android:singleLine="true" android:alpha="0"/> </LinearLayout> @@ -66,7 +72,11 @@ android:id="@+id/maximize_menu_size_toggle_container" android:layout_width="wrap_content" android:layout_height="wrap_content" - android:orientation="vertical"> + android:layout_weight="1" + android:orientation="vertical" + android:gravity="center_horizontal" + android:layout_marginStart="4dp" + android:layout_marginEnd="4dp"> <Button android:layout_width="94dp" @@ -81,15 +91,17 @@ <TextView android:id="@+id/maximize_menu_size_toggle_button_text" - android:layout_width="94dp" - android:layout_height="18dp" + android:layout_width="wrap_content" + android:layout_height="wrap_content" android:textSize="11sp" - android:layout_marginBottom="76dp" + android:lineHeight="16sp" android:gravity="center" android:fontFamily="google-sans-text" + android:textFontWeight="500" android:importantForAccessibility="no" android:text="@string/desktop_mode_maximize_menu_maximize_text" android:textColor="@androidprv:color/materialColorOnSurface" + android:singleLine="true" android:alpha="0"/> </LinearLayout> @@ -97,7 +109,11 @@ android:id="@+id/maximize_menu_snap_container" android:layout_width="wrap_content" android:layout_height="wrap_content" - android:orientation="vertical"> + android:layout_weight="1" + android:orientation="vertical" + android:gravity="center_horizontal" + android:layout_marginStart="4dp" + android:layout_marginEnd="4dp"> <LinearLayout android:id="@+id/maximize_menu_snap_menu_layout" android:layout_width="wrap_content" @@ -106,7 +122,6 @@ android:padding="4dp" android:background="@drawable/desktop_mode_maximize_menu_layout_background" android:layout_marginBottom="4dp" - android:layout_marginStart="8dp" android:alpha="0"> <Button android:id="@+id/maximize_menu_snap_left_button" @@ -131,16 +146,17 @@ </LinearLayout> <TextView android:id="@+id/maximize_menu_snap_window_text" - android:layout_width="94dp" - android:layout_height="18dp" + android:layout_width="wrap_content" + android:layout_height="wrap_content" android:textSize="11sp" - android:layout_marginBottom="76dp" - android:layout_gravity="center" + android:lineHeight="16sp" android:gravity="center" android:importantForAccessibility="no" android:fontFamily="google-sans-text" + android:textFontWeight="500" android:text="@string/desktop_mode_maximize_menu_snap_text" android:textColor="@androidprv:color/materialColorOnSurface" + android:singleLine="true" android:alpha="0"/> </LinearLayout> </LinearLayout> @@ -150,6 +166,6 @@ <View android:id="@+id/maximize_menu_overlay" android:layout_width="match_parent" - android:layout_height="@dimen/desktop_mode_maximize_menu_height"/> + android:layout_height="match_parent"/> </FrameLayout> diff --git a/libs/WindowManager/Shell/res/values/dimen.xml b/libs/WindowManager/Shell/res/values/dimen.xml index e23d5725e9c3..d416ad079412 100644 --- a/libs/WindowManager/Shell/res/values/dimen.xml +++ b/libs/WindowManager/Shell/res/values/dimen.xml @@ -487,14 +487,6 @@ <!-- The default minimum allowed window height when resizing a window in desktop mode. --> <dimen name="desktop_mode_minimum_window_height">352dp</dimen> - <!-- The width of the maximize menu in desktop mode, depending on the number of options --> - <dimen name="desktop_mode_maximize_menu_width_one_options">126dp</dimen> - <dimen name="desktop_mode_maximize_menu_width_two_options">228dp</dimen> - <dimen name="desktop_mode_maximize_menu_width_three_options">330dp</dimen> - - <!-- The height of the maximize menu in desktop mode. --> - <dimen name="desktop_mode_maximize_menu_height">114dp</dimen> - <!-- The padding of the maximize menu in desktop mode. --> <dimen name="desktop_mode_menu_padding">16dp</dimen> 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 3fb94630eab3..271dead467b4 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 @@ -803,8 +803,7 @@ public class DesktopModeWindowDecoration extends WindowDecoration<WindowDecorLin if (!mTaskInfo.isVisible()) { closeMaximizeMenu(); } else { - final int menuWidth = calculateMaximizeMenuWidth(); - mMaximizeMenu.positionMenu(calculateMaximizeMenuPosition(menuWidth), startT); + mMaximizeMenu.positionMenu(startT); } } @@ -1069,27 +1068,7 @@ public class DesktopModeWindowDecoration extends WindowDecoration<WindowDecorLin return Resources.ID_NULL; } - private int calculateMaximizeMenuWidth() { - final boolean showImmersive = DesktopModeFlags.ENABLE_FULLY_IMMERSIVE_IN_DESKTOP.isTrue() - && TaskInfoKt.getRequestingImmersive(mTaskInfo); - final boolean showMaximize = true; - final boolean showSnaps = mTaskInfo.isResizeable; - int showCount = 0; - if (showImmersive) showCount++; - if (showMaximize) showCount++; - if (showSnaps) showCount++; - return switch (showCount) { - case 1 -> loadDimensionPixelSize(mContext.getResources(), - R.dimen.desktop_mode_maximize_menu_width_one_options); - case 2 -> loadDimensionPixelSize(mContext.getResources(), - R.dimen.desktop_mode_maximize_menu_width_two_options); - case 3 -> loadDimensionPixelSize(mContext.getResources(), - R.dimen.desktop_mode_maximize_menu_width_three_options); - default -> throw new IllegalArgumentException(""); - }; - } - - private PointF calculateMaximizeMenuPosition(int menuWidth) { + private PointF calculateMaximizeMenuPosition(int menuWidth, int menuHeight) { final PointF position = new PointF(); final Resources resources = mContext.getResources(); final DisplayLayout displayLayout = @@ -1105,9 +1084,6 @@ public class DesktopModeWindowDecoration extends WindowDecoration<WindowDecorLin final int[] maximizeButtonLocation = new int[2]; maximizeWindowButton.getLocationInWindow(maximizeButtonLocation); - final int menuHeight = loadDimensionPixelSize( - resources, R.dimen.desktop_mode_maximize_menu_height); - float menuLeft = (mPositionInParent.x + maximizeButtonLocation[0] - ((float) (menuWidth - maximizeWindowButton.getWidth()) / 2)); float menuTop = (mPositionInParent.y + captionHeight); @@ -1294,17 +1270,16 @@ public class DesktopModeWindowDecoration extends WindowDecoration<WindowDecorLin * Create and display maximize menu window */ void createMaximizeMenu() { - final int menuWidth = calculateMaximizeMenuWidth(); mMaximizeMenu = mMaximizeMenuFactory.create(mSyncQueue, mRootTaskDisplayAreaOrganizer, mDisplayController, mTaskInfo, mContext, - calculateMaximizeMenuPosition(menuWidth), mSurfaceControlTransactionSupplier); + (width, height) -> calculateMaximizeMenuPosition(width, height), + mSurfaceControlTransactionSupplier); mMaximizeMenu.show( /* isTaskInImmersiveMode= */ DesktopModeFlags.ENABLE_FULLY_IMMERSIVE_IN_DESKTOP.isTrue() && mDesktopUserRepositories.getProfile(mTaskInfo.userId) .isTaskInFullImmersiveState(mTaskInfo.taskId), - /* menuWidth= */ menuWidth, /* showImmersiveOption= */ DesktopModeFlags.ENABLE_FULLY_IMMERSIVE_IN_DESKTOP.isTrue() && TaskInfoKt.getRequestingImmersive(mTaskInfo), 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 index 38accce82999..ad3525af3f94 100644 --- a/libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/MaximizeMenu.kt +++ b/libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/MaximizeMenu.kt @@ -90,7 +90,7 @@ class MaximizeMenu( private val displayController: DisplayController, private val taskInfo: RunningTaskInfo, private val decorWindowContext: Context, - private val menuPosition: PointF, + private val positionSupplier: (Int, Int) -> PointF, private val transactionSupplier: Supplier<Transaction> = Supplier { Transaction() } ) { private var maximizeMenu: AdditionalViewHostViewContainer? = null @@ -100,19 +100,19 @@ class MaximizeMenu( private val cornerRadius = loadDimensionPixelSize( R.dimen.desktop_mode_maximize_menu_corner_radius ).toFloat() - private val menuHeight = loadDimensionPixelSize(R.dimen.desktop_mode_maximize_menu_height) + private lateinit var menuPosition: PointF private val menuPadding = loadDimensionPixelSize(R.dimen.desktop_mode_menu_padding) /** Position the menu relative to the caption's position. */ - fun positionMenu(position: PointF, t: Transaction) { - menuPosition.set(position) + fun positionMenu(t: Transaction) { + menuPosition = positionSupplier(maximizeMenuView?.measureWidth() ?: 0, + maximizeMenuView?.measureHeight() ?: 0) t.setPosition(leash, menuPosition.x, menuPosition.y) } /** Creates and shows the maximize window. */ fun show( isTaskInImmersiveMode: Boolean, - menuWidth: Int, showImmersiveOption: Boolean, showSnapOptions: Boolean, onMaximizeOrRestoreClickListener: () -> Unit, @@ -125,7 +125,6 @@ class MaximizeMenu( if (maximizeMenu != null) return createMaximizeMenu( isTaskInImmersiveMode = isTaskInImmersiveMode, - menuWidth = menuWidth, showImmersiveOption = showImmersiveOption, showSnapOptions = showSnapOptions, onMaximizeClickListener = onMaximizeOrRestoreClickListener, @@ -161,7 +160,6 @@ class MaximizeMenu( /** Create a maximize menu that is attached to the display area. */ private fun createMaximizeMenu( isTaskInImmersiveMode: Boolean, - menuWidth: Int, showImmersiveOption: Boolean, showSnapOptions: Boolean, onMaximizeClickListener: () -> Unit, @@ -178,16 +176,6 @@ class MaximizeMenu( .setName("Maximize Menu") .setContainerLayer() .build() - val lp = WindowManager.LayoutParams( - menuWidth, - menuHeight, - WindowManager.LayoutParams.TYPE_APPLICATION, - WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE - or WindowManager.LayoutParams.FLAG_WATCH_OUTSIDE_TOUCH, - PixelFormat.TRANSPARENT - ) - lp.title = "Maximize Menu for Task=" + taskInfo.taskId - lp.setTrustedOverlay() val windowManager = WindowlessWindowManager( taskInfo.configuration, leash, @@ -207,7 +195,6 @@ class MaximizeMenu( MaximizeMenuView.ImmersiveConfig.Hidden }, showSnapOptions = showSnapOptions, - menuHeight = menuHeight, menuPadding = menuPadding, ).also { menuView -> menuView.bind(taskInfo) @@ -217,6 +204,19 @@ class MaximizeMenu( menuView.onRightSnapClickListener = onRightSnapClickListener menuView.onMenuHoverListener = onHoverListener menuView.onOutsideTouchListener = onOutsideTouchListener + val menuWidth = menuView.measureWidth() + val menuHeight = menuView.measureHeight() + menuPosition = positionSupplier(menuWidth, menuHeight) + val lp = WindowManager.LayoutParams( + menuWidth.toInt(), + menuHeight.toInt(), + WindowManager.LayoutParams.TYPE_APPLICATION, + WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE + or WindowManager.LayoutParams.FLAG_WATCH_OUTSIDE_TOUCH, + PixelFormat.TRANSPARENT + ) + lp.title = "Maximize Menu for Task=" + taskInfo.taskId + lp.setTrustedOverlay() viewHost.setView(menuView.rootView, lp) } @@ -268,7 +268,6 @@ class MaximizeMenu( private val sizeToggleDirection: SizeToggleDirection, immersiveConfig: ImmersiveConfig, showSnapOptions: Boolean, - private val menuHeight: Int, private val menuPadding: Int ) { val rootView = LayoutInflater.from(context) @@ -583,7 +582,7 @@ class MaximizeMenu( // the menu. val value = animatedValue as Float val topPadding = menuPadding - - ((1 - value) * menuHeight).toInt() + ((1 - value) * measureHeight()).toInt() container.setPadding(menuPadding, topPadding, menuPadding, menuPadding) } @@ -604,7 +603,7 @@ class MaximizeMenu( } }, ObjectAnimator.ofFloat(rootView, TRANSLATION_Y, - (STARTING_MENU_HEIGHT_SCALE - 1) * menuHeight, 0f).apply { + (STARTING_MENU_HEIGHT_SCALE - 1) * measureHeight(), 0f).apply { duration = OPEN_MENU_HEIGHT_ANIMATION_DURATION_MS interpolator = EMPHASIZED_DECELERATE }, @@ -667,7 +666,7 @@ class MaximizeMenu( // the menu. val value = animatedValue as Float val topPadding = menuPadding - - ((1 - value) * menuHeight).toInt() + ((1 - value) * measureHeight()).toInt() container.setPadding(menuPadding, topPadding, menuPadding, menuPadding) } @@ -688,7 +687,7 @@ class MaximizeMenu( } }, ObjectAnimator.ofFloat(rootView, TRANSLATION_Y, - 0f, (STARTING_MENU_HEIGHT_SCALE - 1) * menuHeight).apply { + 0f, (STARTING_MENU_HEIGHT_SCALE - 1) * measureHeight()).apply { duration = CLOSE_MENU_HEIGHT_ANIMATION_DURATION_MS interpolator = FAST_OUT_LINEAR_IN }, @@ -792,6 +791,18 @@ class MaximizeMenu( ) } + /** Measure width of the root view of this menu. */ + fun measureWidth() : Int { + rootView.measure(View.MeasureSpec.UNSPECIFIED, View.MeasureSpec.UNSPECIFIED); + return rootView.getMeasuredWidth() + } + + /** Measure height of the root view of this menu. */ + fun measureHeight() : Int { + rootView.measure(View.MeasureSpec.UNSPECIFIED, View.MeasureSpec.UNSPECIFIED); + return rootView.getMeasuredHeight() + } + private fun deactivateSnapOptions() { // TODO(b/346440693): the background/colorStateList set on these buttons is overridden // to a static resource & color on manually tracked hover events, which defeats the @@ -1036,7 +1047,7 @@ interface MaximizeMenuFactory { displayController: DisplayController, taskInfo: RunningTaskInfo, decorWindowContext: Context, - menuPosition: PointF, + positionSupplier: (Int, Int) -> PointF, transactionSupplier: Supplier<Transaction> ): MaximizeMenu } @@ -1049,7 +1060,7 @@ object DefaultMaximizeMenuFactory : MaximizeMenuFactory { displayController: DisplayController, taskInfo: RunningTaskInfo, decorWindowContext: Context, - menuPosition: PointF, + positionSupplier: (Int, Int) -> PointF, transactionSupplier: Supplier<Transaction> ): MaximizeMenu { return MaximizeMenu( @@ -1058,7 +1069,7 @@ object DefaultMaximizeMenuFactory : MaximizeMenuFactory { displayController, taskInfo, decorWindowContext, - menuPosition, + positionSupplier, transactionSupplier ) } 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 71c821dd9b71..c4f70ac2297f 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 @@ -120,6 +120,7 @@ import com.android.wm.shell.windowdecor.viewholder.AppHeaderViewHolder; import kotlin.Unit; import kotlin.jvm.functions.Function0; import kotlin.jvm.functions.Function1; +import kotlin.jvm.functions.Function2; import kotlinx.coroutines.CoroutineScope; import kotlinx.coroutines.MainCoroutineDispatcher; @@ -998,8 +999,8 @@ public class DesktopModeWindowDecorationTests extends ShellTestCase { createMaximizeMenu(decoration); - verify(menu).show(anyBoolean(), anyInt(), anyBoolean(), anyBoolean(), any(), any(), any(), - any(), mOnMaxMenuHoverChangeListener.capture(), any()); + verify(menu).show(anyBoolean(), anyBoolean(), anyBoolean(), any(), any(), any(), any(), + mOnMaxMenuHoverChangeListener.capture(), any()); assertTrue(decoration.isMaximizeMenuActive()); } @@ -1011,8 +1012,8 @@ public class DesktopModeWindowDecorationTests extends ShellTestCase { new FakeMaximizeMenuFactory(menu)); decoration.setAppHeaderMaximizeButtonHovered(false); createMaximizeMenu(decoration); - verify(menu).show(anyBoolean(), anyInt(), anyBoolean(), anyBoolean(), any(), any(), any(), - any(), mOnMaxMenuHoverChangeListener.capture(), any()); + verify(menu).show(anyBoolean(), anyBoolean(), anyBoolean(), any(), any(), any(), any(), + mOnMaxMenuHoverChangeListener.capture(), any()); mOnMaxMenuHoverChangeListener.getValue().invoke(false); @@ -1050,8 +1051,8 @@ public class DesktopModeWindowDecorationTests extends ShellTestCase { final DesktopModeWindowDecoration decoration = createWindowDecoration(taskInfo, new FakeMaximizeMenuFactory(menu)); createMaximizeMenu(decoration); - verify(menu).show(anyBoolean(), anyInt(), anyBoolean(), anyBoolean(), any(), any(), any(), - any(), mOnMaxMenuHoverChangeListener.capture(), any()); + verify(menu).show(anyBoolean(), anyBoolean(), anyBoolean(), any(), any(), any(), any(), + mOnMaxMenuHoverChangeListener.capture(), any()); mOnMaxMenuHoverChangeListener.getValue().invoke(true); @@ -1065,8 +1066,8 @@ public class DesktopModeWindowDecorationTests extends ShellTestCase { final DesktopModeWindowDecoration decoration = createWindowDecoration(taskInfo, new FakeMaximizeMenuFactory(menu)); createMaximizeMenu(decoration); - verify(menu).show(anyBoolean(), anyInt(), anyBoolean(), anyBoolean(), any(), any(), any(), - any(), mOnMaxMenuHoverChangeListener.capture(), any()); + verify(menu).show(anyBoolean(), anyBoolean(), anyBoolean(), any(), any(), any(), any(), + mOnMaxMenuHoverChangeListener.capture(), any()); decoration.setAppHeaderMaximizeButtonHovered(true); @@ -1086,7 +1087,6 @@ public class DesktopModeWindowDecorationTests extends ShellTestCase { verify(menu).show( anyBoolean(), - anyInt(), /* showImmersiveOption= */ eq(true), anyBoolean(), any(), @@ -1111,7 +1111,6 @@ public class DesktopModeWindowDecorationTests extends ShellTestCase { verify(menu).show( anyBoolean(), - anyInt(), /* showImmersiveOption= */ eq(false), anyBoolean(), any(), @@ -1136,7 +1135,6 @@ public class DesktopModeWindowDecorationTests extends ShellTestCase { verify(menu).show( anyBoolean(), - anyInt(), anyBoolean(), /* showSnapOptions= */ eq(true), any(), @@ -1161,7 +1159,6 @@ public class DesktopModeWindowDecorationTests extends ShellTestCase { verify(menu).show( anyBoolean(), - anyInt(), anyBoolean(), /* showSnapOptions= */ eq(false), any(), @@ -1766,7 +1763,9 @@ public class DesktopModeWindowDecorationTests extends ShellTestCase { @NonNull RootTaskDisplayAreaOrganizer rootTdaOrganizer, @NonNull DisplayController displayController, @NonNull ActivityManager.RunningTaskInfo taskInfo, - @NonNull Context decorWindowContext, @NonNull PointF menuPosition, + @NonNull Context decorWindowContext, + @NonNull Function2<? super Integer,? super Integer,? extends PointF> + positionSupplier, @NonNull Supplier<SurfaceControl.Transaction> transactionSupplier) { return mMaximizeMenu; } |