summaryrefslogtreecommitdiff
path: root/libs
diff options
context:
space:
mode:
Diffstat (limited to 'libs')
-rw-r--r--libs/WindowManager/Shell/Android.bp8
-rw-r--r--libs/WindowManager/Shell/aconfig/multitasking.aconfig10
-rw-r--r--libs/WindowManager/Shell/res/drawable/desktop_windowing_transition_background.xml6
-rw-r--r--libs/WindowManager/Shell/res/values-af/strings.xml2
-rw-r--r--libs/WindowManager/Shell/res/values-am/strings.xml2
-rw-r--r--libs/WindowManager/Shell/res/values-ar/strings.xml11
-rw-r--r--libs/WindowManager/Shell/res/values-as/strings.xml2
-rw-r--r--libs/WindowManager/Shell/res/values-az/strings.xml2
-rw-r--r--libs/WindowManager/Shell/res/values-b+sr+Latn/strings.xml2
-rw-r--r--libs/WindowManager/Shell/res/values-be/strings.xml2
-rw-r--r--libs/WindowManager/Shell/res/values-bg/strings.xml2
-rw-r--r--libs/WindowManager/Shell/res/values-bn/strings.xml11
-rw-r--r--libs/WindowManager/Shell/res/values-bs/strings.xml8
-rw-r--r--libs/WindowManager/Shell/res/values-ca/strings.xml2
-rw-r--r--libs/WindowManager/Shell/res/values-cs/strings.xml2
-rw-r--r--libs/WindowManager/Shell/res/values-da/strings.xml2
-rw-r--r--libs/WindowManager/Shell/res/values-de/strings.xml2
-rw-r--r--libs/WindowManager/Shell/res/values-el/strings.xml2
-rw-r--r--libs/WindowManager/Shell/res/values-en-rAU/strings.xml4
-rw-r--r--libs/WindowManager/Shell/res/values-en-rCA/strings.xml1
-rw-r--r--libs/WindowManager/Shell/res/values-en-rGB/strings.xml4
-rw-r--r--libs/WindowManager/Shell/res/values-en-rIN/strings.xml4
-rw-r--r--libs/WindowManager/Shell/res/values-es-rUS/strings.xml11
-rw-r--r--libs/WindowManager/Shell/res/values-es/strings.xml11
-rw-r--r--libs/WindowManager/Shell/res/values-et/strings.xml2
-rw-r--r--libs/WindowManager/Shell/res/values-eu/strings.xml11
-rw-r--r--libs/WindowManager/Shell/res/values-fa/strings.xml2
-rw-r--r--libs/WindowManager/Shell/res/values-fi/strings.xml2
-rw-r--r--libs/WindowManager/Shell/res/values-fr-rCA/strings.xml2
-rw-r--r--libs/WindowManager/Shell/res/values-fr/strings.xml2
-rw-r--r--libs/WindowManager/Shell/res/values-gl/strings.xml2
-rw-r--r--libs/WindowManager/Shell/res/values-gu/strings.xml2
-rw-r--r--libs/WindowManager/Shell/res/values-hi/strings.xml2
-rw-r--r--libs/WindowManager/Shell/res/values-hr/strings.xml2
-rw-r--r--libs/WindowManager/Shell/res/values-hu/strings.xml4
-rw-r--r--libs/WindowManager/Shell/res/values-hy/strings.xml2
-rw-r--r--libs/WindowManager/Shell/res/values-in/strings.xml2
-rw-r--r--libs/WindowManager/Shell/res/values-is/strings.xml2
-rw-r--r--libs/WindowManager/Shell/res/values-it/strings.xml2
-rw-r--r--libs/WindowManager/Shell/res/values-iw/strings.xml11
-rw-r--r--libs/WindowManager/Shell/res/values-ja/strings.xml2
-rw-r--r--libs/WindowManager/Shell/res/values-ka/strings.xml2
-rw-r--r--libs/WindowManager/Shell/res/values-kk/strings.xml8
-rw-r--r--libs/WindowManager/Shell/res/values-km/strings.xml2
-rw-r--r--libs/WindowManager/Shell/res/values-kn/strings.xml2
-rw-r--r--libs/WindowManager/Shell/res/values-ko/strings.xml2
-rw-r--r--libs/WindowManager/Shell/res/values-ky/strings.xml2
-rw-r--r--libs/WindowManager/Shell/res/values-lo/strings.xml2
-rw-r--r--libs/WindowManager/Shell/res/values-lt/strings.xml2
-rw-r--r--libs/WindowManager/Shell/res/values-lv/strings.xml2
-rw-r--r--libs/WindowManager/Shell/res/values-mk/strings.xml2
-rw-r--r--libs/WindowManager/Shell/res/values-ml/strings.xml2
-rw-r--r--libs/WindowManager/Shell/res/values-mn/strings.xml2
-rw-r--r--libs/WindowManager/Shell/res/values-mr/strings.xml2
-rw-r--r--libs/WindowManager/Shell/res/values-ms/strings.xml2
-rw-r--r--libs/WindowManager/Shell/res/values-my/strings.xml2
-rw-r--r--libs/WindowManager/Shell/res/values-nb/strings.xml2
-rw-r--r--libs/WindowManager/Shell/res/values-ne/strings.xml2
-rw-r--r--libs/WindowManager/Shell/res/values-nl/strings.xml2
-rw-r--r--libs/WindowManager/Shell/res/values-or/strings.xml11
-rw-r--r--libs/WindowManager/Shell/res/values-pa/strings.xml2
-rw-r--r--libs/WindowManager/Shell/res/values-pl/strings.xml11
-rw-r--r--libs/WindowManager/Shell/res/values-pt-rBR/strings.xml11
-rw-r--r--libs/WindowManager/Shell/res/values-pt-rPT/strings.xml2
-rw-r--r--libs/WindowManager/Shell/res/values-pt/strings.xml11
-rw-r--r--libs/WindowManager/Shell/res/values-ro/strings.xml2
-rw-r--r--libs/WindowManager/Shell/res/values-ru/strings.xml2
-rw-r--r--libs/WindowManager/Shell/res/values-si/strings.xml2
-rw-r--r--libs/WindowManager/Shell/res/values-sk/strings.xml2
-rw-r--r--libs/WindowManager/Shell/res/values-sl/strings.xml2
-rw-r--r--libs/WindowManager/Shell/res/values-sq/strings.xml2
-rw-r--r--libs/WindowManager/Shell/res/values-sr/strings.xml2
-rw-r--r--libs/WindowManager/Shell/res/values-sv/strings.xml2
-rw-r--r--libs/WindowManager/Shell/res/values-sw/strings.xml2
-rw-r--r--libs/WindowManager/Shell/res/values-ta/strings.xml2
-rw-r--r--libs/WindowManager/Shell/res/values-te/strings.xml2
-rw-r--r--libs/WindowManager/Shell/res/values-th/strings.xml11
-rw-r--r--libs/WindowManager/Shell/res/values-tl/strings.xml2
-rw-r--r--libs/WindowManager/Shell/res/values-tr/strings.xml2
-rw-r--r--libs/WindowManager/Shell/res/values-uk/strings.xml11
-rw-r--r--libs/WindowManager/Shell/res/values-ur/strings.xml2
-rw-r--r--libs/WindowManager/Shell/res/values-uz/strings.xml2
-rw-r--r--libs/WindowManager/Shell/res/values-vi/strings.xml4
-rw-r--r--libs/WindowManager/Shell/res/values-zh-rCN/strings.xml11
-rw-r--r--libs/WindowManager/Shell/res/values-zh-rHK/strings.xml8
-rw-r--r--libs/WindowManager/Shell/res/values-zh-rTW/strings.xml4
-rw-r--r--libs/WindowManager/Shell/res/values-zu/strings.xml2
-rw-r--r--libs/WindowManager/Shell/res/values/colors.xml2
-rw-r--r--libs/WindowManager/Shell/res/values/dimen.xml2
-rw-r--r--libs/WindowManager/Shell/res/values/styles.xml1
-rw-r--r--libs/WindowManager/Shell/shared/res/values/dimen.xml4
-rw-r--r--libs/WindowManager/Shell/shared/src/com/android/wm/shell/shared/IHomeTransitionListener.aidl6
-rw-r--r--libs/WindowManager/Shell/shared/src/com/android/wm/shell/shared/bubbles/ContextUtils.kt (renamed from libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/ContextUtils.kt)2
-rw-r--r--libs/WindowManager/Shell/shared/src/com/android/wm/shell/shared/bubbles/DropTargetView.kt6
-rw-r--r--libs/WindowManager/Shell/shared/src/com/android/wm/shell/shared/desktopmode/DesktopModeStatus.java2
-rw-r--r--libs/WindowManager/Shell/src/com/android/wm/shell/animation/SizeChangeAnimation.java55
-rw-r--r--libs/WindowManager/Shell/src/com/android/wm/shell/back/BackAnimationBackground.java14
-rw-r--r--libs/WindowManager/Shell/src/com/android/wm/shell/back/BackAnimationController.java27
-rw-r--r--libs/WindowManager/Shell/src/com/android/wm/shell/back/CrossActivityBackAnimation.kt19
-rw-r--r--libs/WindowManager/Shell/src/com/android/wm/shell/back/CrossTaskBackAnimation.java3
-rw-r--r--libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/BubbleController.java30
-rw-r--r--libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/BubbleExpandedView.java3
-rw-r--r--libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/BubbleStackView.java4
-rw-r--r--libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/BubbleTaskUnfoldTransitionMerger.kt33
-rw-r--r--libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/bar/BubbleBarAnimationHelper.java12
-rw-r--r--libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/bar/BubbleBarExpandedViewDragController.kt10
-rw-r--r--libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/bar/BubbleBarLayerView.java1
-rw-r--r--libs/WindowManager/Shell/src/com/android/wm/shell/common/DisplayController.java33
-rw-r--r--libs/WindowManager/Shell/src/com/android/wm/shell/common/split/DividerRoundedCorner.java28
-rw-r--r--libs/WindowManager/Shell/src/com/android/wm/shell/dagger/WMShellBaseModule.java14
-rw-r--r--libs/WindowManager/Shell/src/com/android/wm/shell/dagger/WMShellModule.java38
-rw-r--r--libs/WindowManager/Shell/src/com/android/wm/shell/dagger/pip/Pip2Module.java23
-rw-r--r--libs/WindowManager/Shell/src/com/android/wm/shell/desktopmode/DesktopDisplayEventHandler.kt9
-rw-r--r--libs/WindowManager/Shell/src/com/android/wm/shell/desktopmode/DesktopDisplayModeController.kt35
-rw-r--r--libs/WindowManager/Shell/src/com/android/wm/shell/desktopmode/DesktopModeUtils.kt11
-rw-r--r--libs/WindowManager/Shell/src/com/android/wm/shell/desktopmode/DesktopModeVisualIndicator.java76
-rw-r--r--libs/WindowManager/Shell/src/com/android/wm/shell/desktopmode/DesktopPipTransitionController.kt115
-rw-r--r--libs/WindowManager/Shell/src/com/android/wm/shell/desktopmode/DesktopPipTransitionObserver.kt81
-rw-r--r--libs/WindowManager/Shell/src/com/android/wm/shell/desktopmode/DesktopRepository.kt3
-rw-r--r--libs/WindowManager/Shell/src/com/android/wm/shell/desktopmode/DesktopTasksController.kt97
-rw-r--r--libs/WindowManager/Shell/src/com/android/wm/shell/desktopmode/DesktopTasksTransitionObserver.kt3
-rw-r--r--libs/WindowManager/Shell/src/com/android/wm/shell/desktopmode/DesktopUserRepositories.kt21
-rw-r--r--libs/WindowManager/Shell/src/com/android/wm/shell/desktopmode/multidesks/DesksOrganizer.kt3
-rw-r--r--libs/WindowManager/Shell/src/com/android/wm/shell/desktopmode/multidesks/RootTaskDesksOrganizer.kt11
-rw-r--r--libs/WindowManager/Shell/src/com/android/wm/shell/draganddrop/DragLayout.java3
-rw-r--r--libs/WindowManager/Shell/src/com/android/wm/shell/freeform/FreeformTaskTransitionObserver.java6
-rw-r--r--libs/WindowManager/Shell/src/com/android/wm/shell/pip2/phone/PipTransition.java62
-rw-r--r--libs/WindowManager/Shell/src/com/android/wm/shell/splitscreen/StageCoordinator.java4
-rw-r--r--libs/WindowManager/Shell/src/com/android/wm/shell/taskview/TaskViewTransitions.java42
-rw-r--r--libs/WindowManager/Shell/src/com/android/wm/shell/transition/DefaultSurfaceAnimator.java22
-rw-r--r--libs/WindowManager/Shell/src/com/android/wm/shell/transition/DefaultTransitionHandler.java57
-rw-r--r--libs/WindowManager/Shell/src/com/android/wm/shell/transition/HomeTransitionObserver.java22
-rw-r--r--libs/WindowManager/Shell/src/com/android/wm/shell/transition/ScreenRotationAnimation.java6
-rw-r--r--libs/WindowManager/Shell/src/com/android/wm/shell/transition/TransitionAnimationHelper.java81
-rw-r--r--libs/WindowManager/Shell/src/com/android/wm/shell/transition/Transitions.java15
-rw-r--r--libs/WindowManager/Shell/src/com/android/wm/shell/unfold/UnfoldTransitionHandler.java25
-rw-r--r--libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/CaptionWindowDecorViewModel.java4
-rw-r--r--libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/CarWindowDecorViewModel.java4
-rw-r--r--libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/CarWindowDecoration.java19
-rw-r--r--libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/DesktopModeWindowDecorViewModel.java28
-rw-r--r--libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/DesktopModeWindowDecoration.java48
-rw-r--r--libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/DragResizeInputListener.java4
-rw-r--r--libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/HandleMenu.kt29
-rw-r--r--libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/WindowDecorViewModel.java5
-rw-r--r--libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/common/ButtonBackgroundDrawableUtils.kt12
-rw-r--r--libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/common/ThemeUtils.kt3
-rw-r--r--libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/tiling/DesktopTilingDividerWindowManager.kt5
-rw-r--r--libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/tiling/DesktopTilingWindowDecoration.kt1
-rw-r--r--libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/tiling/TilingDividerView.kt41
-rw-r--r--libs/WindowManager/Shell/tests/e2e/splitscreen/flicker-legacy/src/com/android/wm/shell/flicker/splitscreen/benchmark/SwitchAppByDoubleTapDividerBenchmark.kt2
-rw-r--r--libs/WindowManager/Shell/tests/e2e/splitscreen/scenarios/src/com/android/wm/shell/scenarios/SwitchAppByDoubleTapDivider.kt2
-rw-r--r--libs/WindowManager/Shell/tests/e2e/utils/src/com/android/wm/shell/SimulatedConnectedDisplayTestRule.kt30
-rw-r--r--libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/utils/SplitScreenUtils.kt40
-rw-r--r--libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/common/DisplayControllerTests.java21
-rw-r--r--libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/desktopmode/DesktopDisplayEventHandlerTest.kt8
-rw-r--r--libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/desktopmode/DesktopDisplayModeControllerTest.kt442
-rw-r--r--libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/desktopmode/DesktopModeVisualIndicatorTest.kt60
-rw-r--r--libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/desktopmode/DesktopPipTransitionControllerTest.kt165
-rw-r--r--libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/desktopmode/DesktopPipTransitionObserverTest.kt98
-rw-r--r--libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/desktopmode/DesktopRepositoryTest.kt24
-rw-r--r--libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/desktopmode/DesktopTasksControllerTest.kt156
-rw-r--r--libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/desktopmode/DesktopTasksTransitionObserverTest.kt3
-rw-r--r--libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/desktopmode/multidesks/RootTaskDesksOrganizerTest.kt37
-rw-r--r--libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/splitscreen/StageCoordinatorTests.java10
-rw-r--r--libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/taskview/TaskViewTransitionsTest.java71
-rw-r--r--libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/transition/DefaultTransitionHandlerTest.java8
-rw-r--r--libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/transition/HomeTransitionObserverTest.java11
-rw-r--r--libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/transition/ShellTransitionTests.java26
-rw-r--r--libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/unfold/UnfoldTransitionHandlerTest.java4
-rw-r--r--libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/windowdecor/DesktopModeWindowDecorViewModelAppHandleOnlyTest.kt5
-rw-r--r--libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/windowdecor/DesktopModeWindowDecorViewModelTests.kt7
-rw-r--r--libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/windowdecor/DesktopModeWindowDecorViewModelTestsBase.kt5
-rw-r--r--libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/windowdecor/DesktopModeWindowDecorationTests.java121
-rw-r--r--libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/windowdecor/DragResizeInputListenerTest.kt22
-rw-r--r--libs/androidfw/AssetManager2.cpp16
-rw-r--r--libs/androidfw/LocaleDataLookup.cpp2
-rw-r--r--libs/androidfw/include/androidfw/AssetManager2.h11
-rw-r--r--libs/androidfw/tests/AssetManager2_test.cpp15
-rw-r--r--libs/androidfw/tests/data/flagged/AndroidManifest.xml20
-rw-r--r--libs/androidfw/tests/data/flagged/R.h35
-rwxr-xr-xlibs/androidfw/tests/data/flagged/build28
-rw-r--r--libs/androidfw/tests/data/flagged/flagged.apkbin0 -> 1837 bytes
-rw-r--r--libs/androidfw/tests/data/flagged/res/xml/flagged.xml18
-rw-r--r--libs/hwui/hwui/Bitmap.cpp9
-rw-r--r--libs/hwui/jni/GIFMovie.cpp10
-rw-r--r--libs/hwui/renderthread/VulkanManager.cpp13
-rw-r--r--libs/hwui/renderthread/VulkanManager.h8
187 files changed, 2118 insertions, 1168 deletions
diff --git a/libs/WindowManager/Shell/Android.bp b/libs/WindowManager/Shell/Android.bp
index bcb6c4f555f7..033c934056d6 100644
--- a/libs/WindowManager/Shell/Android.bp
+++ b/libs/WindowManager/Shell/Android.bp
@@ -26,9 +26,11 @@ package {
java_library {
name: "wm_shell_protolog-groups",
srcs: [
- ":protolog-common-src",
"src/com/android/wm/shell/protolog/ShellProtoLogGroup.java",
],
+ static_libs: [
+ "protolog-common-lib",
+ ],
}
filegroup {
@@ -159,12 +161,12 @@ java_library {
android_library {
name: "WindowManager-Shell",
srcs: [
- ":wm_shell_protolog_src",
// TODO(b/168581922) protologtool do not support kotlin(*.kt)
- "src/com/android/wm/shell/EventLogTags.logtags",
":wm_shell-aidls",
":wm_shell-shared-aidls",
":wm_shell-sources-kt",
+ ":wm_shell_protolog_src",
+ "src/com/android/wm/shell/EventLogTags.logtags",
],
resource_dirs: [
"res",
diff --git a/libs/WindowManager/Shell/aconfig/multitasking.aconfig b/libs/WindowManager/Shell/aconfig/multitasking.aconfig
index 19455a313a9d..e873dc7c94e8 100644
--- a/libs/WindowManager/Shell/aconfig/multitasking.aconfig
+++ b/libs/WindowManager/Shell/aconfig/multitasking.aconfig
@@ -179,6 +179,16 @@ flag {
}
flag {
+ name: "fix_missing_user_change_callbacks"
+ namespace: "multitasking"
+ description: "Fix a race condition that could make Shell miss a user change callback."
+ bug: "404251029"
+ metadata {
+ purpose: PURPOSE_BUGFIX
+ }
+}
+
+flag {
name: "enable_bubble_bar_on_phones"
namespace: "multitasking"
description: "Try out bubble bar on phones"
diff --git a/libs/WindowManager/Shell/res/drawable/desktop_windowing_transition_background.xml b/libs/WindowManager/Shell/res/drawable/desktop_windowing_transition_background.xml
index dd1a1b1dca13..75ec2ab9f6f9 100644
--- a/libs/WindowManager/Shell/res/drawable/desktop_windowing_transition_background.xml
+++ b/libs/WindowManager/Shell/res/drawable/desktop_windowing_transition_background.xml
@@ -18,15 +18,15 @@
xmlns:androidprv="http://schemas.android.com/apk/prv/res/android">
<item android:id="@+id/indicator_solid">
<shape android:shape="rectangle">
- <solid android:color="@androidprv:color/materialColorPrimaryContainer" />
+ <solid android:color="@androidprv:color/materialColorPrimaryFixed" />
<corners android:radius="28dp" />
</shape>
</item>
<item android:id="@+id/indicator_stroke">
<shape android:shape="rectangle">
<corners android:radius="28dp" />
- <stroke android:width="1dp"
- android:color="@androidprv:color/materialColorPrimaryContainer"/>
+ <stroke android:width="2dp"
+ android:color="@androidprv:color/materialColorPrimaryFixed"/>
</shape>
</item>
</layer-list>
diff --git a/libs/WindowManager/Shell/res/values-af/strings.xml b/libs/WindowManager/Shell/res/values-af/strings.xml
index 05c4c56a5c81..f42fea6a0d17 100644
--- a/libs/WindowManager/Shell/res/values-af/strings.xml
+++ b/libs/WindowManager/Shell/res/values-af/strings.xml
@@ -132,6 +132,8 @@
<string name="new_window_text" msgid="6318648868380652280">"Nuwe venster"</string>
<string name="manage_windows_text" msgid="5567366688493093920">"Bestuur vensters"</string>
<string name="change_aspect_ratio_text" msgid="9104456064548212806">"Verander aspekverhouding"</string>
+ <!-- no translation found for handle_menu_restart_text (3907767216238298098) -->
+ <skip />
<string name="close_text" msgid="4986518933445178928">"Maak toe"</string>
<string name="collapse_menu_text" msgid="7515008122450342029">"Maak kieslys toe"</string>
<string name="desktop_mode_app_header_chip_text" msgid="7617377295944971651">"<xliff:g id="APP_NAME">%1$s</xliff:g> (werkskermvensters)"</string>
diff --git a/libs/WindowManager/Shell/res/values-am/strings.xml b/libs/WindowManager/Shell/res/values-am/strings.xml
index 450419dcc40d..c65bb3822ec2 100644
--- a/libs/WindowManager/Shell/res/values-am/strings.xml
+++ b/libs/WindowManager/Shell/res/values-am/strings.xml
@@ -132,6 +132,8 @@
<string name="new_window_text" msgid="6318648868380652280">"አዲስ መስኮት"</string>
<string name="manage_windows_text" msgid="5567366688493093920">"መስኮቶችን አስተዳድር"</string>
<string name="change_aspect_ratio_text" msgid="9104456064548212806">"ምጥጥነ ገፅታ ለውጥ"</string>
+ <!-- no translation found for handle_menu_restart_text (3907767216238298098) -->
+ <skip />
<string name="close_text" msgid="4986518933445178928">"ዝጋ"</string>
<string name="collapse_menu_text" msgid="7515008122450342029">"ምናሌ ዝጋ"</string>
<string name="desktop_mode_app_header_chip_text" msgid="7617377295944971651">"<xliff:g id="APP_NAME">%1$s</xliff:g> (ዴስክቶፕ መስኮት)"</string>
diff --git a/libs/WindowManager/Shell/res/values-ar/strings.xml b/libs/WindowManager/Shell/res/values-ar/strings.xml
index 70a23b73b6f5..d06d99203245 100644
--- a/libs/WindowManager/Shell/res/values-ar/strings.xml
+++ b/libs/WindowManager/Shell/res/values-ar/strings.xml
@@ -100,8 +100,7 @@
<string name="camera_compat_treatment_applied_button_description" msgid="2944157113330703897">"ألم يتم حل المشكلة؟\nانقر للعودة"</string>
<string name="camera_compat_dismiss_button_description" msgid="2795364433503817511">"أليس هناك مشاكل في الكاميرا؟ انقر للإغلاق."</string>
<string name="windowing_app_handle_education_tooltip" msgid="2929643449849791854">"يمكن العثور على قائمة التطبيقات هنا"</string>
- <!-- no translation found for windowing_desktop_mode_image_button_education_tooltip (7171915734817051666) -->
- <skip />
+ <string name="windowing_desktop_mode_image_button_education_tooltip" msgid="7171915734817051666">"يمكنك الدخول إلى وضع عرض المحتوى في النافذة الحالية على سطح المكتب لفتح عدة تطبيقات معًا"</string>
<string name="windowing_desktop_mode_exit_education_tooltip" msgid="5225660258192054132">"يمكنك الرجوع إلى وضع ملء الشاشة في أي وقت من قائمة التطبيقات"</string>
<string name="letterbox_education_dialog_title" msgid="7739895354143295358">"استخدام تطبيقات متعدّدة في وقت واحد"</string>
<string name="letterbox_education_split_screen_text" msgid="449233070804658627">"اسحب تطبيقًا آخر لاستخدام وضع تقسيم الشاشة."</string>
@@ -122,8 +121,7 @@
<string name="handle_text" msgid="4419667835599523257">"مقبض التطبيق"</string>
<string name="app_icon_text" msgid="2823268023931811747">"رمز التطبيق"</string>
<string name="fullscreen_text" msgid="1162316685217676079">"ملء الشاشة"</string>
- <!-- no translation found for desktop_text (9058641752519570266) -->
- <skip />
+ <string name="desktop_text" msgid="9058641752519570266">"عرض المحتوى في النافذة الحالية على سطح المكتب"</string>
<string name="split_screen_text" msgid="1396336058129570886">"تقسيم الشاشة"</string>
<string name="more_button_text" msgid="3655388105592893530">"المزيد"</string>
<string name="float_button_text" msgid="9221657008391364581">"نافذة عائمة"</string>
@@ -134,10 +132,11 @@
<string name="new_window_text" msgid="6318648868380652280">"نافذة جديدة"</string>
<string name="manage_windows_text" msgid="5567366688493093920">"إدارة النوافذ"</string>
<string name="change_aspect_ratio_text" msgid="9104456064548212806">"تغيير نسبة العرض إلى الارتفاع"</string>
+ <!-- no translation found for handle_menu_restart_text (3907767216238298098) -->
+ <skip />
<string name="close_text" msgid="4986518933445178928">"إغلاق"</string>
<string name="collapse_menu_text" msgid="7515008122450342029">"إغلاق القائمة"</string>
- <!-- no translation found for desktop_mode_app_header_chip_text (7617377295944971651) -->
- <skip />
+ <string name="desktop_mode_app_header_chip_text" msgid="7617377295944971651">"‫<xliff:g id="APP_NAME">%1$s</xliff:g> (عرض المحتوى في النافذة الحالية على سطح المكتب)"</string>
<string name="desktop_mode_maximize_menu_maximize_text" msgid="3275717276171114411">"تكبير الشاشة إلى أقصى حدّ"</string>
<string name="desktop_mode_maximize_menu_snap_text" msgid="5673738963174074006">"تغيير الحجم"</string>
<string name="desktop_mode_non_resizable_snap_text" msgid="3771776422751387878">"لا يمكن نقل التطبيق إلى هنا"</string>
diff --git a/libs/WindowManager/Shell/res/values-as/strings.xml b/libs/WindowManager/Shell/res/values-as/strings.xml
index b1826db57a2c..1d1a048675ac 100644
--- a/libs/WindowManager/Shell/res/values-as/strings.xml
+++ b/libs/WindowManager/Shell/res/values-as/strings.xml
@@ -132,6 +132,8 @@
<string name="new_window_text" msgid="6318648868380652280">"নতুন ৱিণ্ড’"</string>
<string name="manage_windows_text" msgid="5567366688493093920">"ৱিণ্ড’ পৰিচালনা কৰক"</string>
<string name="change_aspect_ratio_text" msgid="9104456064548212806">"আকাৰৰ অনুপাত সলনি কৰক"</string>
+ <!-- no translation found for handle_menu_restart_text (3907767216238298098) -->
+ <skip />
<string name="close_text" msgid="4986518933445178928">"বন্ধ কৰক"</string>
<string name="collapse_menu_text" msgid="7515008122450342029">"মেনু বন্ধ কৰক"</string>
<string name="desktop_mode_app_header_chip_text" msgid="7617377295944971651">"<xliff:g id="APP_NAME">%1$s</xliff:g> (ডেস্কটপ ৱিণ্ড’ৱিং)"</string>
diff --git a/libs/WindowManager/Shell/res/values-az/strings.xml b/libs/WindowManager/Shell/res/values-az/strings.xml
index c5493b573d0f..2770ede1a85a 100644
--- a/libs/WindowManager/Shell/res/values-az/strings.xml
+++ b/libs/WindowManager/Shell/res/values-az/strings.xml
@@ -132,6 +132,8 @@
<string name="new_window_text" msgid="6318648868380652280">"Yeni pəncərə"</string>
<string name="manage_windows_text" msgid="5567366688493093920">"Pəncərələri idarə edin"</string>
<string name="change_aspect_ratio_text" msgid="9104456064548212806">"Tərəflər nisbətini dəyişin"</string>
+ <!-- no translation found for handle_menu_restart_text (3907767216238298098) -->
+ <skip />
<string name="close_text" msgid="4986518933445178928">"Bağlayın"</string>
<string name="collapse_menu_text" msgid="7515008122450342029">"Menyunu bağlayın"</string>
<string name="desktop_mode_app_header_chip_text" msgid="7617377295944971651">"<xliff:g id="APP_NAME">%1$s</xliff:g> (Masaüstü pəncərə rejimi)"</string>
diff --git a/libs/WindowManager/Shell/res/values-b+sr+Latn/strings.xml b/libs/WindowManager/Shell/res/values-b+sr+Latn/strings.xml
index 307c47ab48eb..615b558a23a9 100644
--- a/libs/WindowManager/Shell/res/values-b+sr+Latn/strings.xml
+++ b/libs/WindowManager/Shell/res/values-b+sr+Latn/strings.xml
@@ -132,6 +132,8 @@
<string name="new_window_text" msgid="6318648868380652280">"Novi prozor"</string>
<string name="manage_windows_text" msgid="5567366688493093920">"Upravljajte prozorima"</string>
<string name="change_aspect_ratio_text" msgid="9104456064548212806">"Promeni razmeru"</string>
+ <!-- no translation found for handle_menu_restart_text (3907767216238298098) -->
+ <skip />
<string name="close_text" msgid="4986518933445178928">"Zatvorite"</string>
<string name="collapse_menu_text" msgid="7515008122450342029">"Zatvorite meni"</string>
<string name="desktop_mode_app_header_chip_text" msgid="7617377295944971651">"<xliff:g id="APP_NAME">%1$s</xliff:g> (prozorski prikaz za računare)"</string>
diff --git a/libs/WindowManager/Shell/res/values-be/strings.xml b/libs/WindowManager/Shell/res/values-be/strings.xml
index c53e37c67cfc..d83ed575a34f 100644
--- a/libs/WindowManager/Shell/res/values-be/strings.xml
+++ b/libs/WindowManager/Shell/res/values-be/strings.xml
@@ -132,6 +132,8 @@
<string name="new_window_text" msgid="6318648868380652280">"Новае акно"</string>
<string name="manage_windows_text" msgid="5567366688493093920">"Кіраваць вокнамі"</string>
<string name="change_aspect_ratio_text" msgid="9104456064548212806">"Змяніць суадносіны бакоў"</string>
+ <!-- no translation found for handle_menu_restart_text (3907767216238298098) -->
+ <skip />
<string name="close_text" msgid="4986518933445178928">"Закрыць"</string>
<string name="collapse_menu_text" msgid="7515008122450342029">"Закрыць меню"</string>
<string name="desktop_mode_app_header_chip_text" msgid="7617377295944971651">"<xliff:g id="APP_NAME">%1$s</xliff:g> (рэжым вокнаў працоўнага стала)"</string>
diff --git a/libs/WindowManager/Shell/res/values-bg/strings.xml b/libs/WindowManager/Shell/res/values-bg/strings.xml
index 29af2ed1c38b..9b91d3d540e9 100644
--- a/libs/WindowManager/Shell/res/values-bg/strings.xml
+++ b/libs/WindowManager/Shell/res/values-bg/strings.xml
@@ -132,6 +132,8 @@
<string name="new_window_text" msgid="6318648868380652280">"Нов прозорец"</string>
<string name="manage_windows_text" msgid="5567366688493093920">"Управление на прозорците"</string>
<string name="change_aspect_ratio_text" msgid="9104456064548212806">"Промяна на съотношението"</string>
+ <!-- no translation found for handle_menu_restart_text (3907767216238298098) -->
+ <skip />
<string name="close_text" msgid="4986518933445178928">"Затваряне"</string>
<string name="collapse_menu_text" msgid="7515008122450342029">"Затваряне на менюто"</string>
<string name="desktop_mode_app_header_chip_text" msgid="7617377295944971651">"<xliff:g id="APP_NAME">%1$s</xliff:g> (режим за настолни компютри)"</string>
diff --git a/libs/WindowManager/Shell/res/values-bn/strings.xml b/libs/WindowManager/Shell/res/values-bn/strings.xml
index d4488a220ac7..9fd156fe6dcd 100644
--- a/libs/WindowManager/Shell/res/values-bn/strings.xml
+++ b/libs/WindowManager/Shell/res/values-bn/strings.xml
@@ -100,8 +100,7 @@
<string name="camera_compat_treatment_applied_button_description" msgid="2944157113330703897">"এখনও সমাধান হয়নি?\nরিভার্ট করার জন্য ট্যাপ করুন"</string>
<string name="camera_compat_dismiss_button_description" msgid="2795364433503817511">"ক্যামেরা সংক্রান্ত সমস্যা নেই? বাতিল করতে ট্যাপ করুন।"</string>
<string name="windowing_app_handle_education_tooltip" msgid="2929643449849791854">"অ্যাপ মেনু এখানে খুঁজে পাওয়া যাবে"</string>
- <!-- no translation found for windowing_desktop_mode_image_button_education_tooltip (7171915734817051666) -->
- <skip />
+ <string name="windowing_desktop_mode_image_button_education_tooltip" msgid="7171915734817051666">"একসাথে একাধিক অ্যাপ খোলার জন্য ডেস্কটপ উইন্ডোইংয়ে এন্টার করুন"</string>
<string name="windowing_desktop_mode_exit_education_tooltip" msgid="5225660258192054132">"অ্যাপ মেনু থেকে ফুল-স্ক্রিন মোডে যেকোনও সময়ে ফিরে আসুন"</string>
<string name="letterbox_education_dialog_title" msgid="7739895354143295358">"দেখুন ও আরও অনেক কিছু করুন"</string>
<string name="letterbox_education_split_screen_text" msgid="449233070804658627">"স্প্লিট স্ক্রিনের ক্ষেত্রে অন্য কোনও অ্যাপ টেনে আনুন"</string>
@@ -122,8 +121,7 @@
<string name="handle_text" msgid="4419667835599523257">"অ্যাপের হ্যান্ডেল"</string>
<string name="app_icon_text" msgid="2823268023931811747">"অ্যাপ আইকন"</string>
<string name="fullscreen_text" msgid="1162316685217676079">"ফুলস্ক্রিন"</string>
- <!-- no translation found for desktop_text (9058641752519570266) -->
- <skip />
+ <string name="desktop_text" msgid="9058641752519570266">"ডেস্কটপ উইন্ডোইং"</string>
<string name="split_screen_text" msgid="1396336058129570886">"স্প্লিট স্ক্রিন"</string>
<string name="more_button_text" msgid="3655388105592893530">"আরও"</string>
<string name="float_button_text" msgid="9221657008391364581">"ফ্লোট"</string>
@@ -134,10 +132,11 @@
<string name="new_window_text" msgid="6318648868380652280">"নতুন উইন্ডো"</string>
<string name="manage_windows_text" msgid="5567366688493093920">"উইন্ডো ম্যানেজ করুন"</string>
<string name="change_aspect_ratio_text" msgid="9104456064548212806">"অ্যাস্পেক্ট রেশিও পরিবর্তন করুন"</string>
+ <!-- no translation found for handle_menu_restart_text (3907767216238298098) -->
+ <skip />
<string name="close_text" msgid="4986518933445178928">"বন্ধ করুন"</string>
<string name="collapse_menu_text" msgid="7515008122450342029">"\'মেনু\' বন্ধ করুন"</string>
- <!-- no translation found for desktop_mode_app_header_chip_text (7617377295944971651) -->
- <skip />
+ <string name="desktop_mode_app_header_chip_text" msgid="7617377295944971651">"<xliff:g id="APP_NAME">%1$s</xliff:g> (ডেস্কটপ উইন্ডোইং)"</string>
<string name="desktop_mode_maximize_menu_maximize_text" msgid="3275717276171114411">"স্ক্রিন বড় করুন"</string>
<string name="desktop_mode_maximize_menu_snap_text" msgid="5673738963174074006">"ছোট বড় করুন"</string>
<string name="desktop_mode_non_resizable_snap_text" msgid="3771776422751387878">"অ্যাপটি এখানে সরানো যাবে না"</string>
diff --git a/libs/WindowManager/Shell/res/values-bs/strings.xml b/libs/WindowManager/Shell/res/values-bs/strings.xml
index 537afdcc6de4..4834ad86db67 100644
--- a/libs/WindowManager/Shell/res/values-bs/strings.xml
+++ b/libs/WindowManager/Shell/res/values-bs/strings.xml
@@ -100,7 +100,7 @@
<string name="camera_compat_treatment_applied_button_description" msgid="2944157113330703897">"Nije popravljeno?\nDodirnite da vratite"</string>
<string name="camera_compat_dismiss_button_description" msgid="2795364433503817511">"Nema problema s kamerom? Dodirnite da odbacite."</string>
<string name="windowing_app_handle_education_tooltip" msgid="2929643449849791854">"Ovdje možete pronaći meni aplikacije"</string>
- <string name="windowing_desktop_mode_image_button_education_tooltip" msgid="7171915734817051666">"Otvorite prikaz u prozorima na računalu da biste otvorili više aplikacija zajedno"</string>
+ <string name="windowing_desktop_mode_image_button_education_tooltip" msgid="7171915734817051666">"Ulazak u računarski prikaz prozora radi istovremenog otvaranja više aplikacija"</string>
<string name="windowing_desktop_mode_exit_education_tooltip" msgid="5225660258192054132">"Povratak na prikaz preko cijelog ekrana bilo kada putem menija aplikacije"</string>
<string name="letterbox_education_dialog_title" msgid="7739895354143295358">"Pogledajte i učinite više"</string>
<string name="letterbox_education_split_screen_text" msgid="449233070804658627">"Prevucite još jednu aplikaciju za podijeljeni ekran"</string>
@@ -121,7 +121,7 @@
<string name="handle_text" msgid="4419667835599523257">"Ručica aplikacije"</string>
<string name="app_icon_text" msgid="2823268023931811747">"Ikona aplikacije"</string>
<string name="fullscreen_text" msgid="1162316685217676079">"Cijeli ekran"</string>
- <string name="desktop_text" msgid="9058641752519570266">"Prikaz u prozorima na računalu"</string>
+ <string name="desktop_text" msgid="9058641752519570266">"Računarski prikaz prozora"</string>
<string name="split_screen_text" msgid="1396336058129570886">"Podijeljeni ekran"</string>
<string name="more_button_text" msgid="3655388105592893530">"Više"</string>
<string name="float_button_text" msgid="9221657008391364581">"Lebdeći"</string>
@@ -132,9 +132,11 @@
<string name="new_window_text" msgid="6318648868380652280">"Novi prozor"</string>
<string name="manage_windows_text" msgid="5567366688493093920">"Upravljanje prozorima"</string>
<string name="change_aspect_ratio_text" msgid="9104456064548212806">"Promjena formata slike"</string>
+ <!-- no translation found for handle_menu_restart_text (3907767216238298098) -->
+ <skip />
<string name="close_text" msgid="4986518933445178928">"Zatvaranje"</string>
<string name="collapse_menu_text" msgid="7515008122450342029">"Zatvaranje menija"</string>
- <string name="desktop_mode_app_header_chip_text" msgid="7617377295944971651">"<xliff:g id="APP_NAME">%1$s</xliff:g> (prikaz u prozorima na računalu)"</string>
+ <string name="desktop_mode_app_header_chip_text" msgid="7617377295944971651">"<xliff:g id="APP_NAME">%1$s</xliff:g> (računarski prikaz prozora)"</string>
<string name="desktop_mode_maximize_menu_maximize_text" msgid="3275717276171114411">"Maksimiziraj ekran"</string>
<string name="desktop_mode_maximize_menu_snap_text" msgid="5673738963174074006">"Promijeni veličinu"</string>
<string name="desktop_mode_non_resizable_snap_text" msgid="3771776422751387878">"Ne možete premjestiti aplikaciju ovdje"</string>
diff --git a/libs/WindowManager/Shell/res/values-ca/strings.xml b/libs/WindowManager/Shell/res/values-ca/strings.xml
index 42b07ef3d049..662bd81fe460 100644
--- a/libs/WindowManager/Shell/res/values-ca/strings.xml
+++ b/libs/WindowManager/Shell/res/values-ca/strings.xml
@@ -132,6 +132,8 @@
<string name="new_window_text" msgid="6318648868380652280">"Finestra nova"</string>
<string name="manage_windows_text" msgid="5567366688493093920">"Gestiona les finestres"</string>
<string name="change_aspect_ratio_text" msgid="9104456064548212806">"Canvia la relació d\'aspecte"</string>
+ <!-- no translation found for handle_menu_restart_text (3907767216238298098) -->
+ <skip />
<string name="close_text" msgid="4986518933445178928">"Tanca"</string>
<string name="collapse_menu_text" msgid="7515008122450342029">"Tanca el menú"</string>
<string name="desktop_mode_app_header_chip_text" msgid="7617377295944971651">"<xliff:g id="APP_NAME">%1$s</xliff:g> (enfinestrament d\'escriptori)"</string>
diff --git a/libs/WindowManager/Shell/res/values-cs/strings.xml b/libs/WindowManager/Shell/res/values-cs/strings.xml
index 44548682cbbc..12c9e294e9c4 100644
--- a/libs/WindowManager/Shell/res/values-cs/strings.xml
+++ b/libs/WindowManager/Shell/res/values-cs/strings.xml
@@ -132,6 +132,8 @@
<string name="new_window_text" msgid="6318648868380652280">"Nové okno"</string>
<string name="manage_windows_text" msgid="5567366688493093920">"Spravovat okna"</string>
<string name="change_aspect_ratio_text" msgid="9104456064548212806">"Změnit poměr stran"</string>
+ <!-- no translation found for handle_menu_restart_text (3907767216238298098) -->
+ <skip />
<string name="close_text" msgid="4986518933445178928">"Zavřít"</string>
<string name="collapse_menu_text" msgid="7515008122450342029">"Zavřít nabídku"</string>
<string name="desktop_mode_app_header_chip_text" msgid="7617377295944971651">"<xliff:g id="APP_NAME">%1$s</xliff:g> (okna na ploše)"</string>
diff --git a/libs/WindowManager/Shell/res/values-da/strings.xml b/libs/WindowManager/Shell/res/values-da/strings.xml
index 4d14f93d7b77..5df06ea2b9f7 100644
--- a/libs/WindowManager/Shell/res/values-da/strings.xml
+++ b/libs/WindowManager/Shell/res/values-da/strings.xml
@@ -132,6 +132,8 @@
<string name="new_window_text" msgid="6318648868380652280">"Nyt vindue"</string>
<string name="manage_windows_text" msgid="5567366688493093920">"Administrer vinduer"</string>
<string name="change_aspect_ratio_text" msgid="9104456064548212806">"Skift billedformat"</string>
+ <!-- no translation found for handle_menu_restart_text (3907767216238298098) -->
+ <skip />
<string name="close_text" msgid="4986518933445178928">"Luk"</string>
<string name="collapse_menu_text" msgid="7515008122450342029">"Luk menu"</string>
<string name="desktop_mode_app_header_chip_text" msgid="7617377295944971651">"<xliff:g id="APP_NAME">%1$s</xliff:g> (vinduer på skrivebordet)"</string>
diff --git a/libs/WindowManager/Shell/res/values-de/strings.xml b/libs/WindowManager/Shell/res/values-de/strings.xml
index 82bbfc4eff29..b3444e0ac2b8 100644
--- a/libs/WindowManager/Shell/res/values-de/strings.xml
+++ b/libs/WindowManager/Shell/res/values-de/strings.xml
@@ -132,6 +132,8 @@
<string name="new_window_text" msgid="6318648868380652280">"Neues Fenster"</string>
<string name="manage_windows_text" msgid="5567366688493093920">"Fenster verwalten"</string>
<string name="change_aspect_ratio_text" msgid="9104456064548212806">"Seitenverhältnis ändern"</string>
+ <!-- no translation found for handle_menu_restart_text (3907767216238298098) -->
+ <skip />
<string name="close_text" msgid="4986518933445178928">"Schließen"</string>
<string name="collapse_menu_text" msgid="7515008122450342029">"Menü schließen"</string>
<string name="desktop_mode_app_header_chip_text" msgid="7617377295944971651">"<xliff:g id="APP_NAME">%1$s</xliff:g> (Desktop-Freiform-Fenster)"</string>
diff --git a/libs/WindowManager/Shell/res/values-el/strings.xml b/libs/WindowManager/Shell/res/values-el/strings.xml
index a8696aff1f0c..c137513b4d7c 100644
--- a/libs/WindowManager/Shell/res/values-el/strings.xml
+++ b/libs/WindowManager/Shell/res/values-el/strings.xml
@@ -132,6 +132,8 @@
<string name="new_window_text" msgid="6318648868380652280">"Νέο παράθυρο"</string>
<string name="manage_windows_text" msgid="5567366688493093920">"Διαχείριση παραθύρων"</string>
<string name="change_aspect_ratio_text" msgid="9104456064548212806">"Αλλαγή λόγου διαστάσεων"</string>
+ <!-- no translation found for handle_menu_restart_text (3907767216238298098) -->
+ <skip />
<string name="close_text" msgid="4986518933445178928">"Κλείσιμο"</string>
<string name="collapse_menu_text" msgid="7515008122450342029">"Κλείσιμο μενού"</string>
<string name="desktop_mode_app_header_chip_text" msgid="7617377295944971651">"<xliff:g id="APP_NAME">%1$s</xliff:g> (Προσαρμογή σε παράθυρο στην επιφάνεια εργασίας)"</string>
diff --git a/libs/WindowManager/Shell/res/values-en-rAU/strings.xml b/libs/WindowManager/Shell/res/values-en-rAU/strings.xml
index 61b68a2b2515..a3156bc551eb 100644
--- a/libs/WindowManager/Shell/res/values-en-rAU/strings.xml
+++ b/libs/WindowManager/Shell/res/values-en-rAU/strings.xml
@@ -132,9 +132,11 @@
<string name="new_window_text" msgid="6318648868380652280">"New window"</string>
<string name="manage_windows_text" msgid="5567366688493093920">"Manage windows"</string>
<string name="change_aspect_ratio_text" msgid="9104456064548212806">"Change aspect ratio"</string>
+ <!-- no translation found for handle_menu_restart_text (3907767216238298098) -->
+ <skip />
<string name="close_text" msgid="4986518933445178928">"Close"</string>
<string name="collapse_menu_text" msgid="7515008122450342029">"Close menu"</string>
- <string name="desktop_mode_app_header_chip_text" msgid="7617377295944971651">"<xliff:g id="APP_NAME">%1$s</xliff:g> (desktop windowing)"</string>
+ <string name="desktop_mode_app_header_chip_text" msgid="7617377295944971651">"<xliff:g id="APP_NAME">%1$s</xliff:g> (Desktop windowing)"</string>
<string name="desktop_mode_maximize_menu_maximize_text" msgid="3275717276171114411">"Maximise screen"</string>
<string name="desktop_mode_maximize_menu_snap_text" msgid="5673738963174074006">"Resize"</string>
<string name="desktop_mode_non_resizable_snap_text" msgid="3771776422751387878">"App can\'t be moved here"</string>
diff --git a/libs/WindowManager/Shell/res/values-en-rCA/strings.xml b/libs/WindowManager/Shell/res/values-en-rCA/strings.xml
index 0802f83ab837..3e2de7cd3b56 100644
--- a/libs/WindowManager/Shell/res/values-en-rCA/strings.xml
+++ b/libs/WindowManager/Shell/res/values-en-rCA/strings.xml
@@ -132,6 +132,7 @@
<string name="new_window_text" msgid="6318648868380652280">"New Window"</string>
<string name="manage_windows_text" msgid="5567366688493093920">"Manage Windows"</string>
<string name="change_aspect_ratio_text" msgid="9104456064548212806">"Change aspect ratio"</string>
+ <string name="handle_menu_restart_text" msgid="3907767216238298098">"Optimize View"</string>
<string name="close_text" msgid="4986518933445178928">"Close"</string>
<string name="collapse_menu_text" msgid="7515008122450342029">"Close Menu"</string>
<string name="desktop_mode_app_header_chip_text" msgid="7617377295944971651">"<xliff:g id="APP_NAME">%1$s</xliff:g> (Desktop windowing)"</string>
diff --git a/libs/WindowManager/Shell/res/values-en-rGB/strings.xml b/libs/WindowManager/Shell/res/values-en-rGB/strings.xml
index 61b68a2b2515..a3156bc551eb 100644
--- a/libs/WindowManager/Shell/res/values-en-rGB/strings.xml
+++ b/libs/WindowManager/Shell/res/values-en-rGB/strings.xml
@@ -132,9 +132,11 @@
<string name="new_window_text" msgid="6318648868380652280">"New window"</string>
<string name="manage_windows_text" msgid="5567366688493093920">"Manage windows"</string>
<string name="change_aspect_ratio_text" msgid="9104456064548212806">"Change aspect ratio"</string>
+ <!-- no translation found for handle_menu_restart_text (3907767216238298098) -->
+ <skip />
<string name="close_text" msgid="4986518933445178928">"Close"</string>
<string name="collapse_menu_text" msgid="7515008122450342029">"Close menu"</string>
- <string name="desktop_mode_app_header_chip_text" msgid="7617377295944971651">"<xliff:g id="APP_NAME">%1$s</xliff:g> (desktop windowing)"</string>
+ <string name="desktop_mode_app_header_chip_text" msgid="7617377295944971651">"<xliff:g id="APP_NAME">%1$s</xliff:g> (Desktop windowing)"</string>
<string name="desktop_mode_maximize_menu_maximize_text" msgid="3275717276171114411">"Maximise screen"</string>
<string name="desktop_mode_maximize_menu_snap_text" msgid="5673738963174074006">"Resize"</string>
<string name="desktop_mode_non_resizable_snap_text" msgid="3771776422751387878">"App can\'t be moved here"</string>
diff --git a/libs/WindowManager/Shell/res/values-en-rIN/strings.xml b/libs/WindowManager/Shell/res/values-en-rIN/strings.xml
index 61b68a2b2515..a3156bc551eb 100644
--- a/libs/WindowManager/Shell/res/values-en-rIN/strings.xml
+++ b/libs/WindowManager/Shell/res/values-en-rIN/strings.xml
@@ -132,9 +132,11 @@
<string name="new_window_text" msgid="6318648868380652280">"New window"</string>
<string name="manage_windows_text" msgid="5567366688493093920">"Manage windows"</string>
<string name="change_aspect_ratio_text" msgid="9104456064548212806">"Change aspect ratio"</string>
+ <!-- no translation found for handle_menu_restart_text (3907767216238298098) -->
+ <skip />
<string name="close_text" msgid="4986518933445178928">"Close"</string>
<string name="collapse_menu_text" msgid="7515008122450342029">"Close menu"</string>
- <string name="desktop_mode_app_header_chip_text" msgid="7617377295944971651">"<xliff:g id="APP_NAME">%1$s</xliff:g> (desktop windowing)"</string>
+ <string name="desktop_mode_app_header_chip_text" msgid="7617377295944971651">"<xliff:g id="APP_NAME">%1$s</xliff:g> (Desktop windowing)"</string>
<string name="desktop_mode_maximize_menu_maximize_text" msgid="3275717276171114411">"Maximise screen"</string>
<string name="desktop_mode_maximize_menu_snap_text" msgid="5673738963174074006">"Resize"</string>
<string name="desktop_mode_non_resizable_snap_text" msgid="3771776422751387878">"App can\'t be moved here"</string>
diff --git a/libs/WindowManager/Shell/res/values-es-rUS/strings.xml b/libs/WindowManager/Shell/res/values-es-rUS/strings.xml
index bb70f6e419a5..6027f7df4272 100644
--- a/libs/WindowManager/Shell/res/values-es-rUS/strings.xml
+++ b/libs/WindowManager/Shell/res/values-es-rUS/strings.xml
@@ -100,8 +100,7 @@
<string name="camera_compat_treatment_applied_button_description" msgid="2944157113330703897">"¿No se resolvió?\nPresiona para revertir los cambios"</string>
<string name="camera_compat_dismiss_button_description" msgid="2795364433503817511">"¿No tienes problemas con la cámara? Presionar para descartar."</string>
<string name="windowing_app_handle_education_tooltip" msgid="2929643449849791854">"El menú de la app se encuentra aquí"</string>
- <!-- no translation found for windowing_desktop_mode_image_button_education_tooltip (7171915734817051666) -->
- <skip />
+ <string name="windowing_desktop_mode_image_button_education_tooltip" msgid="7171915734817051666">"Entra a la renderización en ventanas de escritorio para abrir varias apps a la vez"</string>
<string name="windowing_desktop_mode_exit_education_tooltip" msgid="5225660258192054132">"Regresa a pantalla completa en cualquier momento desde el menú de la app"</string>
<string name="letterbox_education_dialog_title" msgid="7739895354143295358">"Aprovecha más"</string>
<string name="letterbox_education_split_screen_text" msgid="449233070804658627">"Arrastra otra app para el modo de pantalla dividida"</string>
@@ -122,8 +121,7 @@
<string name="handle_text" msgid="4419667835599523257">"Controlador de la app"</string>
<string name="app_icon_text" msgid="2823268023931811747">"Ícono de la app"</string>
<string name="fullscreen_text" msgid="1162316685217676079">"Pantalla completa"</string>
- <!-- no translation found for desktop_text (9058641752519570266) -->
- <skip />
+ <string name="desktop_text" msgid="9058641752519570266">"Renderización en ventanas de escritorio"</string>
<string name="split_screen_text" msgid="1396336058129570886">"Pantalla dividida"</string>
<string name="more_button_text" msgid="3655388105592893530">"Más"</string>
<string name="float_button_text" msgid="9221657008391364581">"Flotante"</string>
@@ -134,10 +132,11 @@
<string name="new_window_text" msgid="6318648868380652280">"Nueva ventana"</string>
<string name="manage_windows_text" msgid="5567366688493093920">"Administrar ventanas"</string>
<string name="change_aspect_ratio_text" msgid="9104456064548212806">"Cambiar relación de aspecto"</string>
+ <!-- no translation found for handle_menu_restart_text (3907767216238298098) -->
+ <skip />
<string name="close_text" msgid="4986518933445178928">"Cerrar"</string>
<string name="collapse_menu_text" msgid="7515008122450342029">"Cerrar menú"</string>
- <!-- no translation found for desktop_mode_app_header_chip_text (7617377295944971651) -->
- <skip />
+ <string name="desktop_mode_app_header_chip_text" msgid="7617377295944971651">"<xliff:g id="APP_NAME">%1$s</xliff:g> (renderización en ventanas de escritorio)"</string>
<string name="desktop_mode_maximize_menu_maximize_text" msgid="3275717276171114411">"Maximizar pantalla"</string>
<string name="desktop_mode_maximize_menu_snap_text" msgid="5673738963174074006">"Dividir pantalla"</string>
<string name="desktop_mode_non_resizable_snap_text" msgid="3771776422751387878">"No se puede mover la app aquí"</string>
diff --git a/libs/WindowManager/Shell/res/values-es/strings.xml b/libs/WindowManager/Shell/res/values-es/strings.xml
index a6595aa9292d..81c9e1b214c4 100644
--- a/libs/WindowManager/Shell/res/values-es/strings.xml
+++ b/libs/WindowManager/Shell/res/values-es/strings.xml
@@ -100,8 +100,7 @@
<string name="camera_compat_treatment_applied_button_description" msgid="2944157113330703897">"¿No se ha solucionado?\nToca para revertir"</string>
<string name="camera_compat_dismiss_button_description" msgid="2795364433503817511">"¿No hay problemas con la cámara? Toca para cerrar."</string>
<string name="windowing_app_handle_education_tooltip" msgid="2929643449849791854">"El menú de la aplicación se encuentra aquí"</string>
- <!-- no translation found for windowing_desktop_mode_image_button_education_tooltip (7171915734817051666) -->
- <skip />
+ <string name="windowing_desktop_mode_image_button_education_tooltip" msgid="7171915734817051666">"Entra en el escritorio basado en ventanas si quieres abrir varias aplicaciones a la vez"</string>
<string name="windowing_desktop_mode_exit_education_tooltip" msgid="5225660258192054132">"Vuelve a la pantalla completa en cualquier momento desde el menú de aplicaciones"</string>
<string name="letterbox_education_dialog_title" msgid="7739895354143295358">"Consulta más información y haz más"</string>
<string name="letterbox_education_split_screen_text" msgid="449233070804658627">"Arrastra otra aplicación para activar la pantalla dividida"</string>
@@ -122,8 +121,7 @@
<string name="handle_text" msgid="4419667835599523257">"Controlador de la aplicación"</string>
<string name="app_icon_text" msgid="2823268023931811747">"Icono de la aplicación"</string>
<string name="fullscreen_text" msgid="1162316685217676079">"Pantalla completa"</string>
- <!-- no translation found for desktop_text (9058641752519570266) -->
- <skip />
+ <string name="desktop_text" msgid="9058641752519570266">"Escritorio basado en ventanas"</string>
<string name="split_screen_text" msgid="1396336058129570886">"Pantalla dividida"</string>
<string name="more_button_text" msgid="3655388105592893530">"Más"</string>
<string name="float_button_text" msgid="9221657008391364581">"Flotante"</string>
@@ -134,10 +132,11 @@
<string name="new_window_text" msgid="6318648868380652280">"Ventana nueva"</string>
<string name="manage_windows_text" msgid="5567366688493093920">"Gestionar ventanas"</string>
<string name="change_aspect_ratio_text" msgid="9104456064548212806">"Cambiar relación de aspecto"</string>
+ <!-- no translation found for handle_menu_restart_text (3907767216238298098) -->
+ <skip />
<string name="close_text" msgid="4986518933445178928">"Cerrar"</string>
<string name="collapse_menu_text" msgid="7515008122450342029">"Cerrar menú"</string>
- <!-- no translation found for desktop_mode_app_header_chip_text (7617377295944971651) -->
- <skip />
+ <string name="desktop_mode_app_header_chip_text" msgid="7617377295944971651">"<xliff:g id="APP_NAME">%1$s</xliff:g> (escritorio basado en ventanas)"</string>
<string name="desktop_mode_maximize_menu_maximize_text" msgid="3275717276171114411">"Maximizar pantalla"</string>
<string name="desktop_mode_maximize_menu_snap_text" msgid="5673738963174074006">"Dividir pantalla"</string>
<string name="desktop_mode_non_resizable_snap_text" msgid="3771776422751387878">"La aplicación no se puede mover aquí"</string>
diff --git a/libs/WindowManager/Shell/res/values-et/strings.xml b/libs/WindowManager/Shell/res/values-et/strings.xml
index c0e4eb36b541..f43348d1f2dc 100644
--- a/libs/WindowManager/Shell/res/values-et/strings.xml
+++ b/libs/WindowManager/Shell/res/values-et/strings.xml
@@ -132,6 +132,8 @@
<string name="new_window_text" msgid="6318648868380652280">"Uus aken"</string>
<string name="manage_windows_text" msgid="5567366688493093920">"Akende haldamine"</string>
<string name="change_aspect_ratio_text" msgid="9104456064548212806">"Kuvasuhte muutmine"</string>
+ <!-- no translation found for handle_menu_restart_text (3907767216238298098) -->
+ <skip />
<string name="close_text" msgid="4986518933445178928">"Sule"</string>
<string name="collapse_menu_text" msgid="7515008122450342029">"Sule menüü"</string>
<string name="desktop_mode_app_header_chip_text" msgid="7617377295944971651">"<xliff:g id="APP_NAME">%1$s</xliff:g> (töölaua aknad)"</string>
diff --git a/libs/WindowManager/Shell/res/values-eu/strings.xml b/libs/WindowManager/Shell/res/values-eu/strings.xml
index 446839a8eb06..4ac27c2c248e 100644
--- a/libs/WindowManager/Shell/res/values-eu/strings.xml
+++ b/libs/WindowManager/Shell/res/values-eu/strings.xml
@@ -100,8 +100,7 @@
<string name="camera_compat_treatment_applied_button_description" msgid="2944157113330703897">"Ez al da konpondu?\nLeheneratzeko, sakatu hau."</string>
<string name="camera_compat_dismiss_button_description" msgid="2795364433503817511">"Ez daukazu arazorik kamerarekin? Baztertzeko, sakatu hau."</string>
<string name="windowing_app_handle_education_tooltip" msgid="2929643449849791854">"Aplikazioaren menua dago hemen"</string>
- <!-- no translation found for windowing_desktop_mode_image_button_education_tooltip (7171915734817051666) -->
- <skip />
+ <string name="windowing_desktop_mode_image_button_education_tooltip" msgid="7171915734817051666">"Sartu ordenagailuan leihoak erabiltzeko modua aplikazio bat baino gehiago batera irekitzeko"</string>
<string name="windowing_desktop_mode_exit_education_tooltip" msgid="5225660258192054132">"Pantaila osoko modura itzultzeko, erabili aplikazioaren menua"</string>
<string name="letterbox_education_dialog_title" msgid="7739895354143295358">"Ikusi eta egin gauza gehiago"</string>
<string name="letterbox_education_split_screen_text" msgid="449233070804658627">"Pantaila zatitua ikusteko, arrastatu beste aplikazio bat"</string>
@@ -122,8 +121,7 @@
<string name="handle_text" msgid="4419667835599523257">"Aplikazioaren kontrol-puntua"</string>
<string name="app_icon_text" msgid="2823268023931811747">"Aplikazioaren ikonoa"</string>
<string name="fullscreen_text" msgid="1162316685217676079">"Pantaila osoa"</string>
- <!-- no translation found for desktop_text (9058641752519570266) -->
- <skip />
+ <string name="desktop_text" msgid="9058641752519570266">"Ordenagailuan leihoak erabiltzeko modua"</string>
<string name="split_screen_text" msgid="1396336058129570886">"Pantaila zatitzea"</string>
<string name="more_button_text" msgid="3655388105592893530">"Gehiago"</string>
<string name="float_button_text" msgid="9221657008391364581">"Leiho gainerakorra"</string>
@@ -134,10 +132,11 @@
<string name="new_window_text" msgid="6318648868380652280">"Leiho berria"</string>
<string name="manage_windows_text" msgid="5567366688493093920">"Kudeatu leihoak"</string>
<string name="change_aspect_ratio_text" msgid="9104456064548212806">"Aldatu aspektu-erlazioa"</string>
+ <!-- no translation found for handle_menu_restart_text (3907767216238298098) -->
+ <skip />
<string name="close_text" msgid="4986518933445178928">"Itxi"</string>
<string name="collapse_menu_text" msgid="7515008122450342029">"Itxi menua"</string>
- <!-- no translation found for desktop_mode_app_header_chip_text (7617377295944971651) -->
- <skip />
+ <string name="desktop_mode_app_header_chip_text" msgid="7617377295944971651">"<xliff:g id="APP_NAME">%1$s</xliff:g> (ordenagailuan leihoak erabiltzeko modua)"</string>
<string name="desktop_mode_maximize_menu_maximize_text" msgid="3275717276171114411">"Handitu pantaila"</string>
<string name="desktop_mode_maximize_menu_snap_text" msgid="5673738963174074006">"Aldatu tamaina"</string>
<string name="desktop_mode_non_resizable_snap_text" msgid="3771776422751387878">"Aplikazioa ezin da hona ekarri"</string>
diff --git a/libs/WindowManager/Shell/res/values-fa/strings.xml b/libs/WindowManager/Shell/res/values-fa/strings.xml
index 4879965d1ae7..93a9438ba045 100644
--- a/libs/WindowManager/Shell/res/values-fa/strings.xml
+++ b/libs/WindowManager/Shell/res/values-fa/strings.xml
@@ -132,6 +132,8 @@
<string name="new_window_text" msgid="6318648868380652280">"پنجره جدید"</string>
<string name="manage_windows_text" msgid="5567366688493093920">"مدیریت کردن پنجره‌ها"</string>
<string name="change_aspect_ratio_text" msgid="9104456064548212806">"تغییر نسبت ابعادی"</string>
+ <!-- no translation found for handle_menu_restart_text (3907767216238298098) -->
+ <skip />
<string name="close_text" msgid="4986518933445178928">"بستن"</string>
<string name="collapse_menu_text" msgid="7515008122450342029">"بستن منو"</string>
<string name="desktop_mode_app_header_chip_text" msgid="7617377295944971651">"<xliff:g id="APP_NAME">%1$s</xliff:g> (پردازش پنجره‌ای رایانه)"</string>
diff --git a/libs/WindowManager/Shell/res/values-fi/strings.xml b/libs/WindowManager/Shell/res/values-fi/strings.xml
index 8fd6b1bacbbe..7c9e6e6c5229 100644
--- a/libs/WindowManager/Shell/res/values-fi/strings.xml
+++ b/libs/WindowManager/Shell/res/values-fi/strings.xml
@@ -132,6 +132,8 @@
<string name="new_window_text" msgid="6318648868380652280">"Uusi ikkuna"</string>
<string name="manage_windows_text" msgid="5567366688493093920">"Hallinnoi ikkunoita"</string>
<string name="change_aspect_ratio_text" msgid="9104456064548212806">"Vaihda kuvasuhdetta"</string>
+ <!-- no translation found for handle_menu_restart_text (3907767216238298098) -->
+ <skip />
<string name="close_text" msgid="4986518933445178928">"Sulje"</string>
<string name="collapse_menu_text" msgid="7515008122450342029">"Sulje valikko"</string>
<string name="desktop_mode_app_header_chip_text" msgid="7617377295944971651">"<xliff:g id="APP_NAME">%1$s</xliff:g> (työpöydän ikkunointi)"</string>
diff --git a/libs/WindowManager/Shell/res/values-fr-rCA/strings.xml b/libs/WindowManager/Shell/res/values-fr-rCA/strings.xml
index b729ececfccd..c78b3130cdac 100644
--- a/libs/WindowManager/Shell/res/values-fr-rCA/strings.xml
+++ b/libs/WindowManager/Shell/res/values-fr-rCA/strings.xml
@@ -132,6 +132,8 @@
<string name="new_window_text" msgid="6318648868380652280">"Nouvelle fenêtre"</string>
<string name="manage_windows_text" msgid="5567366688493093920">"Gérer les fenêtres"</string>
<string name="change_aspect_ratio_text" msgid="9104456064548212806">"Modifier les proportions"</string>
+ <!-- no translation found for handle_menu_restart_text (3907767216238298098) -->
+ <skip />
<string name="close_text" msgid="4986518933445178928">"Fermer"</string>
<string name="collapse_menu_text" msgid="7515008122450342029">"Fermer le menu"</string>
<string name="desktop_mode_app_header_chip_text" msgid="7617377295944971651">"<xliff:g id="APP_NAME">%1$s</xliff:g> (fenêtrage du bureau)"</string>
diff --git a/libs/WindowManager/Shell/res/values-fr/strings.xml b/libs/WindowManager/Shell/res/values-fr/strings.xml
index ed87a1388304..708212fe77bc 100644
--- a/libs/WindowManager/Shell/res/values-fr/strings.xml
+++ b/libs/WindowManager/Shell/res/values-fr/strings.xml
@@ -132,6 +132,8 @@
<string name="new_window_text" msgid="6318648868380652280">"Nouvelle fenêtre"</string>
<string name="manage_windows_text" msgid="5567366688493093920">"Gérer les fenêtres"</string>
<string name="change_aspect_ratio_text" msgid="9104456064548212806">"Modifier le format"</string>
+ <!-- no translation found for handle_menu_restart_text (3907767216238298098) -->
+ <skip />
<string name="close_text" msgid="4986518933445178928">"Fermer"</string>
<string name="collapse_menu_text" msgid="7515008122450342029">"Fermer le menu"</string>
<string name="desktop_mode_app_header_chip_text" msgid="7617377295944971651">"<xliff:g id="APP_NAME">%1$s</xliff:g> (fenêtrage de bureau)"</string>
diff --git a/libs/WindowManager/Shell/res/values-gl/strings.xml b/libs/WindowManager/Shell/res/values-gl/strings.xml
index a2b871120464..a0a4df17edfe 100644
--- a/libs/WindowManager/Shell/res/values-gl/strings.xml
+++ b/libs/WindowManager/Shell/res/values-gl/strings.xml
@@ -132,6 +132,8 @@
<string name="new_window_text" msgid="6318648868380652280">"Ventá nova"</string>
<string name="manage_windows_text" msgid="5567366688493093920">"Xestionar as ventás"</string>
<string name="change_aspect_ratio_text" msgid="9104456064548212806">"Cambiar a proporción"</string>
+ <!-- no translation found for handle_menu_restart_text (3907767216238298098) -->
+ <skip />
<string name="close_text" msgid="4986518933445178928">"Pechar"</string>
<string name="collapse_menu_text" msgid="7515008122450342029">"Pechar o menú"</string>
<string name="desktop_mode_app_header_chip_text" msgid="7617377295944971651">"<xliff:g id="APP_NAME">%1$s</xliff:g> (escritorio baseado en ventás)"</string>
diff --git a/libs/WindowManager/Shell/res/values-gu/strings.xml b/libs/WindowManager/Shell/res/values-gu/strings.xml
index ddef9e1fd07b..2a546fa2a23c 100644
--- a/libs/WindowManager/Shell/res/values-gu/strings.xml
+++ b/libs/WindowManager/Shell/res/values-gu/strings.xml
@@ -132,6 +132,8 @@
<string name="new_window_text" msgid="6318648868380652280">"નવી વિન્ડો"</string>
<string name="manage_windows_text" msgid="5567366688493093920">"વિન્ડો મેનેજ કરો"</string>
<string name="change_aspect_ratio_text" msgid="9104456064548212806">"સાપેક્ષ ગુણોત્તર બદલો"</string>
+ <!-- no translation found for handle_menu_restart_text (3907767216238298098) -->
+ <skip />
<string name="close_text" msgid="4986518933445178928">"બંધ કરો"</string>
<string name="collapse_menu_text" msgid="7515008122450342029">"મેનૂ બંધ કરો"</string>
<string name="desktop_mode_app_header_chip_text" msgid="7617377295944971651">"<xliff:g id="APP_NAME">%1$s</xliff:g> (ડેસ્કટૉપ વિન્ડોઇંગ)"</string>
diff --git a/libs/WindowManager/Shell/res/values-hi/strings.xml b/libs/WindowManager/Shell/res/values-hi/strings.xml
index bbe43a1727f8..c2eb2b207740 100644
--- a/libs/WindowManager/Shell/res/values-hi/strings.xml
+++ b/libs/WindowManager/Shell/res/values-hi/strings.xml
@@ -132,6 +132,8 @@
<string name="new_window_text" msgid="6318648868380652280">"नई विंडो"</string>
<string name="manage_windows_text" msgid="5567366688493093920">"विंडो मैनेज करें"</string>
<string name="change_aspect_ratio_text" msgid="9104456064548212806">"आसपेक्ट रेशियो (लंबाई-चौड़ाई का अनुपात) बदलें"</string>
+ <!-- no translation found for handle_menu_restart_text (3907767216238298098) -->
+ <skip />
<string name="close_text" msgid="4986518933445178928">"बंद करें"</string>
<string name="collapse_menu_text" msgid="7515008122450342029">"मेन्यू बंद करें"</string>
<string name="desktop_mode_app_header_chip_text" msgid="7617377295944971651">"<xliff:g id="APP_NAME">%1$s</xliff:g> (डेस्कटॉप विंडोविंग)"</string>
diff --git a/libs/WindowManager/Shell/res/values-hr/strings.xml b/libs/WindowManager/Shell/res/values-hr/strings.xml
index 80ee56102cf2..41315fe466c2 100644
--- a/libs/WindowManager/Shell/res/values-hr/strings.xml
+++ b/libs/WindowManager/Shell/res/values-hr/strings.xml
@@ -132,6 +132,8 @@
<string name="new_window_text" msgid="6318648868380652280">"Novi prozor"</string>
<string name="manage_windows_text" msgid="5567366688493093920">"Upravljanje prozorima"</string>
<string name="change_aspect_ratio_text" msgid="9104456064548212806">"Promijeni omjer slike"</string>
+ <!-- no translation found for handle_menu_restart_text (3907767216238298098) -->
+ <skip />
<string name="close_text" msgid="4986518933445178928">"Zatvorite"</string>
<string name="collapse_menu_text" msgid="7515008122450342029">"Zatvorite izbornik"</string>
<string name="desktop_mode_app_header_chip_text" msgid="7617377295944971651">"<xliff:g id="APP_NAME">%1$s</xliff:g> (prikaz u prozorima na računalu)"</string>
diff --git a/libs/WindowManager/Shell/res/values-hu/strings.xml b/libs/WindowManager/Shell/res/values-hu/strings.xml
index d24e4da8c982..0ebf2cb23946 100644
--- a/libs/WindowManager/Shell/res/values-hu/strings.xml
+++ b/libs/WindowManager/Shell/res/values-hu/strings.xml
@@ -100,7 +100,7 @@
<string name="camera_compat_treatment_applied_button_description" msgid="2944157113330703897">"Nem sikerült a hiba kijavítása?\nKoppintson a visszaállításhoz."</string>
<string name="camera_compat_dismiss_button_description" msgid="2795364433503817511">"Nincsenek problémái kamerával? Koppintson az elvetéshez."</string>
<string name="windowing_app_handle_education_tooltip" msgid="2929643449849791854">"Az alkalmazásmenü itt található"</string>
- <string name="windowing_desktop_mode_image_button_education_tooltip" msgid="7171915734817051666">"Asztali ablakkezelési módba lépve több alkalmazást nyithat meg egyidejűleg"</string>
+ <string name="windowing_desktop_mode_image_button_education_tooltip" msgid="7171915734817051666">"Asztali ablakkezelési módba lépve egyidejűleg több alkalmazást is megnyithat"</string>
<string name="windowing_desktop_mode_exit_education_tooltip" msgid="5225660258192054132">"Az alkalmazásmenüből bármikor visszatérhet a teljes képernyőre"</string>
<string name="letterbox_education_dialog_title" msgid="7739895354143295358">"Több mindent láthat és tehet"</string>
<string name="letterbox_education_split_screen_text" msgid="449233070804658627">"Húzzon ide egy másik alkalmazást az osztott képernyő használatához"</string>
@@ -132,6 +132,8 @@
<string name="new_window_text" msgid="6318648868380652280">"Új ablak"</string>
<string name="manage_windows_text" msgid="5567366688493093920">"Ablakok kezelése"</string>
<string name="change_aspect_ratio_text" msgid="9104456064548212806">"Méretarány módosítása"</string>
+ <!-- no translation found for handle_menu_restart_text (3907767216238298098) -->
+ <skip />
<string name="close_text" msgid="4986518933445178928">"Bezárás"</string>
<string name="collapse_menu_text" msgid="7515008122450342029">"Menü bezárása"</string>
<string name="desktop_mode_app_header_chip_text" msgid="7617377295944971651">"<xliff:g id="APP_NAME">%1$s</xliff:g> (Asztali ablakkezelési mód)"</string>
diff --git a/libs/WindowManager/Shell/res/values-hy/strings.xml b/libs/WindowManager/Shell/res/values-hy/strings.xml
index 6bc3c37cadf4..a792f5bd8844 100644
--- a/libs/WindowManager/Shell/res/values-hy/strings.xml
+++ b/libs/WindowManager/Shell/res/values-hy/strings.xml
@@ -132,6 +132,8 @@
<string name="new_window_text" msgid="6318648868380652280">"Նոր պատուհան"</string>
<string name="manage_windows_text" msgid="5567366688493093920">"Կառավարել պատուհանները"</string>
<string name="change_aspect_ratio_text" msgid="9104456064548212806">"Փոխել կողմերի հարաբերակցությունը"</string>
+ <!-- no translation found for handle_menu_restart_text (3907767216238298098) -->
+ <skip />
<string name="close_text" msgid="4986518933445178928">"Փակել"</string>
<string name="collapse_menu_text" msgid="7515008122450342029">"Փակել ընտրացանկը"</string>
<string name="desktop_mode_app_header_chip_text" msgid="7617377295944971651">"<xliff:g id="APP_NAME">%1$s</xliff:g> (համակարգչային պատուհաններ)"</string>
diff --git a/libs/WindowManager/Shell/res/values-in/strings.xml b/libs/WindowManager/Shell/res/values-in/strings.xml
index c15c2ea6600b..720104511ce6 100644
--- a/libs/WindowManager/Shell/res/values-in/strings.xml
+++ b/libs/WindowManager/Shell/res/values-in/strings.xml
@@ -132,6 +132,8 @@
<string name="new_window_text" msgid="6318648868380652280">"Jendela Baru"</string>
<string name="manage_windows_text" msgid="5567366688493093920">"Kelola Jendela"</string>
<string name="change_aspect_ratio_text" msgid="9104456064548212806">"Ubah rasio aspek"</string>
+ <!-- no translation found for handle_menu_restart_text (3907767216238298098) -->
+ <skip />
<string name="close_text" msgid="4986518933445178928">"Tutup"</string>
<string name="collapse_menu_text" msgid="7515008122450342029">"Tutup Menu"</string>
<string name="desktop_mode_app_header_chip_text" msgid="7617377295944971651">"<xliff:g id="APP_NAME">%1$s</xliff:g> (Mode jendela desktop)"</string>
diff --git a/libs/WindowManager/Shell/res/values-is/strings.xml b/libs/WindowManager/Shell/res/values-is/strings.xml
index 7d98d3b01fc2..8488c308e725 100644
--- a/libs/WindowManager/Shell/res/values-is/strings.xml
+++ b/libs/WindowManager/Shell/res/values-is/strings.xml
@@ -132,6 +132,8 @@
<string name="new_window_text" msgid="6318648868380652280">"Nýr gluggi"</string>
<string name="manage_windows_text" msgid="5567366688493093920">"Stjórna gluggum"</string>
<string name="change_aspect_ratio_text" msgid="9104456064548212806">"Breyta myndhlutfalli"</string>
+ <!-- no translation found for handle_menu_restart_text (3907767216238298098) -->
+ <skip />
<string name="close_text" msgid="4986518933445178928">"Loka"</string>
<string name="collapse_menu_text" msgid="7515008122450342029">"Loka valmynd"</string>
<string name="desktop_mode_app_header_chip_text" msgid="7617377295944971651">"<xliff:g id="APP_NAME">%1$s</xliff:g> (gluggastilling í tölvu)"</string>
diff --git a/libs/WindowManager/Shell/res/values-it/strings.xml b/libs/WindowManager/Shell/res/values-it/strings.xml
index 72f805693146..4fc60ddc51f8 100644
--- a/libs/WindowManager/Shell/res/values-it/strings.xml
+++ b/libs/WindowManager/Shell/res/values-it/strings.xml
@@ -132,6 +132,8 @@
<string name="new_window_text" msgid="6318648868380652280">"Nuova finestra"</string>
<string name="manage_windows_text" msgid="5567366688493093920">"Gestisci finestre"</string>
<string name="change_aspect_ratio_text" msgid="9104456064548212806">"Cambia proporzioni"</string>
+ <!-- no translation found for handle_menu_restart_text (3907767216238298098) -->
+ <skip />
<string name="close_text" msgid="4986518933445178928">"Chiudi"</string>
<string name="collapse_menu_text" msgid="7515008122450342029">"Chiudi il menu"</string>
<string name="desktop_mode_app_header_chip_text" msgid="7617377295944971651">"<xliff:g id="APP_NAME">%1$s</xliff:g> (windowing del desktop)"</string>
diff --git a/libs/WindowManager/Shell/res/values-iw/strings.xml b/libs/WindowManager/Shell/res/values-iw/strings.xml
index c3e85230c319..be14b0081451 100644
--- a/libs/WindowManager/Shell/res/values-iw/strings.xml
+++ b/libs/WindowManager/Shell/res/values-iw/strings.xml
@@ -100,8 +100,7 @@
<string name="camera_compat_treatment_applied_button_description" msgid="2944157113330703897">"הבעיה לא נפתרה?\nאפשר ללחוץ כדי לחזור לגרסה הקודמת"</string>
<string name="camera_compat_dismiss_button_description" msgid="2795364433503817511">"אין בעיות במצלמה? אפשר ללחוץ כדי לסגור."</string>
<string name="windowing_app_handle_education_tooltip" msgid="2929643449849791854">"תפריט האפליקציה נמצא כאן"</string>
- <!-- no translation found for windowing_desktop_mode_image_button_education_tooltip (7171915734817051666) -->
- <skip />
+ <string name="windowing_desktop_mode_image_button_education_tooltip" msgid="7171915734817051666">"‏כדי לפתוח כמה אפליקציות יחד, צריך להיכנס למצב \"שינוי דינמי של חלונות במחשב\" (desktop windowing)"</string>
<string name="windowing_desktop_mode_exit_education_tooltip" msgid="5225660258192054132">"אפשר לחזור למסך מלא בכל שלב מתפריט האפליקציה"</string>
<string name="letterbox_education_dialog_title" msgid="7739895354143295358">"רוצה לראות ולעשות יותר?"</string>
<string name="letterbox_education_split_screen_text" msgid="449233070804658627">"צריך לגרור אפליקציה אחרת כדי להשתמש במסך המפוצל"</string>
@@ -122,8 +121,7 @@
<string name="handle_text" msgid="4419667835599523257">"נקודת אחיזה לאפליקציה"</string>
<string name="app_icon_text" msgid="2823268023931811747">"סמל האפליקציה"</string>
<string name="fullscreen_text" msgid="1162316685217676079">"מסך מלא"</string>
- <!-- no translation found for desktop_text (9058641752519570266) -->
- <skip />
+ <string name="desktop_text" msgid="9058641752519570266">"שינוי דינמי של חלונות במחשב"</string>
<string name="split_screen_text" msgid="1396336058129570886">"מסך מפוצל"</string>
<string name="more_button_text" msgid="3655388105592893530">"עוד"</string>
<string name="float_button_text" msgid="9221657008391364581">"בלונים"</string>
@@ -134,10 +132,11 @@
<string name="new_window_text" msgid="6318648868380652280">"חלון חדש"</string>
<string name="manage_windows_text" msgid="5567366688493093920">"ניהול החלונות"</string>
<string name="change_aspect_ratio_text" msgid="9104456064548212806">"שינוי יחס הגובה-רוחב"</string>
+ <!-- no translation found for handle_menu_restart_text (3907767216238298098) -->
+ <skip />
<string name="close_text" msgid="4986518933445178928">"סגירה"</string>
<string name="collapse_menu_text" msgid="7515008122450342029">"סגירת התפריט"</string>
- <!-- no translation found for desktop_mode_app_header_chip_text (7617377295944971651) -->
- <skip />
+ <string name="desktop_mode_app_header_chip_text" msgid="7617377295944971651">"‫<xliff:g id="APP_NAME">%1$s</xliff:g> (שינוי דינמי של חלונות במחשב)"</string>
<string name="desktop_mode_maximize_menu_maximize_text" msgid="3275717276171114411">"הגדלת המסך"</string>
<string name="desktop_mode_maximize_menu_snap_text" msgid="5673738963174074006">"שינוי הגודל"</string>
<string name="desktop_mode_non_resizable_snap_text" msgid="3771776422751387878">"לא ניתן להעביר את האפליקציה לכאן"</string>
diff --git a/libs/WindowManager/Shell/res/values-ja/strings.xml b/libs/WindowManager/Shell/res/values-ja/strings.xml
index c95ec4ee25a3..761df5cc560c 100644
--- a/libs/WindowManager/Shell/res/values-ja/strings.xml
+++ b/libs/WindowManager/Shell/res/values-ja/strings.xml
@@ -132,6 +132,8 @@
<string name="new_window_text" msgid="6318648868380652280">"新しいウィンドウ"</string>
<string name="manage_windows_text" msgid="5567366688493093920">"ウィンドウを管理する"</string>
<string name="change_aspect_ratio_text" msgid="9104456064548212806">"アスペクト比を変更"</string>
+ <!-- no translation found for handle_menu_restart_text (3907767216238298098) -->
+ <skip />
<string name="close_text" msgid="4986518933445178928">"閉じる"</string>
<string name="collapse_menu_text" msgid="7515008122450342029">"メニューを閉じる"</string>
<string name="desktop_mode_app_header_chip_text" msgid="7617377295944971651">"<xliff:g id="APP_NAME">%1$s</xliff:g>(デスクトップ ウィンドウ)"</string>
diff --git a/libs/WindowManager/Shell/res/values-ka/strings.xml b/libs/WindowManager/Shell/res/values-ka/strings.xml
index 0c7264cf9ede..d5c44fb8a963 100644
--- a/libs/WindowManager/Shell/res/values-ka/strings.xml
+++ b/libs/WindowManager/Shell/res/values-ka/strings.xml
@@ -132,6 +132,8 @@
<string name="new_window_text" msgid="6318648868380652280">"ახალი ფანჯარა"</string>
<string name="manage_windows_text" msgid="5567366688493093920">"ფანჯრების მართვა"</string>
<string name="change_aspect_ratio_text" msgid="9104456064548212806">"თანაფარდობის შეცვლა"</string>
+ <!-- no translation found for handle_menu_restart_text (3907767216238298098) -->
+ <skip />
<string name="close_text" msgid="4986518933445178928">"დახურვა"</string>
<string name="collapse_menu_text" msgid="7515008122450342029">"მენიუს დახურვა"</string>
<string name="desktop_mode_app_header_chip_text" msgid="7617377295944971651">"<xliff:g id="APP_NAME">%1$s</xliff:g> (დესკტოპის ფანჯრის რეჟიმი)"</string>
diff --git a/libs/WindowManager/Shell/res/values-kk/strings.xml b/libs/WindowManager/Shell/res/values-kk/strings.xml
index c1085db12f08..3a9711e2337a 100644
--- a/libs/WindowManager/Shell/res/values-kk/strings.xml
+++ b/libs/WindowManager/Shell/res/values-kk/strings.xml
@@ -100,7 +100,7 @@
<string name="camera_compat_treatment_applied_button_description" msgid="2944157113330703897">"Жөнделмеді ме?\nҚайтару үшін түртіңіз."</string>
<string name="camera_compat_dismiss_button_description" msgid="2795364433503817511">"Камерада қателер шықпады ма? Жабу үшін түртіңіз."</string>
<string name="windowing_app_handle_education_tooltip" msgid="2929643449849791854">"Қолданба мәзірін осы жерден табуға болады."</string>
- <string name="windowing_desktop_mode_image_button_education_tooltip" msgid="7171915734817051666">"Бірнеше қолданбаны бірге ашу үшін жұмыс үстелі көрінісіне кіріңіз."</string>
+ <string name="windowing_desktop_mode_image_button_education_tooltip" msgid="7171915734817051666">"Бірнеше қолданбаны бірге ашу үшін компьютерлік терезелер режиміне кіріңіз."</string>
<string name="windowing_desktop_mode_exit_education_tooltip" msgid="5225660258192054132">"Қолданба мәзірінен кез келген уақытта толық экранға оралыңыз."</string>
<string name="letterbox_education_dialog_title" msgid="7739895354143295358">"Қосымша ақпаратты қарап, әрекеттер жасау"</string>
<string name="letterbox_education_split_screen_text" msgid="449233070804658627">"Экранды бөлу үшін басқа қолданбаға өтіңіз."</string>
@@ -121,7 +121,7 @@
<string name="handle_text" msgid="4419667835599523257">"Қолданба идентификаторы"</string>
<string name="app_icon_text" msgid="2823268023931811747">"Қолданба белгішесі"</string>
<string name="fullscreen_text" msgid="1162316685217676079">"Толық экран"</string>
- <string name="desktop_text" msgid="9058641752519570266">"Жұмыс үстелі көрінісі"</string>
+ <string name="desktop_text" msgid="9058641752519570266">"Компьютерлік терезелер режимі"</string>
<string name="split_screen_text" msgid="1396336058129570886">"Экранды бөлу"</string>
<string name="more_button_text" msgid="3655388105592893530">"Қосымша"</string>
<string name="float_button_text" msgid="9221657008391364581">"Қалқыма"</string>
@@ -132,9 +132,11 @@
<string name="new_window_text" msgid="6318648868380652280">"Жаңа терезе"</string>
<string name="manage_windows_text" msgid="5567366688493093920">"Терезелерді басқару"</string>
<string name="change_aspect_ratio_text" msgid="9104456064548212806">"Арақатынасты өзгерту"</string>
+ <!-- no translation found for handle_menu_restart_text (3907767216238298098) -->
+ <skip />
<string name="close_text" msgid="4986518933445178928">"Жабу"</string>
<string name="collapse_menu_text" msgid="7515008122450342029">"Мәзірді жабу"</string>
- <string name="desktop_mode_app_header_chip_text" msgid="7617377295944971651">"<xliff:g id="APP_NAME">%1$s</xliff:g> (жұмыс үстелі көрінісі)"</string>
+ <string name="desktop_mode_app_header_chip_text" msgid="7617377295944971651">"<xliff:g id="APP_NAME">%1$s</xliff:g> (компьютерлік терезелер режимі)"</string>
<string name="desktop_mode_maximize_menu_maximize_text" msgid="3275717276171114411">"Экранды ұлғайту"</string>
<string name="desktop_mode_maximize_menu_snap_text" msgid="5673738963174074006">"Өлшемін өзгерту"</string>
<string name="desktop_mode_non_resizable_snap_text" msgid="3771776422751387878">"Қолданба бұл жерге қойылмайды."</string>
diff --git a/libs/WindowManager/Shell/res/values-km/strings.xml b/libs/WindowManager/Shell/res/values-km/strings.xml
index afbd9e0c9422..c4b5a9b2009f 100644
--- a/libs/WindowManager/Shell/res/values-km/strings.xml
+++ b/libs/WindowManager/Shell/res/values-km/strings.xml
@@ -132,6 +132,8 @@
<string name="new_window_text" msgid="6318648868380652280">"វិនដូ​ថ្មី"</string>
<string name="manage_windows_text" msgid="5567366688493093920">"គ្រប់គ្រង​វិនដូ"</string>
<string name="change_aspect_ratio_text" msgid="9104456064548212806">"ប្ដូរ​​សមាមាត្រ"</string>
+ <!-- no translation found for handle_menu_restart_text (3907767216238298098) -->
+ <skip />
<string name="close_text" msgid="4986518933445178928">"បិទ"</string>
<string name="collapse_menu_text" msgid="7515008122450342029">"បិទ​ម៉ឺនុយ"</string>
<string name="desktop_mode_app_header_chip_text" msgid="7617377295944971651">"<xliff:g id="APP_NAME">%1$s</xliff:g> (មុខងារវិនដូកុំព្យូទ័រ)"</string>
diff --git a/libs/WindowManager/Shell/res/values-kn/strings.xml b/libs/WindowManager/Shell/res/values-kn/strings.xml
index 34076e8ecebe..9d3ec2a347af 100644
--- a/libs/WindowManager/Shell/res/values-kn/strings.xml
+++ b/libs/WindowManager/Shell/res/values-kn/strings.xml
@@ -132,6 +132,8 @@
<string name="new_window_text" msgid="6318648868380652280">"ಹೊಸ ವಿಂಡೋ"</string>
<string name="manage_windows_text" msgid="5567366688493093920">"ವಿಂಡೋಗಳನ್ನು ನಿರ್ವಹಿಸಿ"</string>
<string name="change_aspect_ratio_text" msgid="9104456064548212806">"ದೃಶ್ಯಾನುಪಾತವನ್ನು ಬದಲಾಯಿಸಿ"</string>
+ <!-- no translation found for handle_menu_restart_text (3907767216238298098) -->
+ <skip />
<string name="close_text" msgid="4986518933445178928">"ಮುಚ್ಚಿ"</string>
<string name="collapse_menu_text" msgid="7515008122450342029">"ಮೆನು ಮುಚ್ಚಿ"</string>
<string name="desktop_mode_app_header_chip_text" msgid="7617377295944971651">"<xliff:g id="APP_NAME">%1$s</xliff:g> (ಡೆಸ್ಕ್‌ಟಾಪ್ ವಿಂಡೋಯಿಂಗ್)"</string>
diff --git a/libs/WindowManager/Shell/res/values-ko/strings.xml b/libs/WindowManager/Shell/res/values-ko/strings.xml
index a0fa7e480663..5206b83ef17a 100644
--- a/libs/WindowManager/Shell/res/values-ko/strings.xml
+++ b/libs/WindowManager/Shell/res/values-ko/strings.xml
@@ -132,6 +132,8 @@
<string name="new_window_text" msgid="6318648868380652280">"새 창"</string>
<string name="manage_windows_text" msgid="5567366688493093920">"창 관리"</string>
<string name="change_aspect_ratio_text" msgid="9104456064548212806">"가로세로 비율 변경"</string>
+ <!-- no translation found for handle_menu_restart_text (3907767216238298098) -->
+ <skip />
<string name="close_text" msgid="4986518933445178928">"닫기"</string>
<string name="collapse_menu_text" msgid="7515008122450342029">"메뉴 닫기"</string>
<string name="desktop_mode_app_header_chip_text" msgid="7617377295944971651">"<xliff:g id="APP_NAME">%1$s</xliff:g>(데스크톱 윈도윙)"</string>
diff --git a/libs/WindowManager/Shell/res/values-ky/strings.xml b/libs/WindowManager/Shell/res/values-ky/strings.xml
index 629070cbe810..810a63841cfb 100644
--- a/libs/WindowManager/Shell/res/values-ky/strings.xml
+++ b/libs/WindowManager/Shell/res/values-ky/strings.xml
@@ -132,6 +132,8 @@
<string name="new_window_text" msgid="6318648868380652280">"Жаңы терезе"</string>
<string name="manage_windows_text" msgid="5567366688493093920">"Терезелерди тескөө"</string>
<string name="change_aspect_ratio_text" msgid="9104456064548212806">"Тараптардын катнашын өзгөртүү"</string>
+ <!-- no translation found for handle_menu_restart_text (3907767216238298098) -->
+ <skip />
<string name="close_text" msgid="4986518933445178928">"Жабуу"</string>
<string name="collapse_menu_text" msgid="7515008122450342029">"Менюну жабуу"</string>
<string name="desktop_mode_app_header_chip_text" msgid="7617377295944971651">"<xliff:g id="APP_NAME">%1$s</xliff:g> (Иш тактанын терезелери)"</string>
diff --git a/libs/WindowManager/Shell/res/values-lo/strings.xml b/libs/WindowManager/Shell/res/values-lo/strings.xml
index f2d0e6bd7af4..7a4fb61bdf0d 100644
--- a/libs/WindowManager/Shell/res/values-lo/strings.xml
+++ b/libs/WindowManager/Shell/res/values-lo/strings.xml
@@ -132,6 +132,8 @@
<string name="new_window_text" msgid="6318648868380652280">"ໜ້າຈໍໃໝ່"</string>
<string name="manage_windows_text" msgid="5567366688493093920">"ຈັດການໜ້າຈໍ"</string>
<string name="change_aspect_ratio_text" msgid="9104456064548212806">"ປ່ຽນອັດຕາສ່ວນຮູບ"</string>
+ <!-- no translation found for handle_menu_restart_text (3907767216238298098) -->
+ <skip />
<string name="close_text" msgid="4986518933445178928">"ປິດ"</string>
<string name="collapse_menu_text" msgid="7515008122450342029">"ປິດເມນູ"</string>
<string name="desktop_mode_app_header_chip_text" msgid="7617377295944971651">"<xliff:g id="APP_NAME">%1$s</xliff:g> (ໜ້າຈໍເດັສທັອບ)"</string>
diff --git a/libs/WindowManager/Shell/res/values-lt/strings.xml b/libs/WindowManager/Shell/res/values-lt/strings.xml
index ed4b14cd94dd..75619eaefd17 100644
--- a/libs/WindowManager/Shell/res/values-lt/strings.xml
+++ b/libs/WindowManager/Shell/res/values-lt/strings.xml
@@ -132,6 +132,8 @@
<string name="new_window_text" msgid="6318648868380652280">"Naujas langas"</string>
<string name="manage_windows_text" msgid="5567366688493093920">"Tvarkyti langus"</string>
<string name="change_aspect_ratio_text" msgid="9104456064548212806">"Keisti kraštinių santykį"</string>
+ <!-- no translation found for handle_menu_restart_text (3907767216238298098) -->
+ <skip />
<string name="close_text" msgid="4986518933445178928">"Uždaryti"</string>
<string name="collapse_menu_text" msgid="7515008122450342029">"Uždaryti meniu"</string>
<string name="desktop_mode_app_header_chip_text" msgid="7617377295944971651">"„<xliff:g id="APP_NAME">%1$s</xliff:g>“ (versijos staliniams kompiuteriams rodinys)"</string>
diff --git a/libs/WindowManager/Shell/res/values-lv/strings.xml b/libs/WindowManager/Shell/res/values-lv/strings.xml
index c24b43a686c3..5eea17c60053 100644
--- a/libs/WindowManager/Shell/res/values-lv/strings.xml
+++ b/libs/WindowManager/Shell/res/values-lv/strings.xml
@@ -132,6 +132,8 @@
<string name="new_window_text" msgid="6318648868380652280">"Jauns logs"</string>
<string name="manage_windows_text" msgid="5567366688493093920">"Pārvaldīt logus"</string>
<string name="change_aspect_ratio_text" msgid="9104456064548212806">"Mainīt malu attiecību"</string>
+ <!-- no translation found for handle_menu_restart_text (3907767216238298098) -->
+ <skip />
<string name="close_text" msgid="4986518933445178928">"Aizvērt"</string>
<string name="collapse_menu_text" msgid="7515008122450342029">"Aizvērt izvēlni"</string>
<string name="desktop_mode_app_header_chip_text" msgid="7617377295944971651">"<xliff:g id="APP_NAME">%1$s</xliff:g> (darbvirsmas logošana)"</string>
diff --git a/libs/WindowManager/Shell/res/values-mk/strings.xml b/libs/WindowManager/Shell/res/values-mk/strings.xml
index 06ed3232514b..4653aa2ca7c5 100644
--- a/libs/WindowManager/Shell/res/values-mk/strings.xml
+++ b/libs/WindowManager/Shell/res/values-mk/strings.xml
@@ -132,6 +132,8 @@
<string name="new_window_text" msgid="6318648868380652280">"Нов прозорец"</string>
<string name="manage_windows_text" msgid="5567366688493093920">"Управувајте со прозорците"</string>
<string name="change_aspect_ratio_text" msgid="9104456064548212806">"Промени го соодносот"</string>
+ <!-- no translation found for handle_menu_restart_text (3907767216238298098) -->
+ <skip />
<string name="close_text" msgid="4986518933445178928">"Затворете"</string>
<string name="collapse_menu_text" msgid="7515008122450342029">"Затворете го менито"</string>
<string name="desktop_mode_app_header_chip_text" msgid="7617377295944971651">"<xliff:g id="APP_NAME">%1$s</xliff:g> (режим со прозорци на работната површина)"</string>
diff --git a/libs/WindowManager/Shell/res/values-ml/strings.xml b/libs/WindowManager/Shell/res/values-ml/strings.xml
index dd4ec1bbf1cd..50c2f6e1a8b2 100644
--- a/libs/WindowManager/Shell/res/values-ml/strings.xml
+++ b/libs/WindowManager/Shell/res/values-ml/strings.xml
@@ -132,6 +132,8 @@
<string name="new_window_text" msgid="6318648868380652280">"പുതിയ വിന്‍ഡോ"</string>
<string name="manage_windows_text" msgid="5567366688493093920">"വിൻഡോകൾ മാനേജ് ചെയ്യുക"</string>
<string name="change_aspect_ratio_text" msgid="9104456064548212806">"വീക്ഷണ അനുപാതം മാറ്റുക"</string>
+ <!-- no translation found for handle_menu_restart_text (3907767216238298098) -->
+ <skip />
<string name="close_text" msgid="4986518933445178928">"അടയ്ക്കുക"</string>
<string name="collapse_menu_text" msgid="7515008122450342029">"മെനു അടയ്ക്കുക"</string>
<string name="desktop_mode_app_header_chip_text" msgid="7617377295944971651">"<xliff:g id="APP_NAME">%1$s</xliff:g> (ഡെസ്ക്ടോപ്പ് വിൻഡോയിംഗ്)"</string>
diff --git a/libs/WindowManager/Shell/res/values-mn/strings.xml b/libs/WindowManager/Shell/res/values-mn/strings.xml
index 8683827ae004..80e83a5a3901 100644
--- a/libs/WindowManager/Shell/res/values-mn/strings.xml
+++ b/libs/WindowManager/Shell/res/values-mn/strings.xml
@@ -132,6 +132,8 @@
<string name="new_window_text" msgid="6318648868380652280">"Шинэ цонх"</string>
<string name="manage_windows_text" msgid="5567366688493093920">"Цонхнуудыг удирдах"</string>
<string name="change_aspect_ratio_text" msgid="9104456064548212806">"Аспектын харьцааг өөрчлөх"</string>
+ <!-- no translation found for handle_menu_restart_text (3907767216238298098) -->
+ <skip />
<string name="close_text" msgid="4986518933445178928">"Хаах"</string>
<string name="collapse_menu_text" msgid="7515008122450342029">"Цэсийг хаах"</string>
<string name="desktop_mode_app_header_chip_text" msgid="7617377295944971651">"<xliff:g id="APP_NAME">%1$s</xliff:g> (Дэлгэцийн цонх үүсгэх онцлог)"</string>
diff --git a/libs/WindowManager/Shell/res/values-mr/strings.xml b/libs/WindowManager/Shell/res/values-mr/strings.xml
index b7b3fb673d96..deb0bafa2058 100644
--- a/libs/WindowManager/Shell/res/values-mr/strings.xml
+++ b/libs/WindowManager/Shell/res/values-mr/strings.xml
@@ -132,6 +132,8 @@
<string name="new_window_text" msgid="6318648868380652280">"नवीन विंडो"</string>
<string name="manage_windows_text" msgid="5567366688493093920">"विंडो व्यवस्थापित करा"</string>
<string name="change_aspect_ratio_text" msgid="9104456064548212806">"आस्पेक्ट रेशो बदला"</string>
+ <!-- no translation found for handle_menu_restart_text (3907767216238298098) -->
+ <skip />
<string name="close_text" msgid="4986518933445178928">"बंद करा"</string>
<string name="collapse_menu_text" msgid="7515008122450342029">"मेनू बंद करा"</string>
<string name="desktop_mode_app_header_chip_text" msgid="7617377295944971651">"<xliff:g id="APP_NAME">%1$s</xliff:g> (डेस्कटॉप विंडोइंग)"</string>
diff --git a/libs/WindowManager/Shell/res/values-ms/strings.xml b/libs/WindowManager/Shell/res/values-ms/strings.xml
index 0896b5ee88cb..1f56033e8c97 100644
--- a/libs/WindowManager/Shell/res/values-ms/strings.xml
+++ b/libs/WindowManager/Shell/res/values-ms/strings.xml
@@ -132,6 +132,8 @@
<string name="new_window_text" msgid="6318648868380652280">"Tetingkap Baharu"</string>
<string name="manage_windows_text" msgid="5567366688493093920">"Urus Tetingkap"</string>
<string name="change_aspect_ratio_text" msgid="9104456064548212806">"Tukar nisbah bidang"</string>
+ <!-- no translation found for handle_menu_restart_text (3907767216238298098) -->
+ <skip />
<string name="close_text" msgid="4986518933445178928">"Tutup"</string>
<string name="collapse_menu_text" msgid="7515008122450342029">"Tutup Menu"</string>
<string name="desktop_mode_app_header_chip_text" msgid="7617377295944971651">"<xliff:g id="APP_NAME">%1$s</xliff:g> (Tetingkap desktop)"</string>
diff --git a/libs/WindowManager/Shell/res/values-my/strings.xml b/libs/WindowManager/Shell/res/values-my/strings.xml
index 0f336e828f47..061ad0405d89 100644
--- a/libs/WindowManager/Shell/res/values-my/strings.xml
+++ b/libs/WindowManager/Shell/res/values-my/strings.xml
@@ -132,6 +132,8 @@
<string name="new_window_text" msgid="6318648868380652280">"ဝင်းဒိုးအသစ်"</string>
<string name="manage_windows_text" msgid="5567366688493093920">"ဝင်းဒိုးများ စီမံရန်"</string>
<string name="change_aspect_ratio_text" msgid="9104456064548212806">"အချိုးအစား ပြောင်းရန်"</string>
+ <!-- no translation found for handle_menu_restart_text (3907767216238298098) -->
+ <skip />
<string name="close_text" msgid="4986518933445178928">"ပိတ်ရန်"</string>
<string name="collapse_menu_text" msgid="7515008122450342029">"မီနူး ပိတ်ရန်"</string>
<string name="desktop_mode_app_header_chip_text" msgid="7617377295944971651">"<xliff:g id="APP_NAME">%1$s</xliff:g> (ဒက်စ်တော့ဝင်းဒိုးမုဒ်)"</string>
diff --git a/libs/WindowManager/Shell/res/values-nb/strings.xml b/libs/WindowManager/Shell/res/values-nb/strings.xml
index 3207614c013f..232fb2b04f92 100644
--- a/libs/WindowManager/Shell/res/values-nb/strings.xml
+++ b/libs/WindowManager/Shell/res/values-nb/strings.xml
@@ -132,6 +132,8 @@
<string name="new_window_text" msgid="6318648868380652280">"Nytt vindu"</string>
<string name="manage_windows_text" msgid="5567366688493093920">"Administrer vinduene"</string>
<string name="change_aspect_ratio_text" msgid="9104456064548212806">"Endre høyde/bredde-forholdet"</string>
+ <!-- no translation found for handle_menu_restart_text (3907767216238298098) -->
+ <skip />
<string name="close_text" msgid="4986518933445178928">"Lukk"</string>
<string name="collapse_menu_text" msgid="7515008122450342029">"Lukk menyen"</string>
<string name="desktop_mode_app_header_chip_text" msgid="7617377295944971651">"<xliff:g id="APP_NAME">%1$s</xliff:g> (datamaskin-vindusvisning)"</string>
diff --git a/libs/WindowManager/Shell/res/values-ne/strings.xml b/libs/WindowManager/Shell/res/values-ne/strings.xml
index 2c7be991dd67..2d6ab7d816ab 100644
--- a/libs/WindowManager/Shell/res/values-ne/strings.xml
+++ b/libs/WindowManager/Shell/res/values-ne/strings.xml
@@ -132,6 +132,8 @@
<string name="new_window_text" msgid="6318648868380652280">"नयाँ विन्डो"</string>
<string name="manage_windows_text" msgid="5567366688493093920">"विन्डोहरू व्यवस्थापन गर्नुहोस्"</string>
<string name="change_aspect_ratio_text" msgid="9104456064548212806">"एस्पेक्ट रेसियो परिवर्तन गर्नुहोस्"</string>
+ <!-- no translation found for handle_menu_restart_text (3907767216238298098) -->
+ <skip />
<string name="close_text" msgid="4986518933445178928">"बन्द गर्नुहोस्"</string>
<string name="collapse_menu_text" msgid="7515008122450342029">"मेनु बन्द गर्नुहोस्"</string>
<string name="desktop_mode_app_header_chip_text" msgid="7617377295944971651">"<xliff:g id="APP_NAME">%1$s</xliff:g> (डेस्कटप विन्डोइङ)"</string>
diff --git a/libs/WindowManager/Shell/res/values-nl/strings.xml b/libs/WindowManager/Shell/res/values-nl/strings.xml
index 099f875e0eb9..23f251f8ef60 100644
--- a/libs/WindowManager/Shell/res/values-nl/strings.xml
+++ b/libs/WindowManager/Shell/res/values-nl/strings.xml
@@ -132,6 +132,8 @@
<string name="new_window_text" msgid="6318648868380652280">"Nieuw venster"</string>
<string name="manage_windows_text" msgid="5567366688493093920">"Vensters beheren"</string>
<string name="change_aspect_ratio_text" msgid="9104456064548212806">"Beeldverhouding wijzigen"</string>
+ <!-- no translation found for handle_menu_restart_text (3907767216238298098) -->
+ <skip />
<string name="close_text" msgid="4986518933445178928">"Sluiten"</string>
<string name="collapse_menu_text" msgid="7515008122450342029">"Menu sluiten"</string>
<string name="desktop_mode_app_header_chip_text" msgid="7617377295944971651">"<xliff:g id="APP_NAME">%1$s</xliff:g> (desktopvensterfunctie)"</string>
diff --git a/libs/WindowManager/Shell/res/values-or/strings.xml b/libs/WindowManager/Shell/res/values-or/strings.xml
index 19cc8ced6517..8b7f0c758ac7 100644
--- a/libs/WindowManager/Shell/res/values-or/strings.xml
+++ b/libs/WindowManager/Shell/res/values-or/strings.xml
@@ -100,8 +100,7 @@
<string name="camera_compat_treatment_applied_button_description" msgid="2944157113330703897">"ଏହାର ସମାଧାନ ହୋଇନାହିଁ?\nଫେରିଯିବା ପାଇଁ ଟାପ କରନ୍ତୁ"</string>
<string name="camera_compat_dismiss_button_description" msgid="2795364433503817511">"କ୍ୟାମେରାରେ କିଛି ସମସ୍ୟା ନାହିଁ? ଖାରଜ କରିବାକୁ ଟାପ କରନ୍ତୁ।"</string>
<string name="windowing_app_handle_education_tooltip" msgid="2929643449849791854">"ଆପ ମେନୁ ଏଠାରେ ମିଳିପାରିବ"</string>
- <!-- no translation found for windowing_desktop_mode_image_button_education_tooltip (7171915734817051666) -->
- <skip />
+ <string name="windowing_desktop_mode_image_button_education_tooltip" msgid="7171915734817051666">"ଏକାଠି ଏକାଧିକ ଆପ୍ସ ଖୋଲିବାକୁ ଡେସ୍କଟପ ୱିଣ୍ଡୋଇଂରେ ଏଣ୍ଟର କରନ୍ତୁ"</string>
<string name="windowing_desktop_mode_exit_education_tooltip" msgid="5225660258192054132">"ଆପ ମେନୁରୁ ଯେ କୌଣସି ସମୟରେ ପୂର୍ଣ୍ଣ ସ୍କ୍ରିନକୁ ଫେରନ୍ତୁ"</string>
<string name="letterbox_education_dialog_title" msgid="7739895354143295358">"ଦେଖନ୍ତୁ ଏବଂ ଆହୁରି ଅନେକ କିଛି କରନ୍ତୁ"</string>
<string name="letterbox_education_split_screen_text" msgid="449233070804658627">"ସ୍ପ୍ଲିଟ ସ୍କ୍ରିନ ପାଇଁ ଅନ୍ୟ ଏକ ଆପକୁ ଡ୍ରାଗ କରନ୍ତୁ"</string>
@@ -122,8 +121,7 @@
<string name="handle_text" msgid="4419667835599523257">"ଆପର ହେଣ୍ଡେଲ"</string>
<string name="app_icon_text" msgid="2823268023931811747">"ଆପ ଆଇକନ"</string>
<string name="fullscreen_text" msgid="1162316685217676079">"ପୂର୍ଣ୍ଣସ୍କ୍ରିନ"</string>
- <!-- no translation found for desktop_text (9058641752519570266) -->
- <skip />
+ <string name="desktop_text" msgid="9058641752519570266">"ଡେସ୍କଟପ ୱିଣ୍ଡୋଇଂ"</string>
<string name="split_screen_text" msgid="1396336058129570886">"ସ୍ପ୍ଲିଟ ସ୍କ୍ରିନ"</string>
<string name="more_button_text" msgid="3655388105592893530">"ଅଧିକ"</string>
<string name="float_button_text" msgid="9221657008391364581">"ଫ୍ଲୋଟ"</string>
@@ -134,10 +132,11 @@
<string name="new_window_text" msgid="6318648868380652280">"ନୂଆ ୱିଣ୍ଡୋ"</string>
<string name="manage_windows_text" msgid="5567366688493093920">"ୱିଣ୍ଡୋଗୁଡ଼ିକୁ ପରିଚାଳନା କରନ୍ତୁ"</string>
<string name="change_aspect_ratio_text" msgid="9104456064548212806">"ଚଉଡ଼ା ଓ ଉଚ୍ଚତାର ଅନୁପାତ ପରିବର୍ତ୍ତନ କରନ୍ତୁ"</string>
+ <!-- no translation found for handle_menu_restart_text (3907767216238298098) -->
+ <skip />
<string name="close_text" msgid="4986518933445178928">"ବନ୍ଦ କରନ୍ତୁ"</string>
<string name="collapse_menu_text" msgid="7515008122450342029">"ମେନୁ ବନ୍ଦ କରନ୍ତୁ"</string>
- <!-- no translation found for desktop_mode_app_header_chip_text (7617377295944971651) -->
- <skip />
+ <string name="desktop_mode_app_header_chip_text" msgid="7617377295944971651">"<xliff:g id="APP_NAME">%1$s</xliff:g> (ଡେସ୍କଟପ ୱିଣ୍ଡୋଇଂ)"</string>
<string name="desktop_mode_maximize_menu_maximize_text" msgid="3275717276171114411">"ସ୍କ୍ରିନକୁ ବଡ଼ କରନ୍ତୁ"</string>
<string name="desktop_mode_maximize_menu_snap_text" msgid="5673738963174074006">"ରିସାଇଜ କରନ୍ତୁ"</string>
<string name="desktop_mode_non_resizable_snap_text" msgid="3771776422751387878">"ଆପକୁ ଏଠାକୁ ମୁଭ କରାଯାଇପାରିବ ନାହିଁ"</string>
diff --git a/libs/WindowManager/Shell/res/values-pa/strings.xml b/libs/WindowManager/Shell/res/values-pa/strings.xml
index 50e3cd6a3022..e074a073de00 100644
--- a/libs/WindowManager/Shell/res/values-pa/strings.xml
+++ b/libs/WindowManager/Shell/res/values-pa/strings.xml
@@ -132,6 +132,8 @@
<string name="new_window_text" msgid="6318648868380652280">"ਨਵੀਂ ਵਿੰਡੋ"</string>
<string name="manage_windows_text" msgid="5567366688493093920">"ਵਿੰਡੋਆਂ ਦਾ ਪ੍ਰਬੰਧਨ ਕਰੋ"</string>
<string name="change_aspect_ratio_text" msgid="9104456064548212806">"ਆਕਾਰ ਅਨੁਪਾਤ ਬਦਲੋ"</string>
+ <!-- no translation found for handle_menu_restart_text (3907767216238298098) -->
+ <skip />
<string name="close_text" msgid="4986518933445178928">"ਬੰਦ ਕਰੋ"</string>
<string name="collapse_menu_text" msgid="7515008122450342029">"ਮੀਨੂ ਬੰਦ ਕਰੋ"</string>
<string name="desktop_mode_app_header_chip_text" msgid="7617377295944971651">"<xliff:g id="APP_NAME">%1$s</xliff:g> (ਡੈਸਕਟਾਪ ਵਿੰਡੋ)"</string>
diff --git a/libs/WindowManager/Shell/res/values-pl/strings.xml b/libs/WindowManager/Shell/res/values-pl/strings.xml
index 58a691f83cca..861d94723317 100644
--- a/libs/WindowManager/Shell/res/values-pl/strings.xml
+++ b/libs/WindowManager/Shell/res/values-pl/strings.xml
@@ -100,8 +100,7 @@
<string name="camera_compat_treatment_applied_button_description" msgid="2944157113330703897">"Naprawa się nie udała?\nKliknij, aby cofnąć"</string>
<string name="camera_compat_dismiss_button_description" msgid="2795364433503817511">"Brak problemów z aparatem? Kliknij, aby zamknąć"</string>
<string name="windowing_app_handle_education_tooltip" msgid="2929643449849791854">"Tu znajdziesz menu aplikacji"</string>
- <!-- no translation found for windowing_desktop_mode_image_button_education_tooltip (7171915734817051666) -->
- <skip />
+ <string name="windowing_desktop_mode_image_button_education_tooltip" msgid="7171915734817051666">"Aby otworzyć kilka aplikacji jednocześnie, przejdź do trybu okien na pulpicie"</string>
<string name="windowing_desktop_mode_exit_education_tooltip" msgid="5225660258192054132">"Z menu aplikacji w każdej chwili możesz wrócić do pełnego ekranu"</string>
<string name="letterbox_education_dialog_title" msgid="7739895354143295358">"Zobacz i zrób więcej"</string>
<string name="letterbox_education_split_screen_text" msgid="449233070804658627">"Aby podzielić ekran, przeciągnij drugą aplikację"</string>
@@ -122,8 +121,7 @@
<string name="handle_text" msgid="4419667835599523257">"Uchwyt aplikacji"</string>
<string name="app_icon_text" msgid="2823268023931811747">"Ikona aplikacji"</string>
<string name="fullscreen_text" msgid="1162316685217676079">"Pełny ekran"</string>
- <!-- no translation found for desktop_text (9058641752519570266) -->
- <skip />
+ <string name="desktop_text" msgid="9058641752519570266">"Tryb okien na pulpicie"</string>
<string name="split_screen_text" msgid="1396336058129570886">"Podzielony ekran"</string>
<string name="more_button_text" msgid="3655388105592893530">"Więcej"</string>
<string name="float_button_text" msgid="9221657008391364581">"Pływające"</string>
@@ -134,10 +132,11 @@
<string name="new_window_text" msgid="6318648868380652280">"Nowe okno"</string>
<string name="manage_windows_text" msgid="5567366688493093920">"Zarządzaj oknami"</string>
<string name="change_aspect_ratio_text" msgid="9104456064548212806">"Zmień format obrazu"</string>
+ <!-- no translation found for handle_menu_restart_text (3907767216238298098) -->
+ <skip />
<string name="close_text" msgid="4986518933445178928">"Zamknij"</string>
<string name="collapse_menu_text" msgid="7515008122450342029">"Zamknij menu"</string>
- <!-- no translation found for desktop_mode_app_header_chip_text (7617377295944971651) -->
- <skip />
+ <string name="desktop_mode_app_header_chip_text" msgid="7617377295944971651">"<xliff:g id="APP_NAME">%1$s</xliff:g> (tryb okien na pulpicie)"</string>
<string name="desktop_mode_maximize_menu_maximize_text" msgid="3275717276171114411">"Maksymalizuj ekran"</string>
<string name="desktop_mode_maximize_menu_snap_text" msgid="5673738963174074006">"Zmień rozmiar"</string>
<string name="desktop_mode_non_resizable_snap_text" msgid="3771776422751387878">"Nie można przenieść aplikacji tutaj"</string>
diff --git a/libs/WindowManager/Shell/res/values-pt-rBR/strings.xml b/libs/WindowManager/Shell/res/values-pt-rBR/strings.xml
index 2d9bc2bc5b80..53db421ac0f0 100644
--- a/libs/WindowManager/Shell/res/values-pt-rBR/strings.xml
+++ b/libs/WindowManager/Shell/res/values-pt-rBR/strings.xml
@@ -100,8 +100,7 @@
<string name="camera_compat_treatment_applied_button_description" msgid="2944157113330703897">"O problema não foi corrigido?\nToque para reverter"</string>
<string name="camera_compat_dismiss_button_description" msgid="2795364433503817511">"Não tem problemas com a câmera? Toque para dispensar."</string>
<string name="windowing_app_handle_education_tooltip" msgid="2929643449849791854">"O menu do app está aqui"</string>
- <!-- no translation found for windowing_desktop_mode_image_button_education_tooltip (7171915734817051666) -->
- <skip />
+ <string name="windowing_desktop_mode_image_button_education_tooltip" msgid="7171915734817051666">"Abra vários apps ao mesmo tempo usando o modo janela para computador"</string>
<string name="windowing_desktop_mode_exit_education_tooltip" msgid="5225660258192054132">"Volte para a tela cheia a qualquer momento no menu do app"</string>
<string name="letterbox_education_dialog_title" msgid="7739895354143295358">"Veja e faça mais"</string>
<string name="letterbox_education_split_screen_text" msgid="449233070804658627">"Arraste outro app para dividir a tela"</string>
@@ -122,8 +121,7 @@
<string name="handle_text" msgid="4419667835599523257">"Identificador do app"</string>
<string name="app_icon_text" msgid="2823268023931811747">"Ícone do app"</string>
<string name="fullscreen_text" msgid="1162316685217676079">"Tela cheia"</string>
- <!-- no translation found for desktop_text (9058641752519570266) -->
- <skip />
+ <string name="desktop_text" msgid="9058641752519570266">"Modo janela para computador"</string>
<string name="split_screen_text" msgid="1396336058129570886">"Tela dividida"</string>
<string name="more_button_text" msgid="3655388105592893530">"Mais"</string>
<string name="float_button_text" msgid="9221657008391364581">"Ponto flutuante"</string>
@@ -134,10 +132,11 @@
<string name="new_window_text" msgid="6318648868380652280">"Nova janela"</string>
<string name="manage_windows_text" msgid="5567366688493093920">"Gerenciar janelas"</string>
<string name="change_aspect_ratio_text" msgid="9104456064548212806">"Mudar a proporção"</string>
+ <!-- no translation found for handle_menu_restart_text (3907767216238298098) -->
+ <skip />
<string name="close_text" msgid="4986518933445178928">"Fechar"</string>
<string name="collapse_menu_text" msgid="7515008122450342029">"Fechar menu"</string>
- <!-- no translation found for desktop_mode_app_header_chip_text (7617377295944971651) -->
- <skip />
+ <string name="desktop_mode_app_header_chip_text" msgid="7617377295944971651">"<xliff:g id="APP_NAME">%1$s</xliff:g> (modo janela para computador)"</string>
<string name="desktop_mode_maximize_menu_maximize_text" msgid="3275717276171114411">"Ampliar tela"</string>
<string name="desktop_mode_maximize_menu_snap_text" msgid="5673738963174074006">"Redimensionar"</string>
<string name="desktop_mode_non_resizable_snap_text" msgid="3771776422751387878">"Não é possível mover o app para cá"</string>
diff --git a/libs/WindowManager/Shell/res/values-pt-rPT/strings.xml b/libs/WindowManager/Shell/res/values-pt-rPT/strings.xml
index d5535183551e..5a4da3c07389 100644
--- a/libs/WindowManager/Shell/res/values-pt-rPT/strings.xml
+++ b/libs/WindowManager/Shell/res/values-pt-rPT/strings.xml
@@ -132,6 +132,8 @@
<string name="new_window_text" msgid="6318648868380652280">"Nova janela"</string>
<string name="manage_windows_text" msgid="5567366688493093920">"Gerir janelas"</string>
<string name="change_aspect_ratio_text" msgid="9104456064548212806">"Alterar formato"</string>
+ <!-- no translation found for handle_menu_restart_text (3907767216238298098) -->
+ <skip />
<string name="close_text" msgid="4986518933445178928">"Fechar"</string>
<string name="collapse_menu_text" msgid="7515008122450342029">"Fechar menu"</string>
<string name="desktop_mode_app_header_chip_text" msgid="7617377295944971651">"<xliff:g id="APP_NAME">%1$s</xliff:g> (janelas de computador)"</string>
diff --git a/libs/WindowManager/Shell/res/values-pt/strings.xml b/libs/WindowManager/Shell/res/values-pt/strings.xml
index 2d9bc2bc5b80..53db421ac0f0 100644
--- a/libs/WindowManager/Shell/res/values-pt/strings.xml
+++ b/libs/WindowManager/Shell/res/values-pt/strings.xml
@@ -100,8 +100,7 @@
<string name="camera_compat_treatment_applied_button_description" msgid="2944157113330703897">"O problema não foi corrigido?\nToque para reverter"</string>
<string name="camera_compat_dismiss_button_description" msgid="2795364433503817511">"Não tem problemas com a câmera? Toque para dispensar."</string>
<string name="windowing_app_handle_education_tooltip" msgid="2929643449849791854">"O menu do app está aqui"</string>
- <!-- no translation found for windowing_desktop_mode_image_button_education_tooltip (7171915734817051666) -->
- <skip />
+ <string name="windowing_desktop_mode_image_button_education_tooltip" msgid="7171915734817051666">"Abra vários apps ao mesmo tempo usando o modo janela para computador"</string>
<string name="windowing_desktop_mode_exit_education_tooltip" msgid="5225660258192054132">"Volte para a tela cheia a qualquer momento no menu do app"</string>
<string name="letterbox_education_dialog_title" msgid="7739895354143295358">"Veja e faça mais"</string>
<string name="letterbox_education_split_screen_text" msgid="449233070804658627">"Arraste outro app para dividir a tela"</string>
@@ -122,8 +121,7 @@
<string name="handle_text" msgid="4419667835599523257">"Identificador do app"</string>
<string name="app_icon_text" msgid="2823268023931811747">"Ícone do app"</string>
<string name="fullscreen_text" msgid="1162316685217676079">"Tela cheia"</string>
- <!-- no translation found for desktop_text (9058641752519570266) -->
- <skip />
+ <string name="desktop_text" msgid="9058641752519570266">"Modo janela para computador"</string>
<string name="split_screen_text" msgid="1396336058129570886">"Tela dividida"</string>
<string name="more_button_text" msgid="3655388105592893530">"Mais"</string>
<string name="float_button_text" msgid="9221657008391364581">"Ponto flutuante"</string>
@@ -134,10 +132,11 @@
<string name="new_window_text" msgid="6318648868380652280">"Nova janela"</string>
<string name="manage_windows_text" msgid="5567366688493093920">"Gerenciar janelas"</string>
<string name="change_aspect_ratio_text" msgid="9104456064548212806">"Mudar a proporção"</string>
+ <!-- no translation found for handle_menu_restart_text (3907767216238298098) -->
+ <skip />
<string name="close_text" msgid="4986518933445178928">"Fechar"</string>
<string name="collapse_menu_text" msgid="7515008122450342029">"Fechar menu"</string>
- <!-- no translation found for desktop_mode_app_header_chip_text (7617377295944971651) -->
- <skip />
+ <string name="desktop_mode_app_header_chip_text" msgid="7617377295944971651">"<xliff:g id="APP_NAME">%1$s</xliff:g> (modo janela para computador)"</string>
<string name="desktop_mode_maximize_menu_maximize_text" msgid="3275717276171114411">"Ampliar tela"</string>
<string name="desktop_mode_maximize_menu_snap_text" msgid="5673738963174074006">"Redimensionar"</string>
<string name="desktop_mode_non_resizable_snap_text" msgid="3771776422751387878">"Não é possível mover o app para cá"</string>
diff --git a/libs/WindowManager/Shell/res/values-ro/strings.xml b/libs/WindowManager/Shell/res/values-ro/strings.xml
index 286443c69d72..159040082a40 100644
--- a/libs/WindowManager/Shell/res/values-ro/strings.xml
+++ b/libs/WindowManager/Shell/res/values-ro/strings.xml
@@ -132,6 +132,8 @@
<string name="new_window_text" msgid="6318648868380652280">"Fereastră nouă"</string>
<string name="manage_windows_text" msgid="5567366688493093920">"Gestionează ferestrele"</string>
<string name="change_aspect_ratio_text" msgid="9104456064548212806">"Schimbă raportul de dimensiuni"</string>
+ <!-- no translation found for handle_menu_restart_text (3907767216238298098) -->
+ <skip />
<string name="close_text" msgid="4986518933445178928">"Închide"</string>
<string name="collapse_menu_text" msgid="7515008122450342029">"Închide meniul"</string>
<string name="desktop_mode_app_header_chip_text" msgid="7617377295944971651">"<xliff:g id="APP_NAME">%1$s</xliff:g> (ferestre pe desktop)"</string>
diff --git a/libs/WindowManager/Shell/res/values-ru/strings.xml b/libs/WindowManager/Shell/res/values-ru/strings.xml
index 472a239ca344..bd7fa6e72b35 100644
--- a/libs/WindowManager/Shell/res/values-ru/strings.xml
+++ b/libs/WindowManager/Shell/res/values-ru/strings.xml
@@ -132,6 +132,8 @@
<string name="new_window_text" msgid="6318648868380652280">"Новое окно"</string>
<string name="manage_windows_text" msgid="5567366688493093920">"Управление окнами"</string>
<string name="change_aspect_ratio_text" msgid="9104456064548212806">"Изменить соотношение сторон"</string>
+ <!-- no translation found for handle_menu_restart_text (3907767216238298098) -->
+ <skip />
<string name="close_text" msgid="4986518933445178928">"Закрыть"</string>
<string name="collapse_menu_text" msgid="7515008122450342029">"Закрыть меню"</string>
<string name="desktop_mode_app_header_chip_text" msgid="7617377295944971651">"<xliff:g id="APP_NAME">%1$s</xliff:g> (режим компьютерных окон)"</string>
diff --git a/libs/WindowManager/Shell/res/values-si/strings.xml b/libs/WindowManager/Shell/res/values-si/strings.xml
index 6c91955a425e..7a72f99034ac 100644
--- a/libs/WindowManager/Shell/res/values-si/strings.xml
+++ b/libs/WindowManager/Shell/res/values-si/strings.xml
@@ -132,6 +132,8 @@
<string name="new_window_text" msgid="6318648868380652280">"නව කවුළුව"</string>
<string name="manage_windows_text" msgid="5567366688493093920">"කවුළු කළමනාකරණය කරන්න"</string>
<string name="change_aspect_ratio_text" msgid="9104456064548212806">"දර්ශන අනුපාතය වෙනස් කරන්න"</string>
+ <!-- no translation found for handle_menu_restart_text (3907767216238298098) -->
+ <skip />
<string name="close_text" msgid="4986518933445178928">"වසන්න"</string>
<string name="collapse_menu_text" msgid="7515008122450342029">"මෙනුව වසන්න"</string>
<string name="desktop_mode_app_header_chip_text" msgid="7617377295944971651">"<xliff:g id="APP_NAME">%1$s</xliff:g> (ඩෙස්ක්ටොප් කවුළුකරණය)"</string>
diff --git a/libs/WindowManager/Shell/res/values-sk/strings.xml b/libs/WindowManager/Shell/res/values-sk/strings.xml
index 08404d016789..f0f3e50dccd4 100644
--- a/libs/WindowManager/Shell/res/values-sk/strings.xml
+++ b/libs/WindowManager/Shell/res/values-sk/strings.xml
@@ -132,6 +132,8 @@
<string name="new_window_text" msgid="6318648868380652280">"Nové okno"</string>
<string name="manage_windows_text" msgid="5567366688493093920">"Spravovať okná"</string>
<string name="change_aspect_ratio_text" msgid="9104456064548212806">"Zmeniť pomer strán"</string>
+ <!-- no translation found for handle_menu_restart_text (3907767216238298098) -->
+ <skip />
<string name="close_text" msgid="4986518933445178928">"Zavrieť"</string>
<string name="collapse_menu_text" msgid="7515008122450342029">"Zavrieť ponuku"</string>
<string name="desktop_mode_app_header_chip_text" msgid="7617377295944971651">"<xliff:g id="APP_NAME">%1$s</xliff:g> (windowing na pracovnej ploche)"</string>
diff --git a/libs/WindowManager/Shell/res/values-sl/strings.xml b/libs/WindowManager/Shell/res/values-sl/strings.xml
index deed0e0fe27a..d86cf6baca67 100644
--- a/libs/WindowManager/Shell/res/values-sl/strings.xml
+++ b/libs/WindowManager/Shell/res/values-sl/strings.xml
@@ -132,6 +132,8 @@
<string name="new_window_text" msgid="6318648868380652280">"Novo okno"</string>
<string name="manage_windows_text" msgid="5567366688493093920">"Upravljanje oken"</string>
<string name="change_aspect_ratio_text" msgid="9104456064548212806">"Sprememba razmerja stranic"</string>
+ <!-- no translation found for handle_menu_restart_text (3907767216238298098) -->
+ <skip />
<string name="close_text" msgid="4986518933445178928">"Zapri"</string>
<string name="collapse_menu_text" msgid="7515008122450342029">"Zapri meni"</string>
<string name="desktop_mode_app_header_chip_text" msgid="7617377295944971651">"<xliff:g id="APP_NAME">%1$s</xliff:g> (namizni način prikaza več oken hkrati)"</string>
diff --git a/libs/WindowManager/Shell/res/values-sq/strings.xml b/libs/WindowManager/Shell/res/values-sq/strings.xml
index c6b8c6da56c2..ca4fe6fd3615 100644
--- a/libs/WindowManager/Shell/res/values-sq/strings.xml
+++ b/libs/WindowManager/Shell/res/values-sq/strings.xml
@@ -132,6 +132,8 @@
<string name="new_window_text" msgid="6318648868380652280">"Dritare e re"</string>
<string name="manage_windows_text" msgid="5567366688493093920">"Menaxho dritaret"</string>
<string name="change_aspect_ratio_text" msgid="9104456064548212806">"Ndrysho raportin e pamjes"</string>
+ <!-- no translation found for handle_menu_restart_text (3907767216238298098) -->
+ <skip />
<string name="close_text" msgid="4986518933445178928">"Mbyll"</string>
<string name="collapse_menu_text" msgid="7515008122450342029">"Mbyll menynë"</string>
<string name="desktop_mode_app_header_chip_text" msgid="7617377295944971651">"<xliff:g id="APP_NAME">%1$s</xliff:g> (ndërfaqja me dritare në desktop)"</string>
diff --git a/libs/WindowManager/Shell/res/values-sr/strings.xml b/libs/WindowManager/Shell/res/values-sr/strings.xml
index 3fe25f9d3d9e..58d9398d8d6c 100644
--- a/libs/WindowManager/Shell/res/values-sr/strings.xml
+++ b/libs/WindowManager/Shell/res/values-sr/strings.xml
@@ -132,6 +132,8 @@
<string name="new_window_text" msgid="6318648868380652280">"Нови прозор"</string>
<string name="manage_windows_text" msgid="5567366688493093920">"Управљајте прозорима"</string>
<string name="change_aspect_ratio_text" msgid="9104456064548212806">"Промени размеру"</string>
+ <!-- no translation found for handle_menu_restart_text (3907767216238298098) -->
+ <skip />
<string name="close_text" msgid="4986518933445178928">"Затворите"</string>
<string name="collapse_menu_text" msgid="7515008122450342029">"Затворите мени"</string>
<string name="desktop_mode_app_header_chip_text" msgid="7617377295944971651">"<xliff:g id="APP_NAME">%1$s</xliff:g> (прозорски приказ за рачунаре)"</string>
diff --git a/libs/WindowManager/Shell/res/values-sv/strings.xml b/libs/WindowManager/Shell/res/values-sv/strings.xml
index 404bdaf6294d..5231a673d1f6 100644
--- a/libs/WindowManager/Shell/res/values-sv/strings.xml
+++ b/libs/WindowManager/Shell/res/values-sv/strings.xml
@@ -132,6 +132,8 @@
<string name="new_window_text" msgid="6318648868380652280">"Nytt fönster"</string>
<string name="manage_windows_text" msgid="5567366688493093920">"Hantera fönster"</string>
<string name="change_aspect_ratio_text" msgid="9104456064548212806">"Ändra bildformat"</string>
+ <!-- no translation found for handle_menu_restart_text (3907767216238298098) -->
+ <skip />
<string name="close_text" msgid="4986518933445178928">"Stäng"</string>
<string name="collapse_menu_text" msgid="7515008122450342029">"Stäng menyn"</string>
<string name="desktop_mode_app_header_chip_text" msgid="7617377295944971651">"<xliff:g id="APP_NAME">%1$s</xliff:g> (fönsterstapling)"</string>
diff --git a/libs/WindowManager/Shell/res/values-sw/strings.xml b/libs/WindowManager/Shell/res/values-sw/strings.xml
index 3bd7988874b8..9c3c10734a00 100644
--- a/libs/WindowManager/Shell/res/values-sw/strings.xml
+++ b/libs/WindowManager/Shell/res/values-sw/strings.xml
@@ -132,6 +132,8 @@
<string name="new_window_text" msgid="6318648868380652280">"Dirisha Jipya"</string>
<string name="manage_windows_text" msgid="5567366688493093920">"Dhibiti Windows"</string>
<string name="change_aspect_ratio_text" msgid="9104456064548212806">"Badilisha uwiano"</string>
+ <!-- no translation found for handle_menu_restart_text (3907767216238298098) -->
+ <skip />
<string name="close_text" msgid="4986518933445178928">"Funga"</string>
<string name="collapse_menu_text" msgid="7515008122450342029">"Funga Menyu"</string>
<string name="desktop_mode_app_header_chip_text" msgid="7617377295944971651">"<xliff:g id="APP_NAME">%1$s</xliff:g> (Kupanga madirisha ya kompyuta ya mezani)"</string>
diff --git a/libs/WindowManager/Shell/res/values-ta/strings.xml b/libs/WindowManager/Shell/res/values-ta/strings.xml
index 12780dfd1747..811fce3b2cb1 100644
--- a/libs/WindowManager/Shell/res/values-ta/strings.xml
+++ b/libs/WindowManager/Shell/res/values-ta/strings.xml
@@ -132,6 +132,8 @@
<string name="new_window_text" msgid="6318648868380652280">"புதிய சாளரம்"</string>
<string name="manage_windows_text" msgid="5567366688493093920">"சாளரங்களை நிர்வகிக்கலாம்"</string>
<string name="change_aspect_ratio_text" msgid="9104456064548212806">"தோற்ற விகிதத்தை மாற்று"</string>
+ <!-- no translation found for handle_menu_restart_text (3907767216238298098) -->
+ <skip />
<string name="close_text" msgid="4986518933445178928">"மூடும்"</string>
<string name="collapse_menu_text" msgid="7515008122450342029">"மெனுவை மூடும்"</string>
<string name="desktop_mode_app_header_chip_text" msgid="7617377295944971651">"<xliff:g id="APP_NAME">%1$s</xliff:g> (டெஸ்க்டாப் சாளரமாக்குதல்)"</string>
diff --git a/libs/WindowManager/Shell/res/values-te/strings.xml b/libs/WindowManager/Shell/res/values-te/strings.xml
index 2044fe70c7c3..7a809f4d4684 100644
--- a/libs/WindowManager/Shell/res/values-te/strings.xml
+++ b/libs/WindowManager/Shell/res/values-te/strings.xml
@@ -132,6 +132,8 @@
<string name="new_window_text" msgid="6318648868380652280">"కొత్త విండో"</string>
<string name="manage_windows_text" msgid="5567366688493093920">"విండోలను మేనేజ్ చేయండి"</string>
<string name="change_aspect_ratio_text" msgid="9104456064548212806">"ఆకార నిష్పత్తిని మార్చండి"</string>
+ <!-- no translation found for handle_menu_restart_text (3907767216238298098) -->
+ <skip />
<string name="close_text" msgid="4986518933445178928">"మూసివేయండి"</string>
<string name="collapse_menu_text" msgid="7515008122450342029">"మెనూను మూసివేయండి"</string>
<string name="desktop_mode_app_header_chip_text" msgid="7617377295944971651">"<xliff:g id="APP_NAME">%1$s</xliff:g> (డెస్క్‌టాప్ వీక్షణ)"</string>
diff --git a/libs/WindowManager/Shell/res/values-th/strings.xml b/libs/WindowManager/Shell/res/values-th/strings.xml
index 60632ada32bb..66996356587e 100644
--- a/libs/WindowManager/Shell/res/values-th/strings.xml
+++ b/libs/WindowManager/Shell/res/values-th/strings.xml
@@ -100,8 +100,7 @@
<string name="camera_compat_treatment_applied_button_description" msgid="2944157113330703897">"หากไม่ได้แก้ไข\nแตะเพื่อเปลี่ยนกลับ"</string>
<string name="camera_compat_dismiss_button_description" msgid="2795364433503817511">"หากไม่พบปัญหากับกล้อง แตะเพื่อปิด"</string>
<string name="windowing_app_handle_education_tooltip" msgid="2929643449849791854">"ดูเมนูแอปที่นี่ได้"</string>
- <!-- no translation found for windowing_desktop_mode_image_button_education_tooltip (7171915734817051666) -->
- <skip />
+ <string name="windowing_desktop_mode_image_button_education_tooltip" msgid="7171915734817051666">"เข้าสู่หน้าต่างเดสก์ท็อปเพื่อเปิดหลายแอปพร้อมกัน"</string>
<string name="windowing_desktop_mode_exit_education_tooltip" msgid="5225660258192054132">"กลับไปที่โหมดเต็มหน้าจอได้ทุกเมื่อจากเมนูแอป"</string>
<string name="letterbox_education_dialog_title" msgid="7739895354143295358">"รับชมและทำสิ่งต่างๆ ได้มากขึ้น"</string>
<string name="letterbox_education_split_screen_text" msgid="449233070804658627">"ลากไปไว้ในแอปอื่นเพื่อแยกหน้าจอ"</string>
@@ -122,8 +121,7 @@
<string name="handle_text" msgid="4419667835599523257">"แฮนเดิลแอป"</string>
<string name="app_icon_text" msgid="2823268023931811747">"ไอคอนแอป"</string>
<string name="fullscreen_text" msgid="1162316685217676079">"เต็มหน้าจอ"</string>
- <!-- no translation found for desktop_text (9058641752519570266) -->
- <skip />
+ <string name="desktop_text" msgid="9058641752519570266">"หน้าต่างเดสก์ท็อป"</string>
<string name="split_screen_text" msgid="1396336058129570886">"แยกหน้าจอ"</string>
<string name="more_button_text" msgid="3655388105592893530">"เพิ่มเติม"</string>
<string name="float_button_text" msgid="9221657008391364581">"ล่องลอย"</string>
@@ -134,10 +132,11 @@
<string name="new_window_text" msgid="6318648868380652280">"หน้าต่างใหม่"</string>
<string name="manage_windows_text" msgid="5567366688493093920">"จัดการหน้าต่าง"</string>
<string name="change_aspect_ratio_text" msgid="9104456064548212806">"เปลี่ยนสัดส่วนการแสดงผล"</string>
+ <!-- no translation found for handle_menu_restart_text (3907767216238298098) -->
+ <skip />
<string name="close_text" msgid="4986518933445178928">"ปิด"</string>
<string name="collapse_menu_text" msgid="7515008122450342029">"ปิดเมนู"</string>
- <!-- no translation found for desktop_mode_app_header_chip_text (7617377295944971651) -->
- <skip />
+ <string name="desktop_mode_app_header_chip_text" msgid="7617377295944971651">"<xliff:g id="APP_NAME">%1$s</xliff:g> (หน้าต่างเดสก์ท็อป)"</string>
<string name="desktop_mode_maximize_menu_maximize_text" msgid="3275717276171114411">"ขยายหน้าจอให้ใหญ่สุด"</string>
<string name="desktop_mode_maximize_menu_snap_text" msgid="5673738963174074006">"ปรับขนาด"</string>
<string name="desktop_mode_non_resizable_snap_text" msgid="3771776422751387878">"ย้ายแอปมาที่นี่ไม่ได้"</string>
diff --git a/libs/WindowManager/Shell/res/values-tl/strings.xml b/libs/WindowManager/Shell/res/values-tl/strings.xml
index 586d655d7901..82c085bcdbe7 100644
--- a/libs/WindowManager/Shell/res/values-tl/strings.xml
+++ b/libs/WindowManager/Shell/res/values-tl/strings.xml
@@ -132,6 +132,8 @@
<string name="new_window_text" msgid="6318648868380652280">"Bagong Window"</string>
<string name="manage_windows_text" msgid="5567366688493093920">"Pamahalaan ang Mga Window"</string>
<string name="change_aspect_ratio_text" msgid="9104456064548212806">"Baguhin ang aspect ratio"</string>
+ <!-- no translation found for handle_menu_restart_text (3907767216238298098) -->
+ <skip />
<string name="close_text" msgid="4986518933445178928">"Isara"</string>
<string name="collapse_menu_text" msgid="7515008122450342029">"Isara ang Menu"</string>
<string name="desktop_mode_app_header_chip_text" msgid="7617377295944971651">"<xliff:g id="APP_NAME">%1$s</xliff:g> (Desktop windowing)"</string>
diff --git a/libs/WindowManager/Shell/res/values-tr/strings.xml b/libs/WindowManager/Shell/res/values-tr/strings.xml
index 9605acfb9a8b..4d6775a9102d 100644
--- a/libs/WindowManager/Shell/res/values-tr/strings.xml
+++ b/libs/WindowManager/Shell/res/values-tr/strings.xml
@@ -132,6 +132,8 @@
<string name="new_window_text" msgid="6318648868380652280">"Yeni Pencere"</string>
<string name="manage_windows_text" msgid="5567366688493093920">"Pencereleri yönet"</string>
<string name="change_aspect_ratio_text" msgid="9104456064548212806">"En boy oranını değiştir"</string>
+ <!-- no translation found for handle_menu_restart_text (3907767216238298098) -->
+ <skip />
<string name="close_text" msgid="4986518933445178928">"Kapat"</string>
<string name="collapse_menu_text" msgid="7515008122450342029">"Menüyü kapat"</string>
<string name="desktop_mode_app_header_chip_text" msgid="7617377295944971651">"<xliff:g id="APP_NAME">%1$s</xliff:g> (masaüstü pencereleme)"</string>
diff --git a/libs/WindowManager/Shell/res/values-uk/strings.xml b/libs/WindowManager/Shell/res/values-uk/strings.xml
index 54af06762029..4b2aad06cec6 100644
--- a/libs/WindowManager/Shell/res/values-uk/strings.xml
+++ b/libs/WindowManager/Shell/res/values-uk/strings.xml
@@ -100,8 +100,7 @@
<string name="camera_compat_treatment_applied_button_description" msgid="2944157113330703897">"Проблему не вирішено?\nНатисніть, щоб скасувати зміни"</string>
<string name="camera_compat_dismiss_button_description" msgid="2795364433503817511">"Немає проблем із камерою? Торкніться, щоб закрити."</string>
<string name="windowing_app_handle_education_tooltip" msgid="2929643449849791854">"Тут ви знайдете меню додатка"</string>
- <!-- no translation found for windowing_desktop_mode_image_button_education_tooltip (7171915734817051666) -->
- <skip />
+ <string name="windowing_desktop_mode_image_button_education_tooltip" msgid="7171915734817051666">"Щоб відкрити кілька додатків одночасно, перейдіть у режим вікон робочого стола"</string>
<string name="windowing_desktop_mode_exit_education_tooltip" msgid="5225660258192054132">"З меню додатка можна будь-коли повернутися в повноекранний режим"</string>
<string name="letterbox_education_dialog_title" msgid="7739895354143295358">"Більше простору та можливостей"</string>
<string name="letterbox_education_split_screen_text" msgid="449233070804658627">"Щоб перейти в режим розділення екрана, перетягніть сюди інший додаток"</string>
@@ -122,8 +121,7 @@
<string name="handle_text" msgid="4419667835599523257">"Дескриптор додатка"</string>
<string name="app_icon_text" msgid="2823268023931811747">"Значок додатка"</string>
<string name="fullscreen_text" msgid="1162316685217676079">"На весь екран"</string>
- <!-- no translation found for desktop_text (9058641752519570266) -->
- <skip />
+ <string name="desktop_text" msgid="9058641752519570266">"Режим вікон робочого стола"</string>
<string name="split_screen_text" msgid="1396336058129570886">"Розділити екран"</string>
<string name="more_button_text" msgid="3655388105592893530">"Більше"</string>
<string name="float_button_text" msgid="9221657008391364581">"Плаваюче вікно"</string>
@@ -134,10 +132,11 @@
<string name="new_window_text" msgid="6318648868380652280">"Нове вікно"</string>
<string name="manage_windows_text" msgid="5567366688493093920">"Керувати вікнами"</string>
<string name="change_aspect_ratio_text" msgid="9104456064548212806">"Змінити формат"</string>
+ <!-- no translation found for handle_menu_restart_text (3907767216238298098) -->
+ <skip />
<string name="close_text" msgid="4986518933445178928">"Закрити"</string>
<string name="collapse_menu_text" msgid="7515008122450342029">"Закрити меню"</string>
- <!-- no translation found for desktop_mode_app_header_chip_text (7617377295944971651) -->
- <skip />
+ <string name="desktop_mode_app_header_chip_text" msgid="7617377295944971651">"<xliff:g id="APP_NAME">%1$s</xliff:g> (режим вікон робочого стола)"</string>
<string name="desktop_mode_maximize_menu_maximize_text" msgid="3275717276171114411">"Розгорнути екран"</string>
<string name="desktop_mode_maximize_menu_snap_text" msgid="5673738963174074006">"Змінити розмір"</string>
<string name="desktop_mode_non_resizable_snap_text" msgid="3771776422751387878">"Сюди не можна перемістити додаток"</string>
diff --git a/libs/WindowManager/Shell/res/values-ur/strings.xml b/libs/WindowManager/Shell/res/values-ur/strings.xml
index 9614ce9112f7..f9972d229062 100644
--- a/libs/WindowManager/Shell/res/values-ur/strings.xml
+++ b/libs/WindowManager/Shell/res/values-ur/strings.xml
@@ -132,6 +132,8 @@
<string name="new_window_text" msgid="6318648868380652280">"نئی ونڈو"</string>
<string name="manage_windows_text" msgid="5567366688493093920">"ونڈوز کا نظم کریں"</string>
<string name="change_aspect_ratio_text" msgid="9104456064548212806">"تناسبی شرح کو تبدیل کریں"</string>
+ <!-- no translation found for handle_menu_restart_text (3907767216238298098) -->
+ <skip />
<string name="close_text" msgid="4986518933445178928">"بند کریں"</string>
<string name="collapse_menu_text" msgid="7515008122450342029">"مینیو بند کریں"</string>
<string name="desktop_mode_app_header_chip_text" msgid="7617377295944971651">"<xliff:g id="APP_NAME">%1$s</xliff:g> (ڈیسک ٹاپ ونڈوئنگ)"</string>
diff --git a/libs/WindowManager/Shell/res/values-uz/strings.xml b/libs/WindowManager/Shell/res/values-uz/strings.xml
index 6025467ea44b..231cb738940b 100644
--- a/libs/WindowManager/Shell/res/values-uz/strings.xml
+++ b/libs/WindowManager/Shell/res/values-uz/strings.xml
@@ -132,6 +132,8 @@
<string name="new_window_text" msgid="6318648868380652280">"Yangi oyna"</string>
<string name="manage_windows_text" msgid="5567366688493093920">"Oynalarni boshqarish"</string>
<string name="change_aspect_ratio_text" msgid="9104456064548212806">"Tomonlar nisbatini oʻzgartirish"</string>
+ <!-- no translation found for handle_menu_restart_text (3907767216238298098) -->
+ <skip />
<string name="close_text" msgid="4986518933445178928">"Yopish"</string>
<string name="collapse_menu_text" msgid="7515008122450342029">"Menyuni yopish"</string>
<string name="desktop_mode_app_header_chip_text" msgid="7617377295944971651">"<xliff:g id="APP_NAME">%1$s</xliff:g> (Desktop rejimidagi oynalar)"</string>
diff --git a/libs/WindowManager/Shell/res/values-vi/strings.xml b/libs/WindowManager/Shell/res/values-vi/strings.xml
index 4c394b2aec46..88ef07186dab 100644
--- a/libs/WindowManager/Shell/res/values-vi/strings.xml
+++ b/libs/WindowManager/Shell/res/values-vi/strings.xml
@@ -121,7 +121,7 @@
<string name="handle_text" msgid="4419667835599523257">"Ô điều khiển ứng dụng"</string>
<string name="app_icon_text" msgid="2823268023931811747">"Biểu tượng ứng dụng"</string>
<string name="fullscreen_text" msgid="1162316685217676079">"Toàn màn hình"</string>
- <string name="desktop_text" msgid="9058641752519570266">"Cửa sổ trên máy tính"</string>
+ <string name="desktop_text" msgid="9058641752519570266">"Chế độ cửa sổ trên máy tính"</string>
<string name="split_screen_text" msgid="1396336058129570886">"Chia đôi màn hình"</string>
<string name="more_button_text" msgid="3655388105592893530">"Tuỳ chọn khác"</string>
<string name="float_button_text" msgid="9221657008391364581">"Nổi"</string>
@@ -132,6 +132,8 @@
<string name="new_window_text" msgid="6318648868380652280">"Cửa sổ mới"</string>
<string name="manage_windows_text" msgid="5567366688493093920">"Quản lý cửa sổ"</string>
<string name="change_aspect_ratio_text" msgid="9104456064548212806">"Thay đổi tỷ lệ khung hình"</string>
+ <!-- no translation found for handle_menu_restart_text (3907767216238298098) -->
+ <skip />
<string name="close_text" msgid="4986518933445178928">"Đóng"</string>
<string name="collapse_menu_text" msgid="7515008122450342029">"Đóng trình đơn"</string>
<string name="desktop_mode_app_header_chip_text" msgid="7617377295944971651">"<xliff:g id="APP_NAME">%1$s</xliff:g> (Chế độ cửa sổ trên máy tính)"</string>
diff --git a/libs/WindowManager/Shell/res/values-zh-rCN/strings.xml b/libs/WindowManager/Shell/res/values-zh-rCN/strings.xml
index b29711df14b9..a07767d0d09a 100644
--- a/libs/WindowManager/Shell/res/values-zh-rCN/strings.xml
+++ b/libs/WindowManager/Shell/res/values-zh-rCN/strings.xml
@@ -100,8 +100,7 @@
<string name="camera_compat_treatment_applied_button_description" msgid="2944157113330703897">"没有解决此问题?\n点按即可恢复"</string>
<string name="camera_compat_dismiss_button_description" msgid="2795364433503817511">"相机没有问题?点按即可忽略。"</string>
<string name="windowing_app_handle_education_tooltip" msgid="2929643449849791854">"您可以在此处找到应用菜单"</string>
- <!-- no translation found for windowing_desktop_mode_image_button_education_tooltip (7171915734817051666) -->
- <skip />
+ <string name="windowing_desktop_mode_image_button_education_tooltip" msgid="7171915734817051666">"进入桌面设备窗口化模式可同时打开多个应用"</string>
<string name="windowing_desktop_mode_exit_education_tooltip" msgid="5225660258192054132">"随时从应用菜单返回全屏模式"</string>
<string name="letterbox_education_dialog_title" msgid="7739895354143295358">"查看和处理更多任务"</string>
<string name="letterbox_education_split_screen_text" msgid="449233070804658627">"拖入另一个应用,即可使用分屏模式"</string>
@@ -122,8 +121,7 @@
<string name="handle_text" msgid="4419667835599523257">"应用手柄"</string>
<string name="app_icon_text" msgid="2823268023931811747">"应用图标"</string>
<string name="fullscreen_text" msgid="1162316685217676079">"全屏"</string>
- <!-- no translation found for desktop_text (9058641752519570266) -->
- <skip />
+ <string name="desktop_text" msgid="9058641752519570266">"桌面设备窗口化"</string>
<string name="split_screen_text" msgid="1396336058129570886">"分屏"</string>
<string name="more_button_text" msgid="3655388105592893530">"更多"</string>
<string name="float_button_text" msgid="9221657008391364581">"悬浮"</string>
@@ -134,10 +132,11 @@
<string name="new_window_text" msgid="6318648868380652280">"新窗口"</string>
<string name="manage_windows_text" msgid="5567366688493093920">"管理窗口"</string>
<string name="change_aspect_ratio_text" msgid="9104456064548212806">"更改宽高比"</string>
+ <!-- no translation found for handle_menu_restart_text (3907767216238298098) -->
+ <skip />
<string name="close_text" msgid="4986518933445178928">"关闭"</string>
<string name="collapse_menu_text" msgid="7515008122450342029">"关闭菜单"</string>
- <!-- no translation found for desktop_mode_app_header_chip_text (7617377295944971651) -->
- <skip />
+ <string name="desktop_mode_app_header_chip_text" msgid="7617377295944971651">"<xliff:g id="APP_NAME">%1$s</xliff:g>(桌面设备窗口化)"</string>
<string name="desktop_mode_maximize_menu_maximize_text" msgid="3275717276171114411">"最大化屏幕"</string>
<string name="desktop_mode_maximize_menu_snap_text" msgid="5673738963174074006">"调整大小"</string>
<string name="desktop_mode_non_resizable_snap_text" msgid="3771776422751387878">"无法将应用移至此处"</string>
diff --git a/libs/WindowManager/Shell/res/values-zh-rHK/strings.xml b/libs/WindowManager/Shell/res/values-zh-rHK/strings.xml
index fda5c744eccf..103ee600ff60 100644
--- a/libs/WindowManager/Shell/res/values-zh-rHK/strings.xml
+++ b/libs/WindowManager/Shell/res/values-zh-rHK/strings.xml
@@ -100,7 +100,7 @@
<string name="camera_compat_treatment_applied_button_description" msgid="2944157113330703897">"未能修正問題?\n輕按即可還原"</string>
<string name="camera_compat_dismiss_button_description" msgid="2795364433503817511">"相機冇問題?㩒一下就可以即可閂咗佢。"</string>
<string name="windowing_app_handle_education_tooltip" msgid="2929643449849791854">"你可在這裡找到應用程式選單"</string>
- <string name="windowing_desktop_mode_image_button_education_tooltip" msgid="7171915734817051666">"進入電腦分割視窗模式可同時開啟多個應用程式"</string>
+ <string name="windowing_desktop_mode_image_button_education_tooltip" msgid="7171915734817051666">"進入桌面電腦視窗模式以同時開啟多個應用程式"</string>
<string name="windowing_desktop_mode_exit_education_tooltip" msgid="5225660258192054132">"你可隨時從應用程式選單返回全螢幕"</string>
<string name="letterbox_education_dialog_title" msgid="7739895354143295358">"瀏覽更多內容及執行更多操作"</string>
<string name="letterbox_education_split_screen_text" msgid="449233070804658627">"拖入另一個應用程式即可分割螢幕"</string>
@@ -121,7 +121,7 @@
<string name="handle_text" msgid="4419667835599523257">"應用程式控點"</string>
<string name="app_icon_text" msgid="2823268023931811747">"應用程式圖示"</string>
<string name="fullscreen_text" msgid="1162316685217676079">"全螢幕"</string>
- <string name="desktop_text" msgid="9058641752519570266">"電腦分割視窗"</string>
+ <string name="desktop_text" msgid="9058641752519570266">"桌面電腦視窗模式"</string>
<string name="split_screen_text" msgid="1396336058129570886">"分割螢幕"</string>
<string name="more_button_text" msgid="3655388105592893530">"更多"</string>
<string name="float_button_text" msgid="9221657008391364581">"浮動"</string>
@@ -132,9 +132,11 @@
<string name="new_window_text" msgid="6318648868380652280">"新視窗"</string>
<string name="manage_windows_text" msgid="5567366688493093920">"管理視窗"</string>
<string name="change_aspect_ratio_text" msgid="9104456064548212806">"變更長寬比"</string>
+ <!-- no translation found for handle_menu_restart_text (3907767216238298098) -->
+ <skip />
<string name="close_text" msgid="4986518933445178928">"關閉"</string>
<string name="collapse_menu_text" msgid="7515008122450342029">"關閉選單"</string>
- <string name="desktop_mode_app_header_chip_text" msgid="7617377295944971651">"<xliff:g id="APP_NAME">%1$s</xliff:g> (電腦分割視窗)"</string>
+ <string name="desktop_mode_app_header_chip_text" msgid="7617377295944971651">"<xliff:g id="APP_NAME">%1$s</xliff:g> (桌面電腦視窗模式)"</string>
<string name="desktop_mode_maximize_menu_maximize_text" msgid="3275717276171114411">"畫面最大化"</string>
<string name="desktop_mode_maximize_menu_snap_text" msgid="5673738963174074006">"調整大小"</string>
<string name="desktop_mode_non_resizable_snap_text" msgid="3771776422751387878">"應用程式無法移至這裡"</string>
diff --git a/libs/WindowManager/Shell/res/values-zh-rTW/strings.xml b/libs/WindowManager/Shell/res/values-zh-rTW/strings.xml
index e83c647b59bb..a3d81fc6f4f0 100644
--- a/libs/WindowManager/Shell/res/values-zh-rTW/strings.xml
+++ b/libs/WindowManager/Shell/res/values-zh-rTW/strings.xml
@@ -100,7 +100,7 @@
<string name="camera_compat_treatment_applied_button_description" msgid="2944157113330703897">"未修正問題嗎?\n輕觸即可還原"</string>
<string name="camera_compat_dismiss_button_description" msgid="2795364433503817511">"相機沒問題嗎?輕觸即可關閉。"</string>
<string name="windowing_app_handle_education_tooltip" msgid="2929643449849791854">"你可以在這裡查看應用程式選單"</string>
- <string name="windowing_desktop_mode_image_button_education_tooltip" msgid="7171915734817051666">"進入電腦分割視窗模式可同時開啟多個應用程式"</string>
+ <string name="windowing_desktop_mode_image_button_education_tooltip" msgid="7171915734817051666">"進入電腦分割視窗模式後,可同時開啟多個應用程式"</string>
<string name="windowing_desktop_mode_exit_education_tooltip" msgid="5225660258192054132">"你隨時可以從應用程式選單返回全螢幕模式"</string>
<string name="letterbox_education_dialog_title" msgid="7739895354143295358">"瀏覽更多內容及執行更多操作"</string>
<string name="letterbox_education_split_screen_text" msgid="449233070804658627">"拖進另一個應用程式即可使用分割畫面模式"</string>
@@ -132,6 +132,8 @@
<string name="new_window_text" msgid="6318648868380652280">"新視窗"</string>
<string name="manage_windows_text" msgid="5567366688493093920">"管理視窗"</string>
<string name="change_aspect_ratio_text" msgid="9104456064548212806">"變更顯示比例"</string>
+ <!-- no translation found for handle_menu_restart_text (3907767216238298098) -->
+ <skip />
<string name="close_text" msgid="4986518933445178928">"關閉"</string>
<string name="collapse_menu_text" msgid="7515008122450342029">"關閉選單"</string>
<string name="desktop_mode_app_header_chip_text" msgid="7617377295944971651">"<xliff:g id="APP_NAME">%1$s</xliff:g> (電腦分割視窗)"</string>
diff --git a/libs/WindowManager/Shell/res/values-zu/strings.xml b/libs/WindowManager/Shell/res/values-zu/strings.xml
index 4d658f291e02..81d9200d6938 100644
--- a/libs/WindowManager/Shell/res/values-zu/strings.xml
+++ b/libs/WindowManager/Shell/res/values-zu/strings.xml
@@ -132,6 +132,8 @@
<string name="new_window_text" msgid="6318648868380652280">"Iwindi Elisha"</string>
<string name="manage_windows_text" msgid="5567366688493093920">"Phatha Amawindi"</string>
<string name="change_aspect_ratio_text" msgid="9104456064548212806">"Shintsha ukubukeka kwesilinganiselo"</string>
+ <!-- no translation found for handle_menu_restart_text (3907767216238298098) -->
+ <skip />
<string name="close_text" msgid="4986518933445178928">"Vala"</string>
<string name="collapse_menu_text" msgid="7515008122450342029">"Vala Imenyu"</string>
<string name="desktop_mode_app_header_chip_text" msgid="7617377295944971651">"<xliff:g id="APP_NAME">%1$s</xliff:g> (Ukwenziwa kwamawindi amaningi kwedeskithophu)"</string>
diff --git a/libs/WindowManager/Shell/res/values/colors.xml b/libs/WindowManager/Shell/res/values/colors.xml
index 8d18f959951b..5732fc936b47 100644
--- a/libs/WindowManager/Shell/res/values/colors.xml
+++ b/libs/WindowManager/Shell/res/values/colors.xml
@@ -68,8 +68,6 @@
<color name="desktop_mode_caption_button_on_hover_light">#11000000</color>
<color name="desktop_mode_caption_button_on_hover_dark">#11FFFFFF</color>
<color name="desktop_mode_caption_button">#00000000</color>
- <color name="tiling_divider_background_light">#C9C7B6</color>
- <color name="tiling_divider_background_dark">#4A4739</color>
<color name="tiling_handle_background_light">#000000</color>
<color name="tiling_handle_background_dark">#FFFFFF</color>
</resources>
diff --git a/libs/WindowManager/Shell/res/values/dimen.xml b/libs/WindowManager/Shell/res/values/dimen.xml
index 733f3bb8d6d0..ca18c97f9127 100644
--- a/libs/WindowManager/Shell/res/values/dimen.xml
+++ b/libs/WindowManager/Shell/res/values/dimen.xml
@@ -304,6 +304,8 @@
<dimen name="bubble_transform_area_width">140dp</dimen>
<!-- Width of the box at the corner of the screen where drag leads to app moving to bubble -->
<dimen name="bubble_transform_area_height">140dp</dimen>
+ <!-- How much elevation a bubble ui needs when dragged, must be above drop target & dismiss. -->
+ <dimen name="dragged_bubble_elevation">3dp</dimen>
<!-- Bottom and end margin for compat buttons. -->
<dimen name="compat_button_margin">24dp</dimen>
diff --git a/libs/WindowManager/Shell/res/values/styles.xml b/libs/WindowManager/Shell/res/values/styles.xml
index 08cda7b94a78..086c8a5651c3 100644
--- a/libs/WindowManager/Shell/res/values/styles.xml
+++ b/libs/WindowManager/Shell/res/values/styles.xml
@@ -51,7 +51,6 @@
<item name="android:clickable">true</item>
<item name="android:focusable">true</item>
<item name="android:orientation">horizontal</item>
- <item name="android:background">?android:attr/selectableItemBackground</item>
</style>
<style name="DesktopModeHandleMenuActionButtonImage">
diff --git a/libs/WindowManager/Shell/shared/res/values/dimen.xml b/libs/WindowManager/Shell/shared/res/values/dimen.xml
index 3b504cf713f1..74b6023bde36 100644
--- a/libs/WindowManager/Shell/shared/res/values/dimen.xml
+++ b/libs/WindowManager/Shell/shared/res/values/dimen.xml
@@ -39,9 +39,9 @@
<dimen name="drag_zone_v_split_from_expanded_view_height_fold_short">100dp</dimen>
<!-- Bubble drop target dimensions -->
- <dimen name="drop_target_elevation">1dp</dimen>
+ <dimen name="drop_target_elevation">2dp</dimen>
<dimen name="drop_target_radius">28dp</dimen>
- <dimen name="drop_target_stroke">1dp</dimen>
+ <dimen name="drop_target_stroke">2dp</dimen>
<dimen name="drop_target_full_screen_padding">20dp</dimen>
<dimen name="drop_target_desktop_window_padding_small">100dp</dimen>
<dimen name="drop_target_desktop_window_padding_large">130dp</dimen>
diff --git a/libs/WindowManager/Shell/shared/src/com/android/wm/shell/shared/IHomeTransitionListener.aidl b/libs/WindowManager/Shell/shared/src/com/android/wm/shell/shared/IHomeTransitionListener.aidl
index 8481c446c6aa..8dcda53b602b 100644
--- a/libs/WindowManager/Shell/shared/src/com/android/wm/shell/shared/IHomeTransitionListener.aidl
+++ b/libs/WindowManager/Shell/shared/src/com/android/wm/shell/shared/IHomeTransitionListener.aidl
@@ -18,6 +18,7 @@ package com.android.wm.shell.shared;
import android.window.RemoteTransition;
import android.window.TransitionFilter;
+import android.view.InsetsState;
/**
* Listener interface that Launcher attaches to SystemUI to get home activity transition callbacks
@@ -29,5 +30,10 @@ oneway interface IHomeTransitionListener {
* Called when a transition changes the visibility of the home activity on the default display.
*/
void onHomeVisibilityChanged(in boolean isVisible);
+
+ /**
+ * Called when the insets at display-level change.
+ */
+ void onDisplayInsetsChanged(in InsetsState insets);
}
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/ContextUtils.kt b/libs/WindowManager/Shell/shared/src/com/android/wm/shell/shared/bubbles/ContextUtils.kt
index 0b36f452348a..27db5297b758 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/ContextUtils.kt
+++ b/libs/WindowManager/Shell/shared/src/com/android/wm/shell/shared/bubbles/ContextUtils.kt
@@ -14,7 +14,7 @@
* limitations under the License.
*/
-package com.android.wm.shell.bubbles
+package com.android.wm.shell.shared.bubbles
import android.content.Context
import android.view.View
diff --git a/libs/WindowManager/Shell/shared/src/com/android/wm/shell/shared/bubbles/DropTargetView.kt b/libs/WindowManager/Shell/shared/src/com/android/wm/shell/shared/bubbles/DropTargetView.kt
index 73277310ffe4..df101fe44b75 100644
--- a/libs/WindowManager/Shell/shared/src/com/android/wm/shell/shared/bubbles/DropTargetView.kt
+++ b/libs/WindowManager/Shell/shared/src/com/android/wm/shell/shared/bubbles/DropTargetView.kt
@@ -30,15 +30,15 @@ import com.android.wm.shell.shared.R
class DropTargetView(context: Context) : View(context) {
private val rectPaint = Paint(Paint.ANTI_ALIAS_FLAG).apply {
- color = context.getColor(com.android.internal.R.color.materialColorPrimaryContainer)
+ color = context.getColor(com.android.internal.R.color.materialColorPrimaryFixed)
style = Paint.Style.FILL
alpha = (0.35f * 255).toInt()
}
private val strokePaint = Paint(Paint.ANTI_ALIAS_FLAG).apply {
- color = context.getColor(com.android.internal.R.color.materialColorPrimaryContainer)
+ color = context.getColor(com.android.internal.R.color.materialColorPrimaryFixed)
style = Paint.Style.STROKE
- strokeWidth = 1.dpToPx()
+ strokeWidth = 2.dpToPx()
}
private val cornerRadius = 28.dpToPx()
diff --git a/libs/WindowManager/Shell/shared/src/com/android/wm/shell/shared/desktopmode/DesktopModeStatus.java b/libs/WindowManager/Shell/shared/src/com/android/wm/shell/shared/desktopmode/DesktopModeStatus.java
index e5a4cd034e72..a9224b02ad31 100644
--- a/libs/WindowManager/Shell/shared/src/com/android/wm/shell/shared/desktopmode/DesktopModeStatus.java
+++ b/libs/WindowManager/Shell/shared/src/com/android/wm/shell/shared/desktopmode/DesktopModeStatus.java
@@ -451,6 +451,6 @@ public class DesktopModeStatus {
pw.println(maxTaskLimitHandle == null ? "null" : maxTaskLimitHandle.getInt(/* def= */ -1));
pw.print(innerPrefix); pw.print("showAppHandle config override=");
- pw.print(overridesShowAppHandle(context));
+ pw.println(overridesShowAppHandle(context));
}
}
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/animation/SizeChangeAnimation.java b/libs/WindowManager/Shell/src/com/android/wm/shell/animation/SizeChangeAnimation.java
index 8e78686ac13d..711667760314 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/animation/SizeChangeAnimation.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/animation/SizeChangeAnimation.java
@@ -34,6 +34,8 @@ import android.view.animation.ScaleAnimation;
import android.view.animation.Transformation;
import android.view.animation.TranslateAnimation;
+import com.android.wm.shell.shared.animation.Interpolators;
+
import java.util.function.Consumer;
/**
@@ -66,7 +68,7 @@ public class SizeChangeAnimation {
* The maximum of stretching applied to any surface during interpolation (since the animation
* is a combination of stretching/cropping/fading).
*/
- private static final float SCALE_FACTOR = 0.7f;
+ private static final float DEFAULT_SCALE_FACTOR = 0.7f;
/**
* Since this animation is made of several sub-animations, we want to pre-arrange the
@@ -82,13 +84,27 @@ public class SizeChangeAnimation {
*/
private static final int ANIMATION_RESOLUTION = 1000;
+ /**
+ * Initialize a size-change animation from start to end bounds
+ */
public SizeChangeAnimation(Rect startBounds, Rect endBounds) {
- this(startBounds, endBounds, 1f);
+ this(startBounds, endBounds, 1f, DEFAULT_SCALE_FACTOR);
}
- public SizeChangeAnimation(Rect startBounds, Rect endBounds, float initialScale) {
- mAnimation = buildContainerAnimation(startBounds, endBounds, initialScale);
- mSnapshotAnim = buildSnapshotAnimation(startBounds, endBounds);
+ /**
+ * Initialize a size-change animation from start to end bounds.
+ * <p>
+ * Allows specifying the initial scale factor, {@code initialScale}, that is applied to the
+ * start bounds. This can be useful for example when a task is scaled down when the size change
+ * animation starts.
+ * <p>
+ * By default the max scale applied to any surface is {@link #DEFAULT_SCALE_FACTOR}. Use
+ * {@code scaleFactor} to override it.
+ */
+ public SizeChangeAnimation(Rect startBounds, Rect endBounds, float initialScale,
+ float scaleFactor) {
+ mAnimation = buildContainerAnimation(startBounds, endBounds, initialScale, scaleFactor);
+ mSnapshotAnim = buildSnapshotAnimation(startBounds, endBounds, scaleFactor);
}
/**
@@ -172,16 +188,18 @@ public class SizeChangeAnimation {
/** Animation for the whole container (snapshot is inside this container). */
private static AnimationSet buildContainerAnimation(Rect startBounds, Rect endBounds,
- float initialScale) {
+ float initialScale, float scaleFactor) {
final long duration = ANIMATION_RESOLUTION;
boolean growing = endBounds.width() - startBounds.width()
+ endBounds.height() - startBounds.height() >= 0;
- long scalePeriod = (long) (duration * SCALE_FACTOR);
- float startScaleX = SCALE_FACTOR * ((float) startBounds.width()) / endBounds.width()
- + (1.f - SCALE_FACTOR);
- float startScaleY = SCALE_FACTOR * ((float) startBounds.height()) / endBounds.height()
- + (1.f - SCALE_FACTOR);
+ long scalePeriod = (long) (duration * scaleFactor);
+ float startScaleX = scaleFactor * ((float) startBounds.width()) / endBounds.width()
+ + (1.f - scaleFactor);
+ float startScaleY = scaleFactor * ((float) startBounds.height()) / endBounds.height()
+ + (1.f - scaleFactor);
final AnimationSet animSet = new AnimationSet(true);
+ // Use a linear interpolator so the driving ValueAnimator sets the interpolation
+ animSet.setInterpolator(Interpolators.LINEAR);
final Animation scaleAnim = new ScaleAnimation(startScaleX, 1, startScaleY, 1);
scaleAnim.setDuration(scalePeriod);
@@ -218,17 +236,20 @@ public class SizeChangeAnimation {
}
/** The snapshot surface is assumed to be a child of the container surface. */
- private static AnimationSet buildSnapshotAnimation(Rect startBounds, Rect endBounds) {
+ private static AnimationSet buildSnapshotAnimation(Rect startBounds, Rect endBounds,
+ float scaleFactor) {
final long duration = ANIMATION_RESOLUTION;
boolean growing = endBounds.width() - startBounds.width()
+ endBounds.height() - startBounds.height() >= 0;
- long scalePeriod = (long) (duration * SCALE_FACTOR);
- float endScaleX = 1.f / (SCALE_FACTOR * ((float) startBounds.width()) / endBounds.width()
- + (1.f - SCALE_FACTOR));
- float endScaleY = 1.f / (SCALE_FACTOR * ((float) startBounds.height()) / endBounds.height()
- + (1.f - SCALE_FACTOR));
+ long scalePeriod = (long) (duration * scaleFactor);
+ float endScaleX = 1.f / (scaleFactor * ((float) startBounds.width()) / endBounds.width()
+ + (1.f - scaleFactor));
+ float endScaleY = 1.f / (scaleFactor * ((float) startBounds.height()) / endBounds.height()
+ + (1.f - scaleFactor));
AnimationSet snapAnimSet = new AnimationSet(true);
+ // Use a linear interpolator so the driving ValueAnimator sets the interpolation
+ snapAnimSet.setInterpolator(Interpolators.LINEAR);
// Animation for the "old-state" snapshot that is atop the task.
final Animation snapAlphaAnim = new AlphaAnimation(1.f, 0.f);
snapAlphaAnim.setDuration(scalePeriod);
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/back/BackAnimationBackground.java b/libs/WindowManager/Shell/src/com/android/wm/shell/back/BackAnimationBackground.java
index 26f7b360e0fc..98cae5ae9296 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/back/BackAnimationBackground.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/back/BackAnimationBackground.java
@@ -19,6 +19,8 @@ package com.android.wm.shell.back;
import static android.view.Display.DEFAULT_DISPLAY;
import static android.view.WindowInsetsController.APPEARANCE_LIGHT_STATUS_BARS;
+import static com.android.window.flags.Flags.enableMultidisplayTrackpadBackGesture;
+
import android.annotation.NonNull;
import android.annotation.Nullable;
import android.graphics.Color;
@@ -59,9 +61,9 @@ public class BackAnimationBackground {
* @param statusbarHeight The height of the statusbar (in px).
*/
public void ensureBackground(Rect startRect, int color,
- @NonNull SurfaceControl.Transaction transaction, int statusbarHeight) {
+ @NonNull SurfaceControl.Transaction transaction, int statusbarHeight, int displayId) {
ensureBackground(startRect, color, transaction, statusbarHeight,
- null /* cropBounds */, 0 /* cornerRadius */);
+ null /* cropBounds */, 0 /* cornerRadius */, displayId);
}
/**
@@ -76,7 +78,7 @@ public class BackAnimationBackground {
*/
public void ensureBackground(Rect startRect, int color,
@NonNull SurfaceControl.Transaction transaction, int statusbarHeight,
- @Nullable Rect cropBounds, float cornerRadius) {
+ @Nullable Rect cropBounds, float cornerRadius, int displayId) {
if (mBackgroundSurface != null) {
return;
}
@@ -91,7 +93,11 @@ public class BackAnimationBackground {
.setCallsite("BackAnimationBackground")
.setColorLayer();
- mRootTaskDisplayAreaOrganizer.attachToDisplayArea(DEFAULT_DISPLAY, colorLayerBuilder);
+ if (enableMultidisplayTrackpadBackGesture()) {
+ mRootTaskDisplayAreaOrganizer.attachToDisplayArea(displayId, colorLayerBuilder);
+ } else {
+ mRootTaskDisplayAreaOrganizer.attachToDisplayArea(DEFAULT_DISPLAY, colorLayerBuilder);
+ }
mBackgroundSurface = colorLayerBuilder.build();
transaction.setColor(mBackgroundSurface, colorComponents)
.setLayer(mBackgroundSurface, BACKGROUND_LAYER)
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/back/BackAnimationController.java b/libs/WindowManager/Shell/src/com/android/wm/shell/back/BackAnimationController.java
index 81cf031994a2..746632f67725 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/back/BackAnimationController.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/back/BackAnimationController.java
@@ -286,6 +286,7 @@ public class BackAnimationController implements RemoteCallable<BackAnimationCont
this::createExternalInterface, this);
mShellCommandHandler.addDumpCallback(this::dump, this);
mShellController.addConfigurationChangeListener(this);
+ registerBackGestureDelegate();
}
public BackAnimation getBackAnimationImpl() {
@@ -1144,6 +1145,32 @@ public class BackAnimationController implements RemoteCallable<BackAnimationCont
mBackAnimationAdapter = new BackAnimationAdapter(runner);
}
+ private void registerBackGestureDelegate() {
+ if (!Flags.delegateBackGestureToShell()) {
+ return;
+ }
+ final RemoteCallback requestBackMonitor = new RemoteCallback(
+ new RemoteCallback.OnResultListener() {
+ @Override
+ public void onResult(@Nullable Bundle result) {
+ mShellExecutor.execute(() -> {
+ if (mBackGestureStarted) {
+ Log.w(TAG, "Back gesture is running, ignore request");
+ return;
+ }
+ onMotionEvent(0, 0, KeyEvent.ACTION_DOWN, EDGE_NONE);
+ setTriggerBack(true);
+ onMotionEvent(0, 0, KeyEvent.ACTION_UP, EDGE_NONE);
+ });
+ }
+ });
+ try {
+ mActivityTaskManager.registerBackGestureDelegate(requestBackMonitor);
+ } catch (RemoteException remoteException) {
+ Log.w(TAG, "Failed register back gesture request ", remoteException);
+ }
+ }
+
/**
* Description of current BackAnimationController state.
*/
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/back/CrossActivityBackAnimation.kt b/libs/WindowManager/Shell/src/com/android/wm/shell/back/CrossActivityBackAnimation.kt
index 7e5a82e640cc..6c41c975cf4d 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/back/CrossActivityBackAnimation.kt
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/back/CrossActivityBackAnimation.kt
@@ -52,6 +52,7 @@ import com.android.internal.jank.Cuj
import com.android.internal.policy.ScreenDecorationsUtils
import com.android.internal.policy.SystemBarUtils
import com.android.internal.protolog.ProtoLog
+import com.android.window.flags.Flags.enableMultidisplayTrackpadBackGesture
import com.android.window.flags.Flags.predictiveBackTimestampApi
import com.android.wm.shell.R
import com.android.wm.shell.RootTaskDisplayAreaOrganizer
@@ -210,7 +211,8 @@ abstract class CrossActivityBackAnimation(
statusbarHeight,
if (closingTarget!!.windowConfiguration.tasksAreFloating())
closingTarget!!.localBounds else null,
- cornerRadius
+ cornerRadius,
+ closingTarget!!.taskInfo.getDisplayId()
)
ensureScrimLayer()
if (isLetterboxed && enteringHasSameLetterbox) {
@@ -409,7 +411,12 @@ abstract class CrossActivityBackAnimation(
.setOpaque(false)
.setHidden(false)
- rootTaskDisplayAreaOrganizer.attachToDisplayArea(Display.DEFAULT_DISPLAY, scrimBuilder)
+ if (enableMultidisplayTrackpadBackGesture()) {
+ rootTaskDisplayAreaOrganizer.attachToDisplayArea(
+ closingTarget!!.taskInfo.getDisplayId(), scrimBuilder)
+ } else {
+ rootTaskDisplayAreaOrganizer.attachToDisplayArea(Display.DEFAULT_DISPLAY, scrimBuilder)
+ }
scrimLayer = scrimBuilder.build()
val colorComponents = floatArrayOf(0f, 0f, 0f)
maxScrimAlpha = if (isDarkTheme) MAX_SCRIM_ALPHA_DARK else MAX_SCRIM_ALPHA_LIGHT
@@ -473,7 +480,13 @@ abstract class CrossActivityBackAnimation(
.setOpaque(true)
.setHidden(false)
- rootTaskDisplayAreaOrganizer.attachToDisplayArea(Display.DEFAULT_DISPLAY, letterboxBuilder)
+ if (enableMultidisplayTrackpadBackGesture()) {
+ rootTaskDisplayAreaOrganizer.attachToDisplayArea(
+ closingTarget!!.taskInfo.getDisplayId(), letterboxBuilder)
+ } else {
+ rootTaskDisplayAreaOrganizer.attachToDisplayArea(
+ Display.DEFAULT_DISPLAY, letterboxBuilder)
+ }
val layer = letterboxBuilder.build()
val colorComponents =
floatArrayOf(
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/back/CrossTaskBackAnimation.java b/libs/WindowManager/Shell/src/com/android/wm/shell/back/CrossTaskBackAnimation.java
index f48b3ffcd598..f5b0e359e019 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/back/CrossTaskBackAnimation.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/back/CrossTaskBackAnimation.java
@@ -175,7 +175,8 @@ public class CrossTaskBackAnimation extends ShellBackAnimation {
// Draw background.
mBackground.ensureBackground(mClosingTarget.windowConfiguration.getBounds(),
- BACKGROUNDCOLOR, mTransaction, mStatusbarHeight);
+ BACKGROUNDCOLOR, mTransaction, mStatusbarHeight,
+ mClosingTarget.taskInfo.getDisplayId());
mInterWindowMargin = mContext.getResources()
.getDimension(R.dimen.cross_task_back_inter_window_margin);
mVerticalMargin = mContext.getResources()
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/BubbleController.java b/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/BubbleController.java
index 81eff6f7399a..6a7b5cc0e1ba 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/BubbleController.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/BubbleController.java
@@ -81,6 +81,7 @@ import android.view.WindowInsets;
import android.view.WindowManager;
import android.window.ScreenCapture;
import android.window.ScreenCapture.SynchronousScreenCaptureListener;
+import android.window.TransitionInfo;
import android.window.WindowContainerToken;
import android.window.WindowContainerTransaction;
@@ -120,6 +121,7 @@ import com.android.wm.shell.shared.bubbles.BubbleBarLocation;
import com.android.wm.shell.shared.bubbles.BubbleBarLocation.UpdateSource;
import com.android.wm.shell.shared.bubbles.BubbleBarUpdate;
import com.android.wm.shell.shared.bubbles.BubbleDropTargetBoundsProvider;
+import com.android.wm.shell.shared.bubbles.ContextUtils;
import com.android.wm.shell.shared.bubbles.DeviceConfig;
import com.android.wm.shell.shared.draganddrop.DragAndDropConstants;
import com.android.wm.shell.sysui.ConfigurationChangeListener;
@@ -155,7 +157,7 @@ import java.util.function.IntConsumer;
*/
public class BubbleController implements ConfigurationChangeListener,
RemoteCallable<BubbleController>, Bubbles.SysuiProxy.Provider,
- BubbleBarDragListener {
+ BubbleBarDragListener, BubbleTaskUnfoldTransitionMerger {
private static final String TAG = TAG_WITH_CLASS_NAME ? "BubbleController" : TAG_BUBBLES;
@@ -2174,6 +2176,32 @@ public class BubbleController implements ConfigurationChangeListener,
});
}
+ @Override
+ public boolean mergeTaskWithUnfold(@NonNull ActivityManager.RunningTaskInfo taskInfo,
+ @NonNull TransitionInfo.Change change,
+ @NonNull SurfaceControl.Transaction startT,
+ @NonNull SurfaceControl.Transaction finishT) {
+ if (!mBubbleTransitions.mTaskViewTransitions.isTaskViewTask(taskInfo)) {
+ // if this task isn't managed by bubble transitions just bail.
+ return false;
+ }
+ if (isShowingAsBubbleBar()) {
+ // if bubble bar is enabled, the task view will switch to a new surface on unfold, so we
+ // should not merge the transition.
+ return false;
+ }
+
+ boolean merged = mBubbleTransitions.mTaskViewTransitions.updateBoundsForUnfold(
+ change.getEndAbsBounds(), startT, finishT, change.getTaskInfo(), change.getLeash());
+ if (merged) {
+ BubbleViewProvider selectedBubble = mBubbleData.getSelectedBubble();
+ if (selectedBubble != null && selectedBubble.getExpandedView() != null) {
+ selectedBubble.getExpandedView().onContainerClipUpdate();
+ }
+ }
+ return merged;
+ }
+
/** When bubbles are floating, this will be used to notify the floating views. */
private final BubbleViewCallback mBubbleStackViewCallback = new BubbleViewCallback() {
@Override
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/BubbleExpandedView.java b/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/BubbleExpandedView.java
index 290ef1633819..ac8393576477 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/BubbleExpandedView.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/BubbleExpandedView.java
@@ -843,7 +843,8 @@ public class BubbleExpandedView extends LinearLayout {
onContainerClipUpdate();
}
- private void onContainerClipUpdate() {
+ /** Updates the clip bounds. */
+ public void onContainerClipUpdate() {
if (mTopClip == 0 && mBottomClip == 0 && mRightClip == 0 && mLeftClip == 0) {
if (mIsClipping) {
mIsClipping = false;
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/BubbleStackView.java b/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/BubbleStackView.java
index 3dce45690cf2..7ae9de8ee65d 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/BubbleStackView.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/BubbleStackView.java
@@ -94,6 +94,7 @@ import com.android.wm.shell.shared.TypefaceUtils.FontFamily;
import com.android.wm.shell.shared.animation.Interpolators;
import com.android.wm.shell.shared.animation.PhysicsAnimator;
import com.android.wm.shell.shared.bubbles.BubbleAnythingFlagHelper;
+import com.android.wm.shell.shared.bubbles.ContextUtils;
import com.android.wm.shell.shared.bubbles.DeviceConfig;
import com.android.wm.shell.shared.bubbles.DismissView;
import com.android.wm.shell.shared.bubbles.RelativeTouchListener;
@@ -2958,6 +2959,9 @@ public class BubbleStackView extends FrameLayout
if (mIsExpanded) {
mExpandedViewAnimationController.animateForImeVisibilityChange(visible);
BubbleExpandedView expandedView = getExpandedView();
+ if (expandedView != null) {
+ expandedView.setImeVisible(visible);
+ }
if (mPositioner.showBubblesVertically() && expandedView != null) {
float selectedY = mPositioner.getExpandedBubbleXY(getState().selectedIndex,
getState()).y;
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/BubbleTaskUnfoldTransitionMerger.kt b/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/BubbleTaskUnfoldTransitionMerger.kt
new file mode 100644
index 000000000000..13fabc8b1d91
--- /dev/null
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/BubbleTaskUnfoldTransitionMerger.kt
@@ -0,0 +1,33 @@
+/*
+ * Copyright (C) 2025 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.bubbles
+
+import android.app.ActivityManager
+import android.view.SurfaceControl
+import android.window.TransitionInfo
+
+/** Merges a bubble task transition with the unfold transition. */
+interface BubbleTaskUnfoldTransitionMerger {
+
+ /** Attempts to merge the transition. Returns `true` if the change was merged. */
+ fun mergeTaskWithUnfold(
+ taskInfo: ActivityManager.RunningTaskInfo,
+ change: TransitionInfo.Change,
+ startT: SurfaceControl.Transaction,
+ finishT: SurfaceControl.Transaction
+ ): Boolean
+}
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/bar/BubbleBarAnimationHelper.java b/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/bar/BubbleBarAnimationHelper.java
index fa22a3961002..ea365efcb400 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/bar/BubbleBarAnimationHelper.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/bar/BubbleBarAnimationHelper.java
@@ -596,11 +596,11 @@ public class BubbleBarAnimationHelper {
final Size size = getExpandedViewSize();
Point position = getExpandedViewRestPosition(size);
- final SizeChangeAnimation sca =
- new SizeChangeAnimation(
- new Rect(origBounds.left - position.x, origBounds.top - position.y,
- origBounds.right - position.x, origBounds.bottom - position.y),
- new Rect(0, 0, size.getWidth(), size.getHeight()), origScale);
+ Rect startBounds = new Rect(origBounds.left - position.x, origBounds.top - position.y,
+ origBounds.right - position.x, origBounds.bottom - position.y);
+ Rect endBounds = new Rect(0, 0, size.getWidth(), size.getHeight());
+ final SizeChangeAnimation sca = new SizeChangeAnimation(startBounds, endBounds,
+ origScale, /* scaleFactor= */ 1f);
sca.initialize(bbev, taskLeash, snapshot, startT);
Animator a = sca.buildViewAnimator(bbev, tvSf, snapshot, /* onFinish */ (va) -> {
@@ -615,7 +615,7 @@ public class BubbleBarAnimationHelper {
bbev.setSurfaceZOrderedOnTop(true);
a.setDuration(EXPANDED_VIEW_ANIMATE_TO_REST_DURATION);
- a.setInterpolator(Interpolators.EMPHASIZED);
+ a.setInterpolator(EMPHASIZED);
a.start();
}
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/bar/BubbleBarExpandedViewDragController.kt b/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/bar/BubbleBarExpandedViewDragController.kt
index 35435569d8b1..44d859dfb9ba 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/bar/BubbleBarExpandedViewDragController.kt
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/bar/BubbleBarExpandedViewDragController.kt
@@ -17,9 +17,11 @@
package com.android.wm.shell.bubbles.bar
import android.annotation.SuppressLint
+import android.content.Context
import android.view.MotionEvent
import android.view.View
import androidx.annotation.VisibleForTesting
+import com.android.wm.shell.R
import com.android.wm.shell.bubbles.BubblePositioner
import com.android.wm.shell.shared.bubbles.BubbleBarLocation
import com.android.wm.shell.shared.bubbles.DismissView
@@ -32,6 +34,7 @@ import com.android.wm.shell.shared.magnetictarget.MagnetizedObject
/** Controller for handling drag interactions with [BubbleBarExpandedView] */
@SuppressLint("ClickableViewAccessibility")
class BubbleBarExpandedViewDragController(
+ private val context: Context,
private val expandedView: BubbleBarExpandedView,
private val dismissView: DismissView,
private val animationHelper: BubbleBarAnimationHelper,
@@ -54,6 +57,8 @@ class BubbleBarExpandedViewDragController(
MagnetizedObject.magnetizeView(expandedView)
private val magnetizedDismissTarget: MagnetizedObject.MagneticTarget
+ private val draggedBubbleElevation: Float
+
init {
magnetizedExpandedView.magnetListener = MagnetListener()
magnetizedExpandedView.animateStuckToTarget =
@@ -70,6 +75,8 @@ class BubbleBarExpandedViewDragController(
MagnetizedObject.MagneticTarget(dismissView.circle, dismissView.circle.width)
magnetizedExpandedView.addTarget(magnetizedDismissTarget)
+ draggedBubbleElevation = context.resources.getDimension(
+ R.dimen.dragged_bubble_elevation)
val dragMotionEventHandler = HandleDragListener()
expandedView.handleView.setOnTouchListener { view, event ->
@@ -103,6 +110,7 @@ class BubbleBarExpandedViewDragController(
override fun onDown(v: View, ev: MotionEvent): Boolean {
// While animating, don't allow new touch events
if (expandedView.isAnimating) return false
+ expandedView.z = draggedBubbleElevation
if (dropTargetManager != null && dragZoneFactory != null) {
val draggedObject = DraggedObject.ExpandedView(
if (bubblePositioner.isBubbleBarOnLeft) {
@@ -154,11 +162,13 @@ class BubbleBarExpandedViewDragController(
velX: Float,
velY: Float,
) {
+ v.translationZ = 0f
finishDrag()
}
override fun onCancel(v: View, ev: MotionEvent, viewInitialX: Float, viewInitialY: Float) {
isStuckToDismiss = false
+ v.translationZ = 0f
finishDrag()
}
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/bar/BubbleBarLayerView.java b/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/bar/BubbleBarLayerView.java
index 2cc9387bd1e9..dd86725f7944 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/bar/BubbleBarLayerView.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/bar/BubbleBarLayerView.java
@@ -349,6 +349,7 @@ public class BubbleBarLayerView extends FrameLayout
}
};
mDragController = new BubbleBarExpandedViewDragController(
+ mContext,
mExpandedView,
mDismissView,
mAnimationHelper,
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/common/DisplayController.java b/libs/WindowManager/Shell/src/com/android/wm/shell/common/DisplayController.java
index 97184c859d4d..06d734c71f6a 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/common/DisplayController.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/common/DisplayController.java
@@ -287,7 +287,13 @@ public class DisplayController {
? mContext
: mContext.createDisplayContext(display);
final Context context = perDisplayContext.createConfigurationContext(newConfig);
- dr.setDisplayLayout(context, new DisplayLayout(context, display));
+ final DisplayLayout displayLayout = new DisplayLayout(context, display);
+ if (mDisplayTopology != null) {
+ displayLayout.setGlobalBoundsDp(
+ mDisplayTopology.getAbsoluteBounds().get(
+ displayId, displayLayout.globalBoundsDp()));
+ }
+ dr.setDisplayLayout(context, displayLayout);
for (int i = 0; i < mDisplayChangedListeners.size(); ++i) {
mDisplayChangedListeners.get(i).onDisplayConfigurationChanged(
displayId, newConfig);
@@ -349,6 +355,19 @@ public class DisplayController {
}
}
+ private void onDesktopModeEligibleChanged(int displayId) {
+ synchronized (mDisplays) {
+ if (mDisplays.get(displayId) == null || getDisplay(displayId) == null) {
+ Slog.w(TAG, "Skipping onDesktopModeEligibleChanged on unknown"
+ + " display, displayId=" + displayId);
+ return;
+ }
+ for (int i = mDisplayChangedListeners.size() - 1; i >= 0; --i) {
+ mDisplayChangedListeners.get(i).onDesktopModeEligibleChanged(displayId);
+ }
+ }
+ }
+
private static class DisplayRecord {
private int mDisplayId;
private Context mContext;
@@ -416,6 +435,13 @@ public class DisplayController {
new ArraySet<>(restricted), new ArraySet<>(unrestricted));
});
}
+
+ @Override
+ public void onDesktopModeEligibleChanged(int displayId) {
+ mMainExecutor.execute(() -> {
+ DisplayController.this.onDesktopModeEligibleChanged(displayId);
+ });
+ }
}
/**
@@ -461,5 +487,10 @@ public class DisplayController {
* Called when the display topology has changed.
*/
default void onTopologyChanged(DisplayTopology topology) {}
+
+ /**
+ * Called when the eligibility of the desktop mode for a display have changed.
+ */
+ default void onDesktopModeEligibleChanged(int displayId) {}
}
}
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/common/split/DividerRoundedCorner.java b/libs/WindowManager/Shell/src/com/android/wm/shell/common/split/DividerRoundedCorner.java
index cf0ecae7c815..a1e7ff04347f 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/common/split/DividerRoundedCorner.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/common/split/DividerRoundedCorner.java
@@ -106,31 +106,37 @@ public class DividerRoundedCorner extends View {
* of non split screen.
*
* @param isSplitScreen Whether the divider is used by split screen or tiling.
- * @param isDarkMode Whether the mode is ui dark mode.
+ * @param color Rounded corner color.
*/
- public void setup(boolean isSplitScreen, boolean isDarkMode) {
+ public void setup(boolean isSplitScreen, int color) {
mIsSplitScreen = isSplitScreen;
if (!isSplitScreen) {
- mDividerBarBackground.setColor(getTilingHandleColor(isDarkMode));
+ mDividerBarBackground.setColor(color);
}
}
/**
- * Notifies the divider of ui mode change.
+ * Notifies the divider of ui mode change and provides a new color.
*
- * @param isDarkMode Whether the mode is ui dark mode.
+ * @param color The new divider rounded corner color.
*/
- public void onUiModeChange(boolean isDarkMode) {
+ public void onUiModeChange(int color) {
if (!mIsSplitScreen) {
- mDividerBarBackground.setColor(getTilingHandleColor(isDarkMode));
+ mDividerBarBackground.setColor(color);
invalidate();
}
}
- private int getTilingHandleColor(boolean isDarkMode) {
- return isDarkMode ? getResources().getColor(
- R.color.tiling_divider_background_dark, null /* theme */) : getResources().getColor(
- R.color.tiling_divider_background_light, null /* theme */);
+ /**
+ * Notifies rounded corner view of color change.
+ *
+ * @param color The new divider rounded corner color.
+ */
+ public void onCornerColorChange(int color) {
+ if (!mIsSplitScreen) {
+ mDividerBarBackground.setColor(color);
+ invalidate();
+ }
}
/**
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/dagger/WMShellBaseModule.java b/libs/WindowManager/Shell/src/com/android/wm/shell/dagger/WMShellBaseModule.java
index f62fd819319e..ad509bcc1ceb 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/dagger/WMShellBaseModule.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/dagger/WMShellBaseModule.java
@@ -762,9 +762,11 @@ public abstract class WMShellBaseModule {
ShellTaskOrganizer organizer,
TransactionPool pool,
DisplayController displayController,
+ DisplayInsetsController displayInsetsController,
@ShellMainThread ShellExecutor mainExecutor,
@ShellMainThread Handler mainHandler,
@ShellAnimationThread ShellExecutor animExecutor,
+ @ShellAnimationThread Handler animHandler,
RootTaskDisplayAreaOrganizer rootTaskDisplayAreaOrganizer,
HomeTransitionObserver homeTransitionObserver,
FocusTransitionObserver focusTransitionObserver) {
@@ -773,15 +775,19 @@ public abstract class WMShellBaseModule {
shellInit = new ShellInit(mainExecutor);
}
return new Transitions(context, shellInit, shellCommandHandler, shellController, organizer,
- pool, displayController, mainExecutor, mainHandler, animExecutor,
- rootTaskDisplayAreaOrganizer, homeTransitionObserver, focusTransitionObserver);
+ pool, displayController, displayInsetsController, mainExecutor, mainHandler,
+ animExecutor, animHandler, rootTaskDisplayAreaOrganizer, homeTransitionObserver,
+ focusTransitionObserver);
}
@WMSingleton
@Provides
static HomeTransitionObserver provideHomeTransitionObserver(Context context,
- @ShellMainThread ShellExecutor mainExecutor) {
- return new HomeTransitionObserver(context, mainExecutor);
+ @ShellMainThread ShellExecutor mainExecutor,
+ DisplayInsetsController displayInsetsController,
+ ShellInit shellInit) {
+ return new HomeTransitionObserver(context, mainExecutor, displayInsetsController,
+ shellInit);
}
@WMSingleton
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 5fbbb0bf1e78..46c9b07fb802 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
@@ -62,6 +62,7 @@ import com.android.wm.shell.bubbles.BubbleEducationController;
import com.android.wm.shell.bubbles.BubbleLogger;
import com.android.wm.shell.bubbles.BubblePositioner;
import com.android.wm.shell.bubbles.BubbleResizabilityChecker;
+import com.android.wm.shell.bubbles.BubbleTaskUnfoldTransitionMerger;
import com.android.wm.shell.bubbles.bar.BubbleBarDragListener;
import com.android.wm.shell.bubbles.storage.BubblePersistentRepository;
import com.android.wm.shell.common.DisplayController;
@@ -100,7 +101,6 @@ import com.android.wm.shell.desktopmode.DesktopModeKeyGestureHandler;
import com.android.wm.shell.desktopmode.DesktopModeLoggerTransitionObserver;
import com.android.wm.shell.desktopmode.DesktopModeMoveToDisplayTransitionHandler;
import com.android.wm.shell.desktopmode.DesktopModeUiEventLogger;
-import com.android.wm.shell.desktopmode.DesktopPipTransitionObserver;
import com.android.wm.shell.desktopmode.DesktopTaskChangeListener;
import com.android.wm.shell.desktopmode.DesktopTasksController;
import com.android.wm.shell.desktopmode.DesktopTasksLimiter;
@@ -244,6 +244,13 @@ public abstract class WMShellModule {
context, logger, positioner, educationController, mainExecutor, bgExecutor);
}
+ @WMSingleton
+ @Provides
+ static Optional<BubbleTaskUnfoldTransitionMerger> provideBubbleTaskUnfoldTransitionMerger(
+ Optional<BubbleController> bubbleController) {
+ return bubbleController.map(controller -> controller);
+ }
+
// Note: Handler needed for LauncherApps.register
@WMSingleton
@Provides
@@ -705,7 +712,8 @@ public abstract class WMShellModule {
Transitions transitions,
@ShellMainThread ShellExecutor executor,
@ShellMainThread Handler handler,
- ShellInit shellInit) {
+ ShellInit shellInit,
+ Optional<BubbleTaskUnfoldTransitionMerger> bubbleTaskUnfoldTransitionMerger) {
return new UnfoldTransitionHandler(
shellInit,
progressProvider.get(),
@@ -714,7 +722,8 @@ public abstract class WMShellModule {
transactionPool,
executor,
handler,
- transitions);
+ transitions,
+ bubbleTaskUnfoldTransitionMerger);
}
@WMSingleton
@@ -783,7 +792,6 @@ public abstract class WMShellModule {
OverviewToDesktopTransitionObserver overviewToDesktopTransitionObserver,
DesksOrganizer desksOrganizer,
Optional<DesksTransitionObserver> desksTransitionObserver,
- Optional<DesktopPipTransitionObserver> desktopPipTransitionObserver,
UserProfileContexts userProfileContexts,
DesktopModeCompatPolicy desktopModeCompatPolicy,
DragToDisplayTransitionHandler dragToDisplayTransitionHandler,
@@ -827,7 +835,6 @@ public abstract class WMShellModule {
overviewToDesktopTransitionObserver,
desksOrganizer,
desksTransitionObserver.get(),
- desktopPipTransitionObserver,
userProfileContexts,
desktopModeCompatPolicy,
dragToDisplayTransitionHandler,
@@ -1047,7 +1054,8 @@ public abstract class WMShellModule {
DesktopModeCompatPolicy desktopModeCompatPolicy,
DesktopTilingDecorViewModel desktopTilingDecorViewModel,
MultiDisplayDragMoveIndicatorController multiDisplayDragMoveIndicatorController,
- Optional<CompatUIHandler> compatUI
+ Optional<CompatUIHandler> compatUI,
+ DesksOrganizer desksOrganizer
) {
if (!DesktopModeStatus.canEnterDesktopModeOrShowAppHandle(context)) {
return Optional.empty();
@@ -1065,7 +1073,8 @@ public abstract class WMShellModule {
activityOrientationChangeHandler, focusTransitionObserver, desktopModeEventLogger,
desktopModeUiEventLogger, taskResourceLoader, recentsTransitionHandler,
desktopModeCompatPolicy, desktopTilingDecorViewModel,
- multiDisplayDragMoveIndicatorController, compatUI.orElse(null)));
+ multiDisplayDragMoveIndicatorController, compatUI.orElse(null),
+ desksOrganizer));
}
@WMSingleton
@@ -1240,7 +1249,6 @@ public abstract class WMShellModule {
Transitions transitions,
ShellTaskOrganizer shellTaskOrganizer,
Optional<DesktopMixedTransitionHandler> desktopMixedTransitionHandler,
- Optional<DesktopPipTransitionObserver> desktopPipTransitionObserver,
Optional<BackAnimationController> backAnimationController,
DesktopWallpaperActivityTokenProvider desktopWallpaperActivityTokenProvider,
ShellInit shellInit) {
@@ -1253,7 +1261,6 @@ public abstract class WMShellModule {
transitions,
shellTaskOrganizer,
desktopMixedTransitionHandler.get(),
- desktopPipTransitionObserver,
backAnimationController.get(),
desktopWallpaperActivityTokenProvider,
shellInit)));
@@ -1275,19 +1282,6 @@ public abstract class WMShellModule {
@WMSingleton
@Provides
- static Optional<DesktopPipTransitionObserver> provideDesktopPipTransitionObserver(
- Context context
- ) {
- if (DesktopModeStatus.canEnterDesktopMode(context)
- && DesktopModeFlags.ENABLE_DESKTOP_WINDOWING_PIP.isTrue()) {
- return Optional.of(
- new DesktopPipTransitionObserver());
- }
- return Optional.empty();
- }
-
- @WMSingleton
- @Provides
static Optional<DesktopMixedTransitionHandler> provideDesktopMixedTransitionHandler(
Context context,
Transitions transitions,
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/dagger/pip/Pip2Module.java b/libs/WindowManager/Shell/src/com/android/wm/shell/dagger/pip/Pip2Module.java
index 6f0919e1d045..c5f956a80702 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/dagger/pip/Pip2Module.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/dagger/pip/Pip2Module.java
@@ -19,6 +19,7 @@ package com.android.wm.shell.dagger.pip;
import android.annotation.NonNull;
import android.content.Context;
import android.os.Handler;
+import android.window.DesktopModeFlags;
import com.android.internal.jank.InteractionJankMonitor;
import com.android.wm.shell.RootTaskDisplayAreaOrganizer;
@@ -42,6 +43,8 @@ import com.android.wm.shell.common.pip.PipUtils;
import com.android.wm.shell.common.pip.SizeSpecSource;
import com.android.wm.shell.dagger.WMShellBaseModule;
import com.android.wm.shell.dagger.WMSingleton;
+import com.android.wm.shell.desktopmode.DesktopPipTransitionController;
+import com.android.wm.shell.desktopmode.DesktopTasksController;
import com.android.wm.shell.desktopmode.DesktopUserRepositories;
import com.android.wm.shell.desktopmode.DragToDesktopTransitionHandler;
import com.android.wm.shell.pip2.phone.PhonePipMenuController;
@@ -55,6 +58,7 @@ import com.android.wm.shell.pip2.phone.PipTransition;
import com.android.wm.shell.pip2.phone.PipTransitionState;
import com.android.wm.shell.pip2.phone.PipUiStateChangeController;
import com.android.wm.shell.shared.annotations.ShellMainThread;
+import com.android.wm.shell.shared.desktopmode.DesktopModeStatus;
import com.android.wm.shell.splitscreen.SplitScreenController;
import com.android.wm.shell.sysui.ShellCommandHandler;
import com.android.wm.shell.sysui.ShellController;
@@ -91,12 +95,13 @@ public abstract class Pip2Module {
DisplayController displayController,
Optional<SplitScreenController> splitScreenControllerOptional,
PipDesktopState pipDesktopState,
+ Optional<DesktopPipTransitionController> desktopPipTransitionController,
PipInteractionHandler pipInteractionHandler) {
return new PipTransition(context, shellInit, shellTaskOrganizer, transitions,
pipBoundsState, null, pipBoundsAlgorithm, pipTaskListener,
pipScheduler, pipStackListenerController, pipDisplayLayoutState,
pipUiStateChangeController, displayController, splitScreenControllerOptional,
- pipDesktopState, pipInteractionHandler);
+ pipDesktopState, desktopPipTransitionController, pipInteractionHandler);
}
@WMSingleton
@@ -250,6 +255,22 @@ public abstract class Pip2Module {
dragToDesktopTransitionHandlerOptional, rootTaskDisplayAreaOrganizer);
}
+ @WMSingleton
+ @Provides
+ static Optional<DesktopPipTransitionController> provideDesktopPipTransitionController(
+ Context context, Optional<DesktopTasksController> desktopTasksControllerOptional,
+ Optional<DesktopUserRepositories> desktopUserRepositoriesOptional,
+ PipDesktopState pipDesktopState
+ ) {
+ if (DesktopModeStatus.canEnterDesktopMode(context)
+ && DesktopModeFlags.ENABLE_DESKTOP_WINDOWING_PIP.isTrue()) {
+ return Optional.of(
+ new DesktopPipTransitionController(desktopTasksControllerOptional.get(),
+ desktopUserRepositoriesOptional.get(), pipDesktopState));
+ }
+ return Optional.empty();
+ }
+
@BindsOptionalOf
abstract DragToDesktopTransitionHandler optionalDragToDesktopTransitionHandler();
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/desktopmode/DesktopDisplayEventHandler.kt b/libs/WindowManager/Shell/src/com/android/wm/shell/desktopmode/DesktopDisplayEventHandler.kt
index 3b98f8123b46..25737c4950d6 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/desktopmode/DesktopDisplayEventHandler.kt
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/desktopmode/DesktopDisplayEventHandler.kt
@@ -89,6 +89,15 @@ class DesktopDisplayEventHandler(
// TODO: b/362720497 - move desks in closing display to the remaining desk.
}
+ override fun onDesktopModeEligibleChanged(displayId: Int) {
+ if (
+ DesktopExperienceFlags.ENABLE_DISPLAY_CONTENT_MODE_MANAGEMENT.isTrue &&
+ displayId != DEFAULT_DISPLAY
+ ) {
+ desktopDisplayModeController.refreshDisplayWindowingMode()
+ }
+ }
+
override fun onDeskRemoved(lastDisplayId: Int, deskId: Int) {
val remainingDesks = desktopRepository.getNumberOfDesks(lastDisplayId)
if (remainingDesks == 0) {
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/desktopmode/DesktopDisplayModeController.kt b/libs/WindowManager/Shell/src/com/android/wm/shell/desktopmode/DesktopDisplayModeController.kt
index ea2fdc0ee8ed..0a3e2cc3b434 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/desktopmode/DesktopDisplayModeController.kt
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/desktopmode/DesktopDisplayModeController.kt
@@ -56,13 +56,6 @@ class DesktopDisplayModeController(
@ShellMainThread private val mainHandler: Handler,
) {
- private val onTabletModeChangedListener =
- object : InputManager.OnTabletModeChangedListener {
- override fun onTabletModeChanged(whenNanos: Long, inTabletMode: Boolean) {
- refreshDisplayWindowingMode()
- }
- }
-
private val inputDeviceListener =
object : InputManager.InputDeviceListener {
override fun onInputDeviceAdded(deviceId: Int) {
@@ -80,10 +73,6 @@ class DesktopDisplayModeController(
init {
if (DesktopExperienceFlags.FORM_FACTOR_BASED_DESKTOP_FIRST_SWITCH.isTrue) {
- inputManager.registerOnTabletModeChangedListener(
- onTabletModeChangedListener,
- mainHandler,
- )
inputManager.registerInputDeviceListener(inputDeviceListener, mainHandler)
}
}
@@ -139,7 +128,7 @@ class DesktopDisplayModeController(
return true
}
if (DesktopExperienceFlags.FORM_FACTOR_BASED_DESKTOP_FIRST_SWITCH.isTrue) {
- if (isInClamshellMode() || hasAnyMouseDevice()) {
+ if (hasAnyTouchpadDevice() && hasAnyPhysicalKeyboardDevice()) {
return true
}
}
@@ -186,17 +175,25 @@ class DesktopDisplayModeController(
private fun hasExternalDisplay() =
rootTaskDisplayAreaOrganizer.getDisplayIds().any { it != DEFAULT_DISPLAY }
- private fun hasAnyMouseDevice() =
- inputManager.inputDeviceIds.any {
- inputManager.getInputDevice(it)?.supportsSource(InputDevice.SOURCE_MOUSE) == true
+ private fun hasAnyTouchpadDevice() =
+ inputManager.inputDeviceIds.any { deviceId ->
+ inputManager.getInputDevice(deviceId)?.let { device ->
+ device.supportsSource(InputDevice.SOURCE_TOUCHPAD) && device.isEnabled()
+ } ?: false
}
- private fun isInClamshellMode() = inputManager.isInTabletMode() == InputManager.SWITCH_STATE_OFF
+ private fun hasAnyPhysicalKeyboardDevice() =
+ inputManager.inputDeviceIds.any { deviceId ->
+ inputManager.getInputDevice(deviceId)?.let { device ->
+ !device.isVirtual() && device.isFullKeyboard() && device.isEnabled()
+ } ?: false
+ }
private fun isDefaultDisplayDesktopEligible(): Boolean {
- val display = requireNotNull(displayController.getDisplay(DEFAULT_DISPLAY)) {
- "Display object of DEFAULT_DISPLAY must be non-null."
- }
+ val display =
+ requireNotNull(displayController.getDisplay(DEFAULT_DISPLAY)) {
+ "Display object of DEFAULT_DISPLAY must be non-null."
+ }
return DesktopModeStatus.isDesktopModeSupportedOnDisplay(context, display)
}
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/desktopmode/DesktopModeUtils.kt b/libs/WindowManager/Shell/src/com/android/wm/shell/desktopmode/DesktopModeUtils.kt
index 3c44fe8061aa..55179511af6e 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/desktopmode/DesktopModeUtils.kt
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/desktopmode/DesktopModeUtils.kt
@@ -22,7 +22,6 @@ import android.app.ActivityManager.RunningTaskInfo
import android.app.TaskInfo
import android.content.Intent.FLAG_ACTIVITY_CLEAR_TASK
import android.content.Intent.FLAG_ACTIVITY_MULTIPLE_TASK
-import android.content.Intent.FLAG_ACTIVITY_NEW_TASK
import android.content.pm.ActivityInfo.LAUNCH_MULTIPLE
import android.content.pm.ActivityInfo.LAUNCH_SINGLE_INSTANCE
import android.content.pm.ActivityInfo.LAUNCH_SINGLE_INSTANCE_PER_TASK
@@ -303,21 +302,19 @@ fun getInheritedExistingTaskBounds(
// Top task is an instance of launching activity. Activity will be launching in a new
// task with the existing task also being closed. Inherit existing task bounds to
// prevent new task jumping.
- (isLaunchingNewTask(launchMode, intentFlags) && isClosingExitingInstance(intentFlags)) ->
+ (isLaunchingNewSingleTask(launchMode) && isClosingExitingInstance(intentFlags)) ->
lastTask.configuration.windowConfiguration.bounds
else -> null
}
}
/**
- * Returns true if the launch mode or intent will result in a new task being created for the
- * activity.
+ * Returns true if the launch mode will result in a single new task being created for the activity.
*/
-private fun isLaunchingNewTask(launchMode: Int, intentFlags: Int) =
+private fun isLaunchingNewSingleTask(launchMode: Int) =
launchMode == LAUNCH_SINGLE_TASK ||
launchMode == LAUNCH_SINGLE_INSTANCE ||
- launchMode == LAUNCH_SINGLE_INSTANCE_PER_TASK ||
- (intentFlags and FLAG_ACTIVITY_NEW_TASK) != 0
+ launchMode == LAUNCH_SINGLE_INSTANCE_PER_TASK
/**
* Returns true if the intent will result in an existing task instance being closed if a new one
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/desktopmode/DesktopModeVisualIndicator.java b/libs/WindowManager/Shell/src/com/android/wm/shell/desktopmode/DesktopModeVisualIndicator.java
index 1c5138f486e4..8bbe36dd6644 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/desktopmode/DesktopModeVisualIndicator.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/desktopmode/DesktopModeVisualIndicator.java
@@ -57,7 +57,7 @@ import com.android.wm.shell.shared.bubbles.BubbleAnythingFlagHelper;
import com.android.wm.shell.shared.bubbles.BubbleDropTargetBoundsProvider;
import com.android.wm.shell.windowdecor.tiling.SnapEventHandler;
-import java.util.Arrays;
+import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
@@ -307,7 +307,8 @@ public class DesktopModeVisualIndicator {
if (splitRightRegion.contains(x, y)) {
result = IndicatorType.TO_SPLIT_RIGHT_INDICATOR;
}
- if (BubbleAnythingFlagHelper.enableBubbleToFullscreen()) {
+ if (BubbleAnythingFlagHelper.enableBubbleToFullscreen()
+ && mDragStartState == DragStartState.FROM_FULLSCREEN) {
if (calculateBubbleLeftRegion(layout).contains(x, y)) {
result = IndicatorType.TO_BUBBLE_LEFT_INDICATOR;
} else if (calculateBubbleRightRegion(layout).contains(x, y)) {
@@ -415,30 +416,59 @@ public class DesktopModeVisualIndicator {
private List<Pair<Rect, IndicatorType>> initSmallTabletRegions(DisplayLayout layout,
boolean isLeftRightSplit) {
- boolean dragFromFullscreen = mDragStartState == DragStartState.FROM_FULLSCREEN;
- boolean dragFromSplit = mDragStartState == DragStartState.FROM_SPLIT;
- if (isLeftRightSplit && (dragFromFullscreen || dragFromSplit)) {
+ return switch (mDragStartState) {
+ case DragStartState.FROM_FULLSCREEN -> initSmallTabletRegionsFromFullscreen(layout,
+ isLeftRightSplit);
+ case DragStartState.FROM_SPLIT -> initSmallTabletRegionsFromSplit(layout,
+ isLeftRightSplit);
+ default -> Collections.emptyList();
+ };
+ }
+
+ private List<Pair<Rect, IndicatorType>> initSmallTabletRegionsFromFullscreen(
+ DisplayLayout layout, boolean isLeftRightSplit) {
+
+ List<Pair<Rect, IndicatorType>> result = new ArrayList<>();
+ if (BubbleAnythingFlagHelper.enableBubbleToFullscreen()) {
+ result.add(new Pair<>(calculateBubbleLeftRegion(layout), TO_BUBBLE_LEFT_INDICATOR));
+ result.add(new Pair<>(calculateBubbleRightRegion(layout), TO_BUBBLE_RIGHT_INDICATOR));
+ }
+
+ if (isLeftRightSplit) {
int splitRegionWidth = mContext.getResources().getDimensionPixelSize(
com.android.wm.shell.shared.R.dimen.drag_zone_h_split_from_app_width_fold);
- return Arrays.asList(
- new Pair<>(calculateBubbleLeftRegion(layout), TO_BUBBLE_LEFT_INDICATOR),
- new Pair<>(calculateBubbleRightRegion(layout), TO_BUBBLE_RIGHT_INDICATOR),
- new Pair<>(calculateSplitLeftRegion(layout, splitRegionWidth,
- /* captionHeight= */ 0), TO_SPLIT_LEFT_INDICATOR),
- new Pair<>(calculateSplitRightRegion(layout, splitRegionWidth,
- /* captionHeight= */ 0), TO_SPLIT_RIGHT_INDICATOR),
- new Pair<>(new Rect(), TO_FULLSCREEN_INDICATOR) // default to fullscreen
- );
+ result.add(new Pair<>(calculateSplitLeftRegion(layout, splitRegionWidth,
+ /* captionHeight= */ 0), TO_SPLIT_LEFT_INDICATOR));
+ result.add(new Pair<>(calculateSplitRightRegion(layout, splitRegionWidth,
+ /* captionHeight= */ 0), TO_SPLIT_RIGHT_INDICATOR));
}
- if (dragFromFullscreen) {
- // If left/right split is not available, we can only drag fullscreen tasks
- // TODO(b/401352409): add support for top/bottom split zones
- return Arrays.asList(
- new Pair<>(calculateBubbleLeftRegion(layout), TO_BUBBLE_LEFT_INDICATOR),
- new Pair<>(calculateBubbleRightRegion(layout), TO_BUBBLE_RIGHT_INDICATOR),
- new Pair<>(new Rect(), TO_FULLSCREEN_INDICATOR) // default to fullscreen
- );
+ // TODO(b/401352409): add support for top/bottom split zones
+ // default to fullscreen
+ result.add(new Pair<>(new Rect(), TO_FULLSCREEN_INDICATOR));
+ return result;
+ }
+
+ private List<Pair<Rect, IndicatorType>> initSmallTabletRegionsFromSplit(DisplayLayout layout,
+ boolean isLeftRightSplit) {
+ if (!isLeftRightSplit) {
+ // Dragging a top/bottom split is not supported on small tablets
+ return Collections.emptyList();
}
- return Collections.emptyList();
+
+ List<Pair<Rect, IndicatorType>> result = new ArrayList<>();
+ if (BubbleAnythingFlagHelper.enableBubbleAnything()) {
+ result.add(new Pair<>(calculateBubbleLeftRegion(layout), TO_BUBBLE_LEFT_INDICATOR));
+ result.add(new Pair<>(calculateBubbleRightRegion(layout), TO_BUBBLE_RIGHT_INDICATOR));
+ }
+
+ int splitRegionWidth = mContext.getResources().getDimensionPixelSize(
+ com.android.wm.shell.shared.R.dimen.drag_zone_h_split_from_app_width_fold);
+ result.add(new Pair<>(calculateSplitLeftRegion(layout, splitRegionWidth,
+ /* captionHeight= */ 0), TO_SPLIT_LEFT_INDICATOR));
+ result.add(new Pair<>(calculateSplitRightRegion(layout, splitRegionWidth,
+ /* captionHeight= */ 0), TO_SPLIT_RIGHT_INDICATOR));
+ // default to fullscreen
+ result.add(new Pair<>(new Rect(), TO_FULLSCREEN_INDICATOR));
+ return result;
}
}
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/desktopmode/DesktopPipTransitionController.kt b/libs/WindowManager/Shell/src/com/android/wm/shell/desktopmode/DesktopPipTransitionController.kt
new file mode 100644
index 000000000000..88468531cc47
--- /dev/null
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/desktopmode/DesktopPipTransitionController.kt
@@ -0,0 +1,115 @@
+/*
+ * Copyright (C) 2025 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.desktopmode
+
+import android.app.ActivityManager
+import android.os.IBinder
+import android.window.DesktopExperienceFlags
+import android.window.WindowContainerTransaction
+import com.android.internal.protolog.ProtoLog
+import com.android.wm.shell.common.pip.PipDesktopState
+import com.android.wm.shell.protolog.ShellProtoLogGroup.WM_SHELL_DESKTOP_MODE
+
+/**
+ * Controller to perform extra handling to PiP transitions that are entering while in Desktop mode.
+ */
+class DesktopPipTransitionController(
+ private val desktopTasksController: DesktopTasksController,
+ private val desktopUserRepositories: DesktopUserRepositories,
+ private val pipDesktopState: PipDesktopState,
+) {
+
+ /**
+ * This is called by [PipTransition#handleRequest] when a request for entering PiP is received.
+ *
+ * @param wct WindowContainerTransaction that will apply these changes
+ * @param transition that will apply this transaction
+ * @param taskInfo of the task that is entering PiP
+ */
+ fun handlePipTransition(
+ wct: WindowContainerTransaction,
+ transition: IBinder,
+ taskInfo: ActivityManager.RunningTaskInfo,
+ ) {
+ if (!pipDesktopState.isDesktopWindowingPipEnabled()) {
+ return
+ }
+
+ // Early return if the transition is a synthetic transition that is not backed by a true
+ // system transition.
+ if (transition == DesktopTasksController.SYNTHETIC_TRANSITION) {
+ logD("handlePipTransitionIfInDesktop: SYNTHETIC_TRANSITION, not a true transition")
+ return
+ }
+
+ val taskId = taskInfo.taskId
+ val displayId = taskInfo.displayId
+ val desktopRepository = desktopUserRepositories.getProfile(taskInfo.userId)
+ if (!desktopRepository.isAnyDeskActive(displayId)) {
+ logD("handlePipTransitionIfInDesktop: PiP transition is not in Desktop session")
+ return
+ }
+
+ val deskId =
+ desktopRepository.getActiveDeskId(displayId)
+ ?: if (DesktopExperienceFlags.ENABLE_MULTIPLE_DESKTOPS_BACKEND.isTrue) {
+ logW(
+ "handlePipTransitionIfInDesktop: " +
+ "Active desk not found for display id %d",
+ displayId,
+ )
+ return
+ } else {
+ checkNotNull(desktopRepository.getDefaultDeskId(displayId)) {
+ "$TAG: handlePipTransitionIfInDesktop: " +
+ "Expected a default desk to exist in display with id $displayId"
+ }
+ }
+
+ val isLastTask =
+ desktopRepository.isOnlyVisibleNonClosingTaskInDesk(
+ taskId = taskId,
+ deskId = deskId,
+ displayId = displayId,
+ )
+ if (!isLastTask) {
+ logD("handlePipTransitionIfInDesktop: PiP task is not last visible task in Desk")
+ return
+ }
+
+ val desktopExitRunnable =
+ desktopTasksController.performDesktopExitCleanUp(
+ wct = wct,
+ deskId = deskId,
+ displayId = displayId,
+ willExitDesktop = true,
+ )
+ desktopExitRunnable?.invoke(transition)
+ }
+
+ private fun logW(msg: String, vararg arguments: Any?) {
+ ProtoLog.w(WM_SHELL_DESKTOP_MODE, "%s: $msg", TAG, *arguments)
+ }
+
+ private fun logD(msg: String, vararg arguments: Any?) {
+ ProtoLog.d(WM_SHELL_DESKTOP_MODE, "%s: $msg", TAG, *arguments)
+ }
+
+ private companion object {
+ private const val TAG = "DesktopPipTransitionController"
+ }
+}
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/desktopmode/DesktopPipTransitionObserver.kt b/libs/WindowManager/Shell/src/com/android/wm/shell/desktopmode/DesktopPipTransitionObserver.kt
deleted file mode 100644
index efd3866e1bc4..000000000000
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/desktopmode/DesktopPipTransitionObserver.kt
+++ /dev/null
@@ -1,81 +0,0 @@
-/*
- * Copyright (C) 2025 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.desktopmode
-
-import android.app.WindowConfiguration.WINDOWING_MODE_PINNED
-import android.os.IBinder
-import android.window.DesktopModeFlags
-import android.window.TransitionInfo
-import com.android.internal.protolog.ProtoLog
-import com.android.wm.shell.protolog.ShellProtoLogGroup.WM_SHELL_DESKTOP_MODE
-
-/**
- * Observer of PiP in Desktop Mode transitions. At the moment, this is specifically tracking a PiP
- * transition for a task that is entering PiP via the minimize button on the caption bar.
- */
-class DesktopPipTransitionObserver {
- private val pendingPipTransitions = mutableMapOf<IBinder, PendingPipTransition>()
-
- /** Adds a pending PiP transition to be tracked. */
- fun addPendingPipTransition(transition: PendingPipTransition) {
- if (!DesktopModeFlags.ENABLE_DESKTOP_WINDOWING_PIP.isTrue) return
- pendingPipTransitions[transition.token] = transition
- }
-
- /**
- * Called when any transition is ready, which may include transitions not tracked by this
- * observer.
- */
- fun onTransitionReady(transition: IBinder, info: TransitionInfo) {
- if (!DesktopModeFlags.ENABLE_DESKTOP_WINDOWING_PIP.isTrue) return
- val pipTransition = pendingPipTransitions.remove(transition) ?: return
-
- logD("Desktop PiP transition ready: %s", transition)
- for (change in info.changes) {
- val taskInfo = change.taskInfo
- if (taskInfo == null || taskInfo.taskId == -1) {
- continue
- }
-
- if (
- taskInfo.taskId == pipTransition.taskId &&
- taskInfo.windowingMode == WINDOWING_MODE_PINNED
- ) {
- logD("Desktop PiP transition was successful")
- pipTransition.onSuccess()
- return
- }
- }
- logD("Change with PiP task not found in Desktop PiP transition; likely failed")
- }
-
- /**
- * Data tracked for a pending PiP transition.
- *
- * @property token the PiP transition that is started.
- * @property taskId task id of the task entering PiP.
- * @property onSuccess callback to be invoked if the PiP transition is successful.
- */
- data class PendingPipTransition(val token: IBinder, val taskId: Int, val onSuccess: () -> Unit)
-
- private fun logD(msg: String, vararg arguments: Any?) {
- ProtoLog.d(WM_SHELL_DESKTOP_MODE, "%s: $msg", TAG, *arguments)
- }
-
- private companion object {
- private const val TAG = "DesktopPipTransitionObserver"
- }
-}
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/desktopmode/DesktopRepository.kt b/libs/WindowManager/Shell/src/com/android/wm/shell/desktopmode/DesktopRepository.kt
index e77acfb805a6..25fdbb348356 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/desktopmode/DesktopRepository.kt
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/desktopmode/DesktopRepository.kt
@@ -1112,6 +1112,7 @@ class DesktopRepository(
internal fun dump(pw: PrintWriter, prefix: String) {
val innerPrefix = "$prefix "
pw.println("${prefix}DesktopRepository")
+ pw.println("${innerPrefix}userId=$userId")
dumpDesktopTaskData(pw, innerPrefix)
pw.println("${innerPrefix}activeTasksListeners=${activeTasksListeners.size}")
pw.println("${innerPrefix}visibleTasksListeners=${visibleTasksListeners.size}")
@@ -1298,6 +1299,7 @@ class DesktopRepository(
deskByDisplayId[displayId]?.let { sequenceOf(it) } ?: emptySequence()
override fun remove(deskId: Int) {
+ setDeskInactive(deskId)
deskByDisplayId[deskId]?.clear()
}
@@ -1397,6 +1399,7 @@ class DesktopRepository(
desktopDisplays[displayId]?.orderedDesks?.asSequence() ?: emptySequence()
override fun remove(deskId: Int) {
+ setDeskInactive(deskId)
desktopDisplays.forEach { _, display ->
display.orderedDesks.removeIf { it.deskId == deskId }
}
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 5849d4af4e7e..6214f329e0fd 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
@@ -214,7 +214,6 @@ class DesktopTasksController(
private val overviewToDesktopTransitionObserver: OverviewToDesktopTransitionObserver,
private val desksOrganizer: DesksOrganizer,
private val desksTransitionObserver: DesksTransitionObserver,
- private val desktopPipTransitionObserver: Optional<DesktopPipTransitionObserver>,
private val userProfileContexts: UserProfileContexts,
private val desktopModeCompatPolicy: DesktopModeCompatPolicy,
private val dragToDisplayTransitionHandler: DragToDisplayTransitionHandler,
@@ -449,6 +448,11 @@ class DesktopTasksController(
return false
}
+ // Secondary displays are always desktop-first
+ if (displayId != DEFAULT_DISPLAY) {
+ return true
+ }
+
val tdaInfo = rootTaskDisplayAreaOrganizer.getDisplayAreaInfo(displayId)
// A non-organized display (e.g., non-trusted virtual displays used in CTS) doesn't have
// TDA.
@@ -842,7 +846,6 @@ class DesktopTasksController(
}
val isMinimizingToPip =
DesktopModeFlags.ENABLE_DESKTOP_WINDOWING_PIP.isTrue &&
- desktopPipTransitionObserver.isPresent &&
(taskInfo.pictureInPictureParams?.isAutoEnterEnabled ?: false)
// If task is going to PiP, start a PiP transition instead of a minimize transition
@@ -856,25 +859,23 @@ class DesktopTasksController(
/* displayChange= */ null,
/* flags= */ 0,
)
- val requestRes = transitions.dispatchRequest(Binder(), requestInfo, /* skip= */ null)
+ val requestRes =
+ transitions.dispatchRequest(SYNTHETIC_TRANSITION, requestInfo, /* skip= */ null)
wct.merge(requestRes.second, true)
- desktopPipTransitionObserver
- .get()
- .addPendingPipTransition(
- DesktopPipTransitionObserver.PendingPipTransition(
- token = freeformTaskTransitionStarter.startPipTransition(wct),
- taskId = taskInfo.taskId,
- onSuccess = {
- onDesktopTaskEnteredPip(
- taskId = taskId,
- deskId = deskId,
- displayId = taskInfo.displayId,
- taskIsLastVisibleTaskBeforePip = isLastTask,
- )
- },
+ // If the task minimizing to PiP is the last task, modify wct to perform Desktop cleanup
+ var desktopExitRunnable: RunOnTransitStart? = null
+ if (isLastTask) {
+ desktopExitRunnable =
+ performDesktopExitCleanUp(
+ wct = wct,
+ deskId = deskId,
+ displayId = displayId,
+ willExitDesktop = true,
)
- )
+ }
+ val transition = freeformTaskTransitionStarter.startPipTransition(wct)
+ desktopExitRunnable?.invoke(transition)
} else {
snapEventHandler.removeTaskIfTiled(displayId, taskId)
val willExitDesktop = willExitDesktop(taskId, displayId, forceExitDesktop = false)
@@ -1140,6 +1141,7 @@ class DesktopTasksController(
}
val t =
if (remoteTransition == null) {
+ logV("startLaunchTransition -- no remoteTransition -- wct = $launchTransaction")
desktopMixedTransitionHandler.startLaunchTransition(
transitionType = transitionType,
wct = launchTransaction,
@@ -1887,11 +1889,7 @@ class DesktopTasksController(
displayId: Int,
forceExitDesktop: Boolean,
): Boolean {
- if (
- forceExitDesktop &&
- (DesktopExperienceFlags.ENABLE_MULTIPLE_DESKTOPS_BACKEND.isTrue ||
- DesktopModeFlags.ENABLE_DESKTOP_WINDOWING_PIP.isTrue)
- ) {
+ if (forceExitDesktop && DesktopExperienceFlags.ENABLE_MULTIPLE_DESKTOPS_BACKEND.isTrue) {
// |forceExitDesktop| is true when the callers knows we'll exit desktop, such as when
// explicitly going fullscreen, so there's no point in checking the desktop state.
return true
@@ -1908,33 +1906,6 @@ class DesktopTasksController(
return true
}
- /** Potentially perform Desktop cleanup after a task successfully enters PiP. */
- @VisibleForTesting
- fun onDesktopTaskEnteredPip(
- taskId: Int,
- deskId: Int,
- displayId: Int,
- taskIsLastVisibleTaskBeforePip: Boolean,
- ) {
- if (
- !willExitDesktop(taskId, displayId, forceExitDesktop = taskIsLastVisibleTaskBeforePip)
- ) {
- return
- }
-
- val wct = WindowContainerTransaction()
- val desktopExitRunnable =
- performDesktopExitCleanUp(
- wct = wct,
- deskId = deskId,
- displayId = displayId,
- willExitDesktop = true,
- )
-
- val transition = transitions.startTransition(TRANSIT_CHANGE, wct, /* handler= */ null)
- desktopExitRunnable?.invoke(transition)
- }
-
private fun performDesktopExitCleanupIfNeeded(
taskId: Int,
deskId: Int? = null,
@@ -1958,7 +1929,7 @@ class DesktopTasksController(
}
/** TODO: b/394268248 - update [deskId] to be non-null. */
- private fun performDesktopExitCleanUp(
+ fun performDesktopExitCleanUp(
wct: WindowContainerTransaction,
deskId: Int?,
displayId: Int,
@@ -2793,11 +2764,14 @@ class DesktopTasksController(
taskInfo: RunningTaskInfo,
deskId: Int?,
): RunOnTransitStart? {
- // This windowing mode is to get the transition animation started; once we complete
- // split select, we will change windowing mode to undefined and inherit from split stage.
- // Going to undefined here causes task to flicker to the top left.
- // Cancelling the split select flow will revert it to fullscreen.
- wct.setWindowingMode(taskInfo.token, WINDOWING_MODE_MULTI_WINDOW)
+ if (!DesktopModeFlags.ENABLE_INPUT_LAYER_TRANSITION_FIX.isTrue) {
+ // This windowing mode is to get the transition animation started; once we complete
+ // split select, we will change windowing mode to undefined and inherit from split
+ // stage.
+ // Going to undefined here causes task to flicker to the top left.
+ // Cancelling the split select flow will revert it to fullscreen.
+ wct.setWindowingMode(taskInfo.token, WINDOWING_MODE_MULTI_WINDOW)
+ }
// The task's density may have been overridden in freeform; revert it here as we don't
// want it overridden in multi-window.
wct.setDensityDpi(taskInfo.token, getDefaultDensityDpi())
@@ -2892,7 +2866,7 @@ class DesktopTasksController(
* null and may be used to run other desktop policies, such as minimizing another task if the
* task limit has been exceeded.
*/
- fun addDeskActivationChanges(
+ private fun addDeskActivationChanges(
deskId: Int,
wct: WindowContainerTransaction,
newTask: TaskInfo? = null,
@@ -2950,6 +2924,8 @@ class DesktopTasksController(
}
}
}
+ val deactivatingDesk = taskRepository.getActiveDeskId(displayId)?.takeIf { it != deskId }
+ val deactivationRunnable = prepareDeskDeactivationIfNeeded(wct, deactivatingDesk)
return { transition ->
val activateDeskTransition =
if (newTaskIdInFront != null) {
@@ -2970,6 +2946,7 @@ class DesktopTasksController(
taskIdToMinimize?.let { minimizingTask ->
addPendingMinimizeTransition(transition, minimizingTask, MinimizeReason.TASK_LIMIT)
}
+ deactivationRunnable?.invoke(transition)
}
}
@@ -3955,6 +3932,12 @@ class DesktopTasksController(
DesktopTaskToFrontReason.TASKBAR_MANAGE_WINDOW ->
UnminimizeReason.TASKBAR_MANAGE_WINDOW
}
+
+ @JvmField
+ /**
+ * A placeholder for a synthetic transition that isn't backed by a true system transition.
+ */
+ val SYNTHETIC_TRANSITION: IBinder = Binder()
}
/** Defines interface for classes that can listen to changes for task resize. */
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/desktopmode/DesktopTasksTransitionObserver.kt b/libs/WindowManager/Shell/src/com/android/wm/shell/desktopmode/DesktopTasksTransitionObserver.kt
index df4d18f8c803..3fd955d112f0 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/desktopmode/DesktopTasksTransitionObserver.kt
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/desktopmode/DesktopTasksTransitionObserver.kt
@@ -42,7 +42,6 @@ import com.android.wm.shell.shared.TransitionUtil.isOpeningMode
import com.android.wm.shell.shared.desktopmode.DesktopModeStatus
import com.android.wm.shell.sysui.ShellInit
import com.android.wm.shell.transition.Transitions
-import java.util.Optional
/**
* A [Transitions.TransitionObserver] that observes shell transitions and updates the
@@ -55,7 +54,6 @@ class DesktopTasksTransitionObserver(
private val transitions: Transitions,
private val shellTaskOrganizer: ShellTaskOrganizer,
private val desktopMixedTransitionHandler: DesktopMixedTransitionHandler,
- private val desktopPipTransitionObserver: Optional<DesktopPipTransitionObserver>,
private val backAnimationController: BackAnimationController,
private val desktopWallpaperActivityTokenProvider: DesktopWallpaperActivityTokenProvider,
shellInit: ShellInit,
@@ -97,7 +95,6 @@ class DesktopTasksTransitionObserver(
removeTaskIfNeeded(info)
}
removeWallpaperOnLastTaskClosingIfNeeded(transition, info)
- desktopPipTransitionObserver.ifPresent { it.onTransitionReady(transition, info) }
}
private fun removeTaskIfNeeded(info: TransitionInfo) {
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/desktopmode/DesktopUserRepositories.kt b/libs/WindowManager/Shell/src/com/android/wm/shell/desktopmode/DesktopUserRepositories.kt
index c10752d36bf9..72758bd538d6 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/desktopmode/DesktopUserRepositories.kt
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/desktopmode/DesktopUserRepositories.kt
@@ -21,6 +21,7 @@ import android.content.Context
import android.content.pm.UserInfo
import android.os.UserManager
import android.util.SparseArray
+import android.window.DesktopExperienceFlags
import android.window.DesktopModeFlags.ENABLE_DESKTOP_WINDOWING_HSUM
import androidx.core.util.forEach
import com.android.internal.protolog.ProtoLog
@@ -68,7 +69,10 @@ class DesktopUserRepositories(
if (DesktopModeStatus.canEnterDesktopMode(context)) {
shellInit.addInitCallback(::onInit, this)
}
- if (ENABLE_DESKTOP_WINDOWING_HSUM.isTrue()) {
+ if (
+ ENABLE_DESKTOP_WINDOWING_HSUM.isTrue() &&
+ !DesktopExperienceFlags.ENABLE_MULTIPLE_DESKTOPS_BACKEND.isTrue
+ ) {
userIdToProfileIdsMap[userId] = userManager.getProfiles(userId).map { it.id }
}
}
@@ -76,6 +80,13 @@ class DesktopUserRepositories(
private fun onInit() {
repositoryInitializer.initialize(this)
shellController.addUserChangeListener(this)
+ if (
+ ENABLE_DESKTOP_WINDOWING_HSUM.isTrue() &&
+ DesktopExperienceFlags.ENABLE_MULTIPLE_DESKTOPS_BACKEND.isTrue
+ ) {
+ userId = ActivityManager.getCurrentUser()
+ userIdToProfileIdsMap[userId] = userManager.getProfiles(userId).map { it.id }
+ }
}
/** Returns [DesktopRepository] for the parent user id. */
@@ -97,10 +108,10 @@ class DesktopUserRepositories(
/** Dumps [DesktopRepository] for each user. */
fun dump(pw: PrintWriter, prefix: String) {
- desktopRepoByUserId.forEach { key, value ->
- pw.println("${prefix}userId=$key")
- value.dump(pw, prefix)
- }
+ val innerPrefix = "$prefix "
+ pw.println("${prefix}DesktopUserRepositories:")
+ pw.println("${innerPrefix}currentUserId=$userId")
+ desktopRepoByUserId.forEach { key, value -> value.dump(pw, innerPrefix) }
}
override fun onUserChanged(newUserId: Int, userContext: Context) {
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/desktopmode/multidesks/DesksOrganizer.kt b/libs/WindowManager/Shell/src/com/android/wm/shell/desktopmode/multidesks/DesksOrganizer.kt
index 5a988fcd1b77..1effcdb20505 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/desktopmode/multidesks/DesksOrganizer.kt
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/desktopmode/multidesks/DesksOrganizer.kt
@@ -78,6 +78,9 @@ interface DesksOrganizer {
/** Whether the desk is activate according to the given change at the end of a transition. */
fun isDeskActiveAtEnd(change: TransitionInfo.Change, deskId: Int): Boolean
+ /** Allows for other classes to respond to task changes this organizer receives. */
+ fun setOnDesktopTaskInfoChangedListener(listener: (ActivityManager.RunningTaskInfo) -> Unit)
+
/** A callback that is invoked when the desk container is created. */
fun interface OnCreateCallback {
/** Calls back when the [deskId] has been created. */
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/desktopmode/multidesks/RootTaskDesksOrganizer.kt b/libs/WindowManager/Shell/src/com/android/wm/shell/desktopmode/multidesks/RootTaskDesksOrganizer.kt
index 49ca58e7b32a..c30987ac7640 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/desktopmode/multidesks/RootTaskDesksOrganizer.kt
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/desktopmode/multidesks/RootTaskDesksOrganizer.kt
@@ -54,6 +54,7 @@ class RootTaskDesksOrganizer(
mutableListOf<CreateDeskMinimizationRootRequest>()
@VisibleForTesting
val deskMinimizationRootsByDeskId: MutableMap<Int, DeskMinimizationRoot> = mutableMapOf()
+ private var onTaskInfoChangedListener: ((RunningTaskInfo) -> Unit)? = null
init {
if (DesktopExperienceFlags.ENABLE_MULTIPLE_DESKTOPS_BACKEND.isTrue) {
@@ -213,6 +214,10 @@ class RootTaskDesksOrganizer(
change.taskInfo?.isVisibleRequested == true &&
change.mode == TRANSIT_TO_FRONT
+ override fun setOnDesktopTaskInfoChangedListener(listener: (RunningTaskInfo) -> Unit) {
+ onTaskInfoChangedListener = listener
+ }
+
override fun onTaskAppeared(taskInfo: RunningTaskInfo, leash: SurfaceControl) {
handleTaskAppeared(taskInfo, leash)
updateLaunchAdjacentController()
@@ -220,6 +225,12 @@ class RootTaskDesksOrganizer(
override fun onTaskInfoChanged(taskInfo: RunningTaskInfo) {
handleTaskInfoChanged(taskInfo)
+ if (
+ taskInfo.taskId !in deskRootsByDeskId &&
+ deskMinimizationRootsByDeskId.values.none { it.rootId == taskInfo.taskId }
+ ) {
+ onTaskInfoChangedListener?.invoke(taskInfo)
+ }
updateLaunchAdjacentController()
}
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/draganddrop/DragLayout.java b/libs/WindowManager/Shell/src/com/android/wm/shell/draganddrop/DragLayout.java
index b3c1a92f5e1d..d6084138b7e7 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/draganddrop/DragLayout.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/draganddrop/DragLayout.java
@@ -663,6 +663,9 @@ public class DragLayout extends LinearLayout
mSession = null;
}
});
+ // notify bubbles of drag cancel
+ mCurrentBubbleBarTarget = null;
+ mBubbleBarDragListener.onItemDraggedOutsideBubbleBarDropZone();
// Reset the state if we previously force-ignore the bottom margin
mDropZoneView1.setForceIgnoreBottomMargin(false);
mDropZoneView2.setForceIgnoreBottomMargin(false);
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/freeform/FreeformTaskTransitionObserver.java b/libs/WindowManager/Shell/src/com/android/wm/shell/freeform/FreeformTaskTransitionObserver.java
index e7492f17835a..2476ee1a4090 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/freeform/FreeformTaskTransitionObserver.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/freeform/FreeformTaskTransitionObserver.java
@@ -174,7 +174,7 @@ public class FreeformTaskTransitionObserver implements Transitions.TransitionObs
SurfaceControl.Transaction finishT) {
mTaskChangeListener.ifPresent(listener -> listener.onTaskChanging(change.getTaskInfo()));
mWindowDecorViewModel.onTaskChanging(
- change.getTaskInfo(), change.getLeash(), startT, finishT, change.getMode());
+ change.getTaskInfo(), change.getLeash(), startT, finishT);
}
private void onToFrontTransitionReady(
@@ -184,7 +184,7 @@ public class FreeformTaskTransitionObserver implements Transitions.TransitionObs
mTaskChangeListener.ifPresent(
listener -> listener.onTaskMovingToFront(change.getTaskInfo()));
mWindowDecorViewModel.onTaskChanging(
- change.getTaskInfo(), change.getLeash(), startT, finishT, change.getMode());
+ change.getTaskInfo(), change.getLeash(), startT, finishT);
}
private void onToBackTransitionReady(
@@ -194,7 +194,7 @@ public class FreeformTaskTransitionObserver implements Transitions.TransitionObs
mTaskChangeListener.ifPresent(
listener -> listener.onTaskMovingToBack(change.getTaskInfo()));
mWindowDecorViewModel.onTaskChanging(
- change.getTaskInfo(), change.getLeash(), startT, finishT, change.getMode());
+ change.getTaskInfo(), change.getLeash(), startT, finishT);
}
@Override
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/pip2/phone/PipTransition.java b/libs/WindowManager/Shell/src/com/android/wm/shell/pip2/phone/PipTransition.java
index 5d8d8b685a23..9ec1c7d65a6e 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/pip2/phone/PipTransition.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/pip2/phone/PipTransition.java
@@ -50,7 +50,9 @@ import android.graphics.Point;
import android.graphics.PointF;
import android.graphics.Rect;
import android.os.Bundle;
+import android.os.Debug;
import android.os.IBinder;
+import android.util.Log;
import android.view.SurfaceControl;
import android.view.WindowManager;
import android.window.TransitionInfo;
@@ -71,6 +73,7 @@ import com.android.wm.shell.common.pip.PipDesktopState;
import com.android.wm.shell.common.pip.PipDisplayLayoutState;
import com.android.wm.shell.common.pip.PipMenuController;
import com.android.wm.shell.common.pip.PipUtils;
+import com.android.wm.shell.desktopmode.DesktopPipTransitionController;
import com.android.wm.shell.pip.PipTransitionController;
import com.android.wm.shell.pip2.PipSurfaceTransactionHelper;
import com.android.wm.shell.pip2.animation.PipAlphaAnimator;
@@ -115,6 +118,7 @@ public class PipTransition extends PipTransitionController implements
private final DisplayController mDisplayController;
private final PipSurfaceTransactionHelper mPipSurfaceTransactionHelper;
private final PipDesktopState mPipDesktopState;
+ private final Optional<DesktopPipTransitionController> mDesktopPipTransitionController;
private final PipInteractionHandler mPipInteractionHandler;
//
@@ -158,6 +162,7 @@ public class PipTransition extends PipTransitionController implements
DisplayController displayController,
Optional<SplitScreenController> splitScreenControllerOptional,
PipDesktopState pipDesktopState,
+ Optional<DesktopPipTransitionController> desktopPipTransitionController,
PipInteractionHandler pipInteractionHandler) {
super(shellInit, shellTaskOrganizer, transitions, pipBoundsState, pipMenuController,
pipBoundsAlgorithm);
@@ -172,6 +177,7 @@ public class PipTransition extends PipTransitionController implements
mDisplayController = displayController;
mPipSurfaceTransactionHelper = new PipSurfaceTransactionHelper(mContext);
mPipDesktopState = pipDesktopState;
+ mDesktopPipTransitionController = desktopPipTransitionController;
mPipInteractionHandler = pipInteractionHandler;
mExpandHandler = new PipExpandHandler(mContext, pipBoundsState, pipBoundsAlgorithm,
@@ -227,7 +233,18 @@ public class PipTransition extends PipTransitionController implements
@NonNull TransitionRequestInfo request) {
if (isAutoEnterInButtonNavigation(request) || isEnterPictureInPictureModeRequest(request)) {
mEnterTransition = transition;
- return getEnterPipTransaction(transition, request.getPipChange());
+ final WindowContainerTransaction wct = getEnterPipTransaction(transition,
+ request.getPipChange());
+
+ mDesktopPipTransitionController.ifPresent(
+ desktopPipTransitionController ->
+ desktopPipTransitionController.handlePipTransition(
+ wct,
+ transition,
+ request.getPipChange().getTaskInfo()
+ )
+ );
+ return wct;
}
return null;
}
@@ -300,6 +317,20 @@ public class PipTransition extends PipTransitionController implements
return startAlphaTypeEnterAnimation(info, startTransaction, finishTransaction,
finishCallback);
}
+
+ TransitionInfo.Change pipActivityChange = PipTransitionUtils
+ .getDeferConfigActivityChange(info, pipChange.getTaskInfo().getToken());
+ if (pipActivityChange == null) {
+ // Legacy-enter and swipe-pip-to-home filters did not resolve a scheduled PiP entry.
+ // Bounds-type enter animation is the last resort, and it requires a config-at-end
+ // activity amongst the list of changes. If no such change, something went wrong.
+ Log.wtf(TAG, String.format("""
+ PipTransition.startAnimation didn't handle a scheduled PiP entry
+ transitionInfo=%s,
+ callers=%s""", info, Debug.getCallers(4)));
+ return false;
+ }
+
return startBoundsTypeEnterAnimation(info, startTransaction, finishTransaction,
finishCallback);
} else if (transition == mExitViaExpandTransition) {
@@ -824,26 +855,15 @@ public class PipTransition extends PipTransitionController implements
return true;
}
- // Sometimes root PiP task can have TF children. These child containers can be collected
- // even if they can promote to their parents: e.g. if they are marked as "organized".
- // So we count the chain of containers under PiP task as one "real" changing target;
- // iterate through changes bottom-to-top to properly identify parents.
- int expectedTargetCount = 1;
- WindowContainerToken lastPipChildToken = pipChange.getContainer();
- for (int i = info.getChanges().size() - 1; i >= 0; --i) {
- TransitionInfo.Change change = info.getChanges().get(i);
- if (change == pipChange || change.getContainer() == null) continue;
- if (change.getParent() != null && change.getParent().equals(lastPipChildToken)) {
- // Allow an extra change since our pinned root task has a child.
- ++expectedTargetCount;
- lastPipChildToken = change.getContainer();
- }
- }
-
- // If the only root task change in the changes list is a opening type PiP task,
- // then this is legacy-enter PiP.
- return info.getChanges().size() == expectedTargetCount
- && TransitionUtil.isOpeningMode(pipChange.getMode());
+ // #getEnterPipTransaction() always attempts to mark PiP activity as config-at-end one.
+ // However, the activity will only actually be marked config-at-end by Core if it is
+ // both isVisible and isVisibleRequested, which is when we can't run bounds animation.
+ //
+ // So we can use the absence of a config-at-end activity as a signal that we should run
+ // a legacy-enter PiP animation instead.
+ return TransitionUtil.isOpeningMode(pipChange.getMode())
+ && PipTransitionUtils.getDeferConfigActivityChange(
+ info, pipChange.getContainer()) == null;
}
return false;
}
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/splitscreen/StageCoordinator.java b/libs/WindowManager/Shell/src/com/android/wm/shell/splitscreen/StageCoordinator.java
index 014c810d1e5f..10db5ca03637 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/splitscreen/StageCoordinator.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/splitscreen/StageCoordinator.java
@@ -124,7 +124,6 @@ import android.view.SurfaceControl;
import android.view.WindowManager;
import android.widget.Toast;
import android.window.DesktopExperienceFlags;
-import android.window.DesktopModeFlags;
import android.window.DisplayAreaInfo;
import android.window.RemoteTransition;
import android.window.TransitionInfo;
@@ -684,8 +683,7 @@ public class StageCoordinator implements SplitLayout.SplitLayoutHandler,
if (!enteredSplitSelect) {
return null;
}
- if (!DesktopExperienceFlags.ENABLE_MULTIPLE_DESKTOPS_BACKEND.isTrue()
- && !DesktopModeFlags.ENABLE_INPUT_LAYER_TRANSITION_FIX.isTrue()) {
+ if (!DesktopExperienceFlags.ENABLE_MULTIPLE_DESKTOPS_BACKEND.isTrue()) {
mTaskOrganizer.applyTransaction(wct);
return null;
}
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/taskview/TaskViewTransitions.java b/libs/WindowManager/Shell/src/com/android/wm/shell/taskview/TaskViewTransitions.java
index a6f872634ee9..22848c38bb1c 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/taskview/TaskViewTransitions.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/taskview/TaskViewTransitions.java
@@ -728,6 +728,48 @@ public class TaskViewTransitions implements Transitions.TransitionHandler, TaskV
taskView.notifyAppeared(newTask);
}
+ /**
+ * Updates bounds for the task view during an unfold transition.
+ *
+ * @return true if the task was found and a transition for this task is pending. false
+ * otherwise.
+ */
+ public boolean updateBoundsForUnfold(Rect bounds, SurfaceControl.Transaction startTransaction,
+ SurfaceControl.Transaction finishTransaction,
+ ActivityManager.RunningTaskInfo taskInfo, SurfaceControl leash) {
+ final TaskViewTaskController taskView = findTaskView(taskInfo);
+ if (taskView == null) {
+ return false;
+ }
+
+ final PendingTransition pendingTransition = findPending(taskView, TRANSIT_CHANGE);
+ if (pendingTransition == null) {
+ return false;
+ }
+
+ mPending.remove(pendingTransition);
+
+ // reparent the task under the task view surface and set the bounds on it
+ startTransaction.reparent(leash, taskView.getSurfaceControl())
+ .setPosition(leash, 0, 0)
+ .setWindowCrop(leash, bounds.width(), bounds.height())
+ .show(leash);
+ // the finish transaction would reparent the task back to the transition root, so reparent
+ // it again to the task view surface
+ finishTransaction.reparent(leash, taskView.getSurfaceControl())
+ .setPosition(leash, 0, 0)
+ .setWindowCrop(leash, bounds.width(), bounds.height());
+ if (useRepo()) {
+ final TaskViewRepository.TaskViewState state = mTaskViewRepo.byTaskView(taskView);
+ if (state != null) {
+ state.mBounds.set(bounds);
+ }
+ } else {
+ updateBoundsState(taskView, bounds);
+ }
+ return true;
+ }
+
private void updateBounds(TaskViewTaskController taskView, Rect boundsOnScreen,
SurfaceControl.Transaction startTransaction,
SurfaceControl.Transaction finishTransaction,
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/transition/DefaultSurfaceAnimator.java b/libs/WindowManager/Shell/src/com/android/wm/shell/transition/DefaultSurfaceAnimator.java
index ce98b03b77a6..bff08ba6d88f 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/transition/DefaultSurfaceAnimator.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/transition/DefaultSurfaceAnimator.java
@@ -42,9 +42,10 @@ public class DefaultSurfaceAnimator {
@NonNull Animation anim, @NonNull SurfaceControl leash,
@NonNull Runnable finishCallback, @NonNull TransactionPool pool,
@NonNull ShellExecutor mainExecutor, @Nullable Point position, float cornerRadius,
- @Nullable Rect clipRect) {
+ @Nullable Rect clipRect,
+ @Nullable TransitionAnimationHelper.RoundedContentPerDisplay roundedBounds) {
final DefaultAnimationAdapter adapter = new DefaultAnimationAdapter(anim, leash,
- position, clipRect, cornerRadius);
+ position, clipRect, cornerRadius, roundedBounds);
buildSurfaceAnimation(animations, anim, finishCallback, pool, mainExecutor, adapter);
}
@@ -109,9 +110,17 @@ public class DefaultSurfaceAnimator {
@Nullable final Rect mClipRect;
@Nullable private final Rect mAnimClipRect;
final float mCornerRadius;
+ final int mWindowBottom;
+
+ /**
+ * Inset changes aren't synchronized with transitions, so use a "provider" to track the
+ * bottom of the display content during the animation.
+ */
+ @Nullable final TransitionAnimationHelper.RoundedContentPerDisplay mRoundedContentBounds;
DefaultAnimationAdapter(@NonNull Animation anim, @NonNull SurfaceControl leash,
- @Nullable Point position, @Nullable Rect clipRect, float cornerRadius) {
+ @Nullable Point position, @Nullable Rect clipRect, float cornerRadius,
+ TransitionAnimationHelper.RoundedContentPerDisplay roundedBounds) {
super(leash);
mAnim = anim;
mPosition = (position != null && (position.x != 0 || position.y != 0))
@@ -119,6 +128,8 @@ public class DefaultSurfaceAnimator {
mClipRect = (clipRect != null && !clipRect.isEmpty()) ? clipRect : null;
mAnimClipRect = mClipRect != null ? new Rect() : null;
mCornerRadius = cornerRadius;
+ mWindowBottom = clipRect != null ? clipRect.bottom : 0;
+ mRoundedContentBounds = roundedBounds;
}
@Override
@@ -136,6 +147,11 @@ public class DefaultSurfaceAnimator {
if (mClipRect != null) {
boolean needCrop = false;
+ if (mRoundedContentBounds != null) {
+ mClipRect.bottom = Math.min(mRoundedContentBounds.mBounds.bottom,
+ mWindowBottom);
+ }
+
mAnimClipRect.set(mClipRect);
if (transformation.hasClipRect()) {
mAnimClipRect.intersectUnchecked(transformation.getClipRect());
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/transition/DefaultTransitionHandler.java b/libs/WindowManager/Shell/src/com/android/wm/shell/transition/DefaultTransitionHandler.java
index bf5800330979..5b6993863c5d 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/transition/DefaultTransitionHandler.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/transition/DefaultTransitionHandler.java
@@ -59,13 +59,13 @@ import static android.window.TransitionInfo.FLAG_STARTING_WINDOW_TRANSFER_RECIPI
import static android.window.TransitionInfo.FLAG_TRANSLUCENT;
import static com.android.internal.jank.Cuj.CUJ_DEFAULT_TASK_TO_TASK_ANIMATION;
-import static com.android.internal.policy.TransitionAnimation.DEFAULT_APP_TRANSITION_DURATION;
import static com.android.internal.policy.TransitionAnimation.WALLPAPER_TRANSITION_CHANGE;
import static com.android.internal.policy.TransitionAnimation.WALLPAPER_TRANSITION_CLOSE;
import static com.android.internal.policy.TransitionAnimation.WALLPAPER_TRANSITION_INTRA_CLOSE;
import static com.android.internal.policy.TransitionAnimation.WALLPAPER_TRANSITION_INTRA_OPEN;
import static com.android.internal.policy.TransitionAnimation.WALLPAPER_TRANSITION_NONE;
import static com.android.internal.policy.TransitionAnimation.WALLPAPER_TRANSITION_OPEN;
+import static com.android.wm.shell.Flags.enableDynamicInsetsForAppLaunch;
import static com.android.wm.shell.transition.DefaultSurfaceAnimator.buildSurfaceAnimation;
import static com.android.wm.shell.transition.TransitionAnimationHelper.getTransitionBackgroundColorIfSet;
import static com.android.wm.shell.transition.TransitionAnimationHelper.getTransitionTypeFromInfo;
@@ -111,11 +111,13 @@ import com.android.window.flags.Flags;
import com.android.wm.shell.RootTaskDisplayAreaOrganizer;
import com.android.wm.shell.animation.SizeChangeAnimation;
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.ShellExecutor;
import com.android.wm.shell.protolog.ShellProtoLogGroup;
import com.android.wm.shell.shared.TransactionPool;
import com.android.wm.shell.shared.TransitionUtil;
+import com.android.wm.shell.shared.animation.Interpolators;
import com.android.wm.shell.sysui.ShellInit;
import java.util.ArrayList;
@@ -125,15 +127,18 @@ import java.util.function.Consumer;
/** The default handler that handles anything not already handled. */
public class DefaultTransitionHandler implements Transitions.TransitionHandler {
private static final int MAX_ANIMATION_DURATION = 3000;
+ private static final int SIZE_CHANGE_ANIMATION_DURATION = 400;
private final TransactionPool mTransactionPool;
private final DisplayController mDisplayController;
private final Context mContext;
private final Handler mMainHandler;
+ private final Handler mAnimHandler;
private final ShellExecutor mMainExecutor;
private final ShellExecutor mAnimExecutor;
private final TransitionAnimation mTransitionAnimation;
private final DevicePolicyManager mDevicePolicyManager;
+ private final TransitionAnimationHelper.RoundedContentTracker mRoundedContentBounds;
/** Keeps track of the currently-running animations associated with each transition. */
private final ArrayMap<IBinder, ArrayList<Animator>> mAnimations = new ArrayMap<>();
@@ -163,9 +168,11 @@ public class DefaultTransitionHandler implements Transitions.TransitionHandler {
DefaultTransitionHandler(@NonNull Context context,
@NonNull ShellInit shellInit,
@NonNull DisplayController displayController,
+ @NonNull DisplayInsetsController displayInsetsController,
@NonNull TransactionPool transactionPool,
@NonNull ShellExecutor mainExecutor, @NonNull Handler mainHandler,
@NonNull ShellExecutor animExecutor,
+ @NonNull Handler animHandler,
@NonNull RootTaskDisplayAreaOrganizer rootTDAOrganizer,
@NonNull InteractionJankMonitor interactionJankMonitor) {
mDisplayController = displayController;
@@ -174,11 +181,14 @@ public class DefaultTransitionHandler implements Transitions.TransitionHandler {
mMainHandler = mainHandler;
mMainExecutor = mainExecutor;
mAnimExecutor = animExecutor;
+ mAnimHandler = animHandler;
mTransitionAnimation = new TransitionAnimation(context, false /* debug */, Transitions.TAG);
mCurrentUserId = UserHandle.myUserId();
mDevicePolicyManager = mContext.getSystemService(DevicePolicyManager.class);
shellInit.addInitCallback(this::onInit, this);
mRootTDAOrganizer = rootTDAOrganizer;
+ mRoundedContentBounds = new TransitionAnimationHelper.RoundedContentTracker(
+ displayController, displayInsetsController);
mInteractionJankMonitor = interactionJankMonitor;
}
@@ -191,6 +201,7 @@ public class DefaultTransitionHandler implements Transitions.TransitionHandler {
mMainHandler);
TransitionAnimation.initAttributeCache(mContext, mMainHandler);
+ mRoundedContentBounds.init();
}
private void updateEnterpriseThumbnailDrawable() {
@@ -297,6 +308,18 @@ public class DefaultTransitionHandler implements Transitions.TransitionHandler {
return ROTATION_ANIMATION_SEAMLESS;
}
+ @Nullable
+ final TransitionAnimationHelper.RoundedContentPerDisplay getRoundedContentBounds(
+ TransitionInfo.Change change) {
+ if (!enableDynamicInsetsForAppLaunch()) {
+ return null;
+ }
+ if (change.getTaskInfo() == null && change.getActivityComponent() == null) {
+ return null;
+ }
+ return mRoundedContentBounds.forDisplay(change.getEndDisplayId());
+ }
+
@Override
public boolean startAnimation(@NonNull IBinder transition, @NonNull TransitionInfo info,
@NonNull SurfaceControl.Transaction startTransaction,
@@ -329,10 +352,6 @@ public class DefaultTransitionHandler implements Transitions.TransitionHandler {
mAnimations.put(transition, animations);
final boolean isTaskTransition = isTaskTransition(info);
- if (isTaskTransition) {
- mInteractionJankMonitor.begin(info.getRoot(0).getLeash(), mContext,
- mMainHandler, CUJ_DEFAULT_TASK_TO_TASK_ANIMATION);
- }
final Runnable onAnimFinish = () -> {
if (!animations.isEmpty()) return;
@@ -556,7 +575,8 @@ public class DefaultTransitionHandler implements Transitions.TransitionHandler {
change.getEndAbsBounds().left - animRoot.getOffset().x,
change.getEndAbsBounds().top - animRoot.getOffset().y);
- if (change.getActivityComponent() != null) {
+ final boolean isActivity = change.getActivityComponent() != null;
+ if (isActivity) {
// For appcompat letterbox: we intentionally report the task-bounds so that we
// can animate as-if letterboxes are "part of" the activity. This means we can't
// always rely solely on endAbsBounds and need to also max with endRelOffset.
@@ -564,7 +584,7 @@ public class DefaultTransitionHandler implements Transitions.TransitionHandler {
animRelOffset.y = Math.max(animRelOffset.y, change.getEndRelOffset().y);
}
- if (change.getActivityComponent() != null && !isActivityLevel
+ if (isActivity && !isActivityLevel
&& !mRotator.isRotated(change)) {
// At this point, this is an independent activity change in a non-activity
// transition. This means that an activity transition got erroneously combined
@@ -589,8 +609,10 @@ public class DefaultTransitionHandler implements Transitions.TransitionHandler {
}
buildSurfaceAnimation(animations, a, change.getLeash(), onAnimFinish,
- mTransactionPool, mMainExecutor, animRelOffset, cornerRadius,
- clipRect);
+ mTransactionPool, mMainExecutor, animRelOffset, cornerRadius, clipRect,
+ isTask || isActivity
+ ? mRoundedContentBounds.forDisplay(change.getEndDisplayId())
+ : null);
final TransitionInfo.AnimationOptions options = change.getAnimationOptions();
if (options != null) {
@@ -619,6 +641,10 @@ public class DefaultTransitionHandler implements Transitions.TransitionHandler {
// now start animations. they are started on another thread, so we have to post them
// *after* applying the startTransaction
mAnimExecutor.execute(() -> {
+ if (isTaskTransition) {
+ mInteractionJankMonitor.begin(info.getRoot(0).getLeash(), mContext,
+ mAnimHandler, CUJ_DEFAULT_TASK_TO_TASK_ANIMATION);
+ }
for (int i = 0; i < animations.size(); ++i) {
animations.get(i).start();
}
@@ -779,15 +805,16 @@ public class DefaultTransitionHandler implements Transitions.TransitionHandler {
private void startBoundsChangeAnimation(@NonNull SurfaceControl.Transaction startT,
@NonNull ArrayList<Animator> animations, @NonNull TransitionInfo.Change change,
@NonNull Runnable finishCb, @NonNull ShellExecutor mainExecutor) {
- final SizeChangeAnimation sca =
- new SizeChangeAnimation(change.getStartAbsBounds(), change.getEndAbsBounds());
+ final SizeChangeAnimation sca = new SizeChangeAnimation(change.getStartAbsBounds(),
+ change.getEndAbsBounds(), /* initialScale= */ 1f, /* scaleFactor= */ 1f);
sca.initialize(change.getLeash(), change.getSnapshot(), startT);
final ValueAnimator va = sca.buildAnimator(change.getLeash(), change.getSnapshot(),
(animator) -> mainExecutor.execute(() -> {
animations.remove(animator);
finishCb.run();
}));
- va.setDuration(DEFAULT_APP_TRANSITION_DURATION);
+ va.setDuration(SIZE_CHANGE_ANIMATION_DURATION);
+ va.setInterpolator(Interpolators.EMPHASIZED);
animations.add(va);
}
@@ -932,7 +959,8 @@ public class DefaultTransitionHandler implements Transitions.TransitionHandler {
a.restrictDuration(MAX_ANIMATION_DURATION);
a.scaleCurrentDuration(mTransitionAnimationScaleSetting);
buildSurfaceAnimation(animations, a, wt.getSurface(), finisher, mTransactionPool,
- mMainExecutor, change.getEndRelOffset(), cornerRadius, change.getEndAbsBounds());
+ mMainExecutor, change.getEndRelOffset(), cornerRadius, change.getEndAbsBounds(),
+ getRoundedContentBounds(change));
}
private void attachThumbnailAnimation(@NonNull ArrayList<Animator> animations,
@@ -956,7 +984,8 @@ public class DefaultTransitionHandler implements Transitions.TransitionHandler {
a.restrictDuration(MAX_ANIMATION_DURATION);
a.scaleCurrentDuration(mTransitionAnimationScaleSetting);
buildSurfaceAnimation(animations, a, wt.getSurface(), finisher, mTransactionPool,
- mMainExecutor, change.getEndRelOffset(), cornerRadius, change.getEndAbsBounds());
+ mMainExecutor, change.getEndRelOffset(), cornerRadius, change.getEndAbsBounds(),
+ getRoundedContentBounds(change));
}
private static int getWallpaperTransitType(TransitionInfo info) {
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/transition/HomeTransitionObserver.java b/libs/WindowManager/Shell/src/com/android/wm/shell/transition/HomeTransitionObserver.java
index cca982142a3a..c71458dec5ce 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/transition/HomeTransitionObserver.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/transition/HomeTransitionObserver.java
@@ -29,15 +29,18 @@ import android.annotation.NonNull;
import android.app.ActivityManager;
import android.content.Context;
import android.os.IBinder;
+import android.view.InsetsState;
import android.view.SurfaceControl;
import android.window.TransitionInfo;
+import com.android.wm.shell.common.DisplayInsetsController;
import com.android.wm.shell.common.RemoteCallable;
import com.android.wm.shell.common.ShellExecutor;
import com.android.wm.shell.common.SingleInstanceRemoteListener;
import com.android.wm.shell.shared.IHomeTransitionListener;
import com.android.wm.shell.shared.TransitionUtil;
import com.android.wm.shell.shared.bubbles.BubbleAnythingFlagHelper;
+import com.android.wm.shell.sysui.ShellInit;
/**
* The {@link TransitionObserver} that observes for transitions involving the home
@@ -51,13 +54,30 @@ public class HomeTransitionObserver implements TransitionObserver,
private @NonNull final Context mContext;
private @NonNull final ShellExecutor mMainExecutor;
+ private @NonNull final DisplayInsetsController mDisplayInsetsController;
private IBinder mPendingStartDragTransition;
private Boolean mPendingHomeVisibilityUpdate;
public HomeTransitionObserver(@NonNull Context context,
- @NonNull ShellExecutor mainExecutor) {
+ @NonNull ShellExecutor mainExecutor,
+ @NonNull DisplayInsetsController displayInsetsController,
+ @NonNull ShellInit shellInit) {
mContext = context;
mMainExecutor = mainExecutor;
+ mDisplayInsetsController = displayInsetsController;
+
+ shellInit.addInitCallback(this::onInit, this);
+ }
+
+ private void onInit() {
+ mDisplayInsetsController.addInsetsChangedListener(DEFAULT_DISPLAY,
+ new DisplayInsetsController.OnInsetsChangedListener() {
+ @Override
+ public void insetsChanged(InsetsState insetsState) {
+ if (mListener == null) return;
+ mListener.call(l -> l.onDisplayInsetsChanged(insetsState));
+ }
+ });
}
@Override
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/transition/ScreenRotationAnimation.java b/libs/WindowManager/Shell/src/com/android/wm/shell/transition/ScreenRotationAnimation.java
index aa42b7f0ca76..8100f1d1a9a9 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/transition/ScreenRotationAnimation.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/transition/ScreenRotationAnimation.java
@@ -347,21 +347,21 @@ class ScreenRotationAnimation {
@NonNull Runnable finishCallback, @NonNull ShellExecutor mainExecutor) {
buildSurfaceAnimation(animations, mRotateEnterAnimation, getEnterSurface(), finishCallback,
mTransactionPool, mainExecutor, null /* position */, 0 /* cornerRadius */,
- null /* clipRect */);
+ null /* clipRect */, null);
}
private void startScreenshotRotationAnimation(@NonNull ArrayList<Animator> animations,
@NonNull Runnable finishCallback, @NonNull ShellExecutor mainExecutor) {
buildSurfaceAnimation(animations, mRotateExitAnimation, mAnimLeash, finishCallback,
mTransactionPool, mainExecutor, null /* position */, 0 /* cornerRadius */,
- null /* clipRect */);
+ null /* clipRect */, null);
}
private void buildScreenshotAlphaAnimation(@NonNull ArrayList<Animator> animations,
@NonNull Runnable finishCallback, @NonNull ShellExecutor mainExecutor) {
buildSurfaceAnimation(animations, mRotateAlphaAnimation, mAnimLeash, finishCallback,
mTransactionPool, mainExecutor, null /* position */, 0 /* cornerRadius */,
- null /* clipRect */);
+ null /* clipRect */, null);
}
private void buildLumaAnimation(@NonNull ArrayList<Animator> animations,
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/transition/TransitionAnimationHelper.java b/libs/WindowManager/Shell/src/com/android/wm/shell/transition/TransitionAnimationHelper.java
index edfb56019a60..48b48640a37f 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/transition/TransitionAnimationHelper.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/transition/TransitionAnimationHelper.java
@@ -39,6 +39,11 @@ import android.annotation.NonNull;
import android.annotation.Nullable;
import android.app.WindowConfiguration;
import android.graphics.Color;
+import android.graphics.Insets;
+import android.graphics.Rect;
+import android.util.SparseArray;
+import android.view.InsetsSource;
+import android.view.InsetsState;
import android.view.SurfaceControl;
import android.view.WindowManager;
import android.view.animation.Animation;
@@ -47,6 +52,9 @@ import android.window.TransitionInfo;
import com.android.internal.R;
import com.android.internal.policy.TransitionAnimation;
import com.android.internal.protolog.ProtoLog;
+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.protolog.ShellProtoLogGroup;
import com.android.wm.shell.shared.TransitionUtil;
@@ -325,4 +333,77 @@ public class TransitionAnimationHelper {
}
return false;
}
+
+ /**
+ * In some situations (eg. TaskBar) the content area of a display appears to be rounded. For
+ * these situations, we may want the animation to also express the same rounded corners (even
+ * though in steady-state, the app internally manages the insets). This class Keeps track of,
+ * and provides, the bounds of rounded-corner display content.
+ *
+ * This is used to enable already-running animations to adapt to changes in taskbar/navbar
+ * position live.
+ */
+ public static class RoundedContentPerDisplay implements
+ DisplayInsetsController.OnInsetsChangedListener {
+
+ /** The current bounds of the display content (post-inset). */
+ final Rect mBounds = new Rect();
+
+ @Override
+ public void insetsChanged(InsetsState insetsState) {
+ Insets insets = Insets.NONE;
+ for (int i = insetsState.sourceSize() - 1; i >= 0; i--) {
+ final InsetsSource source = insetsState.sourceAt(i);
+ if (!source.hasFlags(InsetsSource.FLAG_INSETS_ROUNDED_CORNER)) {
+ continue;
+ }
+ insets = Insets.max(source.calculateInsets(insetsState.getDisplayFrame(), false),
+ insets);
+ }
+ mBounds.set(insetsState.getDisplayFrame());
+ mBounds.inset(insets);
+ }
+ }
+
+ /**
+ * Keeps track of the bounds of rounded-corner display content (post-inset).
+ *
+ * @see RoundedContentPerDisplay
+ */
+ public static class RoundedContentTracker implements
+ DisplayController.OnDisplaysChangedListener {
+ final DisplayController mDisplayController;
+ final DisplayInsetsController mDisplayInsetsController;
+ final SparseArray<RoundedContentPerDisplay> mPerDisplay = new SparseArray<>();
+
+ RoundedContentTracker(DisplayController dc, DisplayInsetsController dic) {
+ mDisplayController = dc;
+ mDisplayInsetsController = dic;
+ }
+
+ void init() {
+ mDisplayController.addDisplayWindowListener(this);
+ }
+
+ RoundedContentPerDisplay forDisplay(int displayId) {
+ return mPerDisplay.get(displayId);
+ }
+
+ @Override
+ public void onDisplayAdded(int displayId) {
+ final RoundedContentPerDisplay perDisplay = new RoundedContentPerDisplay();
+ mDisplayInsetsController.addInsetsChangedListener(displayId, perDisplay);
+ mPerDisplay.put(displayId, perDisplay);
+ final DisplayLayout dl = mDisplayController.getDisplayLayout(displayId);
+ perDisplay.mBounds.set(0, 0, dl.width(), dl.height());
+ }
+
+ @Override
+ public void onDisplayRemoved(int displayId) {
+ final RoundedContentPerDisplay listener = mPerDisplay.removeReturnOld(displayId);
+ if (listener != null) {
+ mDisplayInsetsController.removeInsetsChangedListener(displayId, listener);
+ }
+ }
+ }
}
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/transition/Transitions.java b/libs/WindowManager/Shell/src/com/android/wm/shell/transition/Transitions.java
index 4f49ebcd2e83..84724268cfc2 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/transition/Transitions.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/transition/Transitions.java
@@ -84,6 +84,7 @@ import com.android.internal.protolog.ProtoLog;
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.DisplayInsetsController;
import com.android.wm.shell.common.ExternalInterfaceBinder;
import com.android.wm.shell.common.RemoteCallable;
import com.android.wm.shell.common.ShellExecutor;
@@ -214,6 +215,7 @@ public class Transitions implements RemoteCallable<Transitions>,
private final Context mContext;
private final ShellExecutor mMainExecutor;
private final ShellExecutor mAnimExecutor;
+ private final Handler mAnimHandler;
private final TransitionPlayerImpl mPlayerImpl;
private final DefaultTransitionHandler mDefaultTransitionHandler;
private final RemoteTransitionHandler mRemoteTransitionHandler;
@@ -314,14 +316,16 @@ public class Transitions implements RemoteCallable<Transitions>,
@NonNull ShellTaskOrganizer organizer,
@NonNull TransactionPool pool,
@NonNull DisplayController displayController,
+ @NonNull DisplayInsetsController displayInsetsController,
@NonNull ShellExecutor mainExecutor,
@NonNull Handler mainHandler,
@NonNull ShellExecutor animExecutor,
+ @NonNull Handler animHandler,
@NonNull HomeTransitionObserver homeTransitionObserver,
@NonNull FocusTransitionObserver focusTransitionObserver) {
this(context, shellInit, new ShellCommandHandler(), shellController, organizer, pool,
- displayController, mainExecutor, mainHandler, animExecutor,
- new RootTaskDisplayAreaOrganizer(mainExecutor, context, shellInit),
+ displayController, displayInsetsController, mainExecutor, mainHandler, animExecutor,
+ animHandler, new RootTaskDisplayAreaOrganizer(mainExecutor, context, shellInit),
homeTransitionObserver, focusTransitionObserver);
}
@@ -332,9 +336,11 @@ public class Transitions implements RemoteCallable<Transitions>,
@NonNull ShellTaskOrganizer organizer,
@NonNull TransactionPool pool,
@NonNull DisplayController displayController,
+ @NonNull DisplayInsetsController displayInsetsController,
@NonNull ShellExecutor mainExecutor,
@NonNull Handler mainHandler,
@NonNull ShellExecutor animExecutor,
+ @NonNull Handler animHandler,
@NonNull RootTaskDisplayAreaOrganizer rootTDAOrganizer,
@NonNull HomeTransitionObserver homeTransitionObserver,
@NonNull FocusTransitionObserver focusTransitionObserver) {
@@ -342,11 +348,12 @@ public class Transitions implements RemoteCallable<Transitions>,
mContext = context;
mMainExecutor = mainExecutor;
mAnimExecutor = animExecutor;
+ mAnimHandler = animHandler;
mDisplayController = displayController;
mPlayerImpl = new TransitionPlayerImpl();
mDefaultTransitionHandler = new DefaultTransitionHandler(context, shellInit,
- displayController, pool, mainExecutor, mainHandler, animExecutor, rootTDAOrganizer,
- InteractionJankMonitor.getInstance());
+ displayController, displayInsetsController, pool, mainExecutor, mainHandler,
+ animExecutor, mAnimHandler, rootTDAOrganizer, InteractionJankMonitor.getInstance());
mRemoteTransitionHandler = new RemoteTransitionHandler(mMainExecutor);
mShellCommandHandler = shellCommandHandler;
mShellController = shellController;
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/unfold/UnfoldTransitionHandler.java b/libs/WindowManager/Shell/src/com/android/wm/shell/unfold/UnfoldTransitionHandler.java
index 7fd19a7d2a88..706a366441cd 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/unfold/UnfoldTransitionHandler.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/unfold/UnfoldTransitionHandler.java
@@ -38,6 +38,7 @@ import androidx.annotation.Nullable;
import androidx.annotation.VisibleForTesting;
import com.android.internal.protolog.ProtoLog;
+import com.android.wm.shell.bubbles.BubbleTaskUnfoldTransitionMerger;
import com.android.wm.shell.shared.TransactionPool;
import com.android.wm.shell.shared.TransitionUtil;
import com.android.wm.shell.sysui.ShellInit;
@@ -53,6 +54,7 @@ import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.util.ArrayList;
import java.util.List;
+import java.util.Optional;
import java.util.concurrent.Executor;
/**
@@ -80,6 +82,7 @@ public class UnfoldTransitionHandler implements TransitionHandler, UnfoldListene
private final ShellUnfoldProgressProvider mUnfoldProgressProvider;
private final Transitions mTransitions;
+ private final Optional<BubbleTaskUnfoldTransitionMerger> mBubbleTaskUnfoldTransitionMerger;
private final Executor mExecutor;
private final TransactionPool mTransactionPool;
private final Handler mHandler;
@@ -108,12 +111,14 @@ public class UnfoldTransitionHandler implements TransitionHandler, UnfoldListene
TransactionPool transactionPool,
Executor executor,
Handler handler,
- Transitions transitions) {
+ Transitions transitions,
+ Optional<BubbleTaskUnfoldTransitionMerger> bubbleTaskUnfoldTransitionMerger) {
mUnfoldProgressProvider = unfoldProgressProvider;
mTransitions = transitions;
mTransactionPool = transactionPool;
mExecutor = executor;
mHandler = handler;
+ mBubbleTaskUnfoldTransitionMerger = bubbleTaskUnfoldTransitionMerger;
mAnimators.add(splitUnfoldTaskAnimator);
mAnimators.add(fullscreenUnfoldAnimator);
@@ -237,14 +242,26 @@ public class UnfoldTransitionHandler implements TransitionHandler, UnfoldListene
}
// TODO (b/286928742) unfold transition handler should be part of mixed handler to
// handle merges better.
+
for (int i = 0; i < info.getChanges().size(); ++i) {
final TransitionInfo.Change change = info.getChanges().get(i);
final ActivityManager.RunningTaskInfo taskInfo = change.getTaskInfo();
if (taskInfo != null
&& taskInfo.configuration.windowConfiguration.isAlwaysOnTop()) {
- // Tasks that are always on top (e.g. bubbles), will handle their own transition
- // as they are on top of everything else. So skip merging transitions here.
- return;
+ // Tasks that are always on top, excluding bubbles, will handle their own transition
+ // as they are on top of everything else. If this is a transition for a bubble task,
+ // attempt to merge it. Otherwise skip merging transitions.
+ if (mBubbleTaskUnfoldTransitionMerger.isPresent()) {
+ boolean merged =
+ mBubbleTaskUnfoldTransitionMerger
+ .get()
+ .mergeTaskWithUnfold(taskInfo, change, startT, finishT);
+ if (!merged) {
+ return;
+ }
+ } else {
+ return;
+ }
}
}
// Apply changes happening during the unfold animation immediately
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/CaptionWindowDecorViewModel.java b/libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/CaptionWindowDecorViewModel.java
index 42321e56e72b..7871179a50de 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/CaptionWindowDecorViewModel.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/CaptionWindowDecorViewModel.java
@@ -49,7 +49,6 @@ import android.view.SurfaceControl;
import android.view.View;
import android.view.ViewConfiguration;
import android.window.DisplayAreaInfo;
-import android.window.TransitionInfo;
import android.window.WindowContainerToken;
import android.window.WindowContainerTransaction;
@@ -234,8 +233,7 @@ public class CaptionWindowDecorViewModel implements WindowDecorViewModel, FocusT
RunningTaskInfo taskInfo,
SurfaceControl taskSurface,
SurfaceControl.Transaction startT,
- SurfaceControl.Transaction finishT,
- @TransitionInfo.TransitionMode int changeMode) {
+ SurfaceControl.Transaction finishT) {
final CaptionWindowDecoration decoration = mWindowDecorByTaskId.get(taskInfo.taskId);
if (!shouldShowWindowDecor(taskInfo)) {
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/CarWindowDecorViewModel.java b/libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/CarWindowDecorViewModel.java
index 4511fbe10764..2b2cdf84005c 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/CarWindowDecorViewModel.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/CarWindowDecorViewModel.java
@@ -31,7 +31,6 @@ import android.view.KeyCharacterMap;
import android.view.KeyEvent;
import android.view.SurfaceControl;
import android.view.View;
-import android.window.TransitionInfo;
import android.window.WindowContainerToken;
import android.window.WindowContainerTransaction;
@@ -160,8 +159,7 @@ public abstract class CarWindowDecorViewModel
RunningTaskInfo taskInfo,
SurfaceControl taskSurface,
SurfaceControl.Transaction startT,
- SurfaceControl.Transaction finishT,
- @TransitionInfo.TransitionMode int changeMode) {
+ SurfaceControl.Transaction finishT) {
final CarWindowDecoration decoration = mWindowDecorByTaskId.get(taskInfo.taskId);
if (!shouldShowWindowDecor(taskInfo)) {
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/CarWindowDecoration.java b/libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/CarWindowDecoration.java
index f6acca95916f..dc1b94e80ed7 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/CarWindowDecoration.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/CarWindowDecoration.java
@@ -89,9 +89,6 @@ public class CarWindowDecoration extends WindowDecoration<WindowDecorLinearLayou
updateRelayoutParams(mRelayoutParams, taskInfo, isCaptionVisible);
relayout(mRelayoutParams, startT, finishT, wct, mRootView, mResult);
- if (DesktopModeFlags.ENABLE_DESKTOP_APP_HANDLE_ANIMATION.isTrue()) {
- setCaptionVisibility(isCaptionVisible);
- }
// After this line, mTaskInfo is up-to-date and should be used instead of taskInfo
mBgExecutor.execute(() -> mTaskOrganizer.applyTransaction(wct));
@@ -100,19 +97,23 @@ public class CarWindowDecoration extends WindowDecoration<WindowDecorLinearLayou
// Nothing is set up in this case including the decoration surface.
return;
}
+
if (mRootView != mResult.mRootView) {
mRootView = mResult.mRootView;
setupRootView(mResult.mRootView, mClickListener);
}
- }
- private void setCaptionVisibility(boolean visible) {
- if (mRootView == null) {
- return;
+ if (DesktopModeFlags.ENABLE_DESKTOP_APP_HANDLE_ANIMATION.isTrue()) {
+ setCaptionVisibility(mRootView, mRelayoutParams.mIsCaptionVisible);
}
+ }
+
+ private void setCaptionVisibility(@NonNull View rootView, boolean visible) {
final int v = visible ? View.VISIBLE : View.GONE;
- final View captionView = mRootView.findViewById(getCaptionViewId());
- captionView.setVisibility(v);
+ final View captionView = rootView.findViewById(getCaptionViewId());
+ if (captionView != null) {
+ captionView.setVisibility(v);
+ }
}
@Override
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 69e1f36dec0b..16fa5120d64b 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/DesktopModeWindowDecorViewModel.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/DesktopModeWindowDecorViewModel.java
@@ -27,7 +27,6 @@ import static android.view.MotionEvent.ACTION_HOVER_EXIT;
import static android.view.MotionEvent.ACTION_MOVE;
import static android.view.MotionEvent.ACTION_UP;
import static android.view.WindowInsets.Type.statusBars;
-import static android.view.WindowManager.TRANSIT_TO_BACK;
import static com.android.internal.jank.Cuj.CUJ_DESKTOP_MODE_ENTER_MODE_APP_HANDLE_MENU;
import static com.android.window.flags.Flags.enableDisplayFocusInShellTransitions;
@@ -80,7 +79,6 @@ import android.view.ViewConfiguration;
import android.view.ViewRootImpl;
import android.window.DesktopModeFlags;
import android.window.TaskSnapshot;
-import android.window.TransitionInfo;
import android.window.WindowContainerToken;
import android.window.WindowContainerTransaction;
@@ -127,6 +125,7 @@ import com.android.wm.shell.desktopmode.common.ToggleTaskSizeInteraction;
import com.android.wm.shell.desktopmode.common.ToggleTaskSizeUtilsKt;
import com.android.wm.shell.desktopmode.education.AppHandleEducationController;
import com.android.wm.shell.desktopmode.education.AppToWebEducationController;
+import com.android.wm.shell.desktopmode.multidesks.DesksOrganizer;
import com.android.wm.shell.freeform.FreeformTaskTransitionStarter;
import com.android.wm.shell.recents.RecentsTransitionHandler;
import com.android.wm.shell.recents.RecentsTransitionStateListener;
@@ -212,6 +211,7 @@ public class DesktopModeWindowDecorViewModel implements WindowDecorViewModel,
private final AppHandleAndHeaderVisibilityHelper mAppHandleAndHeaderVisibilityHelper;
private final AppHeaderViewHolder.Factory mAppHeaderViewHolderFactory;
private final AppHandleViewHolder.Factory mAppHandleViewHolderFactory;
+ private final DesksOrganizer mDesksOrganizer;
private boolean mTransitionDragActive;
private SparseArray<EventReceiver> mEventReceiversByDisplay = new SparseArray<>();
@@ -310,7 +310,8 @@ public class DesktopModeWindowDecorViewModel implements WindowDecorViewModel,
DesktopModeCompatPolicy desktopModeCompatPolicy,
DesktopTilingDecorViewModel desktopTilingDecorViewModel,
MultiDisplayDragMoveIndicatorController multiDisplayDragMoveIndicatorController,
- CompatUIHandler compatUI) {
+ CompatUIHandler compatUI,
+ DesksOrganizer desksOrganizer) {
this(
context,
shellExecutor,
@@ -358,7 +359,8 @@ public class DesktopModeWindowDecorViewModel implements WindowDecorViewModel,
desktopModeCompatPolicy,
desktopTilingDecorViewModel,
multiDisplayDragMoveIndicatorController,
- compatUI);
+ compatUI,
+ desksOrganizer);
}
@VisibleForTesting
@@ -409,7 +411,8 @@ public class DesktopModeWindowDecorViewModel implements WindowDecorViewModel,
DesktopModeCompatPolicy desktopModeCompatPolicy,
DesktopTilingDecorViewModel desktopTilingDecorViewModel,
MultiDisplayDragMoveIndicatorController multiDisplayDragMoveIndicatorController,
- CompatUIHandler compatUI) {
+ CompatUIHandler compatUI,
+ DesksOrganizer desksOrganizer) {
mContext = context;
mMainExecutor = shellExecutor;
mMainHandler = mainHandler;
@@ -487,6 +490,7 @@ public class DesktopModeWindowDecorViewModel implements WindowDecorViewModel,
mDesktopTasksController.setSnapEventHandler(this);
mMultiDisplayDragMoveIndicatorController = multiDisplayDragMoveIndicatorController;
mLatencyTracker = LatencyTracker.getInstance(mContext);
+ mDesksOrganizer = desksOrganizer;
shellInit.addInitCallback(this::onInit, this);
}
@@ -525,6 +529,10 @@ public class DesktopModeWindowDecorViewModel implements WindowDecorViewModel,
});
}
mFocusTransitionObserver.setLocalFocusTransitionListener(this, mMainExecutor);
+ mDesksOrganizer.setOnDesktopTaskInfoChangedListener((taskInfo) -> {
+ onTaskInfoChanged(taskInfo);
+ return Unit.INSTANCE;
+ });
}
@Override
@@ -602,8 +610,7 @@ public class DesktopModeWindowDecorViewModel implements WindowDecorViewModel,
RunningTaskInfo taskInfo,
SurfaceControl taskSurface,
SurfaceControl.Transaction startT,
- SurfaceControl.Transaction finishT,
- @TransitionInfo.TransitionMode int changeMode) {
+ SurfaceControl.Transaction finishT) {
final DesktopModeWindowDecoration decoration = mWindowDecorByTaskId.get(taskInfo.taskId);
if (!shouldShowWindowDecor(taskInfo)) {
if (decoration != null) {
@@ -617,8 +624,7 @@ public class DesktopModeWindowDecorViewModel implements WindowDecorViewModel,
} else {
decoration.relayout(taskInfo, startT, finishT, false /* applyStartTransactionOnDraw */,
false /* shouldSetTaskPositionAndCrop */,
- mFocusTransitionObserver.hasGlobalFocus(taskInfo), mExclusionRegion,
- /*isMovingToBack= */ changeMode == TRANSIT_TO_BACK);
+ mFocusTransitionObserver.hasGlobalFocus(taskInfo), mExclusionRegion);
}
}
@@ -633,7 +639,7 @@ public class DesktopModeWindowDecorViewModel implements WindowDecorViewModel,
decoration.relayout(taskInfo, startT, finishT, false /* applyStartTransactionOnDraw */,
false /* shouldSetTaskPositionAndCrop */,
mFocusTransitionObserver.hasGlobalFocus(taskInfo),
- mExclusionRegion, /* isMovingToBack= */ false);
+ mExclusionRegion);
}
@Override
@@ -1892,7 +1898,7 @@ public class DesktopModeWindowDecorViewModel implements WindowDecorViewModel,
windowDecoration.relayout(taskInfo, startT, finishT,
false /* applyStartTransactionOnDraw */, false /* shouldSetTaskPositionAndCrop */,
mFocusTransitionObserver.hasGlobalFocus(taskInfo),
- mExclusionRegion, /* isMovingToBack= */ false);
+ mExclusionRegion);
if (!DesktopModeFlags.ENABLE_HANDLE_INPUT_FIX.isTrue()) {
incrementEventReceiverTasks(taskInfo.displayId);
}
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 50bc7b5e865b..d24308137936 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
@@ -217,7 +217,6 @@ public class DesktopModeWindowDecoration extends WindowDecoration<WindowDecorLin
private boolean mIsDragging = false;
private Runnable mLoadAppInfoRunnable;
private Runnable mSetAppInfoRunnable;
- private boolean mIsMovingToBack;
public DesktopModeWindowDecoration(
Context context,
@@ -479,7 +478,7 @@ public class DesktopModeWindowDecoration extends WindowDecoration<WindowDecorLin
// causes flickering. See b/270202228.
final boolean applyTransactionOnDraw = taskInfo.isFreeform();
relayout(taskInfo, t, t, applyTransactionOnDraw, shouldSetTaskVisibilityPositionAndCrop,
- hasGlobalFocus, displayExclusionRegion, mIsMovingToBack);
+ hasGlobalFocus, displayExclusionRegion);
if (!applyTransactionOnDraw) {
t.apply();
}
@@ -506,8 +505,7 @@ public class DesktopModeWindowDecoration extends WindowDecoration<WindowDecorLin
void relayout(ActivityManager.RunningTaskInfo taskInfo,
SurfaceControl.Transaction startT, SurfaceControl.Transaction finishT,
boolean applyStartTransactionOnDraw, boolean shouldSetTaskVisibilityPositionAndCrop,
- boolean hasGlobalFocus, @NonNull Region displayExclusionRegion,
- boolean isMovingToBack) {
+ boolean hasGlobalFocus, @NonNull Region displayExclusionRegion) {
Trace.beginSection("DesktopModeWindowDecoration#relayout");
if (DesktopModeFlags.ENABLE_DESKTOP_WINDOWING_APP_TO_WEB.isTrue()) {
@@ -530,7 +528,6 @@ public class DesktopModeWindowDecoration extends WindowDecoration<WindowDecorLin
final boolean inFullImmersive = mDesktopUserRepositories.getProfile(taskInfo.userId)
.isTaskInFullImmersiveState(taskInfo.taskId);
- mIsMovingToBack = isMovingToBack;
updateRelayoutParams(mRelayoutParams, mContext, taskInfo, mSplitScreenController,
applyStartTransactionOnDraw, shouldSetTaskVisibilityPositionAndCrop,
mIsStatusBarVisible, mIsKeyguardVisibleAndOccluded, inFullImmersive,
@@ -539,8 +536,7 @@ public class DesktopModeWindowDecoration extends WindowDecoration<WindowDecorLin
/* shouldIgnoreCornerRadius= */ mIsRecentsTransitionRunning
&& DesktopModeFlags
.ENABLE_DESKTOP_RECENTS_TRANSITIONS_CORNERS_BUGFIX.isTrue(),
- mDesktopModeCompatPolicy.shouldExcludeCaptionFromAppBounds(taskInfo),
- mIsRecentsTransitionRunning, mIsMovingToBack);
+ mDesktopModeCompatPolicy.shouldExcludeCaptionFromAppBounds(taskInfo));
final WindowDecorLinearLayout oldRootView = mResult.mRootView;
final SurfaceControl oldDecorationSurface = mDecorationContainerSurface;
@@ -633,6 +629,16 @@ public class DesktopModeWindowDecoration extends WindowDecoration<WindowDecorLin
mBgExecutor.execute(mLoadAppInfoRunnable);
}
+ private boolean showInputLayer() {
+ if (!DesktopModeFlags.ENABLE_INPUT_LAYER_TRANSITION_FIX.isTrue()) {
+ return isCaptionVisible();
+ }
+ // Don't show the input layer during the recents transition, otherwise it could become
+ // touchable while in overview, during quick-switch or even for a short moment after going
+ // Home.
+ return isCaptionVisible() && !mIsRecentsTransitionRunning;
+ }
+
private boolean isCaptionVisible() {
return mTaskInfo.isVisible && mIsCaptionVisible;
}
@@ -874,7 +880,7 @@ public class DesktopModeWindowDecoration extends WindowDecoration<WindowDecorLin
if (!isAppHandle(mWindowDecorViewHolder)) return;
asAppHandle(mWindowDecorViewHolder).bindData(new AppHandleViewHolder.HandleData(
mTaskInfo, determineHandlePosition(), mResult.mCaptionWidth,
- mResult.mCaptionHeight, /* showInputLayer= */ isCaptionVisible(),
+ mResult.mCaptionHeight, /* showInputLayer= */ showInputLayer(),
/* isCaptionVisible= */ isCaptionVisible()
));
}
@@ -959,9 +965,7 @@ public class DesktopModeWindowDecoration extends WindowDecoration<WindowDecorLin
boolean hasGlobalFocus,
@NonNull Region displayExclusionRegion,
boolean shouldIgnoreCornerRadius,
- boolean shouldExcludeCaptionFromAppBounds,
- boolean isRecentsTransitionRunning,
- boolean isMovingToBack) {
+ boolean shouldExcludeCaptionFromAppBounds) {
final int captionLayoutId = getDesktopModeWindowDecorLayoutId(taskInfo.getWindowingMode());
final boolean isAppHeader =
captionLayoutId == R.layout.desktop_mode_app_header;
@@ -979,19 +983,10 @@ public class DesktopModeWindowDecoration extends WindowDecoration<WindowDecorLin
relayoutParams.mAsyncViewHost = isAppHandle;
boolean showCaption;
- // If this relayout is occurring from an observed TRANSIT_TO_BACK transition, do not
- // show caption (this includes split select transition).
- if (DesktopModeFlags.ENABLE_INPUT_LAYER_TRANSITION_FIX.isTrue()
- && isMovingToBack && !isDragging) {
- showCaption = false;
- } else if (DesktopModeFlags.ENABLE_DESKTOP_IMMERSIVE_DRAG_BUGFIX.isTrue() && isDragging) {
+ if (DesktopModeFlags.ENABLE_DESKTOP_IMMERSIVE_DRAG_BUGFIX.isTrue() && isDragging) {
// If the task is being dragged, the caption should not be hidden so that it continues
// receiving input
showCaption = true;
- } else if (DesktopModeFlags.ENABLE_INPUT_LAYER_TRANSITION_FIX.isTrue()
- && isRecentsTransitionRunning) {
- // Caption should not be visible in recents.
- showCaption = false;
} else if (DesktopModeFlags.ENABLE_FULLY_IMMERSIVE_IN_DESKTOP.isTrue()) {
if (inFullImmersiveMode) {
showCaption = (isStatusBarVisible && !isKeyguardVisibleAndOccluded);
@@ -1895,18 +1890,9 @@ public class DesktopModeWindowDecoration extends WindowDecoration<WindowDecorLin
* <p> When a Recents transition is active we allow that transition to take ownership of the
* corner radius of its task surfaces, so each window decoration should stop updating the corner
* radius of its task surface during that time.
- *
- * We should not allow input to reach the input layer during a Recents transition, so
- * update the handle view holder accordingly if transition status changes.
*/
void setIsRecentsTransitionRunning(boolean isRecentsTransitionRunning) {
- if (mIsRecentsTransitionRunning != isRecentsTransitionRunning) {
- mIsRecentsTransitionRunning = isRecentsTransitionRunning;
- if (DesktopModeFlags.ENABLE_INPUT_LAYER_TRANSITION_FIX.isTrue()) {
- // We don't relayout decor on recents transition, so we need to call it directly.
- relayout(mTaskInfo, mHasGlobalFocus, mRelayoutParams.mDisplayExclusionRegion);
- }
- }
+ mIsRecentsTransitionRunning = isRecentsTransitionRunning;
}
/**
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/DragResizeInputListener.java b/libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/DragResizeInputListener.java
index 8a8bdcadd67a..97a47c602bcd 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/DragResizeInputListener.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/DragResizeInputListener.java
@@ -435,7 +435,9 @@ class DragResizeInputListener implements AutoCloseable {
}
// Removing this surface on the background thread to ensure that mInitInputChannels has
// already been finished.
- mSurfaceControlTransactionSupplier.get().remove(mDecorationSurface).apply();
+ // Do not |remove| the surface, the decoration might still be needed even if
+ // drag-resizing isn't.
+ mDecorationSurface.release();
});
}
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 25cf06b4247c..71bb153e4b1e 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
@@ -50,7 +50,6 @@ import androidx.core.view.accessibility.AccessibilityNodeInfoCompat.Accessibilit
import androidx.core.view.isGone
import com.android.window.flags.Flags
import com.android.wm.shell.R
-import com.android.wm.shell.bubbles.ContextUtils.isRtl
import com.android.wm.shell.desktopmode.DesktopModeUiEventLogger
import com.android.wm.shell.desktopmode.DesktopModeUiEventLogger.DesktopUiEventEnum.A11Y_APP_HANDLE_MENU_DESKTOP_VIEW
import com.android.wm.shell.desktopmode.DesktopModeUiEventLogger.DesktopUiEventEnum.A11Y_APP_HANDLE_MENU_FULLSCREEN
@@ -58,6 +57,7 @@ import com.android.wm.shell.desktopmode.DesktopModeUiEventLogger.DesktopUiEventE
import com.android.wm.shell.shared.annotations.ShellBackgroundThread
import com.android.wm.shell.shared.annotations.ShellMainThread
import com.android.wm.shell.shared.bubbles.BubbleAnythingFlagHelper
+import com.android.wm.shell.shared.bubbles.ContextUtils.isRtl
import com.android.wm.shell.shared.split.SplitScreenConstants
import com.android.wm.shell.splitscreen.SplitScreenController
import com.android.wm.shell.windowdecor.additionalviewcontainer.AdditionalSystemViewContainer
@@ -508,6 +508,9 @@ class HandleMenu(
private val iconButtonRippleRadius = context.resources.getDimensionPixelSize(
R.dimen.desktop_mode_handle_menu_icon_button_ripple_radius
)
+ private val handleMenuCornerRadius = context.resources.getDimensionPixelSize(
+ R.dimen.desktop_mode_handle_menu_corner_radius
+ )
private val iconButtonDrawableInsetsBase = DrawableInsets(
t = iconButtondrawableBaseInset,
b = iconButtondrawableBaseInset, l = iconButtondrawableBaseInset,
@@ -866,14 +869,21 @@ class HandleMenu(
private fun bindMoreActionsPill(style: MenuStyle) {
moreActionsPill.background.setTint(style.backgroundColor)
-
- arrayOf(
+ val buttons = arrayOf(
screenshotBtn to SHOULD_SHOW_SCREENSHOT_BUTTON,
newWindowBtn to shouldShowNewWindowButton,
manageWindowBtn to shouldShowManageWindowsButton,
changeAspectRatioBtn to shouldShowChangeAspectRatioButton,
restartBtn to shouldShowRestartButton,
- ).forEach { (button, shouldShow) ->
+ )
+ val firstVisible = buttons.find { it.second }?.first
+ val lastVisible = buttons.findLast { it.second }?.first
+
+ buttons.forEach { (button, shouldShow) ->
+ val topRadius =
+ if (button == firstVisible) handleMenuCornerRadius.toFloat() else 0f
+ val bottomRadius =
+ if (button == lastVisible) handleMenuCornerRadius.toFloat() else 0f
button.apply {
isGone = !shouldShow
textView.apply {
@@ -881,6 +891,13 @@ class HandleMenu(
startMarquee()
}
iconView.imageTintList = ColorStateList.valueOf(style.textColor)
+ background = createBackgroundDrawable(
+ color = style.textColor,
+ cornerRadius = floatArrayOf(
+ topRadius, topRadius, topRadius, topRadius,
+ bottomRadius, bottomRadius, bottomRadius, bottomRadius
+ ),
+ drawableInsets = DrawableInsets())
}
}
}
@@ -899,6 +916,10 @@ class HandleMenu(
openInAppOrBrowserBtn.apply {
contentDescription = btnText
+ background = createBackgroundDrawable(
+ color = style.textColor,
+ cornerRadius = handleMenuCornerRadius,
+ drawableInsets = DrawableInsets())
textView.apply {
text = btnText
setTextColor(style.textColor)
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/WindowDecorViewModel.java b/libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/WindowDecorViewModel.java
index 5e4a0a5860f0..1563259f4a1a 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/WindowDecorViewModel.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/WindowDecorViewModel.java
@@ -18,7 +18,6 @@ package com.android.wm.shell.windowdecor;
import android.app.ActivityManager;
import android.view.SurfaceControl;
-import android.window.TransitionInfo;
import com.android.wm.shell.freeform.FreeformTaskTransitionStarter;
import com.android.wm.shell.splitscreen.SplitScreenController;
@@ -84,14 +83,12 @@ public interface WindowDecorViewModel {
* @param taskSurface the surface of the task
* @param startT the start transaction to be applied before the transition
* @param finishT the finish transaction to restore states after the transition
- * @param changeMode the type of change to the task
*/
void onTaskChanging(
ActivityManager.RunningTaskInfo taskInfo,
SurfaceControl taskSurface,
SurfaceControl.Transaction startT,
- SurfaceControl.Transaction finishT,
- @TransitionInfo.TransitionMode int changeMode);
+ SurfaceControl.Transaction finishT);
/**
* Notifies that the given task is about to close to give the window decoration a chance to
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/common/ButtonBackgroundDrawableUtils.kt b/libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/common/ButtonBackgroundDrawableUtils.kt
index f08cfa987cc7..33e743016d0d 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/common/ButtonBackgroundDrawableUtils.kt
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/common/ButtonBackgroundDrawableUtils.kt
@@ -51,10 +51,20 @@ fun replaceColorAlpha(@ColorInt color: Int, alpha: Int): Int {
*/
fun createBackgroundDrawable(
@ColorInt color: Int, cornerRadius: Int, drawableInsets: DrawableInsets
+): Drawable = createBackgroundDrawable(
+ color,
+ FloatArray(8) { cornerRadius.toFloat() },
+ drawableInsets)
+
+/**
+ * Creates a background drawable with specified color, corner radius, and insets.
+ */
+fun createBackgroundDrawable(
+ @ColorInt color: Int, cornerRadius: FloatArray, drawableInsets: DrawableInsets
): Drawable = LayerDrawable(arrayOf(
ShapeDrawable().apply {
shape = RoundRectShape(
- FloatArray(8) { cornerRadius.toFloat() },
+ cornerRadius,
/* inset= */ null,
/* innerRadii= */ null
)
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/common/ThemeUtils.kt b/libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/common/ThemeUtils.kt
index c5057aa3cc18..f09f22fb1951 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/common/ThemeUtils.kt
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/common/ThemeUtils.kt
@@ -92,4 +92,7 @@ internal class DecorThemeUtil(private val context: Context) {
Theme.LIGHT -> lightColors
Theme.DARK -> darkColors
}
+
+ fun getColorScheme(isDarkMode: Boolean): ColorScheme =
+ if (isDarkMode) darkColors else lightColors
}
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/tiling/DesktopTilingDividerWindowManager.kt b/libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/tiling/DesktopTilingDividerWindowManager.kt
index 57f8046065b4..ab6b72947586 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/tiling/DesktopTilingDividerWindowManager.kt
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/tiling/DesktopTilingDividerWindowManager.kt
@@ -198,6 +198,11 @@ class DesktopTilingDividerWindowManager(
tilingDividerView?.onUiModeChange(isDarkMode)
}
+ /** Notifies the divider view of task info change and possible color change. */
+ fun onTaskInfoChange() {
+ tilingDividerView?.onTaskInfoChange()
+ }
+
/** Hides the divider bar. */
fun hideDividerBar() {
if (!dividerShown) {
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/tiling/DesktopTilingWindowDecoration.kt b/libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/tiling/DesktopTilingWindowDecoration.kt
index b57931121881..3e92d7d994a6 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/tiling/DesktopTilingWindowDecoration.kt
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/tiling/DesktopTilingWindowDecoration.kt
@@ -375,6 +375,7 @@ class DesktopTilingWindowDecoration(
fun onTaskInfoChange(taskInfo: RunningTaskInfo) {
val isCurrentTaskInDarkMode = isTaskInDarkMode(taskInfo)
+ desktopTilingDividerWindowManager?.onTaskInfoChange()
if (isCurrentTaskInDarkMode == isDarkMode || !isTilingManagerInitialised) return
isDarkMode = isCurrentTaskInDarkMode
desktopTilingDividerWindowManager?.onUiModeChange(isDarkMode)
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/tiling/TilingDividerView.kt b/libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/tiling/TilingDividerView.kt
index 54dcd2d082dc..e9bd6f8ef85c 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/tiling/TilingDividerView.kt
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/tiling/TilingDividerView.kt
@@ -29,6 +29,7 @@ import android.view.RoundedCorner
import android.view.View
import android.view.ViewConfiguration
import android.widget.FrameLayout
+import androidx.compose.ui.graphics.toArgb
import com.android.internal.annotations.VisibleForTesting
import com.android.internal.config.sysui.SystemUiDeviceConfigFlags
import com.android.wm.shell.R
@@ -36,6 +37,7 @@ import com.android.wm.shell.common.split.DividerHandleView
import com.android.wm.shell.common.split.DividerRoundedCorner
import com.android.wm.shell.shared.animation.Interpolators
import com.android.wm.shell.windowdecor.DragDetector
+import com.android.wm.shell.windowdecor.common.DecorThemeUtil
/** Divider for tiling split screen, currently mostly a copy of [DividerView]. */
class TilingDividerView : FrameLayout, View.OnTouchListener, DragDetector.MotionEventHandler {
@@ -56,6 +58,9 @@ class TilingDividerView : FrameLayout, View.OnTouchListener, DragDetector.Motion
@VisibleForTesting var handleY: IntRange = 0..0
private var canResize = false
private var resized = false
+ private var isDarkMode = false
+ private var decorThemeUtil = DecorThemeUtil(context)
+
/**
* Tracks divider bar visible bounds in screen-based coordination. Used to calculate with
* insets.
@@ -90,10 +95,12 @@ class TilingDividerView : FrameLayout, View.OnTouchListener, DragDetector.Motion
) {
callback = dividerMoveCallback
this.dividerBounds.set(dividerBounds)
+ this.isDarkMode = isDarkMode
+ paint.color = decorThemeUtil.getColorScheme(isDarkMode).outlineVariant.toArgb()
handle.setIsLeftRightSplit(true)
handle.setup(/* isSplitScreen= */ false, isDarkMode)
corners.setIsLeftRightSplit(true)
- corners.setup(/* isSplitScreen= */ false, isDarkMode)
+ corners.setup(/* isSplitScreen= */ false, paint.color)
handleRegionHeight = handleRegionSize.height
handleRegionWidth = handleRegionSize.width
cornersRadius =
@@ -108,17 +115,22 @@ class TilingDividerView : FrameLayout, View.OnTouchListener, DragDetector.Motion
}
fun onUiModeChange(isDarkMode: Boolean) {
+ this.isDarkMode = isDarkMode
handle.onUiModeChange(isDarkMode)
- corners.onUiModeChange(isDarkMode)
- paint.color =
- if (isDarkMode) {
- resources.getColor(R.color.tiling_divider_background_dark, null /* theme */)
- } else {
- resources.getColor(R.color.tiling_divider_background_light, null /* theme */)
- }
+ paint.color = decorThemeUtil.getColorScheme(isDarkMode).outlineVariant.toArgb()
+ corners.onUiModeChange(paint.color)
invalidate()
}
+ fun onTaskInfoChange() {
+ decorThemeUtil = DecorThemeUtil(context)
+ if (paint.color != decorThemeUtil.getColorScheme(isDarkMode).outlineVariant.toArgb()) {
+ paint.color = decorThemeUtil.getColorScheme(isDarkMode).outlineVariant.toArgb()
+ corners.onCornerColorChange(paint.color)
+ invalidate()
+ }
+ }
+
override fun onFinishInflate() {
super.onFinishInflate()
dividerBar = requireViewById(R.id.divider_bar)
@@ -128,15 +140,10 @@ class TilingDividerView : FrameLayout, View.OnTouchListener, DragDetector.Motion
resources.getDimensionPixelSize(R.dimen.docked_stack_divider_lift_elevation)
setOnTouchListener(this)
setWillNotDraw(false)
- paint.color =
- if (
- context.resources.configuration.uiMode and Configuration.UI_MODE_NIGHT_MASK ==
- Configuration.UI_MODE_NIGHT_YES
- ) {
- resources.getColor(R.color.tiling_divider_background_dark, /* theme= */null)
- } else {
- resources.getColor(R.color.tiling_divider_background_light, /* theme= */ null)
- }
+ val isDarkMode =
+ context.resources.configuration.uiMode and Configuration.UI_MODE_NIGHT_MASK ==
+ Configuration.UI_MODE_NIGHT_YES
+ paint.color = decorThemeUtil.getColorScheme(isDarkMode).outlineVariant.toArgb()
paint.isAntiAlias = true
paint.style = Paint.Style.FILL
}
diff --git a/libs/WindowManager/Shell/tests/e2e/splitscreen/flicker-legacy/src/com/android/wm/shell/flicker/splitscreen/benchmark/SwitchAppByDoubleTapDividerBenchmark.kt b/libs/WindowManager/Shell/tests/e2e/splitscreen/flicker-legacy/src/com/android/wm/shell/flicker/splitscreen/benchmark/SwitchAppByDoubleTapDividerBenchmark.kt
index fa9864b539ee..7cd2bcc8efd4 100644
--- a/libs/WindowManager/Shell/tests/e2e/splitscreen/flicker-legacy/src/com/android/wm/shell/flicker/splitscreen/benchmark/SwitchAppByDoubleTapDividerBenchmark.kt
+++ b/libs/WindowManager/Shell/tests/e2e/splitscreen/flicker-legacy/src/com/android/wm/shell/flicker/splitscreen/benchmark/SwitchAppByDoubleTapDividerBenchmark.kt
@@ -52,7 +52,7 @@ abstract class SwitchAppByDoubleTapDividerBenchmark(override val flicker: Legacy
)
}
transitions {
- SplitScreenUtils.doubleTapDividerToSwitch(device)
+ SplitScreenUtils.doubleTapDividerToSwitch(device, instrumentation.uiAutomation)
wmHelper.StateSyncBuilder().withAppTransitionIdle().waitForAndVerify()
waitForLayersToSwitch(wmHelper)
diff --git a/libs/WindowManager/Shell/tests/e2e/splitscreen/scenarios/src/com/android/wm/shell/scenarios/SwitchAppByDoubleTapDivider.kt b/libs/WindowManager/Shell/tests/e2e/splitscreen/scenarios/src/com/android/wm/shell/scenarios/SwitchAppByDoubleTapDivider.kt
index 3fd93d3eaf59..dfc737174a4f 100644
--- a/libs/WindowManager/Shell/tests/e2e/splitscreen/scenarios/src/com/android/wm/shell/scenarios/SwitchAppByDoubleTapDivider.kt
+++ b/libs/WindowManager/Shell/tests/e2e/splitscreen/scenarios/src/com/android/wm/shell/scenarios/SwitchAppByDoubleTapDivider.kt
@@ -61,7 +61,7 @@ constructor(val rotation: Rotation = Rotation.ROTATION_0) {
@Test
open fun switchAppByDoubleTapDivider() {
- SplitScreenUtils.doubleTapDividerToSwitch(device)
+ SplitScreenUtils.doubleTapDividerToSwitch(device, instrumentation.uiAutomation)
wmHelper.StateSyncBuilder().withAppTransitionIdle().waitForAndVerify()
waitForLayersToSwitch(wmHelper)
diff --git a/libs/WindowManager/Shell/tests/e2e/utils/src/com/android/wm/shell/SimulatedConnectedDisplayTestRule.kt b/libs/WindowManager/Shell/tests/e2e/utils/src/com/android/wm/shell/SimulatedConnectedDisplayTestRule.kt
index 68f7ef09ee70..f9b69d3f5f7e 100644
--- a/libs/WindowManager/Shell/tests/e2e/utils/src/com/android/wm/shell/SimulatedConnectedDisplayTestRule.kt
+++ b/libs/WindowManager/Shell/tests/e2e/utils/src/com/android/wm/shell/SimulatedConnectedDisplayTestRule.kt
@@ -41,7 +41,6 @@ import org.junit.runners.model.Statement
class SimulatedConnectedDisplayTestRule : TestRule {
private val context = InstrumentationRegistry.getInstrumentation().targetContext
- private val uiAutomation = InstrumentationRegistry.getInstrumentation().uiAutomation
private val displayManager = context.getSystemService(DisplayManager::class.java)
private val addedDisplays = mutableListOf<Int>()
@@ -102,7 +101,8 @@ class SimulatedConnectedDisplayTestRule : TestRule {
// Add the overlay displays
Settings.Global.putString(
InstrumentationRegistry.getInstrumentation().context.contentResolver,
- Settings.Global.OVERLAY_DISPLAY_DEVICES, displaySettings
+ Settings.Global.OVERLAY_DISPLAY_DEVICES,
+ displaySettings
)
withTimeoutOrNull(TIMEOUT) {
displayAddedFlow.take(displays.size).collect { displayId ->
@@ -125,10 +125,6 @@ class SimulatedConnectedDisplayTestRule : TestRule {
}
private fun cleanupTestDisplays() = runBlocking {
- if (addedDisplays.isEmpty()) {
- return@runBlocking
- }
-
val displayRemovedFlow: Flow<Int> = callbackFlow {
val listener = object : DisplayListener {
override fun onDisplayAdded(displayId: Int) {}
@@ -146,16 +142,24 @@ class SimulatedConnectedDisplayTestRule : TestRule {
}
}
- // Remove overlay displays
+ // Remove overlay displays. We'll execute this regardless of addedDisplays just to
+ // ensure all overlay displays are removed before and after the test.
+ // Note: If we want to restore the original overlay display added before this test (and its
+ // topology), it will be complicated as re-adding overlay display would lead to different
+ // displayId and topology could not be restored easily.
Settings.Global.putString(
InstrumentationRegistry.getInstrumentation().context.contentResolver,
- Settings.Global.OVERLAY_DISPLAY_DEVICES, null)
+ Settings.Global.OVERLAY_DISPLAY_DEVICES,
+ null
+ )
- withTimeoutOrNull(TIMEOUT) {
- displayRemovedFlow.take(addedDisplays.size).collect { displayId ->
- addedDisplays.remove(displayId)
- }
- } ?: error("Timed out waiting for displays to be removed.")
+ if (!addedDisplays.isEmpty()) {
+ withTimeoutOrNull(TIMEOUT) {
+ displayRemovedFlow.take(addedDisplays.size).collect { displayId ->
+ addedDisplays.remove(displayId)
+ }
+ } ?: error("Timed out waiting for displays to be removed: $addedDisplays")
+ }
}
private companion object {
diff --git a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/utils/SplitScreenUtils.kt b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/utils/SplitScreenUtils.kt
index e4183f16ba14..e54930d730f3 100644
--- a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/utils/SplitScreenUtils.kt
+++ b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/utils/SplitScreenUtils.kt
@@ -17,6 +17,7 @@
package com.android.wm.shell.flicker.utils
import android.app.Instrumentation
+import android.app.UiAutomation
import android.content.Context
import android.graphics.Point
import android.os.SystemClock
@@ -355,13 +356,40 @@ object SplitScreenUtils {
)
}
- fun doubleTapDividerToSwitch(device: UiDevice) {
+ fun doubleTapDividerToSwitch(device: UiDevice, uiAutomation: UiAutomation) {
val dividerBar = device.wait(Until.findObject(dividerBarSelector), TIMEOUT_MS)
- val interval =
- (ViewConfiguration.getDoubleTapTimeout() + ViewConfiguration.getDoubleTapMinTime()) / 2
- dividerBar.click()
- SystemClock.sleep(interval.toLong())
- dividerBar.click()
+ val x = dividerBar.visibleCenter.x.toFloat()
+ val y = dividerBar.visibleCenter.y.toFloat()
+
+ // To send a double-tap action, we set a DOWN event, then UP, then DOWN, then, UP.
+ val startTime = SystemClock.uptimeMillis()
+ val timeOfFirstUp = startTime + ViewConfiguration.getTapTimeout()
+ // Between the two taps, we wait an arbitrary amount of time between the min and max times
+ // for a double-tap.
+ val timeOfSecondDown = timeOfFirstUp + ViewConfiguration.getDoubleTapMinTime() +
+ ((ViewConfiguration.getDoubleTapTimeout() -
+ ViewConfiguration.getDoubleTapMinTime()) / 4)
+ val timeOfSecondUp = timeOfSecondDown + ViewConfiguration.getTapTimeout()
+
+ val downEvent = MotionEvent.obtain(startTime, startTime, MotionEvent.ACTION_DOWN, x, y,
+ 0 /* metaState */)
+ downEvent.setSource(InputDevice.SOURCE_TOUCHSCREEN)
+ uiAutomation.injectInputEvent(downEvent, true)
+
+ val upEvent = MotionEvent.obtain(startTime, timeOfFirstUp, MotionEvent.ACTION_UP, x, y,
+ 0 /* metaState */)
+ upEvent.setSource(InputDevice.SOURCE_TOUCHSCREEN)
+ uiAutomation.injectInputEvent(upEvent, true)
+
+ val downEvent2 = MotionEvent.obtain(timeOfSecondDown, timeOfSecondDown,
+ MotionEvent.ACTION_DOWN, x, y, 0 /* metaState */)
+ downEvent2.setSource(InputDevice.SOURCE_TOUCHSCREEN)
+ uiAutomation.injectInputEvent(downEvent2, true)
+
+ val upEvent2 = MotionEvent.obtain(timeOfSecondDown, timeOfSecondUp, MotionEvent.ACTION_UP,
+ x, y, 0 /* metaState */)
+ upEvent2.setSource(InputDevice.SOURCE_TOUCHSCREEN)
+ uiAutomation.injectInputEvent(upEvent2, true)
}
fun copyContentInSplit(
diff --git a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/common/DisplayControllerTests.java b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/common/DisplayControllerTests.java
index 3d5e9495e29d..1e459d55ed77 100644
--- a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/common/DisplayControllerTests.java
+++ b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/common/DisplayControllerTests.java
@@ -18,6 +18,7 @@ package com.android.wm.shell.common;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.assertNotSame;
import static org.junit.Assert.assertNull;
import static org.mockito.ArgumentMatchers.any;
import static org.mockito.ArgumentMatchers.anyInt;
@@ -231,4 +232,24 @@ public class DisplayControllerTests extends ShellTestCase {
assertEquals(DISPLAY_ABS_BOUNDS_1,
mController.getDisplayLayout(DISPLAY_ID_1).globalBoundsDp());
}
+
+ @Test
+ @EnableFlags(Flags.FLAG_ENABLE_CONNECTED_DISPLAYS_WINDOW_DRAG)
+ public void onDisplayConfigurationChanged_reInitDisplayLayout()
+ throws RemoteException {
+ ExtendedMockito.doReturn(true)
+ .when(() -> DesktopModeStatus.canEnterDesktopMode(any()));
+ mController.onInit();
+ mController.addDisplayWindowListener(mListener);
+
+ mCapturedTopologyListener.accept(mMockTopology);
+
+ DisplayLayout displayLayoutBefore = mController.getDisplayLayout(DISPLAY_ID_0);
+ mDisplayContainerListener.onDisplayConfigurationChanged(DISPLAY_ID_0, new Configuration());
+ DisplayLayout displayLayoutAfter = mController.getDisplayLayout(DISPLAY_ID_0);
+
+ assertNotSame(displayLayoutBefore, displayLayoutAfter);
+ assertEquals(DISPLAY_ABS_BOUNDS_0,
+ mController.getDisplayLayout(DISPLAY_ID_0).globalBoundsDp());
+ }
}
diff --git a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/desktopmode/DesktopDisplayEventHandlerTest.kt b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/desktopmode/DesktopDisplayEventHandlerTest.kt
index 9268db60aa51..85a431be8e8b 100644
--- a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/desktopmode/DesktopDisplayEventHandlerTest.kt
+++ b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/desktopmode/DesktopDisplayEventHandlerTest.kt
@@ -23,6 +23,7 @@ import androidx.test.filters.SmallTest
import com.android.dx.mockito.inline.extended.ExtendedMockito.mockitoSession
import com.android.dx.mockito.inline.extended.ExtendedMockito.never
import com.android.dx.mockito.inline.extended.StaticMockitoSession
+import com.android.server.display.feature.flags.Flags as DisplayFlags
import com.android.window.flags.Flags
import com.android.wm.shell.RootTaskDisplayAreaOrganizer
import com.android.wm.shell.ShellTestCase
@@ -246,6 +247,13 @@ class DesktopDisplayEventHandlerTest : ShellTestCase() {
verify(desktopDisplayModeController).refreshDisplayWindowingMode()
}
+ @Test
+ @EnableFlags(DisplayFlags.FLAG_ENABLE_DISPLAY_CONTENT_MODE_MANAGEMENT)
+ fun testDesktopModeEligibleChanged() {
+ onDisplaysChangedListenerCaptor.lastValue.onDesktopModeEligibleChanged(externalDisplayId)
+ verify(desktopDisplayModeController).refreshDisplayWindowingMode()
+ }
+
private class FakeDesktopRepositoryInitializer : DesktopRepositoryInitializer {
override var deskRecreationFactory: DesktopRepositoryInitializer.DeskRecreationFactory =
DesktopRepositoryInitializer.DeskRecreationFactory { _, _, deskId -> deskId }
diff --git a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/desktopmode/DesktopDisplayModeControllerTest.kt b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/desktopmode/DesktopDisplayModeControllerTest.kt
index 96b826f93aae..488025a3d754 100644
--- a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/desktopmode/DesktopDisplayModeControllerTest.kt
+++ b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/desktopmode/DesktopDisplayModeControllerTest.kt
@@ -104,7 +104,9 @@ class DesktopDisplayModeControllerTest(
private val wallpaperToken = MockToken().token()
private val defaultDisplay = mock<Display>()
private val externalDisplay = mock<Display>()
- private val mouseDevice = mock<InputDevice>()
+ private val touchpadDevice = mock<InputDevice>()
+ private val keyboardDevice = mock<InputDevice>()
+ private val connectedDeviceIds = mutableListOf<Int>()
private lateinit var extendedDisplaySettingsRestoreSession:
ExtendedDisplaySettingsRestoreSession
@@ -145,16 +147,18 @@ class DesktopDisplayModeControllerTest(
whenever(desktopWallpaperActivityTokenProvider.getToken()).thenReturn(wallpaperToken)
whenever(displayController.getDisplay(DEFAULT_DISPLAY)).thenReturn(defaultDisplay)
whenever(displayController.getDisplay(EXTERNAL_DISPLAY_ID)).thenReturn(externalDisplay)
- setTabletModeStatus(SwitchState.UNKNOWN)
- whenever(
- DesktopModeStatus.isDesktopModeSupportedOnDisplay(
- context,
- defaultDisplay
- )
- ).thenReturn(true)
- whenever(mouseDevice.supportsSource(InputDevice.SOURCE_MOUSE)).thenReturn(true)
- whenever(inputManager.getInputDevice(EXTERNAL_DEVICE_ID)).thenReturn(mouseDevice)
- setMouseConnected(false)
+ whenever(DesktopModeStatus.isDesktopModeSupportedOnDisplay(context, defaultDisplay))
+ .thenReturn(true)
+ whenever(touchpadDevice.supportsSource(InputDevice.SOURCE_TOUCHPAD)).thenReturn(true)
+ whenever(touchpadDevice.isEnabled()).thenReturn(true)
+ whenever(inputManager.getInputDevice(TOUCHPAD_DEVICE_ID)).thenReturn(touchpadDevice)
+ whenever(keyboardDevice.isFullKeyboard()).thenReturn(true)
+ whenever(keyboardDevice.isVirtual()).thenReturn(false)
+ whenever(keyboardDevice.isEnabled()).thenReturn(true)
+ whenever(inputManager.getInputDevice(KEYBOARD_DEVICE_ID)).thenReturn(keyboardDevice)
+ whenever(inputManager.inputDeviceIds).thenAnswer { connectedDeviceIds.toIntArray() }
+ setTouchpadConnected(false)
+ setKeyboardConnected(false)
}
@After
@@ -211,8 +215,8 @@ class DesktopDisplayModeControllerTest(
@DisableFlags(Flags.FLAG_FORM_FACTOR_BASED_DESKTOP_FIRST_SWITCH)
fun testTargetWindowingMode_formfactorDisabled(
@TestParameter param: ExternalDisplayBasedTargetModeTestCase,
- @TestParameter tabletModeStatus: SwitchState,
- @TestParameter hasAnyMouseDevice: Boolean,
+ @TestParameter hasAnyTouchpadDevice: Boolean,
+ @TestParameter hasAnyKeyboardDevice: Boolean,
) {
whenever(mockWindowManager.getWindowingMode(anyInt()))
.thenReturn(param.defaultWindowingMode)
@@ -221,15 +225,11 @@ class DesktopDisplayModeControllerTest(
} else {
disconnectExternalDisplay()
}
- setTabletModeStatus(tabletModeStatus)
- setMouseConnected(hasAnyMouseDevice)
+ setTouchpadConnected(hasAnyTouchpadDevice)
+ setKeyboardConnected(hasAnyKeyboardDevice)
setExtendedMode(param.extendedDisplayEnabled)
- whenever(
- DesktopModeStatus.isDesktopModeSupportedOnDisplay(
- context,
- defaultDisplay
- )
- ).thenReturn(param.isDefaultDisplayDesktopEligible)
+ whenever(DesktopModeStatus.isDesktopModeSupportedOnDisplay(context, defaultDisplay))
+ .thenReturn(param.isDefaultDisplayDesktopEligible)
assertThat(controller.getTargetWindowingModeForDefaultDisplay())
.isEqualTo(param.expectedWindowingMode)
@@ -246,15 +246,11 @@ class DesktopDisplayModeControllerTest(
} else {
disconnectExternalDisplay()
}
- setTabletModeStatus(param.tabletModeStatus)
setExtendedMode(param.extendedDisplayEnabled)
- whenever(
- DesktopModeStatus.isDesktopModeSupportedOnDisplay(
- context,
- defaultDisplay
- )
- ).thenReturn(param.isDefaultDisplayDesktopEligible)
- setMouseConnected(param.hasAnyMouseDevice)
+ whenever(DesktopModeStatus.isDesktopModeSupportedOnDisplay(context, defaultDisplay))
+ .thenReturn(param.isDefaultDisplayDesktopEligible)
+ setTouchpadConnected(param.hasAnyTouchpadDevice)
+ setKeyboardConnected(param.hasAnyKeyboardDevice)
assertThat(controller.getTargetWindowingModeForDefaultDisplay())
.isEqualTo(param.expectedWindowingMode)
@@ -308,18 +304,10 @@ class DesktopDisplayModeControllerTest(
controller.refreshDisplayWindowingMode()
}
- private fun setTabletModeStatus(status: SwitchState) {
- whenever(inputManager.isInTabletMode()).thenReturn(status.value)
- }
-
private fun setExtendedMode(enabled: Boolean) {
if (DisplayFlags.enableDisplayContentModeManagement()) {
- whenever(
- DesktopModeStatus.isDesktopModeSupportedOnDisplay(
- context,
- externalDisplay
- )
- ).thenReturn(enabled)
+ whenever(DesktopModeStatus.isDesktopModeSupportedOnDisplay(context, externalDisplay))
+ .thenReturn(enabled)
} else {
Settings.Global.putInt(
context.contentResolver,
@@ -329,9 +317,20 @@ class DesktopDisplayModeControllerTest(
}
}
- private fun setMouseConnected(connected: Boolean) {
- whenever(inputManager.inputDeviceIds)
- .thenReturn(if (connected) intArrayOf(EXTERNAL_DEVICE_ID) else intArrayOf())
+ private fun setTouchpadConnected(connected: Boolean) {
+ if (connected) {
+ connectedDeviceIds.add(TOUCHPAD_DEVICE_ID)
+ } else {
+ connectedDeviceIds.remove(TOUCHPAD_DEVICE_ID)
+ }
+ }
+
+ private fun setKeyboardConnected(connected: Boolean) {
+ if (connected) {
+ connectedDeviceIds.add(KEYBOARD_DEVICE_ID)
+ } else {
+ connectedDeviceIds.remove(KEYBOARD_DEVICE_ID)
+ }
}
private class ExtendedDisplaySettingsRestoreSession(
@@ -358,13 +357,8 @@ class DesktopDisplayModeControllerTest(
companion object {
const val EXTERNAL_DISPLAY_ID = 100
- const val EXTERNAL_DEVICE_ID = 10
-
- enum class SwitchState(val value: Int) {
- UNKNOWN(InputManager.SWITCH_STATE_UNKNOWN),
- ON(InputManager.SWITCH_STATE_ON),
- OFF(InputManager.SWITCH_STATE_OFF),
- }
+ const val TOUCHPAD_DEVICE_ID = 10
+ const val KEYBOARD_DEVICE_ID = 11
enum class ExternalDisplayBasedTargetModeTestCase(
val defaultWindowingMode: Int,
@@ -490,393 +484,265 @@ class DesktopDisplayModeControllerTest(
enum class FormFactorBasedTargetModeTestCase(
val hasExternalDisplay: Boolean,
val extendedDisplayEnabled: Boolean,
- val tabletModeStatus: SwitchState,
val isDefaultDisplayDesktopEligible: Boolean,
- val hasAnyMouseDevice: Boolean,
+ val hasAnyTouchpadDevice: Boolean,
+ val hasAnyKeyboardDevice: Boolean,
val expectedWindowingMode: Int,
) {
- EXTERNAL_EXTENDED_TABLET_NO_PROJECTED_NO_MOUSE(
+ EXTERNAL_EXTENDED_NO_PROJECTED_TOUCHPAD_KEYBOARD(
hasExternalDisplay = true,
extendedDisplayEnabled = true,
- tabletModeStatus = SwitchState.ON,
isDefaultDisplayDesktopEligible = true,
- hasAnyMouseDevice = false,
+ hasAnyTouchpadDevice = true,
+ hasAnyKeyboardDevice = true,
expectedWindowingMode = WINDOWING_MODE_FREEFORM,
),
- NO_EXTERNAL_EXTENDED_TABLET_NO_PROJECTED_NO_MOUSE(
+ NO_EXTERNAL_EXTENDED_NO_PROJECTED_TOUCHPAD_KEYBOARD(
hasExternalDisplay = false,
extendedDisplayEnabled = true,
- tabletModeStatus = SwitchState.ON,
- isDefaultDisplayDesktopEligible = true,
- hasAnyMouseDevice = false,
- expectedWindowingMode = WINDOWING_MODE_FULLSCREEN,
- ),
- EXTERNAL_MIRROR_TABLET_NO_PROJECTED_NO_MOUSE(
- hasExternalDisplay = true,
- extendedDisplayEnabled = false,
- tabletModeStatus = SwitchState.ON,
- isDefaultDisplayDesktopEligible = true,
- hasAnyMouseDevice = false,
- expectedWindowingMode = WINDOWING_MODE_FULLSCREEN,
- ),
- NO_EXTERNAL_MIRROR_TABLET_NO_PROJECTED_NO_MOUSE(
- hasExternalDisplay = false,
- extendedDisplayEnabled = false,
- tabletModeStatus = SwitchState.ON,
- isDefaultDisplayDesktopEligible = true,
- hasAnyMouseDevice = false,
- expectedWindowingMode = WINDOWING_MODE_FULLSCREEN,
- ),
- EXTERNAL_EXTENDED_CLAMSHELL_NO_PROJECTED_NO_MOUSE(
- hasExternalDisplay = true,
- extendedDisplayEnabled = true,
- tabletModeStatus = SwitchState.OFF,
isDefaultDisplayDesktopEligible = true,
- hasAnyMouseDevice = false,
+ hasAnyTouchpadDevice = true,
+ hasAnyKeyboardDevice = true,
expectedWindowingMode = WINDOWING_MODE_FREEFORM,
),
- NO_EXTERNAL_EXTENDED_CLAMSHELL_NO_PROJECTED_NO_MOUSE(
- hasExternalDisplay = false,
- extendedDisplayEnabled = true,
- tabletModeStatus = SwitchState.OFF,
- isDefaultDisplayDesktopEligible = true,
- hasAnyMouseDevice = false,
- expectedWindowingMode = WINDOWING_MODE_FREEFORM,
- ),
- EXTERNAL_MIRROR_CLAMSHELL_NO_PROJECTED_NO_MOUSE(
+ EXTERNAL_MIRROR_NO_PROJECTED_TOUCHPAD_KEYBOARD(
hasExternalDisplay = true,
extendedDisplayEnabled = false,
- tabletModeStatus = SwitchState.OFF,
isDefaultDisplayDesktopEligible = true,
- hasAnyMouseDevice = false,
+ hasAnyTouchpadDevice = true,
+ hasAnyKeyboardDevice = true,
expectedWindowingMode = WINDOWING_MODE_FREEFORM,
),
- NO_EXTERNAL_MIRROR_CLAMSHELL_NO_PROJECTED_NO_MOUSE(
+ NO_EXTERNAL_MIRROR_NO_PROJECTED_TOUCHPAD_KEYBOARD(
hasExternalDisplay = false,
extendedDisplayEnabled = false,
- tabletModeStatus = SwitchState.OFF,
isDefaultDisplayDesktopEligible = true,
- hasAnyMouseDevice = false,
+ hasAnyTouchpadDevice = true,
+ hasAnyKeyboardDevice = true,
expectedWindowingMode = WINDOWING_MODE_FREEFORM,
),
- EXTERNAL_EXTENDED_UNKNOWN_NO_PROJECTED_NO_MOUSE(
- hasExternalDisplay = true,
- extendedDisplayEnabled = true,
- tabletModeStatus = SwitchState.UNKNOWN,
- isDefaultDisplayDesktopEligible = true,
- hasAnyMouseDevice = false,
- expectedWindowingMode = WINDOWING_MODE_FREEFORM,
- ),
- NO_EXTERNAL_EXTENDED_UNKNOWN_NO_PROJECTED_NO_MOUSE(
- hasExternalDisplay = false,
- extendedDisplayEnabled = true,
- tabletModeStatus = SwitchState.UNKNOWN,
- isDefaultDisplayDesktopEligible = true,
- hasAnyMouseDevice = false,
- expectedWindowingMode = WINDOWING_MODE_FULLSCREEN,
- ),
- EXTERNAL_MIRROR_UNKNOWN_NO_PROJECTED_NO_MOUSE(
- hasExternalDisplay = true,
- extendedDisplayEnabled = false,
- tabletModeStatus = SwitchState.UNKNOWN,
- isDefaultDisplayDesktopEligible = true,
- hasAnyMouseDevice = false,
- expectedWindowingMode = WINDOWING_MODE_FULLSCREEN,
- ),
- NO_EXTERNAL_MIRROR_UNKNOWN_NO_PROJECTED_NO_MOUSE(
- hasExternalDisplay = false,
- extendedDisplayEnabled = false,
- tabletModeStatus = SwitchState.UNKNOWN,
- isDefaultDisplayDesktopEligible = true,
- hasAnyMouseDevice = false,
- expectedWindowingMode = WINDOWING_MODE_FULLSCREEN,
- ),
- EXTERNAL_EXTENDED_TABLET_PROJECTED_NO_MOUSE(
+ EXTERNAL_EXTENDED_PROJECTED_TOUCHPAD_KEYBOARD(
hasExternalDisplay = true,
extendedDisplayEnabled = true,
- tabletModeStatus = SwitchState.ON,
isDefaultDisplayDesktopEligible = false,
- hasAnyMouseDevice = false,
+ hasAnyTouchpadDevice = true,
+ hasAnyKeyboardDevice = true,
expectedWindowingMode = WINDOWING_MODE_FULLSCREEN,
),
- NO_EXTERNAL_EXTENDED_TABLET_PROJECTED_NO_MOUSE(
+ NO_EXTERNAL_EXTENDED_PROJECTED_TOUCHPAD_KEYBOARD(
hasExternalDisplay = false,
extendedDisplayEnabled = true,
- tabletModeStatus = SwitchState.ON,
isDefaultDisplayDesktopEligible = false,
- hasAnyMouseDevice = false,
+ hasAnyTouchpadDevice = true,
+ hasAnyKeyboardDevice = true,
expectedWindowingMode = WINDOWING_MODE_FULLSCREEN,
),
- EXTERNAL_MIRROR_TABLET_PROJECTED_NO_MOUSE(
+ EXTERNAL_MIRROR_PROJECTED_TOUCHPAD_KEYBOARD(
hasExternalDisplay = true,
extendedDisplayEnabled = false,
- tabletModeStatus = SwitchState.ON,
isDefaultDisplayDesktopEligible = false,
- hasAnyMouseDevice = false,
+ hasAnyTouchpadDevice = true,
+ hasAnyKeyboardDevice = true,
expectedWindowingMode = WINDOWING_MODE_FULLSCREEN,
),
- NO_EXTERNAL_MIRROR_TABLET_PROJECTED_NO_MOUSE(
+ NO_EXTERNAL_MIRROR_PROJECTED_TOUCHPAD_KEYBOARD(
hasExternalDisplay = false,
extendedDisplayEnabled = false,
- tabletModeStatus = SwitchState.ON,
isDefaultDisplayDesktopEligible = false,
- hasAnyMouseDevice = false,
+ hasAnyTouchpadDevice = true,
+ hasAnyKeyboardDevice = true,
expectedWindowingMode = WINDOWING_MODE_FULLSCREEN,
),
- EXTERNAL_EXTENDED_CLAMSHELL_PROJECTED_NO_MOUSE(
+ EXTERNAL_EXTENDED_NO_PROJECTED_NO_TOUCHPAD_KEYBOARD(
hasExternalDisplay = true,
extendedDisplayEnabled = true,
- tabletModeStatus = SwitchState.OFF,
- isDefaultDisplayDesktopEligible = false,
- hasAnyMouseDevice = false,
- expectedWindowingMode = WINDOWING_MODE_FULLSCREEN,
+ isDefaultDisplayDesktopEligible = true,
+ hasAnyTouchpadDevice = false,
+ hasAnyKeyboardDevice = true,
+ expectedWindowingMode = WINDOWING_MODE_FREEFORM,
),
- NO_EXTERNAL_EXTENDED_CLAMSHELL_PROJECTED_NO_MOUSE(
+ NO_EXTERNAL_EXTENDED_NO_PROJECTED_NO_TOUCHPAD_KEYBOARD(
hasExternalDisplay = false,
extendedDisplayEnabled = true,
- tabletModeStatus = SwitchState.OFF,
- isDefaultDisplayDesktopEligible = false,
- hasAnyMouseDevice = false,
+ isDefaultDisplayDesktopEligible = true,
+ hasAnyTouchpadDevice = false,
+ hasAnyKeyboardDevice = true,
expectedWindowingMode = WINDOWING_MODE_FULLSCREEN,
),
- EXTERNAL_MIRROR_CLAMSHELL_PROJECTED_NO_MOUSE(
+ EXTERNAL_MIRROR_NO_PROJECTED_NO_TOUCHPAD_KEYBOARD(
hasExternalDisplay = true,
extendedDisplayEnabled = false,
- tabletModeStatus = SwitchState.OFF,
- isDefaultDisplayDesktopEligible = false,
- hasAnyMouseDevice = false,
+ isDefaultDisplayDesktopEligible = true,
+ hasAnyTouchpadDevice = false,
+ hasAnyKeyboardDevice = true,
expectedWindowingMode = WINDOWING_MODE_FULLSCREEN,
),
- NO_EXTERNAL_MIRROR_CLAMSHELL_PROJECTED_NO_MOUSE(
+ NO_EXTERNAL_MIRROR_NO_PROJECTED_NO_TOUCHPAD_KEYBOARD(
hasExternalDisplay = false,
extendedDisplayEnabled = false,
- tabletModeStatus = SwitchState.OFF,
- isDefaultDisplayDesktopEligible = false,
- hasAnyMouseDevice = false,
+ isDefaultDisplayDesktopEligible = true,
+ hasAnyTouchpadDevice = false,
+ hasAnyKeyboardDevice = true,
expectedWindowingMode = WINDOWING_MODE_FULLSCREEN,
),
- EXTERNAL_EXTENDED_UNKNOWN_PROJECTED_NO_MOUSE(
+ EXTERNAL_EXTENDED_PROJECTED_NO_TOUCHPAD_KEYBOARD(
hasExternalDisplay = true,
extendedDisplayEnabled = true,
- tabletModeStatus = SwitchState.UNKNOWN,
isDefaultDisplayDesktopEligible = false,
- hasAnyMouseDevice = false,
+ hasAnyTouchpadDevice = false,
+ hasAnyKeyboardDevice = true,
expectedWindowingMode = WINDOWING_MODE_FULLSCREEN,
),
- NO_EXTERNAL_EXTENDED_UNKNOWN_PROJECTED_NO_MOUSE(
+ NO_EXTERNAL_EXTENDED_PROJECTED_NO_TOUCHPAD_KEYBOARD(
hasExternalDisplay = false,
extendedDisplayEnabled = true,
- tabletModeStatus = SwitchState.UNKNOWN,
isDefaultDisplayDesktopEligible = false,
- hasAnyMouseDevice = false,
+ hasAnyTouchpadDevice = false,
+ hasAnyKeyboardDevice = true,
expectedWindowingMode = WINDOWING_MODE_FULLSCREEN,
),
- EXTERNAL_MIRROR_UNKNOWN_PROJECTED_NO_MOUSE(
+ EXTERNAL_MIRROR_PROJECTED_NO_TOUCHPAD_KEYBOARD(
hasExternalDisplay = true,
extendedDisplayEnabled = false,
- tabletModeStatus = SwitchState.UNKNOWN,
isDefaultDisplayDesktopEligible = false,
- hasAnyMouseDevice = false,
+ hasAnyTouchpadDevice = false,
+ hasAnyKeyboardDevice = true,
expectedWindowingMode = WINDOWING_MODE_FULLSCREEN,
),
- NO_EXTERNAL_MIRROR_UNKNOWN_PROJECTED_NO_MOUSE(
+ NO_EXTERNAL_MIRROR_PROJECTED_NO_TOUCHPAD_KEYBOARD(
hasExternalDisplay = false,
extendedDisplayEnabled = false,
- tabletModeStatus = SwitchState.UNKNOWN,
isDefaultDisplayDesktopEligible = false,
- hasAnyMouseDevice = false,
+ hasAnyTouchpadDevice = false,
+ hasAnyKeyboardDevice = true,
expectedWindowingMode = WINDOWING_MODE_FULLSCREEN,
),
- EXTERNAL_EXTENDED_TABLET_NO_PROJECTED_MOUSE(
+ EXTERNAL_EXTENDED_NO_PROJECTED_TOUCHPAD_NO_KEYBOARD(
hasExternalDisplay = true,
extendedDisplayEnabled = true,
- tabletModeStatus = SwitchState.ON,
isDefaultDisplayDesktopEligible = true,
- hasAnyMouseDevice = true,
+ hasAnyTouchpadDevice = true,
+ hasAnyKeyboardDevice = false,
expectedWindowingMode = WINDOWING_MODE_FREEFORM,
),
- NO_EXTERNAL_EXTENDED_TABLET_NO_PROJECTED_MOUSE(
+ NO_EXTERNAL_EXTENDED_NO_PROJECTED_TOUCHPAD_NO_KEYBOARD(
hasExternalDisplay = false,
extendedDisplayEnabled = true,
- tabletModeStatus = SwitchState.ON,
- isDefaultDisplayDesktopEligible = true,
- hasAnyMouseDevice = true,
- expectedWindowingMode = WINDOWING_MODE_FREEFORM,
- ),
- EXTERNAL_MIRROR_TABLET_NO_PROJECTED_MOUSE(
- hasExternalDisplay = true,
- extendedDisplayEnabled = false,
- tabletModeStatus = SwitchState.ON,
- isDefaultDisplayDesktopEligible = true,
- hasAnyMouseDevice = true,
- expectedWindowingMode = WINDOWING_MODE_FREEFORM,
- ),
- NO_EXTERNAL_MIRROR_TABLET_NO_PROJECTED_MOUSE(
- hasExternalDisplay = false,
- extendedDisplayEnabled = false,
- tabletModeStatus = SwitchState.ON,
isDefaultDisplayDesktopEligible = true,
- hasAnyMouseDevice = true,
- expectedWindowingMode = WINDOWING_MODE_FREEFORM,
- ),
- EXTERNAL_EXTENDED_CLAMSHELL_NO_PROJECTED_MOUSE(
- hasExternalDisplay = true,
- extendedDisplayEnabled = true,
- tabletModeStatus = SwitchState.OFF,
- isDefaultDisplayDesktopEligible = true,
- hasAnyMouseDevice = true,
- expectedWindowingMode = WINDOWING_MODE_FREEFORM,
- ),
- NO_EXTERNAL_EXTENDED_CLAMSHELL_NO_PROJECTED_MOUSE(
- hasExternalDisplay = false,
- extendedDisplayEnabled = true,
- tabletModeStatus = SwitchState.OFF,
- isDefaultDisplayDesktopEligible = true,
- hasAnyMouseDevice = true,
- expectedWindowingMode = WINDOWING_MODE_FREEFORM,
- ),
- EXTERNAL_MIRROR_CLAMSHELL_NO_PROJECTED_MOUSE(
- hasExternalDisplay = true,
- extendedDisplayEnabled = false,
- tabletModeStatus = SwitchState.OFF,
- isDefaultDisplayDesktopEligible = true,
- hasAnyMouseDevice = true,
- expectedWindowingMode = WINDOWING_MODE_FREEFORM,
- ),
- NO_EXTERNAL_MIRROR_CLAMSHELL_NO_PROJECTED_MOUSE(
- hasExternalDisplay = false,
- extendedDisplayEnabled = false,
- tabletModeStatus = SwitchState.OFF,
- isDefaultDisplayDesktopEligible = true,
- hasAnyMouseDevice = true,
- expectedWindowingMode = WINDOWING_MODE_FREEFORM,
- ),
- EXTERNAL_EXTENDED_UNKNOWN_NO_PROJECTED_MOUSE(
- hasExternalDisplay = true,
- extendedDisplayEnabled = true,
- tabletModeStatus = SwitchState.UNKNOWN,
- isDefaultDisplayDesktopEligible = true,
- hasAnyMouseDevice = true,
- expectedWindowingMode = WINDOWING_MODE_FREEFORM,
- ),
- NO_EXTERNAL_EXTENDED_UNKNOWN_NO_PROJECTED_MOUSE(
- hasExternalDisplay = false,
- extendedDisplayEnabled = true,
- tabletModeStatus = SwitchState.UNKNOWN,
- isDefaultDisplayDesktopEligible = true,
- hasAnyMouseDevice = true,
- expectedWindowingMode = WINDOWING_MODE_FREEFORM,
+ hasAnyTouchpadDevice = true,
+ hasAnyKeyboardDevice = false,
+ expectedWindowingMode = WINDOWING_MODE_FULLSCREEN,
),
- EXTERNAL_MIRROR_UNKNOWN_NO_PROJECTED_MOUSE(
+ EXTERNAL_MIRROR_NO_PROJECTED_TOUCHPAD_NO_KEYBOARD(
hasExternalDisplay = true,
extendedDisplayEnabled = false,
- tabletModeStatus = SwitchState.UNKNOWN,
isDefaultDisplayDesktopEligible = true,
- hasAnyMouseDevice = true,
- expectedWindowingMode = WINDOWING_MODE_FREEFORM,
+ hasAnyTouchpadDevice = true,
+ hasAnyKeyboardDevice = false,
+ expectedWindowingMode = WINDOWING_MODE_FULLSCREEN,
),
- NO_EXTERNAL_MIRROR_UNKNOWN_NO_PROJECTED_MOUSE(
+ NO_EXTERNAL_MIRROR_NO_PROJECTED_TOUCHPAD_NO_KEYBOARD(
hasExternalDisplay = false,
extendedDisplayEnabled = false,
- tabletModeStatus = SwitchState.UNKNOWN,
isDefaultDisplayDesktopEligible = true,
- hasAnyMouseDevice = true,
- expectedWindowingMode = WINDOWING_MODE_FREEFORM,
+ hasAnyTouchpadDevice = true,
+ hasAnyKeyboardDevice = false,
+ expectedWindowingMode = WINDOWING_MODE_FULLSCREEN,
),
- EXTERNAL_EXTENDED_TABLET_PROJECTED_MOUSE(
+ EXTERNAL_EXTENDED_PROJECTED_TOUCHPAD_NO_KEYBOARD(
hasExternalDisplay = true,
extendedDisplayEnabled = true,
- tabletModeStatus = SwitchState.ON,
isDefaultDisplayDesktopEligible = false,
- hasAnyMouseDevice = true,
+ hasAnyTouchpadDevice = true,
+ hasAnyKeyboardDevice = false,
expectedWindowingMode = WINDOWING_MODE_FULLSCREEN,
),
- NO_EXTERNAL_EXTENDED_TABLET_PROJECTED_MOUSE(
+ NO_EXTERNAL_EXTENDED_PROJECTED_TOUCHPAD_NO_KEYBOARD(
hasExternalDisplay = false,
extendedDisplayEnabled = true,
- tabletModeStatus = SwitchState.ON,
isDefaultDisplayDesktopEligible = false,
- hasAnyMouseDevice = true,
+ hasAnyTouchpadDevice = true,
+ hasAnyKeyboardDevice = false,
expectedWindowingMode = WINDOWING_MODE_FULLSCREEN,
),
- EXTERNAL_MIRROR_TABLET_PROJECTED_MOUSE(
+ EXTERNAL_MIRROR_PROJECTED_TOUCHPAD_NO_KEYBOARD(
hasExternalDisplay = true,
extendedDisplayEnabled = false,
- tabletModeStatus = SwitchState.ON,
isDefaultDisplayDesktopEligible = false,
- hasAnyMouseDevice = true,
+ hasAnyTouchpadDevice = true,
+ hasAnyKeyboardDevice = false,
expectedWindowingMode = WINDOWING_MODE_FULLSCREEN,
),
- NO_EXTERNAL_MIRROR_TABLET_PROJECTED_MOUSE(
+ NO_EXTERNAL_MIRROR_PROJECTED_TOUCHPAD_NO_KEYBOARD(
hasExternalDisplay = false,
extendedDisplayEnabled = false,
- tabletModeStatus = SwitchState.ON,
isDefaultDisplayDesktopEligible = false,
- hasAnyMouseDevice = true,
+ hasAnyTouchpadDevice = true,
+ hasAnyKeyboardDevice = false,
expectedWindowingMode = WINDOWING_MODE_FULLSCREEN,
),
- EXTERNAL_EXTENDED_CLAMSHELL_PROJECTED_MOUSE(
+ EXTERNAL_EXTENDED_NO_PROJECTED_NO_TOUCHPAD_NO_KEYBOARD(
hasExternalDisplay = true,
extendedDisplayEnabled = true,
- tabletModeStatus = SwitchState.OFF,
- isDefaultDisplayDesktopEligible = false,
- hasAnyMouseDevice = true,
- expectedWindowingMode = WINDOWING_MODE_FULLSCREEN,
+ isDefaultDisplayDesktopEligible = true,
+ hasAnyTouchpadDevice = false,
+ hasAnyKeyboardDevice = false,
+ expectedWindowingMode = WINDOWING_MODE_FREEFORM,
),
- NO_EXTERNAL_EXTENDED_CLAMSHELL_PROJECTED_MOUSE(
+ NO_EXTERNAL_EXTENDED_NO_PROJECTED_NO_TOUCHPAD_NO_KEYBOARD(
hasExternalDisplay = false,
extendedDisplayEnabled = true,
- tabletModeStatus = SwitchState.OFF,
- isDefaultDisplayDesktopEligible = false,
- hasAnyMouseDevice = true,
+ isDefaultDisplayDesktopEligible = true,
+ hasAnyTouchpadDevice = false,
+ hasAnyKeyboardDevice = false,
expectedWindowingMode = WINDOWING_MODE_FULLSCREEN,
),
- EXTERNAL_MIRROR_CLAMSHELL_PROJECTED_MOUSE(
+ EXTERNAL_MIRROR_NO_PROJECTED_NO_TOUCHPAD_NO_KEYBOARD(
hasExternalDisplay = true,
extendedDisplayEnabled = false,
- tabletModeStatus = SwitchState.OFF,
- isDefaultDisplayDesktopEligible = false,
- hasAnyMouseDevice = true,
+ isDefaultDisplayDesktopEligible = true,
+ hasAnyTouchpadDevice = false,
+ hasAnyKeyboardDevice = false,
expectedWindowingMode = WINDOWING_MODE_FULLSCREEN,
),
- NO_EXTERNAL_MIRROR_CLAMSHELL_PROJECTED_MOUSE(
+ NO_EXTERNAL_MIRROR_NO_PROJECTED_NO_TOUCHPAD_NO_KEYBOARD(
hasExternalDisplay = false,
extendedDisplayEnabled = false,
- tabletModeStatus = SwitchState.OFF,
- isDefaultDisplayDesktopEligible = false,
- hasAnyMouseDevice = true,
+ isDefaultDisplayDesktopEligible = true,
+ hasAnyTouchpadDevice = false,
+ hasAnyKeyboardDevice = false,
expectedWindowingMode = WINDOWING_MODE_FULLSCREEN,
),
- EXTERNAL_EXTENDED_UNKNOWN_PROJECTED_MOUSE(
+ EXTERNAL_EXTENDED_PROJECTED_NO_TOUCHPAD_NO_KEYBOARD(
hasExternalDisplay = true,
extendedDisplayEnabled = true,
- tabletModeStatus = SwitchState.UNKNOWN,
isDefaultDisplayDesktopEligible = false,
- hasAnyMouseDevice = true,
+ hasAnyTouchpadDevice = false,
+ hasAnyKeyboardDevice = false,
expectedWindowingMode = WINDOWING_MODE_FULLSCREEN,
),
- NO_EXTERNAL_EXTENDED_UNKNOWN_PROJECTED_MOUSE(
+ NO_EXTERNAL_EXTENDED_PROJECTED_NO_TOUCHPAD_NO_KEYBOARD(
hasExternalDisplay = false,
extendedDisplayEnabled = true,
- tabletModeStatus = SwitchState.UNKNOWN,
isDefaultDisplayDesktopEligible = false,
- hasAnyMouseDevice = true,
+ hasAnyTouchpadDevice = false,
+ hasAnyKeyboardDevice = false,
expectedWindowingMode = WINDOWING_MODE_FULLSCREEN,
),
- EXTERNAL_MIRROR_UNKNOWN_PROJECTED_MOUSE(
+ EXTERNAL_MIRROR_PROJECTED_NO_TOUCHPAD_NO_KEYBOARD(
hasExternalDisplay = true,
extendedDisplayEnabled = false,
- tabletModeStatus = SwitchState.UNKNOWN,
isDefaultDisplayDesktopEligible = false,
- hasAnyMouseDevice = true,
+ hasAnyTouchpadDevice = false,
+ hasAnyKeyboardDevice = false,
expectedWindowingMode = WINDOWING_MODE_FULLSCREEN,
),
- NO_EXTERNAL_MIRROR_UNKNOWN_PROJECTED_MOUSE(
+ NO_EXTERNAL_MIRROR_PROJECTED_NO_TOUCHPAD_NO_KEYBOARD(
hasExternalDisplay = false,
extendedDisplayEnabled = false,
- tabletModeStatus = SwitchState.UNKNOWN,
isDefaultDisplayDesktopEligible = false,
- hasAnyMouseDevice = true,
+ hasAnyTouchpadDevice = false,
+ hasAnyKeyboardDevice = false,
expectedWindowingMode = WINDOWING_MODE_FULLSCREEN,
),
}
diff --git a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/desktopmode/DesktopModeVisualIndicatorTest.kt b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/desktopmode/DesktopModeVisualIndicatorTest.kt
index 652fae01c1b2..a4052890f08a 100644
--- a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/desktopmode/DesktopModeVisualIndicatorTest.kt
+++ b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/desktopmode/DesktopModeVisualIndicatorTest.kt
@@ -283,14 +283,32 @@ class DesktopModeVisualIndicatorTest : ShellTestCase() {
com.android.wm.shell.Flags.FLAG_ENABLE_BUBBLE_TO_FULLSCREEN,
com.android.wm.shell.Flags.FLAG_ENABLE_CREATE_ANY_BUBBLE,
)
- fun testDefaultIndicators_bubblesEnabled() {
+ fun testDefaultIndicators_enableBubbleToFullscreen() {
createVisualIndicator(DesktopModeVisualIndicator.DragStartState.FROM_FULLSCREEN)
var result = visualIndicator.updateIndicatorType(PointF(10f, 1500f))
assertThat(result)
.isEqualTo(DesktopModeVisualIndicator.IndicatorType.TO_BUBBLE_LEFT_INDICATOR)
- result = visualIndicator.updateIndicatorType(PointF(2300f, 1500f))
+ result = visualIndicator.updateIndicatorType(PointF(2390f, 1500f))
assertThat(result)
.isEqualTo(DesktopModeVisualIndicator.IndicatorType.TO_BUBBLE_RIGHT_INDICATOR)
+
+ // Check that bubble zones are not available from split
+ createVisualIndicator(DesktopModeVisualIndicator.DragStartState.FROM_SPLIT)
+ result = visualIndicator.updateIndicatorType(PointF(10f, 1500f))
+ assertThat(result)
+ .isEqualTo(DesktopModeVisualIndicator.IndicatorType.TO_SPLIT_LEFT_INDICATOR)
+ result = visualIndicator.updateIndicatorType(PointF(2390f, 1500f))
+ assertThat(result)
+ .isEqualTo(DesktopModeVisualIndicator.IndicatorType.TO_SPLIT_RIGHT_INDICATOR)
+
+ // Check that bubble zones are not available from desktop
+ createVisualIndicator(DesktopModeVisualIndicator.DragStartState.FROM_FREEFORM)
+ result = visualIndicator.updateIndicatorType(PointF(10f, 1500f))
+ assertThat(result)
+ .isEqualTo(DesktopModeVisualIndicator.IndicatorType.TO_SPLIT_LEFT_INDICATOR)
+ result = visualIndicator.updateIndicatorType(PointF(2390f, 1500f))
+ assertThat(result)
+ .isEqualTo(DesktopModeVisualIndicator.IndicatorType.TO_SPLIT_RIGHT_INDICATOR)
}
@Test
@@ -298,7 +316,7 @@ class DesktopModeVisualIndicatorTest : ShellTestCase() {
com.android.wm.shell.Flags.FLAG_ENABLE_BUBBLE_TO_FULLSCREEN,
com.android.wm.shell.Flags.FLAG_ENABLE_CREATE_ANY_BUBBLE,
)
- fun testDefaultIndicators_foldable_leftRightSplit() {
+ fun testDefaultIndicators_foldable_enableBubbleToFullscreen_dragFromFullscreen() {
setUpFoldable()
createVisualIndicator(
@@ -325,13 +343,47 @@ class DesktopModeVisualIndicatorTest : ShellTestCase() {
result = visualIndicator.updateIndicatorType(foldRightBottom())
assertThat(result)
.isEqualTo(DesktopModeVisualIndicator.IndicatorType.TO_BUBBLE_RIGHT_INDICATOR)
+ }
+
+ @Test
+ @EnableFlags(
+ com.android.wm.shell.Flags.FLAG_ENABLE_BUBBLE_TO_FULLSCREEN,
+ com.android.wm.shell.Flags.FLAG_ENABLE_CREATE_ANY_BUBBLE,
+ )
+ @DisableFlags(com.android.wm.shell.Flags.FLAG_ENABLE_BUBBLE_ANYTHING)
+ fun testDefaultIndicators_foldable_enableBubbleToFullscreen_dragFromSplit() {
+ setUpFoldable()
createVisualIndicator(
DesktopModeVisualIndicator.DragStartState.FROM_SPLIT,
isSmallTablet = true,
isLeftRightSplit = true,
)
- result = visualIndicator.updateIndicatorType(foldCenter())
+ var result = visualIndicator.updateIndicatorType(foldCenter())
+ assertThat(result)
+ .isEqualTo(DesktopModeVisualIndicator.IndicatorType.TO_FULLSCREEN_INDICATOR)
+
+ // Check that bubbles are not available from split
+ result = visualIndicator.updateIndicatorType(foldLeftBottom())
+ assertThat(result)
+ .isEqualTo(DesktopModeVisualIndicator.IndicatorType.TO_SPLIT_LEFT_INDICATOR)
+
+ result = visualIndicator.updateIndicatorType(foldRightBottom())
+ assertThat(result)
+ .isEqualTo(DesktopModeVisualIndicator.IndicatorType.TO_SPLIT_RIGHT_INDICATOR)
+ }
+
+ @Test
+ @EnableFlags(com.android.wm.shell.Flags.FLAG_ENABLE_BUBBLE_ANYTHING)
+ fun testDefaultIndicators_foldable_enableBubbleAnything_dragFromSplit() {
+ setUpFoldable()
+
+ createVisualIndicator(
+ DesktopModeVisualIndicator.DragStartState.FROM_SPLIT,
+ isSmallTablet = true,
+ isLeftRightSplit = true,
+ )
+ var result = visualIndicator.updateIndicatorType(foldCenter())
assertThat(result)
.isEqualTo(DesktopModeVisualIndicator.IndicatorType.TO_FULLSCREEN_INDICATOR)
diff --git a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/desktopmode/DesktopPipTransitionControllerTest.kt b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/desktopmode/DesktopPipTransitionControllerTest.kt
new file mode 100644
index 000000000000..47a9a6c8d840
--- /dev/null
+++ b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/desktopmode/DesktopPipTransitionControllerTest.kt
@@ -0,0 +1,165 @@
+/*
+ * Copyright (C) 2025 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.desktopmode
+
+import android.os.Binder
+import android.platform.test.annotations.EnableFlags
+import android.platform.test.flag.junit.FlagsParameterization
+import android.view.Display.DEFAULT_DISPLAY
+import android.window.WindowContainerTransaction
+import androidx.test.filters.SmallTest
+import com.android.window.flags.Flags
+import com.android.window.flags.Flags.FLAG_ENABLE_DESKTOP_WINDOWING_PIP
+import com.android.window.flags.Flags.FLAG_ENABLE_MULTIPLE_DESKTOPS_BACKEND
+import com.android.wm.shell.ShellTestCase
+import com.android.wm.shell.common.pip.PipDesktopState
+import com.android.wm.shell.desktopmode.DesktopTestHelpers.createFreeformTask
+import org.junit.Before
+import org.junit.Test
+import org.junit.runner.RunWith
+import org.mockito.ArgumentMatchers.anyBoolean
+import org.mockito.ArgumentMatchers.anyInt
+import org.mockito.ArgumentMatchers.eq
+import org.mockito.kotlin.any
+import org.mockito.kotlin.mock
+import org.mockito.kotlin.never
+import org.mockito.kotlin.verify
+import org.mockito.kotlin.whenever
+import platform.test.runner.parameterized.ParameterizedAndroidJunit4
+import platform.test.runner.parameterized.Parameters
+
+/**
+ * Tests for [DesktopPipTransitionController].
+ *
+ * Build/Install/Run: atest WMShellUnitTests:DesktopPipTransitionControllerTest
+ */
+@SmallTest
+@RunWith(ParameterizedAndroidJunit4::class)
+@EnableFlags(FLAG_ENABLE_DESKTOP_WINDOWING_PIP)
+class DesktopPipTransitionControllerTest(flags: FlagsParameterization) : ShellTestCase() {
+ private val mockDesktopTasksController = mock<DesktopTasksController>()
+ private val mockDesktopUserRepositories = mock<DesktopUserRepositories>()
+ private val mockDesktopRepository = mock<DesktopRepository>()
+ private val mockPipDesktopState = mock<PipDesktopState>()
+
+ private lateinit var controller: DesktopPipTransitionController
+
+ private val transition = Binder()
+ private val wct = WindowContainerTransaction()
+ private val taskInfo = createFreeformTask()
+
+ init {
+ mSetFlagsRule.setFlagsParameterization(flags)
+ }
+
+ @Before
+ fun setUp() {
+ whenever(mockPipDesktopState.isDesktopWindowingPipEnabled()).thenReturn(true)
+ whenever(mockDesktopUserRepositories.getProfile(anyInt())).thenReturn(mockDesktopRepository)
+ whenever(mockDesktopRepository.isAnyDeskActive(anyInt())).thenReturn(true)
+ whenever(mockDesktopRepository.getActiveDeskId(anyInt())).thenReturn(DESK_ID)
+
+ controller =
+ DesktopPipTransitionController(
+ mockDesktopTasksController,
+ mockDesktopUserRepositories,
+ mockPipDesktopState,
+ )
+ }
+
+ @Test
+ fun handlePipTransition_noDeskActive_doesntPerformDesktopExitCleanup() {
+ whenever(mockDesktopRepository.isAnyDeskActive(eq(taskInfo.displayId))).thenReturn(false)
+
+ controller.handlePipTransition(wct, transition, taskInfo)
+
+ verifyPerformDesktopExitCleanupAfterPip(isCalled = false)
+ }
+
+ @Test
+ fun handlePipTransition_notLastTask_doesntPerformDesktopExitCleanup() {
+ whenever(
+ mockDesktopRepository.isOnlyVisibleNonClosingTaskInDesk(
+ taskId = eq(taskInfo.taskId),
+ deskId = eq(DESK_ID),
+ displayId = eq(taskInfo.displayId),
+ )
+ )
+ .thenReturn(false)
+
+ controller.handlePipTransition(wct, transition, taskInfo)
+
+ verifyPerformDesktopExitCleanupAfterPip(isCalled = false)
+ }
+
+ @Test
+ @EnableFlags(FLAG_ENABLE_MULTIPLE_DESKTOPS_BACKEND)
+ fun handlePipTransition_noActiveDeskId_multiDesk_doesntPerformDesktopExitCleanup() {
+ whenever(mockDesktopRepository.getActiveDeskId(eq(taskInfo.displayId))).thenReturn(null)
+
+ controller.handlePipTransition(wct, transition, taskInfo)
+
+ verifyPerformDesktopExitCleanupAfterPip(isCalled = false)
+ }
+
+ @Test
+ fun handlePipTransition_isLastTask_performDesktopExitCleanup() {
+ whenever(
+ mockDesktopRepository.isOnlyVisibleNonClosingTaskInDesk(
+ taskId = eq(taskInfo.taskId),
+ deskId = eq(DESK_ID),
+ displayId = eq(taskInfo.displayId),
+ )
+ )
+ .thenReturn(true)
+
+ controller.handlePipTransition(wct, transition, taskInfo)
+
+ verifyPerformDesktopExitCleanupAfterPip(isCalled = true)
+ }
+
+ private fun verifyPerformDesktopExitCleanupAfterPip(isCalled: Boolean) {
+ if (isCalled) {
+ verify(mockDesktopTasksController)
+ .performDesktopExitCleanUp(
+ wct = wct,
+ deskId = DESK_ID,
+ displayId = DEFAULT_DISPLAY,
+ willExitDesktop = true,
+ )
+ } else {
+ verify(mockDesktopTasksController, never())
+ .performDesktopExitCleanUp(
+ any(),
+ anyInt(),
+ anyInt(),
+ anyBoolean(),
+ anyBoolean(),
+ anyBoolean(),
+ )
+ }
+ }
+
+ private companion object {
+ const val DESK_ID = 1
+
+ @JvmStatic
+ @Parameters(name = "{0}")
+ fun getParams(): List<FlagsParameterization> =
+ FlagsParameterization.allCombinationsOf(Flags.FLAG_ENABLE_MULTIPLE_DESKTOPS_BACKEND)
+ }
+}
diff --git a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/desktopmode/DesktopPipTransitionObserverTest.kt b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/desktopmode/DesktopPipTransitionObserverTest.kt
deleted file mode 100644
index ef394d81cc57..000000000000
--- a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/desktopmode/DesktopPipTransitionObserverTest.kt
+++ /dev/null
@@ -1,98 +0,0 @@
-/*
- * Copyright (C) 2025 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.desktopmode
-
-import android.app.WindowConfiguration.WINDOWING_MODE_PINNED
-import android.os.Binder
-import android.platform.test.annotations.EnableFlags
-import android.platform.test.flag.junit.SetFlagsRule
-import android.testing.AndroidTestingRunner
-import android.view.WindowManager.TRANSIT_PIP
-import android.window.TransitionInfo
-import androidx.test.filters.SmallTest
-import com.android.window.flags.Flags
-import com.android.wm.shell.ShellTestCase
-import com.android.wm.shell.TestRunningTaskInfoBuilder
-import com.google.common.truth.Truth.assertThat
-import org.junit.Before
-import org.junit.Rule
-import org.junit.Test
-import org.junit.runner.RunWith
-import org.mockito.kotlin.mock
-
-/**
- * Tests for [DesktopPipTransitionObserver].
- *
- * Build/Install/Run: atest WMShellUnitTests:DesktopPipTransitionObserverTest
- */
-@SmallTest
-@RunWith(AndroidTestingRunner::class)
-class DesktopPipTransitionObserverTest : ShellTestCase() {
-
- @JvmField @Rule val setFlagsRule = SetFlagsRule()
-
- private lateinit var observer: DesktopPipTransitionObserver
-
- private val transition = Binder()
- private var onSuccessInvokedCount = 0
-
- @Before
- fun setUp() {
- observer = DesktopPipTransitionObserver()
-
- onSuccessInvokedCount = 0
- }
-
- @Test
- @EnableFlags(Flags.FLAG_ENABLE_DESKTOP_WINDOWING_PIP)
- fun onTransitionReady_taskInPinnedWindowingMode_onSuccessInvoked() {
- val taskId = 1
- val pipTransition = createPendingPipTransition(taskId)
- val successfulChange = createChange(taskId, WINDOWING_MODE_PINNED)
- observer.addPendingPipTransition(pipTransition)
-
- observer.onTransitionReady(
- transition = transition,
- info = TransitionInfo(
- TRANSIT_PIP, /* flags= */
- 0
- ).apply { addChange(successfulChange) },
- )
-
- assertThat(onSuccessInvokedCount).isEqualTo(1)
- }
-
- private fun createPendingPipTransition(
- taskId: Int
- ): DesktopPipTransitionObserver.PendingPipTransition {
- return DesktopPipTransitionObserver.PendingPipTransition(
- token = transition,
- taskId = taskId,
- onSuccess = { onSuccessInvokedCount += 1 },
- )
- }
-
- private fun createChange(taskId: Int, windowingMode: Int): TransitionInfo.Change {
- return TransitionInfo.Change(mock(), mock()).apply {
- taskInfo =
- TestRunningTaskInfoBuilder()
- .setTaskId(taskId)
- .setWindowingMode(windowingMode)
- .build()
- }
- }
-}
diff --git a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/desktopmode/DesktopRepositoryTest.kt b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/desktopmode/DesktopRepositoryTest.kt
index 3fb008377d6e..6ede990df15e 100644
--- a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/desktopmode/DesktopRepositoryTest.kt
+++ b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/desktopmode/DesktopRepositoryTest.kt
@@ -1280,6 +1280,18 @@ class DesktopRepositoryTest(flags: FlagsParameterization) : ShellTestCase() {
@Test
@EnableFlags(FLAG_ENABLE_MULTIPLE_DESKTOPS_BACKEND)
+ fun removeDesk_multipleDesks_active_marksInactiveInDisplay() {
+ repo.addDesk(displayId = DEFAULT_DISPLAY, deskId = 2)
+ repo.addDesk(displayId = DEFAULT_DISPLAY, deskId = 3)
+ repo.setActiveDesk(displayId = DEFAULT_DISPLAY, deskId = 3)
+
+ repo.removeDesk(deskId = 3)
+
+ assertThat(repo.getActiveDeskId(displayId = DEFAULT_DISPLAY)).isNull()
+ }
+
+ @Test
+ @EnableFlags(FLAG_ENABLE_MULTIPLE_DESKTOPS_BACKEND)
fun removeDesk_multipleDesks_inactive_removes() {
repo.addDesk(displayId = DEFAULT_DISPLAY, deskId = 2)
repo.addDesk(displayId = DEFAULT_DISPLAY, deskId = 3)
@@ -1292,6 +1304,18 @@ class DesktopRepositoryTest(flags: FlagsParameterization) : ShellTestCase() {
}
@Test
+ @EnableFlags(FLAG_ENABLE_MULTIPLE_DESKTOPS_BACKEND)
+ fun removeDesk_multipleDesks_inactive_keepsOtherDeskActiveInDisplay() {
+ repo.addDesk(displayId = DEFAULT_DISPLAY, deskId = 2)
+ repo.addDesk(displayId = DEFAULT_DISPLAY, deskId = 3)
+ repo.setActiveDesk(displayId = DEFAULT_DISPLAY, deskId = 3)
+
+ repo.removeDesk(deskId = 2)
+
+ assertThat(repo.getActiveDeskId(displayId = DEFAULT_DISPLAY)).isEqualTo(3)
+ }
+
+ @Test
@EnableFlags(FLAG_ENABLE_MULTIPLE_DESKTOPS_BACKEND, FLAG_ENABLE_DESKTOP_WINDOWING_PERSISTENCE)
fun removeDesk_removesFromPersistence() =
runTest(StandardTestDispatcher()) {
diff --git a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/desktopmode/DesktopTasksControllerTest.kt b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/desktopmode/DesktopTasksControllerTest.kt
index b577667d8279..bcdff11363ab 100644
--- a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/desktopmode/DesktopTasksControllerTest.kt
+++ b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/desktopmode/DesktopTasksControllerTest.kt
@@ -32,9 +32,9 @@ import android.app.WindowConfiguration.WINDOWING_MODE_UNDEFINED
import android.content.ComponentName
import android.content.Context
import android.content.Intent
-import android.content.Intent.FLAG_ACTIVITY_NEW_TASK
import android.content.pm.ActivityInfo
import android.content.pm.ActivityInfo.CONFIG_DENSITY
+import android.content.pm.ActivityInfo.LAUNCH_SINGLE_INSTANCE
import android.content.pm.ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE
import android.content.pm.ActivityInfo.SCREEN_ORIENTATION_PORTRAIT
import android.content.pm.ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED
@@ -265,7 +265,6 @@ class DesktopTasksControllerTest(flags: FlagsParameterization) : ShellTestCase()
@Mock private lateinit var desksOrganizer: DesksOrganizer
@Mock private lateinit var userProfileContexts: UserProfileContexts
@Mock private lateinit var desksTransitionsObserver: DesksTransitionObserver
- @Mock private lateinit var desktopPipTransitionObserver: DesktopPipTransitionObserver
@Mock private lateinit var packageManager: PackageManager
@Mock private lateinit var mockDisplayContext: Context
@Mock private lateinit var dragToDisplayTransitionHandler: DragToDisplayTransitionHandler
@@ -460,7 +459,6 @@ class DesktopTasksControllerTest(flags: FlagsParameterization) : ShellTestCase()
overviewToDesktopTransitionObserver,
desksOrganizer,
desksTransitionsObserver,
- Optional.of(desktopPipTransitionObserver),
userProfileContexts,
desktopModeCompatPolicy,
dragToDisplayTransitionHandler,
@@ -1200,9 +1198,11 @@ class DesktopTasksControllerTest(flags: FlagsParameterization) : ShellTestCase()
existingTask.topActivity = testComponent
existingTask.configuration.windowConfiguration.setBounds(Rect(0, 0, 500, 500))
// Set up new instance of already existing task.
- val launchingTask = setUpFullscreenTask()
+ val launchingTask =
+ setUpFullscreenTask().apply {
+ topActivityInfo = ActivityInfo().apply { launchMode = LAUNCH_SINGLE_INSTANCE }
+ }
launchingTask.topActivity = testComponent
- launchingTask.baseIntent.addFlags(FLAG_ACTIVITY_NEW_TASK)
// Move new instance to desktop. By default multi instance is not supported so first
// instance will close.
@@ -1224,10 +1224,12 @@ class DesktopTasksControllerTest(flags: FlagsParameterization) : ShellTestCase()
existingTask.topActivity = testComponent
existingTask.configuration.windowConfiguration.setBounds(Rect(0, 0, 500, 500))
// Set up new instance of already existing task.
- val launchingTask = setUpFreeformTask(active = false)
+ val launchingTask =
+ setUpFreeformTask(active = false).apply {
+ topActivityInfo = ActivityInfo().apply { launchMode = LAUNCH_SINGLE_INSTANCE }
+ }
taskRepository.removeTask(launchingTask.displayId, launchingTask.taskId)
launchingTask.topActivity = testComponent
- launchingTask.baseIntent.addFlags(FLAG_ACTIVITY_NEW_TASK)
// Move new instance to desktop. By default multi instance is not supported so first
// instance will close.
@@ -3536,15 +3538,20 @@ class DesktopTasksControllerTest(flags: FlagsParameterization) : ShellTestCase()
.addPendingTransition(DeskTransition.DeactivateDesk(token = transition, deskId = 0))
}
- @Test
- @EnableFlags(Flags.FLAG_ENABLE_DESKTOP_WINDOWING_PIP)
- fun onPipTaskMinimize_autoEnterEnabled_startPipTransition() {
- val task = setUpPipTask(autoEnterEnabled = true)
+ private fun minimizePipTask(task: RunningTaskInfo) {
val handler = mock(TransitionHandler::class.java)
whenever(transitions.dispatchRequest(any(), any(), anyOrNull()))
.thenReturn(android.util.Pair(handler, WindowContainerTransaction()))
controller.minimizeTask(task, MinimizeReason.MINIMIZE_BUTTON)
+ }
+
+ @Test
+ @EnableFlags(Flags.FLAG_ENABLE_DESKTOP_WINDOWING_PIP)
+ fun onPipTaskMinimize_autoEnterEnabled_startPipTransition() {
+ val task = setUpPipTask(autoEnterEnabled = true)
+
+ minimizePipTask(task)
verify(freeformTaskTransitionStarter).startPipTransition(any())
verify(freeformTaskTransitionStarter, never())
@@ -3564,7 +3571,7 @@ class DesktopTasksControllerTest(flags: FlagsParameterization) : ShellTestCase()
)
.thenReturn(Binder())
- controller.minimizeTask(task, MinimizeReason.MINIMIZE_BUTTON)
+ minimizePipTask(task)
verify(freeformTaskTransitionStarter)
.startMinimizedModeTransition(any(), eq(task.taskId), anyBoolean())
@@ -3575,52 +3582,24 @@ class DesktopTasksControllerTest(flags: FlagsParameterization) : ShellTestCase()
@EnableFlags(Flags.FLAG_ENABLE_DESKTOP_WINDOWING_PIP)
fun onPipTaskMinimize_autoEnterEnabled_sendsTaskbarRoundingUpdate() {
val task = setUpPipTask(autoEnterEnabled = true)
- val handler = mock(TransitionHandler::class.java)
- whenever(transitions.dispatchRequest(any(), any(), anyOrNull()))
- .thenReturn(android.util.Pair(handler, WindowContainerTransaction()))
- controller.minimizeTask(task, MinimizeReason.MINIMIZE_BUTTON)
+ minimizePipTask(task)
verify(taskbarDesktopTaskListener).onTaskbarCornerRoundingUpdate(anyBoolean())
}
@Test
@EnableFlags(
- Flags.FLAG_ENABLE_DESKTOP_WALLPAPER_ACTIVITY_FOR_SYSTEM_USER,
- Flags.FLAG_ENABLE_DESKTOP_WINDOWING_PIP,
- )
- fun onDesktopTaskEnteredPip_pipIsLastTask_removesWallpaper() {
- val task = setUpPipTask(autoEnterEnabled = true)
-
- controller.onDesktopTaskEnteredPip(
- taskId = task.taskId,
- deskId = DEFAULT_DISPLAY,
- displayId = task.displayId,
- taskIsLastVisibleTaskBeforePip = true,
- )
-
- // Wallpaper is moved to the back
- val wct = getLatestTransition()
- wct.assertReorder(wallpaperToken, /* toTop= */ false)
- }
-
- @Test
- @EnableFlags(
Flags.FLAG_ENABLE_DESKTOP_WINDOWING_PIP,
Flags.FLAG_ENABLE_MULTIPLE_DESKTOPS_BACKEND,
)
- fun onDesktopTaskEnteredPip_pipIsLastTask_deactivatesDesk() {
+ fun onPipTaskMinimize_isLastTask_deactivatesDesk() {
val deskId = DEFAULT_DISPLAY
val task = setUpPipTask(autoEnterEnabled = true, deskId = deskId)
val transition = Binder()
- whenever(transitions.startTransition(any(), any(), anyOrNull())).thenReturn(transition)
+ whenever(freeformTaskTransitionStarter.startPipTransition(any())).thenReturn(transition)
- controller.onDesktopTaskEnteredPip(
- taskId = task.taskId,
- deskId = deskId,
- displayId = task.displayId,
- taskIsLastVisibleTaskBeforePip = true,
- )
+ minimizePipTask(task)
verify(desksOrganizer).deactivateDesk(any(), eq(deskId))
verify(desksTransitionsObserver)
@@ -3628,44 +3607,31 @@ class DesktopTasksControllerTest(flags: FlagsParameterization) : ShellTestCase()
}
@Test
- @EnableFlags(Flags.FLAG_ENABLE_DESKTOP_WINDOWING_PIP)
- fun onDesktopTaskEnteredPip_pipIsLastTask_launchesHome() {
+ @EnableFlags(
+ Flags.FLAG_ENABLE_DESKTOP_WINDOWING_PIP,
+ Flags.FLAG_ENABLE_DESKTOP_WALLPAPER_ACTIVITY_FOR_SYSTEM_USER,
+ )
+ fun onPipTaskMinimize_isLastTask_removesWallpaper() {
val task = setUpPipTask(autoEnterEnabled = true)
- controller.onDesktopTaskEnteredPip(
- taskId = task.taskId,
- deskId = DEFAULT_DISPLAY,
- displayId = task.displayId,
- taskIsLastVisibleTaskBeforePip = true,
- )
+ minimizePipTask(task)
- val wct = getLatestTransition()
- wct.assertPendingIntent(launchHomeIntent(DEFAULT_DISPLAY))
+ val arg = argumentCaptor<WindowContainerTransaction>()
+ verify(freeformTaskTransitionStarter).startPipTransition(arg.capture())
+ // Wallpaper is moved to the back
+ arg.lastValue.assertReorder(wallpaperToken, /* toTop= */ false)
}
@Test
@EnableFlags(Flags.FLAG_ENABLE_DESKTOP_WINDOWING_PIP)
- fun onDesktopTaskEnteredPip_pipIsNotLastTask_doesntExitDesktopMode() {
+ fun onPipTaskMinimize_isLastTask_launchesHome() {
val task = setUpPipTask(autoEnterEnabled = true)
- val deskId = DEFAULT_DISPLAY
- setUpFreeformTask(deskId = deskId) // launch another freeform task
- val transition = Binder()
- whenever(transitions.startTransition(any(), any(), anyOrNull())).thenReturn(transition)
- controller.onDesktopTaskEnteredPip(
- taskId = task.taskId,
- deskId = deskId,
- displayId = task.displayId,
- taskIsLastVisibleTaskBeforePip = false,
- )
+ minimizePipTask(task)
- // No transition to exit Desktop mode is started
- verifyWCTNotExecuted()
- verify(desktopModeEnterExitTransitionListener, never())
- .onExitDesktopModeTransitionStarted(FULLSCREEN_ANIMATION_DURATION)
- verify(desksOrganizer, never()).deactivateDesk(any(), eq(deskId))
- verify(desksTransitionsObserver, never())
- .addPendingTransition(DeskTransition.DeactivateDesk(transition, deskId))
+ val arg = argumentCaptor<WindowContainerTransaction>()
+ verify(freeformTaskTransitionStarter).startPipTransition(arg.capture())
+ arg.lastValue.assertPendingIntent(launchHomeIntent(DEFAULT_DISPLAY))
}
@Test
@@ -4283,6 +4249,25 @@ class DesktopTasksControllerTest(flags: FlagsParameterization) : ShellTestCase()
}
@Test
+ @EnableFlags(
+ Flags.FLAG_ENABLE_DESKTOP_WINDOWING_WALLPAPER_ACTIVITY,
+ Flags.FLAG_ENABLE_MULTIPLE_DESKTOPS_BACKEND,
+ )
+ fun handleRequest_fullscreenTask_noInDesk_enforceDesktop_secondaryDisplay_movesToDesk() {
+ val deskId = 5
+ taskRepository.addDesk(displayId = SECONDARY_DISPLAY_ID, deskId = deskId)
+ taskRepository.setDeskInactive(deskId)
+ whenever(desktopWallpaperActivityTokenProvider.getToken()).thenReturn(null)
+ whenever(DesktopModeStatus.enterDesktopByDefaultOnFreeformDisplay(context)).thenReturn(true)
+
+ val fullscreenTask = createFullscreenTask(displayId = SECONDARY_DISPLAY_ID)
+ val wct = controller.handleRequest(Binder(), createTransition(fullscreenTask))
+
+ assertNotNull(wct, "should handle request")
+ verify(desksOrganizer).moveTaskToDesk(wct, deskId, fullscreenTask)
+ }
+
+ @Test
fun handleRequest_fullscreenTask_notInDesk_enforceDesktop_fullscreenDisplay_returnNull() {
taskRepository.setDeskInactive(deskId = 0)
whenever(DesktopModeStatus.enterDesktopByDefaultOnFreeformDisplay(context)).thenReturn(true)
@@ -5639,6 +5624,33 @@ class DesktopTasksControllerTest(flags: FlagsParameterization) : ShellTestCase()
}
@Test
+ @EnableFlags(Flags.FLAG_ENABLE_MULTIPLE_DESKTOPS_BACKEND)
+ fun activateDesk_otherDeskWasActive_deactivatesOtherDesk() {
+ val previouslyActiveDeskId = 1
+ val activatingDeskId = 0
+ val transition = Binder()
+ val deskChange = mock(TransitionInfo.Change::class.java)
+ whenever(transitions.startTransition(eq(TRANSIT_TO_FRONT), any(), anyOrNull()))
+ .thenReturn(transition)
+ whenever(desksOrganizer.isDeskActiveAtEnd(deskChange, activatingDeskId)).thenReturn(true)
+ // Make desk inactive by activating another desk.
+ taskRepository.addDesk(DEFAULT_DISPLAY, deskId = previouslyActiveDeskId)
+ taskRepository.setActiveDesk(DEFAULT_DISPLAY, deskId = previouslyActiveDeskId)
+
+ controller.activateDesk(activatingDeskId, RemoteTransition(TestRemoteTransition()))
+
+ verify(desksOrganizer).deactivateDesk(any(), eq(previouslyActiveDeskId))
+ verify(desksTransitionsObserver)
+ .addPendingTransition(
+ argThat {
+ this is DeskTransition.DeactivateDesk &&
+ this.token == transition &&
+ this.deskId == previouslyActiveDeskId
+ }
+ )
+ }
+
+ @Test
@EnableFlags(
Flags.FLAG_ENABLE_DESKTOP_WINDOWING_BACK_NAVIGATION,
Flags.FLAG_ENABLE_MULTIPLE_DESKTOPS_BACKEND,
diff --git a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/desktopmode/DesktopTasksTransitionObserverTest.kt b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/desktopmode/DesktopTasksTransitionObserverTest.kt
index 5ef1ace7873d..1e0c94c2452c 100644
--- a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/desktopmode/DesktopTasksTransitionObserverTest.kt
+++ b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/desktopmode/DesktopTasksTransitionObserverTest.kt
@@ -50,7 +50,6 @@ import com.android.wm.shell.sysui.ShellInit
import com.android.wm.shell.transition.Transitions
import com.google.common.truth.Truth.assertThat
import com.google.common.truth.Truth.assertWithMessage
-import java.util.Optional
import org.junit.Before
import org.junit.Rule
import org.junit.Test
@@ -86,7 +85,6 @@ class DesktopTasksTransitionObserverTest {
private val userRepositories = mock<DesktopUserRepositories>()
private val taskRepository = mock<DesktopRepository>()
private val mixedHandler = mock<DesktopMixedTransitionHandler>()
- private val pipTransitionObserver = mock<DesktopPipTransitionObserver>()
private val backAnimationController = mock<BackAnimationController>()
private val desktopWallpaperActivityTokenProvider =
mock<DesktopWallpaperActivityTokenProvider>()
@@ -111,7 +109,6 @@ class DesktopTasksTransitionObserverTest {
transitions,
shellTaskOrganizer,
mixedHandler,
- Optional.of(pipTransitionObserver),
backAnimationController,
desktopWallpaperActivityTokenProvider,
shellInit,
diff --git a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/desktopmode/multidesks/RootTaskDesksOrganizerTest.kt b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/desktopmode/multidesks/RootTaskDesksOrganizerTest.kt
index 9af504797182..e57fc38e3607 100644
--- a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/desktopmode/multidesks/RootTaskDesksOrganizerTest.kt
+++ b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/desktopmode/multidesks/RootTaskDesksOrganizerTest.kt
@@ -15,6 +15,7 @@
*/
package com.android.wm.shell.desktopmode.multidesks
+import android.app.ActivityManager
import android.app.WindowConfiguration.WINDOWING_MODE_FREEFORM
import android.app.WindowConfiguration.WINDOWING_MODE_UNDEFINED
import android.testing.AndroidTestingRunner
@@ -48,7 +49,9 @@ import org.junit.Before
import org.junit.Test
import org.junit.runner.RunWith
import org.mockito.Mockito
+import org.mockito.Mockito.never
import org.mockito.Mockito.verify
+import org.mockito.kotlin.any
import org.mockito.kotlin.argThat
import org.mockito.kotlin.mock
import org.mockito.kotlin.whenever
@@ -67,6 +70,7 @@ class RootTaskDesksOrganizerTest : ShellTestCase() {
private val mockShellCommandHandler = mock<ShellCommandHandler>()
private val mockShellTaskOrganizer = mock<ShellTaskOrganizer>()
private val launchAdjacentController = LaunchAdjacentController(mock())
+ private val taskInfoChangedListener = mock<(ActivityManager.RunningTaskInfo) -> Unit>()
private lateinit var organizer: RootTaskDesksOrganizer
@@ -79,6 +83,7 @@ class RootTaskDesksOrganizerTest : ShellTestCase() {
mockShellTaskOrganizer,
launchAdjacentController,
)
+ organizer.setOnDesktopTaskInfoChangedListener(taskInfoChangedListener)
}
@Test fun testCreateDesk_createsDeskAndMinimizationRoots() = runTest { createDesk() }
@@ -652,6 +657,34 @@ class RootTaskDesksOrganizerTest : ShellTestCase() {
assertThat(launchAdjacentController.launchAdjacentEnabled).isFalse()
}
+ @Test
+ fun onTaskInfoChanged_taskNotRoot_invokesListener() = runTest {
+ createDesk()
+ val task = createFreeformTask().apply { taskId = TEST_CHILD_TASK_ID }
+
+ organizer.onTaskInfoChanged(task)
+
+ verify(taskInfoChangedListener).invoke(task)
+ }
+
+ @Test
+ fun onTaskInfoChanged_isDeskRoot_doesNotInvokeListener() = runTest {
+ val deskRoot = createDesk().deskRoot
+
+ organizer.onTaskInfoChanged(deskRoot.taskInfo)
+
+ verify(taskInfoChangedListener, never()).invoke(any())
+ }
+
+ @Test
+ fun onTaskInfoChanged_isMinimizationRoot_doesNotInvokeListener() = runTest {
+ val minimizationRoot = createDesk().minimizationRoot
+
+ organizer.onTaskInfoChanged(minimizationRoot.taskInfo)
+
+ verify(taskInfoChangedListener, never()).invoke(any())
+ }
+
private data class DeskRoots(
val deskRoot: DeskRoot,
val minimizationRoot: DeskMinimizationRoot,
@@ -712,4 +745,8 @@ class RootTaskDesksOrganizerTest : ShellTestCase() {
hop.newParent == desk.deskRoot.token.asBinder() &&
hop.toTop
}
+
+ companion object {
+ private const val TEST_CHILD_TASK_ID = 100
+ }
}
diff --git a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/splitscreen/StageCoordinatorTests.java b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/splitscreen/StageCoordinatorTests.java
index 077b35583e04..64bd86134d92 100644
--- a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/splitscreen/StageCoordinatorTests.java
+++ b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/splitscreen/StageCoordinatorTests.java
@@ -167,6 +167,7 @@ public class StageCoordinatorTests extends ShellTestCase {
private final TestShellExecutor mMainExecutor = new TestShellExecutor();
private final ShellExecutor mAnimExecutor = new TestShellExecutor();
private final Handler mMainHandler = new Handler(Looper.getMainLooper());
+ private final Handler mAnimHandler = mock(Handler.class);
private final DisplayAreaInfo mDisplayAreaInfo = new DisplayAreaInfo(new MockToken().token(),
DEFAULT_DISPLAY, 0);
private final ActivityManager.RunningTaskInfo mMainChildTaskInfo =
@@ -571,8 +572,7 @@ public class StageCoordinatorTests extends ShellTestCase {
}
@Test
- @DisableFlags({Flags.FLAG_ENABLE_MULTIPLE_DESKTOPS_BACKEND,
- Flags.FLAG_ENABLE_INPUT_LAYER_TRANSITION_FIX})
+ @DisableFlags(Flags.FLAG_ENABLE_MULTIPLE_DESKTOPS_BACKEND)
public void testRequestEnterSplit_didNotEnterSplitSelect_doesNotApplyTransaction() {
final WindowContainerTransaction wct = new WindowContainerTransaction();
mStageCoordinator.registerSplitSelectListener(
@@ -629,9 +629,9 @@ public class StageCoordinatorTests extends ShellTestCase {
private Transitions createTestTransitions() {
ShellInit shellInit = new ShellInit(mMainExecutor);
final Transitions t = new Transitions(mContext, shellInit, mock(ShellController.class),
- mTaskOrganizer, mTransactionPool, mock(DisplayController.class), mMainExecutor,
- mMainHandler, mAnimExecutor, mock(HomeTransitionObserver.class),
- mock(FocusTransitionObserver.class));
+ mTaskOrganizer, mTransactionPool, mock(DisplayController.class),
+ mDisplayInsetsController, mMainExecutor, mMainHandler, mAnimExecutor, mAnimHandler,
+ mock(HomeTransitionObserver.class), mock(FocusTransitionObserver.class));
shellInit.init();
return t;
}
diff --git a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/taskview/TaskViewTransitionsTest.java b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/taskview/TaskViewTransitionsTest.java
index 3a455ba6b5df..f11839ad4e72 100644
--- a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/taskview/TaskViewTransitionsTest.java
+++ b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/taskview/TaskViewTransitionsTest.java
@@ -24,8 +24,12 @@ import static android.view.WindowManager.TRANSIT_TO_FRONT;
import static com.google.common.truth.Truth.assertThat;
import static org.junit.Assume.assumeTrue;
+import static org.mockito.ArgumentMatchers.any;
+import static org.mockito.ArgumentMatchers.anyFloat;
+import static org.mockito.ArgumentMatchers.anyInt;
import static org.mockito.Mockito.doReturn;
import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.never;
import static org.mockito.Mockito.spy;
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.when;
@@ -77,16 +81,15 @@ public class TaskViewTransitionsTest extends ShellTestCase {
@Mock
TaskViewTaskController mTaskViewTaskController;
@Mock
- ActivityManager.RunningTaskInfo mTaskInfo;
- @Mock
WindowContainerToken mToken;
@Mock
ShellTaskOrganizer mOrganizer;
@Mock
SyncTransactionQueue mSyncQueue;
- Executor mExecutor = command -> command.run();
+ Executor mExecutor = Runnable::run;
+ ActivityManager.RunningTaskInfo mTaskInfo;
TaskViewRepository mTaskViewRepository;
TaskViewTransitions mTaskViewTransitions;
@@ -305,4 +308,66 @@ public class TaskViewTransitionsTest extends ShellTestCase {
verify(mTaskViewTaskController).setTaskNotFound();
}
+
+ @Test
+ public void updateBoundsForUnfold_taskNotFound_doesNothing() {
+ assumeTrue(Transitions.ENABLE_SHELL_TRANSITIONS);
+
+ ActivityManager.RunningTaskInfo taskInfo = new ActivityManager.RunningTaskInfo();
+ taskInfo.token = mock(WindowContainerToken.class);
+ taskInfo.taskId = 666;
+ Rect bounds = new Rect(100, 50, 200, 250);
+ SurfaceControl.Transaction startTransaction = mock(SurfaceControl.Transaction.class);
+ SurfaceControl.Transaction finishTransaction = mock(SurfaceControl.Transaction.class);
+ assertThat(
+ mTaskViewTransitions.updateBoundsForUnfold(bounds, startTransaction,
+ finishTransaction, taskInfo, mock(SurfaceControl.class)))
+ .isFalse();
+
+ verify(startTransaction, never()).reparent(any(), any());
+ }
+
+ @Test
+ public void updateBoundsForUnfold_noPendingTransition_doesNothing() {
+ assumeTrue(Transitions.ENABLE_SHELL_TRANSITIONS);
+
+ Rect bounds = new Rect(100, 50, 200, 250);
+ mTaskViewTransitions.setTaskBounds(mTaskViewTaskController, bounds);
+ assertThat(mTaskViewTransitions.hasPending()).isFalse();
+
+ SurfaceControl.Transaction startTransaction = mock(SurfaceControl.Transaction.class);
+ SurfaceControl.Transaction finishTransaction = mock(SurfaceControl.Transaction.class);
+ assertThat(
+ mTaskViewTransitions.updateBoundsForUnfold(bounds, startTransaction,
+ finishTransaction, mTaskInfo, mock(SurfaceControl.class)))
+ .isFalse();
+ verify(startTransaction, never()).reparent(any(), any());
+ }
+
+ @Test
+ public void updateBoundsForUnfold() {
+ assumeTrue(Transitions.ENABLE_SHELL_TRANSITIONS);
+
+ Rect bounds = new Rect(100, 50, 200, 250);
+ mTaskViewTransitions.updateVisibilityState(mTaskViewTaskController, /* visible= */ true);
+ mTaskViewTransitions.setTaskBounds(mTaskViewTaskController, bounds);
+ assertThat(mTaskViewTransitions.hasPending()).isTrue();
+
+ SurfaceControl.Transaction startTransaction = createMockTransaction();
+ SurfaceControl.Transaction finishTransaction = createMockTransaction();
+ assertThat(
+ mTaskViewTransitions.updateBoundsForUnfold(bounds, startTransaction,
+ finishTransaction, mTaskInfo, mock(SurfaceControl.class)))
+ .isTrue();
+ assertThat(mTaskViewRepository.byTaskView(mTaskViewTaskController).mBounds)
+ .isEqualTo(bounds);
+ }
+
+ private SurfaceControl.Transaction createMockTransaction() {
+ SurfaceControl.Transaction transaction = mock(SurfaceControl.Transaction.class);
+ when(transaction.reparent(any(), any())).thenReturn(transaction);
+ when(transaction.setPosition(any(), anyFloat(), anyFloat())).thenReturn(transaction);
+ when(transaction.setWindowCrop(any(), anyInt(), anyInt())).thenReturn(transaction);
+ return transaction;
+ }
}
diff --git a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/transition/DefaultTransitionHandlerTest.java b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/transition/DefaultTransitionHandlerTest.java
index 18fdbeff40f4..2dab39184247 100644
--- a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/transition/DefaultTransitionHandlerTest.java
+++ b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/transition/DefaultTransitionHandlerTest.java
@@ -53,6 +53,7 @@ import com.android.wm.shell.RootTaskDisplayAreaOrganizer;
import com.android.wm.shell.ShellTestCase;
import com.android.wm.shell.TestShellExecutor;
import com.android.wm.shell.common.DisplayController;
+import com.android.wm.shell.common.DisplayInsetsController;
import com.android.wm.shell.shared.TransactionPool;
import com.android.wm.shell.sysui.ShellInit;
@@ -78,6 +79,8 @@ public class DefaultTransitionHandlerTest extends ShellTestCase {
InstrumentationRegistry.getInstrumentation().getTargetContext();
private final DisplayController mDisplayController = mock(DisplayController.class);
+ private final DisplayInsetsController mDisplayInsetsController =
+ mock(DisplayInsetsController.class);
private final TransactionPool mTransactionPool = new MockTransactionPool();
private final TestShellExecutor mMainExecutor = new TestShellExecutor();
private final TestShellExecutor mAnimExecutor = new TestShellExecutor();
@@ -95,9 +98,10 @@ public class DefaultTransitionHandlerTest extends ShellTestCase {
mContext,
mShellInit);
mTransitionHandler = new DefaultTransitionHandler(
- mContext, mShellInit, mDisplayController,
+ mContext, mShellInit, mDisplayController, mDisplayInsetsController,
mTransactionPool, mMainExecutor, mMainHandler, mAnimExecutor,
- mRootTaskDisplayAreaOrganizer, mock(InteractionJankMonitor.class));
+ mock(Handler.class), mRootTaskDisplayAreaOrganizer,
+ mock(InteractionJankMonitor.class));
mShellInit.init();
}
diff --git a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/transition/HomeTransitionObserverTest.java b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/transition/HomeTransitionObserverTest.java
index 55bff09e0ae2..5d77766dc0db 100644
--- a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/transition/HomeTransitionObserverTest.java
+++ b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/transition/HomeTransitionObserverTest.java
@@ -61,6 +61,7 @@ import com.android.wm.shell.ShellTaskOrganizer;
import com.android.wm.shell.ShellTestCase;
import com.android.wm.shell.TestShellExecutor;
import com.android.wm.shell.common.DisplayController;
+import com.android.wm.shell.common.DisplayInsetsController;
import com.android.wm.shell.common.ShellExecutor;
import com.android.wm.shell.shared.IHomeTransitionListener;
import com.android.wm.shell.shared.TransactionPool;
@@ -87,7 +88,10 @@ public class HomeTransitionObserverTest extends ShellTestCase {
private final ShellExecutor mAnimExecutor = new TestShellExecutor();
private final TestShellExecutor mMainExecutor = new TestShellExecutor();
private final Handler mMainHandler = new Handler(Looper.getMainLooper());
+ private final Handler mAnimHandler = mock(Handler.class);
private final DisplayController mDisplayController = mock(DisplayController.class);
+ private final DisplayInsetsController mDisplayInsetsController =
+ mock(DisplayInsetsController.class);
private IHomeTransitionListener mListener;
private Transitions mTransition;
@@ -98,10 +102,11 @@ public class HomeTransitionObserverTest extends ShellTestCase {
mListener = mock(IHomeTransitionListener.class);
when(mListener.asBinder()).thenReturn(mock(IBinder.class));
- mHomeTransitionObserver = new HomeTransitionObserver(mContext, mMainExecutor);
+ mHomeTransitionObserver = new HomeTransitionObserver(mContext, mMainExecutor,
+ mDisplayInsetsController, mock(ShellInit.class));
mTransition = new Transitions(mContext, mock(ShellInit.class), mock(ShellController.class),
- mOrganizer, mTransactionPool, mDisplayController, mMainExecutor,
- mMainHandler, mAnimExecutor, mHomeTransitionObserver,
+ mOrganizer, mTransactionPool, mDisplayController, mDisplayInsetsController,
+ mMainExecutor, mMainHandler, mAnimExecutor, mAnimHandler, mHomeTransitionObserver,
mock(FocusTransitionObserver.class));
mHomeTransitionObserver.setHomeTransitionListener(mTransition, mListener);
}
diff --git a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/transition/ShellTransitionTests.java b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/transition/ShellTransitionTests.java
index 9849b1174d8e..4dd9cab1d340 100644
--- a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/transition/ShellTransitionTests.java
+++ b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/transition/ShellTransitionTests.java
@@ -107,6 +107,7 @@ import com.android.wm.shell.ShellTaskOrganizer;
import com.android.wm.shell.ShellTestCase;
import com.android.wm.shell.TestShellExecutor;
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.ShellExecutor;
import com.android.wm.shell.recents.IRecentsAnimationRunner;
@@ -145,6 +146,9 @@ public class ShellTransitionTests extends ShellTestCase {
private final ShellExecutor mAnimExecutor = new TestShellExecutor();
private final TestTransitionHandler mDefaultHandler = new TestTransitionHandler();
private final Handler mMainHandler = new Handler(Looper.getMainLooper());
+ private final Handler mAnimHandler = mock(Handler.class);
+ private final DisplayInsetsController mDisplayInsets =
+ mock(DisplayInsetsController.class);
@Before
public void setUp() {
@@ -156,9 +160,9 @@ public class ShellTransitionTests extends ShellTestCase {
public void instantiate_addInitCallback() {
ShellInit shellInit = mock(ShellInit.class);
final Transitions t = new Transitions(mContext, shellInit, mock(ShellController.class),
- mOrganizer, mTransactionPool, createTestDisplayController(), mMainExecutor,
- mMainHandler, mAnimExecutor, mock(HomeTransitionObserver.class),
- mock(FocusTransitionObserver.class));
+ mOrganizer, mTransactionPool, createTestDisplayController(), mDisplayInsets,
+ mMainExecutor, mMainHandler, mAnimExecutor, mAnimHandler,
+ mock(HomeTransitionObserver.class), mock(FocusTransitionObserver.class));
// One from Transitions, one from RootTaskDisplayAreaOrganizer
verify(shellInit).addInitCallback(any(), eq(t));
verify(shellInit).addInitCallback(any(), isA(RootTaskDisplayAreaOrganizer.class));
@@ -169,9 +173,9 @@ public class ShellTransitionTests extends ShellTestCase {
ShellInit shellInit = new ShellInit(mMainExecutor);
ShellController shellController = mock(ShellController.class);
final Transitions t = new Transitions(mContext, shellInit, shellController,
- mOrganizer, mTransactionPool, createTestDisplayController(), mMainExecutor,
- mMainHandler, mAnimExecutor, mock(HomeTransitionObserver.class),
- mock(FocusTransitionObserver.class));
+ mOrganizer, mTransactionPool, createTestDisplayController(), mDisplayInsets,
+ mMainExecutor, mMainHandler, mAnimExecutor, mAnimHandler,
+ mock(HomeTransitionObserver.class), mock(FocusTransitionObserver.class));
shellInit.init();
verify(shellController, times(1)).addExternalInterface(
eq(IShellTransitions.DESCRIPTOR), any(), any());
@@ -1314,8 +1318,9 @@ public class ShellTransitionTests extends ShellTestCase {
ShellInit shellInit = new ShellInit(mMainExecutor);
final Transitions transitions =
new Transitions(mContext, shellInit, mock(ShellController.class), mOrganizer,
- mTransactionPool, createTestDisplayController(), mMainExecutor,
- mMainHandler, mAnimExecutor, mock(HomeTransitionObserver.class),
+ mTransactionPool, createTestDisplayController(), mDisplayInsets,
+ mMainExecutor, mMainHandler, mAnimExecutor, mAnimHandler,
+ mock(HomeTransitionObserver.class),
mock(FocusTransitionObserver.class));
final RecentTasksController mockRecentsTaskController = mock(RecentTasksController.class);
doReturn(mContext).when(mockRecentsTaskController).getContext();
@@ -1909,8 +1914,9 @@ public class ShellTransitionTests extends ShellTestCase {
private Transitions createTestTransitions() {
ShellInit shellInit = new ShellInit(mMainExecutor);
final Transitions t = new Transitions(mContext, shellInit, mock(ShellController.class),
- mOrganizer, mTransactionPool, createTestDisplayController(), mMainExecutor,
- mMainHandler, mAnimExecutor, mock(HomeTransitionObserver.class),
+ mOrganizer, mTransactionPool, createTestDisplayController(), mDisplayInsets,
+ mMainExecutor, mMainHandler, mAnimExecutor, mAnimHandler,
+ mock(HomeTransitionObserver.class),
mock(FocusTransitionObserver.class));
shellInit.init();
return t;
diff --git a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/unfold/UnfoldTransitionHandlerTest.java b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/unfold/UnfoldTransitionHandlerTest.java
index aad18cba4436..e28d0acb579f 100644
--- a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/unfold/UnfoldTransitionHandlerTest.java
+++ b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/unfold/UnfoldTransitionHandlerTest.java
@@ -60,6 +60,7 @@ import org.mockito.InOrder;
import java.util.ArrayList;
import java.util.List;
+import java.util.Optional;
import java.util.concurrent.Executor;
public class UnfoldTransitionHandlerTest extends ShellTestCase {
@@ -98,7 +99,8 @@ public class UnfoldTransitionHandlerTest extends ShellTestCase {
mTransactionPool,
executor,
mHandler,
- mTransitions
+ mTransitions,
+ /* bubbleTaskUnfoldTransitionMerger= */ Optional.empty()
);
shellInit.init();
diff --git a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/windowdecor/DesktopModeWindowDecorViewModelAppHandleOnlyTest.kt b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/windowdecor/DesktopModeWindowDecorViewModelAppHandleOnlyTest.kt
index b1f92411c5a3..067dcec5d65d 100644
--- a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/windowdecor/DesktopModeWindowDecorViewModelAppHandleOnlyTest.kt
+++ b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/windowdecor/DesktopModeWindowDecorViewModelAppHandleOnlyTest.kt
@@ -28,7 +28,6 @@ import android.testing.TestableLooper.RunWithLooper
import android.view.Display
import android.view.Display.DEFAULT_DISPLAY
import android.view.SurfaceControl
-import android.view.WindowManager.TRANSIT_CHANGE
import androidx.test.filters.SmallTest
import com.android.dx.mockito.inline.extended.ExtendedMockito.anyBoolean
import com.android.dx.mockito.inline.extended.ExtendedMockito.doReturn
@@ -110,7 +109,7 @@ class DesktopModeWindowDecorViewModelAppHandleOnlyTest :
onTaskOpening(task, taskSurface)
assertTrue(windowDecorByTaskIdSpy.contains(task.taskId))
task.setActivityType(ACTIVITY_TYPE_UNDEFINED)
- onTaskChanging(task, taskSurface, TRANSIT_CHANGE)
+ onTaskChanging(task, taskSurface)
assertFalse(windowDecorByTaskIdSpy.contains(task.taskId))
verify(decoration).close()
@@ -166,7 +165,7 @@ class DesktopModeWindowDecorViewModelAppHandleOnlyTest :
setLargeScreen(false)
setUpMockDecorationForTask(task)
- onTaskChanging(task, taskSurface, TRANSIT_CHANGE)
+ onTaskChanging(task, taskSurface)
assertFalse(windowDecorByTaskIdSpy.contains(task.taskId))
}
diff --git a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/windowdecor/DesktopModeWindowDecorViewModelTests.kt b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/windowdecor/DesktopModeWindowDecorViewModelTests.kt
index ad3426e82805..40aa41b2b72a 100644
--- a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/windowdecor/DesktopModeWindowDecorViewModelTests.kt
+++ b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/windowdecor/DesktopModeWindowDecorViewModelTests.kt
@@ -51,7 +51,6 @@ import android.view.SurfaceView
import android.view.View
import android.view.ViewRootImpl
import android.view.WindowInsets.Type.statusBars
-import android.view.WindowManager.TRANSIT_CHANGE
import android.window.WindowContainerTransaction
import android.window.WindowContainerTransaction.HierarchyOp
import androidx.test.filters.SmallTest
@@ -135,7 +134,7 @@ class DesktopModeWindowDecorViewModelTests : DesktopModeWindowDecorViewModelTest
task.setWindowingMode(WINDOWING_MODE_UNDEFINED)
task.setActivityType(ACTIVITY_TYPE_UNDEFINED)
- onTaskChanging(task, taskSurface, TRANSIT_CHANGE)
+ onTaskChanging(task, taskSurface)
assertFalse(windowDecorByTaskIdSpy.contains(task.taskId))
verify(decoration).close()
@@ -150,12 +149,12 @@ class DesktopModeWindowDecorViewModelTests : DesktopModeWindowDecorViewModelTest
val taskSurface = SurfaceControl()
setUpMockDecorationForTask(task)
- onTaskChanging(task, taskSurface, TRANSIT_CHANGE)
+ onTaskChanging(task, taskSurface)
assertFalse(windowDecorByTaskIdSpy.contains(task.taskId))
task.setWindowingMode(WINDOWING_MODE_FREEFORM)
task.setActivityType(ACTIVITY_TYPE_STANDARD)
- onTaskChanging(task, taskSurface, TRANSIT_CHANGE)
+ onTaskChanging(task, taskSurface)
assertTrue(windowDecorByTaskIdSpy.contains(task.taskId))
}
diff --git a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/windowdecor/DesktopModeWindowDecorViewModelTestsBase.kt b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/windowdecor/DesktopModeWindowDecorViewModelTestsBase.kt
index 2126d1d9b986..23994a2bd547 100644
--- a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/windowdecor/DesktopModeWindowDecorViewModelTestsBase.kt
+++ b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/windowdecor/DesktopModeWindowDecorViewModelTestsBase.kt
@@ -67,6 +67,7 @@ import com.android.wm.shell.desktopmode.DesktopUserRepositories
import com.android.wm.shell.desktopmode.WindowDecorCaptionHandleRepository
import com.android.wm.shell.desktopmode.education.AppHandleEducationController
import com.android.wm.shell.desktopmode.education.AppToWebEducationController
+import com.android.wm.shell.desktopmode.multidesks.DesksOrganizer
import com.android.wm.shell.freeform.FreeformTaskTransitionStarter
import com.android.wm.shell.recents.RecentsTransitionHandler
import com.android.wm.shell.recents.RecentsTransitionStateListener
@@ -146,6 +147,7 @@ open class DesktopModeWindowDecorViewModelTestsBase : ShellTestCase() {
protected val mockMultiDisplayDragMoveIndicatorController =
mock<MultiDisplayDragMoveIndicatorController>()
protected val mockCompatUIHandler = mock<CompatUIHandler>()
+ protected val mockDesksOrganizer = mock<DesksOrganizer>()
protected val mockInputManager = mock<InputManager>()
private val mockTaskPositionerFactory =
mock<DesktopModeWindowDecorViewModel.TaskPositionerFactory>()
@@ -246,6 +248,7 @@ open class DesktopModeWindowDecorViewModelTestsBase : ShellTestCase() {
mockTilingWindowDecoration,
mockMultiDisplayDragMoveIndicatorController,
mockCompatUIHandler,
+ mockDesksOrganizer
)
desktopModeWindowDecorViewModel.setSplitScreenController(mockSplitScreenController)
whenever(mockDisplayController.getDisplayLayout(any())).thenReturn(mockDisplayLayout)
@@ -362,14 +365,12 @@ open class DesktopModeWindowDecorViewModelTestsBase : ShellTestCase() {
protected fun onTaskChanging(
task: RunningTaskInfo,
leash: SurfaceControl = SurfaceControl(),
- changeMode: Int
) {
desktopModeWindowDecorViewModel.onTaskChanging(
task,
leash,
StubTransaction(),
StubTransaction(),
- changeMode
)
}
diff --git a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/windowdecor/DesktopModeWindowDecorationTests.java b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/windowdecor/DesktopModeWindowDecorationTests.java
index 0908f56e1cfb..a0171ea04da3 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
@@ -174,8 +174,6 @@ public class DesktopModeWindowDecorationTests extends ShellTestCase {
private static final boolean DEFAULT_HAS_GLOBAL_FOCUS = true;
private static final boolean DEFAULT_SHOULD_IGNORE_CORNER_RADIUS = false;
private static final boolean DEFAULT_SHOULD_EXCLUDE_CAPTION_FROM_APP_BOUNDS = false;
- private static final boolean DEFAULT_IS_RECENTS_TRANSITION_RUNNING = false;
- private static final boolean DEFAULT_IS_MOVING_TO_BACK = false;
@Mock
@@ -443,9 +441,7 @@ public class DesktopModeWindowDecorationTests extends ShellTestCase {
DEFAULT_HAS_GLOBAL_FOCUS,
mExclusionRegion,
/* shouldIgnoreCornerRadius= */ true,
- DEFAULT_SHOULD_EXCLUDE_CAPTION_FROM_APP_BOUNDS,
- DEFAULT_IS_RECENTS_TRANSITION_RUNNING,
- DEFAULT_IS_MOVING_TO_BACK);
+ DEFAULT_SHOULD_EXCLUDE_CAPTION_FROM_APP_BOUNDS);
assertThat(relayoutParams.mCornerRadius).isEqualTo(INVALID_CORNER_RADIUS);
}
@@ -544,9 +540,7 @@ public class DesktopModeWindowDecorationTests extends ShellTestCase {
DEFAULT_HAS_GLOBAL_FOCUS,
mExclusionRegion,
/* shouldIgnoreCornerRadius= */ true,
- DEFAULT_SHOULD_EXCLUDE_CAPTION_FROM_APP_BOUNDS,
- DEFAULT_IS_RECENTS_TRANSITION_RUNNING,
- DEFAULT_IS_MOVING_TO_BACK);
+ DEFAULT_SHOULD_EXCLUDE_CAPTION_FROM_APP_BOUNDS);
assertThat(relayoutParams.mCornerRadiusId).isEqualTo(Resources.ID_NULL);
}
@@ -748,9 +742,7 @@ public class DesktopModeWindowDecorationTests extends ShellTestCase {
DEFAULT_HAS_GLOBAL_FOCUS,
mExclusionRegion,
DEFAULT_SHOULD_IGNORE_CORNER_RADIUS,
- /* shouldExcludeCaptionFromAppBounds */ true,
- DEFAULT_IS_RECENTS_TRANSITION_RUNNING,
- DEFAULT_IS_MOVING_TO_BACK);
+ /* shouldExcludeCaptionFromAppBounds */ true);
// Force consuming flags are disabled.
assertThat((relayoutParams.mInsetSourceFlags & FLAG_FORCE_CONSUMING) == 0).isTrue();
@@ -785,9 +777,7 @@ public class DesktopModeWindowDecorationTests extends ShellTestCase {
DEFAULT_HAS_GLOBAL_FOCUS,
mExclusionRegion,
DEFAULT_SHOULD_IGNORE_CORNER_RADIUS,
- DEFAULT_SHOULD_EXCLUDE_CAPTION_FROM_APP_BOUNDS,
- DEFAULT_IS_RECENTS_TRANSITION_RUNNING,
- DEFAULT_IS_MOVING_TO_BACK);
+ DEFAULT_SHOULD_EXCLUDE_CAPTION_FROM_APP_BOUNDS);
assertThat((relayoutParams.mInsetSourceFlags & FLAG_FORCE_CONSUMING) != 0).isTrue();
assertThat(
@@ -866,9 +856,7 @@ public class DesktopModeWindowDecorationTests extends ShellTestCase {
DEFAULT_HAS_GLOBAL_FOCUS,
mExclusionRegion,
DEFAULT_SHOULD_IGNORE_CORNER_RADIUS,
- DEFAULT_SHOULD_EXCLUDE_CAPTION_FROM_APP_BOUNDS,
- DEFAULT_IS_RECENTS_TRANSITION_RUNNING,
- DEFAULT_IS_MOVING_TO_BACK);
+ DEFAULT_SHOULD_EXCLUDE_CAPTION_FROM_APP_BOUNDS);
// Takes status bar inset as padding, ignores caption bar inset.
assertThat(relayoutParams.mCaptionTopPadding).isEqualTo(50);
@@ -896,9 +884,7 @@ public class DesktopModeWindowDecorationTests extends ShellTestCase {
DEFAULT_HAS_GLOBAL_FOCUS,
mExclusionRegion,
DEFAULT_SHOULD_IGNORE_CORNER_RADIUS,
- DEFAULT_SHOULD_EXCLUDE_CAPTION_FROM_APP_BOUNDS,
- DEFAULT_IS_RECENTS_TRANSITION_RUNNING,
- DEFAULT_IS_MOVING_TO_BACK);
+ DEFAULT_SHOULD_EXCLUDE_CAPTION_FROM_APP_BOUNDS);
assertThat(relayoutParams.mIsInsetSource).isFalse();
}
@@ -925,9 +911,7 @@ public class DesktopModeWindowDecorationTests extends ShellTestCase {
DEFAULT_HAS_GLOBAL_FOCUS,
mExclusionRegion,
DEFAULT_SHOULD_IGNORE_CORNER_RADIUS,
- DEFAULT_SHOULD_EXCLUDE_CAPTION_FROM_APP_BOUNDS,
- DEFAULT_IS_RECENTS_TRANSITION_RUNNING,
- DEFAULT_IS_MOVING_TO_BACK);
+ DEFAULT_SHOULD_EXCLUDE_CAPTION_FROM_APP_BOUNDS);
// Header is always shown because it's assumed the status bar is always visible.
assertThat(relayoutParams.mIsCaptionVisible).isTrue();
@@ -954,9 +938,7 @@ public class DesktopModeWindowDecorationTests extends ShellTestCase {
DEFAULT_HAS_GLOBAL_FOCUS,
mExclusionRegion,
DEFAULT_SHOULD_IGNORE_CORNER_RADIUS,
- DEFAULT_SHOULD_EXCLUDE_CAPTION_FROM_APP_BOUNDS,
- DEFAULT_IS_RECENTS_TRANSITION_RUNNING,
- DEFAULT_IS_MOVING_TO_BACK);
+ DEFAULT_SHOULD_EXCLUDE_CAPTION_FROM_APP_BOUNDS);
assertThat(relayoutParams.mIsCaptionVisible).isTrue();
}
@@ -982,9 +964,7 @@ public class DesktopModeWindowDecorationTests extends ShellTestCase {
DEFAULT_HAS_GLOBAL_FOCUS,
mExclusionRegion,
DEFAULT_SHOULD_IGNORE_CORNER_RADIUS,
- DEFAULT_SHOULD_EXCLUDE_CAPTION_FROM_APP_BOUNDS,
- DEFAULT_IS_RECENTS_TRANSITION_RUNNING,
- DEFAULT_IS_MOVING_TO_BACK);
+ DEFAULT_SHOULD_EXCLUDE_CAPTION_FROM_APP_BOUNDS);
assertThat(relayoutParams.mIsCaptionVisible).isFalse();
}
@@ -1010,9 +990,7 @@ public class DesktopModeWindowDecorationTests extends ShellTestCase {
DEFAULT_HAS_GLOBAL_FOCUS,
mExclusionRegion,
DEFAULT_SHOULD_IGNORE_CORNER_RADIUS,
- DEFAULT_SHOULD_EXCLUDE_CAPTION_FROM_APP_BOUNDS,
- DEFAULT_IS_RECENTS_TRANSITION_RUNNING,
- DEFAULT_IS_MOVING_TO_BACK);
+ DEFAULT_SHOULD_EXCLUDE_CAPTION_FROM_APP_BOUNDS);
assertThat(relayoutParams.mIsCaptionVisible).isFalse();
}
@@ -1039,9 +1017,7 @@ public class DesktopModeWindowDecorationTests extends ShellTestCase {
DEFAULT_HAS_GLOBAL_FOCUS,
mExclusionRegion,
DEFAULT_SHOULD_IGNORE_CORNER_RADIUS,
- DEFAULT_SHOULD_EXCLUDE_CAPTION_FROM_APP_BOUNDS,
- DEFAULT_IS_RECENTS_TRANSITION_RUNNING,
- DEFAULT_IS_MOVING_TO_BACK);
+ DEFAULT_SHOULD_EXCLUDE_CAPTION_FROM_APP_BOUNDS);
assertThat(relayoutParams.mIsCaptionVisible).isTrue();
@@ -1060,9 +1036,7 @@ public class DesktopModeWindowDecorationTests extends ShellTestCase {
DEFAULT_HAS_GLOBAL_FOCUS,
mExclusionRegion,
DEFAULT_SHOULD_IGNORE_CORNER_RADIUS,
- DEFAULT_SHOULD_EXCLUDE_CAPTION_FROM_APP_BOUNDS,
- DEFAULT_IS_RECENTS_TRANSITION_RUNNING,
- DEFAULT_IS_MOVING_TO_BACK);
+ DEFAULT_SHOULD_EXCLUDE_CAPTION_FROM_APP_BOUNDS);
assertThat(relayoutParams.mIsCaptionVisible).isFalse();
}
@@ -1089,9 +1063,7 @@ public class DesktopModeWindowDecorationTests extends ShellTestCase {
DEFAULT_HAS_GLOBAL_FOCUS,
mExclusionRegion,
DEFAULT_SHOULD_IGNORE_CORNER_RADIUS,
- DEFAULT_SHOULD_EXCLUDE_CAPTION_FROM_APP_BOUNDS,
- DEFAULT_IS_RECENTS_TRANSITION_RUNNING,
- DEFAULT_IS_MOVING_TO_BACK);
+ DEFAULT_SHOULD_EXCLUDE_CAPTION_FROM_APP_BOUNDS);
assertThat(relayoutParams.mIsCaptionVisible).isTrue();
}
@@ -1118,9 +1090,7 @@ public class DesktopModeWindowDecorationTests extends ShellTestCase {
DEFAULT_HAS_GLOBAL_FOCUS,
mExclusionRegion,
DEFAULT_SHOULD_IGNORE_CORNER_RADIUS,
- DEFAULT_SHOULD_EXCLUDE_CAPTION_FROM_APP_BOUNDS,
- DEFAULT_IS_RECENTS_TRANSITION_RUNNING,
- DEFAULT_IS_MOVING_TO_BACK);
+ DEFAULT_SHOULD_EXCLUDE_CAPTION_FROM_APP_BOUNDS);
assertThat(relayoutParams.mIsCaptionVisible).isFalse();
}
@@ -1151,65 +1121,6 @@ public class DesktopModeWindowDecorationTests extends ShellTestCase {
assertThat(relayoutParams.mAsyncViewHost).isFalse();
}
-
- @Test
- @EnableFlags(Flags.FLAG_ENABLE_INPUT_LAYER_TRANSITION_FIX)
- public void updateRelayoutParams_handle_movingToBack_captionNotVisible() {
- final ActivityManager.RunningTaskInfo taskInfo = createTaskInfo(/* visible= */ true);
- taskInfo.configuration.windowConfiguration.setWindowingMode(WINDOWING_MODE_FULLSCREEN);
- final RelayoutParams relayoutParams = new RelayoutParams();
-
- DesktopModeWindowDecoration.updateRelayoutParams(
- relayoutParams,
- mTestableContext,
- taskInfo,
- mMockSplitScreenController,
- DEFAULT_APPLY_START_TRANSACTION_ON_DRAW,
- DEFAULT_SHOULD_SET_TASK_POSITIONING_AND_CROP,
- DEFAULT_IS_STATUSBAR_VISIBLE,
- DEFAULT_IS_KEYGUARD_VISIBLE_AND_OCCLUDED,
- DEFAULT_IS_IN_FULL_IMMERSIVE_MODE,
- DEFAULT_IS_DRAGGING,
- new InsetsState(),
- DEFAULT_HAS_GLOBAL_FOCUS,
- mExclusionRegion,
- DEFAULT_SHOULD_IGNORE_CORNER_RADIUS,
- DEFAULT_SHOULD_EXCLUDE_CAPTION_FROM_APP_BOUNDS,
- DEFAULT_IS_RECENTS_TRANSITION_RUNNING,
- /* isMovingToBack= */ true);
-
- assertThat(relayoutParams.mIsCaptionVisible).isFalse();
- }
-
- @Test
- @EnableFlags(Flags.FLAG_ENABLE_INPUT_LAYER_TRANSITION_FIX)
- public void updateRelayoutParams_handle_inRecentsTransition_captionNotVisible() {
- final ActivityManager.RunningTaskInfo taskInfo = createTaskInfo(/* visible= */ true);
- taskInfo.configuration.windowConfiguration.setWindowingMode(WINDOWING_MODE_FULLSCREEN);
- final RelayoutParams relayoutParams = new RelayoutParams();
-
- DesktopModeWindowDecoration.updateRelayoutParams(
- relayoutParams,
- mTestableContext,
- taskInfo,
- mMockSplitScreenController,
- DEFAULT_APPLY_START_TRANSACTION_ON_DRAW,
- DEFAULT_SHOULD_SET_TASK_POSITIONING_AND_CROP,
- DEFAULT_IS_STATUSBAR_VISIBLE,
- DEFAULT_IS_KEYGUARD_VISIBLE_AND_OCCLUDED,
- DEFAULT_IS_IN_FULL_IMMERSIVE_MODE,
- DEFAULT_IS_DRAGGING,
- new InsetsState(),
- DEFAULT_HAS_GLOBAL_FOCUS,
- mExclusionRegion,
- DEFAULT_SHOULD_IGNORE_CORNER_RADIUS,
- DEFAULT_SHOULD_EXCLUDE_CAPTION_FROM_APP_BOUNDS,
- /* isRecentsTransitionRunning= */ true,
- DEFAULT_IS_MOVING_TO_BACK);
-
- assertThat(relayoutParams.mIsCaptionVisible).isFalse();
- }
-
@Test
public void relayout_fullscreenTask_appliesTransactionImmediately() {
final ActivityManager.RunningTaskInfo taskInfo = createTaskInfo(/* visible= */ true);
@@ -1846,9 +1757,7 @@ public class DesktopModeWindowDecorationTests extends ShellTestCase {
DEFAULT_HAS_GLOBAL_FOCUS,
mExclusionRegion,
DEFAULT_SHOULD_IGNORE_CORNER_RADIUS,
- DEFAULT_SHOULD_EXCLUDE_CAPTION_FROM_APP_BOUNDS,
- DEFAULT_IS_RECENTS_TRANSITION_RUNNING,
- DEFAULT_IS_MOVING_TO_BACK);
+ DEFAULT_SHOULD_EXCLUDE_CAPTION_FROM_APP_BOUNDS);
}
private DesktopModeWindowDecoration createWindowDecoration(
diff --git a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/windowdecor/DragResizeInputListenerTest.kt b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/windowdecor/DragResizeInputListenerTest.kt
index 360099777bde..95ae73cde19e 100644
--- a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/windowdecor/DragResizeInputListenerTest.kt
+++ b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/windowdecor/DragResizeInputListenerTest.kt
@@ -40,6 +40,7 @@ import com.android.wm.shell.windowdecor.DragResizeInputListener.TaskResizeInputE
import com.google.common.truth.Truth.assertThat
import java.util.function.Consumer
import java.util.function.Supplier
+import kotlin.test.assertNotNull
import org.junit.After
import org.junit.Test
import org.junit.runner.RunWith
@@ -69,9 +70,12 @@ class DragResizeInputListenerTest : ShellTestCase() {
private val sinkInputChannel = mock<InputChannel>()
private val decorationSurface = SurfaceControl.Builder().setName("decoration surface").build()
private val createdSurfaces = ArrayList<SurfaceControl>()
+ private val removedSurfaces = ArrayList<SurfaceControl>()
@After
fun tearDown() {
+ createdSurfaces.clear()
+ removedSurfaces.clear()
decorationSurface.release()
}
@@ -217,6 +221,19 @@ class DragResizeInputListenerTest : ShellTestCase() {
assertThat(createdSurfaces[1].isValid).isFalse()
}
+ @Test
+ fun testClose_releasesDecorationSurfaceWithoutRemoval() {
+ val inputListener = create()
+ testBgExecutor.flushAll()
+ inputListener.close()
+ testMainExecutor.flushAll()
+ testBgExecutor.flushAll()
+
+ val decorationSurface = assertNotNull(createdSurfaces[0])
+ assertThat(decorationSurface.isValid).isFalse()
+ assertThat(removedSurfaces.contains(decorationSurface)).isFalse()
+ }
+
private fun verifyNoInputChannelGrantRequests() {
verify(mockWindowSession, never())
.grantInputChannel(
@@ -258,7 +275,10 @@ class DragResizeInputListenerTest : ShellTestCase() {
{
object : StubTransaction() {
override fun remove(sc: SurfaceControl): SurfaceControl.Transaction {
- return super.remove(sc).also { sc.release() }
+ return super.remove(sc).also {
+ sc.release()
+ removedSurfaces.add(sc)
+ }
}
}
},
diff --git a/libs/androidfw/AssetManager2.cpp b/libs/androidfw/AssetManager2.cpp
index e09ab5fd1643..6caae4c7623e 100644
--- a/libs/androidfw/AssetManager2.cpp
+++ b/libs/androidfw/AssetManager2.cpp
@@ -82,6 +82,9 @@ struct FindEntryResult {
// The bitmask of configuration axis with which the resource value varies.
uint32_t type_flags;
+ // The bitmask of ResTable_entry flags
+ uint16_t entry_flags;
+
// The dynamic package ID map for the package from which this resource came from.
const DynamicRefTable* dynamic_ref_table;
@@ -1031,6 +1034,7 @@ base::expected<FindEntryResult, NullOrIOError> AssetManager2::FindEntryInternal(
.entry = *entry,
.config = *best_config,
.type_flags = type_flags,
+ .entry_flags = (*best_entry_verified)->flags(),
.dynamic_ref_table = package_group.dynamic_ref_table.get(),
.package_name = &best_package->GetPackageName(),
.type_string_ref = StringPoolRef(best_package->GetTypeStringPool(), best_type->id - 1),
@@ -1185,16 +1189,16 @@ base::expected<AssetManager2::SelectedValue, NullOrIOError> AssetManager2::GetRe
}
// Create a reference since we can't represent this complex type as a Res_value.
- return SelectedValue(Res_value::TYPE_REFERENCE, resid, result->cookie, result->type_flags,
- resid, result->config);
+ return SelectedValue(Res_value::TYPE_REFERENCE, resid, result->cookie, result->entry_flags,
+ result->type_flags, resid, result->config);
}
// Convert the package ID to the runtime assigned package ID.
Res_value value = std::get<Res_value>(result->entry);
result->dynamic_ref_table->lookupResourceValue(&value);
- return SelectedValue(value.dataType, value.data, result->cookie, result->type_flags,
- resid, result->config);
+ return SelectedValue(value.dataType, value.data, result->cookie, result->entry_flags,
+ result->type_flags, resid, result->config);
}
base::expected<std::monostate, NullOrIOError> AssetManager2::ResolveReference(
@@ -1847,8 +1851,8 @@ std::optional<AssetManager2::SelectedValue> Theme::GetAttribute(uint32_t resid)
}
return AssetManager2::SelectedValue(entry_it->value.dataType, entry_it->value.data,
- entry_it->cookie, type_spec_flags, 0U /* resid */,
- {} /* config */);
+ entry_it->cookie, 0U /* entry flags*/, type_spec_flags,
+ 0U /* resid */, {} /* config */);
}
return std::nullopt;
}
diff --git a/libs/androidfw/LocaleDataLookup.cpp b/libs/androidfw/LocaleDataLookup.cpp
index 9aacdcb9ca92..ed645826234d 100644
--- a/libs/androidfw/LocaleDataLookup.cpp
+++ b/libs/androidfw/LocaleDataLookup.cpp
@@ -5774,7 +5774,6 @@ const char* lookupLikelyScript(uint32_t packed_lang_region) {
case 0xD2120000u: // squ -> Latn
case 0x73724D45u: // sr-ME -> Latn
case 0x7372524Fu: // sr-RO -> Latn
- case 0x73725255u: // sr-RU -> Latn
case 0x73725452u: // sr-TR -> Latn
case 0x82320000u: // sra -> Latn
case 0x92320000u: // sre -> Latn
@@ -7265,7 +7264,6 @@ const char* lookupLikelyScript(uint32_t packed_lang_region) {
return SCRIPT_CODES[73u];
case 0x8ACD0000u: // nwc -> Newa
return SCRIPT_CODES[74u];
- case 0xB40C474Eu: // man-GN -> Nkoo
case 0xBA0D0000u: // nqo -> Nkoo
return SCRIPT_CODES[75u];
case 0xDCF90000u: // zhx -> Nshu
diff --git a/libs/androidfw/include/androidfw/AssetManager2.h b/libs/androidfw/include/androidfw/AssetManager2.h
index b0179524f6cd..ffcef944a6ba 100644
--- a/libs/androidfw/include/androidfw/AssetManager2.h
+++ b/libs/androidfw/include/androidfw/AssetManager2.h
@@ -257,6 +257,7 @@ class AssetManager2 {
: cookie(entry.cookie),
data(entry.value.data),
type(entry.value.dataType),
+ entry_flags(0U),
flags(bag->type_spec_flags),
resid(0U),
config() {
@@ -271,6 +272,9 @@ class AssetManager2 {
// Type of the data value.
uint8_t type;
+ // The bitmask of ResTable_entry flags
+ uint16_t entry_flags;
+
// The bitmask of configuration axis that this resource varies with.
// See ResTable_config::CONFIG_*.
uint32_t flags;
@@ -283,9 +287,10 @@ class AssetManager2 {
private:
SelectedValue(uint8_t value_type, Res_value::data_type value_data, ApkAssetsCookie cookie,
- uint32_t type_flags, uint32_t resid, ResTable_config config) :
- cookie(cookie), data(value_data), type(value_type), flags(type_flags),
- resid(resid), config(std::move(config)) {}
+ uint16_t entry_flags, uint32_t type_flags, uint32_t resid, ResTable_config config)
+ :
+ cookie(cookie), data(value_data), type(value_type), entry_flags(entry_flags),
+ flags(type_flags), resid(resid), config(std::move(config)) {}
};
// Retrieves the best matching resource value with ID `resid`.
diff --git a/libs/androidfw/tests/AssetManager2_test.cpp b/libs/androidfw/tests/AssetManager2_test.cpp
index 3f228841f6ba..948437230ecc 100644
--- a/libs/androidfw/tests/AssetManager2_test.cpp
+++ b/libs/androidfw/tests/AssetManager2_test.cpp
@@ -23,6 +23,7 @@
#include "androidfw/ResourceUtils.h"
#include "data/appaslib/R.h"
#include "data/basic/R.h"
+#include "data/flagged/R.h"
#include "data/lib_one/R.h"
#include "data/lib_two/R.h"
#include "data/libclient/R.h"
@@ -32,6 +33,7 @@
namespace app = com::android::app;
namespace appaslib = com::android::appaslib::app;
namespace basic = com::android::basic;
+namespace flagged = com::android::flagged;
namespace lib_one = com::android::lib_one;
namespace lib_two = com::android::lib_two;
namespace libclient = com::android::libclient;
@@ -87,6 +89,10 @@ class AssetManager2Test : public ::testing::Test {
overlayable_assets_ = ApkAssets::Load("overlayable/overlayable.apk");
ASSERT_THAT(overlayable_assets_, NotNull());
+
+ flagged_assets_ = ApkAssets::Load("flagged/flagged.apk");
+ ASSERT_THAT(app_assets_, NotNull());
+
chdir(original_path.c_str());
}
@@ -104,6 +110,7 @@ class AssetManager2Test : public ::testing::Test {
AssetManager2::ApkAssetsPtr app_assets_;
AssetManager2::ApkAssetsPtr overlay_assets_;
AssetManager2::ApkAssetsPtr overlayable_assets_;
+ AssetManager2::ApkAssetsPtr flagged_assets_;
};
TEST_F(AssetManager2Test, FindsResourceFromSingleApkAssets) {
@@ -856,4 +863,12 @@ TEST_F(AssetManager2Test, GetApkAssets) {
EXPECT_EQ(1, lib_one_assets_->getStrongCount());
}
+TEST_F(AssetManager2Test, GetFlaggedAssets) {
+ AssetManager2 assetmanager;
+ assetmanager.SetApkAssets({flagged_assets_});
+ auto value = assetmanager.GetResource(flagged::R::xml::flagged, false, 0);
+ ASSERT_TRUE(value.has_value());
+ EXPECT_TRUE(value->entry_flags & ResTable_entry::FLAG_USES_FEATURE_FLAGS);
+}
+
} // namespace android
diff --git a/libs/androidfw/tests/data/flagged/AndroidManifest.xml b/libs/androidfw/tests/data/flagged/AndroidManifest.xml
new file mode 100644
index 000000000000..cc1394328797
--- /dev/null
+++ b/libs/androidfw/tests/data/flagged/AndroidManifest.xml
@@ -0,0 +1,20 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2025 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.
+-->
+
+<manifest xmlns:android="http://schemas.android.com/apk/res/android"
+ package="com.android.basic">
+ <application />
+</manifest>
diff --git a/libs/androidfw/tests/data/flagged/R.h b/libs/androidfw/tests/data/flagged/R.h
new file mode 100644
index 000000000000..33ccab28cdd3
--- /dev/null
+++ b/libs/androidfw/tests/data/flagged/R.h
@@ -0,0 +1,35 @@
+/*
+* Copyright (C) 2025 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.
+*/
+
+#pragma once
+
+#include <cstdint>
+
+namespace com {
+namespace android {
+namespace flagged {
+
+struct R {
+ struct xml {
+ enum : uint32_t {
+ flagged = 0x7f010000,
+ };
+ };
+};
+
+} // namespace flagged
+} // namespace android
+} // namespace com \ No newline at end of file
diff --git a/libs/androidfw/tests/data/flagged/build b/libs/androidfw/tests/data/flagged/build
new file mode 100755
index 000000000000..9e5d21ba1833
--- /dev/null
+++ b/libs/androidfw/tests/data/flagged/build
@@ -0,0 +1,28 @@
+#!/bin/bash
+#
+# Copyright (C) 2025 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.
+#
+
+set -e
+
+PATH_TO_FRAMEWORK_RES=${ANDROID_BUILD_TOP}/prebuilts/sdk/current/public/android.jar
+
+aapt2 compile --dir res -o compiled.flata
+aapt2 link -o flagged.apk \
+ --manifest AndroidManifest.xml \
+ -I $PATH_TO_FRAMEWORK_RES \
+ -I ../basic/basic.apk \
+ compiled.flata
+rm compiled.flata
diff --git a/libs/androidfw/tests/data/flagged/flagged.apk b/libs/androidfw/tests/data/flagged/flagged.apk
new file mode 100644
index 000000000000..94b8f4d9fcf0
--- /dev/null
+++ b/libs/androidfw/tests/data/flagged/flagged.apk
Binary files differ
diff --git a/libs/androidfw/tests/data/flagged/res/xml/flagged.xml b/libs/androidfw/tests/data/flagged/res/xml/flagged.xml
new file mode 100644
index 000000000000..5fe8d1b3ac27
--- /dev/null
+++ b/libs/androidfw/tests/data/flagged/res/xml/flagged.xml
@@ -0,0 +1,18 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2025 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.
+-->
+<first xmlns:android="http://schemas.android.com/apk/res/android">
+ <second android:featureFlag="android.content.res.always_false"/>
+</first> \ No newline at end of file
diff --git a/libs/hwui/hwui/Bitmap.cpp b/libs/hwui/hwui/Bitmap.cpp
index 3ef970830dc4..46dcc1f4c50b 100644
--- a/libs/hwui/hwui/Bitmap.cpp
+++ b/libs/hwui/hwui/Bitmap.cpp
@@ -164,8 +164,13 @@ std::string Bitmap::getAshmemId(const char* tag, uint64_t bitmapId,
android::base::ReadFileToString("/proc/self/cmdline", &temp);
return temp;
}();
- return std::format("bitmap/{}-id_{}-{}x{}-size_{}-{}",
- tag, bitmapId, width, height, size, sCmdline);
+ /* counter is to ensure the uniqueness of the ashmem filename,
+ * e.g. a bitmap with same mId could be sent multiple times, an
+ * ashmem region is created each time
+ */
+ static std::atomic<uint32_t> counter{0};
+ return std::format("bitmap/{}_{}_{}x{}_size-{}_id-{}_{}",
+ tag, counter.fetch_add(1), width, height, size, bitmapId, sCmdline);
}
sk_sp<Bitmap> Bitmap::allocateAshmemBitmap(SkBitmap* bitmap) {
diff --git a/libs/hwui/jni/GIFMovie.cpp b/libs/hwui/jni/GIFMovie.cpp
index 476b6fda5007..6c82aa1ca27d 100644
--- a/libs/hwui/jni/GIFMovie.cpp
+++ b/libs/hwui/jni/GIFMovie.cpp
@@ -63,7 +63,7 @@ GIFMovie::GIFMovie(SkStream* stream)
}
fCurrIndex = -1;
fLastDrawIndex = -1;
- fPaintingColor = SK_AlphaTRANSPARENT;
+ fPaintingColor = SkPackARGB32(0, 0, 0, 0);
}
GIFMovie::~GIFMovie()
@@ -127,7 +127,7 @@ static void copyLine(uint32_t* dst, const unsigned char* src, const ColorMapObje
for (; width > 0; width--, src++, dst++) {
if (*src != transparent && *src < cmap->ColorCount) {
const GifColorType& col = cmap->Colors[*src];
- *dst = SkColorSetRGB(col.Red, col.Green, col.Blue);
+ *dst = SkPackARGB32(0xFF, col.Red, col.Green, col.Blue);
}
}
}
@@ -395,10 +395,10 @@ bool GIFMovie::onGetBitmap(SkBitmap* bm)
lastIndex = fGIF->ImageCount - 1;
}
- SkColor bgColor = SK_ColorTRANSPARENT;
+ SkColor bgColor = SkPackARGB32(0, 0, 0, 0);
if (gif->SColorMap != nullptr && gif->SBackGroundColor < gif->SColorMap->ColorCount) {
const GifColorType& col = gif->SColorMap->Colors[gif->SBackGroundColor];
- bgColor = SkColorSetRGB(col.Red, col.Green, col.Blue);
+ bgColor = SkColorSetARGB(0xFF, col.Red, col.Green, col.Blue);
}
// draw each frames - not intelligent way
@@ -411,7 +411,7 @@ bool GIFMovie::onGetBitmap(SkBitmap* bm)
if (!trans && gif->SColorMap != nullptr) {
fPaintingColor = bgColor;
} else {
- fPaintingColor = SK_ColorTRANSPARENT;
+ fPaintingColor = SkColorSetARGB(0, 0, 0, 0);
}
bm->eraseColor(fPaintingColor);
diff --git a/libs/hwui/renderthread/VulkanManager.cpp b/libs/hwui/renderthread/VulkanManager.cpp
index 0cd9c53c830f..e5a6260cfd98 100644
--- a/libs/hwui/renderthread/VulkanManager.cpp
+++ b/libs/hwui/renderthread/VulkanManager.cpp
@@ -44,7 +44,7 @@ namespace uirenderer {
namespace renderthread {
// Not all of these are strictly required, but are all enabled if present.
-static std::array<std::string_view, 23> sEnableExtensions{
+static std::array<std::string_view, 25> sEnableExtensions{
VK_KHR_BIND_MEMORY_2_EXTENSION_NAME,
VK_KHR_DEDICATED_ALLOCATION_EXTENSION_NAME,
VK_KHR_EXTERNAL_MEMORY_CAPABILITIES_EXTENSION_NAME,
@@ -68,6 +68,8 @@ static std::array<std::string_view, 23> sEnableExtensions{
VK_EXT_GLOBAL_PRIORITY_QUERY_EXTENSION_NAME,
VK_KHR_GLOBAL_PRIORITY_EXTENSION_NAME,
VK_EXT_DEVICE_FAULT_EXTENSION_NAME,
+ VK_EXT_FRAME_BOUNDARY_EXTENSION_NAME,
+ VK_ANDROID_FRAME_BOUNDARY_EXTENSION_NAME,
};
static bool shouldEnableExtension(const std::string_view& extension) {
@@ -746,7 +748,14 @@ VulkanManager::VkDrawResult VulkanManager::finishFrame(SkSurface* surface) {
ALOGE_IF(!context, "Surface is not backed by gpu");
GrSemaphoresSubmitted submitted = context->flush(
surface, SkSurfaces::BackendSurfaceAccess::kPresent, flushInfo);
- context->submit();
+
+ static uint64_t currentFrameID = 0;
+ GrSubmitInfo submitInfo;
+ if (!mFrameBoundaryANDROID) {
+ submitInfo.fMarkBoundary = GrMarkFrameBoundary::kYes;
+ submitInfo.fFrameID = currentFrameID++;
+ }
+ context->submit(submitInfo);
VkDrawResult drawResult{
.submissionTime = systemTime(),
};
diff --git a/libs/hwui/renderthread/VulkanManager.h b/libs/hwui/renderthread/VulkanManager.h
index a593ec6f8351..744211e39f79 100644
--- a/libs/hwui/renderthread/VulkanManager.h
+++ b/libs/hwui/renderthread/VulkanManager.h
@@ -30,14 +30,10 @@
// VK_ANDROID_frame_boundary is a bespoke extension defined by AGI
// (https://github.com/google/agi) to enable profiling of apps rendering via
// HWUI. This extension is not defined in Khronos, hence the need to declare it
-// manually here. There's a superseding extension (VK_EXT_frame_boundary) being
-// discussed in Khronos, but in the meantime we use the bespoke
-// VK_ANDROID_frame_boundary. This is a device extension that is implemented by
+// manually here. There's an extension (VK_EXT_frame_boundary) which we will use
+// instead if available. This is a device extension that is implemented by
// AGI's Vulkan capture layer, such that it is only supported by devices when
// AGI is doing a capture of the app.
-//
-// TODO(b/182165045): use the Khronos blessed VK_EXT_frame_boudary once it has
-// landed in the spec.
typedef void(VKAPI_PTR* PFN_vkFrameBoundaryANDROID)(VkDevice device, VkSemaphore semaphore,
VkImage image);
#define VK_ANDROID_FRAME_BOUNDARY_EXTENSION_NAME "VK_ANDROID_frame_boundary"