Merge "Remove heuristic that determines whether to shift cells down or not" into main
diff --git a/Android.bp b/Android.bp
index 6bd8602..5b986ab 100644
--- a/Android.bp
+++ b/Android.bp
@@ -389,6 +389,7 @@
"//frameworks/libs/systemui:contextualeducationlib",
"//frameworks/libs/systemui:msdl",
"SystemUI-statsd",
+ "WindowManager-Shell-shared-AOSP",
"launcher-testing-shared",
"androidx.lifecycle_lifecycle-common-java8",
"androidx.lifecycle_lifecycle-extensions",
diff --git a/aconfig/Android.bp b/aconfig/Android.bp
index 5413601..bca7494 100644
--- a/aconfig/Android.bp
+++ b/aconfig/Android.bp
@@ -20,7 +20,7 @@
aconfig_declarations {
name: "com_android_launcher3_flags",
package: "com.android.launcher3",
- container: "system",
+ container: "system_ext",
srcs: ["**/*.aconfig"],
}
diff --git a/aconfig/launcher.aconfig b/aconfig/launcher.aconfig
index c3fb150..06809d7 100644
--- a/aconfig/launcher.aconfig
+++ b/aconfig/launcher.aconfig
@@ -1,5 +1,5 @@
package: "com.android.launcher3"
-container: "system"
+container: "system_ext"
flag {
name: "enable_expanding_pause_work_button"
diff --git a/aconfig/launcher_overview.aconfig b/aconfig/launcher_overview.aconfig
index e0a597c..30b0d40 100644
--- a/aconfig/launcher_overview.aconfig
+++ b/aconfig/launcher_overview.aconfig
@@ -1,5 +1,5 @@
package: "com.android.launcher3"
-container: "system"
+container: "system_ext"
flag {
name: "enable_grid_only_overview"
@@ -79,3 +79,13 @@
description: "Enables expressive motion and animations for dismissing a task in Overview."
bug: "381239462"
}
+
+flag {
+ name: "enable_separate_external_display_tasks"
+ namespace: "launcher_overview"
+ description: "Enables separating external display tasks in Overview."
+ bug: "391311008"
+ metadata {
+ purpose: PURPOSE_BUGFIX
+ }
+}
diff --git a/aconfig/launcher_search.aconfig b/aconfig/launcher_search.aconfig
index 72f654e..b98eee6 100644
--- a/aconfig/launcher_search.aconfig
+++ b/aconfig/launcher_search.aconfig
@@ -1,5 +1,5 @@
package: "com.android.launcher3"
-container: "system"
+container: "system_ext"
flag {
name: "enable_private_space"
diff --git a/go/quickstep/res/values-fa/strings.xml b/go/quickstep/res/values-fa/strings.xml
index 8453d4e..f0e4a57 100644
--- a/go/quickstep/res/values-fa/strings.xml
+++ b/go/quickstep/res/values-fa/strings.xml
@@ -5,7 +5,7 @@
<string name="action_listen" msgid="2370304050784689486">"گوش دادن"</string>
<string name="action_translate" msgid="8028378961867277746">"ترجمه"</string>
<string name="action_search" msgid="6269564710943755464">"لنز"</string>
- <string name="dialog_acknowledge" msgid="2804025517675853172">"متوجهام"</string>
+ <string name="dialog_acknowledge" msgid="2804025517675853172">"متوجهم"</string>
<string name="dialog_cancel" msgid="6464336969134856366">"لغو"</string>
<string name="dialog_settings" msgid="6564397136021186148">"تنظیمات"</string>
<string name="niu_actions_confirmation_title" msgid="3863451714863526143">"ترجمه نوشتار روی صفحهنمایش یا گوش دادن به آن"</string>
diff --git a/quickstep/AndroidManifest.xml b/quickstep/AndroidManifest.xml
index 201c5f6..5ca7143 100644
--- a/quickstep/AndroidManifest.xml
+++ b/quickstep/AndroidManifest.xml
@@ -119,6 +119,7 @@
android:autoRemoveFromRecents="true"
android:excludeFromRecents="true"
android:theme="@style/GestureTutorialActivity"
+ android:label="@string/gesture_tutorial_title"
android:exported="true"
android:configChanges="orientation">
<intent-filter>
diff --git a/quickstep/res/layout/overview_add_desktop_button.xml b/quickstep/res/layout/overview_add_desktop_button.xml
index 2333dd1..e36cf72 100644
--- a/quickstep/res/layout/overview_add_desktop_button.xml
+++ b/quickstep/res/layout/overview_add_desktop_button.xml
@@ -18,7 +18,7 @@
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:launcher="http://schemas.android.com/apgk/res-auto"
android:id="@+id/add_desktop_button"
- android:layout_width="wrap_content"
- android:layout_height="wrap_content"
+ android:layout_width="@dimen/add_desktop_button_size"
+ android:layout_height="@dimen/add_desktop_button_size"
android:src="@drawable/ic_desktop_add"
android:padding="10dp" />
\ No newline at end of file
diff --git a/quickstep/res/values-af/strings.xml b/quickstep/res/values-af/strings.xml
index cf7b938..eba4ae6 100644
--- a/quickstep/res/values-af/strings.xml
+++ b/quickstep/res/values-af/strings.xml
@@ -46,6 +46,8 @@
<string name="hotsaet_tip_prediction_enabled" msgid="2233554377501347650">"Programvoorstelle is geaktiveer"</string>
<string name="hotsaet_tip_prediction_disabled" msgid="1506426298884658491">"Programvoorstelle is gedeaktiveer"</string>
<string name="hotseat_prediction_content_description" msgid="4582028296938078419">"Voorspelde app: <xliff:g id="TITLE">%1$s</xliff:g>"</string>
+ <!-- no translation found for gesture_tutorial_title (2750751261768388354) -->
+ <skip />
<string name="gesture_tutorial_rotation_prompt_title" msgid="7537946781362766964">"Draai jou toestel"</string>
<string name="gesture_tutorial_rotation_prompt" msgid="1664493449851960691">"Draai asseblief jou toestel om die tutoriaal oor gebaarnavigasie te voltooi"</string>
<string name="back_gesture_feedback_swipe_too_far_from_edge" msgid="4175100312909721217">"Maak seker dat jy van die rand heel regs of heel links af swiep"</string>
@@ -152,4 +154,7 @@
<string name="bubble_bar_accessibility_announce_expand" msgid="1503192695527477102">"vou <xliff:g id="BUBBLE_DESCRIPTION">%1$s</xliff:g> uit"</string>
<string name="bubble_bar_accessibility_announce_collapse" msgid="928284600086798791">"vou <xliff:g id="BUBBLE_DESCRIPTION">%1$s</xliff:g> in"</string>
<string name="search_gesture_feature_title" msgid="1294044108313175306">"Omkring en Soek"</string>
+ <string name="header_app_icon_description" msgid="2184625881433608027">"Appikoon"</string>
+ <string name="header_default_app_title" msgid="8308052350689531566">"Apptitel"</string>
+ <string name="header_close_icon_description" msgid="5400033616675911319">"Maak Toe-knoppie"</string>
</resources>
diff --git a/quickstep/res/values-am/strings.xml b/quickstep/res/values-am/strings.xml
index 60c04dc..019850d 100644
--- a/quickstep/res/values-am/strings.xml
+++ b/quickstep/res/values-am/strings.xml
@@ -46,6 +46,8 @@
<string name="hotsaet_tip_prediction_enabled" msgid="2233554377501347650">"የመተግበሪያ አስተያየት ጥቆማዎች ነቅቷል"</string>
<string name="hotsaet_tip_prediction_disabled" msgid="1506426298884658491">"የመተግበሪያ አስተያየቶች ቦዝነዋል"</string>
<string name="hotseat_prediction_content_description" msgid="4582028296938078419">"የተገመተው መተግበሪያ፦ <xliff:g id="TITLE">%1$s</xliff:g>"</string>
+ <!-- no translation found for gesture_tutorial_title (2750751261768388354) -->
+ <skip />
<string name="gesture_tutorial_rotation_prompt_title" msgid="7537946781362766964">"መሣሪያዎን ያሽከርክሩ"</string>
<string name="gesture_tutorial_rotation_prompt" msgid="1664493449851960691">"የእጅ ምልክት ዳሰሳ አጋዥ ሥልጠናን ለማጠናቀቅ እባክዎ መሣሪያዎን ያሽከርክሩ"</string>
<string name="back_gesture_feedback_swipe_too_far_from_edge" msgid="4175100312909721217">"ከቀኝ ጥግ ወይም ከግራ ጥግ ጠርዝ ጀምሮ ማንሸራተትዎን ያረጋግጡ"</string>
@@ -152,4 +154,7 @@
<string name="bubble_bar_accessibility_announce_expand" msgid="1503192695527477102">"<xliff:g id="BUBBLE_DESCRIPTION">%1$s</xliff:g>ን ዘርጋ"</string>
<string name="bubble_bar_accessibility_announce_collapse" msgid="928284600086798791">"<xliff:g id="BUBBLE_DESCRIPTION">%1$s</xliff:g>ን ሰብስብ"</string>
<string name="search_gesture_feature_title" msgid="1294044108313175306">"ለመፈለግ ክበብ"</string>
+ <string name="header_app_icon_description" msgid="2184625881433608027">"የመተግበሪያ አዶ"</string>
+ <string name="header_default_app_title" msgid="8308052350689531566">"የመተግበሪያ ርዕስ"</string>
+ <string name="header_close_icon_description" msgid="5400033616675911319">"የዝጋ አዝራር"</string>
</resources>
diff --git a/quickstep/res/values-ar/strings.xml b/quickstep/res/values-ar/strings.xml
index dc756d4..a77335f 100644
--- a/quickstep/res/values-ar/strings.xml
+++ b/quickstep/res/values-ar/strings.xml
@@ -46,6 +46,8 @@
<string name="hotsaet_tip_prediction_enabled" msgid="2233554377501347650">"تم تفعيل ميزة \"التطبيقات المقترحة\"."</string>
<string name="hotsaet_tip_prediction_disabled" msgid="1506426298884658491">"ميزة \"التطبيقات المقترحة\" غير مفعّلة."</string>
<string name="hotseat_prediction_content_description" msgid="4582028296938078419">"التطبيق المتوقع: <xliff:g id="TITLE">%1$s</xliff:g>"</string>
+ <!-- no translation found for gesture_tutorial_title (2750751261768388354) -->
+ <skip />
<string name="gesture_tutorial_rotation_prompt_title" msgid="7537946781362766964">"يُرجى تدوير الجهاز"</string>
<string name="gesture_tutorial_rotation_prompt" msgid="1664493449851960691">"يُرجى تدوير جهازك لإكمال الدليل التوجيهي للتنقُّل بالإيماءات."</string>
<string name="back_gesture_feedback_swipe_too_far_from_edge" msgid="4175100312909721217">"تأكَّد من التمرير سريعًا من أقصى الحافة اليسرى أو اليمنى."</string>
@@ -152,4 +154,7 @@
<string name="bubble_bar_accessibility_announce_expand" msgid="1503192695527477102">"توسيع <xliff:g id="BUBBLE_DESCRIPTION">%1$s</xliff:g>"</string>
<string name="bubble_bar_accessibility_announce_collapse" msgid="928284600086798791">"تصغير <xliff:g id="BUBBLE_DESCRIPTION">%1$s</xliff:g>"</string>
<string name="search_gesture_feature_title" msgid="1294044108313175306">"دائرة البحث"</string>
+ <string name="header_app_icon_description" msgid="2184625881433608027">"رمز التطبيق"</string>
+ <string name="header_default_app_title" msgid="8308052350689531566">"عنوان التطبيق"</string>
+ <string name="header_close_icon_description" msgid="5400033616675911319">"زر الإغلاق"</string>
</resources>
diff --git a/quickstep/res/values-as/strings.xml b/quickstep/res/values-as/strings.xml
index ae16f96..a7a66e9 100644
--- a/quickstep/res/values-as/strings.xml
+++ b/quickstep/res/values-as/strings.xml
@@ -46,6 +46,8 @@
<string name="hotsaet_tip_prediction_enabled" msgid="2233554377501347650">"এপৰ পৰামৰ্শসমূহ সক্ষম কৰা আছে"</string>
<string name="hotsaet_tip_prediction_disabled" msgid="1506426298884658491">"এপৰ পৰামৰ্শসমূহ অক্ষম কৰা আছে"</string>
<string name="hotseat_prediction_content_description" msgid="4582028296938078419">"পূৰ্বানুমান কৰা এপ্: <xliff:g id="TITLE">%1$s</xliff:g>"</string>
+ <!-- no translation found for gesture_tutorial_title (2750751261768388354) -->
+ <skip />
<string name="gesture_tutorial_rotation_prompt_title" msgid="7537946781362766964">"আপোনাৰ ডিভাইচটো ঘূৰাওক"</string>
<string name="gesture_tutorial_rotation_prompt" msgid="1664493449851960691">"আঙুলিৰ স্পৰ্শৰ নিৰ্দেশেৰে কৰা নেভিগেশ্বনৰ টিউট’ৰিয়েল শেষ কৰিবলৈ অনুগ্ৰহ কৰি আপোনাৰ ডিভাইচটো ঘূৰাওক"</string>
<string name="back_gesture_feedback_swipe_too_far_from_edge" msgid="4175100312909721217">"আপুনি সোঁ অথবা বাওঁ কাষৰ একেবাৰে সীমাৰ পৰা ছোৱাইপ কৰাটো নিশ্চিত কৰক"</string>
@@ -152,4 +154,7 @@
<string name="bubble_bar_accessibility_announce_expand" msgid="1503192695527477102">"<xliff:g id="BUBBLE_DESCRIPTION">%1$s</xliff:g> বিস্তাৰ কৰক"</string>
<string name="bubble_bar_accessibility_announce_collapse" msgid="928284600086798791">"<xliff:g id="BUBBLE_DESCRIPTION">%1$s</xliff:g> সংকোচন কৰক"</string>
<string name="search_gesture_feature_title" msgid="1294044108313175306">"সন্ধান কৰিবৰ বাবে বৃত্ত"</string>
+ <string name="header_app_icon_description" msgid="2184625881433608027">"এপৰ আইকন"</string>
+ <string name="header_default_app_title" msgid="8308052350689531566">"এপৰ শিৰোনাম"</string>
+ <string name="header_close_icon_description" msgid="5400033616675911319">"বন্ধ কৰা বুটাম"</string>
</resources>
diff --git a/quickstep/res/values-az/strings.xml b/quickstep/res/values-az/strings.xml
index df1b828..0e0181a 100644
--- a/quickstep/res/values-az/strings.xml
+++ b/quickstep/res/values-az/strings.xml
@@ -46,6 +46,8 @@
<string name="hotsaet_tip_prediction_enabled" msgid="2233554377501347650">"Tətbiq təklifləri aktivdir"</string>
<string name="hotsaet_tip_prediction_disabled" msgid="1506426298884658491">"Tətbiq təklifləri deaktivdir"</string>
<string name="hotseat_prediction_content_description" msgid="4582028296938078419">"Proqnozlaşdırılan tətbiq: <xliff:g id="TITLE">%1$s</xliff:g>"</string>
+ <!-- no translation found for gesture_tutorial_title (2750751261768388354) -->
+ <skip />
<string name="gesture_tutorial_rotation_prompt_title" msgid="7537946781362766964">"Cihazı fırladın"</string>
<string name="gesture_tutorial_rotation_prompt" msgid="1664493449851960691">"Jest naviqasiyası təlimatını tamamlamaq üçün cihazı fırladın"</string>
<string name="back_gesture_feedback_swipe_too_far_from_edge" msgid="4175100312909721217">"Ən sağ və ya sol kənardan sürüşdürün"</string>
@@ -152,4 +154,7 @@
<string name="bubble_bar_accessibility_announce_expand" msgid="1503192695527477102">"genişləndirin: <xliff:g id="BUBBLE_DESCRIPTION">%1$s</xliff:g>"</string>
<string name="bubble_bar_accessibility_announce_collapse" msgid="928284600086798791">"yığcamlaşdırın: <xliff:g id="BUBBLE_DESCRIPTION">%1$s</xliff:g>"</string>
<string name="search_gesture_feature_title" msgid="1294044108313175306">"Dairəyə alaraq axtarın"</string>
+ <string name="header_app_icon_description" msgid="2184625881433608027">"Tətbiq ikonası"</string>
+ <string name="header_default_app_title" msgid="8308052350689531566">"Tətbiq başlığı"</string>
+ <string name="header_close_icon_description" msgid="5400033616675911319">"Qapatma düyməsi"</string>
</resources>
diff --git a/quickstep/res/values-b+sr+Latn/strings.xml b/quickstep/res/values-b+sr+Latn/strings.xml
index bad8811..95767e2 100644
--- a/quickstep/res/values-b+sr+Latn/strings.xml
+++ b/quickstep/res/values-b+sr+Latn/strings.xml
@@ -46,6 +46,8 @@
<string name="hotsaet_tip_prediction_enabled" msgid="2233554377501347650">"Predlozi aplikacija su omogućeni"</string>
<string name="hotsaet_tip_prediction_disabled" msgid="1506426298884658491">"Predlozi aplikacija su onemogućeni"</string>
<string name="hotseat_prediction_content_description" msgid="4582028296938078419">"Predviđamo aplikaciju: <xliff:g id="TITLE">%1$s</xliff:g>"</string>
+ <!-- no translation found for gesture_tutorial_title (2750751261768388354) -->
+ <skip />
<string name="gesture_tutorial_rotation_prompt_title" msgid="7537946781362766964">"Rotirajte uređaj"</string>
<string name="gesture_tutorial_rotation_prompt" msgid="1664493449851960691">"Rotirajte uređaj da biste dovršili vodič za navigaciju pomoću pokreta"</string>
<string name="back_gesture_feedback_swipe_too_far_from_edge" msgid="4175100312909721217">"Obavezno prevucite od same desne ili leve ivice"</string>
@@ -152,4 +154,7 @@
<string name="bubble_bar_accessibility_announce_expand" msgid="1503192695527477102">"proširite oblačić <xliff:g id="BUBBLE_DESCRIPTION">%1$s</xliff:g>"</string>
<string name="bubble_bar_accessibility_announce_collapse" msgid="928284600086798791">"skupite oblačić <xliff:g id="BUBBLE_DESCRIPTION">%1$s</xliff:g>"</string>
<string name="search_gesture_feature_title" msgid="1294044108313175306">"Pretraga zaokruživanjem"</string>
+ <string name="header_app_icon_description" msgid="2184625881433608027">"Ikona aplikacije"</string>
+ <string name="header_default_app_title" msgid="8308052350689531566">"Naziv aplikacije"</string>
+ <string name="header_close_icon_description" msgid="5400033616675911319">"Dugme Zatvori"</string>
</resources>
diff --git a/quickstep/res/values-be/strings.xml b/quickstep/res/values-be/strings.xml
index f61b337..0261c0f 100644
--- a/quickstep/res/values-be/strings.xml
+++ b/quickstep/res/values-be/strings.xml
@@ -46,6 +46,8 @@
<string name="hotsaet_tip_prediction_enabled" msgid="2233554377501347650">"Прапановы праграм уключаны"</string>
<string name="hotsaet_tip_prediction_disabled" msgid="1506426298884658491">"Прапановы праграм выключаны"</string>
<string name="hotseat_prediction_content_description" msgid="4582028296938078419">"Праграма з падказкі: <xliff:g id="TITLE">%1$s</xliff:g>"</string>
+ <!-- no translation found for gesture_tutorial_title (2750751261768388354) -->
+ <skip />
<string name="gesture_tutorial_rotation_prompt_title" msgid="7537946781362766964">"Павярніце прыладу"</string>
<string name="gesture_tutorial_rotation_prompt" msgid="1664493449851960691">"Каб пачаць азнаямленне з дапаможнікам па навігацыі жэстамі, павярніце прыладу"</string>
<string name="back_gesture_feedback_swipe_too_far_from_edge" msgid="4175100312909721217">"Правядзіце пальцам справа налева ці злева направа ад самага краю экрана"</string>
@@ -152,4 +154,7 @@
<string name="bubble_bar_accessibility_announce_expand" msgid="1503192695527477102">"<xliff:g id="BUBBLE_DESCRIPTION">%1$s</xliff:g>: разгарнуць"</string>
<string name="bubble_bar_accessibility_announce_collapse" msgid="928284600086798791">"<xliff:g id="BUBBLE_DESCRIPTION">%1$s</xliff:g>: згарнуць"</string>
<string name="search_gesture_feature_title" msgid="1294044108313175306">"Абвесці для пошуку"</string>
+ <string name="header_app_icon_description" msgid="2184625881433608027">"Значок праграмы"</string>
+ <string name="header_default_app_title" msgid="8308052350689531566">"Назва праграмы"</string>
+ <string name="header_close_icon_description" msgid="5400033616675911319">"Кнопка \"Закрыць\""</string>
</resources>
diff --git a/quickstep/res/values-bg/strings.xml b/quickstep/res/values-bg/strings.xml
index 12339d6..660d816 100644
--- a/quickstep/res/values-bg/strings.xml
+++ b/quickstep/res/values-bg/strings.xml
@@ -46,6 +46,8 @@
<string name="hotsaet_tip_prediction_enabled" msgid="2233554377501347650">"Предложенията за приложения са активирани"</string>
<string name="hotsaet_tip_prediction_disabled" msgid="1506426298884658491">"Функцията „Предложения за приложения“ е деактивирана"</string>
<string name="hotseat_prediction_content_description" msgid="4582028296938078419">"Предвидено приложение: <xliff:g id="TITLE">%1$s</xliff:g>"</string>
+ <!-- no translation found for gesture_tutorial_title (2750751261768388354) -->
+ <skip />
<string name="gesture_tutorial_rotation_prompt_title" msgid="7537946781362766964">"Завъртете устройството си"</string>
<string name="gesture_tutorial_rotation_prompt" msgid="1664493449851960691">"Моля, завъртете устройството си, за да завършите урока за навигиране с жестове"</string>
<string name="back_gesture_feedback_swipe_too_far_from_edge" msgid="4175100312909721217">"Трябва да плъзнете пръст от най-дясната или най-лявата част на екрана"</string>
@@ -152,4 +154,7 @@
<string name="bubble_bar_accessibility_announce_expand" msgid="1503192695527477102">"разгъване на <xliff:g id="BUBBLE_DESCRIPTION">%1$s</xliff:g>"</string>
<string name="bubble_bar_accessibility_announce_collapse" msgid="928284600086798791">"свиване на <xliff:g id="BUBBLE_DESCRIPTION">%1$s</xliff:g>"</string>
<string name="search_gesture_feature_title" msgid="1294044108313175306">"Търсене с ограждане"</string>
+ <string name="header_app_icon_description" msgid="2184625881433608027">"Икона на приложението"</string>
+ <string name="header_default_app_title" msgid="8308052350689531566">"Име на приложението"</string>
+ <string name="header_close_icon_description" msgid="5400033616675911319">"Бутон за затваряне"</string>
</resources>
diff --git a/quickstep/res/values-bn/strings.xml b/quickstep/res/values-bn/strings.xml
index 70cd5d1..b5b0a5e 100644
--- a/quickstep/res/values-bn/strings.xml
+++ b/quickstep/res/values-bn/strings.xml
@@ -46,6 +46,8 @@
<string name="hotsaet_tip_prediction_enabled" msgid="2233554377501347650">"অ্যাপ সাজেশন চালু করা আছে"</string>
<string name="hotsaet_tip_prediction_disabled" msgid="1506426298884658491">"অ্যাপ সাজেশন বন্ধ করা আছে"</string>
<string name="hotseat_prediction_content_description" msgid="4582028296938078419">"আপনার প্রয়োজন হতে পারে এমন অ্যাপ: <xliff:g id="TITLE">%1$s</xliff:g>"</string>
+ <!-- no translation found for gesture_tutorial_title (2750751261768388354) -->
+ <skip />
<string name="gesture_tutorial_rotation_prompt_title" msgid="7537946781362766964">"আপনার ডিভাইস ঘোরান"</string>
<string name="gesture_tutorial_rotation_prompt" msgid="1664493449851960691">"জেসচার নেভিগেশন টিউটোরিয়াল সম্পূর্ণ করতে আপনার ডিভাইসটি ঘোরান"</string>
<string name="back_gesture_feedback_swipe_too_far_from_edge" msgid="4175100312909721217">"স্ক্রিনের একেবারে ডান বা বাঁদিকের প্রান্ত থেকে সোয়াইপ করেছেন কিনা তা দেখে নিন"</string>
@@ -152,4 +154,7 @@
<string name="bubble_bar_accessibility_announce_expand" msgid="1503192695527477102">"<xliff:g id="BUBBLE_DESCRIPTION">%1$s</xliff:g> বড় করুন"</string>
<string name="bubble_bar_accessibility_announce_collapse" msgid="928284600086798791">"<xliff:g id="BUBBLE_DESCRIPTION">%1$s</xliff:g> আড়াল করুন"</string>
<string name="search_gesture_feature_title" msgid="1294044108313175306">"খোঁজার জন্য সার্কেল বানান"</string>
+ <string name="header_app_icon_description" msgid="2184625881433608027">"অ্যাপ আইকন"</string>
+ <string name="header_default_app_title" msgid="8308052350689531566">"অ্যাপের শিরোনাম"</string>
+ <string name="header_close_icon_description" msgid="5400033616675911319">"বন্ধ করার বোতাম"</string>
</resources>
diff --git a/quickstep/res/values-bs/strings.xml b/quickstep/res/values-bs/strings.xml
index 430dd9d..69a5cdb 100644
--- a/quickstep/res/values-bs/strings.xml
+++ b/quickstep/res/values-bs/strings.xml
@@ -46,6 +46,8 @@
<string name="hotsaet_tip_prediction_enabled" msgid="2233554377501347650">"Prijedlozi aplikacija su omogućeni"</string>
<string name="hotsaet_tip_prediction_disabled" msgid="1506426298884658491">"Prijedlozi aplikacija su onemogućeni"</string>
<string name="hotseat_prediction_content_description" msgid="4582028296938078419">"Predviđena aplikacija: <xliff:g id="TITLE">%1$s</xliff:g>"</string>
+ <!-- no translation found for gesture_tutorial_title (2750751261768388354) -->
+ <skip />
<string name="gesture_tutorial_rotation_prompt_title" msgid="7537946781362766964">"Rotirajte uređaj"</string>
<string name="gesture_tutorial_rotation_prompt" msgid="1664493449851960691">"Rotirajte uređaj da završite vodič za navigaciju pokretima"</string>
<string name="back_gesture_feedback_swipe_too_far_from_edge" msgid="4175100312909721217">"Prevucite s krajnjeg desnog ili lijevog ruba"</string>
@@ -152,4 +154,7 @@
<string name="bubble_bar_accessibility_announce_expand" msgid="1503192695527477102">"proširivanje oblačića <xliff:g id="BUBBLE_DESCRIPTION">%1$s</xliff:g>"</string>
<string name="bubble_bar_accessibility_announce_collapse" msgid="928284600086798791">"sužavanje oblačića <xliff:g id="BUBBLE_DESCRIPTION">%1$s</xliff:g>"</string>
<string name="search_gesture_feature_title" msgid="1294044108313175306">"Pretraživanje zaokruživanjem"</string>
+ <string name="header_app_icon_description" msgid="2184625881433608027">"Ikona aplikacije"</string>
+ <string name="header_default_app_title" msgid="8308052350689531566">"Naslov aplikacije"</string>
+ <string name="header_close_icon_description" msgid="5400033616675911319">"Dugme za zatvaranje"</string>
</resources>
diff --git a/quickstep/res/values-ca/strings.xml b/quickstep/res/values-ca/strings.xml
index 5226ddc..cc643a6 100644
--- a/quickstep/res/values-ca/strings.xml
+++ b/quickstep/res/values-ca/strings.xml
@@ -46,6 +46,8 @@
<string name="hotsaet_tip_prediction_enabled" msgid="2233554377501347650">"Els suggeriments d\'aplicacions estan activats"</string>
<string name="hotsaet_tip_prediction_disabled" msgid="1506426298884658491">"Els suggeriments d\'aplicacions estan desactivats"</string>
<string name="hotseat_prediction_content_description" msgid="4582028296938078419">"Predicció d\'aplicació: <xliff:g id="TITLE">%1$s</xliff:g>"</string>
+ <!-- no translation found for gesture_tutorial_title (2750751261768388354) -->
+ <skip />
<string name="gesture_tutorial_rotation_prompt_title" msgid="7537946781362766964">"Gira el dispositiu"</string>
<string name="gesture_tutorial_rotation_prompt" msgid="1664493449851960691">"Gira el dispositiu per completar el tutorial de navegació amb gestos"</string>
<string name="back_gesture_feedback_swipe_too_far_from_edge" msgid="4175100312909721217">"Assegura\'t de lliscar des de l\'extrem dret o esquerre de la pantalla."</string>
@@ -152,4 +154,7 @@
<string name="bubble_bar_accessibility_announce_expand" msgid="1503192695527477102">"desplega <xliff:g id="BUBBLE_DESCRIPTION">%1$s</xliff:g>"</string>
<string name="bubble_bar_accessibility_announce_collapse" msgid="928284600086798791">"replega <xliff:g id="BUBBLE_DESCRIPTION">%1$s</xliff:g>"</string>
<string name="search_gesture_feature_title" msgid="1294044108313175306">"Encercla per cercar"</string>
+ <string name="header_app_icon_description" msgid="2184625881433608027">"Icona de l\'aplicació"</string>
+ <string name="header_default_app_title" msgid="8308052350689531566">"Títol de l\'aplicació"</string>
+ <string name="header_close_icon_description" msgid="5400033616675911319">"Botó Tanca"</string>
</resources>
diff --git a/quickstep/res/values-cs/strings.xml b/quickstep/res/values-cs/strings.xml
index a381ac6..eb0e8c8 100644
--- a/quickstep/res/values-cs/strings.xml
+++ b/quickstep/res/values-cs/strings.xml
@@ -46,6 +46,8 @@
<string name="hotsaet_tip_prediction_enabled" msgid="2233554377501347650">"Návrhy aplikací jsou povoleny"</string>
<string name="hotsaet_tip_prediction_disabled" msgid="1506426298884658491">"Návrhy aplikací jsou zakázány"</string>
<string name="hotseat_prediction_content_description" msgid="4582028296938078419">"Předpokládaná aplikace: <xliff:g id="TITLE">%1$s</xliff:g>"</string>
+ <!-- no translation found for gesture_tutorial_title (2750751261768388354) -->
+ <skip />
<string name="gesture_tutorial_rotation_prompt_title" msgid="7537946781362766964">"Otočte zařízení"</string>
<string name="gesture_tutorial_rotation_prompt" msgid="1664493449851960691">"Pokud chcete dokončit výukový program navigace gesty, otočte zařízení"</string>
<string name="back_gesture_feedback_swipe_too_far_from_edge" msgid="4175100312909721217">"Přejeďte prstem z úplného pravého nebo levého okraje obrazovky"</string>
@@ -134,7 +136,7 @@
<string name="taskbar_a11y_hidden_with_bubbles_title" msgid="7397395993149508087">"Panel a bubliny jsou skryty"</string>
<string name="taskbar_phone_a11y_title" msgid="4933360237131229395">"Navigační panel"</string>
<string name="always_show_taskbar" msgid="3608801276107751229">"Vždy zobrazovat panel aplikací"</string>
- <string name="change_navigation_mode" msgid="9088393078736808968">"Změnit režim navigace"</string>
+ <string name="change_navigation_mode" msgid="9088393078736808968">"Změnit navigační režim"</string>
<string name="taskbar_divider_a11y_title" msgid="6608690309720242080">"Rozdělovač panelu aplikací"</string>
<string name="taskbar_overflow_a11y_title" msgid="7960342079198820179">"Přetečení panelu aplikací"</string>
<string name="move_drop_target_top_or_left" msgid="2988702185049595807">"Přesunout doleva nahoru"</string>
@@ -152,4 +154,7 @@
<string name="bubble_bar_accessibility_announce_expand" msgid="1503192695527477102">"rozbalit <xliff:g id="BUBBLE_DESCRIPTION">%1$s</xliff:g>"</string>
<string name="bubble_bar_accessibility_announce_collapse" msgid="928284600086798791">"sbalit <xliff:g id="BUBBLE_DESCRIPTION">%1$s</xliff:g>"</string>
<string name="search_gesture_feature_title" msgid="1294044108313175306">"Zakroužkuj a hledej"</string>
+ <string name="header_app_icon_description" msgid="2184625881433608027">"Ikona aplikace"</string>
+ <string name="header_default_app_title" msgid="8308052350689531566">"Název aplikace"</string>
+ <string name="header_close_icon_description" msgid="5400033616675911319">"Tlačítko Zavřít"</string>
</resources>
diff --git a/quickstep/res/values-da/strings.xml b/quickstep/res/values-da/strings.xml
index fbe81f7..a7b7d04 100644
--- a/quickstep/res/values-da/strings.xml
+++ b/quickstep/res/values-da/strings.xml
@@ -23,7 +23,7 @@
<string name="recent_task_option_freeform" msgid="48863056265284071">"Frit format"</string>
<string name="recent_task_option_desktop" msgid="8280879717125435668">"Computertilstand"</string>
<string name="recent_task_option_external_display" msgid="4533840664313389484">"Flyt til ekstern skærm"</string>
- <string name="recent_task_desktop" msgid="8081113562549637334">"Computer"</string>
+ <string name="recent_task_desktop" msgid="8081113562549637334">"Computertilstand"</string>
<string name="recents_empty_message" msgid="7040467240571714191">"Ingen nye elementer"</string>
<string name="accessibility_app_usage_settings" msgid="6312864233673544149">"Indstillinger for appforbrug"</string>
<string name="recents_clear_all" msgid="5328176793634888831">"Ryd alt"</string>
@@ -46,6 +46,8 @@
<string name="hotsaet_tip_prediction_enabled" msgid="2233554377501347650">"Appforslag er aktiveret"</string>
<string name="hotsaet_tip_prediction_disabled" msgid="1506426298884658491">"Appforslag er deaktiveret"</string>
<string name="hotseat_prediction_content_description" msgid="4582028296938078419">"App, du forventes at skulle bruge: <xliff:g id="TITLE">%1$s</xliff:g>"</string>
+ <!-- no translation found for gesture_tutorial_title (2750751261768388354) -->
+ <skip />
<string name="gesture_tutorial_rotation_prompt_title" msgid="7537946781362766964">"Rotér din enhed"</string>
<string name="gesture_tutorial_rotation_prompt" msgid="1664493449851960691">"Rotér enheden for at gennemgå vejledningen i navigation med bevægelser"</string>
<string name="back_gesture_feedback_swipe_too_far_from_edge" msgid="4175100312909721217">"Stryg fra kanten yderst til højre eller venstre"</string>
@@ -140,7 +142,7 @@
<string name="move_drop_target_top_or_left" msgid="2988702185049595807">"Flyt til toppen eller venstre side"</string>
<string name="move_drop_target_bottom_or_right" msgid="5431393418797620162">"Flyt til bunden eller højre side"</string>
<string name="quick_switch_overflow" msgid="3679780650881041632">"{count,plural, =1{yderligere app}one{yderligere app}other{yderligere apps}}"</string>
- <string name="quick_switch_desktop" msgid="8393802056024499749">"Computer"</string>
+ <string name="quick_switch_desktop" msgid="8393802056024499749">"Computertilstand"</string>
<string name="quick_switch_split_task" msgid="5598194724255333896">"<xliff:g id="APP_NAME_1">%1$s</xliff:g> og <xliff:g id="APP_NAME_2">%2$s</xliff:g>"</string>
<string name="bubble_bar_bubble_fallback_description" msgid="7811684548953452009">"Boble"</string>
<string name="bubble_bar_overflow_description" msgid="8617628132733151708">"Overløb"</string>
@@ -152,4 +154,7 @@
<string name="bubble_bar_accessibility_announce_expand" msgid="1503192695527477102">"udvid <xliff:g id="BUBBLE_DESCRIPTION">%1$s</xliff:g>"</string>
<string name="bubble_bar_accessibility_announce_collapse" msgid="928284600086798791">"skjul <xliff:g id="BUBBLE_DESCRIPTION">%1$s</xliff:g>"</string>
<string name="search_gesture_feature_title" msgid="1294044108313175306">"Circle to Search"</string>
+ <string name="header_app_icon_description" msgid="2184625881433608027">"Appikon"</string>
+ <string name="header_default_app_title" msgid="8308052350689531566">"Apptitel"</string>
+ <string name="header_close_icon_description" msgid="5400033616675911319">"Knappen Luk"</string>
</resources>
diff --git a/quickstep/res/values-de/strings.xml b/quickstep/res/values-de/strings.xml
index 30f2cfb..dd7b467 100644
--- a/quickstep/res/values-de/strings.xml
+++ b/quickstep/res/values-de/strings.xml
@@ -46,6 +46,8 @@
<string name="hotsaet_tip_prediction_enabled" msgid="2233554377501347650">"Funktion „App-Vorschläge“ aktiviert"</string>
<string name="hotsaet_tip_prediction_disabled" msgid="1506426298884658491">"Funktion \"App-Vorschläge\" deaktiviert"</string>
<string name="hotseat_prediction_content_description" msgid="4582028296938078419">"Vorgeschlagene App: <xliff:g id="TITLE">%1$s</xliff:g>"</string>
+ <!-- no translation found for gesture_tutorial_title (2750751261768388354) -->
+ <skip />
<string name="gesture_tutorial_rotation_prompt_title" msgid="7537946781362766964">"Gerät drehen"</string>
<string name="gesture_tutorial_rotation_prompt" msgid="1664493449851960691">"Bitte drehe dein Gerät, um die Anleitung für die Bedienung über Gesten abzuschließen"</string>
<string name="back_gesture_feedback_swipe_too_far_from_edge" msgid="4175100312909721217">"Wische vom äußersten rechten oder linken Displayrand"</string>
@@ -152,4 +154,7 @@
<string name="bubble_bar_accessibility_announce_expand" msgid="1503192695527477102">"„<xliff:g id="BUBBLE_DESCRIPTION">%1$s</xliff:g>“ maximieren"</string>
<string name="bubble_bar_accessibility_announce_collapse" msgid="928284600086798791">"„<xliff:g id="BUBBLE_DESCRIPTION">%1$s</xliff:g>“ minimieren"</string>
<string name="search_gesture_feature_title" msgid="1294044108313175306">"Circle to Search"</string>
+ <string name="header_app_icon_description" msgid="2184625881433608027">"App-Symbol"</string>
+ <string name="header_default_app_title" msgid="8308052350689531566">"Titel der App"</string>
+ <string name="header_close_icon_description" msgid="5400033616675911319">"Schaltfläche „Schließen“"</string>
</resources>
diff --git a/quickstep/res/values-el/strings.xml b/quickstep/res/values-el/strings.xml
index ecd8604..058d7ba 100644
--- a/quickstep/res/values-el/strings.xml
+++ b/quickstep/res/values-el/strings.xml
@@ -46,6 +46,8 @@
<string name="hotsaet_tip_prediction_enabled" msgid="2233554377501347650">"Οι προτεινόμενες εφαρμογές ενεργοποιήθηκαν"</string>
<string name="hotsaet_tip_prediction_disabled" msgid="1506426298884658491">"Οι προτεινόμενες εφαρμογές είναι απενεργοποιημένες"</string>
<string name="hotseat_prediction_content_description" msgid="4582028296938078419">"Εφαρμογή από πρόβλεψη: <xliff:g id="TITLE">%1$s</xliff:g>"</string>
+ <!-- no translation found for gesture_tutorial_title (2750751261768388354) -->
+ <skip />
<string name="gesture_tutorial_rotation_prompt_title" msgid="7537946781362766964">"Περιστρέψτε τη συσκευή σας"</string>
<string name="gesture_tutorial_rotation_prompt" msgid="1664493449851960691">"Περιστρέψτε τη συσκευή σας για να ολοκληρώσετε τον οδηγό πλοήγησης με κινήσεις"</string>
<string name="back_gesture_feedback_swipe_too_far_from_edge" msgid="4175100312909721217">"Φροντίστε να σύρετε από το άκρο της δεξιάς ή της αριστερής πλευράς."</string>
@@ -152,4 +154,7 @@
<string name="bubble_bar_accessibility_announce_expand" msgid="1503192695527477102">"ανάπτυξη <xliff:g id="BUBBLE_DESCRIPTION">%1$s</xliff:g>"</string>
<string name="bubble_bar_accessibility_announce_collapse" msgid="928284600086798791">"σύμπτυξη <xliff:g id="BUBBLE_DESCRIPTION">%1$s</xliff:g>"</string>
<string name="search_gesture_feature_title" msgid="1294044108313175306">"Κυκλώστε για αναζήτηση"</string>
+ <string name="header_app_icon_description" msgid="2184625881433608027">"Εικονίδιο εφαρμογής"</string>
+ <string name="header_default_app_title" msgid="8308052350689531566">"Τίτλος εφαρμογής"</string>
+ <string name="header_close_icon_description" msgid="5400033616675911319">"Κουμπί κλεισίματος"</string>
</resources>
diff --git a/quickstep/res/values-en-rAU/strings.xml b/quickstep/res/values-en-rAU/strings.xml
index a799d0a..506e36d 100644
--- a/quickstep/res/values-en-rAU/strings.xml
+++ b/quickstep/res/values-en-rAU/strings.xml
@@ -46,6 +46,8 @@
<string name="hotsaet_tip_prediction_enabled" msgid="2233554377501347650">"App suggestions enabled"</string>
<string name="hotsaet_tip_prediction_disabled" msgid="1506426298884658491">"App suggestions are disabled"</string>
<string name="hotseat_prediction_content_description" msgid="4582028296938078419">"Predicted app: <xliff:g id="TITLE">%1$s</xliff:g>"</string>
+ <!-- no translation found for gesture_tutorial_title (2750751261768388354) -->
+ <skip />
<string name="gesture_tutorial_rotation_prompt_title" msgid="7537946781362766964">"Rotate your device"</string>
<string name="gesture_tutorial_rotation_prompt" msgid="1664493449851960691">"Please rotate your device to complete the gesture navigation tutorial"</string>
<string name="back_gesture_feedback_swipe_too_far_from_edge" msgid="4175100312909721217">"Make sure you swipe from the far-right or far-left edge"</string>
@@ -152,4 +154,7 @@
<string name="bubble_bar_accessibility_announce_expand" msgid="1503192695527477102">"expand <xliff:g id="BUBBLE_DESCRIPTION">%1$s</xliff:g>"</string>
<string name="bubble_bar_accessibility_announce_collapse" msgid="928284600086798791">"collapse <xliff:g id="BUBBLE_DESCRIPTION">%1$s</xliff:g>"</string>
<string name="search_gesture_feature_title" msgid="1294044108313175306">"Circle to Search"</string>
+ <string name="header_app_icon_description" msgid="2184625881433608027">"App icon"</string>
+ <string name="header_default_app_title" msgid="8308052350689531566">"App title"</string>
+ <string name="header_close_icon_description" msgid="5400033616675911319">"Close button"</string>
</resources>
diff --git a/quickstep/res/values-en-rCA/strings.xml b/quickstep/res/values-en-rCA/strings.xml
index 3528cd6..f91f4ee 100644
--- a/quickstep/res/values-en-rCA/strings.xml
+++ b/quickstep/res/values-en-rCA/strings.xml
@@ -46,6 +46,8 @@
<string name="hotsaet_tip_prediction_enabled" msgid="2233554377501347650">"App suggestions enabled"</string>
<string name="hotsaet_tip_prediction_disabled" msgid="1506426298884658491">"App suggestions are disabled"</string>
<string name="hotseat_prediction_content_description" msgid="4582028296938078419">"Predicted app: <xliff:g id="TITLE">%1$s</xliff:g>"</string>
+ <!-- no translation found for gesture_tutorial_title (2750751261768388354) -->
+ <skip />
<string name="gesture_tutorial_rotation_prompt_title" msgid="7537946781362766964">"Rotate your device"</string>
<string name="gesture_tutorial_rotation_prompt" msgid="1664493449851960691">"Please rotate your device to complete the gesture navigation tutorial"</string>
<string name="back_gesture_feedback_swipe_too_far_from_edge" msgid="4175100312909721217">"Make sure you swipe from the far-right or far-left edge"</string>
@@ -152,4 +154,7 @@
<string name="bubble_bar_accessibility_announce_expand" msgid="1503192695527477102">"expand <xliff:g id="BUBBLE_DESCRIPTION">%1$s</xliff:g>"</string>
<string name="bubble_bar_accessibility_announce_collapse" msgid="928284600086798791">"collapse <xliff:g id="BUBBLE_DESCRIPTION">%1$s</xliff:g>"</string>
<string name="search_gesture_feature_title" msgid="1294044108313175306">"Circle to Search"</string>
+ <string name="header_app_icon_description" msgid="2184625881433608027">"App icon"</string>
+ <string name="header_default_app_title" msgid="8308052350689531566">"App title"</string>
+ <string name="header_close_icon_description" msgid="5400033616675911319">"Close button"</string>
</resources>
diff --git a/quickstep/res/values-en-rGB/strings.xml b/quickstep/res/values-en-rGB/strings.xml
index a799d0a..506e36d 100644
--- a/quickstep/res/values-en-rGB/strings.xml
+++ b/quickstep/res/values-en-rGB/strings.xml
@@ -46,6 +46,8 @@
<string name="hotsaet_tip_prediction_enabled" msgid="2233554377501347650">"App suggestions enabled"</string>
<string name="hotsaet_tip_prediction_disabled" msgid="1506426298884658491">"App suggestions are disabled"</string>
<string name="hotseat_prediction_content_description" msgid="4582028296938078419">"Predicted app: <xliff:g id="TITLE">%1$s</xliff:g>"</string>
+ <!-- no translation found for gesture_tutorial_title (2750751261768388354) -->
+ <skip />
<string name="gesture_tutorial_rotation_prompt_title" msgid="7537946781362766964">"Rotate your device"</string>
<string name="gesture_tutorial_rotation_prompt" msgid="1664493449851960691">"Please rotate your device to complete the gesture navigation tutorial"</string>
<string name="back_gesture_feedback_swipe_too_far_from_edge" msgid="4175100312909721217">"Make sure you swipe from the far-right or far-left edge"</string>
@@ -152,4 +154,7 @@
<string name="bubble_bar_accessibility_announce_expand" msgid="1503192695527477102">"expand <xliff:g id="BUBBLE_DESCRIPTION">%1$s</xliff:g>"</string>
<string name="bubble_bar_accessibility_announce_collapse" msgid="928284600086798791">"collapse <xliff:g id="BUBBLE_DESCRIPTION">%1$s</xliff:g>"</string>
<string name="search_gesture_feature_title" msgid="1294044108313175306">"Circle to Search"</string>
+ <string name="header_app_icon_description" msgid="2184625881433608027">"App icon"</string>
+ <string name="header_default_app_title" msgid="8308052350689531566">"App title"</string>
+ <string name="header_close_icon_description" msgid="5400033616675911319">"Close button"</string>
</resources>
diff --git a/quickstep/res/values-en-rIN/strings.xml b/quickstep/res/values-en-rIN/strings.xml
index a799d0a..506e36d 100644
--- a/quickstep/res/values-en-rIN/strings.xml
+++ b/quickstep/res/values-en-rIN/strings.xml
@@ -46,6 +46,8 @@
<string name="hotsaet_tip_prediction_enabled" msgid="2233554377501347650">"App suggestions enabled"</string>
<string name="hotsaet_tip_prediction_disabled" msgid="1506426298884658491">"App suggestions are disabled"</string>
<string name="hotseat_prediction_content_description" msgid="4582028296938078419">"Predicted app: <xliff:g id="TITLE">%1$s</xliff:g>"</string>
+ <!-- no translation found for gesture_tutorial_title (2750751261768388354) -->
+ <skip />
<string name="gesture_tutorial_rotation_prompt_title" msgid="7537946781362766964">"Rotate your device"</string>
<string name="gesture_tutorial_rotation_prompt" msgid="1664493449851960691">"Please rotate your device to complete the gesture navigation tutorial"</string>
<string name="back_gesture_feedback_swipe_too_far_from_edge" msgid="4175100312909721217">"Make sure you swipe from the far-right or far-left edge"</string>
@@ -152,4 +154,7 @@
<string name="bubble_bar_accessibility_announce_expand" msgid="1503192695527477102">"expand <xliff:g id="BUBBLE_DESCRIPTION">%1$s</xliff:g>"</string>
<string name="bubble_bar_accessibility_announce_collapse" msgid="928284600086798791">"collapse <xliff:g id="BUBBLE_DESCRIPTION">%1$s</xliff:g>"</string>
<string name="search_gesture_feature_title" msgid="1294044108313175306">"Circle to Search"</string>
+ <string name="header_app_icon_description" msgid="2184625881433608027">"App icon"</string>
+ <string name="header_default_app_title" msgid="8308052350689531566">"App title"</string>
+ <string name="header_close_icon_description" msgid="5400033616675911319">"Close button"</string>
</resources>
diff --git a/quickstep/res/values-es-rUS/strings.xml b/quickstep/res/values-es-rUS/strings.xml
index f51cdea..dd969d7 100644
--- a/quickstep/res/values-es-rUS/strings.xml
+++ b/quickstep/res/values-es-rUS/strings.xml
@@ -46,6 +46,8 @@
<string name="hotsaet_tip_prediction_enabled" msgid="2233554377501347650">"Sugerencias de apps habilitadas"</string>
<string name="hotsaet_tip_prediction_disabled" msgid="1506426298884658491">"Las sugerencias de aplicaciones están inhabilitadas"</string>
<string name="hotseat_prediction_content_description" msgid="4582028296938078419">"Predicción de app: <xliff:g id="TITLE">%1$s</xliff:g>"</string>
+ <!-- no translation found for gesture_tutorial_title (2750751261768388354) -->
+ <skip />
<string name="gesture_tutorial_rotation_prompt_title" msgid="7537946781362766964">"Rota el dispositivo"</string>
<string name="gesture_tutorial_rotation_prompt" msgid="1664493449851960691">"Rota el dispositivo para completar el instructivo de la navegación por gestos"</string>
<string name="back_gesture_feedback_swipe_too_far_from_edge" msgid="4175100312909721217">"Asegúrate de deslizar desde el extremo derecho o izquierdo"</string>
@@ -152,4 +154,7 @@
<string name="bubble_bar_accessibility_announce_expand" msgid="1503192695527477102">"expandir <xliff:g id="BUBBLE_DESCRIPTION">%1$s</xliff:g>"</string>
<string name="bubble_bar_accessibility_announce_collapse" msgid="928284600086798791">"contraer <xliff:g id="BUBBLE_DESCRIPTION">%1$s</xliff:g>"</string>
<string name="search_gesture_feature_title" msgid="1294044108313175306">"Busca con un círculo"</string>
+ <string name="header_app_icon_description" msgid="2184625881433608027">"Ícono de la app"</string>
+ <string name="header_default_app_title" msgid="8308052350689531566">"Título de la app"</string>
+ <string name="header_close_icon_description" msgid="5400033616675911319">"Botón de cerrar"</string>
</resources>
diff --git a/quickstep/res/values-es/strings.xml b/quickstep/res/values-es/strings.xml
index 06c2d50..1da35e6 100644
--- a/quickstep/res/values-es/strings.xml
+++ b/quickstep/res/values-es/strings.xml
@@ -46,6 +46,8 @@
<string name="hotsaet_tip_prediction_enabled" msgid="2233554377501347650">"Sugerencias de aplicaciones habilitadas"</string>
<string name="hotsaet_tip_prediction_disabled" msgid="1506426298884658491">"Las sugerencias de aplicaciones están inhabilitadas"</string>
<string name="hotseat_prediction_content_description" msgid="4582028296938078419">"Aplicación sugerida: <xliff:g id="TITLE">%1$s</xliff:g>"</string>
+ <!-- no translation found for gesture_tutorial_title (2750751261768388354) -->
+ <skip />
<string name="gesture_tutorial_rotation_prompt_title" msgid="7537946781362766964">"Gira el dispositivo"</string>
<string name="gesture_tutorial_rotation_prompt" msgid="1664493449851960691">"Gira el dispositivo para completar el tutorial de navegación por gestos"</string>
<string name="back_gesture_feedback_swipe_too_far_from_edge" msgid="4175100312909721217">"Asegúrate de deslizar desde el borde derecho o izquierdo de la pantalla"</string>
@@ -139,7 +141,7 @@
<string name="taskbar_overflow_a11y_title" msgid="7960342079198820179">"Barra de tareas ampliada"</string>
<string name="move_drop_target_top_or_left" msgid="2988702185049595807">"Mover arriba/a la izquierda"</string>
<string name="move_drop_target_bottom_or_right" msgid="5431393418797620162">"Mover abajo/a la derecha"</string>
- <string name="quick_switch_overflow" msgid="3679780650881041632">"{count,plural, =1{aplicación más}other{aplicaciones más}}"</string>
+ <string name="quick_switch_overflow" msgid="3679780650881041632">"{count,plural, =1{app más}other{apps más}}"</string>
<string name="quick_switch_desktop" msgid="8393802056024499749">"Ordenador"</string>
<string name="quick_switch_split_task" msgid="5598194724255333896">"<xliff:g id="APP_NAME_1">%1$s</xliff:g> y <xliff:g id="APP_NAME_2">%2$s</xliff:g>"</string>
<string name="bubble_bar_bubble_fallback_description" msgid="7811684548953452009">"Burbuja"</string>
@@ -152,4 +154,7 @@
<string name="bubble_bar_accessibility_announce_expand" msgid="1503192695527477102">"desplegar <xliff:g id="BUBBLE_DESCRIPTION">%1$s</xliff:g>"</string>
<string name="bubble_bar_accessibility_announce_collapse" msgid="928284600086798791">"contraer <xliff:g id="BUBBLE_DESCRIPTION">%1$s</xliff:g>"</string>
<string name="search_gesture_feature_title" msgid="1294044108313175306">"Rodea para buscar"</string>
+ <string name="header_app_icon_description" msgid="2184625881433608027">"Icono de la aplicación"</string>
+ <string name="header_default_app_title" msgid="8308052350689531566">"Título de la aplicación"</string>
+ <string name="header_close_icon_description" msgid="5400033616675911319">"Botón de cerrar"</string>
</resources>
diff --git a/quickstep/res/values-et/strings.xml b/quickstep/res/values-et/strings.xml
index d394c2a..70acc52 100644
--- a/quickstep/res/values-et/strings.xml
+++ b/quickstep/res/values-et/strings.xml
@@ -46,6 +46,8 @@
<string name="hotsaet_tip_prediction_enabled" msgid="2233554377501347650">"Rakenduste soovitused on lubatud"</string>
<string name="hotsaet_tip_prediction_disabled" msgid="1506426298884658491">"Rakenduste soovitused on keelatud"</string>
<string name="hotseat_prediction_content_description" msgid="4582028296938078419">"Ennustatud rakendus: <xliff:g id="TITLE">%1$s</xliff:g>"</string>
+ <!-- no translation found for gesture_tutorial_title (2750751261768388354) -->
+ <skip />
<string name="gesture_tutorial_rotation_prompt_title" msgid="7537946781362766964">"Pöörake seadet"</string>
<string name="gesture_tutorial_rotation_prompt" msgid="1664493449851960691">"Pöörake seadet, et liigutustega navigeerimise õpetused lõpetada"</string>
<string name="back_gesture_feedback_swipe_too_far_from_edge" msgid="4175100312909721217">"Pühkige kindlasti parem- või vasakpoolsest servast"</string>
@@ -152,4 +154,7 @@
<string name="bubble_bar_accessibility_announce_expand" msgid="1503192695527477102">"Toiminguriba <xliff:g id="BUBBLE_DESCRIPTION">%1$s</xliff:g> laiendamine"</string>
<string name="bubble_bar_accessibility_announce_collapse" msgid="928284600086798791">"Toiminguriba <xliff:g id="BUBBLE_DESCRIPTION">%1$s</xliff:g> ahendamine"</string>
<string name="search_gesture_feature_title" msgid="1294044108313175306">"Ring otsimiseks"</string>
+ <string name="header_app_icon_description" msgid="2184625881433608027">"Rakenduse ikoon"</string>
+ <string name="header_default_app_title" msgid="8308052350689531566">"Rakenduse pealkiri"</string>
+ <string name="header_close_icon_description" msgid="5400033616675911319">"Sulgemisnupp"</string>
</resources>
diff --git a/quickstep/res/values-eu/strings.xml b/quickstep/res/values-eu/strings.xml
index 02ea865..af5962a 100644
--- a/quickstep/res/values-eu/strings.xml
+++ b/quickstep/res/values-eu/strings.xml
@@ -46,6 +46,8 @@
<string name="hotsaet_tip_prediction_enabled" msgid="2233554377501347650">"Gaituta daude aplikazioen iradokizunak"</string>
<string name="hotsaet_tip_prediction_disabled" msgid="1506426298884658491">"Desgaituta daude aplikazioen iradokizunak"</string>
<string name="hotseat_prediction_content_description" msgid="4582028296938078419">"Iragarritako aplikazioa: <xliff:g id="TITLE">%1$s</xliff:g>"</string>
+ <!-- no translation found for gesture_tutorial_title (2750751261768388354) -->
+ <skip />
<string name="gesture_tutorial_rotation_prompt_title" msgid="7537946781362766964">"Biratu gailua"</string>
<string name="gesture_tutorial_rotation_prompt" msgid="1664493449851960691">"Keinu bidezko nabigazioaren tutoriala osatzeko, biratu gailua"</string>
<string name="back_gesture_feedback_swipe_too_far_from_edge" msgid="4175100312909721217">"Ziurtatu hatza pantailaren eskuineko edo ezkerreko ertzetik hasten zarela pasatzen"</string>
@@ -152,4 +154,7 @@
<string name="bubble_bar_accessibility_announce_expand" msgid="1503192695527477102">"zabaldu <xliff:g id="BUBBLE_DESCRIPTION">%1$s</xliff:g>"</string>
<string name="bubble_bar_accessibility_announce_collapse" msgid="928284600086798791">"tolestu <xliff:g id="BUBBLE_DESCRIPTION">%1$s</xliff:g>"</string>
<string name="search_gesture_feature_title" msgid="1294044108313175306">"Inguratu bilatzeko"</string>
+ <string name="header_app_icon_description" msgid="2184625881433608027">"Aplikazioaren ikonoa"</string>
+ <string name="header_default_app_title" msgid="8308052350689531566">"Aplikazioaren izena"</string>
+ <string name="header_close_icon_description" msgid="5400033616675911319">"Ixteko botoia"</string>
</resources>
diff --git a/quickstep/res/values-fa/strings.xml b/quickstep/res/values-fa/strings.xml
index f2f58ce..40469f5 100644
--- a/quickstep/res/values-fa/strings.xml
+++ b/quickstep/res/values-fa/strings.xml
@@ -46,6 +46,8 @@
<string name="hotsaet_tip_prediction_enabled" msgid="2233554377501347650">"«پیشنهاد برنامه» فعال است"</string>
<string name="hotsaet_tip_prediction_disabled" msgid="1506426298884658491">"«پیشنهاد برنامه» غیرفعال است"</string>
<string name="hotseat_prediction_content_description" msgid="4582028296938078419">"برنامه پیشبینیشده: <xliff:g id="TITLE">%1$s</xliff:g>"</string>
+ <!-- no translation found for gesture_tutorial_title (2750751261768388354) -->
+ <skip />
<string name="gesture_tutorial_rotation_prompt_title" msgid="7537946781362766964">"دستگاهتان را بچرخانید"</string>
<string name="gesture_tutorial_rotation_prompt" msgid="1664493449851960691">"لطفاً برای تکمیل آموزش گامبهگام پیمایش اشارهای، دستگاهتان را بچرخانید"</string>
<string name="back_gesture_feedback_swipe_too_far_from_edge" msgid="4175100312909721217">"دقت کنید که از انتهای لبه سمت راست یا سمت چپ تند بکشید"</string>
@@ -152,4 +154,7 @@
<string name="bubble_bar_accessibility_announce_expand" msgid="1503192695527477102">"ازهم باز کردن <xliff:g id="BUBBLE_DESCRIPTION">%1$s</xliff:g>"</string>
<string name="bubble_bar_accessibility_announce_collapse" msgid="928284600086798791">"جمع کردن <xliff:g id="BUBBLE_DESCRIPTION">%1$s</xliff:g>"</string>
<string name="search_gesture_feature_title" msgid="1294044108313175306">"حلقه جستجو"</string>
+ <string name="header_app_icon_description" msgid="2184625881433608027">"نماد برنامه"</string>
+ <string name="header_default_app_title" msgid="8308052350689531566">"عنوان برنامه"</string>
+ <string name="header_close_icon_description" msgid="5400033616675911319">"دکمه بستن"</string>
</resources>
diff --git a/quickstep/res/values-fi/strings.xml b/quickstep/res/values-fi/strings.xml
index d5540f4..6907e49 100644
--- a/quickstep/res/values-fi/strings.xml
+++ b/quickstep/res/values-fi/strings.xml
@@ -46,6 +46,8 @@
<string name="hotsaet_tip_prediction_enabled" msgid="2233554377501347650">"Sovellusehdotukset käytössä"</string>
<string name="hotsaet_tip_prediction_disabled" msgid="1506426298884658491">"Sovellusehdotukset on poistettu käytöstä"</string>
<string name="hotseat_prediction_content_description" msgid="4582028296938078419">"Ennakoitu sovellus: <xliff:g id="TITLE">%1$s</xliff:g>"</string>
+ <!-- no translation found for gesture_tutorial_title (2750751261768388354) -->
+ <skip />
<string name="gesture_tutorial_rotation_prompt_title" msgid="7537946781362766964">"Käännä laite"</string>
<string name="gesture_tutorial_rotation_prompt" msgid="1664493449851960691">"Käännä laite, niin voit katsoa esittelyn eleillä navigoinnista"</string>
<string name="back_gesture_feedback_swipe_too_far_from_edge" msgid="4175100312909721217">"Pyyhkäise aivan oikeasta tai vasemmasta reunasta"</string>
@@ -152,4 +154,7 @@
<string name="bubble_bar_accessibility_announce_expand" msgid="1503192695527477102">"laajenna <xliff:g id="BUBBLE_DESCRIPTION">%1$s</xliff:g>"</string>
<string name="bubble_bar_accessibility_announce_collapse" msgid="928284600086798791">"tiivistä <xliff:g id="BUBBLE_DESCRIPTION">%1$s</xliff:g>"</string>
<string name="search_gesture_feature_title" msgid="1294044108313175306">"Circle to Search"</string>
+ <string name="header_app_icon_description" msgid="2184625881433608027">"Sovelluskuvake"</string>
+ <string name="header_default_app_title" msgid="8308052350689531566">"Sovelluksen nimi"</string>
+ <string name="header_close_icon_description" msgid="5400033616675911319">"Sulje-painike"</string>
</resources>
diff --git a/quickstep/res/values-fr-rCA/strings.xml b/quickstep/res/values-fr-rCA/strings.xml
index c087fae..d57479d 100644
--- a/quickstep/res/values-fr-rCA/strings.xml
+++ b/quickstep/res/values-fr-rCA/strings.xml
@@ -21,9 +21,9 @@
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
<string name="recent_task_option_pin" msgid="7929860679018978258">"Épingler"</string>
<string name="recent_task_option_freeform" msgid="48863056265284071">"Forme libre"</string>
- <string name="recent_task_option_desktop" msgid="8280879717125435668">"Ordinateur de bureau"</string>
+ <string name="recent_task_option_desktop" msgid="8280879717125435668">"Bureau"</string>
<string name="recent_task_option_external_display" msgid="4533840664313389484">"Passer à un écran externe"</string>
- <string name="recent_task_desktop" msgid="8081113562549637334">"Ordinateur de bureau"</string>
+ <string name="recent_task_desktop" msgid="8081113562549637334">"Bureau"</string>
<string name="recents_empty_message" msgid="7040467240571714191">"Aucun élément récent"</string>
<string name="accessibility_app_usage_settings" msgid="6312864233673544149">"Paramètres d\'utilisation de l\'appli"</string>
<string name="recents_clear_all" msgid="5328176793634888831">"Tout effacer"</string>
@@ -46,6 +46,8 @@
<string name="hotsaet_tip_prediction_enabled" msgid="2233554377501347650">"Les suggestions d\'applis sont activées"</string>
<string name="hotsaet_tip_prediction_disabled" msgid="1506426298884658491">"Les suggestions d\'applis sont désactivées"</string>
<string name="hotseat_prediction_content_description" msgid="4582028296938078419">"Appli prédite : <xliff:g id="TITLE">%1$s</xliff:g>"</string>
+ <!-- no translation found for gesture_tutorial_title (2750751261768388354) -->
+ <skip />
<string name="gesture_tutorial_rotation_prompt_title" msgid="7537946781362766964">"Faites pivoter votre appareil"</string>
<string name="gesture_tutorial_rotation_prompt" msgid="1664493449851960691">"Veuillez faire pivoter votre appareil pour terminer le tutoriel de navigation par gestes"</string>
<string name="back_gesture_feedback_swipe_too_far_from_edge" msgid="4175100312909721217">"Assurez-vous de balayer l\'écran à partir de l\'extrémité droite ou gauche"</string>
@@ -140,7 +142,7 @@
<string name="move_drop_target_top_or_left" msgid="2988702185049595807">"Déplacer vers le coin supérieur gauche de l\'écran"</string>
<string name="move_drop_target_bottom_or_right" msgid="5431393418797620162">"Déplacer vers le coin inférieur droit de l\'écran"</string>
<string name="quick_switch_overflow" msgid="3679780650881041632">"{count,plural, =1{autre appli}one{autre appli}other{autres applis}}"</string>
- <string name="quick_switch_desktop" msgid="8393802056024499749">"Ordinateur de bureau"</string>
+ <string name="quick_switch_desktop" msgid="8393802056024499749">"Bureau"</string>
<string name="quick_switch_split_task" msgid="5598194724255333896">"<xliff:g id="APP_NAME_1">%1$s</xliff:g> et <xliff:g id="APP_NAME_2">%2$s</xliff:g>"</string>
<string name="bubble_bar_bubble_fallback_description" msgid="7811684548953452009">"Bulle"</string>
<string name="bubble_bar_overflow_description" msgid="8617628132733151708">"Bulle à développer"</string>
@@ -152,4 +154,7 @@
<string name="bubble_bar_accessibility_announce_expand" msgid="1503192695527477102">"Développer <xliff:g id="BUBBLE_DESCRIPTION">%1$s</xliff:g>"</string>
<string name="bubble_bar_accessibility_announce_collapse" msgid="928284600086798791">"Réduire <xliff:g id="BUBBLE_DESCRIPTION">%1$s</xliff:g>"</string>
<string name="search_gesture_feature_title" msgid="1294044108313175306">"Encercler et rechercher"</string>
+ <string name="header_app_icon_description" msgid="2184625881433608027">"Icône de l\'appli"</string>
+ <string name="header_default_app_title" msgid="8308052350689531566">"Nom de l\'appli"</string>
+ <string name="header_close_icon_description" msgid="5400033616675911319">"Bouton Fermer"</string>
</resources>
diff --git a/quickstep/res/values-fr/strings.xml b/quickstep/res/values-fr/strings.xml
index ddda716..b185e0c 100644
--- a/quickstep/res/values-fr/strings.xml
+++ b/quickstep/res/values-fr/strings.xml
@@ -21,9 +21,9 @@
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
<string name="recent_task_option_pin" msgid="7929860679018978258">"Épingler"</string>
<string name="recent_task_option_freeform" msgid="48863056265284071">"Format libre"</string>
- <string name="recent_task_option_desktop" msgid="8280879717125435668">"Ordinateur"</string>
+ <string name="recent_task_option_desktop" msgid="8280879717125435668">"Mode ordinateur"</string>
<string name="recent_task_option_external_display" msgid="4533840664313389484">"Déplacer vers l\'écran externe"</string>
- <string name="recent_task_desktop" msgid="8081113562549637334">"Ordinateur"</string>
+ <string name="recent_task_desktop" msgid="8081113562549637334">"Mode ordinateur"</string>
<string name="recents_empty_message" msgid="7040467240571714191">"Aucun élément récent"</string>
<string name="accessibility_app_usage_settings" msgid="6312864233673544149">"Paramètres de consommation de l\'application"</string>
<string name="recents_clear_all" msgid="5328176793634888831">"Tout effacer"</string>
@@ -46,6 +46,8 @@
<string name="hotsaet_tip_prediction_enabled" msgid="2233554377501347650">"Suggestions d\'applications activées"</string>
<string name="hotsaet_tip_prediction_disabled" msgid="1506426298884658491">"Les suggestions d\'applications sont désactivées"</string>
<string name="hotseat_prediction_content_description" msgid="4582028296938078419">"Application prédite : <xliff:g id="TITLE">%1$s</xliff:g>"</string>
+ <!-- no translation found for gesture_tutorial_title (2750751261768388354) -->
+ <skip />
<string name="gesture_tutorial_rotation_prompt_title" msgid="7537946781362766964">"Faire pivoter l\'appareil"</string>
<string name="gesture_tutorial_rotation_prompt" msgid="1664493449851960691">"Veuillez faire pivoter votre appareil pour effectuer le tutoriel de navigation par gestes"</string>
<string name="back_gesture_feedback_swipe_too_far_from_edge" msgid="4175100312909721217">"Veillez à bien balayer l\'écran depuis le bord gauche ou droit"</string>
@@ -140,7 +142,7 @@
<string name="move_drop_target_top_or_left" msgid="2988702185049595807">"Déplacer en haut ou à gauche"</string>
<string name="move_drop_target_bottom_or_right" msgid="5431393418797620162">"Déplacer en bas ou à droite"</string>
<string name="quick_switch_overflow" msgid="3679780650881041632">"{count,plural, =1{autre application}one{autre application}other{autres applications}}"</string>
- <string name="quick_switch_desktop" msgid="8393802056024499749">"Ordinateur"</string>
+ <string name="quick_switch_desktop" msgid="8393802056024499749">"Mode ordinateur"</string>
<string name="quick_switch_split_task" msgid="5598194724255333896">"<xliff:g id="APP_NAME_1">%1$s</xliff:g> et <xliff:g id="APP_NAME_2">%2$s</xliff:g>"</string>
<string name="bubble_bar_bubble_fallback_description" msgid="7811684548953452009">"Bulle"</string>
<string name="bubble_bar_overflow_description" msgid="8617628132733151708">"Dépassement"</string>
@@ -152,4 +154,7 @@
<string name="bubble_bar_accessibility_announce_expand" msgid="1503192695527477102">"Développer <xliff:g id="BUBBLE_DESCRIPTION">%1$s</xliff:g>"</string>
<string name="bubble_bar_accessibility_announce_collapse" msgid="928284600086798791">"Réduire <xliff:g id="BUBBLE_DESCRIPTION">%1$s</xliff:g>"</string>
<string name="search_gesture_feature_title" msgid="1294044108313175306">"Entourer pour chercher"</string>
+ <string name="header_app_icon_description" msgid="2184625881433608027">"Icône de l\'application"</string>
+ <string name="header_default_app_title" msgid="8308052350689531566">"Titre de l\'application"</string>
+ <string name="header_close_icon_description" msgid="5400033616675911319">"Bouton \"Fermer\""</string>
</resources>
diff --git a/quickstep/res/values-gl/strings.xml b/quickstep/res/values-gl/strings.xml
index ac02be0..8990a5f 100644
--- a/quickstep/res/values-gl/strings.xml
+++ b/quickstep/res/values-gl/strings.xml
@@ -46,6 +46,8 @@
<string name="hotsaet_tip_prediction_enabled" msgid="2233554377501347650">"As suxestións de aplicacións están activadas"</string>
<string name="hotsaet_tip_prediction_disabled" msgid="1506426298884658491">"As suxestións de aplicacións están desactivadas"</string>
<string name="hotseat_prediction_content_description" msgid="4582028296938078419">"Aplicación predita: <xliff:g id="TITLE">%1$s</xliff:g>"</string>
+ <!-- no translation found for gesture_tutorial_title (2750751261768388354) -->
+ <skip />
<string name="gesture_tutorial_rotation_prompt_title" msgid="7537946781362766964">"Xira o dispositivo"</string>
<string name="gesture_tutorial_rotation_prompt" msgid="1664493449851960691">"Xira o dispositivo para completar o titorial de navegación con xestos"</string>
<string name="back_gesture_feedback_swipe_too_far_from_edge" msgid="4175100312909721217">"Asegúrate de pasar o dedo desde o bordo dereito ou esquerdo"</string>
@@ -152,4 +154,7 @@
<string name="bubble_bar_accessibility_announce_expand" msgid="1503192695527477102">"despregar <xliff:g id="BUBBLE_DESCRIPTION">%1$s</xliff:g>"</string>
<string name="bubble_bar_accessibility_announce_collapse" msgid="928284600086798791">"contraer <xliff:g id="BUBBLE_DESCRIPTION">%1$s</xliff:g>"</string>
<string name="search_gesture_feature_title" msgid="1294044108313175306">"Rodear para buscar"</string>
+ <string name="header_app_icon_description" msgid="2184625881433608027">"Icona da aplicación"</string>
+ <string name="header_default_app_title" msgid="8308052350689531566">"Título da aplicación"</string>
+ <string name="header_close_icon_description" msgid="5400033616675911319">"Botón Pechar"</string>
</resources>
diff --git a/quickstep/res/values-gu/strings.xml b/quickstep/res/values-gu/strings.xml
index 57551d6..cb8a35a 100644
--- a/quickstep/res/values-gu/strings.xml
+++ b/quickstep/res/values-gu/strings.xml
@@ -46,6 +46,8 @@
<string name="hotsaet_tip_prediction_enabled" msgid="2233554377501347650">"ઍપના સુઝાવો ચાલુ છે"</string>
<string name="hotsaet_tip_prediction_disabled" msgid="1506426298884658491">"ઍપના સુઝાવો બંધ છે"</string>
<string name="hotseat_prediction_content_description" msgid="4582028296938078419">"પૂર્વાનુમાનિત ઍપ: <xliff:g id="TITLE">%1$s</xliff:g>"</string>
+ <!-- no translation found for gesture_tutorial_title (2750751261768388354) -->
+ <skip />
<string name="gesture_tutorial_rotation_prompt_title" msgid="7537946781362766964">"તમારા ડિવાઇસને ફેરવો"</string>
<string name="gesture_tutorial_rotation_prompt" msgid="1664493449851960691">"સંકેતથી નૅવિગેશન ટ્યૂટૉરિઅલ પૂર્ણ કરવા માટે કૃપા કરીને તમારા ડિવાઇસને ફેરવો"</string>
<string name="back_gesture_feedback_swipe_too_far_from_edge" msgid="4175100312909721217">"ખાતરી કરો કે તમે એકદમ દૂરની જમણી કે ડાબી કિનારીએથી સ્વાઇપ કરો છો"</string>
@@ -152,4 +154,7 @@
<string name="bubble_bar_accessibility_announce_expand" msgid="1503192695527477102">"<xliff:g id="BUBBLE_DESCRIPTION">%1$s</xliff:g> મોટો કરો"</string>
<string name="bubble_bar_accessibility_announce_collapse" msgid="928284600086798791">"<xliff:g id="BUBBLE_DESCRIPTION">%1$s</xliff:g> નાનો કરો"</string>
<string name="search_gesture_feature_title" msgid="1294044108313175306">"શોધવા માટે વર્તુળ દોરો"</string>
+ <string name="header_app_icon_description" msgid="2184625881433608027">"ઍપનું આઇકન"</string>
+ <string name="header_default_app_title" msgid="8308052350689531566">"ઍપનું શીર્ષક"</string>
+ <string name="header_close_icon_description" msgid="5400033616675911319">"\'બંધ કરો\' બટન"</string>
</resources>
diff --git a/quickstep/res/values-hi/strings.xml b/quickstep/res/values-hi/strings.xml
index 4d6a91b..b7ca582 100644
--- a/quickstep/res/values-hi/strings.xml
+++ b/quickstep/res/values-hi/strings.xml
@@ -46,6 +46,8 @@
<string name="hotsaet_tip_prediction_enabled" msgid="2233554377501347650">"सुझाए गए ऐप्लिकेशन की सुविधा चालू है"</string>
<string name="hotsaet_tip_prediction_disabled" msgid="1506426298884658491">"सुझाए गए ऐप्लिकेशन की सुविधा बंद है"</string>
<string name="hotseat_prediction_content_description" msgid="4582028296938078419">"सुझाया गया ऐप्लिकेशन: <xliff:g id="TITLE">%1$s</xliff:g>"</string>
+ <!-- no translation found for gesture_tutorial_title (2750751261768388354) -->
+ <skip />
<string name="gesture_tutorial_rotation_prompt_title" msgid="7537946781362766964">"अपना डिवाइस घुमाएं"</string>
<string name="gesture_tutorial_rotation_prompt" msgid="1664493449851960691">"जेस्चर वाले नेविगेशन से जुड़े ट्यूटोरियल को पूरा करने के लिए अपने डिवाइस को घुमाएं"</string>
<string name="back_gesture_feedback_swipe_too_far_from_edge" msgid="4175100312909721217">"स्क्रीन पर बिलकुल दाएं या बाएं किनारे से स्वाइप करें"</string>
@@ -152,4 +154,7 @@
<string name="bubble_bar_accessibility_announce_expand" msgid="1503192695527477102">"<xliff:g id="BUBBLE_DESCRIPTION">%1$s</xliff:g> को बड़ा करें"</string>
<string name="bubble_bar_accessibility_announce_collapse" msgid="928284600086798791">"<xliff:g id="BUBBLE_DESCRIPTION">%1$s</xliff:g> को छोटा करें"</string>
<string name="search_gesture_feature_title" msgid="1294044108313175306">"सर्कल बनाकर ढूंढें"</string>
+ <string name="header_app_icon_description" msgid="2184625881433608027">"ऐप्लिकेशन आइकॉन"</string>
+ <string name="header_default_app_title" msgid="8308052350689531566">"ऐप्लिकेशन का नाम"</string>
+ <string name="header_close_icon_description" msgid="5400033616675911319">"\'बंद करें\' बटन"</string>
</resources>
diff --git a/quickstep/res/values-hr/strings.xml b/quickstep/res/values-hr/strings.xml
index dc66c49..cb7d9b9 100644
--- a/quickstep/res/values-hr/strings.xml
+++ b/quickstep/res/values-hr/strings.xml
@@ -46,6 +46,8 @@
<string name="hotsaet_tip_prediction_enabled" msgid="2233554377501347650">"Predlaganje apl. omogućeno"</string>
<string name="hotsaet_tip_prediction_disabled" msgid="1506426298884658491">"Predlaganje apl. onemogućeno"</string>
<string name="hotseat_prediction_content_description" msgid="4582028296938078419">"Predviđena aplikacija: <xliff:g id="TITLE">%1$s</xliff:g>"</string>
+ <!-- no translation found for gesture_tutorial_title (2750751261768388354) -->
+ <skip />
<string name="gesture_tutorial_rotation_prompt_title" msgid="7537946781362766964">"Zakrenite uređaj"</string>
<string name="gesture_tutorial_rotation_prompt" msgid="1664493449851960691">"Zakrenite uređaj da biste dovršili vodič o navigaciji pokretima"</string>
<string name="back_gesture_feedback_swipe_too_far_from_edge" msgid="4175100312909721217">"Prijeđite prstom od krajnjeg desnog ili krajnjeg lijevog ruba"</string>
@@ -152,4 +154,7 @@
<string name="bubble_bar_accessibility_announce_expand" msgid="1503192695527477102">"proširite oblačić <xliff:g id="BUBBLE_DESCRIPTION">%1$s</xliff:g>"</string>
<string name="bubble_bar_accessibility_announce_collapse" msgid="928284600086798791">"sažmite oblačić <xliff:g id="BUBBLE_DESCRIPTION">%1$s</xliff:g>"</string>
<string name="search_gesture_feature_title" msgid="1294044108313175306">"Zaokružite i potražite"</string>
+ <string name="header_app_icon_description" msgid="2184625881433608027">"Ikona aplikacije"</string>
+ <string name="header_default_app_title" msgid="8308052350689531566">"Naziv aplikacije"</string>
+ <string name="header_close_icon_description" msgid="5400033616675911319">"Gumb Zatvori"</string>
</resources>
diff --git a/quickstep/res/values-hu/strings.xml b/quickstep/res/values-hu/strings.xml
index 4a2b9d2..184fef0 100644
--- a/quickstep/res/values-hu/strings.xml
+++ b/quickstep/res/values-hu/strings.xml
@@ -46,6 +46,8 @@
<string name="hotsaet_tip_prediction_enabled" msgid="2233554377501347650">"Alkalmazásjavaslatok engedélyezve"</string>
<string name="hotsaet_tip_prediction_disabled" msgid="1506426298884658491">"Alkalmazásjavaslatok letiltva"</string>
<string name="hotseat_prediction_content_description" msgid="4582028296938078419">"Várható alkalmazás: <xliff:g id="TITLE">%1$s</xliff:g>"</string>
+ <!-- no translation found for gesture_tutorial_title (2750751261768388354) -->
+ <skip />
<string name="gesture_tutorial_rotation_prompt_title" msgid="7537946781362766964">"Forgassa el eszközét"</string>
<string name="gesture_tutorial_rotation_prompt" msgid="1664493449851960691">"Forgassa el eszközét a kézmozdulatokkal való navigáció útmutatójának befejezéséhez"</string>
<string name="back_gesture_feedback_swipe_too_far_from_edge" msgid="4175100312909721217">"Csúsztasson a képernyő jobb vagy bal széléről."</string>
@@ -152,4 +154,7 @@
<string name="bubble_bar_accessibility_announce_expand" msgid="1503192695527477102">"<xliff:g id="BUBBLE_DESCRIPTION">%1$s</xliff:g> kibontása"</string>
<string name="bubble_bar_accessibility_announce_collapse" msgid="928284600086798791">"<xliff:g id="BUBBLE_DESCRIPTION">%1$s</xliff:g> összecsukása"</string>
<string name="search_gesture_feature_title" msgid="1294044108313175306">"Bekarikázással keresés"</string>
+ <string name="header_app_icon_description" msgid="2184625881433608027">"Alkalmazásikon"</string>
+ <string name="header_default_app_title" msgid="8308052350689531566">"Alkalmazás neve"</string>
+ <string name="header_close_icon_description" msgid="5400033616675911319">"Bezárás gomb"</string>
</resources>
diff --git a/quickstep/res/values-hy/strings.xml b/quickstep/res/values-hy/strings.xml
index b7e2800..8da1a6d 100644
--- a/quickstep/res/values-hy/strings.xml
+++ b/quickstep/res/values-hy/strings.xml
@@ -46,6 +46,8 @@
<string name="hotsaet_tip_prediction_enabled" msgid="2233554377501347650">"«Առաջարկվող հավելվածներ» գործառույթը միացված է"</string>
<string name="hotsaet_tip_prediction_disabled" msgid="1506426298884658491">"«Առաջարկվող հավելվածներ» գործառույթն անջատված է"</string>
<string name="hotseat_prediction_content_description" msgid="4582028296938078419">"Առաջարկվող հավելված՝ <xliff:g id="TITLE">%1$s</xliff:g>"</string>
+ <!-- no translation found for gesture_tutorial_title (2750751261768388354) -->
+ <skip />
<string name="gesture_tutorial_rotation_prompt_title" msgid="7537946781362766964">"Պտտեք սարքը"</string>
<string name="gesture_tutorial_rotation_prompt" msgid="1664493449851960691">"Պտտեք սարքը՝ ժեստերով նավիգացիայի ուղեցույցն ավարտելու համար"</string>
<string name="back_gesture_feedback_swipe_too_far_from_edge" msgid="4175100312909721217">"Համոզվեք, որ մատը սահեցնում եք էկրանի աջ կամ ձախ եզրից"</string>
@@ -152,4 +154,7 @@
<string name="bubble_bar_accessibility_announce_expand" msgid="1503192695527477102">"<xliff:g id="BUBBLE_DESCRIPTION">%1$s</xliff:g>. ծավալել"</string>
<string name="bubble_bar_accessibility_announce_collapse" msgid="928284600086798791">"<xliff:g id="BUBBLE_DESCRIPTION">%1$s</xliff:g>. ծալել"</string>
<string name="search_gesture_feature_title" msgid="1294044108313175306">"Շրջագծել որոնելու համար"</string>
+ <string name="header_app_icon_description" msgid="2184625881433608027">"Հավելվածի պատկերակ"</string>
+ <string name="header_default_app_title" msgid="8308052350689531566">"Հավելվածի անվանում"</string>
+ <string name="header_close_icon_description" msgid="5400033616675911319">"«Փակել» կոճակ"</string>
</resources>
diff --git a/quickstep/res/values-in/strings.xml b/quickstep/res/values-in/strings.xml
index 243b428..eb592db 100644
--- a/quickstep/res/values-in/strings.xml
+++ b/quickstep/res/values-in/strings.xml
@@ -46,6 +46,8 @@
<string name="hotsaet_tip_prediction_enabled" msgid="2233554377501347650">"Saran aplikasi diaktifkan"</string>
<string name="hotsaet_tip_prediction_disabled" msgid="1506426298884658491">"Saran aplikasi dinonaktifkan"</string>
<string name="hotseat_prediction_content_description" msgid="4582028296938078419">"Aplikasi yang diprediksi: <xliff:g id="TITLE">%1$s</xliff:g>"</string>
+ <!-- no translation found for gesture_tutorial_title (2750751261768388354) -->
+ <skip />
<string name="gesture_tutorial_rotation_prompt_title" msgid="7537946781362766964">"Putar perangkat Anda"</string>
<string name="gesture_tutorial_rotation_prompt" msgid="1664493449851960691">"Putar perangkat Anda untuk menyelesaikan tutorial navigasi gestur"</string>
<string name="back_gesture_feedback_swipe_too_far_from_edge" msgid="4175100312909721217">"Pastikan Anda menggeser dari tepi ujung kanan atau ujung kiri"</string>
@@ -152,4 +154,7 @@
<string name="bubble_bar_accessibility_announce_expand" msgid="1503192695527477102">"luaskan <xliff:g id="BUBBLE_DESCRIPTION">%1$s</xliff:g>"</string>
<string name="bubble_bar_accessibility_announce_collapse" msgid="928284600086798791">"ciutkan <xliff:g id="BUBBLE_DESCRIPTION">%1$s</xliff:g>"</string>
<string name="search_gesture_feature_title" msgid="1294044108313175306">"Lingkari untuk Menelusuri"</string>
+ <string name="header_app_icon_description" msgid="2184625881433608027">"Ikon aplikasi"</string>
+ <string name="header_default_app_title" msgid="8308052350689531566">"Judul aplikasi"</string>
+ <string name="header_close_icon_description" msgid="5400033616675911319">"Tombol tutup"</string>
</resources>
diff --git a/quickstep/res/values-is/strings.xml b/quickstep/res/values-is/strings.xml
index 8265027..3500001 100644
--- a/quickstep/res/values-is/strings.xml
+++ b/quickstep/res/values-is/strings.xml
@@ -46,6 +46,8 @@
<string name="hotsaet_tip_prediction_enabled" msgid="2233554377501347650">"Kveikt á tillögum að forritum"</string>
<string name="hotsaet_tip_prediction_disabled" msgid="1506426298884658491">"Slökkt er á tillögðum forritum"</string>
<string name="hotseat_prediction_content_description" msgid="4582028296938078419">"Tillaga að forriti: <xliff:g id="TITLE">%1$s</xliff:g>"</string>
+ <!-- no translation found for gesture_tutorial_title (2750751261768388354) -->
+ <skip />
<string name="gesture_tutorial_rotation_prompt_title" msgid="7537946781362766964">"Snúðu tækinu"</string>
<string name="gesture_tutorial_rotation_prompt" msgid="1664493449851960691">"Snúðu tækinu til að ljúka leiðsögn um bendingastjórnun"</string>
<string name="back_gesture_feedback_swipe_too_far_from_edge" msgid="4175100312909721217">"Passaðu að strjúka frá jaðri hægri eða vinstri brúnar"</string>
@@ -152,4 +154,7 @@
<string name="bubble_bar_accessibility_announce_expand" msgid="1503192695527477102">"stækka <xliff:g id="BUBBLE_DESCRIPTION">%1$s</xliff:g>"</string>
<string name="bubble_bar_accessibility_announce_collapse" msgid="928284600086798791">"minnka <xliff:g id="BUBBLE_DESCRIPTION">%1$s</xliff:g>"</string>
<string name="search_gesture_feature_title" msgid="1294044108313175306">"Circle to Search"</string>
+ <string name="header_app_icon_description" msgid="2184625881433608027">"Forritstákn"</string>
+ <string name="header_default_app_title" msgid="8308052350689531566">"Titil forrits"</string>
+ <string name="header_close_icon_description" msgid="5400033616675911319">"Hnappur til að loka"</string>
</resources>
diff --git a/quickstep/res/values-it/strings.xml b/quickstep/res/values-it/strings.xml
index e7771d9..b8fa813 100644
--- a/quickstep/res/values-it/strings.xml
+++ b/quickstep/res/values-it/strings.xml
@@ -46,6 +46,8 @@
<string name="hotsaet_tip_prediction_enabled" msgid="2233554377501347650">"La funzionalità app suggerite è attiva"</string>
<string name="hotsaet_tip_prediction_disabled" msgid="1506426298884658491">"La funzionalità app suggerite è disattivata"</string>
<string name="hotseat_prediction_content_description" msgid="4582028296938078419">"App prevista: <xliff:g id="TITLE">%1$s</xliff:g>"</string>
+ <!-- no translation found for gesture_tutorial_title (2750751261768388354) -->
+ <skip />
<string name="gesture_tutorial_rotation_prompt_title" msgid="7537946781362766964">"Ruota il dispositivo"</string>
<string name="gesture_tutorial_rotation_prompt" msgid="1664493449851960691">"Ruota il dispositivo per completare il tutorial relativo alla navigazione tramite gesti"</string>
<string name="back_gesture_feedback_swipe_too_far_from_edge" msgid="4175100312909721217">"Assicurati di scorrere dal bordo all\'estrema destra o all\'estrema sinistra"</string>
@@ -152,4 +154,7 @@
<string name="bubble_bar_accessibility_announce_expand" msgid="1503192695527477102">"espandi <xliff:g id="BUBBLE_DESCRIPTION">%1$s</xliff:g>"</string>
<string name="bubble_bar_accessibility_announce_collapse" msgid="928284600086798791">"comprimi <xliff:g id="BUBBLE_DESCRIPTION">%1$s</xliff:g>"</string>
<string name="search_gesture_feature_title" msgid="1294044108313175306">"Cerchia e Cerca"</string>
+ <string name="header_app_icon_description" msgid="2184625881433608027">"Icona dell\'app"</string>
+ <string name="header_default_app_title" msgid="8308052350689531566">"Titolo dell\'app"</string>
+ <string name="header_close_icon_description" msgid="5400033616675911319">"Pulsante Chiudi"</string>
</resources>
diff --git a/quickstep/res/values-iw/strings.xml b/quickstep/res/values-iw/strings.xml
index ae84699..c6fc845 100644
--- a/quickstep/res/values-iw/strings.xml
+++ b/quickstep/res/values-iw/strings.xml
@@ -46,6 +46,8 @@
<string name="hotsaet_tip_prediction_enabled" msgid="2233554377501347650">"התכונה \'הצעות לאפליקציות\' מופעלת"</string>
<string name="hotsaet_tip_prediction_disabled" msgid="1506426298884658491">"ההצעות לאפליקציות מושבתות"</string>
<string name="hotseat_prediction_content_description" msgid="4582028296938078419">"האפליקציות החזויות: <xliff:g id="TITLE">%1$s</xliff:g>"</string>
+ <!-- no translation found for gesture_tutorial_title (2750751261768388354) -->
+ <skip />
<string name="gesture_tutorial_rotation_prompt_title" msgid="7537946781362766964">"צריך לסובב את המכשיר"</string>
<string name="gesture_tutorial_rotation_prompt" msgid="1664493449851960691">"צריך לסובב את המכשיר כדי להשלים את המדריך לניווט באמצעות תנועות"</string>
<string name="back_gesture_feedback_swipe_too_far_from_edge" msgid="4175100312909721217">"חשוב להחליק מהקצה השמאלי או הימני"</string>
@@ -152,4 +154,7 @@
<string name="bubble_bar_accessibility_announce_expand" msgid="1503192695527477102">"הרחבה של <xliff:g id="BUBBLE_DESCRIPTION">%1$s</xliff:g>"</string>
<string name="bubble_bar_accessibility_announce_collapse" msgid="928284600086798791">"כיווץ של <xliff:g id="BUBBLE_DESCRIPTION">%1$s</xliff:g>"</string>
<string name="search_gesture_feature_title" msgid="1294044108313175306">"מקיפים ומחפשים"</string>
+ <string name="header_app_icon_description" msgid="2184625881433608027">"סמל האפליקציה"</string>
+ <string name="header_default_app_title" msgid="8308052350689531566">"שם האפליקציה"</string>
+ <string name="header_close_icon_description" msgid="5400033616675911319">"כפתור הסגירה"</string>
</resources>
diff --git a/quickstep/res/values-ja/strings.xml b/quickstep/res/values-ja/strings.xml
index 3be39b9..5fdcf4a 100644
--- a/quickstep/res/values-ja/strings.xml
+++ b/quickstep/res/values-ja/strings.xml
@@ -23,7 +23,7 @@
<string name="recent_task_option_freeform" msgid="48863056265284071">"フリーフォーム"</string>
<string name="recent_task_option_desktop" msgid="8280879717125435668">"デスクトップ"</string>
<string name="recent_task_option_external_display" msgid="4533840664313389484">"外部ディスプレイに移動する"</string>
- <string name="recent_task_desktop" msgid="8081113562549637334">"パソコン"</string>
+ <string name="recent_task_desktop" msgid="8081113562549637334">"デスクトップ"</string>
<string name="recents_empty_message" msgid="7040467240571714191">"最近のアイテムはありません"</string>
<string name="accessibility_app_usage_settings" msgid="6312864233673544149">"アプリの使用状況の設定"</string>
<string name="recents_clear_all" msgid="5328176793634888831">"すべてクリア"</string>
@@ -46,6 +46,8 @@
<string name="hotsaet_tip_prediction_enabled" msgid="2233554377501347650">"アプリの候補表示が有効です"</string>
<string name="hotsaet_tip_prediction_disabled" msgid="1506426298884658491">"アプリの候補は無効です"</string>
<string name="hotseat_prediction_content_description" msgid="4582028296938078419">"予測されたアプリ: <xliff:g id="TITLE">%1$s</xliff:g>"</string>
+ <!-- no translation found for gesture_tutorial_title (2750751261768388354) -->
+ <skip />
<string name="gesture_tutorial_rotation_prompt_title" msgid="7537946781362766964">"デバイスを回転してください"</string>
<string name="gesture_tutorial_rotation_prompt" msgid="1664493449851960691">"ジェスチャー ナビゲーションのチュートリアルを終了するには、デバイスを回転してください"</string>
<string name="back_gesture_feedback_swipe_too_far_from_edge" msgid="4175100312909721217">"右端または左端からスワイプしてください"</string>
@@ -140,7 +142,7 @@
<string name="move_drop_target_top_or_left" msgid="2988702185049595807">"上 / 左に移動"</string>
<string name="move_drop_target_bottom_or_right" msgid="5431393418797620162">"下 / 右に移動"</string>
<string name="quick_switch_overflow" msgid="3679780650881041632">"{count,plural, =1{個のその他のアプリ}other{個のその他のアプリ}}"</string>
- <string name="quick_switch_desktop" msgid="8393802056024499749">"パソコン"</string>
+ <string name="quick_switch_desktop" msgid="8393802056024499749">"デスクトップ"</string>
<string name="quick_switch_split_task" msgid="5598194724255333896">"<xliff:g id="APP_NAME_1">%1$s</xliff:g> と <xliff:g id="APP_NAME_2">%2$s</xliff:g>"</string>
<string name="bubble_bar_bubble_fallback_description" msgid="7811684548953452009">"ふきだし"</string>
<string name="bubble_bar_overflow_description" msgid="8617628132733151708">"オーバーフロー"</string>
@@ -152,4 +154,7 @@
<string name="bubble_bar_accessibility_announce_expand" msgid="1503192695527477102">"<xliff:g id="BUBBLE_DESCRIPTION">%1$s</xliff:g>を開きます"</string>
<string name="bubble_bar_accessibility_announce_collapse" msgid="928284600086798791">"<xliff:g id="BUBBLE_DESCRIPTION">%1$s</xliff:g>を閉じます"</string>
<string name="search_gesture_feature_title" msgid="1294044108313175306">"かこって検索"</string>
+ <string name="header_app_icon_description" msgid="2184625881433608027">"アプリのアイコン"</string>
+ <string name="header_default_app_title" msgid="8308052350689531566">"アプリのタイトル"</string>
+ <string name="header_close_icon_description" msgid="5400033616675911319">"閉じるボタン"</string>
</resources>
diff --git a/quickstep/res/values-ka/strings.xml b/quickstep/res/values-ka/strings.xml
index d6797d0..01becd7 100644
--- a/quickstep/res/values-ka/strings.xml
+++ b/quickstep/res/values-ka/strings.xml
@@ -46,6 +46,8 @@
<string name="hotsaet_tip_prediction_enabled" msgid="2233554377501347650">"აპის შეთავაზებები ჩართულია"</string>
<string name="hotsaet_tip_prediction_disabled" msgid="1506426298884658491">"აპის შეთავაზებები გათიშულია"</string>
<string name="hotseat_prediction_content_description" msgid="4582028296938078419">"ნაწინასწარმეტყველები აპი: <xliff:g id="TITLE">%1$s</xliff:g>"</string>
+ <!-- no translation found for gesture_tutorial_title (2750751261768388354) -->
+ <skip />
<string name="gesture_tutorial_rotation_prompt_title" msgid="7537946781362766964">"შეატრიალეთ მოწყობილობა"</string>
<string name="gesture_tutorial_rotation_prompt" msgid="1664493449851960691">"ჟესტებით ნავიგაციის სახელმძღვანელოს დასასრულებლად შეატრიალეთ თქვენი მოწყობილობა"</string>
<string name="back_gesture_feedback_swipe_too_far_from_edge" msgid="4175100312909721217">"გადაფურცლეთ უკიდურესი მარჯვენა ან მარცხენა ბოლოდან"</string>
@@ -152,4 +154,7 @@
<string name="bubble_bar_accessibility_announce_expand" msgid="1503192695527477102">"<xliff:g id="BUBBLE_DESCRIPTION">%1$s</xliff:g>-ის გაფართოება"</string>
<string name="bubble_bar_accessibility_announce_collapse" msgid="928284600086798791">"<xliff:g id="BUBBLE_DESCRIPTION">%1$s</xliff:g>-ის ჩაკეცვა"</string>
<string name="search_gesture_feature_title" msgid="1294044108313175306">"ძიება წრის მოხაზვით"</string>
+ <string name="header_app_icon_description" msgid="2184625881433608027">"აპის ხატულა"</string>
+ <string name="header_default_app_title" msgid="8308052350689531566">"აპის სათაური"</string>
+ <string name="header_close_icon_description" msgid="5400033616675911319">"დახურვის ღილაკი"</string>
</resources>
diff --git a/quickstep/res/values-kk/strings.xml b/quickstep/res/values-kk/strings.xml
index 632ed16..3280908 100644
--- a/quickstep/res/values-kk/strings.xml
+++ b/quickstep/res/values-kk/strings.xml
@@ -46,6 +46,8 @@
<string name="hotsaet_tip_prediction_enabled" msgid="2233554377501347650">"\"Қолданба ұсыныстары\" функциясы қосылды."</string>
<string name="hotsaet_tip_prediction_disabled" msgid="1506426298884658491">"\"Қолданба ұсыныстары\" функциясы өшірулі."</string>
<string name="hotseat_prediction_content_description" msgid="4582028296938078419">"Болжалды қолданба: <xliff:g id="TITLE">%1$s</xliff:g>"</string>
+ <!-- no translation found for gesture_tutorial_title (2750751261768388354) -->
+ <skip />
<string name="gesture_tutorial_rotation_prompt_title" msgid="7537946781362766964">"Құрылғыны бұрыңыз"</string>
<string name="gesture_tutorial_rotation_prompt" msgid="1664493449851960691">"Қимылмен басқару нұсқаулығын аяқтау үшін құрылғыны бұрыңыз."</string>
<string name="back_gesture_feedback_swipe_too_far_from_edge" msgid="4175100312909721217">"Экранның оң немесе сол жиегінен сырғытыңыз."</string>
@@ -152,4 +154,7 @@
<string name="bubble_bar_accessibility_announce_expand" msgid="1503192695527477102">"<xliff:g id="BUBBLE_DESCRIPTION">%1$s</xliff:g>: жаю"</string>
<string name="bubble_bar_accessibility_announce_collapse" msgid="928284600086798791">"<xliff:g id="BUBBLE_DESCRIPTION">%1$s</xliff:g>: жию"</string>
<string name="search_gesture_feature_title" msgid="1294044108313175306">"Қоршау арқылы іздеу"</string>
+ <string name="header_app_icon_description" msgid="2184625881433608027">"Қолданба белгішесі"</string>
+ <string name="header_default_app_title" msgid="8308052350689531566">"Қолданба атауы"</string>
+ <string name="header_close_icon_description" msgid="5400033616675911319">"\"Жабу\" түймесі"</string>
</resources>
diff --git a/quickstep/res/values-km/strings.xml b/quickstep/res/values-km/strings.xml
index b5158db..d05ef16 100644
--- a/quickstep/res/values-km/strings.xml
+++ b/quickstep/res/values-km/strings.xml
@@ -46,6 +46,8 @@
<string name="hotsaet_tip_prediction_enabled" msgid="2233554377501347650">"បានបើកការណែនាំកម្មវិធី"</string>
<string name="hotsaet_tip_prediction_disabled" msgid="1506426298884658491">"បានបិទការណែនាំកម្មវិធី"</string>
<string name="hotseat_prediction_content_description" msgid="4582028296938078419">"កម្មវិធីដែលបានព្យាករ៖ <xliff:g id="TITLE">%1$s</xliff:g>"</string>
+ <!-- no translation found for gesture_tutorial_title (2750751261768388354) -->
+ <skip />
<string name="gesture_tutorial_rotation_prompt_title" msgid="7537946781362766964">"បង្វិលឧបករណ៍របស់អ្នក"</string>
<string name="gesture_tutorial_rotation_prompt" msgid="1664493449851960691">"សូមបង្វិលឧបករណ៍របស់អ្នក ដើម្បីបញ្ចប់មេរៀនអំពីការរុករកដោយប្រើចលនា"</string>
<string name="back_gesture_feedback_swipe_too_far_from_edge" msgid="4175100312909721217">"ត្រូវប្រាកដថាអ្នកអូសពីគែមខាងស្ដាំ ឬខាងឆ្វេង"</string>
@@ -152,4 +154,7 @@
<string name="bubble_bar_accessibility_announce_expand" msgid="1503192695527477102">"ពង្រីក <xliff:g id="BUBBLE_DESCRIPTION">%1$s</xliff:g>"</string>
<string name="bubble_bar_accessibility_announce_collapse" msgid="928284600086798791">"បង្រួម <xliff:g id="BUBBLE_DESCRIPTION">%1$s</xliff:g>"</string>
<string name="search_gesture_feature_title" msgid="1294044108313175306">"គូររង្វង់ដើម្បីស្វែងរក"</string>
+ <string name="header_app_icon_description" msgid="2184625881433608027">"រូបកម្មវិធី"</string>
+ <string name="header_default_app_title" msgid="8308052350689531566">"ចំណងជើងកម្មវិធី"</string>
+ <string name="header_close_icon_description" msgid="5400033616675911319">"ប៊ូតុងបិទ"</string>
</resources>
diff --git a/quickstep/res/values-kn/strings.xml b/quickstep/res/values-kn/strings.xml
index 438bbf0..3240b2a 100644
--- a/quickstep/res/values-kn/strings.xml
+++ b/quickstep/res/values-kn/strings.xml
@@ -46,6 +46,8 @@
<string name="hotsaet_tip_prediction_enabled" msgid="2233554377501347650">"ಆ್ಯಪ್ ಸಲಹೆಗಳನ್ನು ಸಕ್ರಿಯಗೊಳಿಸಲಾಗಿದೆ"</string>
<string name="hotsaet_tip_prediction_disabled" msgid="1506426298884658491">"ಆ್ಯಪ್ ಸಲಹೆಗಳನ್ನು ನಿಷ್ಕ್ರಿಯಗೊಳಿಸಲಾಗಿದೆ"</string>
<string name="hotseat_prediction_content_description" msgid="4582028296938078419">"ಶಿಫಾರಸು ಮಾಡಿದ ಆ್ಯಪ್: <xliff:g id="TITLE">%1$s</xliff:g>"</string>
+ <!-- no translation found for gesture_tutorial_title (2750751261768388354) -->
+ <skip />
<string name="gesture_tutorial_rotation_prompt_title" msgid="7537946781362766964">"ನಿಮ್ಮ ಸಾಧನವನ್ನು ತಿರುಗಿಸಿ"</string>
<string name="gesture_tutorial_rotation_prompt" msgid="1664493449851960691">"ಗೆಸ್ಚರ್ ನ್ಯಾವಿಗೇಶನ್ ಟುಟೋರಿಯಲ್ ಅನ್ನು ಪೂರ್ಣಗೊಳಿಸಲು, ನಿಮ್ಮ ಸಾಧನವನ್ನು ತಿರುಗಿಸಿ"</string>
<string name="back_gesture_feedback_swipe_too_far_from_edge" msgid="4175100312909721217">"ನೀವು ಬಲಕೊನೆಯ ಅಂಚಿನಿಂದ ಅಥವಾ ಎಡಕೊನೆಯ ಅಂಚಿನಿಂದ ಸ್ವೈಪ್ ಮಾಡುತ್ತಿದ್ದೀರಿ ಎಂದು ಖಚಿತಪಡಿಸಿಕೊಳ್ಳಿ"</string>
@@ -152,4 +154,7 @@
<string name="bubble_bar_accessibility_announce_expand" msgid="1503192695527477102">"<xliff:g id="BUBBLE_DESCRIPTION">%1$s</xliff:g> ಅನ್ನು ವಿಸ್ತೃತಗೊಳಿಸಿ"</string>
<string name="bubble_bar_accessibility_announce_collapse" msgid="928284600086798791">"<xliff:g id="BUBBLE_DESCRIPTION">%1$s</xliff:g> ಅನ್ನು ಕುಗ್ಗಿಸಿ"</string>
<string name="search_gesture_feature_title" msgid="1294044108313175306">"ಹುಡುಕಲು ಒಂದು ಸರ್ಕಲ್ ರಚಿಸಿ"</string>
+ <string name="header_app_icon_description" msgid="2184625881433608027">"ಆ್ಯಪ್ ಐಕಾನ್"</string>
+ <string name="header_default_app_title" msgid="8308052350689531566">"ಆ್ಯಪ್ ಶೀರ್ಷಿಕೆ"</string>
+ <string name="header_close_icon_description" msgid="5400033616675911319">"ಮುಚ್ಚುವ ಬಟನ್"</string>
</resources>
diff --git a/quickstep/res/values-ko/strings.xml b/quickstep/res/values-ko/strings.xml
index b50bd03..c8b8674 100644
--- a/quickstep/res/values-ko/strings.xml
+++ b/quickstep/res/values-ko/strings.xml
@@ -46,6 +46,8 @@
<string name="hotsaet_tip_prediction_enabled" msgid="2233554377501347650">"앱 제안이 사용 설정됨"</string>
<string name="hotsaet_tip_prediction_disabled" msgid="1506426298884658491">"앱 제안이 사용 중지됨"</string>
<string name="hotseat_prediction_content_description" msgid="4582028296938078419">"예상 앱: <xliff:g id="TITLE">%1$s</xliff:g>"</string>
+ <!-- no translation found for gesture_tutorial_title (2750751261768388354) -->
+ <skip />
<string name="gesture_tutorial_rotation_prompt_title" msgid="7537946781362766964">"기기를 회전시키세요"</string>
<string name="gesture_tutorial_rotation_prompt" msgid="1664493449851960691">"동작 탐색 튜토리얼을 완료하려면 기기를 회전시키세요."</string>
<string name="back_gesture_feedback_swipe_too_far_from_edge" msgid="4175100312909721217">"오른쪽 또는 왼쪽 가장자리 끝에서 스와이프하세요."</string>
@@ -152,4 +154,7 @@
<string name="bubble_bar_accessibility_announce_expand" msgid="1503192695527477102">"<xliff:g id="BUBBLE_DESCRIPTION">%1$s</xliff:g> 펼치기"</string>
<string name="bubble_bar_accessibility_announce_collapse" msgid="928284600086798791">"<xliff:g id="BUBBLE_DESCRIPTION">%1$s</xliff:g> 접기"</string>
<string name="search_gesture_feature_title" msgid="1294044108313175306">"서클 투 서치"</string>
+ <string name="header_app_icon_description" msgid="2184625881433608027">"앱 아이콘"</string>
+ <string name="header_default_app_title" msgid="8308052350689531566">"앱 제목"</string>
+ <string name="header_close_icon_description" msgid="5400033616675911319">"닫기 버튼"</string>
</resources>
diff --git a/quickstep/res/values-ky/strings.xml b/quickstep/res/values-ky/strings.xml
index f9ac3ca..6dafcd0 100644
--- a/quickstep/res/values-ky/strings.xml
+++ b/quickstep/res/values-ky/strings.xml
@@ -46,6 +46,8 @@
<string name="hotsaet_tip_prediction_enabled" msgid="2233554377501347650">"Сунушталган колдонмолор функциясы иштетилди"</string>
<string name="hotsaet_tip_prediction_disabled" msgid="1506426298884658491">"Сунушталган колдонмолор функциясы өчүрүлгөн"</string>
<string name="hotseat_prediction_content_description" msgid="4582028296938078419">"Божомолдонгон колдонмо: <xliff:g id="TITLE">%1$s</xliff:g>"</string>
+ <!-- no translation found for gesture_tutorial_title (2750751261768388354) -->
+ <skip />
<string name="gesture_tutorial_rotation_prompt_title" msgid="7537946781362766964">"Түзмөгүңүздү буруңуз"</string>
<string name="gesture_tutorial_rotation_prompt" msgid="1664493449851960691">"Жаңсап чабыттоо үйрөткүчүнүн аягына чыгуу үчүн түзмөктү буруңуз"</string>
<string name="back_gesture_feedback_swipe_too_far_from_edge" msgid="4175100312909721217">"Экранды эң четинен оңдон солго же солдон оңго карай сүрүңүз"</string>
@@ -152,4 +154,7 @@
<string name="bubble_bar_accessibility_announce_expand" msgid="1503192695527477102">"<xliff:g id="BUBBLE_DESCRIPTION">%1$s</xliff:g> жайып көрсөтүү"</string>
<string name="bubble_bar_accessibility_announce_collapse" msgid="928284600086798791">"<xliff:g id="BUBBLE_DESCRIPTION">%1$s</xliff:g> жыйыштыруу"</string>
<string name="search_gesture_feature_title" msgid="1294044108313175306">"Тегеректеп издөө"</string>
+ <string name="header_app_icon_description" msgid="2184625881433608027">"Колдонмонун сүрөтчөсү"</string>
+ <string name="header_default_app_title" msgid="8308052350689531566">"Колдонмонун аталышы"</string>
+ <string name="header_close_icon_description" msgid="5400033616675911319">"Жабуу баскычы"</string>
</resources>
diff --git a/quickstep/res/values-lo/strings.xml b/quickstep/res/values-lo/strings.xml
index ec1622f..a13da69 100644
--- a/quickstep/res/values-lo/strings.xml
+++ b/quickstep/res/values-lo/strings.xml
@@ -46,6 +46,8 @@
<string name="hotsaet_tip_prediction_enabled" msgid="2233554377501347650">"ເປີດການນຳໃຊ້ການແນະນຳແອັບແລ້ວ"</string>
<string name="hotsaet_tip_prediction_disabled" msgid="1506426298884658491">"ປິດການນຳໃຊ້ການແນະນຳແອັບແລ້ວ"</string>
<string name="hotseat_prediction_content_description" msgid="4582028296938078419">"ແອັບທີ່ຄາດເດົາໄວ້: <xliff:g id="TITLE">%1$s</xliff:g>"</string>
+ <!-- no translation found for gesture_tutorial_title (2750751261768388354) -->
+ <skip />
<string name="gesture_tutorial_rotation_prompt_title" msgid="7537946781362766964">"ໝຸນອຸປະກອນຂອງທ່ານ"</string>
<string name="gesture_tutorial_rotation_prompt" msgid="1664493449851960691">"ກະລຸນາໝຸນອຸປະກອນຂອງທ່ານເພື່ອເຮັດຕາມການສອນການນຳໃຊ້ກ່ຽວກັບການນຳທາງແບບທ່າທາງໃຫ້ສຳເລັດ"</string>
<string name="back_gesture_feedback_swipe_too_far_from_edge" msgid="4175100312909721217">"ກະລຸນາກວດສອບວ່າທ່ານປັດຈາກຂອບຂວາສຸດ ຫຼື ຊ້າຍສຸດ"</string>
@@ -152,4 +154,7 @@
<string name="bubble_bar_accessibility_announce_expand" msgid="1503192695527477102">"ຂະຫຍາຍ <xliff:g id="BUBBLE_DESCRIPTION">%1$s</xliff:g>"</string>
<string name="bubble_bar_accessibility_announce_collapse" msgid="928284600086798791">"ຫຍໍ້ <xliff:g id="BUBBLE_DESCRIPTION">%1$s</xliff:g> ລົງ"</string>
<string name="search_gesture_feature_title" msgid="1294044108313175306">"ແຕ້ມວົງມົນເພື່ອຊອກຫາ"</string>
+ <string name="header_app_icon_description" msgid="2184625881433608027">"ໄອຄອນແອັບ"</string>
+ <string name="header_default_app_title" msgid="8308052350689531566">"ຊື່ແອັບ"</string>
+ <string name="header_close_icon_description" msgid="5400033616675911319">"ປຸ່ມປິດ"</string>
</resources>
diff --git a/quickstep/res/values-lt/strings.xml b/quickstep/res/values-lt/strings.xml
index cc44886..7334b0a 100644
--- a/quickstep/res/values-lt/strings.xml
+++ b/quickstep/res/values-lt/strings.xml
@@ -46,6 +46,8 @@
<string name="hotsaet_tip_prediction_enabled" msgid="2233554377501347650">"Siūlomų programų funkcija įgalinta"</string>
<string name="hotsaet_tip_prediction_disabled" msgid="1506426298884658491">"Siūlomų programų funkcija išjungta"</string>
<string name="hotseat_prediction_content_description" msgid="4582028296938078419">"Numatoma programa: <xliff:g id="TITLE">%1$s</xliff:g>"</string>
+ <!-- no translation found for gesture_tutorial_title (2750751261768388354) -->
+ <skip />
<string name="gesture_tutorial_rotation_prompt_title" msgid="7537946781362766964">"Pasukite įrenginį"</string>
<string name="gesture_tutorial_rotation_prompt" msgid="1664493449851960691">"Pasukite įrenginį, kad pereitumėte į naršymo gestais mokomąją medžiagą"</string>
<string name="back_gesture_feedback_swipe_too_far_from_edge" msgid="4175100312909721217">"Turite perbraukti nuo dešiniojo ar kairiojo krašto"</string>
@@ -152,4 +154,7 @@
<string name="bubble_bar_accessibility_announce_expand" msgid="1503192695527477102">"išskleisti „<xliff:g id="BUBBLE_DESCRIPTION">%1$s</xliff:g>“"</string>
<string name="bubble_bar_accessibility_announce_collapse" msgid="928284600086798791">"sutraukti „<xliff:g id="BUBBLE_DESCRIPTION">%1$s</xliff:g>“"</string>
<string name="search_gesture_feature_title" msgid="1294044108313175306">"Paieška apibrėžiant"</string>
+ <string name="header_app_icon_description" msgid="2184625881433608027">"Programos piktograma"</string>
+ <string name="header_default_app_title" msgid="8308052350689531566">"Programos pavadinimas"</string>
+ <string name="header_close_icon_description" msgid="5400033616675911319">"Mygtukas „Uždaryti“"</string>
</resources>
diff --git a/quickstep/res/values-lv/strings.xml b/quickstep/res/values-lv/strings.xml
index c57db9c..bbf45c3 100644
--- a/quickstep/res/values-lv/strings.xml
+++ b/quickstep/res/values-lv/strings.xml
@@ -46,6 +46,8 @@
<string name="hotsaet_tip_prediction_enabled" msgid="2233554377501347650">"Ieteicamās lietotnes ir iespējotas"</string>
<string name="hotsaet_tip_prediction_disabled" msgid="1506426298884658491">"Ieteicamās lietotnes ir atspējotas"</string>
<string name="hotseat_prediction_content_description" msgid="4582028296938078419">"Prognozētā lietotne: <xliff:g id="TITLE">%1$s</xliff:g>"</string>
+ <!-- no translation found for gesture_tutorial_title (2750751261768388354) -->
+ <skip />
<string name="gesture_tutorial_rotation_prompt_title" msgid="7537946781362766964">"Pagrieziet ierīci"</string>
<string name="gesture_tutorial_rotation_prompt" msgid="1664493449851960691">"Lūdzu, pagrieziet savu ierīci, lai pabeigtu žestu navigācijas apmācību."</string>
<string name="back_gesture_feedback_swipe_too_far_from_edge" msgid="4175100312909721217">"Jāvelk no pašas labās vai kreisās malas."</string>
@@ -152,4 +154,7 @@
<string name="bubble_bar_accessibility_announce_expand" msgid="1503192695527477102">"izvērst “<xliff:g id="BUBBLE_DESCRIPTION">%1$s</xliff:g>”"</string>
<string name="bubble_bar_accessibility_announce_collapse" msgid="928284600086798791">"sakļaut “<xliff:g id="BUBBLE_DESCRIPTION">%1$s</xliff:g>”"</string>
<string name="search_gesture_feature_title" msgid="1294044108313175306">"Apvilkt un meklēt"</string>
+ <string name="header_app_icon_description" msgid="2184625881433608027">"Lietotnes ikona"</string>
+ <string name="header_default_app_title" msgid="8308052350689531566">"Lietotnes nosaukums"</string>
+ <string name="header_close_icon_description" msgid="5400033616675911319">"Poga Aizvērt"</string>
</resources>
diff --git a/quickstep/res/values-mk/strings.xml b/quickstep/res/values-mk/strings.xml
index 186153d..5340854 100644
--- a/quickstep/res/values-mk/strings.xml
+++ b/quickstep/res/values-mk/strings.xml
@@ -46,6 +46,8 @@
<string name="hotsaet_tip_prediction_enabled" msgid="2233554377501347650">"Предлозите за апликации се овозможени"</string>
<string name="hotsaet_tip_prediction_disabled" msgid="1506426298884658491">"Предлозите за апликации се оневозможени"</string>
<string name="hotseat_prediction_content_description" msgid="4582028296938078419">"Предвидена апликација: <xliff:g id="TITLE">%1$s</xliff:g>"</string>
+ <!-- no translation found for gesture_tutorial_title (2750751261768388354) -->
+ <skip />
<string name="gesture_tutorial_rotation_prompt_title" msgid="7537946781362766964">"Ротирајте го уредот"</string>
<string name="gesture_tutorial_rotation_prompt" msgid="1664493449851960691">"Ротирајте го уредот за да го завршите упатството за навигација со движење"</string>
<string name="back_gesture_feedback_swipe_too_far_from_edge" msgid="4175100312909721217">"Повлечете од крајниот десен или крајниот лев раб"</string>
@@ -152,4 +154,7 @@
<string name="bubble_bar_accessibility_announce_expand" msgid="1503192695527477102">"прошири <xliff:g id="BUBBLE_DESCRIPTION">%1$s</xliff:g>"</string>
<string name="bubble_bar_accessibility_announce_collapse" msgid="928284600086798791">"собери <xliff:g id="BUBBLE_DESCRIPTION">%1$s</xliff:g>"</string>
<string name="search_gesture_feature_title" msgid="1294044108313175306">"Пребарување со заокружување"</string>
+ <string name="header_app_icon_description" msgid="2184625881433608027">"Икона за апликацијата"</string>
+ <string name="header_default_app_title" msgid="8308052350689531566">"Наслов на апликацијата"</string>
+ <string name="header_close_icon_description" msgid="5400033616675911319">"Копче за затворање"</string>
</resources>
diff --git a/quickstep/res/values-ml/strings.xml b/quickstep/res/values-ml/strings.xml
index b25ce07..d92ddbc 100644
--- a/quickstep/res/values-ml/strings.xml
+++ b/quickstep/res/values-ml/strings.xml
@@ -46,6 +46,8 @@
<string name="hotsaet_tip_prediction_enabled" msgid="2233554377501347650">"ആപ്പ് നിർദ്ദേശങ്ങൾ പ്രവർത്തനക്ഷമമാക്കി"</string>
<string name="hotsaet_tip_prediction_disabled" msgid="1506426298884658491">"ആപ്പ് നിർദ്ദേശങ്ങൾ പ്രവർത്തനരഹിതമാക്കി"</string>
<string name="hotseat_prediction_content_description" msgid="4582028296938078419">"പ്രവചിച്ച ആപ്പ്: <xliff:g id="TITLE">%1$s</xliff:g>"</string>
+ <!-- no translation found for gesture_tutorial_title (2750751261768388354) -->
+ <skip />
<string name="gesture_tutorial_rotation_prompt_title" msgid="7537946781362766964">"നിങ്ങളുടെ ഉപകരണം റൊട്ടേറ്റ് ചെയ്യുക"</string>
<string name="gesture_tutorial_rotation_prompt" msgid="1664493449851960691">"ജെസ്ച്ചർ നാവിഗേഷൻ ട്യൂട്ടോറിയൽ പൂർത്തിയാക്കാൻ നിങ്ങളുടെ ഉപകരണം റൊട്ടേറ്റ് ചെയ്യുക"</string>
<string name="back_gesture_feedback_swipe_too_far_from_edge" msgid="4175100312909721217">"വലത്തേയറ്റത്തെയോ ഇടത്തേയറ്റത്തെയോ അരികിൽ നിന്നാണ് സ്വെെപ്പ് ചെയ്യുന്നതെന്ന് ഉറപ്പാക്കുക"</string>
@@ -152,4 +154,7 @@
<string name="bubble_bar_accessibility_announce_expand" msgid="1503192695527477102">"<xliff:g id="BUBBLE_DESCRIPTION">%1$s</xliff:g> വികസിപ്പിക്കുക"</string>
<string name="bubble_bar_accessibility_announce_collapse" msgid="928284600086798791">"<xliff:g id="BUBBLE_DESCRIPTION">%1$s</xliff:g> ചുരുക്കുക"</string>
<string name="search_gesture_feature_title" msgid="1294044108313175306">"തിരയാൻ വട്ടം വരയ്ക്കൽ"</string>
+ <string name="header_app_icon_description" msgid="2184625881433608027">"ആപ്പ് ഐക്കൺ"</string>
+ <string name="header_default_app_title" msgid="8308052350689531566">"ആപ്പിന്റെ പേര്"</string>
+ <string name="header_close_icon_description" msgid="5400033616675911319">"അടയ്ക്കുക ബട്ടൺ"</string>
</resources>
diff --git a/quickstep/res/values-mn/strings.xml b/quickstep/res/values-mn/strings.xml
index b45bfa4..2b335a9 100644
--- a/quickstep/res/values-mn/strings.xml
+++ b/quickstep/res/values-mn/strings.xml
@@ -46,6 +46,8 @@
<string name="hotsaet_tip_prediction_enabled" msgid="2233554377501347650">"Санал болгож буй аппуудыг идэвхжүүлсэн"</string>
<string name="hotsaet_tip_prediction_disabled" msgid="1506426298884658491">"Санал болгож буй аппуудыг идэвхгүй болгосон"</string>
<string name="hotseat_prediction_content_description" msgid="4582028296938078419">"Таамаглаж буй апп: <xliff:g id="TITLE">%1$s</xliff:g>"</string>
+ <!-- no translation found for gesture_tutorial_title (2750751261768388354) -->
+ <skip />
<string name="gesture_tutorial_rotation_prompt_title" msgid="7537946781362766964">"Төхөөрөмжөө эргүүлэх"</string>
<string name="gesture_tutorial_rotation_prompt" msgid="1664493449851960691">"Зангааны навигацын практик хичээлийг дуусгахын тулд төхөөрөмжөө эргүүлнэ үү"</string>
<string name="back_gesture_feedback_swipe_too_far_from_edge" msgid="4175100312909721217">"Та баруун зах эсвэл зүүн захын ирмэгээс шударна уу"</string>
@@ -152,4 +154,7 @@
<string name="bubble_bar_accessibility_announce_expand" msgid="1503192695527477102">"<xliff:g id="BUBBLE_DESCRIPTION">%1$s</xliff:g>-г дэлгэх"</string>
<string name="bubble_bar_accessibility_announce_collapse" msgid="928284600086798791">"<xliff:g id="BUBBLE_DESCRIPTION">%1$s</xliff:g>-г хураах"</string>
<string name="search_gesture_feature_title" msgid="1294044108313175306">"Тойруулж зураад хай"</string>
+ <string name="header_app_icon_description" msgid="2184625881433608027">"Aппын дүрс тэмдэг"</string>
+ <string name="header_default_app_title" msgid="8308052350689531566">"Аппын нэр"</string>
+ <string name="header_close_icon_description" msgid="5400033616675911319">"Хаах товч"</string>
</resources>
diff --git a/quickstep/res/values-mr/strings.xml b/quickstep/res/values-mr/strings.xml
index 06b8bd8..647e88d 100644
--- a/quickstep/res/values-mr/strings.xml
+++ b/quickstep/res/values-mr/strings.xml
@@ -46,6 +46,8 @@
<string name="hotsaet_tip_prediction_enabled" msgid="2233554377501347650">"अॅप सूचना सुरू केल्या आहेत"</string>
<string name="hotsaet_tip_prediction_disabled" msgid="1506426298884658491">"अॅप सूचना बंद केल्या आहेत"</string>
<string name="hotseat_prediction_content_description" msgid="4582028296938078419">"पूर्वानुमान केलेले अॅप: <xliff:g id="TITLE">%1$s</xliff:g>"</string>
+ <!-- no translation found for gesture_tutorial_title (2750751261768388354) -->
+ <skip />
<string name="gesture_tutorial_rotation_prompt_title" msgid="7537946781362766964">"तुमचे डिव्हाइस फिरवा"</string>
<string name="gesture_tutorial_rotation_prompt" msgid="1664493449851960691">"कृपया जेश्चर नेव्हिगेशन ट्यूटोरियल पूर्ण करण्यासाठी तुमचे डिव्हाइस फिरवा"</string>
<string name="back_gesture_feedback_swipe_too_far_from_edge" msgid="4175100312909721217">"तुम्ही स्क्रीनच्या अगदी उजव्या किंवा अगदी डाव्या कडेपासून स्वाइप करत आहात खात्री करा"</string>
@@ -152,4 +154,7 @@
<string name="bubble_bar_accessibility_announce_expand" msgid="1503192695527477102">"<xliff:g id="BUBBLE_DESCRIPTION">%1$s</xliff:g> चा विस्तार करा"</string>
<string name="bubble_bar_accessibility_announce_collapse" msgid="928284600086798791">"<xliff:g id="BUBBLE_DESCRIPTION">%1$s</xliff:g> कोलॅप्स करा"</string>
<string name="search_gesture_feature_title" msgid="1294044108313175306">"शोधण्यासाठी वर्तुळ करा"</string>
+ <string name="header_app_icon_description" msgid="2184625881433608027">"अॅपचा आयकन"</string>
+ <string name="header_default_app_title" msgid="8308052350689531566">"अॅपचे शीर्षक"</string>
+ <string name="header_close_icon_description" msgid="5400033616675911319">"बंद करा बटण"</string>
</resources>
diff --git a/quickstep/res/values-ms/strings.xml b/quickstep/res/values-ms/strings.xml
index 82839e2..baffcbb 100644
--- a/quickstep/res/values-ms/strings.xml
+++ b/quickstep/res/values-ms/strings.xml
@@ -46,6 +46,8 @@
<string name="hotsaet_tip_prediction_enabled" msgid="2233554377501347650">"Cadangan apl didayakan"</string>
<string name="hotsaet_tip_prediction_disabled" msgid="1506426298884658491">"Cadangan apl dilumpuhkan"</string>
<string name="hotseat_prediction_content_description" msgid="4582028296938078419">"Apl yang diramalkan: <xliff:g id="TITLE">%1$s</xliff:g>"</string>
+ <!-- no translation found for gesture_tutorial_title (2750751261768388354) -->
+ <skip />
<string name="gesture_tutorial_rotation_prompt_title" msgid="7537946781362766964">"Putarkan peranti anda"</string>
<string name="gesture_tutorial_rotation_prompt" msgid="1664493449851960691">"Sila putarkan peranti anda untuk melengkapkan tutorial navigasi gerak isyarat"</string>
<string name="back_gesture_feedback_swipe_too_far_from_edge" msgid="4175100312909721217">"Pastikan anda meleret dari hujung sebelah kanan atau hujung sebelah kiri"</string>
@@ -152,4 +154,7 @@
<string name="bubble_bar_accessibility_announce_expand" msgid="1503192695527477102">"kembangkan <xliff:g id="BUBBLE_DESCRIPTION">%1$s</xliff:g>"</string>
<string name="bubble_bar_accessibility_announce_collapse" msgid="928284600086798791">"kuncupkan <xliff:g id="BUBBLE_DESCRIPTION">%1$s</xliff:g>"</string>
<string name="search_gesture_feature_title" msgid="1294044108313175306">"Bulatkan untuk Membuat Carian"</string>
+ <string name="header_app_icon_description" msgid="2184625881433608027">"Ikon apl"</string>
+ <string name="header_default_app_title" msgid="8308052350689531566">"Tajuk apl"</string>
+ <string name="header_close_icon_description" msgid="5400033616675911319">"Butang tutup"</string>
</resources>
diff --git a/quickstep/res/values-my/strings.xml b/quickstep/res/values-my/strings.xml
index 2951a09..f89920b 100644
--- a/quickstep/res/values-my/strings.xml
+++ b/quickstep/res/values-my/strings.xml
@@ -46,6 +46,8 @@
<string name="hotsaet_tip_prediction_enabled" msgid="2233554377501347650">"အက်ပ်အကြံပြုချက်များ ဖွင့်ထားသည်"</string>
<string name="hotsaet_tip_prediction_disabled" msgid="1506426298884658491">"အက်ပ်အကြံပြုချက်များကို ပိတ်ထားသည်"</string>
<string name="hotseat_prediction_content_description" msgid="4582028296938078419">"ကြိုတင်မှန်းဆထားသော အက်ပ်− <xliff:g id="TITLE">%1$s</xliff:g>"</string>
+ <!-- no translation found for gesture_tutorial_title (2750751261768388354) -->
+ <skip />
<string name="gesture_tutorial_rotation_prompt_title" msgid="7537946781362766964">"သင့်စက်ကို လှည့်ပါ"</string>
<string name="gesture_tutorial_rotation_prompt" msgid="1664493449851960691">"လက်ဟန်ဖြင့် လမ်းညွှန်ခြင်း ရှင်းလင်းပို့ချချက်အား အပြီးသတ်ရန် သင့်စက်ကို လှည့်ပါ"</string>
<string name="back_gesture_feedback_swipe_too_far_from_edge" msgid="4175100312909721217">"ညာ (သို့) ဘယ်ဘက်အစွန်ဆုံးမှ ပွတ်ဆွဲကြောင်း သေချာပါစေ"</string>
@@ -152,4 +154,7 @@
<string name="bubble_bar_accessibility_announce_expand" msgid="1503192695527477102">"<xliff:g id="BUBBLE_DESCRIPTION">%1$s</xliff:g> ကို ပိုပြပါ"</string>
<string name="bubble_bar_accessibility_announce_collapse" msgid="928284600086798791">"<xliff:g id="BUBBLE_DESCRIPTION">%1$s</xliff:g> ကို လျှော့ပြပါ"</string>
<string name="search_gesture_feature_title" msgid="1294044108313175306">"ရှာရန် ကွက်၍ဝိုင်းလိုက်ပါ"</string>
+ <string name="header_app_icon_description" msgid="2184625881433608027">"အက်ပ်သင်္ကေတ"</string>
+ <string name="header_default_app_title" msgid="8308052350689531566">"အက်ပ်ခေါင်းစဉ်"</string>
+ <string name="header_close_icon_description" msgid="5400033616675911319">"အပိတ် ခလုတ်"</string>
</resources>
diff --git a/quickstep/res/values-nb/strings.xml b/quickstep/res/values-nb/strings.xml
index c485ecf..3be8d68 100644
--- a/quickstep/res/values-nb/strings.xml
+++ b/quickstep/res/values-nb/strings.xml
@@ -46,6 +46,8 @@
<string name="hotsaet_tip_prediction_enabled" msgid="2233554377501347650">"Appforslag er på"</string>
<string name="hotsaet_tip_prediction_disabled" msgid="1506426298884658491">"Appforslag er slått av"</string>
<string name="hotseat_prediction_content_description" msgid="4582028296938078419">"Foreslått app: <xliff:g id="TITLE">%1$s</xliff:g>"</string>
+ <!-- no translation found for gesture_tutorial_title (2750751261768388354) -->
+ <skip />
<string name="gesture_tutorial_rotation_prompt_title" msgid="7537946781362766964">"Roter enheten"</string>
<string name="gesture_tutorial_rotation_prompt" msgid="1664493449851960691">"Roter enheten for å fullføre veiledningen for navigasjon med bevegelser"</string>
<string name="back_gesture_feedback_swipe_too_far_from_edge" msgid="4175100312909721217">"Sørg for at du sveiper fra kanten helt til høyre eller venstre"</string>
@@ -140,7 +142,7 @@
<string name="move_drop_target_top_or_left" msgid="2988702185049595807">"Flytt til øverst/venstre"</string>
<string name="move_drop_target_bottom_or_right" msgid="5431393418797620162">"Flytt til nederst/høyre"</string>
<string name="quick_switch_overflow" msgid="3679780650881041632">"{count,plural, =1{app til}other{apper til}}"</string>
- <string name="quick_switch_desktop" msgid="8393802056024499749">"Datamaskin"</string>
+ <string name="quick_switch_desktop" msgid="8393802056024499749">"Skrivebord"</string>
<string name="quick_switch_split_task" msgid="5598194724255333896">"<xliff:g id="APP_NAME_1">%1$s</xliff:g> og <xliff:g id="APP_NAME_2">%2$s</xliff:g>"</string>
<string name="bubble_bar_bubble_fallback_description" msgid="7811684548953452009">"Boble"</string>
<string name="bubble_bar_overflow_description" msgid="8617628132733151708">"Overflyt"</string>
@@ -152,4 +154,7 @@
<string name="bubble_bar_accessibility_announce_expand" msgid="1503192695527477102">"vis <xliff:g id="BUBBLE_DESCRIPTION">%1$s</xliff:g>"</string>
<string name="bubble_bar_accessibility_announce_collapse" msgid="928284600086798791">"skjul <xliff:g id="BUBBLE_DESCRIPTION">%1$s</xliff:g>"</string>
<string name="search_gesture_feature_title" msgid="1294044108313175306">"Circle to Search"</string>
+ <string name="header_app_icon_description" msgid="2184625881433608027">"Appikon"</string>
+ <string name="header_default_app_title" msgid="8308052350689531566">"Apptittel"</string>
+ <string name="header_close_icon_description" msgid="5400033616675911319">"Lukkeknapp"</string>
</resources>
diff --git a/quickstep/res/values-ne/strings.xml b/quickstep/res/values-ne/strings.xml
index 4d0e82a..4ed8bb9 100644
--- a/quickstep/res/values-ne/strings.xml
+++ b/quickstep/res/values-ne/strings.xml
@@ -46,6 +46,8 @@
<string name="hotsaet_tip_prediction_enabled" msgid="2233554377501347650">"सिफारिस गरिएका एप देखाउने सुविधा अन गरिएको छ"</string>
<string name="hotsaet_tip_prediction_disabled" msgid="1506426298884658491">"सिफारिस गरिएका एपहरू देखाउने सुविधा असक्षम पारिएको छ"</string>
<string name="hotseat_prediction_content_description" msgid="4582028296938078419">"पूर्वानुमान गरिएको एप: <xliff:g id="TITLE">%1$s</xliff:g>"</string>
+ <!-- no translation found for gesture_tutorial_title (2750751261768388354) -->
+ <skip />
<string name="gesture_tutorial_rotation_prompt_title" msgid="7537946781362766964">"आफ्नो डिभाइस रोटेट गर्नुहोस्"</string>
<string name="gesture_tutorial_rotation_prompt" msgid="1664493449851960691">"जेस्चर नेभिगेसनको ट्युटोरियल पूरा गर्न कृपया आफ्नो डिभाइस रोटेट गर्नुहोस्"</string>
<string name="back_gesture_feedback_swipe_too_far_from_edge" msgid="4175100312909721217">"स्क्रिनको सबैभन्दा दायाँ किनारा वा सबैभन्दा बायाँ किनाराबाट स्वाइप गर्नुहोस्"</string>
@@ -152,4 +154,7 @@
<string name="bubble_bar_accessibility_announce_expand" msgid="1503192695527477102">"<xliff:g id="BUBBLE_DESCRIPTION">%1$s</xliff:g> एक्स्पान्ड गर्नुहोस्"</string>
<string name="bubble_bar_accessibility_announce_collapse" msgid="928284600086798791">"<xliff:g id="BUBBLE_DESCRIPTION">%1$s</xliff:g> कोल्याप्स गर्नुहोस्"</string>
<string name="search_gesture_feature_title" msgid="1294044108313175306">"खोज्न सर्कल बनाउनुहोस्"</string>
+ <string name="header_app_icon_description" msgid="2184625881433608027">"एप जनाउने आइकन"</string>
+ <string name="header_default_app_title" msgid="8308052350689531566">"एपको शीर्षक"</string>
+ <string name="header_close_icon_description" msgid="5400033616675911319">"\"बन्द गर्नुहोस्\" बटन"</string>
</resources>
diff --git a/quickstep/res/values-nl/strings.xml b/quickstep/res/values-nl/strings.xml
index 20b132f..c1c1a22 100644
--- a/quickstep/res/values-nl/strings.xml
+++ b/quickstep/res/values-nl/strings.xml
@@ -46,6 +46,8 @@
<string name="hotsaet_tip_prediction_enabled" msgid="2233554377501347650">"App-suggesties staan aan"</string>
<string name="hotsaet_tip_prediction_disabled" msgid="1506426298884658491">"App-suggesties staan uit"</string>
<string name="hotseat_prediction_content_description" msgid="4582028296938078419">"Voorspelde app: <xliff:g id="TITLE">%1$s</xliff:g>"</string>
+ <!-- no translation found for gesture_tutorial_title (2750751261768388354) -->
+ <skip />
<string name="gesture_tutorial_rotation_prompt_title" msgid="7537946781362766964">"Het apparaat draaien"</string>
<string name="gesture_tutorial_rotation_prompt" msgid="1664493449851960691">"Draai het apparaat om de tutorial voor navigatie met gebaren af te ronden"</string>
<string name="back_gesture_feedback_swipe_too_far_from_edge" msgid="4175100312909721217">"Swipe vanaf de rechter- of linkerrand"</string>
@@ -152,4 +154,7 @@
<string name="bubble_bar_accessibility_announce_expand" msgid="1503192695527477102">"<xliff:g id="BUBBLE_DESCRIPTION">%1$s</xliff:g> uitvouwen"</string>
<string name="bubble_bar_accessibility_announce_collapse" msgid="928284600086798791">"<xliff:g id="BUBBLE_DESCRIPTION">%1$s</xliff:g> samenvouwen"</string>
<string name="search_gesture_feature_title" msgid="1294044108313175306">"Circle to Search"</string>
+ <string name="header_app_icon_description" msgid="2184625881433608027">"Icoon van app"</string>
+ <string name="header_default_app_title" msgid="8308052350689531566">"Titel van app"</string>
+ <string name="header_close_icon_description" msgid="5400033616675911319">"Knop Sluiten"</string>
</resources>
diff --git a/quickstep/res/values-or/strings.xml b/quickstep/res/values-or/strings.xml
index fe71252..789ba0a 100644
--- a/quickstep/res/values-or/strings.xml
+++ b/quickstep/res/values-or/strings.xml
@@ -46,6 +46,8 @@
<string name="hotsaet_tip_prediction_enabled" msgid="2233554377501347650">"ଆପ୍ ପରାମର୍ଶଗୁଡ଼ିକୁ ସକ୍ଷମ କରାଯାଇଛି"</string>
<string name="hotsaet_tip_prediction_disabled" msgid="1506426298884658491">"ଆପ୍ ପରାମର୍ଶଗୁଡ଼ିକୁ ଅକ୍ଷମ କରାଯାଇଛି"</string>
<string name="hotseat_prediction_content_description" msgid="4582028296938078419">"ପୂର୍ବାନୁମାନ କରାଯାଇଥିବା ଆପ୍: <xliff:g id="TITLE">%1$s</xliff:g>"</string>
+ <!-- no translation found for gesture_tutorial_title (2750751261768388354) -->
+ <skip />
<string name="gesture_tutorial_rotation_prompt_title" msgid="7537946781362766964">"ଆପଣଙ୍କ ଡିଭାଇସକୁ ରୋଟେଟ କରନ୍ତୁ"</string>
<string name="gesture_tutorial_rotation_prompt" msgid="1664493449851960691">"ଜେଶ୍ଚର ନାଭିଗେସନ ଟ୍ୟୁଟୋରିଆଲ ସମ୍ପୂର୍ଣ୍ଣ କରିବାକୁ ଦୟାକରି ଆପଣଙ୍କ ଡିଭାଇସ ରୋଟେଟ କରନ୍ତୁ"</string>
<string name="back_gesture_feedback_swipe_too_far_from_edge" msgid="4175100312909721217">"ଆପଣ ସ୍କ୍ରିନର ଏକଦମ-ଡାହାଣ ବା ବାମ ଧାରରୁ ସ୍ୱାଇପ କରୁଥିବା ସୁନିଶ୍ଚିତ କରନ୍ତୁ।"</string>
@@ -152,4 +154,7 @@
<string name="bubble_bar_accessibility_announce_expand" msgid="1503192695527477102">"<xliff:g id="BUBBLE_DESCRIPTION">%1$s</xliff:g> ବିସ୍ତାର କରନ୍ତୁ"</string>
<string name="bubble_bar_accessibility_announce_collapse" msgid="928284600086798791">"<xliff:g id="BUBBLE_DESCRIPTION">%1$s</xliff:g> ସଙ୍କୁଚିତ କରନ୍ତୁ"</string>
<string name="search_gesture_feature_title" msgid="1294044108313175306">"ସର୍ଚ୍ଚ କରିବାକୁ ସର୍କଲ କରନ୍ତୁ"</string>
+ <string name="header_app_icon_description" msgid="2184625881433608027">"ଆପ ଆଇକନ"</string>
+ <string name="header_default_app_title" msgid="8308052350689531566">"ଆପ ଟାଇଟେଲ"</string>
+ <string name="header_close_icon_description" msgid="5400033616675911319">"\"ବନ୍ଦ କରନ୍ତୁ\" ବଟନ"</string>
</resources>
diff --git a/quickstep/res/values-pa/strings.xml b/quickstep/res/values-pa/strings.xml
index 73b971f..2392890 100644
--- a/quickstep/res/values-pa/strings.xml
+++ b/quickstep/res/values-pa/strings.xml
@@ -46,6 +46,8 @@
<string name="hotsaet_tip_prediction_enabled" msgid="2233554377501347650">"ਐਪ ਸੁਝਾਵਾਂ ਨੂੰ ਚਾਲੂ ਕੀਤਾ ਗਿਆ"</string>
<string name="hotsaet_tip_prediction_disabled" msgid="1506426298884658491">"ਐਪ ਸੁਝਾਵਾਂ ਨੂੰ ਬੰਦ ਕੀਤਾ ਗਿਆ"</string>
<string name="hotseat_prediction_content_description" msgid="4582028296938078419">"ਪੂਰਵ ਅਨੁਮਾਨਿਤ ਐਪ: <xliff:g id="TITLE">%1$s</xliff:g>"</string>
+ <!-- no translation found for gesture_tutorial_title (2750751261768388354) -->
+ <skip />
<string name="gesture_tutorial_rotation_prompt_title" msgid="7537946781362766964">"ਆਪਣੇ ਡੀਵਾਈਸ ਨੂੰ ਘੁੰਮਾਓ"</string>
<string name="gesture_tutorial_rotation_prompt" msgid="1664493449851960691">"ਕਿਰਪਾ ਕਰਕੇ ਇਸ਼ਾਰਾ ਨੈਵੀਗੇਸ਼ਨ ਟਿਊਟੋਰੀਅਲ ਨੂੰ ਪੂਰਾ ਕਰਨ ਲਈ ਆਪਣੇ ਡੀਵਾਈਸ ਨੂੰ ਘੁੰਮਾਓ"</string>
<string name="back_gesture_feedback_swipe_too_far_from_edge" msgid="4175100312909721217">"ਇਹ ਪੱਕਾ ਕਰੋ ਕਿ ਤੁਸੀਂ ਸੱਜੇ ਜਾਂ ਖੱਬੇ ਪਾਸੇ ਦੇ ਬਿਲਕੁਲ ਕਿਨਾਰੇ ਤੋਂ ਸਵਾਈਪ ਕਰਦੇ ਹੋ"</string>
@@ -152,4 +154,7 @@
<string name="bubble_bar_accessibility_announce_expand" msgid="1503192695527477102">"<xliff:g id="BUBBLE_DESCRIPTION">%1$s</xliff:g> ਦਾ ਵਿਸਤਾਰ ਕਰੋ"</string>
<string name="bubble_bar_accessibility_announce_collapse" msgid="928284600086798791">"<xliff:g id="BUBBLE_DESCRIPTION">%1$s</xliff:g> ਨੂੰ ਸਮੇਟੋ"</string>
<string name="search_gesture_feature_title" msgid="1294044108313175306">"ਖੋਜਣ ਲਈ ਚੱਕਰ ਬਣਾਓ"</string>
+ <string name="header_app_icon_description" msgid="2184625881433608027">"ਐਪ ਪ੍ਰਤੀਕ"</string>
+ <string name="header_default_app_title" msgid="8308052350689531566">"ਐਪ ਸਿਰਲੇਖ"</string>
+ <string name="header_close_icon_description" msgid="5400033616675911319">"\'ਬੰਦ ਕਰੋ\' ਬਟਨ"</string>
</resources>
diff --git a/quickstep/res/values-pl/strings.xml b/quickstep/res/values-pl/strings.xml
index 4eb9c45..74aec66 100644
--- a/quickstep/res/values-pl/strings.xml
+++ b/quickstep/res/values-pl/strings.xml
@@ -46,6 +46,8 @@
<string name="hotsaet_tip_prediction_enabled" msgid="2233554377501347650">"Włączono sugestie aplikacji"</string>
<string name="hotsaet_tip_prediction_disabled" msgid="1506426298884658491">"Sugestie aplikacji są wyłączone"</string>
<string name="hotseat_prediction_content_description" msgid="4582028296938078419">"Przewidywana aplikacja: <xliff:g id="TITLE">%1$s</xliff:g>"</string>
+ <!-- no translation found for gesture_tutorial_title (2750751261768388354) -->
+ <skip />
<string name="gesture_tutorial_rotation_prompt_title" msgid="7537946781362766964">"Obróć urządzenie"</string>
<string name="gesture_tutorial_rotation_prompt" msgid="1664493449851960691">"Obróć urządzenie, aby ukończyć samouczek nawigacji przy użyciu gestów"</string>
<string name="back_gesture_feedback_swipe_too_far_from_edge" msgid="4175100312909721217">"Pamiętaj, aby przesuwać palcem od samej krawędzi (prawej lub lewej)"</string>
@@ -152,4 +154,7 @@
<string name="bubble_bar_accessibility_announce_expand" msgid="1503192695527477102">"rozwiń dymek: <xliff:g id="BUBBLE_DESCRIPTION">%1$s</xliff:g>"</string>
<string name="bubble_bar_accessibility_announce_collapse" msgid="928284600086798791">"zwiń dymek: <xliff:g id="BUBBLE_DESCRIPTION">%1$s</xliff:g>"</string>
<string name="search_gesture_feature_title" msgid="1294044108313175306">"Zaznacz, aby wyszukać"</string>
+ <string name="header_app_icon_description" msgid="2184625881433608027">"Ikona aplikacji"</string>
+ <string name="header_default_app_title" msgid="8308052350689531566">"Tytuł aplikacji"</string>
+ <string name="header_close_icon_description" msgid="5400033616675911319">"Przycisk Zamknij"</string>
</resources>
diff --git a/quickstep/res/values-pt-rPT/strings.xml b/quickstep/res/values-pt-rPT/strings.xml
index a2e3a43..56d5514 100644
--- a/quickstep/res/values-pt-rPT/strings.xml
+++ b/quickstep/res/values-pt-rPT/strings.xml
@@ -46,6 +46,8 @@
<string name="hotsaet_tip_prediction_enabled" msgid="2233554377501347650">"Sugestões de apps ativadas"</string>
<string name="hotsaet_tip_prediction_disabled" msgid="1506426298884658491">"As sugestões de apps estão desativadas"</string>
<string name="hotseat_prediction_content_description" msgid="4582028296938078419">"App prevista: <xliff:g id="TITLE">%1$s</xliff:g>"</string>
+ <!-- no translation found for gesture_tutorial_title (2750751261768388354) -->
+ <skip />
<string name="gesture_tutorial_rotation_prompt_title" msgid="7537946781362766964">"Rode o dispositivo"</string>
<string name="gesture_tutorial_rotation_prompt" msgid="1664493449851960691">"Rode o seu dispositivo para concluir o tutorial de navegação por gestos"</string>
<string name="back_gesture_feedback_swipe_too_far_from_edge" msgid="4175100312909721217">"Deslize a partir da extremidade mais à direita ou mais à esquerda"</string>
@@ -152,4 +154,7 @@
<string name="bubble_bar_accessibility_announce_expand" msgid="1503192695527477102">"expandir <xliff:g id="BUBBLE_DESCRIPTION">%1$s</xliff:g>"</string>
<string name="bubble_bar_accessibility_announce_collapse" msgid="928284600086798791">"reduzir <xliff:g id="BUBBLE_DESCRIPTION">%1$s</xliff:g>"</string>
<string name="search_gesture_feature_title" msgid="1294044108313175306">"Circundar para Pesquisar"</string>
+ <string name="header_app_icon_description" msgid="2184625881433608027">"Ícone da app"</string>
+ <string name="header_default_app_title" msgid="8308052350689531566">"Título da app"</string>
+ <string name="header_close_icon_description" msgid="5400033616675911319">"Botão Fechar"</string>
</resources>
diff --git a/quickstep/res/values-pt/strings.xml b/quickstep/res/values-pt/strings.xml
index f7022ec..bdcad13 100644
--- a/quickstep/res/values-pt/strings.xml
+++ b/quickstep/res/values-pt/strings.xml
@@ -46,6 +46,8 @@
<string name="hotsaet_tip_prediction_enabled" msgid="2233554377501347650">"O recurso \"sugestões de apps\" está ativado"</string>
<string name="hotsaet_tip_prediction_disabled" msgid="1506426298884658491">"O recurso \"sugestões de apps\" está desativado"</string>
<string name="hotseat_prediction_content_description" msgid="4582028296938078419">"App previsto: <xliff:g id="TITLE">%1$s</xliff:g>"</string>
+ <!-- no translation found for gesture_tutorial_title (2750751261768388354) -->
+ <skip />
<string name="gesture_tutorial_rotation_prompt_title" msgid="7537946781362766964">"Gire o dispositivo"</string>
<string name="gesture_tutorial_rotation_prompt" msgid="1664493449851960691">"Gire o dispositivo para concluir o tutorial da navegação por gestos"</string>
<string name="back_gesture_feedback_swipe_too_far_from_edge" msgid="4175100312909721217">"Deslize da borda direita ou esquerda"</string>
@@ -152,4 +154,7 @@
<string name="bubble_bar_accessibility_announce_expand" msgid="1503192695527477102">"abrir <xliff:g id="BUBBLE_DESCRIPTION">%1$s</xliff:g>"</string>
<string name="bubble_bar_accessibility_announce_collapse" msgid="928284600086798791">"fechar <xliff:g id="BUBBLE_DESCRIPTION">%1$s</xliff:g>"</string>
<string name="search_gesture_feature_title" msgid="1294044108313175306">"Circule para pesquisar"</string>
+ <string name="header_app_icon_description" msgid="2184625881433608027">"Ícone do app"</string>
+ <string name="header_default_app_title" msgid="8308052350689531566">"Título do app"</string>
+ <string name="header_close_icon_description" msgid="5400033616675911319">"Botão \"Fechar\""</string>
</resources>
diff --git a/quickstep/res/values-ro/strings.xml b/quickstep/res/values-ro/strings.xml
index 4ad6846..6a05909 100644
--- a/quickstep/res/values-ro/strings.xml
+++ b/quickstep/res/values-ro/strings.xml
@@ -46,6 +46,8 @@
<string name="hotsaet_tip_prediction_enabled" msgid="2233554377501347650">"Sugestiile de aplicații au fost activate"</string>
<string name="hotsaet_tip_prediction_disabled" msgid="1506426298884658491">"Sugestiile de aplicații au fost dezactivate"</string>
<string name="hotseat_prediction_content_description" msgid="4582028296938078419">"Aplicația estimată: <xliff:g id="TITLE">%1$s</xliff:g>"</string>
+ <!-- no translation found for gesture_tutorial_title (2750751261768388354) -->
+ <skip />
<string name="gesture_tutorial_rotation_prompt_title" msgid="7537946781362766964">"Rotește dispozitivul"</string>
<string name="gesture_tutorial_rotation_prompt" msgid="1664493449851960691">"Rotește dispozitivul pentru a încheia tutorialul de navigare prin gesturi"</string>
<string name="back_gesture_feedback_swipe_too_far_from_edge" msgid="4175100312909721217">"Glisează dinspre marginea dreaptă îndepărtată sau dinspre marginea stângă îndepărtată"</string>
@@ -152,4 +154,7 @@
<string name="bubble_bar_accessibility_announce_expand" msgid="1503192695527477102">"extinde <xliff:g id="BUBBLE_DESCRIPTION">%1$s</xliff:g>"</string>
<string name="bubble_bar_accessibility_announce_collapse" msgid="928284600086798791">"restrânge <xliff:g id="BUBBLE_DESCRIPTION">%1$s</xliff:g>"</string>
<string name="search_gesture_feature_title" msgid="1294044108313175306">"Încercuiește și caută"</string>
+ <string name="header_app_icon_description" msgid="2184625881433608027">"Pictograma aplicației"</string>
+ <string name="header_default_app_title" msgid="8308052350689531566">"Titlul aplicației"</string>
+ <string name="header_close_icon_description" msgid="5400033616675911319">"Buton de închidere"</string>
</resources>
diff --git a/quickstep/res/values-ru/strings.xml b/quickstep/res/values-ru/strings.xml
index 2a52261..69f560d 100644
--- a/quickstep/res/values-ru/strings.xml
+++ b/quickstep/res/values-ru/strings.xml
@@ -46,6 +46,8 @@
<string name="hotsaet_tip_prediction_enabled" msgid="2233554377501347650">"Функция \"Рекомендуемые приложения\" включена."</string>
<string name="hotsaet_tip_prediction_disabled" msgid="1506426298884658491">"Функция \"Рекомендуемые приложения\" отключена."</string>
<string name="hotseat_prediction_content_description" msgid="4582028296938078419">"Рекомендуемое приложение: <xliff:g id="TITLE">%1$s</xliff:g>"</string>
+ <!-- no translation found for gesture_tutorial_title (2750751261768388354) -->
+ <skip />
<string name="gesture_tutorial_rotation_prompt_title" msgid="7537946781362766964">"Поверните устройство"</string>
<string name="gesture_tutorial_rotation_prompt" msgid="1664493449851960691">"Чтобы перейти к руководству по жестам, нужно повернуть устройство."</string>
<string name="back_gesture_feedback_swipe_too_far_from_edge" msgid="4175100312909721217">"Проведите справа налево или слева направо от самого края экрана."</string>
@@ -152,4 +154,7 @@
<string name="bubble_bar_accessibility_announce_expand" msgid="1503192695527477102">"Развернуто: <xliff:g id="BUBBLE_DESCRIPTION">%1$s</xliff:g>"</string>
<string name="bubble_bar_accessibility_announce_collapse" msgid="928284600086798791">"Свернуто: <xliff:g id="BUBBLE_DESCRIPTION">%1$s</xliff:g>"</string>
<string name="search_gesture_feature_title" msgid="1294044108313175306">"Обвести и найти"</string>
+ <string name="header_app_icon_description" msgid="2184625881433608027">"Значок приложения"</string>
+ <string name="header_default_app_title" msgid="8308052350689531566">"Название приложения"</string>
+ <string name="header_close_icon_description" msgid="5400033616675911319">"Кнопка \"Закрыть\""</string>
</resources>
diff --git a/quickstep/res/values-si/strings.xml b/quickstep/res/values-si/strings.xml
index bb95988..2b1f147 100644
--- a/quickstep/res/values-si/strings.xml
+++ b/quickstep/res/values-si/strings.xml
@@ -46,6 +46,8 @@
<string name="hotsaet_tip_prediction_enabled" msgid="2233554377501347650">"යෙදුම් යෝජනා සබලිතයි"</string>
<string name="hotsaet_tip_prediction_disabled" msgid="1506426298884658491">"යෙදුම් යෝජනා අබල කර ඇත"</string>
<string name="hotseat_prediction_content_description" msgid="4582028296938078419">"පුරෝකථනය කළ යෙදුම: <xliff:g id="TITLE">%1$s</xliff:g>"</string>
+ <!-- no translation found for gesture_tutorial_title (2750751261768388354) -->
+ <skip />
<string name="gesture_tutorial_rotation_prompt_title" msgid="7537946781362766964">"ඔබේ උපාංගය කරකවන්න"</string>
<string name="gesture_tutorial_rotation_prompt" msgid="1664493449851960691">"අභින සංචාලන නිබන්ධනය සම්පූර්ණ කිරීම සඳහා ඔබේ උපාංගය කරකවන්න"</string>
<string name="back_gesture_feedback_swipe_too_far_from_edge" msgid="4175100312909721217">"ඔබ ඈත දකුණු හෝ ඈත වම් දාරයේ සිට ස්වයිප් කරන බව සහතික කර ගන්න"</string>
@@ -152,4 +154,7 @@
<string name="bubble_bar_accessibility_announce_expand" msgid="1503192695527477102">"<xliff:g id="BUBBLE_DESCRIPTION">%1$s</xliff:g> දිග හරින්න"</string>
<string name="bubble_bar_accessibility_announce_collapse" msgid="928284600086798791">"<xliff:g id="BUBBLE_DESCRIPTION">%1$s</xliff:g> හකුළන්න"</string>
<string name="search_gesture_feature_title" msgid="1294044108313175306">"සෙවීමට කවයසෙවීමට කවය අදින්න"</string>
+ <string name="header_app_icon_description" msgid="2184625881433608027">"යෙදුම් නිරූපකය"</string>
+ <string name="header_default_app_title" msgid="8308052350689531566">"යෙදුම් මාතෘකාව"</string>
+ <string name="header_close_icon_description" msgid="5400033616675911319">"වැසීමේ බොත්තම"</string>
</resources>
diff --git a/quickstep/res/values-sk/strings.xml b/quickstep/res/values-sk/strings.xml
index bd22b29..c2e6b85 100644
--- a/quickstep/res/values-sk/strings.xml
+++ b/quickstep/res/values-sk/strings.xml
@@ -46,6 +46,8 @@
<string name="hotsaet_tip_prediction_enabled" msgid="2233554377501347650">"Návrhy aplikácií zapnuté"</string>
<string name="hotsaet_tip_prediction_disabled" msgid="1506426298884658491">"Návrhy aplikácií vypnuté"</string>
<string name="hotseat_prediction_content_description" msgid="4582028296938078419">"Predpovedaná aplikácia: <xliff:g id="TITLE">%1$s</xliff:g>"</string>
+ <!-- no translation found for gesture_tutorial_title (2750751261768388354) -->
+ <skip />
<string name="gesture_tutorial_rotation_prompt_title" msgid="7537946781362766964">"Otočte zariadenie"</string>
<string name="gesture_tutorial_rotation_prompt" msgid="1664493449851960691">"Otočte zariadenie a dokončite tak návod, ako navigovať gestami"</string>
<string name="back_gesture_feedback_swipe_too_far_from_edge" msgid="4175100312909721217">"Musíte potiahnuť úplne z pravého alebo ľavého okraja."</string>
@@ -152,4 +154,7 @@
<string name="bubble_bar_accessibility_announce_expand" msgid="1503192695527477102">"rozbaliť <xliff:g id="BUBBLE_DESCRIPTION">%1$s</xliff:g>"</string>
<string name="bubble_bar_accessibility_announce_collapse" msgid="928284600086798791">"zbaliť <xliff:g id="BUBBLE_DESCRIPTION">%1$s</xliff:g>"</string>
<string name="search_gesture_feature_title" msgid="1294044108313175306">"Vyhľadávanie krúžením"</string>
+ <string name="header_app_icon_description" msgid="2184625881433608027">"Ikona aplikácie"</string>
+ <string name="header_default_app_title" msgid="8308052350689531566">"Názov aplikácie"</string>
+ <string name="header_close_icon_description" msgid="5400033616675911319">"Tlačidlo Zavrieť"</string>
</resources>
diff --git a/quickstep/res/values-sl/strings.xml b/quickstep/res/values-sl/strings.xml
index 740d95e..0922f24 100644
--- a/quickstep/res/values-sl/strings.xml
+++ b/quickstep/res/values-sl/strings.xml
@@ -46,6 +46,8 @@
<string name="hotsaet_tip_prediction_enabled" msgid="2233554377501347650">"Predlogi aplikacij so omogočeni."</string>
<string name="hotsaet_tip_prediction_disabled" msgid="1506426298884658491">"Predlogi aplikacij so onemogočeni."</string>
<string name="hotseat_prediction_content_description" msgid="4582028296938078419">"Predvidena aplikacija: <xliff:g id="TITLE">%1$s</xliff:g>"</string>
+ <!-- no translation found for gesture_tutorial_title (2750751261768388354) -->
+ <skip />
<string name="gesture_tutorial_rotation_prompt_title" msgid="7537946781362766964">"Zasukajte napravo"</string>
<string name="gesture_tutorial_rotation_prompt" msgid="1664493449851960691">"Zasukajte napravo, če si želite ogledati vadnico za krmarjenje s potezami"</string>
<string name="back_gesture_feedback_swipe_too_far_from_edge" msgid="4175100312909721217">"Pazite, da povlečete s skrajno desnega ali skrajno levega roba."</string>
@@ -152,4 +154,7 @@
<string name="bubble_bar_accessibility_announce_expand" msgid="1503192695527477102">"razširitev oblačka <xliff:g id="BUBBLE_DESCRIPTION">%1$s</xliff:g>"</string>
<string name="bubble_bar_accessibility_announce_collapse" msgid="928284600086798791">"strnitev oblačka <xliff:g id="BUBBLE_DESCRIPTION">%1$s</xliff:g>"</string>
<string name="search_gesture_feature_title" msgid="1294044108313175306">"Iskanje z obkroževanjem"</string>
+ <string name="header_app_icon_description" msgid="2184625881433608027">"Ikona aplikacije"</string>
+ <string name="header_default_app_title" msgid="8308052350689531566">"Ime aplikacije"</string>
+ <string name="header_close_icon_description" msgid="5400033616675911319">"Gumb za zapiranje"</string>
</resources>
diff --git a/quickstep/res/values-sq/strings.xml b/quickstep/res/values-sq/strings.xml
index 12d824f..50b9fa1 100644
--- a/quickstep/res/values-sq/strings.xml
+++ b/quickstep/res/values-sq/strings.xml
@@ -46,6 +46,8 @@
<string name="hotsaet_tip_prediction_enabled" msgid="2233554377501347650">"Aplikacionet e sugjeruara janë aktivizuar"</string>
<string name="hotsaet_tip_prediction_disabled" msgid="1506426298884658491">"Sugjerimet e aplikacioneve janë çaktivizuar"</string>
<string name="hotseat_prediction_content_description" msgid="4582028296938078419">"Aplikacioni i parashikuar: <xliff:g id="TITLE">%1$s</xliff:g>"</string>
+ <!-- no translation found for gesture_tutorial_title (2750751261768388354) -->
+ <skip />
<string name="gesture_tutorial_rotation_prompt_title" msgid="7537946781362766964">"Rrotullo pajisjen"</string>
<string name="gesture_tutorial_rotation_prompt" msgid="1664493449851960691">"Rrotullo pajisjen për të përfunduar udhëzuesin e navigimit me gjeste"</string>
<string name="back_gesture_feedback_swipe_too_far_from_edge" msgid="4175100312909721217">"Sigurohu që të rrëshqasësh shpejt nga skaji më i djathtë ose më i majtë"</string>
@@ -152,4 +154,7 @@
<string name="bubble_bar_accessibility_announce_expand" msgid="1503192695527477102">"zgjero <xliff:g id="BUBBLE_DESCRIPTION">%1$s</xliff:g>"</string>
<string name="bubble_bar_accessibility_announce_collapse" msgid="928284600086798791">"palos <xliff:g id="BUBBLE_DESCRIPTION">%1$s</xliff:g>"</string>
<string name="search_gesture_feature_title" msgid="1294044108313175306">"Qarko për të kërkuar"</string>
+ <string name="header_app_icon_description" msgid="2184625881433608027">"Ikona e aplikacionit"</string>
+ <string name="header_default_app_title" msgid="8308052350689531566">"Titulli i aplikacionit"</string>
+ <string name="header_close_icon_description" msgid="5400033616675911319">"Butoni i mbylljes"</string>
</resources>
diff --git a/quickstep/res/values-sr/strings.xml b/quickstep/res/values-sr/strings.xml
index b6830aa..a20e927 100644
--- a/quickstep/res/values-sr/strings.xml
+++ b/quickstep/res/values-sr/strings.xml
@@ -46,6 +46,8 @@
<string name="hotsaet_tip_prediction_enabled" msgid="2233554377501347650">"Предлози апликација су омогућени"</string>
<string name="hotsaet_tip_prediction_disabled" msgid="1506426298884658491">"Предлози апликација су онемогућени"</string>
<string name="hotseat_prediction_content_description" msgid="4582028296938078419">"Предвиђамо апликацију: <xliff:g id="TITLE">%1$s</xliff:g>"</string>
+ <!-- no translation found for gesture_tutorial_title (2750751261768388354) -->
+ <skip />
<string name="gesture_tutorial_rotation_prompt_title" msgid="7537946781362766964">"Ротирајте уређај"</string>
<string name="gesture_tutorial_rotation_prompt" msgid="1664493449851960691">"Ротирајте уређај да бисте довршили водич за навигацију помоћу покрета"</string>
<string name="back_gesture_feedback_swipe_too_far_from_edge" msgid="4175100312909721217">"Обавезно превуците од саме десне или леве ивице"</string>
@@ -152,4 +154,7 @@
<string name="bubble_bar_accessibility_announce_expand" msgid="1503192695527477102">"проширите облачић <xliff:g id="BUBBLE_DESCRIPTION">%1$s</xliff:g>"</string>
<string name="bubble_bar_accessibility_announce_collapse" msgid="928284600086798791">"скупите облачић <xliff:g id="BUBBLE_DESCRIPTION">%1$s</xliff:g>"</string>
<string name="search_gesture_feature_title" msgid="1294044108313175306">"Претрага заокруживањем"</string>
+ <string name="header_app_icon_description" msgid="2184625881433608027">"Икона апликације"</string>
+ <string name="header_default_app_title" msgid="8308052350689531566">"Назив апликације"</string>
+ <string name="header_close_icon_description" msgid="5400033616675911319">"Дугме Затвори"</string>
</resources>
diff --git a/quickstep/res/values-sv/strings.xml b/quickstep/res/values-sv/strings.xml
index c752a79..7c826cd 100644
--- a/quickstep/res/values-sv/strings.xml
+++ b/quickstep/res/values-sv/strings.xml
@@ -21,9 +21,9 @@
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
<string name="recent_task_option_pin" msgid="7929860679018978258">"Fäst"</string>
<string name="recent_task_option_freeform" msgid="48863056265284071">"Fritt format"</string>
- <string name="recent_task_option_desktop" msgid="8280879717125435668">"Dator"</string>
+ <string name="recent_task_option_desktop" msgid="8280879717125435668">"Skrivbordsläge"</string>
<string name="recent_task_option_external_display" msgid="4533840664313389484">"Flytta till extern skärm"</string>
- <string name="recent_task_desktop" msgid="8081113562549637334">"Dator"</string>
+ <string name="recent_task_desktop" msgid="8081113562549637334">"Skrivbordsläge"</string>
<string name="recents_empty_message" msgid="7040467240571714191">"Listan är tom"</string>
<string name="accessibility_app_usage_settings" msgid="6312864233673544149">"Inställningar för appanvändning"</string>
<string name="recents_clear_all" msgid="5328176793634888831">"Rensa alla"</string>
@@ -46,6 +46,8 @@
<string name="hotsaet_tip_prediction_enabled" msgid="2233554377501347650">"Appförslag har aktiverats"</string>
<string name="hotsaet_tip_prediction_disabled" msgid="1506426298884658491">"Appförslag har inaktiverats"</string>
<string name="hotseat_prediction_content_description" msgid="4582028296938078419">"Appförslag: <xliff:g id="TITLE">%1$s</xliff:g>"</string>
+ <!-- no translation found for gesture_tutorial_title (2750751261768388354) -->
+ <skip />
<string name="gesture_tutorial_rotation_prompt_title" msgid="7537946781362766964">"Rotera enheten"</string>
<string name="gesture_tutorial_rotation_prompt" msgid="1664493449851960691">"Rotera enheten för att slutföra guiden för navigering med rörelser"</string>
<string name="back_gesture_feedback_swipe_too_far_from_edge" msgid="4175100312909721217">"Se till att du sveper ända från högerkanten eller vänsterkanten"</string>
@@ -140,7 +142,7 @@
<string name="move_drop_target_top_or_left" msgid="2988702185049595807">"Flytta högst upp/till vänster"</string>
<string name="move_drop_target_bottom_or_right" msgid="5431393418797620162">"Flytta längst ned/till höger"</string>
<string name="quick_switch_overflow" msgid="3679780650881041632">"{count,plural, =1{app till}other{appar till}}"</string>
- <string name="quick_switch_desktop" msgid="8393802056024499749">"Dator"</string>
+ <string name="quick_switch_desktop" msgid="8393802056024499749">"Skrivbordsläge"</string>
<string name="quick_switch_split_task" msgid="5598194724255333896">"<xliff:g id="APP_NAME_1">%1$s</xliff:g> och <xliff:g id="APP_NAME_2">%2$s</xliff:g>"</string>
<string name="bubble_bar_bubble_fallback_description" msgid="7811684548953452009">"Bubbla"</string>
<string name="bubble_bar_overflow_description" msgid="8617628132733151708">"Fler alternativ"</string>
@@ -152,4 +154,7 @@
<string name="bubble_bar_accessibility_announce_expand" msgid="1503192695527477102">"utöka <xliff:g id="BUBBLE_DESCRIPTION">%1$s</xliff:g>"</string>
<string name="bubble_bar_accessibility_announce_collapse" msgid="928284600086798791">"komprimera <xliff:g id="BUBBLE_DESCRIPTION">%1$s</xliff:g>"</string>
<string name="search_gesture_feature_title" msgid="1294044108313175306">"Circle to Search"</string>
+ <string name="header_app_icon_description" msgid="2184625881433608027">"Appikon"</string>
+ <string name="header_default_app_title" msgid="8308052350689531566">"Apptitel"</string>
+ <string name="header_close_icon_description" msgid="5400033616675911319">"Knappen Stäng"</string>
</resources>
diff --git a/quickstep/res/values-sw/strings.xml b/quickstep/res/values-sw/strings.xml
index 05d120c..9181599 100644
--- a/quickstep/res/values-sw/strings.xml
+++ b/quickstep/res/values-sw/strings.xml
@@ -46,6 +46,8 @@
<string name="hotsaet_tip_prediction_enabled" msgid="2233554377501347650">"Mapendekezo ya programu yamewashwa"</string>
<string name="hotsaet_tip_prediction_disabled" msgid="1506426298884658491">"Umezima mapendekezo ya programu"</string>
<string name="hotseat_prediction_content_description" msgid="4582028296938078419">"Programu iliyotabiriwa: <xliff:g id="TITLE">%1$s</xliff:g>"</string>
+ <!-- no translation found for gesture_tutorial_title (2750751261768388354) -->
+ <skip />
<string name="gesture_tutorial_rotation_prompt_title" msgid="7537946781362766964">"Zungusha kifaa chako"</string>
<string name="gesture_tutorial_rotation_prompt" msgid="1664493449851960691">"Tafadhali zungusha kifaa chako ili ukamilishe mafunzo ya usogezaji kwa kutumia ishara"</string>
<string name="back_gesture_feedback_swipe_too_far_from_edge" msgid="4175100312909721217">"Hakikisha unatelezesha kidole kutoka ukingo wa kulia au kushoto kabisa"</string>
@@ -152,4 +154,7 @@
<string name="bubble_bar_accessibility_announce_expand" msgid="1503192695527477102">"panua <xliff:g id="BUBBLE_DESCRIPTION">%1$s</xliff:g>"</string>
<string name="bubble_bar_accessibility_announce_collapse" msgid="928284600086798791">"kunja <xliff:g id="BUBBLE_DESCRIPTION">%1$s</xliff:g>"</string>
<string name="search_gesture_feature_title" msgid="1294044108313175306">"Chora Mviringo ili Kutafuta"</string>
+ <string name="header_app_icon_description" msgid="2184625881433608027">"Aikoni ya programu"</string>
+ <string name="header_default_app_title" msgid="8308052350689531566">"Kichwa cha programu"</string>
+ <string name="header_close_icon_description" msgid="5400033616675911319">"Kitufe cha kufunga"</string>
</resources>
diff --git a/quickstep/res/values-ta/strings.xml b/quickstep/res/values-ta/strings.xml
index 75ef7f0..4e3a075 100644
--- a/quickstep/res/values-ta/strings.xml
+++ b/quickstep/res/values-ta/strings.xml
@@ -46,6 +46,8 @@
<string name="hotsaet_tip_prediction_enabled" msgid="2233554377501347650">"ஆப்ஸ் பரிந்துரைகள் இயக்கப்பட்டுள்ளன"</string>
<string name="hotsaet_tip_prediction_disabled" msgid="1506426298884658491">"ஆப்ஸ் பரிந்துரைகள் முடக்கப்பட்டுள்ளன"</string>
<string name="hotseat_prediction_content_description" msgid="4582028296938078419">"கணித்த ஆப்ஸ்: <xliff:g id="TITLE">%1$s</xliff:g>"</string>
+ <!-- no translation found for gesture_tutorial_title (2750751261768388354) -->
+ <skip />
<string name="gesture_tutorial_rotation_prompt_title" msgid="7537946781362766964">"உங்கள் சாதனத்தைச் சுழற்றுங்கள்"</string>
<string name="gesture_tutorial_rotation_prompt" msgid="1664493449851960691">"சைகை வழிசெலுத்தல் பயிற்சியை நிறைவுசெய்ய உங்கள் சாதனத்தைச் சுழற்றுங்கள்"</string>
<string name="back_gesture_feedback_swipe_too_far_from_edge" msgid="4175100312909721217">"வலது அல்லது இடது ஓரத்தின் விளிம்பிலிருந்து ஸ்வைப் செய்வதை உறுதிசெய்துகொள்ளுங்கள்"</string>
@@ -152,4 +154,7 @@
<string name="bubble_bar_accessibility_announce_expand" msgid="1503192695527477102">"<xliff:g id="BUBBLE_DESCRIPTION">%1$s</xliff:g> ஐ விரிவாக்கும்"</string>
<string name="bubble_bar_accessibility_announce_collapse" msgid="928284600086798791">"<xliff:g id="BUBBLE_DESCRIPTION">%1$s</xliff:g> ஐச் சுருக்கும்"</string>
<string name="search_gesture_feature_title" msgid="1294044108313175306">"வட்டமிட்டுத் தேடல்"</string>
+ <string name="header_app_icon_description" msgid="2184625881433608027">"ஆப்ஸ் ஐகான்"</string>
+ <string name="header_default_app_title" msgid="8308052350689531566">"ஆப்ஸ் தலைப்பு"</string>
+ <string name="header_close_icon_description" msgid="5400033616675911319">"மூடுவதற்கான பட்டன்"</string>
</resources>
diff --git a/quickstep/res/values-te/strings.xml b/quickstep/res/values-te/strings.xml
index ac5479e..94fac1b 100644
--- a/quickstep/res/values-te/strings.xml
+++ b/quickstep/res/values-te/strings.xml
@@ -46,6 +46,8 @@
<string name="hotsaet_tip_prediction_enabled" msgid="2233554377501347650">"యాప్ సలహాలు ఎనేబుల్ చేయబడ్డాయి"</string>
<string name="hotsaet_tip_prediction_disabled" msgid="1506426298884658491">"యాప్ సూచనలు డిజేబుల్ చేయబడ్డాయి"</string>
<string name="hotseat_prediction_content_description" msgid="4582028296938078419">"సూచించబడిన యాప్: <xliff:g id="TITLE">%1$s</xliff:g>"</string>
+ <!-- no translation found for gesture_tutorial_title (2750751261768388354) -->
+ <skip />
<string name="gesture_tutorial_rotation_prompt_title" msgid="7537946781362766964">"మీ పరికరాన్ని రొటేట్ చేయండి"</string>
<string name="gesture_tutorial_rotation_prompt" msgid="1664493449851960691">"సంజ్ఞ నావిగేషన్ ట్యుటోరియల్ను పూర్తి చేయడానికి దయచేసి మీ పరికరాన్ని రొటేట్ చేయండి"</string>
<string name="back_gesture_feedback_swipe_too_far_from_edge" msgid="4175100312909721217">"కుడి వైపు చిట్ట చివరి లేదా ఎడమ వైపు చిట్ట చివరి అంచు నుండి స్వైప్ చేస్తున్నారని నిర్ధారించుకోండి"</string>
@@ -152,4 +154,7 @@
<string name="bubble_bar_accessibility_announce_expand" msgid="1503192695527477102">"<xliff:g id="BUBBLE_DESCRIPTION">%1$s</xliff:g>ను విస్తరించండి"</string>
<string name="bubble_bar_accessibility_announce_collapse" msgid="928284600086798791">"<xliff:g id="BUBBLE_DESCRIPTION">%1$s</xliff:g>ను కుదించండి"</string>
<string name="search_gesture_feature_title" msgid="1294044108313175306">"సెర్చ్ చేయడానికి సర్కిల్ గీయండి"</string>
+ <string name="header_app_icon_description" msgid="2184625881433608027">"యాప్ చిహ్నం"</string>
+ <string name="header_default_app_title" msgid="8308052350689531566">"యాప్ టైటిల్"</string>
+ <string name="header_close_icon_description" msgid="5400033616675911319">"\'మూసివేయండి\' బటన్"</string>
</resources>
diff --git a/quickstep/res/values-th/strings.xml b/quickstep/res/values-th/strings.xml
index c9dadd7..ee515b9 100644
--- a/quickstep/res/values-th/strings.xml
+++ b/quickstep/res/values-th/strings.xml
@@ -46,6 +46,8 @@
<string name="hotsaet_tip_prediction_enabled" msgid="2233554377501347650">"เปิดใช้แอปแนะนำแล้ว"</string>
<string name="hotsaet_tip_prediction_disabled" msgid="1506426298884658491">"ปิดใช้คำแนะนำเกี่ยวกับแอปอยู่"</string>
<string name="hotseat_prediction_content_description" msgid="4582028296938078419">"แอปที่คาดว่าจะใช้: <xliff:g id="TITLE">%1$s</xliff:g>"</string>
+ <!-- no translation found for gesture_tutorial_title (2750751261768388354) -->
+ <skip />
<string name="gesture_tutorial_rotation_prompt_title" msgid="7537946781362766964">"หมุนอุปกรณ์ของคุณ"</string>
<string name="gesture_tutorial_rotation_prompt" msgid="1664493449851960691">"โปรดหมุนอุปกรณ์เพื่อทำตามบทแนะนำการนำทางด้วยท่าทางสัมผัสให้เสร็จสมบูรณ์"</string>
<string name="back_gesture_feedback_swipe_too_far_from_edge" msgid="4175100312909721217">"ปัดจากขอบด้านขวาสุดหรือซ้ายสุด"</string>
@@ -152,4 +154,7 @@
<string name="bubble_bar_accessibility_announce_expand" msgid="1503192695527477102">"ขยาย <xliff:g id="BUBBLE_DESCRIPTION">%1$s</xliff:g>"</string>
<string name="bubble_bar_accessibility_announce_collapse" msgid="928284600086798791">"ยุบ <xliff:g id="BUBBLE_DESCRIPTION">%1$s</xliff:g>"</string>
<string name="search_gesture_feature_title" msgid="1294044108313175306">"วงเพื่อค้นหา"</string>
+ <string name="header_app_icon_description" msgid="2184625881433608027">"ไอคอนแอป"</string>
+ <string name="header_default_app_title" msgid="8308052350689531566">"ชื่อแอป"</string>
+ <string name="header_close_icon_description" msgid="5400033616675911319">"ปุ่มปิด"</string>
</resources>
diff --git a/quickstep/res/values-tl/strings.xml b/quickstep/res/values-tl/strings.xml
index c72e38b..1bc4a3d 100644
--- a/quickstep/res/values-tl/strings.xml
+++ b/quickstep/res/values-tl/strings.xml
@@ -46,6 +46,8 @@
<string name="hotsaet_tip_prediction_enabled" msgid="2233554377501347650">"Naka-enable ang mga iminumungkahing app"</string>
<string name="hotsaet_tip_prediction_disabled" msgid="1506426298884658491">"Naka-disable ang mga iminumungkahing app"</string>
<string name="hotseat_prediction_content_description" msgid="4582028296938078419">"Hinulaang app: <xliff:g id="TITLE">%1$s</xliff:g>"</string>
+ <!-- no translation found for gesture_tutorial_title (2750751261768388354) -->
+ <skip />
<string name="gesture_tutorial_rotation_prompt_title" msgid="7537946781362766964">"I-rotate ang iyong device"</string>
<string name="gesture_tutorial_rotation_prompt" msgid="1664493449851960691">"Paki-rotate ang iyong device para tapusin ang tutorial sa navigation gamit ang galaw"</string>
<string name="back_gesture_feedback_swipe_too_far_from_edge" msgid="4175100312909721217">"Tiyaking magsa-swipe ka mula sa dulong kanan o dulong kaliwang gilid"</string>
@@ -152,4 +154,7 @@
<string name="bubble_bar_accessibility_announce_expand" msgid="1503192695527477102">"i-expand ang <xliff:g id="BUBBLE_DESCRIPTION">%1$s</xliff:g>"</string>
<string name="bubble_bar_accessibility_announce_collapse" msgid="928284600086798791">"i-collapse ang <xliff:g id="BUBBLE_DESCRIPTION">%1$s</xliff:g>"</string>
<string name="search_gesture_feature_title" msgid="1294044108313175306">"Circle to Search"</string>
+ <string name="header_app_icon_description" msgid="2184625881433608027">"Icon ng app"</string>
+ <string name="header_default_app_title" msgid="8308052350689531566">"Pamagat ng app"</string>
+ <string name="header_close_icon_description" msgid="5400033616675911319">"Button na isara"</string>
</resources>
diff --git a/quickstep/res/values-tr/strings.xml b/quickstep/res/values-tr/strings.xml
index 645ef54..691e6c0 100644
--- a/quickstep/res/values-tr/strings.xml
+++ b/quickstep/res/values-tr/strings.xml
@@ -46,6 +46,8 @@
<string name="hotsaet_tip_prediction_enabled" msgid="2233554377501347650">"Uygulama önerileri etkinleştirildi"</string>
<string name="hotsaet_tip_prediction_disabled" msgid="1506426298884658491">"Uygulama önerileri devre dışı bırakıldı"</string>
<string name="hotseat_prediction_content_description" msgid="4582028296938078419">"Tahmin edilen uygulama: <xliff:g id="TITLE">%1$s</xliff:g>"</string>
+ <!-- no translation found for gesture_tutorial_title (2750751261768388354) -->
+ <skip />
<string name="gesture_tutorial_rotation_prompt_title" msgid="7537946781362766964">"Cihazınızı döndürün"</string>
<string name="gesture_tutorial_rotation_prompt" msgid="1664493449851960691">"Hareketle gezinme eğitimini tamamlamak için lütfen cihazınızı döndürün"</string>
<string name="back_gesture_feedback_swipe_too_far_from_edge" msgid="4175100312909721217">"En sağ veya en sol kenardan kaydırdığınızdan emin olun"</string>
@@ -152,4 +154,7 @@
<string name="bubble_bar_accessibility_announce_expand" msgid="1503192695527477102">"genişlet: <xliff:g id="BUBBLE_DESCRIPTION">%1$s</xliff:g>"</string>
<string name="bubble_bar_accessibility_announce_collapse" msgid="928284600086798791">"daralt: <xliff:g id="BUBBLE_DESCRIPTION">%1$s</xliff:g>"</string>
<string name="search_gesture_feature_title" msgid="1294044108313175306">"Seçerek Arat"</string>
+ <string name="header_app_icon_description" msgid="2184625881433608027">"Uygulama simgesi"</string>
+ <string name="header_default_app_title" msgid="8308052350689531566">"Uygulama başlığı"</string>
+ <string name="header_close_icon_description" msgid="5400033616675911319">"Kapat düğmesi"</string>
</resources>
diff --git a/quickstep/res/values-uk/strings.xml b/quickstep/res/values-uk/strings.xml
index 8629d49..1668b4f 100644
--- a/quickstep/res/values-uk/strings.xml
+++ b/quickstep/res/values-uk/strings.xml
@@ -46,6 +46,8 @@
<string name="hotsaet_tip_prediction_enabled" msgid="2233554377501347650">"Рекомендовані додатки ввімкнено"</string>
<string name="hotsaet_tip_prediction_disabled" msgid="1506426298884658491">"Рекомендовані додатки вимкнено"</string>
<string name="hotseat_prediction_content_description" msgid="4582028296938078419">"Передбачений додаток: <xliff:g id="TITLE">%1$s</xliff:g>"</string>
+ <!-- no translation found for gesture_tutorial_title (2750751261768388354) -->
+ <skip />
<string name="gesture_tutorial_rotation_prompt_title" msgid="7537946781362766964">"Оберніть пристрій"</string>
<string name="gesture_tutorial_rotation_prompt" msgid="1664493449851960691">"Обертайте пристрій, щоб ознайомитися з посібником із навігації за допомогою жестів"</string>
<string name="back_gesture_feedback_swipe_too_far_from_edge" msgid="4175100312909721217">"Проведіть пальцем від самого краю екрана (правого або лівого)"</string>
@@ -152,4 +154,7 @@
<string name="bubble_bar_accessibility_announce_expand" msgid="1503192695527477102">"розгорнути \"<xliff:g id="BUBBLE_DESCRIPTION">%1$s</xliff:g>\""</string>
<string name="bubble_bar_accessibility_announce_collapse" msgid="928284600086798791">"згорнути \"<xliff:g id="BUBBLE_DESCRIPTION">%1$s</xliff:g>\""</string>
<string name="search_gesture_feature_title" msgid="1294044108313175306">"Обвести й знайти"</string>
+ <string name="header_app_icon_description" msgid="2184625881433608027">"Значок додатка"</string>
+ <string name="header_default_app_title" msgid="8308052350689531566">"Назва додатка"</string>
+ <string name="header_close_icon_description" msgid="5400033616675911319">"Кнопка \"Закрити\""</string>
</resources>
diff --git a/quickstep/res/values-ur/strings.xml b/quickstep/res/values-ur/strings.xml
index 3ca1fb8..5b780c3 100644
--- a/quickstep/res/values-ur/strings.xml
+++ b/quickstep/res/values-ur/strings.xml
@@ -46,6 +46,8 @@
<string name="hotsaet_tip_prediction_enabled" msgid="2233554377501347650">"ایپ کی تجاویز فعال ہیں"</string>
<string name="hotsaet_tip_prediction_disabled" msgid="1506426298884658491">"ایپ کی تجاویز غیر فعال ہیں"</string>
<string name="hotseat_prediction_content_description" msgid="4582028296938078419">"پیشن گوئی کردہ ایپ: <xliff:g id="TITLE">%1$s</xliff:g>"</string>
+ <!-- no translation found for gesture_tutorial_title (2750751261768388354) -->
+ <skip />
<string name="gesture_tutorial_rotation_prompt_title" msgid="7537946781362766964">"اپنا آلہ گھمائیں"</string>
<string name="gesture_tutorial_rotation_prompt" msgid="1664493449851960691">"براہ کرم اشاروں والی نیویگیشن کا ٹیوٹوریل مکمل کرنے کے لیے اپنا آلہ گھمائیں"</string>
<string name="back_gesture_feedback_swipe_too_far_from_edge" msgid="4175100312909721217">"یقینی بنائیں کہ آپ دائیں یا بائیں کنارے سے دور سے سوائپ کریں"</string>
@@ -152,4 +154,7 @@
<string name="bubble_bar_accessibility_announce_expand" msgid="1503192695527477102">"<xliff:g id="BUBBLE_DESCRIPTION">%1$s</xliff:g> کو پھیلائیں"</string>
<string name="bubble_bar_accessibility_announce_collapse" msgid="928284600086798791">"<xliff:g id="BUBBLE_DESCRIPTION">%1$s</xliff:g> کو سکیڑیں"</string>
<string name="search_gesture_feature_title" msgid="1294044108313175306">"تلاش کرنے کیلئے دائرہ بنائیں"</string>
+ <string name="header_app_icon_description" msgid="2184625881433608027">"ایپ آئیکن"</string>
+ <string name="header_default_app_title" msgid="8308052350689531566">"ایپ کا عنوان"</string>
+ <string name="header_close_icon_description" msgid="5400033616675911319">"\'بند کریں\' بٹن"</string>
</resources>
diff --git a/quickstep/res/values-uz/strings.xml b/quickstep/res/values-uz/strings.xml
index b4c2ef1..7de3648 100644
--- a/quickstep/res/values-uz/strings.xml
+++ b/quickstep/res/values-uz/strings.xml
@@ -46,6 +46,8 @@
<string name="hotsaet_tip_prediction_enabled" msgid="2233554377501347650">"Ilova tavsiyalari yoqildi"</string>
<string name="hotsaet_tip_prediction_disabled" msgid="1506426298884658491">"Endi ilova takliflari chiqmaydi"</string>
<string name="hotseat_prediction_content_description" msgid="4582028296938078419">"Taklif etilgan ilova: <xliff:g id="TITLE">%1$s</xliff:g>"</string>
+ <!-- no translation found for gesture_tutorial_title (2750751261768388354) -->
+ <skip />
<string name="gesture_tutorial_rotation_prompt_title" msgid="7537946781362766964">"Qurilmangizni buring"</string>
<string name="gesture_tutorial_rotation_prompt" msgid="1664493449851960691">"Ishorali navigatsiya darsligini tugatish uchun qurilmani buring"</string>
<string name="back_gesture_feedback_swipe_too_far_from_edge" msgid="4175100312909721217">"Ekran chetidan boshlab oʻngdan yoki chapdan suring"</string>
@@ -152,4 +154,7 @@
<string name="bubble_bar_accessibility_announce_expand" msgid="1503192695527477102">"<xliff:g id="BUBBLE_DESCRIPTION">%1$s</xliff:g>ni yoyish"</string>
<string name="bubble_bar_accessibility_announce_collapse" msgid="928284600086798791">"<xliff:g id="BUBBLE_DESCRIPTION">%1$s</xliff:g>ni yigʻish"</string>
<string name="search_gesture_feature_title" msgid="1294044108313175306">"Chizib qidirish"</string>
+ <string name="header_app_icon_description" msgid="2184625881433608027">"Ilova belgisi"</string>
+ <string name="header_default_app_title" msgid="8308052350689531566">"Ilova nomi"</string>
+ <string name="header_close_icon_description" msgid="5400033616675911319">"Yopish tugmasi"</string>
</resources>
diff --git a/quickstep/res/values-vi/strings.xml b/quickstep/res/values-vi/strings.xml
index a27b053..dffcd6c 100644
--- a/quickstep/res/values-vi/strings.xml
+++ b/quickstep/res/values-vi/strings.xml
@@ -46,6 +46,8 @@
<string name="hotsaet_tip_prediction_enabled" msgid="2233554377501347650">"Đã bật tính năng Ứng dụng đề xuất"</string>
<string name="hotsaet_tip_prediction_disabled" msgid="1506426298884658491">"Tính năng Ứng dụng đề xuất bị tắt"</string>
<string name="hotseat_prediction_content_description" msgid="4582028296938078419">"Ứng dụng dự đoán: <xliff:g id="TITLE">%1$s</xliff:g>"</string>
+ <!-- no translation found for gesture_tutorial_title (2750751261768388354) -->
+ <skip />
<string name="gesture_tutorial_rotation_prompt_title" msgid="7537946781362766964">"Xoay thiết bị của bạn"</string>
<string name="gesture_tutorial_rotation_prompt" msgid="1664493449851960691">"Vui lòng xoay thiết bị của bạn để hoàn tất hướng dẫn thao tác bằng cử chỉ"</string>
<string name="back_gesture_feedback_swipe_too_far_from_edge" msgid="4175100312909721217">"Hãy vuốt từ mép ngoài cùng bên phải hoặc ngoài cùng bên trái"</string>
@@ -152,4 +154,7 @@
<string name="bubble_bar_accessibility_announce_expand" msgid="1503192695527477102">"mở rộng <xliff:g id="BUBBLE_DESCRIPTION">%1$s</xliff:g>"</string>
<string name="bubble_bar_accessibility_announce_collapse" msgid="928284600086798791">"thu gọn <xliff:g id="BUBBLE_DESCRIPTION">%1$s</xliff:g>"</string>
<string name="search_gesture_feature_title" msgid="1294044108313175306">"Khoanh tròn để tìm kiếm"</string>
+ <string name="header_app_icon_description" msgid="2184625881433608027">"Biểu tượng ứng dụng"</string>
+ <string name="header_default_app_title" msgid="8308052350689531566">"Tên ứng dụng"</string>
+ <string name="header_close_icon_description" msgid="5400033616675911319">"Nút đóng"</string>
</resources>
diff --git a/quickstep/res/values-zh-rCN/strings.xml b/quickstep/res/values-zh-rCN/strings.xml
index 048d675..4d35d39 100644
--- a/quickstep/res/values-zh-rCN/strings.xml
+++ b/quickstep/res/values-zh-rCN/strings.xml
@@ -46,6 +46,8 @@
<string name="hotsaet_tip_prediction_enabled" msgid="2233554377501347650">"已启用应用建议"</string>
<string name="hotsaet_tip_prediction_disabled" msgid="1506426298884658491">"已停用应用建议"</string>
<string name="hotseat_prediction_content_description" msgid="4582028296938078419">"预测的应用:<xliff:g id="TITLE">%1$s</xliff:g>"</string>
+ <!-- no translation found for gesture_tutorial_title (2750751261768388354) -->
+ <skip />
<string name="gesture_tutorial_rotation_prompt_title" msgid="7537946781362766964">"请旋转设备"</string>
<string name="gesture_tutorial_rotation_prompt" msgid="1664493449851960691">"请旋转设备,完成手势导航教程"</string>
<string name="back_gesture_feedback_swipe_too_far_from_edge" msgid="4175100312909721217">"确保从最右侧或最左侧边缘开始滑动"</string>
@@ -152,4 +154,7 @@
<string name="bubble_bar_accessibility_announce_expand" msgid="1503192695527477102">"展开“<xliff:g id="BUBBLE_DESCRIPTION">%1$s</xliff:g>”"</string>
<string name="bubble_bar_accessibility_announce_collapse" msgid="928284600086798791">"收起“<xliff:g id="BUBBLE_DESCRIPTION">%1$s</xliff:g>”"</string>
<string name="search_gesture_feature_title" msgid="1294044108313175306">"圈定即搜"</string>
+ <string name="header_app_icon_description" msgid="2184625881433608027">"应用图标"</string>
+ <string name="header_default_app_title" msgid="8308052350689531566">"应用名称"</string>
+ <string name="header_close_icon_description" msgid="5400033616675911319">"“关闭”按钮"</string>
</resources>
diff --git a/quickstep/res/values-zh-rHK/strings.xml b/quickstep/res/values-zh-rHK/strings.xml
index f1127da..fd11ba1 100644
--- a/quickstep/res/values-zh-rHK/strings.xml
+++ b/quickstep/res/values-zh-rHK/strings.xml
@@ -46,6 +46,8 @@
<string name="hotsaet_tip_prediction_enabled" msgid="2233554377501347650">"已啟用應用程式建議"</string>
<string name="hotsaet_tip_prediction_disabled" msgid="1506426298884658491">"已停用應用程式建議"</string>
<string name="hotseat_prediction_content_description" msgid="4582028296938078419">"預測應用程式:<xliff:g id="TITLE">%1$s</xliff:g>"</string>
+ <!-- no translation found for gesture_tutorial_title (2750751261768388354) -->
+ <skip />
<string name="gesture_tutorial_rotation_prompt_title" msgid="7537946781362766964">"旋轉裝置方向"</string>
<string name="gesture_tutorial_rotation_prompt" msgid="1664493449851960691">"請旋轉裝置方向以完成手勢導覽教學課程"</string>
<string name="back_gesture_feedback_swipe_too_far_from_edge" msgid="4175100312909721217">"請確保從螢幕最右側或最左側邊緣滑動"</string>
@@ -152,4 +154,7 @@
<string name="bubble_bar_accessibility_announce_expand" msgid="1503192695527477102">"打開<xliff:g id="BUBBLE_DESCRIPTION">%1$s</xliff:g>"</string>
<string name="bubble_bar_accessibility_announce_collapse" msgid="928284600086798791">"收埋<xliff:g id="BUBBLE_DESCRIPTION">%1$s</xliff:g>"</string>
<string name="search_gesture_feature_title" msgid="1294044108313175306">"一圈即搜"</string>
+ <string name="header_app_icon_description" msgid="2184625881433608027">"應用程式圖示"</string>
+ <string name="header_default_app_title" msgid="8308052350689531566">"應用程式名稱"</string>
+ <string name="header_close_icon_description" msgid="5400033616675911319">"關閉按鈕"</string>
</resources>
diff --git a/quickstep/res/values-zh-rTW/strings.xml b/quickstep/res/values-zh-rTW/strings.xml
index b524414..729f7fd 100644
--- a/quickstep/res/values-zh-rTW/strings.xml
+++ b/quickstep/res/values-zh-rTW/strings.xml
@@ -21,9 +21,9 @@
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
<string name="recent_task_option_pin" msgid="7929860679018978258">"固定"</string>
<string name="recent_task_option_freeform" msgid="48863056265284071">"自由形式"</string>
- <string name="recent_task_option_desktop" msgid="8280879717125435668">"桌面"</string>
+ <string name="recent_task_option_desktop" msgid="8280879717125435668">"電腦模式"</string>
<string name="recent_task_option_external_display" msgid="4533840664313389484">"移至外接螢幕"</string>
- <string name="recent_task_desktop" msgid="8081113562549637334">"電腦"</string>
+ <string name="recent_task_desktop" msgid="8081113562549637334">"電腦模式"</string>
<string name="recents_empty_message" msgid="7040467240571714191">"最近沒有任何項目"</string>
<string name="accessibility_app_usage_settings" msgid="6312864233673544149">"應用程式使用情況設定"</string>
<string name="recents_clear_all" msgid="5328176793634888831">"全部清除"</string>
@@ -46,6 +46,8 @@
<string name="hotsaet_tip_prediction_enabled" msgid="2233554377501347650">"應用程式建議功能已啟用"</string>
<string name="hotsaet_tip_prediction_disabled" msgid="1506426298884658491">"應用程式建議功能已停用"</string>
<string name="hotseat_prediction_content_description" msgid="4582028296938078419">"預測的應用程式:<xliff:g id="TITLE">%1$s</xliff:g>"</string>
+ <!-- no translation found for gesture_tutorial_title (2750751261768388354) -->
+ <skip />
<string name="gesture_tutorial_rotation_prompt_title" msgid="7537946781362766964">"旋轉裝置螢幕方向"</string>
<string name="gesture_tutorial_rotation_prompt" msgid="1664493449851960691">"如要完成手勢操作教學課程,請旋轉裝置螢幕方向"</string>
<string name="back_gesture_feedback_swipe_too_far_from_edge" msgid="4175100312909721217">"請務必從螢幕最右側或最左側滑動"</string>
@@ -140,7 +142,7 @@
<string name="move_drop_target_top_or_left" msgid="2988702185049595807">"移到上方/左側"</string>
<string name="move_drop_target_bottom_or_right" msgid="5431393418797620162">"移到底部/右側"</string>
<string name="quick_switch_overflow" msgid="3679780650881041632">"{count,plural, =1{個其他應用程式}other{個其他應用程式}}"</string>
- <string name="quick_switch_desktop" msgid="8393802056024499749">"電腦"</string>
+ <string name="quick_switch_desktop" msgid="8393802056024499749">"電腦模式"</string>
<string name="quick_switch_split_task" msgid="5598194724255333896">"「<xliff:g id="APP_NAME_1">%1$s</xliff:g>」和「<xliff:g id="APP_NAME_2">%2$s</xliff:g>」"</string>
<string name="bubble_bar_bubble_fallback_description" msgid="7811684548953452009">"泡泡"</string>
<string name="bubble_bar_overflow_description" msgid="8617628132733151708">"溢位"</string>
@@ -152,4 +154,7 @@
<string name="bubble_bar_accessibility_announce_expand" msgid="1503192695527477102">"展開「<xliff:g id="BUBBLE_DESCRIPTION">%1$s</xliff:g>」"</string>
<string name="bubble_bar_accessibility_announce_collapse" msgid="928284600086798791">"收合「<xliff:g id="BUBBLE_DESCRIPTION">%1$s</xliff:g>」"</string>
<string name="search_gesture_feature_title" msgid="1294044108313175306">"畫圈搜尋"</string>
+ <string name="header_app_icon_description" msgid="2184625881433608027">"應用程式圖示"</string>
+ <string name="header_default_app_title" msgid="8308052350689531566">"應用程式標題"</string>
+ <string name="header_close_icon_description" msgid="5400033616675911319">"關閉按鈕"</string>
</resources>
diff --git a/quickstep/res/values-zu/strings.xml b/quickstep/res/values-zu/strings.xml
index 4340857..5209ac1 100644
--- a/quickstep/res/values-zu/strings.xml
+++ b/quickstep/res/values-zu/strings.xml
@@ -46,6 +46,8 @@
<string name="hotsaet_tip_prediction_enabled" msgid="2233554377501347650">"Iziphakamiso zohlelo lokusebenza zinikwe amandla"</string>
<string name="hotsaet_tip_prediction_disabled" msgid="1506426298884658491">"Iziphakamiso zohlelo lokusebenza zikhutshaziwe"</string>
<string name="hotseat_prediction_content_description" msgid="4582028296938078419">"Uhlelo lokusebenza olubikezelwe: <xliff:g id="TITLE">%1$s</xliff:g>"</string>
+ <!-- no translation found for gesture_tutorial_title (2750751261768388354) -->
+ <skip />
<string name="gesture_tutorial_rotation_prompt_title" msgid="7537946781362766964">"Zungezisa idivayisi yakho"</string>
<string name="gesture_tutorial_rotation_prompt" msgid="1664493449851960691">"Sicela uzungezise idivayisi yakho ukuze uqedele okokufundisa kokufuna ngokuthinta"</string>
<string name="back_gesture_feedback_swipe_too_far_from_edge" msgid="4175100312909721217">"Qinisekisa ukuthi uswayipha ukusuka onqenqemeni olukude ngakwesokudla noma olukude ngakwesokunxele"</string>
@@ -152,4 +154,7 @@
<string name="bubble_bar_accessibility_announce_expand" msgid="1503192695527477102">"nweba <xliff:g id="BUBBLE_DESCRIPTION">%1$s</xliff:g>"</string>
<string name="bubble_bar_accessibility_announce_collapse" msgid="928284600086798791">"goqa <xliff:g id="BUBBLE_DESCRIPTION">%1$s</xliff:g>"</string>
<string name="search_gesture_feature_title" msgid="1294044108313175306">"Khethela Ukusesha"</string>
+ <string name="header_app_icon_description" msgid="2184625881433608027">"Isithonjana se-app"</string>
+ <string name="header_default_app_title" msgid="8308052350689531566">"Isihloko se-app"</string>
+ <string name="header_close_icon_description" msgid="5400033616675911319">"Inkinobho yokuvala"</string>
</resources>
diff --git a/quickstep/res/values/dimens.xml b/quickstep/res/values/dimens.xml
index 493a5b8..b253343 100644
--- a/quickstep/res/values/dimens.xml
+++ b/quickstep/res/values/dimens.xml
@@ -106,6 +106,9 @@
<dimen name="recents_clear_all_outline_radius">24dp</dimen>
<dimen name="recents_clear_all_outline_padding">2dp</dimen>
+ <!-- Recents add desktop button -->
+ <dimen name="add_desktop_button_size">56dp</dimen>
+
<!-- The speed in dp/s at which the user needs to be scrolling in recents such that we start
loading full resolution screenshots. -->
<dimen name="recents_fast_fling_velocity">600dp</dimen>
diff --git a/quickstep/res/values/strings.xml b/quickstep/res/values/strings.xml
index 324ea31..0474000 100644
--- a/quickstep/res/values/strings.xml
+++ b/quickstep/res/values/strings.xml
@@ -98,6 +98,9 @@
<!-- content description for hotseat items -->
<string name="hotseat_prediction_content_description">Predicted app: <xliff:g id="title" example="Chrome">%1$s</xliff:g></string>
+ <!-- Title of the Gesture Navigation Tutorial page [CHAR LIMIT=NONE] -->
+ <string name="gesture_tutorial_title">Gesture Navigation Tutorial</string>
+
<!-- Title of prompt shown before the gesture navigation tutorial to users who need to rotate their screen. [CHAR LIMIT=100] -->
<string name="gesture_tutorial_rotation_prompt_title">Rotate your device</string>
<!-- Prompt shown before the gesture navigation tutorial to users who need to rotate their screen to begin. [CHAR LIMIT=100] -->
diff --git a/quickstep/src/com/android/launcher3/desktop/DesktopAppLaunchTransition.kt b/quickstep/src/com/android/launcher3/desktop/DesktopAppLaunchTransition.kt
index 87a82f0..2406fb6 100644
--- a/quickstep/src/com/android/launcher3/desktop/DesktopAppLaunchTransition.kt
+++ b/quickstep/src/com/android/launcher3/desktop/DesktopAppLaunchTransition.kt
@@ -22,6 +22,7 @@
import android.content.Context
import android.graphics.Rect
import android.os.IBinder
+import android.view.Choreographer
import android.view.SurfaceControl.Transaction
import android.view.WindowManager.TRANSIT_OPEN
import android.view.WindowManager.TRANSIT_TO_BACK
@@ -32,6 +33,8 @@
import android.window.TransitionInfo.Change
import androidx.core.animation.addListener
import com.android.app.animation.Interpolators
+import com.android.internal.jank.Cuj
+import com.android.internal.jank.InteractionJankMonitor
import com.android.internal.policy.ScreenDecorationsUtils
import com.android.quickstep.RemoteRunnable
import com.android.wm.shell.shared.animation.MinimizeAnimator
@@ -49,8 +52,11 @@
private val context: Context,
private val mainExecutor: Executor,
private val launchType: AppLaunchType,
+ @Cuj.CujType private val cujType: Int,
) : RemoteTransitionStub() {
+ private val interactionJankMonitor = InteractionJankMonitor.getInstance()
+
enum class AppLaunchType(
val boundsAnimationParams: WindowAnimator.BoundsAnimationParams,
val alphaDurationMs: Long,
@@ -127,7 +133,10 @@
duration = launchType.alphaDurationMs
interpolator = Interpolators.LINEAR
addUpdateListener { animation ->
- transaction.setAlpha(change.leash, animation.animatedValue as Float).apply()
+ transaction
+ .setAlpha(change.leash, animation.animatedValue as Float)
+ .setFrameTimeline(Choreographer.getInstance().vsyncId)
+ .apply()
}
}
val clipRect = Rect(change.endAbsBounds).apply { offsetTo(0, 0) }
@@ -137,8 +146,14 @@
ScreenDecorationsUtils.getWindowCornerRadius(context),
)
return AnimatorSet().apply {
+ interactionJankMonitor.begin(change.leash, context, context.mainThreadHandler, cujType)
playTogether(boundsAnimator, alphaAnimator)
- addListener(onEnd = { animation -> onAnimFinish(animation) })
+ addListener(
+ onEnd = { animation ->
+ onAnimFinish(animation)
+ interactionJankMonitor.end(cujType)
+ }
+ )
}
}
diff --git a/quickstep/src/com/android/launcher3/desktop/DesktopAppLaunchTransitionManager.kt b/quickstep/src/com/android/launcher3/desktop/DesktopAppLaunchTransitionManager.kt
index 6e36305..6cf9b9e 100644
--- a/quickstep/src/com/android/launcher3/desktop/DesktopAppLaunchTransitionManager.kt
+++ b/quickstep/src/com/android/launcher3/desktop/DesktopAppLaunchTransitionManager.kt
@@ -23,6 +23,7 @@
import android.window.RemoteTransition
import android.window.TransitionFilter
import android.window.TransitionFilter.CONTAINER_ORDER_TOP
+import com.android.internal.jank.Cuj
import com.android.launcher3.desktop.DesktopAppLaunchTransition.AppLaunchType
import com.android.launcher3.util.Executors.MAIN_EXECUTOR
import com.android.quickstep.SystemUiProxy
@@ -45,8 +46,13 @@
}
remoteWindowLimitUnminimizeTransition =
RemoteTransition(
- DesktopAppLaunchTransition(context, MAIN_EXECUTOR, AppLaunchType.UNMINIMIZE),
- "DesktopWindowLimitUnminimize"
+ DesktopAppLaunchTransition(
+ context,
+ MAIN_EXECUTOR,
+ AppLaunchType.UNMINIMIZE,
+ Cuj.CUJ_DESKTOP_MODE_APP_LAUNCH_FROM_INTENT,
+ ),
+ "DesktopWindowLimitUnminimize",
)
systemUiProxy.registerRemoteTransition(
remoteWindowLimitUnminimizeTransition,
diff --git a/quickstep/src/com/android/launcher3/desktop/DesktopRecentsTransitionController.kt b/quickstep/src/com/android/launcher3/desktop/DesktopRecentsTransitionController.kt
index 8b064d3..010a5c8 100644
--- a/quickstep/src/com/android/launcher3/desktop/DesktopRecentsTransitionController.kt
+++ b/quickstep/src/com/android/launcher3/desktop/DesktopRecentsTransitionController.kt
@@ -64,11 +64,16 @@
}
/** Launch desktop tasks from recents view */
- fun moveToDesktop(taskContainer: TaskContainer, transitionSource: DesktopModeTransitionSource) {
+ fun moveToDesktop(
+ taskContainer: TaskContainer,
+ transitionSource: DesktopModeTransitionSource,
+ successCallback: Runnable,
+ ) {
systemUiProxy.moveToDesktop(
taskContainer.task.key.id,
transitionSource,
/* transition = */ null,
+ successCallback,
)
}
diff --git a/quickstep/src/com/android/launcher3/taskbar/BaseTaskbarContext.java b/quickstep/src/com/android/launcher3/taskbar/BaseTaskbarContext.java
index a833ccf..b33fd38 100644
--- a/quickstep/src/com/android/launcher3/taskbar/BaseTaskbarContext.java
+++ b/quickstep/src/com/android/launcher3/taskbar/BaseTaskbarContext.java
@@ -18,6 +18,7 @@
import android.content.Context;
import android.content.Intent;
import android.content.pm.ShortcutInfo;
+import android.os.UserHandle;
import android.view.ContextThemeWrapper;
import android.view.LayoutInflater;
@@ -60,9 +61,9 @@
}
@Override
- public void showAppBubble(Intent intent) {
+ public void showAppBubble(Intent intent, UserHandle user) {
if (intent == null || intent.getPackage() == null) return;
- SystemUiProxy.INSTANCE.get(this).showAppBubble(intent);
+ SystemUiProxy.INSTANCE.get(this).showAppBubble(intent, user);
}
/** Callback invoked when a drag is initiated within this context. */
diff --git a/quickstep/src/com/android/launcher3/taskbar/KeyboardQuickSwitchViewController.java b/quickstep/src/com/android/launcher3/taskbar/KeyboardQuickSwitchViewController.java
index cb811d6..8cb43d2 100644
--- a/quickstep/src/com/android/launcher3/taskbar/KeyboardQuickSwitchViewController.java
+++ b/quickstep/src/com/android/launcher3/taskbar/KeyboardQuickSwitchViewController.java
@@ -38,7 +38,6 @@
import com.android.launcher3.Utilities;
import com.android.launcher3.anim.AnimatorListeners;
import com.android.launcher3.desktop.DesktopAppLaunchTransition;
-import com.android.launcher3.desktop.DesktopAppLaunchTransition.AppLaunchType;
import com.android.launcher3.taskbar.overlay.TaskbarOverlayContext;
import com.android.launcher3.taskbar.overlay.TaskbarOverlayDragLayer;
import com.android.launcher3.util.DisplayController;
@@ -50,6 +49,7 @@
import com.android.systemui.shared.recents.model.ThumbnailData;
import com.android.systemui.shared.system.InteractionJankMonitorWrapper;
import com.android.systemui.shared.system.QuickStepContract;
+import com.android.wm.shell.shared.desktopmode.DesktopTaskToFrontReason;
import java.io.PrintWriter;
import java.util.List;
@@ -286,13 +286,19 @@
) {
// This app is being unminimized - use our own transition runner.
remoteTransition = new RemoteTransition(
- new DesktopAppLaunchTransition(context, MAIN_EXECUTOR, UNMINIMIZE),
+ new DesktopAppLaunchTransition(
+ context,
+ MAIN_EXECUTOR,
+ UNMINIMIZE,
+ Cuj.CUJ_DESKTOP_MODE_KEYBOARD_QUICK_SWITCH_APP_LAUNCH
+ ),
"DesktopKeyboardQuickSwitchUnminimize");
}
mControllers.taskbarActivityContext.handleGroupTaskLaunch(
task,
remoteTransition,
mOnDesktop,
+ DesktopTaskToFrontReason.ALT_TAB,
onStartCallback,
onFinishCallback);
return -1;
diff --git a/quickstep/src/com/android/launcher3/taskbar/ManageWindowsTaskbarShortcut.kt b/quickstep/src/com/android/launcher3/taskbar/ManageWindowsTaskbarShortcut.kt
index 75ce7c3..bfd93dd 100644
--- a/quickstep/src/com/android/launcher3/taskbar/ManageWindowsTaskbarShortcut.kt
+++ b/quickstep/src/com/android/launcher3/taskbar/ManageWindowsTaskbarShortcut.kt
@@ -27,7 +27,6 @@
import com.android.launcher3.popup.SystemShortcut
import com.android.launcher3.taskbar.TaskbarAutohideSuspendController.FLAG_AUTOHIDE_SUSPEND_MULTI_INSTANCE_MENU_OPEN
import com.android.launcher3.taskbar.overlay.TaskbarOverlayContext
-import com.android.launcher3.util.Themes
import com.android.launcher3.util.TouchController
import com.android.launcher3.views.ActivityContext
import com.android.quickstep.RecentsModel
@@ -35,9 +34,8 @@
import com.android.quickstep.util.DesktopTask
import com.android.systemui.shared.recents.model.Task
import com.android.systemui.shared.recents.model.ThumbnailData
+import com.android.wm.shell.shared.desktopmode.DesktopTaskToFrontReason
import com.android.wm.shell.shared.multiinstance.ManageWindowsViewContainer
-import java.util.Collections
-import java.util.function.Predicate
/**
* A single menu item shortcut to execute displaying open instances of an app. Default interaction
@@ -72,7 +70,7 @@
val packageDesktopTasks =
(desktopTask?.tasks ?: emptyList()).filter(isTargetPackageTask)
val nonDesktopPackageTasks =
- tasks.filter { isTargetPackageTask(it.task1) }.map { it.task1 }
+ tasks.flatMap { it.tasks }.filter { isTargetPackageTask(it) }
// Add tasks from the fetched tasks, deduplicating by task ID
val packageTasks =
@@ -120,7 +118,12 @@
({ taskId: Int? ->
taskbarShortcutAllWindowsView.animateClose()
if (taskId != null) {
- SystemUiProxy.INSTANCE.get(target).showDesktopApp(taskId, null)
+ SystemUiProxy.INSTANCE.get(target)
+ .showDesktopApp(
+ taskId,
+ /* transition= */ null,
+ DesktopTaskToFrontReason.TASKBAR_MANAGE_WINDOW,
+ )
}
})
diff --git a/quickstep/src/com/android/launcher3/taskbar/TaskbarActivityContext.java b/quickstep/src/com/android/launcher3/taskbar/TaskbarActivityContext.java
index 2745129..e28e488 100644
--- a/quickstep/src/com/android/launcher3/taskbar/TaskbarActivityContext.java
+++ b/quickstep/src/com/android/launcher3/taskbar/TaskbarActivityContext.java
@@ -82,9 +82,11 @@
import androidx.core.graphics.Insets;
import androidx.core.view.WindowInsetsCompat;
+import com.android.internal.jank.Cuj;
import com.android.launcher3.AbstractFloatingView;
import com.android.launcher3.BubbleTextView;
import com.android.launcher3.DeviceProfile;
+import com.android.launcher3.Flags;
import com.android.launcher3.LauncherPrefs;
import com.android.launcher3.LauncherSettings.Favorites;
import com.android.launcher3.R;
@@ -164,6 +166,7 @@
import com.android.systemui.shared.system.QuickStepContract.SystemUiStateFlags;
import com.android.systemui.unfold.updates.RotationChangeProvider;
import com.android.systemui.unfold.util.ScopedUnfoldTransitionProgressProvider;
+import com.android.wm.shell.shared.desktopmode.DesktopTaskToFrontReason;
import java.io.PrintWriter;
import java.util.Collections;
@@ -230,6 +233,7 @@
private DeviceProfile mPersistentTaskbarDeviceProfile;
private final LauncherPrefs mLauncherPrefs;
+ private final SystemUiProxy mSysUiProxy;
private TaskbarFeatureEvaluator mTaskbarFeatureEvaluator;
@@ -239,10 +243,11 @@
@Nullable Context navigationBarPanelContext, DeviceProfile launcherDp,
TaskbarNavButtonController buttonController,
ScopedUnfoldTransitionProgressProvider unfoldTransitionProgressProvider,
- boolean isPrimaryDisplay) {
+ boolean isPrimaryDisplay, SystemUiProxy sysUiProxy) {
super(windowContext);
mIsPrimaryDisplay = isPrimaryDisplay;
mNavigationBarPanelContext = navigationBarPanelContext;
+ mSysUiProxy = sysUiProxy;
applyDeviceProfile(launcherDp);
final Resources resources = getResources();
mTaskbarFeatureEvaluator = TaskbarFeatureEvaluator.getInstance(this);
@@ -910,7 +915,11 @@
ActivityOptions options = ActivityOptions.makeRemoteTransition(
new RemoteTransition(
new DesktopAppLaunchTransition(
- /* context= */ this, getMainExecutor(), launchType),
+ /* context= */ this,
+ getMainExecutor(),
+ launchType,
+ Cuj.CUJ_DESKTOP_MODE_APP_LAUNCH_FROM_ICON
+ ),
"TaskbarDesktopLaunch"));
return new ActivityOptionsWrapper(options, new RunnableList());
}
@@ -1313,7 +1322,8 @@
if (tag instanceof GroupTask groupTask) {
RemoteTransition remoteTransition =
(areDesktopTasksVisible() && canUnminimizeDesktopTask(groupTask.task1.key.id))
- ? createUnminimizeRemoteTransition() : null;
+ ? createUnminimizeRemoteTransition(
+ Cuj.CUJ_DESKTOP_MODE_APP_LAUNCH_FROM_ICON) : null;
if (areDesktopTasksVisible() && mControllers.uiController.isInOverviewUi()) {
RunnableList runnableList = recents.launchRunningDesktopTaskView();
// Wrapping it in runnable so we post after DW is ready for the app
@@ -1321,10 +1331,12 @@
if (runnableList != null) {
runnableList.add(() -> UI_HELPER_EXECUTOR.execute(
() -> handleGroupTaskLaunch(groupTask, remoteTransition,
- areDesktopTasksVisible())));
+ areDesktopTasksVisible(),
+ DesktopTaskToFrontReason.TASKBAR_TAP)));
}
} else {
- handleGroupTaskLaunch(groupTask, remoteTransition, areDesktopTasksVisible());
+ handleGroupTaskLaunch(groupTask, remoteTransition, areDesktopTasksVisible(),
+ DesktopTaskToFrontReason.TASKBAR_TAP);
}
mControllers.taskbarStashController.updateAndAnimateTransientTaskbar(true);
} else if (tag instanceof FolderInfo) {
@@ -1342,9 +1354,10 @@
mControllers.uiController.onTaskbarIconLaunched(api);
mControllers.taskbarStashController.updateAndAnimateTransientTaskbar(true);
}
- } else if (tag instanceof TaskItemInfo info) {
+ } else if (tag instanceof TaskItemInfo info && !Flags.enableMultiInstanceMenuTaskbar()) {
RemoteTransition remoteTransition = canUnminimizeDesktopTask(info.getTaskId())
- ? createUnminimizeRemoteTransition() : null;
+ ? createUnminimizeRemoteTransition(Cuj.CUJ_DESKTOP_MODE_APP_LAUNCH_FROM_ICON)
+ : null;
TaskView taskView = null;
if (recents != null) {
@@ -1360,12 +1373,14 @@
// task will show.
UI_HELPER_EXECUTOR.execute(() ->
SystemUiProxy.INSTANCE.get(this).showDesktopApp(
- info.getTaskId(), remoteTransition)));
+ info.getTaskId(), remoteTransition,
+ DesktopTaskToFrontReason.TASKBAR_TAP)));
}
} else {
UI_HELPER_EXECUTOR.execute(() ->
SystemUiProxy.INSTANCE.get(this).showDesktopApp(
- info.getTaskId(), remoteTransition));
+ info.getTaskId(), remoteTransition,
+ DesktopTaskToFrontReason.TASKBAR_TAP));
}
mControllers.taskbarStashController.updateAndAnimateTransientTaskbar(
@@ -1458,8 +1473,9 @@
public void handleGroupTaskLaunch(
GroupTask task,
@Nullable RemoteTransition remoteTransition,
- boolean onDesktop) {
- handleGroupTaskLaunch(task, remoteTransition, onDesktop,
+ boolean onDesktop,
+ DesktopTaskToFrontReason toFrontReason) {
+ handleGroupTaskLaunch(task, remoteTransition, onDesktop, toFrontReason,
/* onStartCallback= */ null, /* onFinishCallback= */ null);
}
@@ -1478,6 +1494,7 @@
GroupTask task,
@Nullable RemoteTransition remoteTransition,
boolean onDesktop,
+ DesktopTaskToFrontReason toFrontReason,
@Nullable Runnable onStartCallback,
@Nullable Runnable onFinishCallback) {
if (task instanceof DesktopTask) {
@@ -1492,8 +1509,8 @@
if (onStartCallback != null) {
onStartCallback.run();
}
- SystemUiProxy.INSTANCE.get(this).showDesktopApp(
- task.task1.key.id, useRemoteTransition ? remoteTransition : null);
+ SystemUiProxy.INSTANCE.get(this).showDesktopApp(task.task1.key.id,
+ useRemoteTransition ? remoteTransition : null, toFrontReason);
if (onFinishCallback != null) {
onFinishCallback.run();
}
@@ -1524,9 +1541,14 @@
);
}
- private RemoteTransition createUnminimizeRemoteTransition() {
+ private RemoteTransition createUnminimizeRemoteTransition(@Cuj.CujType int cujType) {
return new RemoteTransition(
- new DesktopAppLaunchTransition(this, getMainExecutor(), AppLaunchType.UNMINIMIZE),
+ new DesktopAppLaunchTransition(
+ this,
+ getMainExecutor(),
+ AppLaunchType.UNMINIMIZE,
+ cujType
+ ),
"TaskbarDesktopUnminimize");
}
@@ -1645,12 +1667,12 @@
intent.getComponent(), info.user, intent.getSourceBounds(), null);
return;
}
+ int displayId = getDisplay() == null ? DEFAULT_DISPLAY : getDisplay().getDisplayId();
// TODO(b/216683257): Use startActivityForResult for search results that require it.
if (taskInRecents != null) {
// Re launch instance from recents
ActivityOptionsWrapper opts = getActivityLaunchOptions(null, info);
- opts.options.setLaunchDisplayId(
- getDisplay() == null ? DEFAULT_DISPLAY : getDisplay().getDisplayId());
+ opts.options.setLaunchDisplayId(displayId);
if (ActivityManagerWrapper.getInstance()
.startActivityFromRecents(taskInRecents.key, opts.options)) {
mControllers.uiController.getRecentsView()
@@ -1658,12 +1680,13 @@
return;
}
}
- ActivityOptionsWrapper opts = null;
if (areDesktopTasksVisible()) {
- opts = getActivityLaunchDesktopOptions(info);
+ ActivityOptionsWrapper opts = getActivityLaunchDesktopOptions(info);
+ Bundle optionsBundle = opts == null ? Bundle.EMPTY : opts.options.toBundle();
+ mSysUiProxy.startLaunchIntentTransition(intent, optionsBundle, displayId);
+ } else {
+ startActivity(intent, null);
}
- Bundle optionsBundle = opts == null ? null : opts.options.toBundle();
- startActivity(intent, optionsBundle);
} catch (NullPointerException | ActivityNotFoundException | SecurityException e) {
Toast.makeText(this, R.string.activity_not_found, Toast.LENGTH_SHORT)
.show();
diff --git a/quickstep/src/com/android/launcher3/taskbar/TaskbarHoverToolTipController.java b/quickstep/src/com/android/launcher3/taskbar/TaskbarHoverToolTipController.java
index 3bff31f..b7000db 100644
--- a/quickstep/src/com/android/launcher3/taskbar/TaskbarHoverToolTipController.java
+++ b/quickstep/src/com/android/launcher3/taskbar/TaskbarHoverToolTipController.java
@@ -108,7 +108,7 @@
revealHoverToolTip();
mActivity.setAutohideSuspendFlag(FLAG_AUTOHIDE_SUSPEND_HOVERING_ICONS, true);
}
- return true;
+ return false;
}
private void revealHoverToolTip() {
diff --git a/quickstep/src/com/android/launcher3/taskbar/TaskbarManager.java b/quickstep/src/com/android/launcher3/taskbar/TaskbarManager.java
index 7c6c7ac..21c8255 100644
--- a/quickstep/src/com/android/launcher3/taskbar/TaskbarManager.java
+++ b/quickstep/src/com/android/launcher3/taskbar/TaskbarManager.java
@@ -687,6 +687,20 @@
}
}
+ /**
+ * Signal from SysUI indicating that a non-mirroring display was just connected to the
+ * primary device.
+ */
+ public void onDisplayReady(int displayId) {
+ }
+
+ /**
+ * Signal from SysUI indicating that a previously connected non-mirroring display was just
+ * removed from the primary device.
+ */
+ public void onDisplayRemoved(int displayId) {
+ }
+
private void removeActivityCallbacksAndListeners() {
if (mActivity != null) {
mActivity.removeOnDeviceProfileChangeListener(mDebugActivityDeviceProfileChanged);
@@ -793,7 +807,8 @@
private TaskbarActivityContext createTaskbarActivityContext(DeviceProfile dp, int displayId) {
TaskbarActivityContext newTaskbar = new TaskbarActivityContext(mWindowContext,
mNavigationBarPanelContext, dp, mDefaultNavButtonController,
- mUnfoldProgressProvider, isDefaultDisplay(displayId));
+ mUnfoldProgressProvider, isDefaultDisplay(displayId),
+ SystemUiProxy.INSTANCE.get(mWindowContext));
addTaskbarToMap(displayId, newTaskbar);
return newTaskbar;
diff --git a/quickstep/src/com/android/launcher3/taskbar/TaskbarPopupController.java b/quickstep/src/com/android/launcher3/taskbar/TaskbarPopupController.java
index e704691..feb9b33 100644
--- a/quickstep/src/com/android/launcher3/taskbar/TaskbarPopupController.java
+++ b/quickstep/src/com/android/launcher3/taskbar/TaskbarPopupController.java
@@ -56,6 +56,7 @@
import com.android.launcher3.views.ActivityContext;
import com.android.quickstep.SystemUiProxy;
import com.android.quickstep.util.LogUtils;
+import com.android.wm.shell.shared.bubbles.BubbleAnythingFlagHelper;
import com.android.wm.shell.shared.desktopmode.DesktopModeStatus;
import java.io.PrintWriter;
@@ -219,7 +220,7 @@
.getAreDesktopTasksVisibleAndNotInOverview()) {
shortcuts.addAll(mControllers.uiController.getSplitMenuOptions().toList());
}
- if (com.android.wm.shell.Flags.enableBubbleAnything()) {
+ if (BubbleAnythingFlagHelper.enableCreateAnyBubble()) {
shortcuts.add(BUBBLE);
}
diff --git a/quickstep/src/com/android/launcher3/taskbar/TaskbarRecentAppsController.kt b/quickstep/src/com/android/launcher3/taskbar/TaskbarRecentAppsController.kt
index a059b22..4afabde 100644
--- a/quickstep/src/com/android/launcher3/taskbar/TaskbarRecentAppsController.kt
+++ b/quickstep/src/com/android/launcher3/taskbar/TaskbarRecentAppsController.kt
@@ -19,6 +19,7 @@
import android.window.DesktopModeFlags
import androidx.annotation.VisibleForTesting
import com.android.launcher3.BubbleTextView.RunningAppState
+import com.android.launcher3.Flags
import com.android.launcher3.Flags.enableRecentsInTaskbar
import com.android.launcher3.model.data.ItemInfo
import com.android.launcher3.model.data.TaskItemInfo
@@ -265,8 +266,8 @@
}
private fun updateOrderedRunningTaskIds(): MutableList<Int> {
- val desktopTaskAsList = getOrderedAndWrappedDesktopTasks()
- val desktopTaskIds = desktopTaskAsList.map { it.task1.key.id }
+ val desktopTasksAsList = getOrderedAndWrappedDesktopTasks().flatMap { it.tasks }
+ val desktopTaskIds = desktopTasksAsList.map { it.key.id }
var newOrder =
orderedRunningTaskIds
.filter { it in desktopTaskIds } // Only keep the tasks that are still running
@@ -276,27 +277,60 @@
return newOrder
}
+ /**
+ * Computes the list of running tasks to be shown in the recent apps section of the taskbar in
+ * desktop mode, taking into account deduplication against hotseat items and existing tasks.
+ */
private fun computeShownRunningTasks(): List<GroupTask> {
if (!canShowRunningApps) {
return emptyList()
}
- val desktopTaskAsList = getOrderedAndWrappedDesktopTasks()
- val desktopTaskIds = desktopTaskAsList.map { it.task1.key.id }
- val shownTaskIds = shownTasks.map { it.task1.key.id }
- // TODO(b/315344726 Multi-instance support): only show one icon per package once we support
- // taskbar multi-instance menus
- val shownHotseatItemTaskIds =
- shownHotseatItems.mapNotNull { it as? TaskItemInfo }.map { it.taskId }
- // Remove any newly-missing Tasks, and actual group-tasks
+
+ val desktopTasks = getOrderedAndWrappedDesktopTasks()
+
val newShownTasks =
- shownTasks
- .filter { !it.supportsMultipleTasks() }
- .filter { it.task1.key.id in desktopTaskIds }
- .toMutableList()
- // Add any new Tasks, maintaining the order from previous shownTasks.
- newShownTasks.addAll(desktopTaskAsList.filter { it.task1.key.id !in shownTaskIds })
- // Remove any tasks already covered by Hotseat icons
- return newShownTasks.filter { it.task1.key.id !in shownHotseatItemTaskIds }
+ if (Flags.enableMultiInstanceMenuTaskbar()) {
+ val deduplicatedDesktopTasks =
+ desktopTasks.distinctBy { Pair(it.task1.key.packageName, it.task1.key.userId) }
+
+ shownTasks
+ .filter {
+ !it.supportsMultipleTasks() &&
+ it.task1.key.id in deduplicatedDesktopTasks.map { it.task1.key.id }
+ }
+ .toMutableList()
+ .apply {
+ addAll(
+ deduplicatedDesktopTasks.filter { currentTask ->
+ val currentTaskKey = currentTask.task1.key
+ currentTaskKey.id !in shownTasks.map { it.task1.key.id } &&
+ shownHotseatItems.none { hotseatItem ->
+ hotseatItem.targetPackage == currentTaskKey.packageName &&
+ hotseatItem.user.identifier == currentTaskKey.userId
+ }
+ }
+ )
+ }
+ } else {
+ val desktopTaskIds = desktopTasks.map { it.task1.key.id }
+ val shownHotseatItemTaskIds =
+ shownHotseatItems.mapNotNull { it as? TaskItemInfo }.map { it.taskId }
+
+ shownTasks
+ .filter { !it.supportsMultipleTasks() && it.task1.key.id in desktopTaskIds }
+ .toMutableList()
+ .apply {
+ addAll(
+ desktopTasks.filter { desktopTask ->
+ desktopTask.task1.key.id !in
+ shownTasks.map { shownTask -> shownTask.task1.key.id }
+ }
+ )
+ removeAll { it.task1.key.id in shownHotseatItemTaskIds }
+ }
+ }
+
+ return newShownTasks
}
private fun computeShownRecentTasks(): List<GroupTask> {
@@ -305,7 +339,6 @@
}
// Remove the current task.
val allRecentTasks = allRecentTasks.subList(0, allRecentTasks.size - 1)
- // TODO(b/315344726 Multi-instance support): dedupe Tasks of the same package too
var shownTasks = dedupeHotseatTasks(allRecentTasks, shownHotseatItems)
if (shownTasks.size > MAX_RECENT_TASKS) {
// Remove any tasks older than MAX_RECENT_TASKS.
@@ -318,10 +351,22 @@
groupTasks: List<GroupTask>,
shownHotseatItems: List<ItemInfo>,
): List<GroupTask> {
- val hotseatPackages = shownHotseatItems.map { item -> item.targetPackage }
- return groupTasks.filter { groupTask ->
- groupTask.hasMultipleTasks() ||
- !hotseatPackages.contains(groupTask.task1.key.packageName)
+ return if (Flags.enableMultiInstanceMenuTaskbar()) {
+ groupTasks.filter { groupTask ->
+ val taskKey = groupTask.task1.key
+ // Keep tasks that are group tasks or unique package name/user combinations
+ groupTask.hasMultipleTasks() ||
+ shownHotseatItems.none {
+ it.targetPackage == taskKey.packageName &&
+ it.user.identifier == taskKey.userId
+ }
+ }
+ } else {
+ val hotseatPackages = shownHotseatItems.map { it.targetPackage }
+ groupTasks.filter { groupTask ->
+ groupTask.hasMultipleTasks() ||
+ !hotseatPackages.contains(groupTask.task1.key.packageName)
+ }
}
}
@@ -338,11 +383,13 @@
itemInfo
} else {
val foundTask =
- groupTasks.find { task ->
- task.task1.key.packageName == itemInfo.targetPackage &&
- task.task1.key.userId == itemInfo.user.identifier
- } ?: return@map itemInfo
- TaskItemInfo(foundTask.task1.key.id, itemInfo as WorkspaceItemInfo)
+ groupTasks
+ .flatMap { it.tasks }
+ .find { task ->
+ task.key.packageName == itemInfo.targetPackage &&
+ task.key.userId == itemInfo.user.identifier
+ } ?: return@map itemInfo
+ TaskItemInfo(foundTask.key.id, itemInfo as WorkspaceItemInfo)
}
}
diff --git a/quickstep/src/com/android/launcher3/taskbar/TaskbarView.java b/quickstep/src/com/android/launcher3/taskbar/TaskbarView.java
index 6b9f5a9..e4e97e5 100644
--- a/quickstep/src/com/android/launcher3/taskbar/TaskbarView.java
+++ b/quickstep/src/com/android/launcher3/taskbar/TaskbarView.java
@@ -402,6 +402,16 @@
view.setTag(null);
}
+ /** Loop through all {@link FolderIcon} as child views and clear listeners to avoid leak. */
+ public void removeFolderIconListeners() {
+ final int childCount = getChildCount();
+ for (int i = 0; i < childCount; i++) {
+ if (getChildAt(i) instanceof FolderIcon fi) {
+ fi.removeListeners();
+ }
+ }
+ }
+
/** Inflates/binds the hotseat items and recent tasks to the view. */
protected void updateItems(ItemInfo[] hotseatItemInfos, List<GroupTask> recentTasks) {
// Filter out unsupported items.
diff --git a/quickstep/src/com/android/launcher3/taskbar/TaskbarViewController.java b/quickstep/src/com/android/launcher3/taskbar/TaskbarViewController.java
index e0be39d..0f05887 100644
--- a/quickstep/src/com/android/launcher3/taskbar/TaskbarViewController.java
+++ b/quickstep/src/com/android/launcher3/taskbar/TaskbarViewController.java
@@ -365,6 +365,7 @@
if (enableTaskbarPinning()) {
mTaskbarView.removeOnLayoutChangeListener(mTaskbarViewLayoutChangeListener);
}
+ mTaskbarView.removeFolderIconListeners();
LauncherAppState.getInstance(mActivity).getModel().removeCallbacks(mModelCallbacks);
mActivity.removeOnDeviceProfileChangeListener(mDeviceProfileChangeListener);
}
diff --git a/quickstep/src/com/android/launcher3/taskbar/bubbles/BubbleBarViewController.java b/quickstep/src/com/android/launcher3/taskbar/bubbles/BubbleBarViewController.java
index afbc932..026f239 100644
--- a/quickstep/src/com/android/launcher3/taskbar/bubbles/BubbleBarViewController.java
+++ b/quickstep/src/com/android/launcher3/taskbar/bubbles/BubbleBarViewController.java
@@ -588,7 +588,7 @@
/** Returns maximum height of the bubble bar with the flyout view. */
public int getBubbleBarWithFlyoutMaximumHeight() {
- if (!isBubbleBarVisible() && !isAnimatingNewBubble()) return 0;
+ if (!hasBubbles() && !isAnimatingNewBubble()) return 0;
int bubbleBarTopOnHome = (int) (mBubbleStashController.getBubbleBarVerticalCenterForHome()
+ mBarView.getBubbleBarCollapsedHeight() / 2 + mBarView.getArrowHeight());
if (isAnimatingNewBubble()) {
diff --git a/quickstep/src/com/android/launcher3/uioverrides/PredictedAppIcon.java b/quickstep/src/com/android/launcher3/uioverrides/PredictedAppIcon.java
index caac35e..a85e5e0 100644
--- a/quickstep/src/com/android/launcher3/uioverrides/PredictedAppIcon.java
+++ b/quickstep/src/com/android/launcher3/uioverrides/PredictedAppIcon.java
@@ -36,6 +36,7 @@
import android.graphics.drawable.Drawable;
import android.util.AttributeSet;
import android.util.FloatProperty;
+import android.util.Log;
import android.util.Property;
import android.view.LayoutInflater;
import android.view.ViewGroup;
@@ -49,8 +50,8 @@
import com.android.launcher3.anim.AnimatorListeners;
import com.android.launcher3.celllayout.CellLayoutLayoutParams;
import com.android.launcher3.celllayout.DelegatedCellDrawing;
+import com.android.launcher3.graphics.IconShape;
import com.android.launcher3.icons.FastBitmapDrawable;
-import com.android.launcher3.icons.GraphicsUtils;
import com.android.launcher3.icons.IconNormalizer;
import com.android.launcher3.icons.LauncherIcons;
import com.android.launcher3.model.data.ItemInfoWithIcon;
@@ -110,6 +111,8 @@
private boolean mForceHideRing = false;
private Animator mRingScaleAnim;
+ private int mWidth;
+
private static final FloatProperty<PredictedAppIcon> SLOT_MACHINE_TRANSLATION_Y =
new FloatProperty<PredictedAppIcon>("slotMachineTranslationY") {
@Override
@@ -139,7 +142,7 @@
int shadowSize = context.getResources().getDimensionPixelSize(
R.dimen.blur_size_thin_outline);
mShadowFilter = new BlurMaskFilter(shadowSize, BlurMaskFilter.Blur.OUTER);
- mShapePath = GraphicsUtils.getShapePath(context, mNormalizedIconSize);
+ mShapePath = IconShape.INSTANCE.get(context).getShapeOverridePath(mNormalizedIconSize);
}
@Override
@@ -300,7 +303,13 @@
}
private int getOutlineOffsetX() {
- return (getMeasuredWidth() - mNormalizedIconSize) / 2;
+ int measuredWidth = getMeasuredWidth();
+ if (mDisplay != DISPLAY_TASKBAR) {
+ Log.d("b/387844520", "getOutlineOffsetX: measured width = " + measuredWidth
+ + ", mNormalizedIconSize = " + mNormalizedIconSize
+ + ", last updated width = " + mWidth);
+ }
+ return (mWidth - mNormalizedIconSize) / 2;
}
private int getOutlineOffsetY() {
@@ -313,7 +322,11 @@
@Override
protected void onSizeChanged(int w, int h, int oldw, int oldh) {
super.onSizeChanged(w, h, oldw, oldh);
+ mWidth = w;
mSlotIconBound.offsetTo((w - getIconSize()) / 2, (h - getIconSize()) / 2);
+ if (mDisplay != DISPLAY_TASKBAR) {
+ Log.d("b/387844520", "calling updateRingPath from onSizeChanged");
+ }
updateRingPath();
}
@@ -325,6 +338,7 @@
private void updateRingPath() {
mRingPath.reset();
+ mTmpMatrix.reset();
mTmpMatrix.setTranslate(getOutlineOffsetX(), getOutlineOffsetY());
mRingPath.addPath(mShapePath, mTmpMatrix);
@@ -339,6 +353,7 @@
mTmpMatrix.preTranslate(-mNormalizedIconSize, -mNormalizedIconSize);
mRingPath.addPath(mShapePath, mTmpMatrix);
}
+ invalidate();
}
@Override
diff --git a/quickstep/src/com/android/launcher3/uioverrides/QuickstepLauncher.java b/quickstep/src/com/android/launcher3/uioverrides/QuickstepLauncher.java
index 810325c..58ebc50 100644
--- a/quickstep/src/com/android/launcher3/uioverrides/QuickstepLauncher.java
+++ b/quickstep/src/com/android/launcher3/uioverrides/QuickstepLauncher.java
@@ -64,7 +64,6 @@
import static com.android.quickstep.util.AnimUtils.completeRunnableListCallback;
import static com.android.quickstep.util.SplitAnimationTimings.TABLET_HOME_TO_SPLIT;
import static com.android.systemui.shared.system.ActivityManagerWrapper.CLOSE_SYSTEM_WINDOWS_REASON_HOME_KEY;
-import static com.android.wm.shell.Flags.enableBubbleAnything;
import static com.android.wm.shell.shared.split.SplitScreenConstants.SNAP_TO_2_50_50;
import android.animation.Animator;
@@ -85,6 +84,7 @@
import android.os.IRemoteCallback;
import android.os.SystemProperties;
import android.os.Trace;
+import android.os.UserHandle;
import android.util.AttributeSet;
import android.view.Display;
import android.view.HapticFeedbackConstants;
@@ -200,6 +200,7 @@
import com.android.systemui.unfold.dagger.UnfoldMain;
import com.android.systemui.unfold.progress.RemoteUnfoldTransitionReceiver;
import com.android.systemui.unfold.updates.RotationChangeProvider;
+import com.android.wm.shell.shared.bubbles.BubbleAnythingFlagHelper;
import com.android.wm.shell.shared.bubbles.BubbleBarLocation;
import com.android.wm.shell.shared.desktopmode.DesktopModeStatus;
@@ -467,7 +468,7 @@
if (Flags.enablePrivateSpace()) {
shortcuts.add(UNINSTALL_APP);
}
- if (enableBubbleAnything()) {
+ if (BubbleAnythingFlagHelper.enableCreateAnyBubble()) {
shortcuts.add(BUBBLE_SHORTCUT);
}
return shortcuts.stream();
@@ -1431,9 +1432,9 @@
}
@Override
- public void showAppBubble(Intent intent) {
+ public void showAppBubble(Intent intent, UserHandle user) {
if (intent == null || intent.getPackage() == null) return;
- SystemUiProxy.INSTANCE.get(this).showAppBubble(intent);
+ SystemUiProxy.INSTANCE.get(this).showAppBubble(intent, user);
}
/** Sets the location of the bubble bar */
diff --git a/quickstep/src/com/android/quickstep/AbsSwipeUpHandler.java b/quickstep/src/com/android/quickstep/AbsSwipeUpHandler.java
index 3dd1473..8b76ce9 100644
--- a/quickstep/src/com/android/quickstep/AbsSwipeUpHandler.java
+++ b/quickstep/src/com/android/quickstep/AbsSwipeUpHandler.java
@@ -1826,9 +1826,7 @@
final Rect hotseatKeepClearArea = getKeepClearAreaForHotseat();
final Rect destinationBounds = SystemUiProxy.INSTANCE.get(mContext)
- .startSwipePipToHome(taskInfo.topActivity,
- taskInfo.topActivityInfo,
- runningTaskTarget.taskInfo.pictureInPictureParams,
+ .startSwipePipToHome(taskInfo,
homeRotation,
hotseatKeepClearArea);
if (destinationBounds == null) {
diff --git a/quickstep/src/com/android/quickstep/GestureState.java b/quickstep/src/com/android/quickstep/GestureState.java
index e0fa77a..e1d4536 100644
--- a/quickstep/src/com/android/quickstep/GestureState.java
+++ b/quickstep/src/com/android/quickstep/GestureState.java
@@ -28,7 +28,6 @@
import static com.android.quickstep.util.ActiveGestureErrorDetector.GestureEvent.SET_END_TARGET_HOME;
import static com.android.quickstep.util.ActiveGestureErrorDetector.GestureEvent.SET_END_TARGET_NEW_TASK;
-import android.app.TaskInfo;
import android.content.Intent;
import android.os.SystemClock;
import android.view.MotionEvent;
@@ -47,7 +46,6 @@
import com.android.quickstep.util.ActiveGestureProtoLogProxy;
import com.android.quickstep.views.RecentsViewContainer;
import com.android.systemui.shared.recents.model.ThumbnailData;
-import com.android.wm.shell.shared.GroupedTaskInfo;
import java.io.PrintWriter;
import java.util.ArrayList;
@@ -334,13 +332,7 @@
return new int[]{INVALID_TASK_ID, INVALID_TASK_ID};
} else {
if (com.android.wm.shell.Flags.enableShellTopTaskTracking()) {
- if (mRunningTask.getVisibleTasks().isEmpty()) {
- return new int[0];
- }
- GroupedTaskInfo topRunningTask = mRunningTask.getVisibleTasks().getFirst();
- List<TaskInfo> groupedTasks = topRunningTask.getTaskInfoList();
- return groupedTasks.stream().mapToInt(
- groupedTask -> groupedTask.taskId).toArray();
+ return mRunningTask.topGroupedTaskIds();
} else {
int cachedTasksSize = mRunningTask.mAllCachedTasks.size();
int count = Math.min(cachedTasksSize, getMultipleTasks ? 2 : 1);
diff --git a/quickstep/src/com/android/quickstep/RecentTasksList.java b/quickstep/src/com/android/quickstep/RecentTasksList.java
index 32ccd72..ee4ee38 100644
--- a/quickstep/src/com/android/quickstep/RecentTasksList.java
+++ b/quickstep/src/com/android/quickstep/RecentTasksList.java
@@ -21,6 +21,7 @@
import static com.android.launcher3.util.Executors.UI_HELPER_EXECUTOR;
import static com.android.quickstep.util.SplitScreenUtils.convertShellSplitBoundsToLauncher;
import static com.android.wm.shell.shared.GroupedTaskInfo.TYPE_FREEFORM;
+import static com.android.wm.shell.shared.GroupedTaskInfo.TYPE_SPLIT;
import android.app.ActivityManager.RunningTaskInfo;
import android.app.KeyguardManager;
@@ -39,6 +40,7 @@
import com.android.quickstep.util.DesktopTask;
import com.android.quickstep.util.GroupTask;
import com.android.systemui.shared.recents.model.Task;
+import com.android.wm.shell.Flags;
import com.android.wm.shell.recents.IRecentTasksListener;
import com.android.wm.shell.shared.GroupedTaskInfo;
import com.android.wm.shell.shared.desktopmode.DesktopModeStatus;
@@ -116,7 +118,8 @@
@Override
public void onTaskMovedToFront(GroupedTaskInfo taskToFront) {
mMainThreadExecutor.execute(() -> {
- topTaskTracker.handleTaskMovedToFront(taskToFront.getTaskInfo1());
+ topTaskTracker.handleTaskMovedToFront(
+ taskToFront.getBaseGroupedTask().getTaskInfo1());
});
}
@@ -340,50 +343,74 @@
int numVisibleTasks = 0;
for (GroupedTaskInfo rawTask : rawTasks) {
- if (rawTask.getType() == TYPE_FREEFORM) {
+ if (rawTask.isBaseType(TYPE_FREEFORM)) {
// TYPE_FREEFORM tasks is only created when desktop mode can be entered,
// leftover TYPE_FREEFORM tasks created when flag was on should be ignored.
if (DesktopModeStatus.canEnterDesktopMode(mContext)) {
- GroupTask desktopTask = createDesktopTask(rawTask);
+ GroupTask desktopTask = createDesktopTask(rawTask.getBaseGroupedTask());
if (desktopTask != null) {
allTasks.add(desktopTask);
}
}
continue;
}
- TaskInfo taskInfo1 = rawTask.getTaskInfo1();
- TaskInfo taskInfo2 = rawTask.getTaskInfo2();
- Task.TaskKey task1Key = new Task.TaskKey(taskInfo1);
- Task task1 = loadKeysOnly
- ? new Task(task1Key)
- : Task.from(task1Key, taskInfo1,
- tmpLockedUsers.get(task1Key.userId) /* isLocked */);
- Task task2 = null;
- if (taskInfo2 != null) {
- // Is split task
- Task.TaskKey task2Key = new Task.TaskKey(taskInfo2);
- task2 = loadKeysOnly
- ? new Task(task2Key)
- : Task.from(task2Key, taskInfo2,
- tmpLockedUsers.get(task2Key.userId) /* isLocked */);
+
+ if (Flags.enableShellTopTaskTracking()) {
+ final TaskInfo taskInfo1 = rawTask.getBaseGroupedTask().getTaskInfo1();
+ final Task.TaskKey task1Key = new Task.TaskKey(taskInfo1);
+ final Task task1 = Task.from(task1Key, taskInfo1,
+ tmpLockedUsers.get(task1Key.userId) /* isLocked */);
+ final Task task2;
+ final SplitConfigurationOptions.SplitBounds launcherSplitBounds;
+
+ if (rawTask.isBaseType(TYPE_SPLIT)) {
+ final TaskInfo taskInfo2 = rawTask.getBaseGroupedTask().getTaskInfo2();
+ final Task.TaskKey task2Key = new Task.TaskKey(taskInfo2);
+ task2 = Task.from(task2Key, taskInfo2,
+ tmpLockedUsers.get(task2Key.userId) /* isLocked */);
+ launcherSplitBounds =
+ convertShellSplitBoundsToLauncher(
+ rawTask.getBaseGroupedTask().getSplitBounds());
+ } else {
+ task2 = null;
+ launcherSplitBounds = null;
+ }
+ allTasks.add(new GroupTask(task1, task2, launcherSplitBounds));
} else {
- // Is fullscreen task
- if (numVisibleTasks > 0) {
- boolean isExcluded = (taskInfo1.baseIntent.getFlags()
- & FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS) != 0;
- if (taskInfo1.isTopActivityTransparent && isExcluded) {
- // If there are already visible tasks, then ignore the excluded tasks and
- // don't add them to the returned list
- continue;
+ TaskInfo taskInfo1 = rawTask.getTaskInfo1();
+ TaskInfo taskInfo2 = rawTask.getTaskInfo2();
+ Task.TaskKey task1Key = new Task.TaskKey(taskInfo1);
+ Task task1 = loadKeysOnly
+ ? new Task(task1Key)
+ : Task.from(task1Key, taskInfo1,
+ tmpLockedUsers.get(task1Key.userId) /* isLocked */);
+ Task task2 = null;
+ if (taskInfo2 != null) {
+ // Is split task
+ Task.TaskKey task2Key = new Task.TaskKey(taskInfo2);
+ task2 = loadKeysOnly
+ ? new Task(task2Key)
+ : Task.from(task2Key, taskInfo2,
+ tmpLockedUsers.get(task2Key.userId) /* isLocked */);
+ } else {
+ // Is fullscreen task
+ if (numVisibleTasks > 0) {
+ boolean isExcluded = (taskInfo1.baseIntent.getFlags()
+ & FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS) != 0;
+ if (taskInfo1.isTopActivityTransparent && isExcluded) {
+ // If there are already visible tasks, then ignore the excluded tasks
+ // and don't add them to the returned list
+ continue;
+ }
}
}
+ if (taskInfo1.isVisible) {
+ numVisibleTasks++;
+ }
+ final SplitConfigurationOptions.SplitBounds launcherSplitBounds =
+ convertShellSplitBoundsToLauncher(rawTask.getSplitBounds());
+ allTasks.add(new GroupTask(task1, task2, launcherSplitBounds));
}
- if (taskInfo1.isVisible) {
- numVisibleTasks++;
- }
- final SplitConfigurationOptions.SplitBounds launcherSplitBounds =
- convertShellSplitBoundsToLauncher(rawTask.getSplitBounds());
- allTasks.add(new GroupTask(task1, task2, launcherSplitBounds));
}
return allTasks;
@@ -409,14 +436,6 @@
return new DesktopTask(tasks);
}
- private ArrayList<GroupTask> copyOf(ArrayList<GroupTask> tasks) {
- ArrayList<GroupTask> newTasks = new ArrayList<>();
- for (int i = 0; i < tasks.size(); i++) {
- newTasks.add(tasks.get(i).copy());
- }
- return newTasks;
- }
-
public void dump(String prefix, PrintWriter writer) {
writer.println(prefix + "RecentTasksList:");
writer.println(prefix + " mChangeId=" + mChangeId);
@@ -439,14 +458,7 @@
}
writer.println(prefix + " rawTasks=[");
for (GroupedTaskInfo task : rawTasks) {
- TaskInfo taskInfo1 = task.getTaskInfo1();
- TaskInfo taskInfo2 = task.getTaskInfo2();
- ComponentName cn1 = taskInfo1.topActivity;
- ComponentName cn2 = taskInfo2 != null ? taskInfo2.topActivity : null;
- writer.println(prefix + " t1: (id=" + taskInfo1.taskId
- + "; package=" + (cn1 != null ? cn1.getPackageName() + ")" : "no package)")
- + " t2: (id=" + (taskInfo2 != null ? taskInfo2.taskId : "-1")
- + "; package=" + (cn2 != null ? cn2.getPackageName() + ")" : "no package)"));
+ writer.println(prefix + task);
}
writer.println(prefix + " ]");
}
diff --git a/quickstep/src/com/android/quickstep/SystemUiProxy.kt b/quickstep/src/com/android/quickstep/SystemUiProxy.kt
index f2cedba..94ef4dd 100644
--- a/quickstep/src/com/android/quickstep/SystemUiProxy.kt
+++ b/quickstep/src/com/android/quickstep/SystemUiProxy.kt
@@ -19,11 +19,9 @@
import android.app.ActivityManager.RunningTaskInfo
import android.app.ActivityOptions
import android.app.PendingIntent
-import android.app.PictureInPictureParams
import android.content.ComponentName
import android.content.Context
import android.content.Intent
-import android.content.pm.ActivityInfo
import android.content.pm.ShortcutInfo
import android.graphics.Point
import android.graphics.Rect
@@ -83,6 +81,7 @@
import com.android.wm.shell.common.pip.IPipAnimationListener
import com.android.wm.shell.desktopmode.IDesktopMode
import com.android.wm.shell.desktopmode.IDesktopTaskListener
+import com.android.wm.shell.desktopmode.IMoveToDesktopCallback
import com.android.wm.shell.draganddrop.IDragAndDrop
import com.android.wm.shell.onehanded.IOneHanded
import com.android.wm.shell.recents.IRecentTasks
@@ -95,6 +94,7 @@
import com.android.wm.shell.shared.bubbles.BubbleBarLocation.UpdateSource
import com.android.wm.shell.shared.desktopmode.DesktopModeStatus
import com.android.wm.shell.shared.desktopmode.DesktopModeTransitionSource
+import com.android.wm.shell.shared.desktopmode.DesktopTaskToFrontReason
import com.android.wm.shell.shared.split.SplitBounds
import com.android.wm.shell.shared.split.SplitScreenConstants.PersistentSnapPosition
import com.android.wm.shell.splitscreen.ISplitScreen
@@ -170,7 +170,7 @@
* different process). It is bare-bones, so it's expected that the component and options will be
* provided via fill-in intent.
*/
- private val recentsPendingIntent =
+ private val recentsPendingIntent by lazy {
PendingIntent.getActivity(
context,
0,
@@ -184,6 +184,7 @@
)
.toBundle(),
)
+ }
val unfoldTransitionProvider: ProxyUnfoldTransitionProvider? =
if ((Flags.enableUnfoldStateAnimation() && ResourceUnfoldTransitionConfig().isEnabled))
@@ -499,20 +500,12 @@
/** @return Destination bounds of auto-pip animation, `null` if the animation is not ready. */
fun startSwipePipToHome(
- componentName: ComponentName?,
- activityInfo: ActivityInfo?,
- pictureInPictureParams: PictureInPictureParams?,
+ taskInfo: RunningTaskInfo,
launcherRotation: Int,
hotseatKeepClearArea: Rect?,
): Rect? {
executeWithErrorLog({ "Failed call startSwipePipToHome" }) {
- return pip?.startSwipePipToHome(
- componentName,
- activityInfo,
- pictureInPictureParams,
- launcherRotation,
- hotseatKeepClearArea,
- )
+ return pip?.startSwipePipToHome(taskInfo, launcherRotation, hotseatKeepClearArea)
}
return null
}
@@ -673,8 +666,10 @@
*
* @param intent the intent used to create the bubble.
*/
- fun showAppBubble(intent: Intent?) =
- executeWithErrorLog({ "Failed call showAppBubble" }) { bubbles?.showAppBubble(intent) }
+ fun showAppBubble(intent: Intent?, user: UserHandle) =
+ executeWithErrorLog({ "Failed call showAppBubble" }) {
+ bubbles?.showAppBubble(intent, user)
+ }
/** Tells SysUI to show the expanded view. */
fun showExpandedView() =
@@ -838,6 +833,15 @@
splitScreen?.startIntent(intent, userId, fillInIntent, position, options, instanceId)
}
+ /**
+ * Call the desktop mode interface to start a TRANSIT_OPEN transition when launching an intent
+ * from the taskbar so that it can be handled in desktop mode.
+ */
+ fun startLaunchIntentTransition(intent: Intent, options: Bundle, displayId: Int) =
+ executeWithErrorLog({ "Failed call startLaunchIntentTransition" }) {
+ desktopMode?.startLaunchIntentTransition(intent, options, displayId)
+ }
+
//
// One handed
//
@@ -1076,9 +1080,13 @@
}
/** If task with the given id is on the desktop, bring it to front */
- fun showDesktopApp(taskId: Int, transition: RemoteTransition?) =
+ fun showDesktopApp(
+ taskId: Int,
+ transition: RemoteTransition?,
+ toFrontReason: DesktopTaskToFrontReason,
+ ) =
executeWithErrorLog({ "Failed call showDesktopApp" }) {
- desktopMode?.showDesktopApp(taskId, transition)
+ desktopMode?.showDesktopApp(taskId, transition, toFrontReason)
}
/** Call shell to get number of visible freeform tasks */
@@ -1108,9 +1116,19 @@
taskId: Int,
transitionSource: DesktopModeTransitionSource?,
transition: RemoteTransition?,
+ successCallback: Runnable,
) =
executeWithErrorLog({ "Failed call moveToDesktop" }) {
- desktopMode?.moveToDesktop(taskId, transitionSource, transition)
+ desktopMode?.moveToDesktop(
+ taskId,
+ transitionSource,
+ transition,
+ object : IMoveToDesktopCallback.Stub() {
+ override fun onTaskMovedToDesktop() {
+ successCallback.run()
+ }
+ },
+ )
}
/** Call shell to remove the desktop that is on given `displayId` */
diff --git a/quickstep/src/com/android/quickstep/TopTaskTracker.java b/quickstep/src/com/android/quickstep/TopTaskTracker.java
index bfd6107..b3d9da3 100644
--- a/quickstep/src/com/android/quickstep/TopTaskTracker.java
+++ b/quickstep/src/com/android/quickstep/TopTaskTracker.java
@@ -24,12 +24,12 @@
import static com.android.launcher3.util.SplitConfigurationOptions.STAGE_POSITION_TOP_OR_LEFT;
import static com.android.launcher3.util.SplitConfigurationOptions.STAGE_TYPE_A;
+import static com.android.wm.shell.Flags.enableShellTopTaskTracking;
import static com.android.wm.shell.Flags.enableFlexibleSplit;
import static com.android.wm.shell.shared.GroupedTaskInfo.TYPE_SPLIT;
import android.app.ActivityManager.RunningTaskInfo;
import android.app.TaskInfo;
-import android.content.Context;
import android.util.ArrayMap;
import android.util.Log;
@@ -37,7 +37,6 @@
import androidx.annotation.Nullable;
import androidx.annotation.UiThread;
-import com.android.launcher3.dagger.ApplicationContext;
import com.android.launcher3.dagger.LauncherAppSingleton;
import com.android.launcher3.util.DaggerSingletonObject;
import com.android.launcher3.util.DaggerSingletonTracker;
@@ -77,8 +76,6 @@
private static final int HISTORY_SIZE = 5;
- private final Context mContext;
-
// Only used when Flags.enableShellTopTaskTracking() is disabled
// Ordered list with first item being the most recent task.
private final LinkedList<TaskInfo> mOrderedTaskList = new LinkedList<>();
@@ -87,20 +84,13 @@
private int mPinnedTaskId = INVALID_TASK_ID;
// Only used when Flags.enableShellTopTaskTracking() is enabled
- // Mapping of display id to running tasks. Running tasks are ordered from top most to
- // bottom most.
- private ArrayMap<Integer, ArrayList<GroupedTaskInfo>> mVisibleTasks = new ArrayMap<>();
+ // Mapping of display id to visible tasks. Visible tasks are ordered from top most to bottom
+ // most.
+ private ArrayMap<Integer, GroupedTaskInfo> mVisibleTasks = new ArrayMap<>();
@Inject
- public TopTaskTracker(@ApplicationContext Context context, DaggerSingletonTracker tracker,
- SystemUiProxy systemUiProxy) {
- mContext = context;
-
- if (com.android.wm.shell.Flags.enableShellTopTaskTracking()) {
- // Just prepopulate a list for the default display tasks so we don't need to add null
- // checks everywhere
- mVisibleTasks.put(DEFAULT_DISPLAY, new ArrayList<>());
- } else {
+ public TopTaskTracker(DaggerSingletonTracker tracker, SystemUiProxy systemUiProxy) {
+ if (!enableShellTopTaskTracking()) {
mMainStagePosition.stageType = SplitConfigurationOptions.STAGE_TYPE_MAIN;
mSideStagePosition.stageType = SplitConfigurationOptions.STAGE_TYPE_SIDE;
@@ -109,7 +99,7 @@
}
tracker.addCloseable(() -> {
- if (com.android.wm.shell.Flags.enableShellTopTaskTracking()) {
+ if (enableShellTopTaskTracking()) {
return;
}
@@ -120,7 +110,7 @@
@Override
public void onTaskRemoved(int taskId) {
- if (com.android.wm.shell.Flags.enableShellTopTaskTracking()) {
+ if (enableShellTopTaskTracking()) {
return;
}
@@ -133,7 +123,7 @@
}
void handleTaskMovedToFront(TaskInfo taskInfo) {
- if (com.android.wm.shell.Flags.enableShellTopTaskTracking()) {
+ if (enableShellTopTaskTracking()) {
return;
}
@@ -187,32 +177,25 @@
* Called when the set of visible tasks have changed.
*/
public void onVisibleTasksChanged(GroupedTaskInfo[] visibleTasks) {
- if (!com.android.wm.shell.Flags.enableShellTopTaskTracking()) {
+ if (!enableShellTopTaskTracking()) {
return;
}
- // TODO(346588978): Per-display info, just have everything in order by display
-
// Clear existing tasks for each display
- mVisibleTasks.forEach((displayId, visibleTasksOnDisplay) -> visibleTasksOnDisplay.clear());
+ mVisibleTasks.clear();
// Update the visible tasks on each display
- for (int i = 0; i < visibleTasks.length; i++) {
- final int displayId = visibleTasks[i].getTaskInfo1().getDisplayId();
- final ArrayList<GroupedTaskInfo> displayTasks;
- if (mVisibleTasks.containsKey(displayId)) {
- displayTasks = mVisibleTasks.get(displayId);
- } else {
- displayTasks = new ArrayList<>();
- mVisibleTasks.put(displayId, displayTasks);
- }
- displayTasks.add(visibleTasks[i]);
+ Log.d(TAG, "onVisibleTasksChanged:");
+ for (GroupedTaskInfo groupedTask : visibleTasks) {
+ Log.d(TAG, "\t" + groupedTask);
+ final int displayId = groupedTask.getBaseGroupedTask().getTaskInfo1().getDisplayId();
+ mVisibleTasks.put(displayId, groupedTask);
}
}
@Override
public void onStagePositionChanged(@StageType int stage, @StagePosition int position) {
- if (com.android.wm.shell.Flags.enableShellTopTaskTracking()) {
+ if (enableShellTopTaskTracking()) {
return;
}
@@ -224,7 +207,7 @@
}
public void onTaskChanged(RunningTaskInfo taskInfo) {
- if (com.android.wm.shell.Flags.enableShellTopTaskTracking()) {
+ if (enableShellTopTaskTracking()) {
return;
}
@@ -238,7 +221,7 @@
@Override
public void onTaskStageChanged(int taskId, @StageType int stage, boolean visible) {
- if (com.android.wm.shell.Flags.enableShellTopTaskTracking()) {
+ if (enableShellTopTaskTracking()) {
return;
}
@@ -262,7 +245,7 @@
@Override
public void onActivityPinned(String packageName, int userId, int taskId, int stackId) {
- if (com.android.wm.shell.Flags.enableShellTopTaskTracking()) {
+ if (enableShellTopTaskTracking()) {
return;
}
@@ -271,7 +254,7 @@
@Override
public void onActivityUnpinned() {
- if (com.android.wm.shell.Flags.enableShellTopTaskTracking()) {
+ if (enableShellTopTaskTracking()) {
return;
}
@@ -279,16 +262,17 @@
}
/**
- * @return index 0 will be task in left/top position, index 1 in right/bottom position.
- * Will return empty array if device is not in staged split
+ * Return the running split task ids. Index 0 will be task in left/top position, index 1 in
+ * right/bottom position, or and empty array if device is not in splitscreen.
*/
public int[] getRunningSplitTaskIds() {
- if (com.android.wm.shell.Flags.enableShellTopTaskTracking()) {
- // TODO(346588978): This assumes default display for now
- final ArrayList<GroupedTaskInfo> visibleTasks = mVisibleTasks.get(DEFAULT_DISPLAY);
- final GroupedTaskInfo splitTaskInfo = visibleTasks.stream()
- .filter(taskInfo -> taskInfo.getType() == TYPE_SPLIT)
- .findFirst().orElse(null);
+ if (enableShellTopTaskTracking()) {
+ // TODO(346588978): This assumes default display as splitscreen is only currently there
+ final GroupedTaskInfo visibleTasks = mVisibleTasks.get(DEFAULT_DISPLAY);
+ final GroupedTaskInfo splitTaskInfo =
+ visibleTasks != null && visibleTasks.isBaseType(TYPE_SPLIT)
+ ? visibleTasks.getBaseGroupedTask()
+ : null;
if (splitTaskInfo != null && splitTaskInfo.getSplitBounds() != null) {
return new int[] {
splitTaskInfo.getSplitBounds().leftTopTaskId,
@@ -317,24 +301,13 @@
* Dumps the list of tasks in top task tracker.
*/
public void dump(PrintWriter pw) {
- if (!com.android.wm.shell.Flags.enableShellTopTaskTracking()) {
+ if (!enableShellTopTaskTracking()) {
return;
}
- // TODO(346588978): This assumes default display for now
- final ArrayList<GroupedTaskInfo> displayTasks = mVisibleTasks.get(DEFAULT_DISPLAY);
pw.println("TopTaskTracker:");
- pw.println(" tasks: [");
- for (GroupedTaskInfo taskInfo : displayTasks) {
- final TaskInfo info = taskInfo.getTaskInfo1();
- final boolean isExcluded = (info.baseIntent.getFlags()
- & FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS) != 0;
- pw.println(" " + info.taskId + ": excluded=" + isExcluded
- + " visibleRequested=" + info.isVisibleRequested
- + " visible=" + info.isVisible
- + " " + info.baseIntent.getComponent());
- }
- pw.println(" ]");
+ mVisibleTasks.forEach((displayId, tasks) ->
+ pw.println(" visibleTasks(" + displayId + "): " + tasks));
}
/**
@@ -343,13 +316,12 @@
@NonNull
@UiThread
public CachedTaskInfo getCachedTopTask(boolean filterOnlyVisibleRecents) {
- if (com.android.wm.shell.Flags.enableShellTopTaskTracking()) {
+ if (enableShellTopTaskTracking()) {
// TODO(346588978): Currently ignore filterOnlyVisibleRecents, but perhaps make this an
// explicit filter For things to ignore (ie. PIP/Bubbles/Assistant/etc/so that this is
// explicit)
- // TODO(346588978): This assumes default display for now (as does all of Launcher)
- final ArrayList<GroupedTaskInfo> displayTasks = mVisibleTasks.get(DEFAULT_DISPLAY);
- return new CachedTaskInfo(new ArrayList<>(displayTasks));
+ // TODO(346588978): This assumes default display as gesture nav is only supported there
+ return new CachedTaskInfo(mVisibleTasks.get(DEFAULT_DISPLAY));
} else {
if (filterOnlyVisibleRecents) {
// Since we only know about the top most task, any filtering may not be applied on
@@ -374,6 +346,11 @@
}
}
+ private static boolean isHomeTask(TaskInfo task) {
+ return task != null && task.configuration.windowConfiguration
+ .getActivityType() == ACTIVITY_TYPE_HOME;
+ }
+
private static boolean isRecentsTask(TaskInfo task) {
return task != null && task.configuration.windowConfiguration
.getActivityType() == ACTIVITY_TYPE_RECENTS;
@@ -384,7 +361,6 @@
* during the lifecycle of the task.
*/
public static class CachedTaskInfo {
-
// Only used when enableShellTopTaskTracking() is disabled
@Nullable
private final TaskInfo mTopTask;
@@ -393,40 +369,48 @@
// Only used when enableShellTopTaskTracking() is enabled
@Nullable
- private final GroupedTaskInfo mTopGroupedTask;
- @Nullable
- private final ArrayList<GroupedTaskInfo> mVisibleTasks;
+ private final GroupedTaskInfo mVisibleTasks;
// Only used when enableShellTopTaskTracking() is enabled
- CachedTaskInfo(@NonNull ArrayList<GroupedTaskInfo> visibleTasks) {
+ CachedTaskInfo(@Nullable GroupedTaskInfo visibleTasks) {
mAllCachedTasks = null;
mTopTask = null;
mVisibleTasks = visibleTasks;
- mTopGroupedTask = !mVisibleTasks.isEmpty() ? mVisibleTasks.getFirst() : null;
}
// Only used when enableShellTopTaskTracking() is disabled
CachedTaskInfo(@NonNull List<TaskInfo> allCachedTasks) {
mVisibleTasks = null;
- mTopGroupedTask = null;
mAllCachedTasks = allCachedTasks;
mTopTask = allCachedTasks.isEmpty() ? null : allCachedTasks.get(0);
}
/**
- * @return The list of visible tasks
+ * Returns the "base" task that is used the as the representative running task of the set
+ * of tasks initially provided.
+ *
+ * Not for general use, as in other windowing modes (ie. split/desktop) the caller should
+ * not make assumptions about there being a single base task.
+ * TODO(346588978): Try to remove all usage of this if possible
*/
- public ArrayList<GroupedTaskInfo> getVisibleTasks() {
- return mVisibleTasks;
+ @Nullable
+ private TaskInfo getLegacyBaseTask() {
+ if (enableShellTopTaskTracking()) {
+ return mVisibleTasks != null
+ ? mVisibleTasks.getBaseGroupedTask().getTaskInfo1()
+ : null;
+ } else {
+ return mTopTask;
+ }
}
/**
- * @return The top task id
+ * Returns the top task id.
*/
public int getTaskId() {
- if (com.android.wm.shell.Flags.enableShellTopTaskTracking()) {
+ if (enableShellTopTaskTracking()) {
// Callers should use topGroupedTaskContainsTask() instead
return INVALID_TASK_ID;
} else {
@@ -435,29 +419,58 @@
}
/**
- * @return Whether the top grouped task contains the given {@param taskId} if
- * Flags.enableShellTopTaskTracking() is true, otherwise it checks the top
- * task as reported from TaskStackListener.
+ * Returns the top grouped task ids if Flags.enableShellTopTaskTracking() is true, otherwise
+ * an empty array.
+ */
+ public int[] topGroupedTaskIds() {
+ if (enableShellTopTaskTracking()) {
+ if (mVisibleTasks == null) {
+ return new int[0];
+ }
+ List<TaskInfo> groupedTasks = mVisibleTasks.getTaskInfoList();
+ return groupedTasks.stream().mapToInt(
+ groupedTask -> groupedTask.taskId).toArray();
+ } else {
+ // Not used
+ return new int[0];
+ }
+ }
+
+ /**
+ * Returns whether the top grouped task contains the given {@param taskId} if
+ * Flags.enableShellTopTaskTracking() is true, otherwise it checks the top task as reported
+ * from TaskStackListener.
*/
public boolean topGroupedTaskContainsTask(int taskId) {
- if (com.android.wm.shell.Flags.enableShellTopTaskTracking()) {
- return mTopGroupedTask != null && mTopGroupedTask.containsTask(taskId);
+ if (enableShellTopTaskTracking()) {
+ return mVisibleTasks != null && mVisibleTasks.containsTask(taskId);
} else {
return mTopTask != null && mTopTask.taskId == taskId;
}
}
/**
- * Returns true if the root of the task chooser activity
+ * Returns true if this represents the task chooser activity
*/
public boolean isRootChooseActivity() {
- if (com.android.wm.shell.Flags.enableShellTopTaskTracking()) {
- // TODO(346588978): Update this to not make an assumption on a specific task info
- return mTopGroupedTask != null && ACTION_CHOOSER.equals(
- mTopGroupedTask.getTaskInfo1().baseIntent.getAction());
- } else {
- return mTopTask != null && ACTION_CHOOSER.equals(mTopTask.baseIntent.getAction());
- }
+ final TaskInfo baseTask = getLegacyBaseTask();
+ return baseTask != null && ACTION_CHOOSER.equals(baseTask.baseIntent.getAction());
+ }
+
+ /**
+ * Returns true if this represents the HOME activity type task
+ */
+ public boolean isHomeTask() {
+ final TaskInfo baseTask = getLegacyBaseTask();
+ return baseTask != null && TopTaskTracker.isHomeTask(baseTask);
+ }
+
+ /**
+ * Returns true if this represents the RECENTS activity type task
+ */
+ public boolean isRecentsTask() {
+ final TaskInfo baseTask = getLegacyBaseTask();
+ return baseTask != null && TopTaskTracker.isRecentsTask(baseTask);
}
/**
@@ -465,7 +478,7 @@
* is another running task that is not excluded from recents, returns that underlying task.
*/
public @Nullable CachedTaskInfo getVisibleNonExcludedTask() {
- if (com.android.wm.shell.Flags.enableShellTopTaskTracking()) {
+ if (enableShellTopTaskTracking()) {
// Callers should not need this when the full set of visible tasks are provided
return null;
}
@@ -485,49 +498,16 @@
}
/**
- * Returns true if this represents the HOME activity type task
- */
- public boolean isHomeTask() {
- if (com.android.wm.shell.Flags.enableShellTopTaskTracking()) {
- // TODO(346588978): Update this to not make an assumption on a specific task info
- return mTopGroupedTask != null
- && mTopGroupedTask.getTaskInfo1().getActivityType() == ACTIVITY_TYPE_HOME;
- } else {
- return mTopTask != null && mTopTask.configuration.windowConfiguration
- .getActivityType() == ACTIVITY_TYPE_HOME;
- }
- }
-
- /**
- * Returns true if this represents the RECENTS activity type task
- */
- public boolean isRecentsTask() {
- if (com.android.wm.shell.Flags.enableShellTopTaskTracking()) {
- // TODO(346588978): Update this to not make an assumption on a specific task info
- return mTopGroupedTask != null
- && TopTaskTracker.isRecentsTask(mTopGroupedTask.getTaskInfo1());
- } else {
- return TopTaskTracker.isRecentsTask(mTopTask);
- }
- }
-
- /**
* Returns {@link Task} array which can be used as a placeholder until the true object
* is loaded by the model
*/
public Task[] getPlaceholderTasks() {
- if (com.android.wm.shell.Flags.enableShellTopTaskTracking()) {
- // TODO(346588978): Update this to return more than a single task once the callers
- // are refactored
- if (mVisibleTasks.isEmpty()) {
- return new Task[0];
- }
- final TaskInfo info = mVisibleTasks.getFirst().getTaskInfo1();
- return new Task[]{Task.from(new TaskKey(info), info, false)};
- } else {
- return mTopTask == null ? new Task[0]
- : new Task[]{Task.from(new TaskKey(mTopTask), mTopTask, false)};
- }
+ final TaskInfo baseTask = getLegacyBaseTask();
+ // TODO(346588978): Update this to return more than a single task once the callers
+ // are refactored
+ return baseTask == null
+ ? new Task[0]
+ : new Task[]{Task.from(new TaskKey(baseTask), baseTask, false)};
}
/**
@@ -535,13 +515,12 @@
* placeholder until the true object is loaded by the model
*/
public Task[] getSplitPlaceholderTasks(int[] taskIds) {
- if (com.android.wm.shell.Flags.enableShellTopTaskTracking()) {
- if (mVisibleTasks.isEmpty()
- || mVisibleTasks.getFirst().getType() != TYPE_SPLIT) {
+ if (enableShellTopTaskTracking()) {
+ if (mVisibleTasks == null || !mVisibleTasks.isBaseType(TYPE_SPLIT)) {
return new Task[0];
}
- GroupedTaskInfo splitTask = mVisibleTasks.getFirst();
+ GroupedTaskInfo splitTask = mVisibleTasks.getBaseGroupedTask();
Task[] result = new Task[taskIds.length];
for (int i = 0; i < taskIds.length; i++) {
TaskInfo info = splitTask.getTaskById(taskIds[i]);
@@ -572,22 +551,11 @@
@Nullable
public String getPackageName() {
- if (com.android.wm.shell.Flags.enableShellTopTaskTracking()) {
- // TODO(346588978): Update this to not make an assumption on a specific task info
- if (mTopGroupedTask == null) {
- return null;
- }
- final TaskInfo info = mTopGroupedTask.getTaskInfo1();
- if (info.baseActivity == null) {
- return null;
- }
- return info.baseActivity.getPackageName();
- } else {
- if (mTopTask == null || mTopTask.baseActivity == null) {
- return null;
- }
- return mTopTask.baseActivity.getPackageName();
+ final TaskInfo baseTask = getLegacyBaseTask();
+ if (baseTask == null || baseTask.baseActivity == null) {
+ return null;
}
+ return baseTask.baseActivity.getPackageName();
}
}
}
diff --git a/quickstep/src/com/android/quickstep/TouchInteractionService.java b/quickstep/src/com/android/quickstep/TouchInteractionService.java
index f7fb18b..15f320d 100644
--- a/quickstep/src/com/android/quickstep/TouchInteractionService.java
+++ b/quickstep/src/com/android/quickstep/TouchInteractionService.java
@@ -301,6 +301,22 @@
@BinderThread
@Override
+ public void onDisplayReady(int displayId) {
+ MAIN_EXECUTOR.execute(() -> executeForTouchInteractionService(
+ tis -> executeForTaskbarManager(
+ taskbarManager -> taskbarManager.onDisplayReady(displayId))));
+ }
+
+ @BinderThread
+ @Override
+ public void onDisplayRemoved(int displayId) {
+ MAIN_EXECUTOR.execute(() -> executeForTouchInteractionService(
+ tis -> executeForTaskbarManager(
+ taskbarManager -> taskbarManager.onDisplayRemoved(displayId))));
+ }
+
+ @BinderThread
+ @Override
public void updateWallpaperVisibility(int displayId, boolean visible) {
MAIN_EXECUTOR.execute(() -> executeForTouchInteractionService(
tis -> executeForTaskbarManager(
diff --git a/quickstep/src/com/android/quickstep/fallback/window/RecentsDisplayModel.kt b/quickstep/src/com/android/quickstep/fallback/window/RecentsDisplayModel.kt
index e7e9f51..31a1be8 100644
--- a/quickstep/src/com/android/quickstep/fallback/window/RecentsDisplayModel.kt
+++ b/quickstep/src/com/android/quickstep/fallback/window/RecentsDisplayModel.kt
@@ -25,6 +25,7 @@
import com.android.launcher3.util.DaggerSingletonObject
import com.android.launcher3.util.DaggerSingletonTracker
import com.android.launcher3.util.Executors
+import com.android.launcher3.util.WallpaperColorHints
import com.android.quickstep.DisplayModel
import com.android.quickstep.FallbackWindowInterface
import com.android.quickstep.dagger.QuickstepBaseAppComponent
@@ -34,8 +35,11 @@
@LauncherAppSingleton
class RecentsDisplayModel
@Inject
-constructor(@ApplicationContext context: Context, tracker: DaggerSingletonTracker) :
- DisplayModel<RecentsDisplayResource>(context) {
+constructor(
+ @ApplicationContext context: Context,
+ private val wallpaperColorHints: WallpaperColorHints,
+ tracker: DaggerSingletonTracker,
+) : DisplayModel<RecentsDisplayResource>(context) {
companion object {
private const val TAG = "RecentsDisplayModel"
@@ -81,7 +85,11 @@
private fun storeRecentsDisplayResource(displayId: Int, display: Display) {
displayResourceArray[displayId] =
- RecentsDisplayResource(displayId, context.createDisplayContext(display))
+ RecentsDisplayResource(
+ displayId,
+ context.createDisplayContext(display),
+ wallpaperColorHints.hints,
+ )
}
fun getRecentsWindowManager(displayId: Int): RecentsWindowManager? {
@@ -92,9 +100,12 @@
return getDisplayResource(displayId)?.fallbackWindowInterface
}
- data class RecentsDisplayResource(var displayId: Int, var displayContext: Context) :
- DisplayResource() {
- val recentsWindowManager = RecentsWindowManager(displayContext)
+ data class RecentsDisplayResource(
+ var displayId: Int,
+ var displayContext: Context,
+ val wallpaperColorHints: Int,
+ ) : DisplayResource() {
+ val recentsWindowManager = RecentsWindowManager(displayContext, wallpaperColorHints)
val fallbackWindowInterface: FallbackWindowInterface =
FallbackWindowInterface(recentsWindowManager)
diff --git a/quickstep/src/com/android/quickstep/fallback/window/RecentsWindowContext.kt b/quickstep/src/com/android/quickstep/fallback/window/RecentsWindowContext.kt
index 52a7682..047658c 100644
--- a/quickstep/src/com/android/quickstep/fallback/window/RecentsWindowContext.kt
+++ b/quickstep/src/com/android/quickstep/fallback/window/RecentsWindowContext.kt
@@ -32,11 +32,16 @@
/**
* Window context for the Overview overlays.
+ *
* <p>
* Overlays have their own window and need a window context.
*/
-open class RecentsWindowContext(windowContext: Context) :
- ContextThemeWrapper(windowContext, Themes.getActivityThemeRes(windowContext)), ActivityContext {
+open class RecentsWindowContext(windowContext: Context, wallpaperColorHints: Int) :
+ ContextThemeWrapper(
+ windowContext,
+ Themes.getActivityThemeRes(windowContext, wallpaperColorHints),
+ ),
+ ActivityContext {
private var deviceProfile: DeviceProfile? = null
private var dragLayer: RecentsDragLayer<RecentsWindowManager> = RecentsDragLayer(this, null)
@@ -48,7 +53,9 @@
protected var windowLayoutParams: WindowManager.LayoutParams? =
createDefaultWindowLayoutParams(
- WindowManager.LayoutParams.TYPE_APPLICATION_OVERLAY, windowTitle)
+ WindowManager.LayoutParams.TYPE_APPLICATION_OVERLAY,
+ windowTitle,
+ )
override fun getDragLayer(): BaseDragLayer<RecentsWindowManager> {
return dragLayer
@@ -56,8 +63,7 @@
override fun getDeviceProfile(): DeviceProfile {
if (deviceProfile == null) {
- deviceProfile = InvariantDeviceProfile.INSTANCE[this].getDeviceProfile(this)
- .copy(this)
+ deviceProfile = InvariantDeviceProfile.INSTANCE[this].getDeviceProfile(this).copy(this)
}
return deviceProfile!!
}
diff --git a/quickstep/src/com/android/quickstep/fallback/window/RecentsWindowManager.kt b/quickstep/src/com/android/quickstep/fallback/window/RecentsWindowManager.kt
index 5d99aec..cda6c1b 100644
--- a/quickstep/src/com/android/quickstep/fallback/window/RecentsWindowManager.kt
+++ b/quickstep/src/com/android/quickstep/fallback/window/RecentsWindowManager.kt
@@ -88,8 +88,10 @@
* To add new protologs, see [RecentsWindowProtoLogProxy]. To enable logging to logcat, see
* [QuickstepProtoLogGroup.Constants.DEBUG_RECENTS_WINDOW]
*/
-class RecentsWindowManager(context: Context) :
- RecentsWindowContext(context), RecentsViewContainer, StatefulContainer<RecentsState> {
+class RecentsWindowManager(context: Context, wallpaperColorHints: Int) :
+ RecentsWindowContext(context, wallpaperColorHints),
+ RecentsViewContainer,
+ StatefulContainer<RecentsState> {
companion object {
private const val HOME_APPEAR_DURATION: Long = 250
diff --git a/quickstep/src/com/android/quickstep/recents/data/TasksRepository.kt b/quickstep/src/com/android/quickstep/recents/data/TasksRepository.kt
index 703d631..2f95413 100644
--- a/quickstep/src/com/android/quickstep/recents/data/TasksRepository.kt
+++ b/quickstep/src/com/android/quickstep/recents/data/TasksRepository.kt
@@ -79,6 +79,10 @@
}
}
tasks.value = MapForStateFlow(recentTasks)
+ Log.d(
+ TAG,
+ "getAllTaskData: oldTasks ${oldTaskMap.keys}, newTasks: ${recentTasks.keys}",
+ )
}
}
return tasks.map { it.values.toList() }
diff --git a/quickstep/src/com/android/quickstep/recents/di/RecentsDependencies.kt b/quickstep/src/com/android/quickstep/recents/di/RecentsDependencies.kt
index 2b364f9..358537c 100644
--- a/quickstep/src/com/android/quickstep/recents/di/RecentsDependencies.kt
+++ b/quickstep/src/com/android/quickstep/recents/di/RecentsDependencies.kt
@@ -252,6 +252,7 @@
fun initialize(view: View): RecentsDependencies = initialize(view.context)
fun initialize(context: Context): RecentsDependencies {
+ Log.d(TAG, "initializing")
synchronized(this) {
activeRecentsCount++
instance = RecentsDependencies(context.applicationContext)
@@ -286,10 +287,12 @@
activeRecentsCount--
if (activeRecentsCount == 0) {
instance.scopes.clear()
+ Log.d(TAG, "destroyed", Exception("Printing stack trace"))
} else {
- instance.log(
+ Log.d(
+ TAG,
"RecentsDependencies was not destroyed. " +
- "There is still an active RecentsView instance."
+ "There is still an active RecentsView instance.",
)
}
}
diff --git a/quickstep/src/com/android/quickstep/recents/domain/model/TaskModel.kt b/quickstep/src/com/android/quickstep/recents/domain/model/TaskModel.kt
new file mode 100644
index 0000000..3823100
--- /dev/null
+++ b/quickstep/src/com/android/quickstep/recents/domain/model/TaskModel.kt
@@ -0,0 +1,49 @@
+/*
+ * 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.quickstep.recents.domain.model
+
+import android.graphics.drawable.Drawable
+import com.android.systemui.shared.recents.model.ThumbnailData
+
+/**
+ * Data class representing a task in the application.
+ *
+ * This class holds the essential information about a task, including its unique identifier, display
+ * title, associated icon, optional thumbnail data, and background color.
+ *
+ * @property id The unique identifier for this task. Must be an integer.
+ * @property title The display title of the task.
+ * @property titleDescription A content description of the task.
+ * @property icon An optional drawable resource representing an icon for the task. Can be null if no
+ * icon is required.
+ * @property thumbnail An optional [ThumbnailData] object containing thumbnail information. Can be
+ * null if no thumbnail is needed.
+ * @property backgroundColor The background color of the task, represented as an integer color
+ * value.
+ * @property isLocked Indicates whether the [Task] is locked.
+ */
+data class TaskModel(
+ val id: TaskId,
+ val title: String,
+ val titleDescription: String?,
+ val icon: Drawable?,
+ val thumbnail: ThumbnailData?,
+ val backgroundColor: Int,
+ val isLocked: Boolean,
+)
+
+typealias TaskId = Int
diff --git a/quickstep/src/com/android/quickstep/recents/domain/usecase/GetTaskUseCase.kt b/quickstep/src/com/android/quickstep/recents/domain/usecase/GetTaskUseCase.kt
new file mode 100644
index 0000000..a60144b
--- /dev/null
+++ b/quickstep/src/com/android/quickstep/recents/domain/usecase/GetTaskUseCase.kt
@@ -0,0 +1,41 @@
+/*
+ * 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.quickstep.recents.domain.usecase
+
+import com.android.quickstep.recents.data.RecentTasksRepository
+import com.android.quickstep.recents.domain.model.TaskModel
+import kotlinx.coroutines.flow.Flow
+import kotlinx.coroutines.flow.map
+
+class GetTaskUseCase(private val repository: RecentTasksRepository) {
+ operator fun invoke(taskId: Int): Flow<TaskModel?> =
+ repository.getTaskDataById(taskId).map { task ->
+ if (task != null) {
+ TaskModel(
+ id = task.key.id,
+ title = task.title,
+ titleDescription = task.titleDescription,
+ icon = task.icon,
+ thumbnail = task.thumbnail,
+ backgroundColor = task.colorBackground,
+ isLocked = task.isLocked,
+ )
+ } else {
+ null
+ }
+ }
+}
diff --git a/quickstep/src/com/android/quickstep/recents/ui/viewmodel/TaskTileUiState.kt b/quickstep/src/com/android/quickstep/recents/ui/viewmodel/TaskTileUiState.kt
new file mode 100644
index 0000000..5f98479
--- /dev/null
+++ b/quickstep/src/com/android/quickstep/recents/ui/viewmodel/TaskTileUiState.kt
@@ -0,0 +1,57 @@
+/*
+ * 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.quickstep.recents.ui.viewmodel
+
+import android.graphics.drawable.Drawable
+import com.android.systemui.shared.recents.model.ThumbnailData
+
+/**
+ * This class represents the UI state to be consumed by TaskView, GroupTaskView and DesktopTaskView.
+ * Data class representing the state of a list of tasks.
+ *
+ * This class encapsulates a list of [TaskTileUiState] objects, along with a flag indicating whether
+ * the data is being used for a live tile display.
+ *
+ * @property tasks The list of [TaskTileUiState] objects representing the individual tasks.
+ * @property isLiveTile Indicates whether this data is intended for a live tile. If `true`, the
+ * running app will be displayed instead of the thumbnail.
+ */
+data class TaskTileUiState(val tasks: List<TaskData>, val isLiveTile: Boolean)
+
+sealed interface TaskData {
+ /** When no data was found for the TaskId provided */
+ data class NoData(val taskId: Int) : TaskData
+
+ /**
+ * This class provides UI information related to a Task (App) to be displayed within a TaskView.
+ *
+ * @property taskId Identifier of the task
+ * @property title App title
+ * @property icon App icon
+ * @property thumbnailData Information related to the last snapshot retrieved from the app
+ * @property backgroundColor The background color of the task.
+ * @property isLocked Indicates whether the task is locked or not.
+ */
+ data class Data(
+ val taskId: Int,
+ val title: String,
+ val icon: Drawable?,
+ val thumbnailData: ThumbnailData?,
+ val backgroundColor: Int,
+ val isLocked: Boolean,
+ ) : TaskData
+}
diff --git a/quickstep/src/com/android/quickstep/recents/ui/viewmodel/TaskViewModel.kt b/quickstep/src/com/android/quickstep/recents/ui/viewmodel/TaskViewModel.kt
new file mode 100644
index 0000000..2e51a8a
--- /dev/null
+++ b/quickstep/src/com/android/quickstep/recents/ui/viewmodel/TaskViewModel.kt
@@ -0,0 +1,91 @@
+/*
+ * 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.quickstep.recents.ui.viewmodel
+
+import android.util.Log
+import com.android.launcher3.util.coroutines.DispatcherProvider
+import com.android.quickstep.recents.domain.model.TaskId
+import com.android.quickstep.recents.domain.model.TaskModel
+import com.android.quickstep.recents.domain.usecase.GetTaskUseCase
+import com.android.quickstep.recents.viewmodel.RecentsViewData
+import kotlinx.coroutines.ExperimentalCoroutinesApi
+import kotlinx.coroutines.flow.Flow
+import kotlinx.coroutines.flow.MutableStateFlow
+import kotlinx.coroutines.flow.combine
+import kotlinx.coroutines.flow.distinctUntilChanged
+import kotlinx.coroutines.flow.flatMapLatest
+import kotlinx.coroutines.flow.flowOn
+import kotlinx.coroutines.flow.map
+
+/**
+ * ViewModel used for [com.android.quickstep.views.TaskView],
+ * [com.android.quickstep.views.DesktopTaskView] and [com.android.quickstep.views.GroupedTaskView].
+ */
+@OptIn(ExperimentalCoroutinesApi::class)
+class TaskViewModel(
+ recentsViewData: RecentsViewData,
+ private val getTaskUseCase: GetTaskUseCase,
+ dispatcherProvider: DispatcherProvider,
+) {
+ private var taskIds = MutableStateFlow(emptySet<Int>())
+
+ private val isLiveTile =
+ combine(
+ taskIds,
+ recentsViewData.runningTaskIds,
+ recentsViewData.runningTaskShowScreenshot,
+ ) { taskIds, runningTaskIds, runningTaskShowScreenshot ->
+ runningTaskIds == taskIds && !runningTaskShowScreenshot
+ }
+ .distinctUntilChanged()
+
+ val state: Flow<TaskTileUiState> =
+ taskIds
+ .flatMapLatest { ids ->
+ // Combine Tasks requests
+ combine(
+ ids.map { id -> getTaskUseCase(id).map { taskModel -> id to taskModel } },
+ ::mapToUiState,
+ )
+ }
+ .combine(isLiveTile) { tasks, isLiveTile -> TaskTileUiState(tasks, isLiveTile) }
+ .flowOn(dispatcherProvider.background)
+
+ fun bind(vararg taskId: TaskId) {
+ Log.d(TAG, "bind: $taskId")
+ taskIds.value = taskId.toSet()
+ }
+
+ private fun mapToUiState(result: Array<Pair<TaskId, TaskModel?>>): List<TaskData> =
+ result.map { mapToUiState(it.first, it.second) }
+
+ private fun mapToUiState(taskId: TaskId, result: TaskModel?): TaskData =
+ result?.let {
+ TaskData.Data(
+ taskId = taskId,
+ title = result.title,
+ icon = result.icon,
+ thumbnailData = result.thumbnail,
+ backgroundColor = result.backgroundColor,
+ isLocked = result.isLocked,
+ )
+ } ?: TaskData.NoData(taskId)
+
+ private companion object {
+ const val TAG = "TaskViewModel"
+ }
+}
diff --git a/quickstep/src/com/android/quickstep/util/AppPairsController.java b/quickstep/src/com/android/quickstep/util/AppPairsController.java
index 8399792..6b8650f 100644
--- a/quickstep/src/com/android/quickstep/util/AppPairsController.java
+++ b/quickstep/src/com/android/quickstep/util/AppPairsController.java
@@ -46,7 +46,6 @@
import com.android.launcher3.accessibility.LauncherAccessibilityDelegate;
import com.android.launcher3.allapps.AllAppsStore;
import com.android.launcher3.apppairs.AppPairIcon;
-import com.android.launcher3.config.FeatureFlags;
import com.android.launcher3.icons.IconCache;
import com.android.launcher3.logging.InstanceId;
import com.android.launcher3.logging.StatsLogManager;
@@ -127,8 +126,7 @@
.anyMatch(att -> att != null && att.getItemInfo() != null
&& ((att.getItemInfo().runtimeStatusFlags
& ItemInfoWithIcon.FLAG_NOT_PINNABLE) != 0));
- if (!FeatureFlags.enableAppPairs()
- || !taskView.containsMultipleTasks()
+ if (!taskView.containsMultipleTasks()
|| hasUnpinnableApp
|| !(taskView instanceof GroupedTaskView)) {
return false;
diff --git a/quickstep/src/com/android/quickstep/views/AddDesktopButton.kt b/quickstep/src/com/android/quickstep/views/AddDesktopButton.kt
index f973dd0..1dab18a 100644
--- a/quickstep/src/com/android/quickstep/views/AddDesktopButton.kt
+++ b/quickstep/src/com/android/quickstep/views/AddDesktopButton.kt
@@ -17,8 +17,11 @@
package com.android.quickstep.views
import android.content.Context
+import android.graphics.drawable.ShapeDrawable
+import android.graphics.drawable.shapes.RoundRectShape
import android.util.AttributeSet
import android.widget.ImageButton
+import com.android.launcher3.R
/**
* Button for supporting multiple desktop sessions. The button will be next to the first TaskView
@@ -26,5 +29,21 @@
*/
class AddDesktopButton @JvmOverloads constructor(context: Context, attrs: AttributeSet? = null) :
ImageButton(context, attrs) {
- // TODO(b/382057498): add this button the overview.
+
+ override fun onFinishInflate() {
+ super.onFinishInflate()
+
+ background =
+ ShapeDrawable().apply {
+ shape =
+ RoundRectShape(
+ FloatArray(8) { R.dimen.add_desktop_button_size.toFloat() },
+ null,
+ null,
+ )
+ setTint(
+ resources.getColor(android.R.color.system_surface_bright_light, context.theme)
+ )
+ }
+ }
}
diff --git a/quickstep/src/com/android/quickstep/views/GroupedTaskView.kt b/quickstep/src/com/android/quickstep/views/GroupedTaskView.kt
index 3f0b520..38ffe50 100644
--- a/quickstep/src/com/android/quickstep/views/GroupedTaskView.kt
+++ b/quickstep/src/com/android/quickstep/views/GroupedTaskView.kt
@@ -27,7 +27,6 @@
import com.android.launcher3.Flags.enableRefactorTaskThumbnail
import com.android.launcher3.R
import com.android.launcher3.Utilities
-import com.android.launcher3.config.FeatureFlags
import com.android.launcher3.util.RunnableList
import com.android.launcher3.util.SplitConfigurationOptions
import com.android.launcher3.util.SplitConfigurationOptions.STAGE_POSITION_BOTTOM_OR_RIGHT
@@ -340,14 +339,6 @@
return Utilities.pointInView(this, localPos[0], localPos[1], 0f /* slop */)
}
- override fun setOverlayEnabled(overlayEnabled: Boolean) {
- if (FeatureFlags.enableAppPairs()) {
- super.setOverlayEnabled(overlayEnabled)
- } else {
- // Intentional no-op to prevent setting smart actions overlay on thumbnails
- }
- }
-
companion object {
private const val TAG = "GroupedTaskView"
}
diff --git a/quickstep/src/com/android/quickstep/views/RecentsView.java b/quickstep/src/com/android/quickstep/views/RecentsView.java
index cfad303..684e84a 100644
--- a/quickstep/src/com/android/quickstep/views/RecentsView.java
+++ b/quickstep/src/com/android/quickstep/views/RecentsView.java
@@ -74,7 +74,6 @@
import static com.android.quickstep.views.OverviewActionsView.HIDDEN_NON_ZERO_ROTATION;
import static com.android.quickstep.views.OverviewActionsView.HIDDEN_NO_RECENTS;
import static com.android.quickstep.views.OverviewActionsView.HIDDEN_NO_TASKS;
-import static com.android.quickstep.views.OverviewActionsView.HIDDEN_SPLIT_SCREEN;
import static com.android.quickstep.views.OverviewActionsView.HIDDEN_SPLIT_SELECT_ACTIVE;
import android.animation.Animator;
@@ -547,6 +546,8 @@
private final int mSplitPlaceholderSize;
private final int mSplitPlaceholderInset;
private final ClearAllButton mClearAllButton;
+ @Nullable
+ private AddDesktopButton mAddDesktopButton = null;
private final Rect mClearAllButtonDeadZoneRect = new Rect();
private final Rect mTaskViewDeadZoneRect = new Rect();
private final Rect mTopRowDeadZoneRect = new Rect();
@@ -902,6 +903,12 @@
mClearAllButton = (ClearAllButton) LayoutInflater.from(context)
.inflate(R.layout.overview_clear_all_button, this, false);
mClearAllButton.setOnClickListener(this::dismissAllTasks);
+
+ if (DesktopModeStatus.enableMultipleDesktops(mContext)) {
+ mAddDesktopButton = (AddDesktopButton) LayoutInflater.from(context).inflate(
+ R.layout.overview_add_desktop_button, this, false);
+ }
+
mTaskViewPool = new ViewPool<>(context, this, R.layout.task, 20 /* max size */,
10 /* initial size */);
mGroupedTaskViewPool = new ViewPool<>(context, this,
@@ -1247,6 +1254,13 @@
public void destroy() {
Log.d(TAG, "destroy");
if (enableRefactorTaskThumbnail()) {
+ try {
+ mTaskViewPool.killOngoingInitializations();
+ mGroupedTaskViewPool.killOngoingInitializations();
+ mDesktopTaskViewPool.killOngoingInitializations();
+ } catch (InterruptedException e) {
+ Log.e(TAG, "Ongoing initializations could not be killed", e);
+ }
mHelper.onDestroy();
RecentsDependencies.destroy();
}
@@ -1880,7 +1894,7 @@
}
mLoadPlanEverApplied = true;
if (taskGroups == null || taskGroups.isEmpty()) {
- removeTasksViewsAndClearAllButton();
+ removeAllTaskViews();
onTaskStackUpdated();
// With all tasks removed, touch handling in PagedView is disabled and we need to reset
// touch state or otherwise values will be obsolete.
@@ -1943,6 +1957,11 @@
taskGroups = mUtils.sortDesktopTasksToFront(taskGroups);
}
+ if (mAddDesktopButton != null) {
+ // Add `mAddDesktopButton` as the first child.
+ addView(mAddDesktopButton);
+ }
+
// Add views as children based on whether it's grouped or single task. Looping through
// taskGroups backwards populates the thumbnail grid from least recent to most recent.
for (int i = taskGroups.size() - 1; i >= 0; i--) {
@@ -2088,13 +2107,14 @@
return mModel.isLoadingTasksInBackground();
}
- private void removeTasksViewsAndClearAllButton() {
+ private void removeAllTaskViews() {
// This handles an edge case where applyLoadPlan happens during a gesture when the only
// Task is one with excludeFromRecents, in which case we should not remove it.
CollectionsKt
.filter(getTaskViews(), taskView -> !isGestureActive() || !taskView.isRunningTask())
.forEach(this::removeView);
if (!hasTaskViews()) {
+ removeView(mAddDesktopButton);
removeView(mClearAllButton);
}
}
@@ -2324,6 +2344,9 @@
float taskAlignmentTranslationY = getTaskAlignmentTranslationY();
mClearAllButton.setTaskAlignmentTranslationY(taskAlignmentTranslationY);
+ if (mAddDesktopButton != null) {
+ mAddDesktopButton.setTranslationY(taskAlignmentTranslationY);
+ }
updateGridProperties();
}
@@ -3006,6 +3029,9 @@
taskView = getTaskViewFromPool(TaskViewType.SINGLE);
taskView.bind(runningTasks[0], mOrientationState, mTaskOverlayFactory);
}
+ if (mAddDesktopButton != null && wasEmpty) {
+ addView(mAddDesktopButton);
+ }
addView(taskView, getRunningTaskExpectedIndex(taskView));
runningTaskViewId = taskView.getTaskViewId();
if (wasEmpty) {
@@ -3204,7 +3230,7 @@
Map<TaskView, Float> gridTranslations = new HashMap<>();
TaskView lastLargeTaskView = mUtils.getLastLargeTaskView();
- int focusedTaskShift = 0;
+ int focusedTaskViewShift = 0;
int largeTaskWidthAndSpacing = 0;
int snappedTaskRowWidth = 0;
int snappedPage = isKeyboardTaskFocusPending() ? mKeyboardTaskFocusIndex : getNextPage();
@@ -3249,7 +3275,7 @@
topRowWidth += taskWidthAndSpacing;
bottomRowWidth += taskWidthAndSpacing;
}
- gridTranslation += focusedTaskShift;
+ gridTranslation += focusedTaskViewShift;
gridTranslation += mIsRtl ? taskWidthAndSpacing : -taskWidthAndSpacing;
// Center view vertically in case it's from different orientation.
@@ -3268,9 +3294,12 @@
gridTranslation +=
mIsRtl ? largeTaskWidthAndSpacing : -largeTaskWidthAndSpacing;
} else {
- // For task before the focused task, accumulate the width and spacing to
- // calculate the distance focused task need to shift.
- focusedTaskShift += mIsRtl ? taskWidthAndSpacing : -taskWidthAndSpacing;
+ // For TaskViews before the new focused TaskView, accumulate the width and
+ // spacing to calculate the distance the new focused TaskView needs to shift.
+ // This could happen for example after multiple times of dismissing the
+ // focused TaskView, the triggered rebalance might set a non-first TaskView
+ // inside `mChildren` as the new focused TaskView.
+ focusedTaskViewShift += mIsRtl ? taskWidthAndSpacing : -taskWidthAndSpacing;
}
int taskViewId = taskView.getTaskViewId();
@@ -3341,7 +3370,7 @@
if (snappedTaskView != null) {
snappedTaskNonGridScrollAdjustment = snappedTaskView.getScrollAdjustment(
/*gridEnabled=*/false);
- snappedTaskGridTranslationX = gridTranslations.get(snappedTaskView);
+ snappedTaskGridTranslationX = gridTranslations.getOrDefault(snappedTaskView, 0f);
}
// Use the accumulated translation of the row containing the last task.
@@ -3422,10 +3451,24 @@
for (TaskView taskView : getTaskViews()) {
taskView.setGridTranslationX(
- gridTranslations.get(taskView) - snappedTaskGridTranslationX
+ gridTranslations.getOrDefault(taskView, 0f) - snappedTaskGridTranslationX
+ snappedTaskNonGridScrollAdjustment);
}
+ if (mAddDesktopButton != null) {
+ TaskView firstTaskView = getFirstTaskView();
+ float translationX = 0f;
+ if (firstTaskView != null) {
+ translationX += firstTaskView.getGridTranslationX();
+ }
+ if (focusedTaskViewShift != 0) {
+ // If the focused task is inserted between `firstTaskView` and
+ // `mAddDesktopButton`, shift `mAddDesktopButton` to accommodate.
+ translationX += largeTaskWidthAndSpacing;
+ }
+ mAddDesktopButton.setTranslationX(translationX);
+ }
+
final TaskView runningTask = getRunningTaskView();
if (showAsGrid() && enableGridOnlyOverview() && runningTask != null) {
runActionOnRemoteHandles(
@@ -4137,6 +4180,7 @@
if (taskCount == 1) {
removeViewInLayout(mClearAllButton);
+ removeViewInLayout(mAddDesktopButton);
if (isHomeTaskDismissed) {
updateEmptyMessage();
} else if (!mSplitSelectStateController.isSplitSelectActive()) {
@@ -4344,9 +4388,6 @@
boolean isCurrentSplit = taskView instanceof GroupedTaskView;
GroupedTaskView groupedTaskView = isCurrentSplit ? (GroupedTaskView) taskView : null;
// Update flags to see if entire actions bar should be hidden.
- if (!FeatureFlags.enableAppPairs()) {
- mActionsView.updateHiddenFlags(HIDDEN_SPLIT_SCREEN, isCurrentSplit);
- }
mActionsView.updateHiddenFlags(HIDDEN_SPLIT_SELECT_ACTIVE, isSplitSelectionActive());
// Update flags to see if actions bar should show buttons for a single task or a pair of
// tasks.
@@ -4468,7 +4509,7 @@
finishRecentsAnimation(true /* toRecents */, false /* shouldPip */, () -> {
UI_HELPER_EXECUTOR.getHandler().post(
ActivityManagerWrapper.getInstance()::removeAllRecentTasks);
- removeTasksViewsAndClearAllButton();
+ removeAllTaskViews();
startHome();
});
}
@@ -4627,6 +4668,11 @@
taskView.setStableAlpha(alpha);
}
mClearAllButton.setContentAlpha(mContentAlpha);
+
+ // TODO(b/389209338): Handle the visibility of the `mAddDesktopButton`.
+ if (mAddDesktopButton != null) {
+ mAddDesktopButton.setAlpha(mContentAlpha);
+ }
int alphaInt = Math.round(alpha * 255);
mEmptyMessagePaint.setAlpha(alphaInt);
mEmptyIcon.setAlpha(alphaInt);
@@ -4923,9 +4969,11 @@
+ carouselHiddenOffsetSize;
if (child instanceof TaskView taskView) {
taskView.getPrimaryTaskOffsetTranslationProperty().set(taskView, totalTranslationX);
- } else {
+ } else if (child instanceof ClearAllButton) {
getPagedOrientationHandler().getPrimaryViewTranslate().set(child,
totalTranslationX);
+ } else {
+ // TODO(b/389209581): Handle the page offsets update of the 'mAddDesktopButton'.
}
if (mEnableDrawingLiveTile && i == getRunningTaskIndex()) {
runActionOnRemoteHandles(
@@ -6104,6 +6152,13 @@
outPageScrolls[clearAllIndex] = clearAllScroll;
}
+ int addDesktopButtonIndex = indexOfChild(mAddDesktopButton);
+ if (addDesktopButtonIndex != -1 && addDesktopButtonIndex < outPageScrolls.length) {
+ outPageScrolls[addDesktopButtonIndex] =
+ newPageScrolls[addDesktopButtonIndex] + Math.round(
+ mAddDesktopButton.getTranslationX());
+ }
+
int lastTaskScroll = getLastTaskScroll(clearAllScroll, clearAllWidth);
getTaskViews().forEachWithIndexInParent((index, taskView) -> {
float scrollDiff = taskView.getScrollAdjustment(showAsGrid);
@@ -6784,10 +6839,8 @@
return;
}
- mDesktopRecentsTransitionController.moveToDesktop(taskContainer, transitionSource);
- // TODO(b/387471509): Invoke successCallback after actual transition completion of
- // overview menu to desktop
- successCallback.run();
+ mDesktopRecentsTransitionController.moveToDesktop(taskContainer, transitionSource,
+ successCallback);
}
/**
diff --git a/quickstep/src/com/android/quickstep/views/TaskThumbnailViewDeprecated.java b/quickstep/src/com/android/quickstep/views/TaskThumbnailViewDeprecated.java
index 9f2bb9a..5ee5e10 100644
--- a/quickstep/src/com/android/quickstep/views/TaskThumbnailViewDeprecated.java
+++ b/quickstep/src/com/android/quickstep/views/TaskThumbnailViewDeprecated.java
@@ -46,7 +46,6 @@
import com.android.launcher3.DeviceProfile;
import com.android.launcher3.Utilities;
-import com.android.launcher3.util.MainThreadInitializedObject;
import com.android.launcher3.util.SystemUiController;
import com.android.launcher3.util.SystemUiController.SystemUiControllerFlags;
import com.android.launcher3.util.ViewPool;
@@ -66,8 +65,6 @@
*/
@Deprecated
public class TaskThumbnailViewDeprecated extends View implements ViewPool.Reusable {
- private static final MainThreadInitializedObject<FullscreenDrawParams> TEMP_PARAMS =
- new MainThreadInitializedObject<>(FullscreenDrawParams::new);
public static final Property<TaskThumbnailViewDeprecated, Float> DIM_ALPHA =
new FloatProperty<TaskThumbnailViewDeprecated>("dimAlpha") {
@@ -145,8 +142,7 @@
mClearPaint.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.CLEAR));
mContainer = RecentsViewContainer.containerFromContext(context);
// Initialize with placeholder value. It is overridden later by TaskView
- mFullscreenParams = TEMP_PARAMS.get(context);
-
+ mFullscreenParams = new FullscreenDrawParams(context, __ -> 0f, __ -> 0f);
mDimColor = RecentsView.getForegroundScrimDimColor(context);
mDimmingPaintAfterClearing.setColor(mDimColor);
}
diff --git a/quickstep/src/com/android/quickstep/views/TaskView.kt b/quickstep/src/com/android/quickstep/views/TaskView.kt
index dc849f3..99df84c 100644
--- a/quickstep/src/com/android/quickstep/views/TaskView.kt
+++ b/quickstep/src/com/android/quickstep/views/TaskView.kt
@@ -613,6 +613,7 @@
borderEnabled = false
hoverBorderVisible = false
taskViewId = UNBOUND_TASK_VIEW_ID
+ // TODO(b/390583187): Clean the components UI State when TaskView is recycled.
taskContainers.forEach { it.destroy() }
}
diff --git a/quickstep/src_protolog/com/android/quickstep/util/ActiveGestureProtoLogProxy.java b/quickstep/src_protolog/com/android/quickstep/util/ActiveGestureProtoLogProxy.java
index be1a4e8..37c64cf 100644
--- a/quickstep/src_protolog/com/android/quickstep/util/ActiveGestureProtoLogProxy.java
+++ b/quickstep/src_protolog/com/android/quickstep/util/ActiveGestureProtoLogProxy.java
@@ -395,11 +395,11 @@
public static void logOnRecentsAnimationStart(int appCount) {
ActiveGestureLog.INSTANCE.addLog(new ActiveGestureLog.CompoundString(
- "RecentsAnimationCallbacks.onAnimationStart (canceled): %d", appCount),
+ "RecentsAnimationCallbacks.onAnimationStart: %d", appCount),
/* gestureEvent= */ ON_START_RECENTS_ANIMATION);
if (!enableActiveGestureProtoLog() || !isProtoLogInitialized()) return;
ProtoLog.d(ACTIVE_GESTURE_LOG,
- "RecentsAnimationCallbacks.onAnimationStart (canceled): %d", appCount);
+ "RecentsAnimationCallbacks.onAnimationStart: %d", appCount);
}
public static void logStartRecentsAnimationCallback(@NonNull String callback) {
diff --git a/quickstep/tests/src/com/android/launcher3/taskbar/FallbackTaskbarUIControllerTest.kt b/quickstep/tests/multivalentTests/src/com/android/launcher3/taskbar/FallbackTaskbarUIControllerTest.kt
similarity index 98%
rename from quickstep/tests/src/com/android/launcher3/taskbar/FallbackTaskbarUIControllerTest.kt
rename to quickstep/tests/multivalentTests/src/com/android/launcher3/taskbar/FallbackTaskbarUIControllerTest.kt
index df98606..b39c3f1 100644
--- a/quickstep/tests/src/com/android/launcher3/taskbar/FallbackTaskbarUIControllerTest.kt
+++ b/quickstep/tests/multivalentTests/src/com/android/launcher3/taskbar/FallbackTaskbarUIControllerTest.kt
@@ -17,7 +17,7 @@
package com.android.launcher3.taskbar
-import androidx.test.runner.AndroidJUnit4
+import androidx.test.ext.junit.runners.AndroidJUnit4
import com.android.launcher3.statemanager.StateManager
import com.android.quickstep.RecentsActivity
import com.android.quickstep.fallback.RecentsState
diff --git a/quickstep/tests/src/com/android/launcher3/taskbar/TaskbarBaseTestCase.kt b/quickstep/tests/multivalentTests/src/com/android/launcher3/taskbar/TaskbarBaseTestCase.kt
similarity index 98%
rename from quickstep/tests/src/com/android/launcher3/taskbar/TaskbarBaseTestCase.kt
rename to quickstep/tests/multivalentTests/src/com/android/launcher3/taskbar/TaskbarBaseTestCase.kt
index d064f4a..26f1197 100644
--- a/quickstep/tests/src/com/android/launcher3/taskbar/TaskbarBaseTestCase.kt
+++ b/quickstep/tests/multivalentTests/src/com/android/launcher3/taskbar/TaskbarBaseTestCase.kt
@@ -99,7 +99,7 @@
keyboardQuickSwitchController,
taskbarPinningController,
optionalBubbleControllers,
- taskbarDesktopModeController
+ taskbarDesktopModeController,
)
}
}
diff --git a/quickstep/tests/src/com/android/launcher3/taskbar/TaskbarKeyguardControllerTest.kt b/quickstep/tests/multivalentTests/src/com/android/launcher3/taskbar/TaskbarKeyguardControllerTest.kt
similarity index 97%
rename from quickstep/tests/src/com/android/launcher3/taskbar/TaskbarKeyguardControllerTest.kt
rename to quickstep/tests/multivalentTests/src/com/android/launcher3/taskbar/TaskbarKeyguardControllerTest.kt
index e619e7c..2431020 100644
--- a/quickstep/tests/src/com/android/launcher3/taskbar/TaskbarKeyguardControllerTest.kt
+++ b/quickstep/tests/multivalentTests/src/com/android/launcher3/taskbar/TaskbarKeyguardControllerTest.kt
@@ -16,6 +16,7 @@
package com.android.launcher3.taskbar
import android.app.KeyguardManager
+import androidx.test.ext.junit.runners.AndroidJUnit4
import com.android.systemui.shared.system.QuickStepContract.SYSUI_STATE_BACK_DISABLED
import com.android.systemui.shared.system.QuickStepContract.SYSUI_STATE_BOUNCER_SHOWING
import com.android.systemui.shared.system.QuickStepContract.SYSUI_STATE_DEVICE_DOZING
@@ -23,6 +24,7 @@
import com.android.systemui.shared.system.QuickStepContract.SYSUI_STATE_STATUS_BAR_KEYGUARD_SHOWING_OCCLUDED
import org.junit.Before
import org.junit.Test
+import org.junit.runner.RunWith
import org.mockito.kotlin.any
import org.mockito.kotlin.mock
import org.mockito.kotlin.never
@@ -30,6 +32,7 @@
import org.mockito.kotlin.verify
import org.mockito.kotlin.whenever
+@RunWith(AndroidJUnit4::class)
class TaskbarKeyguardControllerTest : TaskbarBaseTestCase() {
private val baseDragLayer: TaskbarDragLayer = mock()
diff --git a/quickstep/tests/multivalentTests/src/com/android/launcher3/taskbar/TaskbarOverflowTest.kt b/quickstep/tests/multivalentTests/src/com/android/launcher3/taskbar/TaskbarOverflowTest.kt
index 13880f1..9ca8a1b 100644
--- a/quickstep/tests/multivalentTests/src/com/android/launcher3/taskbar/TaskbarOverflowTest.kt
+++ b/quickstep/tests/multivalentTests/src/com/android/launcher3/taskbar/TaskbarOverflowTest.kt
@@ -19,9 +19,11 @@
import android.animation.AnimatorTestRule
import android.content.ComponentName
import android.content.Intent
+import android.platform.test.annotations.DisableFlags
import android.platform.test.annotations.EnableFlags
import android.platform.test.flag.junit.SetFlagsRule
import androidx.test.core.app.ApplicationProvider
+import com.android.launcher3.Flags.FLAG_ENABLE_MULTI_INSTANCE_MENU_TASKBAR
import com.android.launcher3.Flags.FLAG_TASKBAR_OVERFLOW
import com.android.launcher3.R
import com.android.launcher3.taskbar.TaskbarControllerTestUtil.runOnMainSync
@@ -64,6 +66,7 @@
FLAG_ENABLE_DESKTOP_WINDOWING_MODE,
FLAG_ENABLE_BUBBLE_BAR,
)
+@DisableFlags(FLAG_ENABLE_MULTI_INSTANCE_MENU_TASKBAR)
class TaskbarOverflowTest {
@get:Rule(order = 0) val setFlagsRule = SetFlagsRule()
diff --git a/quickstep/tests/src/com/android/launcher3/taskbar/TaskbarRecentAppsControllerTest.kt b/quickstep/tests/multivalentTests/src/com/android/launcher3/taskbar/TaskbarRecentAppsControllerTest.kt
similarity index 93%
rename from quickstep/tests/src/com/android/launcher3/taskbar/TaskbarRecentAppsControllerTest.kt
rename to quickstep/tests/multivalentTests/src/com/android/launcher3/taskbar/TaskbarRecentAppsControllerTest.kt
index ed0c928..8d8e62e 100644
--- a/quickstep/tests/src/com/android/launcher3/taskbar/TaskbarRecentAppsControllerTest.kt
+++ b/quickstep/tests/multivalentTests/src/com/android/launcher3/taskbar/TaskbarRecentAppsControllerTest.kt
@@ -23,16 +23,18 @@
import android.content.res.Resources
import android.os.Process
import android.os.UserHandle
-import android.platform.test.rule.TestWatcher
-import android.testing.AndroidTestingRunner
+import android.platform.test.annotations.EnableFlags
+import androidx.test.annotation.UiThreadTest
import com.android.internal.R
import com.android.launcher3.BubbleTextView.RunningAppState
+import com.android.launcher3.Flags
import com.android.launcher3.LauncherSettings.Favorites.CONTAINER_HOTSEAT
import com.android.launcher3.LauncherSettings.Favorites.CONTAINER_HOTSEAT_PREDICTION
import com.android.launcher3.model.data.AppInfo
import com.android.launcher3.model.data.ItemInfo
import com.android.launcher3.model.data.TaskItemInfo
import com.android.launcher3.model.data.WorkspaceItemInfo
+import com.android.launcher3.util.LauncherMultivalentJUnit
import com.android.quickstep.RecentsModel
import com.android.quickstep.RecentsModel.RecentTasksChangedListener
import com.android.quickstep.TaskIconCache
@@ -44,6 +46,7 @@
import org.junit.Before
import org.junit.Rule
import org.junit.Test
+import org.junit.rules.TestWatcher
import org.junit.runner.Description
import org.junit.runner.RunWith
import org.mockito.ArgumentCaptor
@@ -56,7 +59,9 @@
import org.mockito.kotlin.verify
import org.mockito.kotlin.whenever
-@RunWith(AndroidTestingRunner::class)
+@UiThreadTest
+@RunWith(LauncherMultivalentJUnit::class)
+@EnableFlags(Flags.FLAG_ENABLE_MULTI_INSTANCE_MENU_TASKBAR)
class TaskbarRecentAppsControllerTest : TaskbarBaseTestCase() {
@get:Rule val mockitoRule = MockitoJUnit.rule()
@@ -86,6 +91,9 @@
private var canShowRunningAndRecentAppsAtInit = true
private var recentTasksChangedListener: RecentTasksChangedListener? = null
+ val recentShownTasks: List<Task>
+ get() = recentAppsController.shownTasks.flatMap { it.tasks }
+
@Before
fun setUp() {
super.setup()
@@ -323,8 +331,12 @@
assertThat(hotseatItem1.taskId).isEqualTo(1)
}
+ /**
+ * Tests that in desktop mode, when two tasks have the same package name and one is in the
+ * hotseat, only the hotseat item represents the app, and no duplicate is shown in recent apps.
+ */
@Test
- fun updateHotseatItemInfos_inDesktopMode_twoRunningTasksSamePackage_hotseatCoversFirstTask() {
+ fun updateHotseatItemInfos_inDesktopMode_twoRunningTasksSamePackage_onlyHotseatCoversTask() {
setInDesktopMode(true)
val newHotseatItems =
@@ -338,16 +350,15 @@
recentTaskPackages = emptyList(),
)
- // First task is in Hotseat Items
+ // The task is in Hotseat Items
assertThat(newHotseatItems).hasLength(2)
assertThat(newHotseatItems[0]).isInstanceOf(TaskItemInfo::class.java)
assertThat(newHotseatItems[1]).isNotInstanceOf(TaskItemInfo::class.java)
val hotseatItem1 = newHotseatItems[0] as TaskItemInfo
- assertThat(hotseatItem1.taskId).isEqualTo(1)
- // Second task is in shownTasks
- val shownTasks = recentAppsController.shownTasks.map { it.task1 }
- assertThat(shownTasks)
- .containsExactlyElementsIn(listOf(createTask(id = 2, HOTSEAT_PACKAGE_1)))
+ assertThat(hotseatItem1.targetPackage).isEqualTo(HOTSEAT_PACKAGE_1)
+
+ // The other task of the same package is not in recentShownTasks
+ assertThat(recentShownTasks).isEmpty()
}
@Test
@@ -430,8 +441,7 @@
runningTasks = listOf(task1, task2),
recentTaskPackages = emptyList(),
)
- val shownTasks = recentAppsController.shownTasks.map { it.task1 }
- assertThat(shownTasks).containsExactlyElementsIn(listOf(task1, task2))
+ assertThat(recentShownTasks).containsExactlyElementsIn(listOf(task1, task2))
}
@Test
@@ -526,12 +536,15 @@
recentTaskPackages = emptyList(),
)
- val shownTasks = recentAppsController.shownTasks.map { it.task1 }
- assertThat(shownTasks).isEqualTo(listOf(task1, task2))
+ assertThat(recentShownTasks).isEqualTo(listOf(task1, task2))
}
+ /**
+ * Tests that when multiple instances of the same app are running in desktop mode and the app is
+ * not in the hotseat, only one instance is shown in the recent apps section.
+ */
@Test
- fun onRecentTasksChanged_inDesktopMode_multiInstance_shownTasks_maintainsOrder() {
+ fun onRecentTasksChanged_inDesktopMode_multiInstance_noHotseat_shownTasksHasOneInstance() {
setInDesktopMode(true)
val task1 = createTask(id = 1, RUNNING_APP_PACKAGE_1)
val task2 = createTask(id = 2, RUNNING_APP_PACKAGE_1)
@@ -541,43 +554,9 @@
recentTaskPackages = emptyList(),
)
- prepareHotseatAndRunningAndRecentApps(
- hotseatPackages = emptyList(),
- runningTasks = listOf(task2, task1),
- recentTaskPackages = emptyList(),
- )
-
- val shownTasks = recentAppsController.shownTasks.map { it.task1 }
- assertThat(shownTasks).isEqualTo(listOf(task1, task2))
- }
-
- @Test
- fun updateHotseatItems_inDesktopMode_multiInstanceHotseatPackage_shownItems_maintainsOrder() {
- setInDesktopMode(true)
- val task1 = createTask(id = 1, RUNNING_APP_PACKAGE_1)
- val task2 = createTask(id = 2, RUNNING_APP_PACKAGE_1)
- prepareHotseatAndRunningAndRecentApps(
- hotseatPackages = listOf(RUNNING_APP_PACKAGE_1),
- runningTasks = listOf(task1, task2),
- recentTaskPackages = emptyList(),
- )
- updateRecentTasks( // Trigger a recent-tasks change before calling updateHotseatItems()
- runningTasks = listOf(task2, task1),
- recentTaskPackages = emptyList(),
- )
-
- prepareHotseatAndRunningAndRecentApps(
- hotseatPackages = listOf(RUNNING_APP_PACKAGE_1),
- runningTasks = listOf(task2, task1),
- recentTaskPackages = emptyList(),
- )
-
- val newHotseatItems = recentAppsController.shownHotseatItems
- assertThat(newHotseatItems).hasSize(1)
- assertThat(newHotseatItems[0]).isInstanceOf(TaskItemInfo::class.java)
- assertThat((newHotseatItems[0] as TaskItemInfo).taskId).isEqualTo(1)
- val shownTasks = recentAppsController.shownTasks.map { it.task1 }
- assertThat(shownTasks).isEqualTo(listOf(task2))
+ // Assert that recentShownTasks contains only one instance of the app
+ assertThat(recentShownTasks).hasSize(1)
+ assertThat(recentShownTasks[0].key.packageName).isEqualTo(RUNNING_APP_PACKAGE_1)
}
@Test
@@ -859,8 +838,7 @@
runningTasks = runningTasks,
recentTaskPackages = emptyList(),
)
- val shownTasks = recentAppsController.shownTasks.map { it.task1 }
- assertThat(shownTasks).contains(runningTask)
+ assertThat(recentShownTasks).contains(runningTask)
assertThat(recentAppsController.runningTaskIds).containsExactlyElementsIn(listOf(1))
}
diff --git a/quickstep/tests/multivalentTests/src/com/android/launcher3/taskbar/TaskbarViewTestUtil.kt b/quickstep/tests/multivalentTests/src/com/android/launcher3/taskbar/TaskbarViewTestUtil.kt
index f2dcf77..e7f3523 100644
--- a/quickstep/tests/multivalentTests/src/com/android/launcher3/taskbar/TaskbarViewTestUtil.kt
+++ b/quickstep/tests/multivalentTests/src/com/android/launcher3/taskbar/TaskbarViewTestUtil.kt
@@ -99,9 +99,9 @@
/** Verifies that recents from [startIndex] have IDs that match [expectedIds] in order. */
fun hasRecentsOrder(startIndex: Int, expectedIds: List<Int>) {
val actualIds =
- view.iconViews.slice(startIndex..<startIndex + expectedIds.size).map {
+ view.iconViews.slice(startIndex..<startIndex + expectedIds.size).flatMap {
assertThat(it.tag).isInstanceOf(GroupTask::class.java)
- (it.tag as? GroupTask)?.task1?.key?.id
+ (it.tag as GroupTask).tasks.map { task -> task.key.id }
}
assertThat(actualIds).containsExactlyElementsIn(expectedIds).inOrder()
}
diff --git a/quickstep/tests/multivalentTests/src/com/android/quickstep/LauncherSwipeHandlerV2TestCase.java b/quickstep/tests/multivalentTests/src/com/android/quickstep/LauncherSwipeHandlerV2TestCase.java
index e6c5a6c..66c4ab5 100644
--- a/quickstep/tests/multivalentTests/src/com/android/quickstep/LauncherSwipeHandlerV2TestCase.java
+++ b/quickstep/tests/multivalentTests/src/com/android/quickstep/LauncherSwipeHandlerV2TestCase.java
@@ -33,11 +33,13 @@
import com.android.quickstep.views.RecentsView;
import org.junit.Before;
+import org.junit.Ignore;
import org.junit.runner.RunWith;
import org.mockito.Mock;
@SmallTest
@RunWith(LauncherMultivalentJUnit.class)
+@Ignore
public class LauncherSwipeHandlerV2TestCase extends AbsSwipeUpHandlerTestCase<
LauncherState,
QuickstepLauncher,
diff --git a/quickstep/tests/src/com/android/quickstep/RecentTasksListTest.java b/quickstep/tests/multivalentTests/src/com/android/quickstep/RecentTasksListTest.java
similarity index 97%
rename from quickstep/tests/src/com/android/quickstep/RecentTasksListTest.java
rename to quickstep/tests/multivalentTests/src/com/android/quickstep/RecentTasksListTest.java
index ccc0311..ccfe36d 100644
--- a/quickstep/tests/src/com/android/quickstep/RecentTasksListTest.java
+++ b/quickstep/tests/multivalentTests/src/com/android/quickstep/RecentTasksListTest.java
@@ -21,7 +21,7 @@
import static junit.framework.TestCase.assertNull;
import static org.junit.Assert.assertEquals;
-import static org.mockito.Matchers.anyInt;
+import static org.mockito.ArgumentMatchers.anyInt;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.times;
import static org.mockito.Mockito.verify;
@@ -34,6 +34,7 @@
import android.content.Context;
import android.content.res.Resources;
+import androidx.test.ext.junit.runners.AndroidJUnit4;
import androidx.test.filters.SmallTest;
import com.android.internal.R;
@@ -45,6 +46,7 @@
import org.junit.Before;
import org.junit.Test;
+import org.junit.runner.RunWith;
import org.mockito.Mock;
import org.mockito.MockitoAnnotations;
@@ -56,6 +58,7 @@
import java.util.stream.Collectors;
@SmallTest
+@RunWith(AndroidJUnit4.class)
public class RecentTasksListTest {
@Mock
diff --git a/quickstep/tests/src/com/android/quickstep/RecentsAnimationDeviceStateTest.kt b/quickstep/tests/multivalentTests/src/com/android/quickstep/RecentsAnimationDeviceStateTest.kt
similarity index 72%
rename from quickstep/tests/src/com/android/quickstep/RecentsAnimationDeviceStateTest.kt
rename to quickstep/tests/multivalentTests/src/com/android/quickstep/RecentsAnimationDeviceStateTest.kt
index 80fbce7..0245908 100644
--- a/quickstep/tests/src/com/android/quickstep/RecentsAnimationDeviceStateTest.kt
+++ b/quickstep/tests/multivalentTests/src/com/android/quickstep/RecentsAnimationDeviceStateTest.kt
@@ -1,13 +1,16 @@
package com.android.quickstep
import android.content.Context
-import android.testing.AndroidTestingRunner
+import androidx.test.annotation.UiThreadTest
import androidx.test.core.app.ApplicationProvider
import androidx.test.filters.SmallTest
import com.android.launcher3.util.DisplayController.CHANGE_DENSITY
import com.android.launcher3.util.DisplayController.CHANGE_NAVIGATION_MODE
import com.android.launcher3.util.DisplayController.CHANGE_ROTATION
import com.android.launcher3.util.DisplayController.Info
+import com.android.launcher3.util.Executors.MAIN_EXECUTOR
+import com.android.launcher3.util.Executors.UI_HELPER_EXECUTOR
+import com.android.launcher3.util.LauncherMultivalentJUnit
import com.android.launcher3.util.NavigationMode
import com.android.quickstep.util.GestureExclusionManager
import com.android.systemui.shared.system.QuickStepContract.SYSUI_STATE_ALLOW_GESTURE_IGNORING_BAR_VISIBILITY
@@ -22,6 +25,7 @@
import com.android.systemui.shared.system.QuickStepContract.SYSUI_STATE_STATUS_BAR_KEYGUARD_SHOWING
import com.android.systemui.shared.system.QuickStepContract.SYSUI_STATE_TOUCHPAD_GESTURES_DISABLED
import com.google.common.truth.Truth.assertThat
+import org.junit.After
import org.junit.Before
import org.junit.Test
import org.junit.runner.RunWith
@@ -30,12 +34,13 @@
import org.mockito.Mockito.verify
import org.mockito.MockitoAnnotations
import org.mockito.kotlin.doReturn
-import org.mockito.kotlin.verifyZeroInteractions
+import org.mockito.kotlin.verifyNoMoreInteractions
import org.mockito.kotlin.whenever
/** Unit test for [RecentsAnimationDeviceState]. */
@SmallTest
-@RunWith(AndroidTestingRunner::class)
+@UiThreadTest
+@RunWith(LauncherMultivalentJUnit::class)
class RecentsAnimationDeviceStateTest {
@Mock private lateinit var exclusionManager: GestureExclusionManager
@@ -50,6 +55,13 @@
underTest = RecentsAnimationDeviceState(context, exclusionManager)
}
+ @After
+ fun tearDown() {
+ underTest.close()
+ UI_HELPER_EXECUTOR.submit {}.get()
+ MAIN_EXECUTOR.submit {}.get()
+ }
+
@Test
fun registerExclusionListener_success() {
underTest.registerExclusionListener()
@@ -64,7 +76,7 @@
underTest.registerExclusionListener()
- verifyZeroInteractions(exclusionManager)
+ verifyNoMoreInteractions(exclusionManager)
}
@Test
@@ -85,7 +97,7 @@
underTest.unregisterExclusionListener()
- verifyZeroInteractions(exclusionManager)
+ verifyNoMoreInteractions(exclusionManager)
}
@Test
@@ -116,13 +128,13 @@
underTest.onDisplayInfoChanged(context, info, CHANGE_DENSITY)
- verifyZeroInteractions(exclusionManager)
+ verifyNoMoreInteractions(exclusionManager)
}
@Test
fun trackpadGesturesNotAllowedForSelectedStates() {
- val disablingStates = GESTURE_DISABLING_SYSUI_STATES +
- SYSUI_STATE_TOUCHPAD_GESTURES_DISABLED
+ val disablingStates =
+ GESTURE_DISABLING_SYSUI_STATES + SYSUI_STATE_TOUCHPAD_GESTURES_DISABLED
allSysUiStates().forEach { state ->
val canStartGesture = !disablingStates.contains(state)
@@ -133,13 +145,13 @@
@Test
fun trackpadGesturesNotAllowedIfHomeAndOverviewIsDisabled() {
- val stateToExpectedResult = mapOf(
- SYSUI_STATE_HOME_DISABLED to true,
- SYSUI_STATE_OVERVIEW_DISABLED to true,
- DEFAULT_STATE
- .enable(SYSUI_STATE_OVERVIEW_DISABLED)
- .enable(SYSUI_STATE_HOME_DISABLED) to false
- )
+ val stateToExpectedResult =
+ mapOf(
+ SYSUI_STATE_HOME_DISABLED to true,
+ SYSUI_STATE_OVERVIEW_DISABLED to true,
+ DEFAULT_STATE.enable(SYSUI_STATE_OVERVIEW_DISABLED)
+ .enable(SYSUI_STATE_HOME_DISABLED) to false,
+ )
stateToExpectedResult.forEach { (state, allowed) ->
underTest.setSystemUiFlags(state)
@@ -160,22 +172,19 @@
@Test
fun systemGesturesNotAllowedWhenGestureStateDisabledAndNavBarVisible() {
- val stateToExpectedResult = mapOf(
- DEFAULT_STATE
- .enable(SYSUI_STATE_ALLOW_GESTURE_IGNORING_BAR_VISIBILITY)
- .disable(SYSUI_STATE_NAV_BAR_HIDDEN) to true,
- DEFAULT_STATE
- .enable(SYSUI_STATE_ALLOW_GESTURE_IGNORING_BAR_VISIBILITY)
- .enable(SYSUI_STATE_NAV_BAR_HIDDEN) to true,
- DEFAULT_STATE
- .disable(SYSUI_STATE_ALLOW_GESTURE_IGNORING_BAR_VISIBILITY)
- .disable(SYSUI_STATE_NAV_BAR_HIDDEN) to true,
- DEFAULT_STATE
- .disable(SYSUI_STATE_ALLOW_GESTURE_IGNORING_BAR_VISIBILITY)
- .enable(SYSUI_STATE_NAV_BAR_HIDDEN) to false,
- )
+ val stateToExpectedResult =
+ mapOf(
+ DEFAULT_STATE.enable(SYSUI_STATE_ALLOW_GESTURE_IGNORING_BAR_VISIBILITY)
+ .disable(SYSUI_STATE_NAV_BAR_HIDDEN) to true,
+ DEFAULT_STATE.enable(SYSUI_STATE_ALLOW_GESTURE_IGNORING_BAR_VISIBILITY)
+ .enable(SYSUI_STATE_NAV_BAR_HIDDEN) to true,
+ DEFAULT_STATE.disable(SYSUI_STATE_ALLOW_GESTURE_IGNORING_BAR_VISIBILITY)
+ .disable(SYSUI_STATE_NAV_BAR_HIDDEN) to true,
+ DEFAULT_STATE.disable(SYSUI_STATE_ALLOW_GESTURE_IGNORING_BAR_VISIBILITY)
+ .enable(SYSUI_STATE_NAV_BAR_HIDDEN) to false,
+ )
- stateToExpectedResult.forEach {(state, gestureAllowed) ->
+ stateToExpectedResult.forEach { (state, gestureAllowed) ->
underTest.setSystemUiFlags(state)
assertThat(underTest.canStartSystemGesture()).isEqualTo(gestureAllowed)
}
@@ -187,14 +196,15 @@
}
companion object {
- private val GESTURE_DISABLING_SYSUI_STATES = listOf(
- SYSUI_STATE_NOTIFICATION_PANEL_EXPANDED,
- SYSUI_STATE_STATUS_BAR_KEYGUARD_SHOWING,
- SYSUI_STATE_QUICK_SETTINGS_EXPANDED,
- SYSUI_STATE_MAGNIFICATION_OVERLAP,
- SYSUI_STATE_DEVICE_DREAMING,
- SYSUI_STATE_DISABLE_GESTURE_SPLIT_INVOCATION,
- )
+ private val GESTURE_DISABLING_SYSUI_STATES =
+ listOf(
+ SYSUI_STATE_NOTIFICATION_PANEL_EXPANDED,
+ SYSUI_STATE_STATUS_BAR_KEYGUARD_SHOWING,
+ SYSUI_STATE_QUICK_SETTINGS_EXPANDED,
+ SYSUI_STATE_MAGNIFICATION_OVERLAP,
+ SYSUI_STATE_DEVICE_DREAMING,
+ SYSUI_STATE_DISABLE_GESTURE_SPLIT_INVOCATION,
+ )
private const val SYSUI_STATES_COUNT = 33
private const val DEFAULT_STATE = 0L
}
diff --git a/quickstep/tests/src/com/android/quickstep/RecentsModelTest.java b/quickstep/tests/multivalentTests/src/com/android/quickstep/RecentsModelTest.java
similarity index 97%
rename from quickstep/tests/src/com/android/quickstep/RecentsModelTest.java
rename to quickstep/tests/multivalentTests/src/com/android/quickstep/RecentsModelTest.java
index 4e34e11..a5c60ce 100644
--- a/quickstep/tests/src/com/android/quickstep/RecentsModelTest.java
+++ b/quickstep/tests/multivalentTests/src/com/android/quickstep/RecentsModelTest.java
@@ -35,6 +35,7 @@
import android.platform.test.flag.junit.SetFlagsRule;
import androidx.test.annotation.UiThreadTest;
+import androidx.test.ext.junit.runners.AndroidJUnit4;
import androidx.test.filters.SmallTest;
import com.android.launcher3.Flags;
@@ -48,6 +49,7 @@
import org.junit.Before;
import org.junit.Rule;
import org.junit.Test;
+import org.junit.runner.RunWith;
import org.mockito.ArgumentCaptor;
import org.mockito.Mock;
import org.mockito.MockitoAnnotations;
@@ -56,6 +58,7 @@
import java.util.function.Consumer;
@SmallTest
+@RunWith(AndroidJUnit4.class)
public class RecentsModelTest {
@Mock
private Context mContext;
diff --git a/quickstep/tests/src/com/android/quickstep/TaskAnimationManagerTest.java b/quickstep/tests/multivalentTests/src/com/android/quickstep/TaskAnimationManagerTest.java
similarity index 96%
rename from quickstep/tests/src/com/android/quickstep/TaskAnimationManagerTest.java
rename to quickstep/tests/multivalentTests/src/com/android/quickstep/TaskAnimationManagerTest.java
index a87c328..6e9885a 100644
--- a/quickstep/tests/src/com/android/quickstep/TaskAnimationManagerTest.java
+++ b/quickstep/tests/multivalentTests/src/com/android/quickstep/TaskAnimationManagerTest.java
@@ -27,16 +27,19 @@
import android.content.Context;
import android.content.Intent;
+import androidx.test.ext.junit.runners.AndroidJUnit4;
import androidx.test.filters.SmallTest;
import androidx.test.platform.app.InstrumentationRegistry;
import org.junit.Before;
import org.junit.Test;
+import org.junit.runner.RunWith;
import org.mockito.ArgumentCaptor;
import org.mockito.Mock;
import org.mockito.MockitoAnnotations;
@SmallTest
+@RunWith(AndroidJUnit4.class)
public class TaskAnimationManagerTest {
protected final Context mContext =
diff --git a/quickstep/tests/src/com/android/quickstep/TaskThumbnailCacheTest.java b/quickstep/tests/multivalentTests/src/com/android/quickstep/TaskThumbnailCacheTest.java
similarity index 96%
rename from quickstep/tests/src/com/android/quickstep/TaskThumbnailCacheTest.java
rename to quickstep/tests/multivalentTests/src/com/android/quickstep/TaskThumbnailCacheTest.java
index 4e04261..3686c16 100644
--- a/quickstep/tests/src/com/android/quickstep/TaskThumbnailCacheTest.java
+++ b/quickstep/tests/multivalentTests/src/com/android/quickstep/TaskThumbnailCacheTest.java
@@ -28,6 +28,7 @@
import android.content.Context;
import android.content.res.Resources;
+import androidx.test.ext.junit.runners.AndroidJUnit4;
import androidx.test.filters.SmallTest;
import com.android.launcher3.R;
@@ -35,12 +36,14 @@
import org.junit.Before;
import org.junit.Test;
+import org.junit.runner.RunWith;
import org.mockito.Mock;
import org.mockito.MockitoAnnotations;
import java.util.concurrent.Executor;
@SmallTest
+@RunWith(AndroidJUnit4.class)
public class TaskThumbnailCacheTest {
@Mock
private Context mContext;
diff --git a/quickstep/tests/multivalentTests/src/com/android/quickstep/recents/data/FakeTasksRepository.kt b/quickstep/tests/multivalentTests/src/com/android/quickstep/recents/data/FakeTasksRepository.kt
index 1c9ce0b..35af29f 100644
--- a/quickstep/tests/multivalentTests/src/com/android/quickstep/recents/data/FakeTasksRepository.kt
+++ b/quickstep/tests/multivalentTests/src/com/android/quickstep/recents/data/FakeTasksRepository.kt
@@ -58,10 +58,10 @@
tasks.value.map {
it.apply {
thumbnail = thumbnailDataMap[it.key.id]
- taskIconDataMap[it.key.id].let { data ->
- title = data?.title
- titleDescription = data?.titleDescription
- icon = data?.icon
+ taskIconDataMap[it.key.id]?.let { data ->
+ title = data.title
+ titleDescription = data.titleDescription
+ icon = data.icon
}
}
}
diff --git a/quickstep/tests/multivalentTests/src/com/android/quickstep/recents/domain/usecase/GetTaskUseCaseTest.kt b/quickstep/tests/multivalentTests/src/com/android/quickstep/recents/domain/usecase/GetTaskUseCaseTest.kt
new file mode 100644
index 0000000..b036bce
--- /dev/null
+++ b/quickstep/tests/multivalentTests/src/com/android/quickstep/recents/domain/usecase/GetTaskUseCaseTest.kt
@@ -0,0 +1,107 @@
+/*
+ * 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.quickstep.recents.domain.usecase
+
+import android.content.ComponentName
+import android.content.Intent
+import android.graphics.Color
+import android.graphics.drawable.ShapeDrawable
+import androidx.test.ext.junit.runners.AndroidJUnit4
+import com.android.quickstep.recents.data.FakeTasksRepository
+import com.android.quickstep.recents.domain.model.TaskModel
+import com.android.systemui.shared.recents.model.Task
+import com.google.common.truth.Truth.assertThat
+import kotlinx.coroutines.ExperimentalCoroutinesApi
+import kotlinx.coroutines.flow.firstOrNull
+import kotlinx.coroutines.test.TestScope
+import kotlinx.coroutines.test.UnconfinedTestDispatcher
+import kotlinx.coroutines.test.runTest
+import org.junit.Before
+import org.junit.Test
+import org.junit.runner.RunWith
+
+@OptIn(ExperimentalCoroutinesApi::class)
+@RunWith(AndroidJUnit4::class)
+class GetTaskUseCaseTest {
+ private val unconfinedTestDispatcher = UnconfinedTestDispatcher()
+ private val testScope = TestScope(unconfinedTestDispatcher)
+
+ private val tasksRepository = FakeTasksRepository()
+ private val sut = GetTaskUseCase(repository = tasksRepository)
+
+ @Before
+ fun setUp() {
+ tasksRepository.seedTasks(listOf(TASK_1))
+ }
+
+ @Test
+ fun taskNotSeeded_returnsNull() =
+ testScope.runTest {
+ val result = sut.invoke(NOT_FOUND_TASK_ID).firstOrNull()
+ assertThat(result).isNull()
+ }
+
+ @Test
+ fun taskNotVisible_returnsNull() =
+ testScope.runTest {
+ val result = sut.invoke(TASK_1_ID).firstOrNull()
+ assertThat(result).isNull()
+ }
+
+ @Test
+ fun taskVisible_returnsData() =
+ testScope.runTest {
+ tasksRepository.setVisibleTasks(setOf(TASK_1_ID))
+ val expectedResult =
+ TaskModel(
+ id = TASK_1_ID,
+ title = "Title $TASK_1_ID",
+ titleDescription = "Content Description $TASK_1_ID",
+ icon = TASK_1_ICON,
+ thumbnail = null,
+ backgroundColor = Color.BLACK,
+ isLocked = false,
+ )
+ val result = sut.invoke(TASK_1_ID).firstOrNull()
+ assertThat(result).isEqualTo(expectedResult)
+ }
+
+ private companion object {
+ const val NOT_FOUND_TASK_ID = 404
+ private const val TASK_1_ID = 1
+ private val TASK_1_ICON = ShapeDrawable()
+ private val TASK_1 =
+ Task(
+ Task.TaskKey(
+ /* id = */ TASK_1_ID,
+ /* windowingMode = */ 0,
+ /* intent = */ Intent(),
+ /* sourceComponent = */ ComponentName("", ""),
+ /* userId = */ 0,
+ /* lastActiveTime = */ 2000,
+ )
+ )
+ .apply {
+ title = "Title 1"
+ titleDescription = "Content Description 1"
+ colorBackground = Color.BLACK
+ icon = TASK_1_ICON
+ thumbnail = null
+ isLocked = false
+ }
+ }
+}
diff --git a/quickstep/tests/multivalentTests/src/com/android/quickstep/recents/ui/viewmodel/TaskViewModelTest.kt b/quickstep/tests/multivalentTests/src/com/android/quickstep/recents/ui/viewmodel/TaskViewModelTest.kt
new file mode 100644
index 0000000..54a27e9
--- /dev/null
+++ b/quickstep/tests/multivalentTests/src/com/android/quickstep/recents/ui/viewmodel/TaskViewModelTest.kt
@@ -0,0 +1,216 @@
+/*
+ * 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.quickstep.recents.ui.viewmodel
+
+import android.graphics.Color
+import android.graphics.drawable.ShapeDrawable
+import androidx.test.ext.junit.runners.AndroidJUnit4
+import com.android.launcher3.util.TestDispatcherProvider
+import com.android.quickstep.recents.domain.model.TaskModel
+import com.android.quickstep.recents.domain.usecase.GetTaskUseCase
+import com.android.quickstep.recents.viewmodel.RecentsViewData
+import com.android.systemui.shared.recents.model.ThumbnailData
+import com.google.common.truth.Truth.assertThat
+import kotlinx.coroutines.ExperimentalCoroutinesApi
+import kotlinx.coroutines.flow.first
+import kotlinx.coroutines.flow.flow
+import kotlinx.coroutines.test.TestScope
+import kotlinx.coroutines.test.UnconfinedTestDispatcher
+import kotlinx.coroutines.test.runTest
+import org.junit.Before
+import org.junit.Test
+import org.junit.runner.RunWith
+import org.mockito.kotlin.mock
+import org.mockito.kotlin.whenever
+
+@OptIn(ExperimentalCoroutinesApi::class)
+@RunWith(AndroidJUnit4::class)
+class TaskViewModelTest {
+ private val unconfinedTestDispatcher = UnconfinedTestDispatcher()
+ private val testScope = TestScope(unconfinedTestDispatcher)
+
+ private val recentsViewData = RecentsViewData()
+ private val getTaskUseCase = mock<GetTaskUseCase>()
+ private val sut =
+ TaskViewModel(
+ recentsViewData = recentsViewData,
+ getTaskUseCase = getTaskUseCase,
+ dispatcherProvider = TestDispatcherProvider(unconfinedTestDispatcher),
+ )
+
+ @Before
+ fun setUp() {
+ whenever(getTaskUseCase.invoke(TASK_MODEL_1.id)).thenReturn(flow { emit(TASK_MODEL_1) })
+ whenever(getTaskUseCase.invoke(TASK_MODEL_2.id)).thenReturn(flow { emit(TASK_MODEL_2) })
+ whenever(getTaskUseCase.invoke(TASK_MODEL_3.id)).thenReturn(flow { emit(TASK_MODEL_3) })
+ whenever(getTaskUseCase.invoke(INVALID_TASK_ID)).thenReturn(flow { emit(null) })
+ recentsViewData.runningTaskIds.value = emptySet()
+ }
+
+ @Test
+ fun singleTaskRetrieved_when_validTaskId() =
+ testScope.runTest {
+ sut.bind(TASK_MODEL_1.id)
+ val expectedResult = TaskTileUiState(listOf(TASK_MODEL_1.toUiState()), false)
+ assertThat(sut.state.first()).isEqualTo(expectedResult)
+ }
+
+ @Test
+ fun multipleTasksRetrieved_when_validTaskIds() =
+ testScope.runTest {
+ sut.bind(TASK_MODEL_1.id, TASK_MODEL_2.id, TASK_MODEL_3.id, INVALID_TASK_ID)
+ val expectedResult =
+ TaskTileUiState(
+ tasks =
+ listOf(
+ TASK_MODEL_1.toUiState(),
+ TASK_MODEL_2.toUiState(),
+ TASK_MODEL_3.toUiState(),
+ TaskData.NoData(INVALID_TASK_ID),
+ ),
+ isLiveTile = false,
+ )
+ assertThat(sut.state.first()).isEqualTo(expectedResult)
+ }
+
+ @Test
+ fun isLiveTile_when_runningTasksMatchTasks() =
+ testScope.runTest {
+ recentsViewData.runningTaskShowScreenshot.value = false
+ recentsViewData.runningTaskIds.value =
+ setOf(TASK_MODEL_1.id, TASK_MODEL_2.id, TASK_MODEL_3.id)
+ sut.bind(TASK_MODEL_1.id, TASK_MODEL_2.id, TASK_MODEL_3.id)
+ val expectedResult =
+ TaskTileUiState(
+ tasks =
+ listOf(
+ TASK_MODEL_1.toUiState(),
+ TASK_MODEL_2.toUiState(),
+ TASK_MODEL_3.toUiState(),
+ ),
+ isLiveTile = true,
+ )
+ assertThat(sut.state.first()).isEqualTo(expectedResult)
+ }
+
+ @Test
+ fun isNotLiveTile_when_runningTaskShowScreenshotIsTrue() =
+ testScope.runTest {
+ recentsViewData.runningTaskShowScreenshot.value = true
+ recentsViewData.runningTaskIds.value =
+ setOf(TASK_MODEL_1.id, TASK_MODEL_2.id, TASK_MODEL_3.id)
+ sut.bind(TASK_MODEL_1.id, TASK_MODEL_2.id, TASK_MODEL_3.id)
+ val expectedResult =
+ TaskTileUiState(
+ tasks =
+ listOf(
+ TASK_MODEL_1.toUiState(),
+ TASK_MODEL_2.toUiState(),
+ TASK_MODEL_3.toUiState(),
+ ),
+ isLiveTile = false,
+ )
+ assertThat(sut.state.first()).isEqualTo(expectedResult)
+ }
+
+ @Test
+ fun isNotLiveTile_when_runningTasksMatchPartialTasks_lessRunningTasks() =
+ testScope.runTest {
+ recentsViewData.runningTaskShowScreenshot.value = false
+ recentsViewData.runningTaskIds.value = setOf(TASK_MODEL_1.id, TASK_MODEL_2.id)
+ sut.bind(TASK_MODEL_1.id, TASK_MODEL_2.id, TASK_MODEL_3.id)
+ val expectedResult =
+ TaskTileUiState(
+ tasks =
+ listOf(
+ TASK_MODEL_1.toUiState(),
+ TASK_MODEL_2.toUiState(),
+ TASK_MODEL_3.toUiState(),
+ ),
+ isLiveTile = false,
+ )
+ assertThat(sut.state.first()).isEqualTo(expectedResult)
+ }
+
+ @Test
+ fun isNotLiveTile_when_runningTasksMatchPartialTasks_moreRunningTasks() =
+ testScope.runTest {
+ recentsViewData.runningTaskShowScreenshot.value = false
+ recentsViewData.runningTaskIds.value =
+ setOf(TASK_MODEL_1.id, TASK_MODEL_2.id, TASK_MODEL_3.id)
+ sut.bind(TASK_MODEL_1.id, TASK_MODEL_2.id)
+ val expectedResult =
+ TaskTileUiState(
+ tasks = listOf(TASK_MODEL_1.toUiState(), TASK_MODEL_2.toUiState()),
+ isLiveTile = false,
+ )
+ assertThat(sut.state.first()).isEqualTo(expectedResult)
+ }
+
+ @Test
+ fun noDataAvailable_when_InvalidTaskId() =
+ testScope.runTest {
+ sut.bind(INVALID_TASK_ID)
+ val expectedResult =
+ TaskTileUiState(listOf(TaskData.NoData(INVALID_TASK_ID)), isLiveTile = false)
+ assertThat(sut.state.first()).isEqualTo(expectedResult)
+ }
+
+ private fun TaskModel.toUiState() =
+ TaskData.Data(
+ taskId = id,
+ title = title,
+ icon = icon!!,
+ thumbnailData = thumbnail,
+ backgroundColor = backgroundColor,
+ isLocked = isLocked,
+ )
+
+ companion object {
+ const val INVALID_TASK_ID = -1
+ val TASK_MODEL_1 =
+ TaskModel(
+ 1,
+ "Title 1",
+ "Content Description 1",
+ ShapeDrawable(),
+ ThumbnailData(),
+ Color.BLACK,
+ false,
+ )
+ val TASK_MODEL_2 =
+ TaskModel(
+ 2,
+ "Title 2",
+ "Content Description 2",
+ ShapeDrawable(),
+ ThumbnailData(),
+ Color.RED,
+ true,
+ )
+ val TASK_MODEL_3 =
+ TaskModel(
+ 3,
+ "Title 3",
+ "Content Description 3",
+ ShapeDrawable(),
+ ThumbnailData(),
+ Color.BLUE,
+ false,
+ )
+ }
+}
diff --git a/quickstep/tests/multivalentTests/src/com/android/quickstep/recents/usecase/GetThumbnailUseCaseTest.kt b/quickstep/tests/multivalentTests/src/com/android/quickstep/recents/usecase/GetThumbnailUseCaseTest.kt
index 73aa460..0044631 100644
--- a/quickstep/tests/multivalentTests/src/com/android/quickstep/recents/usecase/GetThumbnailUseCaseTest.kt
+++ b/quickstep/tests/multivalentTests/src/com/android/quickstep/recents/usecase/GetThumbnailUseCaseTest.kt
@@ -76,7 +76,7 @@
assertThat(systemUnderTest.run(TASK_ID)).isEqualTo(thumbnailData.thumbnail)
}
- companion object {
+ private companion object {
const val TASK_ID = 0
const val THUMBNAIL_WIDTH = 100
const val THUMBNAIL_HEIGHT = 200
diff --git a/quickstep/tests/src/com/android/quickstep/taskbar/controllers/TaskbarPinningControllerTest.kt b/quickstep/tests/multivalentTests/src/com/android/quickstep/taskbar/controllers/TaskbarPinningControllerTest.kt
similarity index 97%
rename from quickstep/tests/src/com/android/quickstep/taskbar/controllers/TaskbarPinningControllerTest.kt
rename to quickstep/tests/multivalentTests/src/com/android/quickstep/taskbar/controllers/TaskbarPinningControllerTest.kt
index 3148737..5b42d6c 100644
--- a/quickstep/tests/src/com/android/quickstep/taskbar/controllers/TaskbarPinningControllerTest.kt
+++ b/quickstep/tests/multivalentTests/src/com/android/quickstep/taskbar/controllers/TaskbarPinningControllerTest.kt
@@ -56,9 +56,9 @@
private val taskbarSharedState = mock<TaskbarSharedState>()
private var isInDesktopMode = false
private val launcherPrefs =
- mock<LauncherPrefs> {
- on { get(TASKBAR_PINNING) } doReturn false
- on { get(TASKBAR_PINNING_IN_DESKTOP_MODE) } doReturn false
+ mock<LauncherPrefs>().apply {
+ doReturn(false).whenever(this).get(TASKBAR_PINNING)
+ doReturn(false).whenever(this).get(TASKBAR_PINNING_IN_DESKTOP_MODE)
}
private val statsLogger = mock<StatsLogManager.StatsLogger>()
private val statsLogManager = mock<StatsLogManager> { on { logger() } doReturn statsLogger }
diff --git a/quickstep/tests/src/com/android/quickstep/util/GestureExclusionManagerTest.kt b/quickstep/tests/multivalentTests/src/com/android/quickstep/util/GestureExclusionManagerTest.kt
similarity index 90%
rename from quickstep/tests/src/com/android/quickstep/util/GestureExclusionManagerTest.kt
rename to quickstep/tests/multivalentTests/src/com/android/quickstep/util/GestureExclusionManagerTest.kt
index c190cfe..555e62b 100644
--- a/quickstep/tests/src/com/android/quickstep/util/GestureExclusionManagerTest.kt
+++ b/quickstep/tests/multivalentTests/src/com/android/quickstep/util/GestureExclusionManagerTest.kt
@@ -18,11 +18,12 @@
import android.graphics.Rect
import android.graphics.Region
-import android.testing.AndroidTestingRunner
import android.view.Display.DEFAULT_DISPLAY
import android.view.IWindowManager
+import androidx.test.annotation.UiThreadTest
import androidx.test.filters.SmallTest
import com.android.launcher3.util.Executors
+import com.android.launcher3.util.LauncherMultivalentJUnit
import com.android.quickstep.util.GestureExclusionManager.ExclusionListener
import org.junit.Before
import org.junit.Test
@@ -31,11 +32,12 @@
import org.mockito.MockitoAnnotations
import org.mockito.kotlin.reset
import org.mockito.kotlin.verify
-import org.mockito.kotlin.verifyZeroInteractions
+import org.mockito.kotlin.verifyNoMoreInteractions
/** Unit test for [GestureExclusionManager]. */
@SmallTest
-@RunWith(AndroidTestingRunner::class)
+@UiThreadTest
+@RunWith(LauncherMultivalentJUnit::class)
class GestureExclusionManagerTest {
@Mock private lateinit var windowManager: IWindowManager
@@ -72,7 +74,7 @@
underTest.addListener(listener2)
awaitTasksCompleted()
- verifyZeroInteractions(windowManager)
+ verifyNoMoreInteractions(windowManager)
}
@Test
@@ -98,7 +100,7 @@
underTest.removeListener(listener1)
awaitTasksCompleted()
- verifyZeroInteractions(windowManager)
+ verifyNoMoreInteractions(windowManager)
}
@Test
@@ -119,12 +121,12 @@
awaitTasksCompleted()
underTest.addListener(listener1)
awaitTasksCompleted()
- verifyZeroInteractions(listener1)
+ verifyNoMoreInteractions(listener1)
underTest.addListener(listener2)
awaitTasksCompleted()
- verifyZeroInteractions(listener1)
+ verifyNoMoreInteractions(listener1)
verify(listener2).onGestureExclusionChanged(r1, r2)
}
diff --git a/quickstep/tests/src/com/android/launcher3/taskbar/TaskbarHoverToolTipControllerTest.java b/quickstep/tests/src/com/android/launcher3/taskbar/TaskbarHoverToolTipControllerTest.java
index 67a0ee4..3f7c85c 100644
--- a/quickstep/tests/src/com/android/launcher3/taskbar/TaskbarHoverToolTipControllerTest.java
+++ b/quickstep/tests/src/com/android/launcher3/taskbar/TaskbarHoverToolTipControllerTest.java
@@ -127,11 +127,11 @@
when(mMotionEvent.getAction()).thenReturn(MotionEvent.ACTION_HOVER_ENTER);
when(mMotionEvent.getActionMasked()).thenReturn(MotionEvent.ACTION_HOVER_ENTER);
- boolean hoverHandled =
+ boolean hoverConsumed =
mTaskbarHoverToolTipController.onHover(mHoverBubbleTextView, mMotionEvent);
waitForIdleSync();
- assertThat(hoverHandled).isTrue();
+ assertThat(hoverConsumed).isFalse();
verify(taskbarActivityContext).setAutohideSuspendFlag(FLAG_AUTOHIDE_SUSPEND_HOVERING_ICONS,
true);
}
@@ -141,11 +141,11 @@
when(mMotionEvent.getAction()).thenReturn(MotionEvent.ACTION_HOVER_EXIT);
when(mMotionEvent.getActionMasked()).thenReturn(MotionEvent.ACTION_HOVER_EXIT);
- boolean hoverHandled =
+ boolean hoverConsumed =
mTaskbarHoverToolTipController.onHover(mHoverBubbleTextView, mMotionEvent);
waitForIdleSync();
- assertThat(hoverHandled).isTrue();
+ assertThat(hoverConsumed).isFalse();
verify(taskbarActivityContext).setAutohideSuspendFlag(FLAG_AUTOHIDE_SUSPEND_HOVERING_ICONS,
false);
}
@@ -155,11 +155,11 @@
when(mMotionEvent.getAction()).thenReturn(MotionEvent.ACTION_HOVER_ENTER);
when(mMotionEvent.getActionMasked()).thenReturn(MotionEvent.ACTION_HOVER_ENTER);
- boolean hoverHandled =
+ boolean hoverConsumed =
mTaskbarHoverToolTipController.onHover(mHoverFolderIcon, mMotionEvent);
waitForIdleSync();
- assertThat(hoverHandled).isTrue();
+ assertThat(hoverConsumed).isFalse();
verify(taskbarActivityContext).setAutohideSuspendFlag(FLAG_AUTOHIDE_SUSPEND_HOVERING_ICONS,
true);
}
@@ -169,11 +169,11 @@
when(mMotionEvent.getAction()).thenReturn(MotionEvent.ACTION_HOVER_EXIT);
when(mMotionEvent.getActionMasked()).thenReturn(MotionEvent.ACTION_HOVER_EXIT);
- boolean hoverHandled =
+ boolean hoverConsumed =
mTaskbarHoverToolTipController.onHover(mHoverFolderIcon, mMotionEvent);
waitForIdleSync();
- assertThat(hoverHandled).isTrue();
+ assertThat(hoverConsumed).isFalse();
verify(taskbarActivityContext).setAutohideSuspendFlag(FLAG_AUTOHIDE_SUSPEND_HOVERING_ICONS,
false);
}
@@ -184,11 +184,11 @@
when(mMotionEvent.getActionMasked()).thenReturn(MotionEvent.ACTION_HOVER_EXIT);
doReturn(true).when(mSpyFolderView).isOpen();
- boolean hoverHandled =
+ boolean hoverConsumed =
mTaskbarHoverToolTipController.onHover(mHoverFolderIcon, mMotionEvent);
waitForIdleSync();
- assertThat(hoverHandled).isTrue();
+ assertThat(hoverConsumed).isFalse();
verify(taskbarActivityContext).setAutohideSuspendFlag(FLAG_AUTOHIDE_SUSPEND_HOVERING_ICONS,
false);
}
@@ -199,10 +199,10 @@
when(mMotionEvent.getActionMasked()).thenReturn(MotionEvent.ACTION_HOVER_ENTER);
doReturn(true).when(mSpyFolderView).isOpen();
- boolean hoverHandled =
+ boolean hoverConsumed =
mTaskbarHoverToolTipController.onHover(mHoverFolderIcon, mMotionEvent);
- assertThat(hoverHandled).isTrue();
+ assertThat(hoverConsumed).isFalse();
}
@Test
@@ -210,10 +210,10 @@
when(mMotionEvent.getAction()).thenReturn(MotionEvent.ACTION_HOVER_MOVE);
when(mMotionEvent.getActionMasked()).thenReturn(MotionEvent.ACTION_HOVER_MOVE);
- boolean hoverHandled =
+ boolean hoverConsumed =
mTaskbarHoverToolTipController.onHover(mHoverFolderIcon, mMotionEvent);
- assertThat(hoverHandled).isTrue();
+ assertThat(hoverConsumed).isFalse();
}
@Test
@@ -221,11 +221,11 @@
when(mMotionEvent.getAction()).thenReturn(MotionEvent.ACTION_HOVER_ENTER);
when(mMotionEvent.getActionMasked()).thenReturn(MotionEvent.ACTION_HOVER_ENTER);
- boolean hoverHandled =
+ boolean hoverConsumed =
mTaskbarHoverToolTipController.onHover(mAppPairIcon, mMotionEvent);
waitForIdleSync();
- assertThat(hoverHandled).isTrue();
+ assertThat(hoverConsumed).isFalse();
verify(taskbarActivityContext).setAutohideSuspendFlag(FLAG_AUTOHIDE_SUSPEND_HOVERING_ICONS,
true);
}
@@ -235,11 +235,11 @@
when(mMotionEvent.getAction()).thenReturn(MotionEvent.ACTION_HOVER_EXIT);
when(mMotionEvent.getActionMasked()).thenReturn(MotionEvent.ACTION_HOVER_EXIT);
- boolean hoverHandled =
+ boolean hoverConsumed =
mTaskbarHoverToolTipController.onHover(mAppPairIcon, mMotionEvent);
waitForIdleSync();
- assertThat(hoverHandled).isTrue();
+ assertThat(hoverConsumed).isFalse();
verify(taskbarActivityContext).setAutohideSuspendFlag(FLAG_AUTOHIDE_SUSPEND_HOVERING_ICONS,
false);
}
@@ -250,11 +250,11 @@
when(mMotionEvent.getActionMasked()).thenReturn(MotionEvent.ACTION_HOVER_ENTER);
when(taskbarActivityContext.isIconAlignedWithHotseat()).thenReturn(true);
- boolean hoverHandled =
+ boolean hoverConsumed =
mTaskbarHoverToolTipController.onHover(mHoverBubbleTextView, mMotionEvent);
waitForIdleSync();
- assertThat(hoverHandled).isTrue();
+ assertThat(hoverConsumed).isFalse();
verify(taskbarActivityContext).setAutohideSuspendFlag(FLAG_AUTOHIDE_SUSPEND_HOVERING_ICONS,
true);
}
diff --git a/quickstep/tests/src/com/android/quickstep/TaplTestsLockedTaskbar.java b/quickstep/tests/src/com/android/quickstep/TaplTestsLockedTaskbar.java
new file mode 100644
index 0000000..8fedf5c
--- /dev/null
+++ b/quickstep/tests/src/com/android/quickstep/TaplTestsLockedTaskbar.java
@@ -0,0 +1,99 @@
+/*
+ * 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.quickstep;
+
+import static android.view.Display.DEFAULT_DISPLAY;
+
+import static androidx.test.InstrumentationRegistry.getTargetContext;
+
+import static com.android.quickstep.TaskbarModeSwitchRule.Mode.PERSISTENT;
+import static com.android.wm.shell.shared.desktopmode.DesktopModeStatus.ENTER_DESKTOP_BY_DEFAULT_ON_FREEFORM_DISPLAY_SYS_PROP;
+
+import android.app.WindowConfiguration;
+import android.os.RemoteException;
+import android.util.Log;
+import android.view.WindowManagerGlobal;
+
+import androidx.test.filters.LargeTest;
+import androidx.test.runner.AndroidJUnit4;
+
+import com.android.launcher3.ui.PortraitLandscapeRunner.PortraitLandscape;
+import com.android.launcher3.util.rule.SetPropRule;
+import com.android.quickstep.NavigationModeSwitchRule.NavigationModeSwitch;
+import com.android.quickstep.TaskbarModeSwitchRule.TaskbarModeSwitch;
+import com.android.window.flags.Flags;
+import com.android.wm.shell.shared.desktopmode.DesktopModeStatus;
+
+import org.junit.Assume;
+import org.junit.Rule;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
+@LargeTest
+@RunWith(AndroidJUnit4.class)
+public class TaplTestsLockedTaskbar extends AbstractTaplTestsTaskbar {
+ private static final String TAG = "TaplTestsLockedTaskbar";
+
+ @Rule
+ public SetPropRule mSetPropRule =
+ new SetPropRule(ENTER_DESKTOP_BY_DEFAULT_ON_FREEFORM_DISPLAY_SYS_PROP, "true");
+
+ @Override
+ public void setUp() throws Exception {
+ Assume.assumeTrue(mLauncher.isTablet());
+ Assume.assumeTrue(Flags.enterDesktopByDefaultOnFreeformDisplays());
+ Assume.assumeTrue(DesktopModeStatus.canEnterDesktopMode(getTargetContext()));
+ super.setUp();
+
+ // Default-to-desktop feature requires the display to be freeform mode.
+ setDisplayWindowingMode(WindowConfiguration.WINDOWING_MODE_FREEFORM);
+ }
+
+ @Override
+ public void tearDown() throws Exception {
+ // Reset the display windowing mode to the device default.
+ setDisplayWindowingMode(WindowConfiguration.WINDOWING_MODE_UNDEFINED);
+
+ mLauncher.recreateTaskbar();
+
+ super.tearDown();
+ }
+
+ @Test
+ @PortraitLandscape
+ @NavigationModeSwitch
+ @TaskbarModeSwitch(mode = PERSISTENT)
+ public void testTaskbarVisibility() {
+ // The taskbar should be visible on home.
+ mDevice.pressHome();
+ waitForResumed("Launcher internal state is still Background");
+ mLauncher.getLaunchedAppState().assertTaskbarVisible();
+
+ // The taskbar should be visible when a freeform task is active.
+ startAppFast(CALCULATOR_APP_PACKAGE);
+ mLauncher.getLaunchedAppState().assertTaskbarVisible();
+ }
+
+ private void setDisplayWindowingMode(int windowingMode) {
+ try {
+ WindowManagerGlobal.getWindowManagerService().setWindowingMode(
+ DEFAULT_DISPLAY, windowingMode);
+ } catch (RemoteException e) {
+ Log.e(TAG, "error setting windowing mode", e);
+ throw new RuntimeException(e);
+ }
+ }
+}
diff --git a/quickstep/tests/src/com/android/quickstep/TaplTestsOverviewDesktop.kt b/quickstep/tests/src/com/android/quickstep/TaplTestsOverviewDesktop.kt
index b744039..75947ab 100644
--- a/quickstep/tests/src/com/android/quickstep/TaplTestsOverviewDesktop.kt
+++ b/quickstep/tests/src/com/android/quickstep/TaplTestsOverviewDesktop.kt
@@ -122,25 +122,25 @@
val desktop = moveTaskToDesktop(TEST_ACTIVITY_EXTRA)
var overview = desktop.switchToOverview()
- // Open focused task and go back to Overview to validate whether it has adjacent tasks in
- // its both sides (grid task on left and desktop tasks at its right side)
- val focusedTaskOpened = overview.getTestActivityTask(TEST_ACTIVITY_2).open()
+ // Open first fullscreen task and go back to Overview to validate whether it has adjacent
+ // tasks in its both sides (grid task on left and desktop tasks at its right side)
+ val firstFullscreenTaskOpened = overview.getTestActivityTask(TEST_ACTIVITY_2).open()
- // Fling to desktop task and dismiss the focused task to check repositioning of
+ // Fling to desktop task and dismiss the first fullscreen task to check repositioning of
// grid tasks.
- overview = focusedTaskOpened.switchToOverview().apply { flingBackward() }
+ overview = firstFullscreenTaskOpened.switchToOverview().apply { flingBackward() }
val desktopTask = overview.currentTask
assertWithMessage("The current task is not a Desktop.").that(desktopTask.isDesktop).isTrue()
- // Get focused task (previously opened task) then dismiss this task
- val focusedTaskInOverview = overview.getTestActivityTask(TEST_ACTIVITY_2)
- assertTaskContentDescription(focusedTaskInOverview, TEST_ACTIVITY_2)
- focusedTaskInOverview.dismiss()
+ // Get first fullscreen task (previously opened task) then dismiss this task
+ val firstFullscreenTaskInOverview = overview.getTestActivityTask(TEST_ACTIVITY_2)
+ assertTaskContentDescription(firstFullscreenTaskInOverview, TEST_ACTIVITY_2)
+ firstFullscreenTaskInOverview.dismiss()
- // Dismiss DesktopTask to validate whether the new focused task will take its position
+ // Dismiss DesktopTask to validate whether the new task will take its position
desktopTask.dismiss()
- // Dismiss last focused task
+ // Dismiss last fullscreen task
val lastFocusedTask = overview.currentTask
assertTaskContentDescription(lastFocusedTask, TEST_ACTIVITY_1)
lastFocusedTask.dismiss()
diff --git a/quickstep/tests/src/com/android/quickstep/TaplTestsSplitscreen.java b/quickstep/tests/src/com/android/quickstep/TaplTestsSplitscreen.java
index afe6368..37ac4a0 100644
--- a/quickstep/tests/src/com/android/quickstep/TaplTestsSplitscreen.java
+++ b/quickstep/tests/src/com/android/quickstep/TaplTestsSplitscreen.java
@@ -30,7 +30,6 @@
import com.android.launcher3.tapl.Taskbar;
import com.android.launcher3.tapl.TaskbarAppIcon;
import com.android.quickstep.util.SplitScreenTestUtils;
-import com.android.wm.shell.Flags;
import org.junit.After;
import org.junit.Before;
@@ -95,9 +94,6 @@
@Test
public void testSaveAppPairMenuItemOrActionExistsOnSplitPair() {
- assumeTrue("App pairs feature is currently not enabled, no test needed",
- Flags.enableAppPairs());
-
Overview overview = SplitScreenTestUtils.createAndLaunchASplitPairInOverview(mLauncher);
if (mLauncher.isGridOnlyOverviewEnabled() || !mLauncher.isTablet()) {
@@ -110,9 +106,6 @@
@Test
public void testSaveAppPairMenuItemDoesNotExistOnSingleTask() throws Exception {
- assumeTrue("App pairs feature is currently not enabled, no test needed",
- Flags.enableAppPairs());
-
startAppFast(CALCULATOR_APP_PACKAGE);
assertFalse("Save app pair menu item is erroneously appearing on single task",
diff --git a/res/drawable/ic_desktop_add.xml b/res/drawable/ic_desktop_add.xml
index fa5e0de..d31b04b 100644
--- a/res/drawable/ic_desktop_add.xml
+++ b/res/drawable/ic_desktop_add.xml
@@ -14,8 +14,8 @@
~ limitations under the License.
-->
<vector xmlns:android="http://schemas.android.com/apk/res/android"
- android:width="48dp"
- android:height="48dp"
+ android:width="24dp"
+ android:height="24dp"
android:viewportWidth="960"
android:viewportHeight="960">
<path
diff --git a/res/values-fa/strings.xml b/res/values-fa/strings.xml
index b62bbfa..c45d372 100644
--- a/res/values-fa/strings.xml
+++ b/res/values-fa/strings.xml
@@ -189,13 +189,13 @@
<string name="all_apps_work_tab" msgid="4884822796154055118">"کاری"</string>
<string name="work_profile_toggle_label" msgid="3081029915775481146">"نمایه کاری"</string>
<string name="work_profile_edu_work_apps" msgid="7895468576497746520">"برنامههای کاری نشاندار هستند و سرپرست فناوری اطلاعات میتواند آنها را ببیند"</string>
- <string name="work_profile_edu_accept" msgid="6069788082535149071">"متوجهام"</string>
+ <string name="work_profile_edu_accept" msgid="6069788082535149071">"متوجهم"</string>
<string name="work_apps_paused_title" msgid="3040901117349444598">"برنامههای کاری موقتاً متوقف شدهاند."</string>
<string name="work_apps_paused_info_body" msgid="1687828929959237477">"از برنامههای کاریتان اعلان دریافت نخواهید کرد"</string>
<string name="work_apps_paused_body" msgid="261634750995824906">"برنامههای کاری نمیتوانند برای شما اعلان ارسال کنند، از باتری استفاده کنند، یا به مکانتان دسترسی داشته باشند"</string>
<string name="work_apps_paused_telephony_unavailable_body" msgid="8358872357502756790">"از برنامههای کاریتان تماس تلفنی، پیام نوشتاری، یا اعلان دریافت نخواهید کرد"</string>
<string name="work_apps_paused_edu_banner" msgid="8872412121608402058">"برنامههای کاری نشاندار هستند و سرپرست فناوری اطلاعات میتواند آنها را ببیند."</string>
- <string name="work_apps_paused_edu_accept" msgid="6377476824357318532">"متوجهام"</string>
+ <string name="work_apps_paused_edu_accept" msgid="6377476824357318532">"متوجهم"</string>
<string name="work_apps_pause_btn_text" msgid="4669288269140620646">"توقف موقت برنامههای کاری"</string>
<string name="work_apps_enable_btn_text" msgid="1736198302467317371">"ازسرگیری"</string>
<string name="work_scheduler_button_content_description" msgid="917340740986764967">"برنامه زمانی برنامههای کاری"</string>
diff --git a/shared/src/com/android/launcher3/testing/shared/TestProtocol.java b/shared/src/com/android/launcher3/testing/shared/TestProtocol.java
index 5fcbbf1..0583d6d 100644
--- a/shared/src/com/android/launcher3/testing/shared/TestProtocol.java
+++ b/shared/src/com/android/launcher3/testing/shared/TestProtocol.java
@@ -169,7 +169,6 @@
public static final String PERMANENT_DIAG_TAG = "TaplTarget";
public static final String ICON_MISSING = "b/282963545";
public static final String REQUEST_FLAG_ENABLE_GRID_ONLY_OVERVIEW = "enable-grid-only-overview";
- public static final String REQUEST_FLAG_ENABLE_APP_PAIRS = "enable-app-pairs";
public static final String REQUEST_IS_RECENTS_WINDOW_ENABLED = "recents-window-enabled";
public static final String REQUEST_UNSTASH_BUBBLE_BAR_IF_STASHED =
diff --git a/src/com/android/launcher3/AbstractFloatingView.java b/src/com/android/launcher3/AbstractFloatingView.java
index 76c0f90..753b2e2 100644
--- a/src/com/android/launcher3/AbstractFloatingView.java
+++ b/src/com/android/launcher3/AbstractFloatingView.java
@@ -75,7 +75,8 @@
TYPE_ADD_TO_HOME_CONFIRMATION,
TYPE_TASKBAR_OVERLAY_PROXY,
TYPE_TASKBAR_PINNING_POPUP,
- TYPE_PIN_IME_POPUP
+ TYPE_PIN_IME_POPUP,
+ TYPE_ONE_GRID_MIGRATION_EDU,
})
@Retention(RetentionPolicy.SOURCE)
public @interface FloatingViewType {}
@@ -104,6 +105,7 @@
public static final int TYPE_TASKBAR_OVERLAY_PROXY = 1 << 20;
public static final int TYPE_TASKBAR_PINNING_POPUP = 1 << 21;
public static final int TYPE_PIN_IME_POPUP = 1 << 22;
+ public static final int TYPE_ONE_GRID_MIGRATION_EDU = 1 << 23;
public static final int TYPE_ALL = TYPE_FOLDER | TYPE_ACTION_POPUP
| TYPE_WIDGETS_BOTTOM_SHEET | TYPE_WIDGET_RESIZE_FRAME | TYPE_WIDGETS_FULL_SHEET
@@ -112,19 +114,19 @@
| TYPE_ICON_SURFACE | TYPE_DRAG_DROP_POPUP | TYPE_PIN_WIDGET_FROM_EXTERNAL_POPUP
| TYPE_TASKBAR_EDUCATION_DIALOG | TYPE_TASKBAR_ALL_APPS | TYPE_OPTIONS_POPUP_DIALOG
| TYPE_ADD_TO_HOME_CONFIRMATION | TYPE_TASKBAR_OVERLAY_PROXY
- | TYPE_TASKBAR_PINNING_POPUP | TYPE_PIN_IME_POPUP;
+ | TYPE_TASKBAR_PINNING_POPUP | TYPE_PIN_IME_POPUP | TYPE_ONE_GRID_MIGRATION_EDU;
// Type of popups which should be kept open during launcher rebind
public static final int TYPE_REBIND_SAFE = TYPE_WIDGETS_FULL_SHEET
| TYPE_WIDGETS_BOTTOM_SHEET | TYPE_ON_BOARD_POPUP | TYPE_DISCOVERY_BOUNCE
| TYPE_ALL_APPS_EDU | TYPE_ICON_SURFACE | TYPE_TASKBAR_EDUCATION_DIALOG
| TYPE_TASKBAR_ALL_APPS | TYPE_OPTIONS_POPUP_DIALOG | TYPE_TASKBAR_OVERLAY_PROXY
- | TYPE_PIN_IME_POPUP;
+ | TYPE_PIN_IME_POPUP | TYPE_ONE_GRID_MIGRATION_EDU;
/** Type of popups that should get exclusive accessibility focus. */
public static final int TYPE_ACCESSIBLE = TYPE_ALL & ~TYPE_DISCOVERY_BOUNCE & ~TYPE_LISTENER
& ~TYPE_ALL_APPS_EDU & ~TYPE_TASKBAR_ALL_APPS & ~TYPE_PIN_IME_POPUP
- & ~TYPE_WIDGET_RESIZE_FRAME;
+ & ~TYPE_WIDGET_RESIZE_FRAME & ~TYPE_ONE_GRID_MIGRATION_EDU & ~TYPE_ON_BOARD_POPUP;
// These view all have particular operation associated with swipe down interaction.
public static final int TYPE_STATUS_BAR_SWIPE_DOWN_DISALLOW = TYPE_WIDGETS_BOTTOM_SHEET |
diff --git a/src/com/android/launcher3/AutoInstallsLayout.java b/src/com/android/launcher3/AutoInstallsLayout.java
index 175d6ec..468cee8 100644
--- a/src/com/android/launcher3/AutoInstallsLayout.java
+++ b/src/com/android/launcher3/AutoInstallsLayout.java
@@ -261,6 +261,13 @@
return count;
}
+ private void addProfileId(XmlPullParser parser) {
+ Long profileId = mUserTypeToSerial.get(getAttributeValue(parser, ATTR_USER_TYPE));
+ if (profileId != null) {
+ mValues.put(Favorites.PROFILE_ID, profileId);
+ }
+ }
+
/**
* Parses container and screenId attribute from the current tag, and puts it in the out.
* @param out array of size 2.
@@ -305,10 +312,6 @@
convertToDistanceFromEnd(getAttributeValue(parser, ATTR_X), mColumnCount));
mValues.put(Favorites.CELLY,
convertToDistanceFromEnd(getAttributeValue(parser, ATTR_Y), mRowCount));
- Long profileId = mUserTypeToSerial.get(getAttributeValue(parser, ATTR_USER_TYPE));
- if (profileId != null) {
- mValues.put(Favorites.PROFILE_ID, profileId);
- }
TagParser tagParser = tagParserMap.get(parser.getName());
if (tagParser == null) {
@@ -382,7 +385,7 @@
public int parseAndAdd(XmlPullParser parser) {
final String packageName = getAttributeValue(parser, ATTR_PACKAGE_NAME);
final String className = getAttributeValue(parser, ATTR_CLASS_NAME);
-
+ addProfileId(parser);
if (!TextUtils.isEmpty(packageName) && !TextUtils.isEmpty(className)) {
ActivityInfo info;
try {
@@ -431,6 +434,7 @@
public int parseAndAdd(XmlPullParser parser) {
final String packageName = getAttributeValue(parser, ATTR_PACKAGE_NAME);
final String className = getAttributeValue(parser, ATTR_CLASS_NAME);
+ addProfileId(parser);
if (TextUtils.isEmpty(packageName) || TextUtils.isEmpty(className)) {
if (LOGD) Log.d(TAG, "Skipping invalid <favorite> with no component");
return -1;
@@ -452,7 +456,7 @@
public int parseAndAdd(XmlPullParser parser) {
final String packageName = getAttributeValue(parser, ATTR_PACKAGE_NAME);
final String shortcutId = getAttributeValue(parser, ATTR_SHORTCUT_ID);
-
+ addProfileId(parser);
try {
LauncherApps launcherApps = mContext.getSystemService(LauncherApps.class);
launcherApps.pinShortcuts(packageName, Collections.singletonList(shortcutId),
@@ -482,13 +486,13 @@
public ComponentName getComponentName(XmlPullParser parser) {
final String packageName = getAttributeValue(parser, ATTR_PACKAGE_NAME);
final String className = getAttributeValue(parser, ATTR_CLASS_NAME);
+ addProfileId(parser);
if (TextUtils.isEmpty(packageName) || TextUtils.isEmpty(className)) {
return null;
}
return new ComponentName(packageName, className);
}
-
@Override
public int parseAndAdd(XmlPullParser parser)
throws XmlPullParserException, IOException {
diff --git a/src/com/android/launcher3/BubbleTextView.java b/src/com/android/launcher3/BubbleTextView.java
index 9aa06bf..315096c 100644
--- a/src/com/android/launcher3/BubbleTextView.java
+++ b/src/com/android/launcher3/BubbleTextView.java
@@ -75,6 +75,7 @@
import com.android.launcher3.folder.FolderIcon;
import com.android.launcher3.graphics.IconShape;
import com.android.launcher3.graphics.PreloadIconDrawable;
+import com.android.launcher3.graphics.ThemeManager;
import com.android.launcher3.icons.DotRenderer;
import com.android.launcher3.icons.FastBitmapDrawable;
import com.android.launcher3.icons.IconCache.ItemInfoUpdateReceiver;
@@ -448,7 +449,9 @@
@VisibleForTesting
@UiThread
public void applyIconAndLabel(ItemInfoWithIcon info) {
- int flags = shouldUseTheme() ? FLAG_THEMED : 0;
+ ThemeManager themeManager = ThemeManager.INSTANCE.get(getContext());
+ int flags = (shouldUseTheme()
+ && themeManager.isMonoThemeEnabled()) ? FLAG_THEMED : 0;
// Remove badge on icons smaller than 48dp.
if (mHideBadge || mDisplay == DISPLAY_SEARCH_RESULT_SMALL) {
flags |= FLAG_NO_BADGE;
@@ -1236,6 +1239,7 @@
mIcon = icon;
if (mIcon != null) {
mIcon.setVisible(getWindowVisibility() == VISIBLE && isShown(), false);
+ mIcon.setHoverScaleEnabledForDisplay(mDisplay != DISPLAY_TASKBAR);
}
}
diff --git a/src/com/android/launcher3/DeviceProfile.java b/src/com/android/launcher3/DeviceProfile.java
index 9ebae9f..9f47da7 100644
--- a/src/com/android/launcher3/DeviceProfile.java
+++ b/src/com/android/launcher3/DeviceProfile.java
@@ -26,7 +26,6 @@
import static com.android.launcher3.Utilities.dpiFromPx;
import static com.android.launcher3.Utilities.pxFromSp;
import static com.android.launcher3.folder.ClippedFolderIconLayoutRule.ICON_OVERLAP_FACTOR;
-import static com.android.launcher3.icons.GraphicsUtils.getShapePath;
import static com.android.launcher3.icons.IconNormalizer.ICON_VISIBLE_AREA_FACTOR;
import static com.android.launcher3.testing.shared.ResourceUtils.INVALID_RESOURCE_HANDLE;
import static com.android.launcher3.testing.shared.ResourceUtils.pxFromDp;
@@ -53,6 +52,7 @@
import com.android.launcher3.CellLayout.ContainerType;
import com.android.launcher3.DevicePaddings.DevicePadding;
+import com.android.launcher3.graphics.IconShape;
import com.android.launcher3.icons.DotRenderer;
import com.android.launcher3.icons.IconNormalizer;
import com.android.launcher3.model.data.ItemInfo;
@@ -792,8 +792,7 @@
int leftRightSplitPortraitResId = Resources.getSystem().getIdentifier(
"config_leftRightSplitInPortrait", "bool", "android");
boolean allowLeftRightSplitInPortrait =
- com.android.wm.shell.Flags.enableLeftRightSplitInPortrait()
- && leftRightSplitPortraitResId > 0
+ leftRightSplitPortraitResId > 0
&& res.getBoolean(leftRightSplitPortraitResId);
if (allowLeftRightSplitInPortrait && isTablet) {
isLeftRightSplit = !isLandscape;
@@ -872,7 +871,9 @@
@NonNull Context context, int size, @NonNull SparseArray<DotRenderer> cache) {
DotRenderer renderer = cache.get(size);
if (renderer == null) {
- renderer = new DotRenderer(size, getShapePath(context, DEFAULT_DOT_SIZE),
+ renderer = new DotRenderer(
+ size,
+ IconShape.INSTANCE.get(context).getShapeOverridePath(DEFAULT_DOT_SIZE),
DEFAULT_DOT_SIZE);
cache.put(size, renderer);
}
diff --git a/src/com/android/launcher3/Workspace.java b/src/com/android/launcher3/Workspace.java
index 0d050b2..86c49d0 100644
--- a/src/com/android/launcher3/Workspace.java
+++ b/src/com/android/launcher3/Workspace.java
@@ -3572,7 +3572,7 @@
int nScreens = getChildCount();
int extraScreenId = mScreenOrder.indexOf(EXTRA_EMPTY_SCREEN_ID);
if (extraScreenId >= 0 && nScreens > 1) {
- if (page == extraScreenId) {
+ if (page == extraScreenId || (isTwoPanelEnabled() && page == extraScreenId + 1)) {
return getContext().getString(R.string.workspace_new_page);
}
nScreens--;
@@ -3584,6 +3584,11 @@
int panelCount = getPanelCount();
int currentPage = (page / panelCount) + 1;
int totalPages = nScreens / panelCount + nScreens % panelCount;
+
+ // When dragging, a blank screen is added. This increases the total page count, but we still
+ // want to describe the original page count where icons are currently pinned
+ if (extraScreenId > 0) totalPages--;
+
return getContext().getString(R.string.workspace_scroll_format, currentPage, totalPages);
}
diff --git a/src/com/android/launcher3/config/FeatureFlags.java b/src/com/android/launcher3/config/FeatureFlags.java
index 1fe42f7..44dcc06 100644
--- a/src/com/android/launcher3/config/FeatureFlags.java
+++ b/src/com/android/launcher3/config/FeatureFlags.java
@@ -144,15 +144,6 @@
return ENABLE_TASKBAR_PINNING.get() || Flags.enableTaskbarPinning();
}
- // Aconfig migration complete for ENABLE_APP_PAIRS.
- public static final BooleanFlag ENABLE_APP_PAIRS = getDebugFlag(274189428,
- "ENABLE_APP_PAIRS", DISABLED,
- "Enables the ability to create and save app pairs on the Home screen for easy"
- + " split screen launching.");
- public static boolean enableAppPairs() {
- return ENABLE_APP_PAIRS.get() || com.android.wm.shell.Flags.enableAppPairs();
- }
-
// TODO(Block 20): Clean up flags
// Aconfig migration complete for ENABLE_HOME_TRANSITION_LISTENER.
public static final BooleanFlag ENABLE_HOME_TRANSITION_LISTENER = getDebugFlag(306053414,
diff --git a/src/com/android/launcher3/dagger/LauncherBaseAppComponent.java b/src/com/android/launcher3/dagger/LauncherBaseAppComponent.java
index 5883a88..c3e3992 100644
--- a/src/com/android/launcher3/dagger/LauncherBaseAppComponent.java
+++ b/src/com/android/launcher3/dagger/LauncherBaseAppComponent.java
@@ -33,6 +33,7 @@
import com.android.launcher3.util.ScreenOnTracker;
import com.android.launcher3.util.SettingsCache;
import com.android.launcher3.util.VibratorWrapper;
+import com.android.launcher3.util.WallpaperColorHints;
import com.android.launcher3.util.window.RefreshRateTracker;
import com.android.launcher3.util.window.WindowManagerProxy;
import com.android.launcher3.widget.custom.CustomWidgetManager;
@@ -66,6 +67,7 @@
LauncherPrefs getLauncherPrefs();
ThemeManager getThemeManager();
DisplayController getDisplayController();
+ WallpaperColorHints getWallpaperColorHints();
/** Builder for LauncherBaseAppComponent. */
interface Builder {
diff --git a/src/com/android/launcher3/dragndrop/DragView.java b/src/com/android/launcher3/dragndrop/DragView.java
index f1b461b..9c82748 100644
--- a/src/com/android/launcher3/dragndrop/DragView.java
+++ b/src/com/android/launcher3/dragndrop/DragView.java
@@ -60,6 +60,7 @@
import com.android.app.animation.Interpolators;
import com.android.launcher3.R;
import com.android.launcher3.Utilities;
+import com.android.launcher3.graphics.IconShape;
import com.android.launcher3.icons.FastBitmapDrawable;
import com.android.launcher3.icons.LauncherIcons;
import com.android.launcher3.model.data.ItemInfo;
@@ -272,7 +273,7 @@
Rect shrunkBounds = new Rect(bounds);
Utilities.scaleRectAboutCenter(shrunkBounds, 0.98f);
adaptiveIcon.setBounds(shrunkBounds);
- final Path mask = adaptiveIcon.getIconMask();
+ final Path mask = IconShape.INSTANCE.get(getContext()).getShapeOverridePath(w);
mTranslateX = new SpringFloatValue(DragView.this,
w * AdaptiveIconDrawable.getExtraInsetFraction());
diff --git a/src/com/android/launcher3/graphics/IconShape.kt b/src/com/android/launcher3/graphics/IconShape.kt
index 2d2ee30..2c4d8e4 100644
--- a/src/com/android/launcher3/graphics/IconShape.kt
+++ b/src/com/android/launcher3/graphics/IconShape.kt
@@ -34,6 +34,7 @@
import android.view.View
import android.view.ViewOutlineProvider
import androidx.annotation.VisibleForTesting
+import androidx.core.graphics.PathParser
import androidx.graphics.shapes.CornerRounding
import androidx.graphics.shapes.Morph
import androidx.graphics.shapes.RoundedPolygon
@@ -65,7 +66,7 @@
constructor(
@ApplicationContext private val context: Context,
private val prefs: LauncherPrefs,
- themeManager: ThemeManager,
+ private val themeManager: ThemeManager,
lifeCycle: DaggerSingletonTracker,
) {
@@ -89,6 +90,17 @@
lifeCycle.addCloseable { themeManager.removeChangeListener(changeListener) }
}
+ fun getShapeOverridePath(pathSize: Float = DEFAULT_PATH_SIZE): Path {
+ val path = PathParser.createPathFromPathData(themeManager.iconState.iconMask)
+ if (pathSize != DEFAULT_PATH_SIZE) {
+ val matrix = Matrix()
+ val scale: Float = pathSize / DEFAULT_PATH_SIZE
+ matrix.setScale(scale, scale)
+ path.transform(matrix)
+ }
+ return path
+ }
+
/** Initializes the shape which is closest to the [AdaptiveIconDrawable] */
private fun pickBestShape(themeManager: ThemeManager): ShapeDelegate {
val drawable =
@@ -281,6 +293,7 @@
const val TAG = "IconShape"
const val KEY_ICON_SHAPE = "icon_shape"
+ const val DEFAULT_PATH_SIZE = 100f
const val AREA_CALC_SIZE = 1000
// .1% error margin
const val AREA_DIFF_THRESHOLD = AREA_CALC_SIZE * AREA_CALC_SIZE / 1000
diff --git a/src/com/android/launcher3/graphics/PreloadIconDrawable.java b/src/com/android/launcher3/graphics/PreloadIconDrawable.java
index 9fffcc1..3464e9b 100644
--- a/src/com/android/launcher3/graphics/PreloadIconDrawable.java
+++ b/src/com/android/launcher3/graphics/PreloadIconDrawable.java
@@ -40,7 +40,6 @@
import com.android.launcher3.anim.AnimatedFloat;
import com.android.launcher3.anim.AnimatorListeners;
import com.android.launcher3.icons.FastBitmapDrawable;
-import com.android.launcher3.icons.GraphicsUtils;
import com.android.launcher3.model.data.ItemInfoWithIcon;
import com.android.launcher3.util.Themes;
@@ -121,7 +120,8 @@
IconPalette.getPreloadProgressColor(context, info.bitmap.color),
getPreloadColors(context),
Utilities.isDarkTheme(context),
- GraphicsUtils.getShapePath(context, DEFAULT_PATH_SIZE));
+ IconShape.INSTANCE.get(context).getShapeOverridePath(DEFAULT_PATH_SIZE)
+ );
}
public PreloadIconDrawable(
diff --git a/src/com/android/launcher3/icons/CacheableShortcutInfo.kt b/src/com/android/launcher3/icons/CacheableShortcutInfo.kt
index a78da23..225e12f 100644
--- a/src/com/android/launcher3/icons/CacheableShortcutInfo.kt
+++ b/src/com/android/launcher3/icons/CacheableShortcutInfo.kt
@@ -112,7 +112,9 @@
?.let { d ->
li.createBadgedIconBitmap(
d,
- IconOptions().setExtractedColor(Themes.getColorAccent(context)),
+ IconOptions()
+ .setExtractedColor(Themes.getColorAccent(context))
+ .setSourceHint(getSourceHint(info, cache)),
)
} ?: BitmapInfo.LOW_RES_INFO
}
diff --git a/src/com/android/launcher3/icons/IconCache.java b/src/com/android/launcher3/icons/IconCache.java
index 88a60ea..9f99e8f 100644
--- a/src/com/android/launcher3/icons/IconCache.java
+++ b/src/com/android/launcher3/icons/IconCache.java
@@ -594,7 +594,8 @@
@VisibleForTesting
synchronized boolean isItemInDb(ComponentKey cacheKey) {
- return getEntryFromDBLocked(cacheKey, new CacheEntry(), DEFAULT_LOOKUP_FLAG);
+ return getEntryFromDBLocked(cacheKey, new CacheEntry(), DEFAULT_LOOKUP_FLAG,
+ LauncherActivityCachingLogic.INSTANCE);
}
/**
diff --git a/src/com/android/launcher3/model/WorkspaceItemProcessor.kt b/src/com/android/launcher3/model/WorkspaceItemProcessor.kt
index 0272bd9..dad78dd 100644
--- a/src/com/android/launcher3/model/WorkspaceItemProcessor.kt
+++ b/src/com/android/launcher3/model/WorkspaceItemProcessor.kt
@@ -32,7 +32,6 @@
import com.android.launcher3.LauncherAppState
import com.android.launcher3.LauncherSettings.Favorites
import com.android.launcher3.backuprestore.LauncherRestoreEventLogger.RestoreError
-import com.android.launcher3.config.FeatureFlags
import com.android.launcher3.icons.CacheableShortcutInfo
import com.android.launcher3.icons.cache.CacheLookupFlag.Companion.DEFAULT_LOOKUP_FLAG
import com.android.launcher3.logging.FileLog
@@ -409,12 +408,6 @@
// If we generated a placeholder Folder before this point, it may need to be replaced with
// an app pair.
if (c.itemType == Favorites.ITEM_TYPE_APP_PAIR && collection is FolderInfo) {
- if (!FeatureFlags.enableAppPairs()) {
- // If app pairs are not enabled, stop loading.
- Log.e(TAG, "app pairs flag is off, did not load app pair")
- return
- }
-
val folderInfo: FolderInfo = collection
val newAppPair = AppPairInfo()
// Move the placeholder's contents over to the new app pair.
diff --git a/src/com/android/launcher3/model/data/WorkspaceItemInfo.java b/src/com/android/launcher3/model/data/WorkspaceItemInfo.java
index 0a5dd62..9a7c347 100644
--- a/src/com/android/launcher3/model/data/WorkspaceItemInfo.java
+++ b/src/com/android/launcher3/model/data/WorkspaceItemInfo.java
@@ -36,6 +36,7 @@
import com.android.launcher3.shortcuts.ShortcutKey;
import com.android.launcher3.util.ApiWrapper;
import com.android.launcher3.util.ContentWriter;
+import com.android.wm.shell.shared.bubbles.BubbleAnythingFlagHelper;
import java.util.Arrays;
@@ -178,7 +179,7 @@
public void updateFromDeepShortcutInfo(@NonNull final ShortcutInfo shortcutInfo,
@NonNull final Context context) {
- if (com.android.wm.shell.Flags.enableBubbleAnything()) {
+ if (BubbleAnythingFlagHelper.enableCreateAnyBubble()) {
mShortcutInfo = shortcutInfo;
}
// {@link ShortcutInfo#getActivity} can change during an update. Recreate the intent
diff --git a/src/com/android/launcher3/popup/SystemShortcut.java b/src/com/android/launcher3/popup/SystemShortcut.java
index 329d9df..7e08c6e 100644
--- a/src/com/android/launcher3/popup/SystemShortcut.java
+++ b/src/com/android/launcher3/popup/SystemShortcut.java
@@ -431,7 +431,7 @@
&& !(itemInfo instanceof WorkspaceItemInfo)) {
return null;
}
- return new BubbleShortcut(activity, itemInfo, originalView);
+ return new BubbleShortcut<>(activity, itemInfo, originalView);
};
public interface BubbleActivityStarter {
@@ -439,7 +439,7 @@
void showShortcutBubble(ShortcutInfo info);
/** Tell SysUI to show the provided intent in a bubble. */
- void showAppBubble(Intent intent);
+ void showAppBubble(Intent intent, UserHandle user);
}
public static class BubbleShortcut<T extends ActivityContext> extends SystemShortcut<T> {
@@ -476,7 +476,7 @@
if (intent.getPackage() == null) {
intent.setPackage(mItemInfo.getTargetPackage());
}
- mStarter.showAppBubble(intent);
+ mStarter.showAppBubble(intent, mItemInfo.user);
} else {
Log.w(TAG, "unable to bubble, no intent: " + mItemInfo);
}
diff --git a/src/com/android/launcher3/testing/TestInformationHandler.java b/src/com/android/launcher3/testing/TestInformationHandler.java
index daa6e67..943a913 100644
--- a/src/com/android/launcher3/testing/TestInformationHandler.java
+++ b/src/com/android/launcher3/testing/TestInformationHandler.java
@@ -21,7 +21,6 @@
import static com.android.launcher3.allapps.AllAppsStore.DEFER_UPDATES_TEST;
import static com.android.launcher3.config.FeatureFlags.ENABLE_TASKBAR_NAVBAR_UNIFICATION;
import static com.android.launcher3.config.FeatureFlags.FOLDABLE_SINGLE_PAGE;
-import static com.android.launcher3.config.FeatureFlags.enableAppPairs;
import static com.android.launcher3.testing.shared.TestProtocol.TEST_INFO_RESPONSE_FIELD;
import static com.android.launcher3.util.Executors.MAIN_EXECUTOR;
import static com.android.launcher3.util.Executors.MODEL_EXECUTOR;
@@ -326,11 +325,6 @@
return response;
}
- case TestProtocol.REQUEST_FLAG_ENABLE_APP_PAIRS: {
- response.putBoolean(TestProtocol.TEST_INFO_RESPONSE_FIELD, enableAppPairs());
- return response;
- }
-
case TestProtocol.REQUEST_IS_RECENTS_WINDOW_ENABLED: {
response.putBoolean(TestProtocol.TEST_INFO_RESPONSE_FIELD,
enableLauncherOverviewInWindow() || enableFallbackOverviewInWindow());
diff --git a/src/com/android/launcher3/util/LayoutImportExportHelper.kt b/src/com/android/launcher3/util/LayoutImportExportHelper.kt
index 4033f60..0df9dae 100644
--- a/src/com/android/launcher3/util/LayoutImportExportHelper.kt
+++ b/src/com/android/launcher3/util/LayoutImportExportHelper.kt
@@ -136,4 +136,4 @@
)
}
}
-}
\ No newline at end of file
+}
diff --git a/src/com/android/launcher3/util/ViewPool.java b/src/com/android/launcher3/util/ViewPool.java
index 2fa8bf4..1627057 100644
--- a/src/com/android/launcher3/util/ViewPool.java
+++ b/src/com/android/launcher3/util/ViewPool.java
@@ -17,6 +17,7 @@
import android.content.Context;
import android.os.Handler;
+import android.util.Log;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
@@ -33,6 +34,7 @@
* During initialization, views are inflated on the background thread.
*/
public class ViewPool<T extends View & Reusable> {
+ private static final String TAG = ViewPool.class.getSimpleName();
private final Object[] mPool;
@@ -42,6 +44,9 @@
private int mCurrentSize = 0;
+ @Nullable
+ private Thread mViewPoolInitThread;
+
public ViewPool(Context context, @Nullable ViewGroup parent,
int layoutId, int maxSize, int initialSize) {
this(LayoutInflater.from(context).cloneInContext(context),
@@ -72,12 +77,15 @@
// Inflate views on a non looper thread. This allows us to catch errors like calling
// "new Handler()" in constructor easily.
- new Thread(() -> {
+ mViewPoolInitThread = new Thread(() -> {
for (int i = 0; i < initialSize; i++) {
T view = inflateNewView(inflater);
handler.post(() -> addToPool(view));
}
- }, "ViewPool-init").start();
+ Log.d(TAG, "initPool complete");
+ mViewPoolInitThread = null;
+ }, "ViewPool-init");
+ mViewPoolInitThread.start();
}
@UiThread
@@ -114,6 +122,12 @@
return (T) inflater.inflate(mLayoutId, mParent, false);
}
+ public void killOngoingInitializations() throws InterruptedException {
+ if (mViewPoolInitThread != null) {
+ mViewPoolInitThread.join();
+ }
+ }
+
/**
* Interface to indicate that a view is reusable
*/
diff --git a/src/com/android/launcher3/util/WallpaperColorHints.kt b/src/com/android/launcher3/util/WallpaperColorHints.kt
index 11d4c25..29fe31a 100644
--- a/src/com/android/launcher3/util/WallpaperColorHints.kt
+++ b/src/com/android/launcher3/util/WallpaperColorHints.kt
@@ -23,14 +23,21 @@
import android.content.Context
import androidx.annotation.MainThread
import androidx.annotation.VisibleForTesting
+import com.android.launcher3.dagger.ApplicationContext
+import com.android.launcher3.dagger.LauncherAppComponent
+import com.android.launcher3.dagger.LauncherAppSingleton
import com.android.launcher3.util.Executors.MAIN_EXECUTOR
import com.android.launcher3.util.Executors.UI_HELPER_EXECUTOR
+import javax.inject.Inject
/**
* This class caches the system's wallpaper color hints for use by other classes as a performance
* enhancer. It also centralizes all the WallpaperManager color hint code in one location.
*/
-class WallpaperColorHints(private val context: Context) : SafeCloseable {
+@LauncherAppSingleton
+class WallpaperColorHints
+@Inject
+constructor(@ApplicationContext private val context: Context, tracker: DaggerSingletonTracker) {
var hints: Int = 0
private set
@@ -38,7 +45,6 @@
get() = context.getSystemService(WallpaperManager::class.java)!!
private val onColorHintsChangedListeners = mutableListOf<OnColorHintListener>()
- private val onClose: SafeCloseable
init {
hints = wallpaperManager.getWallpaperColors(FLAG_SYSTEM)?.colorHints ?: 0
@@ -51,7 +57,7 @@
MAIN_EXECUTOR.handler,
)
}
- onClose = SafeCloseable {
+ tracker.addCloseable {
UI_HELPER_EXECUTOR.execute {
wallpaperManager.removeOnColorsChangedListener(onColorsChangedListener)
}
@@ -69,8 +75,6 @@
}
}
- override fun close() = onClose.close()
-
fun registerOnColorHintsChangedListener(listener: OnColorHintListener) {
onColorHintsChangedListeners.add(listener)
}
@@ -82,7 +86,7 @@
companion object {
@VisibleForTesting
@JvmField
- val INSTANCE = MainThreadInitializedObject { WallpaperColorHints(it) }
+ val INSTANCE = DaggerSingletonObject(LauncherAppComponent::getWallpaperColorHints)
@JvmStatic fun get(context: Context): WallpaperColorHints = INSTANCE.get(context)
}
diff --git a/tests/AndroidManifest.xml b/tests/AndroidManifest.xml
index 5cf96c8..862b862 100644
--- a/tests/AndroidManifest.xml
+++ b/tests/AndroidManifest.xml
@@ -29,6 +29,8 @@
android:functionalTest="false"
android:handleProfiling="false"
android:name="androidx.test.runner.AndroidJUnitRunner"
- android:targetPackage="com.android.launcher3" >
+ android:targetPackage="com.android.launcher3" >
+ <meta-data android:name="listener"
+ android:value="com.android.launcher3.util.GlobalTestRunListener"/>
</instrumentation>
</manifest>
diff --git a/tests/src/com/android/launcher3/allapps/FloatingMaskViewTest.kt b/tests/multivalentTests/src/com/android/launcher3/allapps/FloatingMaskViewTest.kt
similarity index 83%
rename from tests/src/com/android/launcher3/allapps/FloatingMaskViewTest.kt
rename to tests/multivalentTests/src/com/android/launcher3/allapps/FloatingMaskViewTest.kt
index cf03adc..7ddd859 100644
--- a/tests/src/com/android/launcher3/allapps/FloatingMaskViewTest.kt
+++ b/tests/multivalentTests/src/com/android/launcher3/allapps/FloatingMaskViewTest.kt
@@ -20,28 +20,33 @@
import android.view.ViewGroup.MarginLayoutParams
import android.widget.ImageView
import androidx.test.core.app.ApplicationProvider
+import androidx.test.ext.junit.runners.AndroidJUnit4
import com.android.launcher3.util.ActivityContextWrapper
import com.google.common.truth.Truth
import org.junit.Before
import org.junit.Test
+import org.junit.runner.RunWith
import org.mockito.Mock
import org.mockito.Mockito
import org.mockito.MockitoAnnotations
+@RunWith(AndroidJUnit4::class)
class FloatingMaskViewTest {
- @Mock
- private val mockAllAppsRecyclerView: AllAppsRecyclerView? = null
+ @Mock private val mockAllAppsRecyclerView: AllAppsRecyclerView? = null
- @Mock
- private val mockBottomBox: ImageView? = null
+ @Mock private val mockBottomBox: ImageView? = null
private var mVut: FloatingMaskView? = null
+
@Before
fun setUp() {
MockitoAnnotations.initMocks(this)
val context: Context = ActivityContextWrapper(ApplicationProvider.getApplicationContext())
mVut = FloatingMaskView(context)
- mVut!!.layoutParams = MarginLayoutParams(ViewGroup.LayoutParams.WRAP_CONTENT,
- ViewGroup.LayoutParams.WRAP_CONTENT)
+ mVut!!.layoutParams =
+ MarginLayoutParams(
+ ViewGroup.LayoutParams.WRAP_CONTENT,
+ ViewGroup.LayoutParams.WRAP_CONTENT,
+ )
}
@Test
diff --git a/tests/src/com/android/launcher3/allapps/PrivateProfileManagerTest.java b/tests/multivalentTests/src/com/android/launcher3/allapps/PrivateProfileManagerTest.java
similarity index 99%
rename from tests/src/com/android/launcher3/allapps/PrivateProfileManagerTest.java
rename to tests/multivalentTests/src/com/android/launcher3/allapps/PrivateProfileManagerTest.java
index 430e496..d757d10 100644
--- a/tests/src/com/android/launcher3/allapps/PrivateProfileManagerTest.java
+++ b/tests/multivalentTests/src/com/android/launcher3/allapps/PrivateProfileManagerTest.java
@@ -42,7 +42,7 @@
import android.os.UserHandle;
import android.os.UserManager;
-import androidx.test.runner.AndroidJUnit4;
+import androidx.test.ext.junit.runners.AndroidJUnit4;
import com.android.launcher3.logging.StatsLogManager;
import com.android.launcher3.pm.UserCache;
diff --git a/tests/src/com/android/launcher3/allapps/PrivateSpaceHeaderViewTest.java b/tests/multivalentTests/src/com/android/launcher3/allapps/PrivateSpaceHeaderViewTest.java
similarity index 98%
rename from tests/src/com/android/launcher3/allapps/PrivateSpaceHeaderViewTest.java
rename to tests/multivalentTests/src/com/android/launcher3/allapps/PrivateSpaceHeaderViewTest.java
index 398f9c5..23b00c2 100644
--- a/tests/src/com/android/launcher3/allapps/PrivateSpaceHeaderViewTest.java
+++ b/tests/multivalentTests/src/com/android/launcher3/allapps/PrivateSpaceHeaderViewTest.java
@@ -52,8 +52,8 @@
import android.widget.RelativeLayout;
import android.widget.TextView;
+import androidx.test.ext.junit.runners.AndroidJUnit4;
import androidx.test.filters.SmallTest;
-import androidx.test.runner.AndroidJUnit4;
import com.android.launcher3.R;
import com.android.launcher3.logging.StatsLogManager;
@@ -300,7 +300,7 @@
&& info.user.equals(MAIN_HANDLE));
int rows = (int) (ALL_APPS_HEIGHT - PS_HEADER_HEIGHT - HEADER_PROTECTION_HEIGHT);
- int position = rows * NUM_APP_COLS - (NUM_APP_COLS-1) + 1;
+ int position = rows * NUM_APP_COLS - (NUM_APP_COLS - 1) + 1;
assertEquals(NUM_PRIVATE_SPACE_APPS + MAIN_USER_APP_COUNT
+ CONTAINER_HEADER_ELEMENT_COUNT + VIEW_AT_END_OF_APP_LIST,
@@ -335,7 +335,7 @@
&& info.user.equals(MAIN_HANDLE));
int rows = (int) (ALL_APPS_HEIGHT - PS_HEADER_HEIGHT - HEADER_PROTECTION_HEIGHT) - 1;
- int position = rows * NUM_APP_COLS - (NUM_APP_COLS-1) + 1;
+ int position = rows * NUM_APP_COLS - (NUM_APP_COLS - 1) + 1;
assertEquals(NUM_PRIVATE_SPACE_APPS + MAIN_USER_APP_COUNT
+ CONTAINER_HEADER_ELEMENT_COUNT + VIEW_AT_END_OF_APP_LIST,
@@ -370,7 +370,7 @@
&& info.user.equals(MAIN_HANDLE));
int rows = (int) (ALL_APPS_HEIGHT - BIGGER_PS_HEADER_HEIGHT - HEADER_PROTECTION_HEIGHT);
- int position = rows * NUM_APP_COLS - (NUM_APP_COLS-1) + 1;
+ int position = rows * NUM_APP_COLS - (NUM_APP_COLS - 1) + 1;
assertEquals(NUM_PRIVATE_SPACE_APPS + MAIN_USER_APP_COUNT
+ CONTAINER_HEADER_ELEMENT_COUNT + VIEW_AT_END_OF_APP_LIST,
diff --git a/tests/src/com/android/launcher3/allapps/WorkUtilityViewTest.java b/tests/multivalentTests/src/com/android/launcher3/allapps/WorkUtilityViewTest.java
similarity index 100%
rename from tests/src/com/android/launcher3/allapps/WorkUtilityViewTest.java
rename to tests/multivalentTests/src/com/android/launcher3/allapps/WorkUtilityViewTest.java
diff --git a/tests/multivalentTests/src/com/android/launcher3/icons/mono/MonoIconThemeControllerTest.kt b/tests/multivalentTests/src/com/android/launcher3/icons/mono/MonoIconThemeControllerTest.kt
index 4af564e..12c14fb 100644
--- a/tests/multivalentTests/src/com/android/launcher3/icons/mono/MonoIconThemeControllerTest.kt
+++ b/tests/multivalentTests/src/com/android/launcher3/icons/mono/MonoIconThemeControllerTest.kt
@@ -16,9 +16,11 @@
package com.android.launcher3.icons.mono
+import android.content.ComponentName
import android.graphics.Color
import android.graphics.drawable.AdaptiveIconDrawable
import android.graphics.drawable.ColorDrawable
+import android.os.Process
import android.platform.test.annotations.DisableFlags
import android.platform.test.annotations.EnableFlags
import android.platform.test.flag.junit.SetFlagsRule
@@ -29,6 +31,9 @@
import com.android.launcher3.Flags
import com.android.launcher3.icons.BaseIconFactory
import com.android.launcher3.icons.BitmapInfo
+import com.android.launcher3.icons.SourceHint
+import com.android.launcher3.icons.cache.LauncherActivityCachingLogic
+import com.android.launcher3.util.ComponentKey
import com.android.launcher3.util.LauncherMultivalentJUnit.Companion.isRunningInRobolectric
import org.junit.Assert.assertNotNull
import org.junit.Assert.assertNull
@@ -45,6 +50,12 @@
private val iconFactory = BaseIconFactory(context, DisplayMetrics.DENSITY_MEDIUM, 30)
+ private val sourceHint =
+ SourceHint(
+ key = ComponentKey(ComponentName("a", "a"), Process.myUserHandle()),
+ logic = LauncherActivityCachingLogic,
+ )
+
@Test
fun `createThemedBitmap when mono drawable is present`() {
val icon = AdaptiveIconDrawable(ColorDrawable(Color.BLACK), null, ColorDrawable(Color.RED))
@@ -81,7 +92,8 @@
val themeBitmap =
MonoIconThemeController().createThemedBitmap(icon, iconInfo, iconFactory)!!
assertNotNull(
- MonoIconThemeController().decode(themeBitmap.serialize(), iconInfo, iconFactory)
+ MonoIconThemeController()
+ .decode(themeBitmap.serialize(), iconInfo, iconFactory, sourceHint)
)
}
@@ -90,7 +102,10 @@
ensureBitmapSerializationSupported()
val icon = AdaptiveIconDrawable(ColorDrawable(Color.BLACK), null, ColorDrawable(Color.RED))
val iconInfo = iconFactory.createBadgedIconBitmap(icon)
- assertNull(MonoIconThemeController().decode(byteArrayOf(1, 1, 1, 1), iconInfo, iconFactory))
+ assertNull(
+ MonoIconThemeController()
+ .decode(byteArrayOf(1, 1, 1, 1), iconInfo, iconFactory, sourceHint)
+ )
}
@Test
diff --git a/tests/multivalentTests/src/com/android/launcher3/util/GlobalTestRunListener.java b/tests/multivalentTests/src/com/android/launcher3/util/GlobalTestRunListener.java
new file mode 100644
index 0000000..667f540
--- /dev/null
+++ b/tests/multivalentTests/src/com/android/launcher3/util/GlobalTestRunListener.java
@@ -0,0 +1,38 @@
+/*
+ * 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.launcher3.util;
+
+import org.junit.runner.Description;
+import org.junit.runner.notification.RunListener;
+import org.mockito.Mockito;
+
+public class GlobalTestRunListener extends RunListener {
+ /**
+ * See {@link RunListener#testFinished} which executes per atomic test.
+ * {@link RunListener#testSuiteFinished} which executes per test suite. Test suite = test class
+ * in this context.
+ * {@link RunListener#testRunFinished} which executes after everything (all test suites) is
+ * completed.
+ */
+ @Override
+ public void testSuiteFinished(Description description) throws Exception {
+ // This method runs after every test class and will clear mocks after every test class
+ // execution is completed.
+ Mockito.framework().clearInlineMocks();
+ super.testSuiteFinished(description);
+ }
+}
diff --git a/tests/src/com/android/launcher3/backuprestore/BackupAndRestoreDBSelectionTest.kt b/tests/src/com/android/launcher3/backuprestore/BackupAndRestoreDBSelectionTest.kt
index 38fad6b..1e54603 100644
--- a/tests/src/com/android/launcher3/backuprestore/BackupAndRestoreDBSelectionTest.kt
+++ b/tests/src/com/android/launcher3/backuprestore/BackupAndRestoreDBSelectionTest.kt
@@ -32,6 +32,7 @@
import com.android.launcher3.util.rule.BackAndRestoreRule
import com.android.launcher3.util.rule.setFlags
import org.junit.Before
+import org.junit.Ignore
import org.junit.Rule
import org.junit.Test
import org.junit.runner.RunWith
@@ -69,6 +70,7 @@
}
@Test
+ @Ignore("b/385147987")
fun oldDatabasesNotPresentAfterRestore() {
val dbController = ModelDbController(getInstrumentation().targetContext)
if (Flags.gridMigrationRefactor()) {
diff --git a/tests/src/com/android/launcher3/pm/InstallSessionHelperTest.kt b/tests/src/com/android/launcher3/pm/InstallSessionHelperTest.kt
index 94b2c7e..707c2c1 100644
--- a/tests/src/com/android/launcher3/pm/InstallSessionHelperTest.kt
+++ b/tests/src/com/android/launcher3/pm/InstallSessionHelperTest.kt
@@ -52,7 +52,7 @@
private val sandboxContext = spy(launcherModelHelper.sandboxContext)
private val packageManager = sandboxContext.packageManager
private val expectedAppPackage = "expectedAppPackage"
- private val expectedInstallerPackage = "expectedInstallerPackage"
+ private val expectedInstallerPackage = sandboxContext.packageName
private val mockPackageInstaller: PackageInstaller = mock()
private lateinit var installSessionHelper: InstallSessionHelper
@@ -61,7 +61,6 @@
@Before
fun setup() {
whenever(packageManager.packageInstaller).thenReturn(mockPackageInstaller)
- whenever(sandboxContext.packageName).thenReturn(expectedInstallerPackage)
launcherApps = sandboxContext.spyService(LauncherApps::class.java)
installSessionHelper = InstallSessionHelper(sandboxContext)
}
diff --git a/tests/tapl/com/android/launcher3/tapl/AppIconMenu.java b/tests/tapl/com/android/launcher3/tapl/AppIconMenu.java
index bbcc6a8..033cfb0 100644
--- a/tests/tapl/com/android/launcher3/tapl/AppIconMenu.java
+++ b/tests/tapl/com/android/launcher3/tapl/AppIconMenu.java
@@ -63,5 +63,12 @@
return new SplitScreenMenuItem(mLauncher, menuItem);
}
+ /** Returns the Bubble menu item. */
+ public BubbleMenuItem getBubbleMenuItem() {
+ final UiObject2 menuItem = mLauncher.waitForObjectInContainer(mDeepShortcutsContainer,
+ AppIcon.getMenuItemSelector("Bubble", mLauncher));
+ return new BubbleMenuItem(mLauncher, menuItem);
+ }
+
protected abstract AppIconMenuItem createMenuItem(UiObject2 menuItem);
}
diff --git a/tests/tapl/com/android/launcher3/tapl/BaseOverview.java b/tests/tapl/com/android/launcher3/tapl/BaseOverview.java
index b15afc1..ef72a0f 100644
--- a/tests/tapl/com/android/launcher3/tapl/BaseOverview.java
+++ b/tests/tapl/com/android/launcher3/tapl/BaseOverview.java
@@ -440,7 +440,7 @@
"Not expecting an actions bar: device is tablet and task is not centered");
return false;
}
- if (task.isGrouped() && (!mLauncher.isAppPairsEnabled() || !isTablet)) {
+ if (task.isGrouped() && !isTablet) {
testLogD(TAG, "Not expecting an actions bar: device is phone and task is split");
// Overview actions aren't visible for split screen tasks, except for save app pair
// button on tablets.
diff --git a/tests/tapl/com/android/launcher3/tapl/BubbleMenuItem.kt b/tests/tapl/com/android/launcher3/tapl/BubbleMenuItem.kt
new file mode 100644
index 0000000..77391f1
--- /dev/null
+++ b/tests/tapl/com/android/launcher3/tapl/BubbleMenuItem.kt
@@ -0,0 +1,42 @@
+/*
+ * 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.launcher3.tapl
+
+import androidx.test.uiautomator.UiObject2
+
+/**
+ * A class representing the Bubble menu item in the app long-press menu, which moves the app into a
+ * bubble.
+ */
+class BubbleMenuItem(
+ private val launcher: LauncherInstrumentation,
+ private val uiObject: UiObject2,
+) {
+
+ fun click() {
+ launcher.addContextLayer("want to create bubble from app long-press menu").use {
+ LauncherInstrumentation.log(
+ "clicking on bubble menu item ${uiObject.visibleCenter} in ${
+ launcher.getVisibleBounds(
+ uiObject
+ )
+ }"
+ )
+ launcher.clickLauncherObject(uiObject)
+ }
+ }
+}
diff --git a/tests/tapl/com/android/launcher3/tapl/LauncherInstrumentation.java b/tests/tapl/com/android/launcher3/tapl/LauncherInstrumentation.java
index 0d9f5ce..edca6dc 100644
--- a/tests/tapl/com/android/launcher3/tapl/LauncherInstrumentation.java
+++ b/tests/tapl/com/android/launcher3/tapl/LauncherInstrumentation.java
@@ -2015,11 +2015,6 @@
TestProtocol.TEST_INFO_RESPONSE_FIELD);
}
- boolean isAppPairsEnabled() {
- return getTestInfo(TestProtocol.REQUEST_FLAG_ENABLE_APP_PAIRS).getBoolean(
- TestProtocol.TEST_INFO_RESPONSE_FIELD);
- }
-
public void sendPointer(long downTime, long currentTime, int action, Point point,
GestureScope gestureScope) {
sendPointer(downTime, currentTime, action, point, gestureScope,
diff --git a/tests/tapl/com/android/launcher3/tapl/OverviewTask.java b/tests/tapl/com/android/launcher3/tapl/OverviewTask.java
index 70bfb60..2431ef5 100644
--- a/tests/tapl/com/android/launcher3/tapl/OverviewTask.java
+++ b/tests/tapl/com/android/launcher3/tapl/OverviewTask.java
@@ -157,6 +157,7 @@
}
boolean taskWasFocused = mLauncher.isTablet()
+ && !isDesktop()
&& getVisibleHeight() == mLauncher.getOverviewTaskSize().height();
List<Integer> originalTasksCenterX =
getCurrentTasksCenterXList().stream().sorted().toList();