diff options
Diffstat (limited to 'libs')
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 Binary files differnew file mode 100644 index 000000000000..94b8f4d9fcf0 --- /dev/null +++ b/libs/androidfw/tests/data/flagged/flagged.apk 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" |