Merge "Add "New Window" option to Handle Menu." into main
diff --git a/libs/WindowManager/Shell/res/drawable/desktop_mode_ic_handle_menu_new_window.xml b/libs/WindowManager/Shell/res/drawable/desktop_mode_ic_handle_menu_new_window.xml
new file mode 100644
index 0000000..c154059
--- /dev/null
+++ b/libs/WindowManager/Shell/res/drawable/desktop_mode_ic_handle_menu_new_window.xml
@@ -0,0 +1,25 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+ ~ Copyright (C) 2024 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.
+ -->
+<vector xmlns:android="http://schemas.android.com/apk/res/android"
+ android:width="20dp"
+ android:height="20dp"
+ android:viewportWidth="20"
+ android:viewportHeight="20">
+ <path
+ android:pathData="M15 16V14H13V12.5H15V10.5H16.5V12.5H18.5V14H16.5V16H15ZM3.5 17C3.09722 17 2.74306 16.8542 2.4375 16.5625C2.14583 16.2569 2 15.9028 2 15.5V4.5C2 4.08333 2.14583 3.72917 2.4375 3.4375C2.74306 3.14583 3.09722 3 3.5 3H14.5C14.9167 3 15.2708 3.14583 15.5625 3.4375C15.8542 3.72917 16 4.08333 16 4.5V9H14.5V7H3.5V15.5H13.625V17H3.5ZM3.5 5.5H14.5V4.5H3.5V5.5ZM3.5 5.5V4.5V5.5Z"
+ android:fillColor="#1C1C14"/>
+</vector>
diff --git a/libs/WindowManager/Shell/res/layout/desktop_mode_window_decor_handle_menu.xml b/libs/WindowManager/Shell/res/layout/desktop_mode_window_decor_handle_menu.xml
index 49d9029..eea3de8 100644
--- a/libs/WindowManager/Shell/res/layout/desktop_mode_window_decor_handle_menu.xml
+++ b/libs/WindowManager/Shell/res/layout/desktop_mode_window_decor_handle_menu.xml
@@ -125,7 +125,7 @@
<LinearLayout
android:id="@+id/more_actions_pill"
android:layout_width="match_parent"
- android:layout_height="@dimen/desktop_mode_handle_menu_more_actions_pill_height"
+ android:layout_height="wrap_content"
android:layout_marginTop="@dimen/desktop_mode_handle_menu_pill_spacing_margin"
android:layout_marginStart="1dp"
android:orientation="vertical"
@@ -139,6 +139,14 @@
android:drawableStart="@drawable/desktop_mode_ic_handle_menu_screenshot"
android:drawableTint="?androidprv:attr/materialColorOnSurface"
style="@style/DesktopModeHandleMenuActionButton"/>
+
+ <Button
+ android:id="@+id/new_window_button"
+ android:contentDescription="@string/new_window_text"
+ android:text="@string/new_window_text"
+ android:drawableStart="@drawable/desktop_mode_ic_handle_menu_new_window"
+ android:drawableTint="?androidprv:attr/materialColorOnSurface"
+ style="@style/DesktopModeHandleMenuActionButton" />
</LinearLayout>
<LinearLayout
diff --git a/libs/WindowManager/Shell/res/values/dimen.xml b/libs/WindowManager/Shell/res/values/dimen.xml
index 1eb2458..e6807ac 100644
--- a/libs/WindowManager/Shell/res/values/dimen.xml
+++ b/libs/WindowManager/Shell/res/values/dimen.xml
@@ -497,7 +497,7 @@
<!-- The maximum height of the handle menu in desktop mode. Four pills (52dp each) plus 2dp
spacing between them plus 4dp top padding. -->
- <dimen name="desktop_mode_handle_menu_height">218dp</dimen>
+ <dimen name="desktop_mode_handle_menu_height">270dp</dimen>
<!-- The elevation set on the handle menu pills. -->
<dimen name="desktop_mode_handle_menu_pill_elevation">1dp</dimen>
@@ -508,8 +508,11 @@
<!-- The height of the handle menu's "Windowing" pill in desktop mode. -->
<dimen name="desktop_mode_handle_menu_windowing_pill_height">52dp</dimen>
- <!-- The height of the handle menu's "More Actions" pill in desktop mode. -->
- <dimen name="desktop_mode_handle_menu_more_actions_pill_height">52dp</dimen>
+ <!-- The maximum height of the handle menu's "New Window" button in desktop mode. -->
+ <dimen name="desktop_mode_handle_menu_new_window_height">52dp</dimen>
+
+ <!-- The maximum height of the handle menu's "Screenshot" button in desktop mode. -->
+ <dimen name="desktop_mode_handle_menu_screenshot_height">52dp</dimen>
<!-- The height of the handle menu's "Open in browser" pill in desktop mode. -->
<dimen name="desktop_mode_handle_menu_open_in_browser_pill_height">52dp</dimen>
diff --git a/libs/WindowManager/Shell/res/values/strings.xml b/libs/WindowManager/Shell/res/values/strings.xml
index 8669af3..0a8166f 100644
--- a/libs/WindowManager/Shell/res/values/strings.xml
+++ b/libs/WindowManager/Shell/res/values/strings.xml
@@ -282,6 +282,8 @@
<string name="screenshot_text">Screenshot</string>
<!-- Accessibility text for the handle menu open in browser button [CHAR LIMIT=NONE] -->
<string name="open_in_browser_text">Open in browser</string>
+ <!-- Accessibility text for the handle menu new window button [CHAR LIMIT=NONE] -->
+ <string name="new_window_text">New Window</string>
<!-- Accessibility text for the handle menu close button [CHAR LIMIT=NONE] -->
<string name="close_text">Close</string>
<!-- Accessibility text for the handle menu close menu button [CHAR LIMIT=NONE] -->
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/common/MultiInstanceHelper.kt b/libs/WindowManager/Shell/src/com/android/wm/shell/common/MultiInstanceHelper.kt
index a6be640..4cd2fd0 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/common/MultiInstanceHelper.kt
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/common/MultiInstanceHelper.kt
@@ -22,7 +22,6 @@
import android.content.pm.PackageManager
import android.os.UserHandle
import android.view.WindowManager.PROPERTY_SUPPORTS_MULTI_INSTANCE_SYSTEM_UI
-import com.android.internal.annotations.VisibleForTesting
import com.android.internal.protolog.ProtoLog
import com.android.wm.shell.R
import com.android.wm.shell.protolog.ShellProtoLogGroup.WM_SHELL
@@ -41,7 +40,6 @@
/**
* Returns whether a specific component desires to be launched in multiple instances.
*/
- @VisibleForTesting
fun supportsMultiInstanceSplit(componentName: ComponentName?): Boolean {
if (componentName == null || componentName.packageName == null) {
// TODO(b/262864589): Handle empty component case
@@ -60,7 +58,7 @@
if (!supportsMultiInstanceProperty) {
// If not checking the multi-instance properties, then return early
- return false;
+ return false
}
// Check the activity property first
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 da1af0d..9cfbde4 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
@@ -226,7 +226,8 @@
Optional<DesktopTasksController> desktopTasksController,
RootTaskDisplayAreaOrganizer rootTaskDisplayAreaOrganizer,
InteractionJankMonitor interactionJankMonitor,
- AppToWebGenericLinksParser genericLinksParser) {
+ AppToWebGenericLinksParser genericLinksParser,
+ MultiInstanceHelper multiInstanceHelper) {
if (DesktopModeStatus.canEnterDesktopMode(context)) {
return new DesktopModeWindowDecorViewModel(
context,
@@ -246,7 +247,8 @@
desktopTasksController,
rootTaskDisplayAreaOrganizer,
interactionJankMonitor,
- genericLinksParser);
+ genericLinksParser,
+ multiInstanceHelper);
}
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 7175ec4..2bb172f 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
@@ -98,6 +98,7 @@
import com.android.wm.shell.windowdecor.MoveToDesktopAnimator
import com.android.wm.shell.windowdecor.OnTaskResizeAnimationListener
import com.android.wm.shell.windowdecor.extension.isFullscreen
+import com.android.wm.shell.windowdecor.extension.isMultiWindow
import java.io.PrintWriter
import java.util.Optional
import java.util.concurrent.Executor
@@ -902,6 +903,60 @@
request.triggerTask != null
}
+ fun openNewWindow(
+ taskInfo: RunningTaskInfo
+ ) {
+ // TODO(b/337915660): Add a transition handler for these; animations
+ // need updates in some cases.
+ val newTaskWindowingMode = when {
+ taskInfo.isFreeform -> {
+ WINDOWING_MODE_FREEFORM
+ }
+ taskInfo.isFullscreen || taskInfo.isMultiWindow -> {
+ WINDOWING_MODE_MULTI_WINDOW
+ }
+ else -> {
+ error("Invalid windowing mode: ${taskInfo.windowingMode}")
+ }
+ }
+
+ val baseActivity = taskInfo.baseActivity ?: return
+ val fillIn: Intent = context.packageManager
+ .getLaunchIntentForPackage(
+ baseActivity.packageName
+ ) ?: return
+ fillIn
+ .setFlags(Intent.FLAG_ACTIVITY_NEW_TASK or Intent.FLAG_ACTIVITY_MULTIPLE_TASK)
+ val options =
+ ActivityOptions.makeBasic().apply {
+ launchWindowingMode = newTaskWindowingMode
+ isPendingIntentBackgroundActivityLaunchAllowedByPermission = true
+ pendingIntentBackgroundActivityStartMode =
+ ActivityOptions.MODE_BACKGROUND_ACTIVITY_START_ALLOWED
+ }
+ val launchIntent = PendingIntent.getActivity(
+ context,
+ /* requestCode= */ 0,
+ fillIn,
+ PendingIntent.FLAG_IMMUTABLE
+ )
+ when (newTaskWindowingMode) {
+ WINDOWING_MODE_MULTI_WINDOW -> {
+ val splitPosition = splitScreenController.determineNewInstancePosition(taskInfo)
+ splitScreenController.startIntent(
+ launchIntent, context.userId, fillIn, splitPosition,
+ options.toBundle(), null /* hideTaskToken */
+ )
+ }
+ WINDOWING_MODE_FREEFORM -> {
+ // TODO(b/336289597): This currently does not respect the desktop window limit.
+ val wct = WindowContainerTransaction()
+ wct.sendPendingIntent(launchIntent, fillIn, options.toBundle())
+ transitions.startTransition(TRANSIT_OPEN, wct, null)
+ }
+ }
+ }
+
private fun handleFreeformTaskLaunch(
task: RunningTaskInfo,
transition: IBinder
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/splitscreen/SplitScreenController.java b/libs/WindowManager/Shell/src/com/android/wm/shell/splitscreen/SplitScreenController.java
index b857556..c4af148 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/splitscreen/SplitScreenController.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/splitscreen/SplitScreenController.java
@@ -19,6 +19,7 @@
import static android.app.ActivityManager.START_SUCCESS;
import static android.app.ActivityManager.START_TASK_TO_FRONT;
import static android.app.ActivityTaskManager.INVALID_TASK_ID;
+import static android.app.WindowConfiguration.WINDOWING_MODE_FULLSCREEN;
import static android.content.Intent.FLAG_ACTIVITY_MULTIPLE_TASK;
import static android.content.Intent.FLAG_ACTIVITY_NO_USER_ACTION;
import static android.view.Display.DEFAULT_DISPLAY;
@@ -431,6 +432,20 @@
mStageCoordinator.clearSplitPairedInRecents(reason);
}
+ /**
+ * Determines which split position a new instance of a task should take.
+ * @param callingTask The task requesting a new instance.
+ * @return the split position of the new instance
+ */
+ public int determineNewInstancePosition(@NonNull ActivityManager.RunningTaskInfo callingTask) {
+ if (callingTask.getWindowingMode() == WINDOWING_MODE_FULLSCREEN
+ || getSplitPosition(callingTask.taskId) == SPLIT_POSITION_TOP_OR_LEFT) {
+ return SPLIT_POSITION_BOTTOM_OR_RIGHT;
+ } else {
+ return SPLIT_POSITION_TOP_OR_LEFT;
+ }
+ }
+
public void enterSplitScreen(int taskId, boolean leftOrTop) {
enterSplitScreen(taskId, leftOrTop, new WindowContainerTransaction());
}
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 ecd5eda..633067d 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
@@ -93,6 +93,7 @@
import com.android.wm.shell.common.DisplayController;
import com.android.wm.shell.common.DisplayInsetsController;
import com.android.wm.shell.common.DisplayLayout;
+import com.android.wm.shell.common.MultiInstanceHelper;
import com.android.wm.shell.common.ShellExecutor;
import com.android.wm.shell.common.SyncTransactionQueue;
import com.android.wm.shell.common.desktopmode.DesktopModeTransitionSource;
@@ -145,6 +146,7 @@
private final DesktopTasksController mDesktopTasksController;
private final InputManager mInputManager;
private final InteractionJankMonitor mInteractionJankMonitor;
+ private final MultiInstanceHelper mMultiInstanceHelper;
private boolean mTransitionDragActive;
private SparseArray<EventReceiver> mEventReceiversByDisplay = new SparseArray<>();
@@ -204,7 +206,8 @@
Optional<DesktopTasksController> desktopTasksController,
RootTaskDisplayAreaOrganizer rootTaskDisplayAreaOrganizer,
InteractionJankMonitor interactionJankMonitor,
- AppToWebGenericLinksParser genericLinksParser
+ AppToWebGenericLinksParser genericLinksParser,
+ MultiInstanceHelper multiInstanceHelper
) {
this(
context,
@@ -223,6 +226,7 @@
transitions,
desktopTasksController,
genericLinksParser,
+ multiInstanceHelper,
new DesktopModeWindowDecoration.Factory(),
new InputMonitorFactory(),
SurfaceControl.Transaction::new,
@@ -249,6 +253,7 @@
Transitions transitions,
Optional<DesktopTasksController> desktopTasksController,
AppToWebGenericLinksParser genericLinksParser,
+ MultiInstanceHelper multiInstanceHelper,
DesktopModeWindowDecoration.Factory desktopModeWindowDecorFactory,
InputMonitorFactory inputMonitorFactory,
Supplier<SurfaceControl.Transaction> transactionFactory,
@@ -268,6 +273,7 @@
mSyncQueue = syncQueue;
mTransitions = transitions;
mDesktopTasksController = desktopTasksController.get();
+ mMultiInstanceHelper = multiInstanceHelper;
mShellCommandHandler = shellCommandHandler;
mWindowManager = windowManager;
mDesktopModeWindowDecorFactory = desktopModeWindowDecorFactory;
@@ -536,6 +542,9 @@
decoration.onOpenInBrowserClick();
} else if (id == R.id.collapse_menu_button) {
decoration.closeHandleMenu();
+ } else if (id == R.id.new_window_button) {
+ decoration.closeHandleMenu();
+ mDesktopTasksController.openNewWindow(decoration.mTaskInfo);
} else if (id == R.id.maximize_window) {
// TODO(b/346441962): move click detection logic into the decor's
// {@link AppHeaderViewHolder}. Let it encapsulate the that and have it report
@@ -1161,7 +1170,8 @@
mMainChoreographer,
mSyncQueue,
mRootTaskDisplayAreaOrganizer,
- mGenericLinksParser);
+ mGenericLinksParser,
+ mMultiInstanceHelper);
mWindowDecorByTaskId.put(taskInfo.taskId, windowDecoration);
final DragPositioningCallback dragPositioningCallback;
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 df41d31..b888344 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
@@ -74,6 +74,7 @@
import com.android.wm.shell.apptoweb.AppToWebGenericLinksParser;
import com.android.wm.shell.common.DisplayController;
import com.android.wm.shell.common.DisplayLayout;
+import com.android.wm.shell.common.MultiInstanceHelper;
import com.android.wm.shell.common.ShellExecutor;
import com.android.wm.shell.common.SyncTransactionQueue;
import com.android.wm.shell.shared.annotations.ShellBackgroundThread;
@@ -157,6 +158,7 @@
// to cancel the close.
private final Runnable mCloseMaximizeWindowRunnable = this::closeMaximizeMenu;
private final Runnable mCapturedLinkExpiredRunnable = this::onCapturedLinkExpired;
+ private final MultiInstanceHelper mMultiInstanceHelper;
DesktopModeWindowDecoration(
Context context,
@@ -171,13 +173,15 @@
Choreographer choreographer,
SyncTransactionQueue syncQueue,
RootTaskDisplayAreaOrganizer rootTaskDisplayAreaOrganizer,
- AppToWebGenericLinksParser genericLinksParser) {
+ AppToWebGenericLinksParser genericLinksParser,
+ MultiInstanceHelper multiInstanceHelper) {
this (context, userContext, displayController, splitScreenController, taskOrganizer,
taskInfo, taskSurface, handler, bgExecutor, choreographer, syncQueue,
rootTaskDisplayAreaOrganizer, genericLinksParser, SurfaceControl.Builder::new,
SurfaceControl.Transaction::new, WindowContainerTransaction::new,
SurfaceControl::new, new SurfaceControlViewHostFactory() {},
- DefaultMaximizeMenuFactory.INSTANCE, DefaultHandleMenuFactory.INSTANCE);
+ DefaultMaximizeMenuFactory.INSTANCE, DefaultHandleMenuFactory.INSTANCE,
+ multiInstanceHelper);
}
DesktopModeWindowDecoration(
@@ -200,7 +204,8 @@
Supplier<SurfaceControl> surfaceControlSupplier,
SurfaceControlViewHostFactory surfaceControlViewHostFactory,
MaximizeMenuFactory maximizeMenuFactory,
- HandleMenuFactory handleMenuFactory) {
+ HandleMenuFactory handleMenuFactory,
+ MultiInstanceHelper multiInstanceHelper) {
super(context, userContext, displayController, taskOrganizer, taskInfo, taskSurface,
surfaceControlBuilderSupplier, surfaceControlTransactionSupplier,
windowContainerTransactionSupplier, surfaceControlSupplier,
@@ -214,6 +219,7 @@
mGenericLinksParser = genericLinksParser;
mMaximizeMenuFactory = maximizeMenuFactory;
mHandleMenuFactory = handleMenuFactory;
+ mMultiInstanceHelper = multiInstanceHelper;
}
/**
@@ -966,6 +972,9 @@
mDisplayController,
splitScreenController,
DesktopModeStatus.canEnterDesktopMode(mContext),
+ Flags.enableDesktopWindowingMultiInstanceFeatures()
+ && mMultiInstanceHelper
+ .supportsMultiInstanceSplit(mTaskInfo.baseActivity),
getBrowserLink(),
mResult.mCaptionWidth,
mResult.mCaptionHeight,
@@ -1274,7 +1283,8 @@
Choreographer choreographer,
SyncTransactionQueue syncQueue,
RootTaskDisplayAreaOrganizer rootTaskDisplayAreaOrganizer,
- AppToWebGenericLinksParser genericLinksParser) {
+ AppToWebGenericLinksParser genericLinksParser,
+ MultiInstanceHelper multiInstanceHelper) {
return new DesktopModeWindowDecoration(
context,
userContext,
@@ -1288,7 +1298,8 @@
choreographer,
syncQueue,
rootTaskDisplayAreaOrganizer,
- genericLinksParser);
+ genericLinksParser,
+ multiInstanceHelper);
}
}
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/HandleMenu.kt b/libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/HandleMenu.kt
index 7a81d4c..74a6407 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/HandleMenu.kt
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/HandleMenu.kt
@@ -70,6 +70,7 @@
private val displayController: DisplayController,
private val splitScreenController: SplitScreenController,
private val shouldShowWindowingPill: Boolean,
+ private val shouldShowNewWindowButton: Boolean,
val openInBrowserLink: Uri?,
private val captionWidth: Int,
private val captionHeight: Int,
@@ -245,13 +246,24 @@
* Set up interactive elements & height of handle menu's more actions pill
*/
private fun setupMoreActionsPill(handleMenu: View, style: MenuStyle) {
- val pill = handleMenu.requireViewById<View>(R.id.more_actions_pill).apply {
- isGone = !SHOULD_SHOW_MORE_ACTIONS_PILL
- background.colorFilter = BlendModeColorFilter(style.backgroundColor, BlendMode.MULTIPLY)
- }
- pill.requireViewById<Button>(R.id.screenshot_button).let { screenshotBtn ->
- screenshotBtn.setTextColor(style.textColor)
- screenshotBtn.compoundDrawableTintList = ColorStateList.valueOf(style.textColor)
+ val moreActionsPill = handleMenu.findViewById<View>(R.id.more_actions_pill)
+ moreActionsPill.isGone = !shouldShowNewWindowButton && !SHOULD_SHOW_SCREENSHOT_BUTTON
+ if (!moreActionsPill.isGone) {
+ handleMenu.requireViewById<Button>(R.id.screenshot_button).apply {
+ isGone = !SHOULD_SHOW_SCREENSHOT_BUTTON
+ background.colorFilter =
+ BlendModeColorFilter(style.backgroundColor, BlendMode.MULTIPLY)
+ setTextColor(style.textColor)
+ compoundDrawableTintList = ColorStateList.valueOf(style.textColor)
+ }
+ handleMenu.findViewById<Button>(R.id.new_window_button).apply {
+ isGone = !shouldShowNewWindowButton
+ background.colorFilter =
+ BlendModeColorFilter(style.backgroundColor, BlendMode.MULTIPLY)
+ setTextColor(style.textColor)
+ compoundDrawableTintList = ColorStateList.valueOf(style.textColor)
+ if (!isGone) setOnClickListener(onClickListener)
+ }
}
}
@@ -439,9 +451,17 @@
R.dimen.desktop_mode_handle_menu_windowing_pill_height)
menuHeight -= pillTopMargin
}
- if (!SHOULD_SHOW_MORE_ACTIONS_PILL) {
+ if (!SHOULD_SHOW_SCREENSHOT_BUTTON) {
menuHeight -= loadDimensionPixelSize(
- R.dimen.desktop_mode_handle_menu_more_actions_pill_height)
+ R.dimen.desktop_mode_handle_menu_screenshot_height
+ )
+ }
+ if (!shouldShowNewWindowButton) {
+ menuHeight -= loadDimensionPixelSize(
+ R.dimen.desktop_mode_handle_menu_new_window_height
+ )
+ }
+ if (!SHOULD_SHOW_SCREENSHOT_BUTTON && !shouldShowNewWindowButton) {
menuHeight -= pillTopMargin
}
if (!shouldShowBrowserPill) {
@@ -501,7 +521,7 @@
companion object {
private const val TAG = "HandleMenu"
- private const val SHOULD_SHOW_MORE_ACTIONS_PILL = false
+ private const val SHOULD_SHOW_SCREENSHOT_BUTTON = false
}
}
@@ -517,6 +537,7 @@
displayController: DisplayController,
splitScreenController: SplitScreenController,
shouldShowWindowingPill: Boolean,
+ shouldShowNewWindowButton: Boolean,
openInBrowserLink: Uri?,
captionWidth: Int,
captionHeight: Int,
@@ -536,6 +557,7 @@
displayController: DisplayController,
splitScreenController: SplitScreenController,
shouldShowWindowingPill: Boolean,
+ shouldShowNewWindowButton: Boolean,
openInBrowserLink: Uri?,
captionWidth: Int,
captionHeight: Int,
@@ -551,6 +573,7 @@
displayController,
splitScreenController,
shouldShowWindowingPill,
+ shouldShowNewWindowButton,
openInBrowserLink,
captionWidth,
captionHeight,
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 e264160..c3a0bd9 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
@@ -68,6 +68,7 @@
import com.android.wm.shell.common.DisplayController
import com.android.wm.shell.common.DisplayInsetsController
import com.android.wm.shell.common.DisplayLayout
+import com.android.wm.shell.common.MultiInstanceHelper
import com.android.wm.shell.common.ShellExecutor
import com.android.wm.shell.common.SyncTransactionQueue
import com.android.wm.shell.desktopmode.DesktopTasksController
@@ -145,6 +146,7 @@
@Mock private lateinit var mockInteractionJankMonitor: InteractionJankMonitor
@Mock private lateinit var mockGenericLinksParser: AppToWebGenericLinksParser
private val bgExecutor = TestShellExecutor()
+ @Mock private lateinit var mockMultiInstanceHelper: MultiInstanceHelper
private val transactionFactory = Supplier<SurfaceControl.Transaction> {
SurfaceControl.Transaction()
@@ -176,6 +178,7 @@
mockTransitions,
Optional.of(mockDesktopTasksController),
mockGenericLinksParser,
+ mockMultiInstanceHelper,
mockDesktopModeWindowDecorFactory,
mockInputMonitorFactory,
transactionFactory,
@@ -659,8 +662,9 @@
private fun setUpMockDecorationForTask(task: RunningTaskInfo): DesktopModeWindowDecoration {
val decoration = mock(DesktopModeWindowDecoration::class.java)
whenever(
- mockDesktopModeWindowDecorFactory.create(any(), any(), any(), any(), any(), eq(task),
- any(), any(), any(), any(), any(), any(), any())
+ mockDesktopModeWindowDecorFactory.create(
+ any(), any(), any(), any(), any(), eq(task), any(), any(), any(), any(), any(),
+ any(), any(), any())
).thenReturn(decoration)
decoration.mTaskInfo = task
whenever(decoration.isFocused).thenReturn(task.isFocused)
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 04b1eed..e60eb77 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
@@ -89,6 +89,7 @@
import com.android.wm.shell.TestShellExecutor;
import com.android.wm.shell.apptoweb.AppToWebGenericLinksParser;
import com.android.wm.shell.common.DisplayController;
+import com.android.wm.shell.common.MultiInstanceHelper;
import com.android.wm.shell.common.ShellExecutor;
import com.android.wm.shell.common.SyncTransactionQueue;
import com.android.wm.shell.shared.desktopmode.DesktopModeStatus;
@@ -174,6 +175,7 @@
private HandleMenu mMockHandleMenu;
@Mock
private HandleMenuFactory mMockHandleMenuFactory;
+ private MultiInstanceHelper mMockMultiInstanceHelper;
@Captor
private ArgumentCaptor<Function1<Boolean, Unit>> mOnMaxMenuHoverChangeListener;
@Captor
@@ -218,7 +220,8 @@
doReturn(defaultDisplay).when(mMockDisplayController).getDisplay(Display.DEFAULT_DISPLAY);
doReturn(mInsetsState).when(mMockDisplayController).getInsetsState(anyInt());
doReturn(mMockHandleMenu).when(mMockHandleMenuFactory).create(any(), anyInt(), any(), any(),
- any(), any(), any(), any(), anyBoolean(), any(), anyInt(), anyInt(), anyInt());
+ any(), any(), any(), any(), anyBoolean(), anyBoolean(), any(), anyInt(), anyInt(),
+ anyInt());
}
@After
@@ -775,7 +778,7 @@
private void verifyHandleMenuCreated(@Nullable Uri uri) {
verify(mMockHandleMenuFactory).create(any(), anyInt(), any(), any(), any(), any(), any(),
- any(), anyBoolean(), eq(uri), anyInt(), anyInt(), anyInt());
+ any(), anyBoolean(), anyBoolean(), eq(uri), anyInt(), anyInt(), anyInt());
}
private void createMaximizeMenu(DesktopModeWindowDecoration decoration, MaximizeMenu menu) {
@@ -831,7 +834,8 @@
mMockChoreographer, mMockSyncQueue, mMockRootTaskDisplayAreaOrganizer,
mMockGenericLinksParser, SurfaceControl.Builder::new, mMockTransactionSupplier,
WindowContainerTransaction::new, SurfaceControl::new,
- mMockSurfaceControlViewHostFactory, maximizeMenuFactory, mMockHandleMenuFactory);
+ mMockSurfaceControlViewHostFactory, maximizeMenuFactory, mMockHandleMenuFactory,
+ mMockMultiInstanceHelper);
windowDecor.setCaptionListeners(mMockTouchEventListener, mMockTouchEventListener,
mMockTouchEventListener, mMockTouchEventListener);
windowDecor.setExclusionRegionListener(mMockExclusionRegionListener);
diff --git a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/windowdecor/HandleMenuTest.kt b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/windowdecor/HandleMenuTest.kt
index ed43aa3..cca83dd 100644
--- a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/windowdecor/HandleMenuTest.kt
+++ b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/windowdecor/HandleMenuTest.kt
@@ -227,11 +227,11 @@
else -> error("Invalid windowing mode")
}
val handleMenu = HandleMenu(mockDesktopWindowDecoration, layoutId,
- onClickListener, onTouchListener, appIcon, appName, displayController,
- splitScreenController, shouldShowWindowingPill = true,
- null /* openInBrowserLink */, captionWidth = HANDLE_WIDTH, captionHeight = 50,
- captionX = captionX
- )
+ onClickListener, onTouchListener, appIcon, appName, displayController,
+ splitScreenController, shouldShowWindowingPill = true,
+ shouldShowNewWindowButton = true,
+ openInBrowserLink = null, captionWidth = HANDLE_WIDTH, captionHeight = 50,
+ captionX = captionX)
handleMenu.show()
return handleMenu
}