Merge "Differentiate failed restores from failed grid migrations." into main
diff --git a/aconfig/launcher.aconfig b/aconfig/launcher.aconfig
index aafa1f6..c71b833 100644
--- a/aconfig/launcher.aconfig
+++ b/aconfig/launcher.aconfig
@@ -471,3 +471,24 @@
description: "Shows filtered set of widgets by default and an option to show all widgets in the widget picker"
bug: "356127021"
}
+
+flag {
+ name: "show_taskbar_pinning_popup_from_anywhere"
+ namespace: "launcher"
+ description: "Shows the pinning popup view after long-pressing or right-clicking anywhere on the pinned taskbar"
+ bug: "297325541"
+}
+
+flag {
+ name: "enable_launcher_overview_in_window"
+ namespace: "launcher"
+ description: "Enables launcher recents opening inside of a window instead of being hosted in launcher activity."
+ bug: "292269949"
+}
+
+flag {
+ name: "enforce_system_radius_for_app_widgets"
+ namespace: "launcher"
+ description: "Enforce system radius for widget corners instead of a separate 16.dp value"
+ bug: "370950552"
+}
diff --git a/quickstep/res/values-af/strings.xml b/quickstep/res/values-af/strings.xml
index 5cbe556..eac8043 100644
--- a/quickstep/res/values-af/strings.xml
+++ b/quickstep/res/values-af/strings.xml
@@ -22,8 +22,7 @@
<string name="recent_task_option_pin" msgid="7929860679018978258">"Speld vas"</string>
<string name="recent_task_option_freeform" msgid="48863056265284071">"Vormvry"</string>
<string name="recent_task_option_desktop" msgid="8280879717125435668">"Rekenaar"</string>
- <!-- no translation found for recent_task_option_external_display (4533840664313389484) -->
- <skip />
+ <string name="recent_task_option_external_display" msgid="4533840664313389484">"Skuif na eksterne skerm"</string>
<string name="recent_task_desktop" msgid="8081113562549637334">"Werkskerm"</string>
<string name="recents_empty_message" msgid="7040467240571714191">"Geen onlangse items nie"</string>
<string name="accessibility_app_usage_settings" msgid="6312864233673544149">"Programgebruikinstellings"</string>
@@ -156,6 +155,5 @@
<string name="bubble_bar_action_dismiss_all" msgid="3290722022983403060">"Maak almal toe"</string>
<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>
- <!-- no translation found for search_gesture_feature_title (1294044108313175306) -->
- <skip />
+ <string name="search_gesture_feature_title" msgid="1294044108313175306">"Omkring en Soek"</string>
</resources>
diff --git a/quickstep/res/values-am/strings.xml b/quickstep/res/values-am/strings.xml
index ce12f9d..b9ee381 100644
--- a/quickstep/res/values-am/strings.xml
+++ b/quickstep/res/values-am/strings.xml
@@ -22,8 +22,7 @@
<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>
- <!-- no translation found for recent_task_option_external_display (4533840664313389484) -->
- <skip />
+ <string name="recent_task_option_external_display" msgid="4533840664313389484">"ወደ ውጫዊ ማሳያ አንቀሳቅስ"</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>
@@ -156,6 +155,5 @@
<string name="bubble_bar_action_dismiss_all" msgid="3290722022983403060">"ሁሉንም አሰናብት"</string>
<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>
- <!-- no translation found for search_gesture_feature_title (1294044108313175306) -->
- <skip />
+ <string name="search_gesture_feature_title" msgid="1294044108313175306">"ለመፈለግ ክበብ"</string>
</resources>
diff --git a/quickstep/res/values-ar/strings.xml b/quickstep/res/values-ar/strings.xml
index 0f3a854..0d3825f 100644
--- a/quickstep/res/values-ar/strings.xml
+++ b/quickstep/res/values-ar/strings.xml
@@ -156,6 +156,5 @@
<string name="bubble_bar_action_dismiss_all" msgid="3290722022983403060">"إغلاق الكل"</string>
<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>
- <!-- no translation found for search_gesture_feature_title (1294044108313175306) -->
- <skip />
+ <string name="search_gesture_feature_title" msgid="1294044108313175306">"دائرة البحث"</string>
</resources>
diff --git a/quickstep/res/values-as/strings.xml b/quickstep/res/values-as/strings.xml
index 1d536e8..7599530 100644
--- a/quickstep/res/values-as/strings.xml
+++ b/quickstep/res/values-as/strings.xml
@@ -22,8 +22,7 @@
<string name="recent_task_option_pin" msgid="7929860679018978258">"পিন"</string>
<string name="recent_task_option_freeform" msgid="48863056265284071">"Freeform"</string>
<string name="recent_task_option_desktop" msgid="8280879717125435668">"ডেস্কটপ"</string>
- <!-- no translation found for recent_task_option_external_display (4533840664313389484) -->
- <skip />
+ <string name="recent_task_option_external_display" msgid="4533840664313389484">"বাহ্যিক ডিছপ্লে’লৈ নিয়ক"</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>
@@ -156,6 +155,5 @@
<string name="bubble_bar_action_dismiss_all" msgid="3290722022983403060">"সকলো অগ্ৰাহ্য কৰক"</string>
<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>
- <!-- no translation found for search_gesture_feature_title (1294044108313175306) -->
- <skip />
+ <string name="search_gesture_feature_title" msgid="1294044108313175306">"সন্ধান কৰিবৰ বাবে বৃত্ত"</string>
</resources>
diff --git a/quickstep/res/values-az/strings.xml b/quickstep/res/values-az/strings.xml
index 2e6337a..a87ed44 100644
--- a/quickstep/res/values-az/strings.xml
+++ b/quickstep/res/values-az/strings.xml
@@ -22,8 +22,7 @@
<string name="recent_task_option_pin" msgid="7929860679018978258">"Sancın"</string>
<string name="recent_task_option_freeform" msgid="48863056265284071">"Sərbəst rejim"</string>
<string name="recent_task_option_desktop" msgid="8280879717125435668">"Masaüstü"</string>
- <!-- no translation found for recent_task_option_external_display (4533840664313389484) -->
- <skip />
+ <string name="recent_task_option_external_display" msgid="4533840664313389484">"Xarici displeyə köçürün"</string>
<string name="recent_task_desktop" msgid="8081113562549637334">"Masaüstü"</string>
<string name="recents_empty_message" msgid="7040467240571714191">"Son elementlər yoxdur"</string>
<string name="accessibility_app_usage_settings" msgid="6312864233673544149">"Tətbiq istifadə ayarları"</string>
@@ -156,6 +155,5 @@
<string name="bubble_bar_action_dismiss_all" msgid="3290722022983403060">"Hamısını kənarlaşdırın"</string>
<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>
- <!-- no translation found for search_gesture_feature_title (1294044108313175306) -->
- <skip />
+ <string name="search_gesture_feature_title" msgid="1294044108313175306">"Dairəyə alaraq axtarın"</string>
</resources>
diff --git a/quickstep/res/values-b+sr+Latn/strings.xml b/quickstep/res/values-b+sr+Latn/strings.xml
index 93a8d48..cbcffdf 100644
--- a/quickstep/res/values-b+sr+Latn/strings.xml
+++ b/quickstep/res/values-b+sr+Latn/strings.xml
@@ -22,8 +22,7 @@
<string name="recent_task_option_pin" msgid="7929860679018978258">"Zakači"</string>
<string name="recent_task_option_freeform" msgid="48863056265284071">"Slobodni oblik"</string>
<string name="recent_task_option_desktop" msgid="8280879717125435668">"Računar"</string>
- <!-- no translation found for recent_task_option_external_display (4533840664313389484) -->
- <skip />
+ <string name="recent_task_option_external_display" msgid="4533840664313389484">"Premestite na spoljni ekran"</string>
<string name="recent_task_desktop" msgid="8081113562549637334">"Računari"</string>
<string name="recents_empty_message" msgid="7040467240571714191">"Nema nedavnih stavki"</string>
<string name="accessibility_app_usage_settings" msgid="6312864233673544149">"Podešavanja korišćenja aplikacije"</string>
@@ -156,6 +155,5 @@
<string name="bubble_bar_action_dismiss_all" msgid="3290722022983403060">"Odbaci sve"</string>
<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>
- <!-- no translation found for search_gesture_feature_title (1294044108313175306) -->
- <skip />
+ <string name="search_gesture_feature_title" msgid="1294044108313175306">"Pretraga zaokruživanjem"</string>
</resources>
diff --git a/quickstep/res/values-be/strings.xml b/quickstep/res/values-be/strings.xml
index 3f5a617..103e243 100644
--- a/quickstep/res/values-be/strings.xml
+++ b/quickstep/res/values-be/strings.xml
@@ -22,8 +22,7 @@
<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>
- <!-- no translation found for recent_task_option_external_display (4533840664313389484) -->
- <skip />
+ <string name="recent_task_option_external_display" msgid="4533840664313389484">"Перамясціць на знешні дысплэй"</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>
@@ -156,6 +155,5 @@
<string name="bubble_bar_action_dismiss_all" msgid="3290722022983403060">"Закрыць усе"</string>
<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>
- <!-- no translation found for search_gesture_feature_title (1294044108313175306) -->
- <skip />
+ <string name="search_gesture_feature_title" msgid="1294044108313175306">"Абвесці для пошуку"</string>
</resources>
diff --git a/quickstep/res/values-bg/strings.xml b/quickstep/res/values-bg/strings.xml
index adabb31..d624914 100644
--- a/quickstep/res/values-bg/strings.xml
+++ b/quickstep/res/values-bg/strings.xml
@@ -22,8 +22,7 @@
<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>
- <!-- no translation found for recent_task_option_external_display (4533840664313389484) -->
- <skip />
+ <string name="recent_task_option_external_display" msgid="4533840664313389484">"Преместване към външния екран"</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>
@@ -156,6 +155,5 @@
<string name="bubble_bar_action_dismiss_all" msgid="3290722022983403060">"Отхвърляне на всички"</string>
<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>
- <!-- no translation found for search_gesture_feature_title (1294044108313175306) -->
- <skip />
+ <string name="search_gesture_feature_title" msgid="1294044108313175306">"Търсене с ограждане"</string>
</resources>
diff --git a/quickstep/res/values-bn/strings.xml b/quickstep/res/values-bn/strings.xml
index 7d93d9b..c7bc2cf 100644
--- a/quickstep/res/values-bn/strings.xml
+++ b/quickstep/res/values-bn/strings.xml
@@ -22,8 +22,7 @@
<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>
- <!-- no translation found for recent_task_option_external_display (4533840664313389484) -->
- <skip />
+ <string name="recent_task_option_external_display" msgid="4533840664313389484">"এক্সটার্নাল ডিসপ্লেতে সরিয়ে নিয়ে যান"</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>
@@ -156,6 +155,5 @@
<string name="bubble_bar_action_dismiss_all" msgid="3290722022983403060">"সব বাতিল করুন"</string>
<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>
- <!-- no translation found for search_gesture_feature_title (1294044108313175306) -->
- <skip />
+ <string name="search_gesture_feature_title" msgid="1294044108313175306">"খোঁজার জন্য সার্কেল বানান"</string>
</resources>
diff --git a/quickstep/res/values-bs/strings.xml b/quickstep/res/values-bs/strings.xml
index 2ac0ab1..cea1921 100644
--- a/quickstep/res/values-bs/strings.xml
+++ b/quickstep/res/values-bs/strings.xml
@@ -22,8 +22,7 @@
<string name="recent_task_option_pin" msgid="7929860679018978258">"Zakači"</string>
<string name="recent_task_option_freeform" msgid="48863056265284071">"Slobodan oblik"</string>
<string name="recent_task_option_desktop" msgid="8280879717125435668">"Radna površina"</string>
- <!-- no translation found for recent_task_option_external_display (4533840664313389484) -->
- <skip />
+ <string name="recent_task_option_external_display" msgid="4533840664313389484">"Premještanje na vanjski ekran"</string>
<string name="recent_task_desktop" msgid="8081113562549637334">"Radna površina"</string>
<string name="recents_empty_message" msgid="7040467240571714191">"Nema nedavnih stavki"</string>
<string name="accessibility_app_usage_settings" msgid="6312864233673544149">"Postavke korištenja aplikacije"</string>
@@ -156,6 +155,5 @@
<string name="bubble_bar_action_dismiss_all" msgid="3290722022983403060">"Odbacivanje svega"</string>
<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>
- <!-- no translation found for search_gesture_feature_title (1294044108313175306) -->
- <skip />
+ <string name="search_gesture_feature_title" msgid="1294044108313175306">"Pretraživanje zaokruživanjem"</string>
</resources>
diff --git a/quickstep/res/values-ca/strings.xml b/quickstep/res/values-ca/strings.xml
index 1c27b08..e2352d7 100644
--- a/quickstep/res/values-ca/strings.xml
+++ b/quickstep/res/values-ca/strings.xml
@@ -22,8 +22,7 @@
<string name="recent_task_option_pin" msgid="7929860679018978258">"Fixa"</string>
<string name="recent_task_option_freeform" msgid="48863056265284071">"Format lliure"</string>
<string name="recent_task_option_desktop" msgid="8280879717125435668">"Escriptori"</string>
- <!-- no translation found for recent_task_option_external_display (4533840664313389484) -->
- <skip />
+ <string name="recent_task_option_external_display" msgid="4533840664313389484">"Mou a la pantalla externa"</string>
<string name="recent_task_desktop" msgid="8081113562549637334">"Escriptori"</string>
<string name="recents_empty_message" msgid="7040467240571714191">"No hi ha cap element recent"</string>
<string name="accessibility_app_usage_settings" msgid="6312864233673544149">"Configuració d\'ús d\'aplicacions"</string>
@@ -156,6 +155,5 @@
<string name="bubble_bar_action_dismiss_all" msgid="3290722022983403060">"Ignora-ho tot"</string>
<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>
- <!-- no translation found for search_gesture_feature_title (1294044108313175306) -->
- <skip />
+ <string name="search_gesture_feature_title" msgid="1294044108313175306">"Encercla per cercar"</string>
</resources>
diff --git a/quickstep/res/values-cs/strings.xml b/quickstep/res/values-cs/strings.xml
index 2f8d4b0..f868baa 100644
--- a/quickstep/res/values-cs/strings.xml
+++ b/quickstep/res/values-cs/strings.xml
@@ -22,8 +22,7 @@
<string name="recent_task_option_pin" msgid="7929860679018978258">"Připnout"</string>
<string name="recent_task_option_freeform" msgid="48863056265284071">"Neomezený režim"</string>
<string name="recent_task_option_desktop" msgid="8280879717125435668">"Počítač"</string>
- <!-- no translation found for recent_task_option_external_display (4533840664313389484) -->
- <skip />
+ <string name="recent_task_option_external_display" msgid="4533840664313389484">"Přesunout na externí displej"</string>
<string name="recent_task_desktop" msgid="8081113562549637334">"Počítač"</string>
<string name="recents_empty_message" msgid="7040467240571714191">"Žádné položky z nedávné doby"</string>
<string name="accessibility_app_usage_settings" msgid="6312864233673544149">"Nastavení využití aplikací"</string>
@@ -156,6 +155,5 @@
<string name="bubble_bar_action_dismiss_all" msgid="3290722022983403060">"Zavřít vše"</string>
<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>
- <!-- no translation found for search_gesture_feature_title (1294044108313175306) -->
- <skip />
+ <string name="search_gesture_feature_title" msgid="1294044108313175306">"Zakroužkuj a hledej"</string>
</resources>
diff --git a/quickstep/res/values-da/strings.xml b/quickstep/res/values-da/strings.xml
index 4684af2..07ab18b 100644
--- a/quickstep/res/values-da/strings.xml
+++ b/quickstep/res/values-da/strings.xml
@@ -22,8 +22,7 @@
<string name="recent_task_option_pin" msgid="7929860679018978258">"Fastgør"</string>
<string name="recent_task_option_freeform" msgid="48863056265284071">"Frit format"</string>
<string name="recent_task_option_desktop" msgid="8280879717125435668">"Computertilstand"</string>
- <!-- no translation found for recent_task_option_external_display (4533840664313389484) -->
- <skip />
+ <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="recents_empty_message" msgid="7040467240571714191">"Ingen nye elementer"</string>
<string name="accessibility_app_usage_settings" msgid="6312864233673544149">"Indstillinger for appforbrug"</string>
@@ -156,6 +155,5 @@
<string name="bubble_bar_action_dismiss_all" msgid="3290722022983403060">"Afvis alle"</string>
<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>
- <!-- no translation found for search_gesture_feature_title (1294044108313175306) -->
- <skip />
+ <string name="search_gesture_feature_title" msgid="1294044108313175306">"Circle to Search"</string>
</resources>
diff --git a/quickstep/res/values-de/strings.xml b/quickstep/res/values-de/strings.xml
index 155abb4..f70e408 100644
--- a/quickstep/res/values-de/strings.xml
+++ b/quickstep/res/values-de/strings.xml
@@ -22,8 +22,7 @@
<string name="recent_task_option_pin" msgid="7929860679018978258">"Fixieren"</string>
<string name="recent_task_option_freeform" msgid="48863056265284071">"Freeform-Modus"</string>
<string name="recent_task_option_desktop" msgid="8280879717125435668">"Desktopmodus"</string>
- <!-- no translation found for recent_task_option_external_display (4533840664313389484) -->
- <skip />
+ <string name="recent_task_option_external_display" msgid="4533840664313389484">"Auf externes Display verschieben"</string>
<string name="recent_task_desktop" msgid="8081113562549637334">"Desktopmodus"</string>
<string name="recents_empty_message" msgid="7040467240571714191">"Keine kürzlich verwendeten Elemente"</string>
<string name="accessibility_app_usage_settings" msgid="6312864233673544149">"Einstellungen zur App-Nutzung"</string>
@@ -156,6 +155,5 @@
<string name="bubble_bar_action_dismiss_all" msgid="3290722022983403060">"Alle schließen"</string>
<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>
- <!-- no translation found for search_gesture_feature_title (1294044108313175306) -->
- <skip />
+ <string name="search_gesture_feature_title" msgid="1294044108313175306">"Circle to Search"</string>
</resources>
diff --git a/quickstep/res/values-el/strings.xml b/quickstep/res/values-el/strings.xml
index 39e8916..d7ff2ad 100644
--- a/quickstep/res/values-el/strings.xml
+++ b/quickstep/res/values-el/strings.xml
@@ -22,8 +22,7 @@
<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>
- <!-- no translation found for recent_task_option_external_display (4533840664313389484) -->
- <skip />
+ <string name="recent_task_option_external_display" msgid="4533840664313389484">"Μετακίνηση σε εξωτερική οθόνη"</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>
@@ -156,6 +155,5 @@
<string name="bubble_bar_action_dismiss_all" msgid="3290722022983403060">"Παράβλεψη όλων"</string>
<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>
- <!-- no translation found for search_gesture_feature_title (1294044108313175306) -->
- <skip />
+ <string name="search_gesture_feature_title" msgid="1294044108313175306">"Κυκλώστε για αναζήτηση"</string>
</resources>
diff --git a/quickstep/res/values-en-rAU/strings.xml b/quickstep/res/values-en-rAU/strings.xml
index bc73bfe..6b81b05 100644
--- a/quickstep/res/values-en-rAU/strings.xml
+++ b/quickstep/res/values-en-rAU/strings.xml
@@ -22,8 +22,7 @@
<string name="recent_task_option_pin" msgid="7929860679018978258">"Pin"</string>
<string name="recent_task_option_freeform" msgid="48863056265284071">"Freeform"</string>
<string name="recent_task_option_desktop" msgid="8280879717125435668">"Desktop"</string>
- <!-- no translation found for recent_task_option_external_display (4533840664313389484) -->
- <skip />
+ <string name="recent_task_option_external_display" msgid="4533840664313389484">"Move to external display"</string>
<string name="recent_task_desktop" msgid="8081113562549637334">"Desktop"</string>
<string name="recents_empty_message" msgid="7040467240571714191">"No recent items"</string>
<string name="accessibility_app_usage_settings" msgid="6312864233673544149">"App usage settings"</string>
@@ -156,6 +155,5 @@
<string name="bubble_bar_action_dismiss_all" msgid="3290722022983403060">"Dismiss all"</string>
<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>
- <!-- no translation found for search_gesture_feature_title (1294044108313175306) -->
- <skip />
+ <string name="search_gesture_feature_title" msgid="1294044108313175306">"Circle to Search"</string>
</resources>
diff --git a/quickstep/res/values-en-rGB/strings.xml b/quickstep/res/values-en-rGB/strings.xml
index bc73bfe..6b81b05 100644
--- a/quickstep/res/values-en-rGB/strings.xml
+++ b/quickstep/res/values-en-rGB/strings.xml
@@ -22,8 +22,7 @@
<string name="recent_task_option_pin" msgid="7929860679018978258">"Pin"</string>
<string name="recent_task_option_freeform" msgid="48863056265284071">"Freeform"</string>
<string name="recent_task_option_desktop" msgid="8280879717125435668">"Desktop"</string>
- <!-- no translation found for recent_task_option_external_display (4533840664313389484) -->
- <skip />
+ <string name="recent_task_option_external_display" msgid="4533840664313389484">"Move to external display"</string>
<string name="recent_task_desktop" msgid="8081113562549637334">"Desktop"</string>
<string name="recents_empty_message" msgid="7040467240571714191">"No recent items"</string>
<string name="accessibility_app_usage_settings" msgid="6312864233673544149">"App usage settings"</string>
@@ -156,6 +155,5 @@
<string name="bubble_bar_action_dismiss_all" msgid="3290722022983403060">"Dismiss all"</string>
<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>
- <!-- no translation found for search_gesture_feature_title (1294044108313175306) -->
- <skip />
+ <string name="search_gesture_feature_title" msgid="1294044108313175306">"Circle to Search"</string>
</resources>
diff --git a/quickstep/res/values-en-rIN/strings.xml b/quickstep/res/values-en-rIN/strings.xml
index bc73bfe..6b81b05 100644
--- a/quickstep/res/values-en-rIN/strings.xml
+++ b/quickstep/res/values-en-rIN/strings.xml
@@ -22,8 +22,7 @@
<string name="recent_task_option_pin" msgid="7929860679018978258">"Pin"</string>
<string name="recent_task_option_freeform" msgid="48863056265284071">"Freeform"</string>
<string name="recent_task_option_desktop" msgid="8280879717125435668">"Desktop"</string>
- <!-- no translation found for recent_task_option_external_display (4533840664313389484) -->
- <skip />
+ <string name="recent_task_option_external_display" msgid="4533840664313389484">"Move to external display"</string>
<string name="recent_task_desktop" msgid="8081113562549637334">"Desktop"</string>
<string name="recents_empty_message" msgid="7040467240571714191">"No recent items"</string>
<string name="accessibility_app_usage_settings" msgid="6312864233673544149">"App usage settings"</string>
@@ -156,6 +155,5 @@
<string name="bubble_bar_action_dismiss_all" msgid="3290722022983403060">"Dismiss all"</string>
<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>
- <!-- no translation found for search_gesture_feature_title (1294044108313175306) -->
- <skip />
+ <string name="search_gesture_feature_title" msgid="1294044108313175306">"Circle to Search"</string>
</resources>
diff --git a/quickstep/res/values-es-rUS/strings.xml b/quickstep/res/values-es-rUS/strings.xml
index 25bbba2..57333f4 100644
--- a/quickstep/res/values-es-rUS/strings.xml
+++ b/quickstep/res/values-es-rUS/strings.xml
@@ -22,8 +22,7 @@
<string name="recent_task_option_pin" msgid="7929860679018978258">"Fijar"</string>
<string name="recent_task_option_freeform" msgid="48863056265284071">"Formato libre"</string>
<string name="recent_task_option_desktop" msgid="8280879717125435668">"Escritorio"</string>
- <!-- no translation found for recent_task_option_external_display (4533840664313389484) -->
- <skip />
+ <string name="recent_task_option_external_display" msgid="4533840664313389484">"Mover a pantalla externa"</string>
<string name="recent_task_desktop" msgid="8081113562549637334">"Computadoras"</string>
<string name="recents_empty_message" msgid="7040467240571714191">"No hay elementos recientes"</string>
<string name="accessibility_app_usage_settings" msgid="6312864233673544149">"Configuración de uso de la app"</string>
@@ -156,6 +155,5 @@
<string name="bubble_bar_action_dismiss_all" msgid="3290722022983403060">"Descartar todo"</string>
<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>
- <!-- no translation found for search_gesture_feature_title (1294044108313175306) -->
- <skip />
+ <string name="search_gesture_feature_title" msgid="1294044108313175306">"Busca con un círculo"</string>
</resources>
diff --git a/quickstep/res/values-es/strings.xml b/quickstep/res/values-es/strings.xml
index a4d7a8b..8355a88 100644
--- a/quickstep/res/values-es/strings.xml
+++ b/quickstep/res/values-es/strings.xml
@@ -22,8 +22,7 @@
<string name="recent_task_option_pin" msgid="7929860679018978258">"Fijar"</string>
<string name="recent_task_option_freeform" msgid="48863056265284071">"Formato libre"</string>
<string name="recent_task_option_desktop" msgid="8280879717125435668">"Escritorio"</string>
- <!-- no translation found for recent_task_option_external_display (4533840664313389484) -->
- <skip />
+ <string name="recent_task_option_external_display" msgid="4533840664313389484">"Mover a pantalla externa"</string>
<string name="recent_task_desktop" msgid="8081113562549637334">"Ordenador"</string>
<string name="recents_empty_message" msgid="7040467240571714191">"No hay nada reciente"</string>
<string name="accessibility_app_usage_settings" msgid="6312864233673544149">"Ajustes de uso de la aplicación"</string>
@@ -156,6 +155,5 @@
<string name="bubble_bar_action_dismiss_all" msgid="3290722022983403060">"Cerrar todo"</string>
<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>
- <!-- no translation found for search_gesture_feature_title (1294044108313175306) -->
- <skip />
+ <string name="search_gesture_feature_title" msgid="1294044108313175306">"Rodea para buscar"</string>
</resources>
diff --git a/quickstep/res/values-et/strings.xml b/quickstep/res/values-et/strings.xml
index 63d4d2f..6192e81 100644
--- a/quickstep/res/values-et/strings.xml
+++ b/quickstep/res/values-et/strings.xml
@@ -22,8 +22,7 @@
<string name="recent_task_option_pin" msgid="7929860679018978258">"Kinnita"</string>
<string name="recent_task_option_freeform" msgid="48863056265284071">"Vabavorm"</string>
<string name="recent_task_option_desktop" msgid="8280879717125435668">"Lauaarvuti režiim"</string>
- <!-- no translation found for recent_task_option_external_display (4533840664313389484) -->
- <skip />
+ <string name="recent_task_option_external_display" msgid="4533840664313389484">"Liikuge välisele ekraanile"</string>
<string name="recent_task_desktop" msgid="8081113562549637334">"Töölaud"</string>
<string name="recents_empty_message" msgid="7040467240571714191">"Hiljutisi üksusi pole"</string>
<string name="accessibility_app_usage_settings" msgid="6312864233673544149">"Rakenduse kasutuse seaded"</string>
@@ -156,6 +155,5 @@
<string name="bubble_bar_action_dismiss_all" msgid="3290722022983403060">"Loobu kõigist"</string>
<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>
- <!-- no translation found for search_gesture_feature_title (1294044108313175306) -->
- <skip />
+ <string name="search_gesture_feature_title" msgid="1294044108313175306">"Ring otsimiseks"</string>
</resources>
diff --git a/quickstep/res/values-eu/strings.xml b/quickstep/res/values-eu/strings.xml
index 3c0698c..de19f15 100644
--- a/quickstep/res/values-eu/strings.xml
+++ b/quickstep/res/values-eu/strings.xml
@@ -22,8 +22,7 @@
<string name="recent_task_option_pin" msgid="7929860679018978258">"Ainguratu"</string>
<string name="recent_task_option_freeform" msgid="48863056265284071">"Modu librea"</string>
<string name="recent_task_option_desktop" msgid="8280879717125435668">"Ordenagailua"</string>
- <!-- no translation found for recent_task_option_external_display (4533840664313389484) -->
- <skip />
+ <string name="recent_task_option_external_display" msgid="4533840664313389484">"Eraman kanpoko pantailara"</string>
<string name="recent_task_desktop" msgid="8081113562549637334">"Mahaigaina"</string>
<string name="recents_empty_message" msgid="7040467240571714191">"Ez dago azkenaldi honetako ezer"</string>
<string name="accessibility_app_usage_settings" msgid="6312864233673544149">"Aplikazioen erabileraren ezarpenak"</string>
@@ -156,6 +155,5 @@
<string name="bubble_bar_action_dismiss_all" msgid="3290722022983403060">"Baztertu guztiak"</string>
<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>
- <!-- no translation found for search_gesture_feature_title (1294044108313175306) -->
- <skip />
+ <string name="search_gesture_feature_title" msgid="1294044108313175306">"Inguratu bilatzeko"</string>
</resources>
diff --git a/quickstep/res/values-fa/strings.xml b/quickstep/res/values-fa/strings.xml
index 8d5d15e..bc14f0b 100644
--- a/quickstep/res/values-fa/strings.xml
+++ b/quickstep/res/values-fa/strings.xml
@@ -22,8 +22,7 @@
<string name="recent_task_option_pin" msgid="7929860679018978258">"پین"</string>
<string name="recent_task_option_freeform" msgid="48863056265284071">"Freeform"</string>
<string name="recent_task_option_desktop" msgid="8280879717125435668">"حالت رایانه"</string>
- <!-- no translation found for recent_task_option_external_display (4533840664313389484) -->
- <skip />
+ <string name="recent_task_option_external_display" msgid="4533840664313389484">"انتقال به نمایشگر خارجی"</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>
@@ -156,6 +155,5 @@
<string name="bubble_bar_action_dismiss_all" msgid="3290722022983403060">"رد کردن همه"</string>
<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>
- <!-- no translation found for search_gesture_feature_title (1294044108313175306) -->
- <skip />
+ <string name="search_gesture_feature_title" msgid="1294044108313175306">"حلقه جستجو"</string>
</resources>
diff --git a/quickstep/res/values-fi/strings.xml b/quickstep/res/values-fi/strings.xml
index 10ea9ee..10e4699 100644
--- a/quickstep/res/values-fi/strings.xml
+++ b/quickstep/res/values-fi/strings.xml
@@ -22,8 +22,7 @@
<string name="recent_task_option_pin" msgid="7929860679018978258">"Kiinnitä"</string>
<string name="recent_task_option_freeform" msgid="48863056265284071">"Vapaamuotoinen"</string>
<string name="recent_task_option_desktop" msgid="8280879717125435668">"Tietokone"</string>
- <!-- no translation found for recent_task_option_external_display (4533840664313389484) -->
- <skip />
+ <string name="recent_task_option_external_display" msgid="4533840664313389484">"Siirrä ulkoiselle näytölle"</string>
<string name="recent_task_desktop" msgid="8081113562549637334">"Tietokone"</string>
<string name="recents_empty_message" msgid="7040467240571714191">"Ei viimeaikaisia kohteita"</string>
<string name="accessibility_app_usage_settings" msgid="6312864233673544149">"Sovelluksen käyttöasetukset"</string>
@@ -156,6 +155,5 @@
<string name="bubble_bar_action_dismiss_all" msgid="3290722022983403060">"Hylkää kaikki"</string>
<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>
- <!-- no translation found for search_gesture_feature_title (1294044108313175306) -->
- <skip />
+ <string name="search_gesture_feature_title" msgid="1294044108313175306">"Circle to Search"</string>
</resources>
diff --git a/quickstep/res/values-fr-rCA/strings.xml b/quickstep/res/values-fr-rCA/strings.xml
index b624b4f..746bf50 100644
--- a/quickstep/res/values-fr-rCA/strings.xml
+++ b/quickstep/res/values-fr-rCA/strings.xml
@@ -22,8 +22,7 @@
<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>
- <!-- no translation found for recent_task_option_external_display (4533840664313389484) -->
- <skip />
+ <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="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>
@@ -156,6 +155,5 @@
<string name="bubble_bar_action_dismiss_all" msgid="3290722022983403060">"Tout ignorer"</string>
<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>
- <!-- no translation found for search_gesture_feature_title (1294044108313175306) -->
- <skip />
+ <string name="search_gesture_feature_title" msgid="1294044108313175306">"Encercler et rechercher"</string>
</resources>
diff --git a/quickstep/res/values-fr/strings.xml b/quickstep/res/values-fr/strings.xml
index 3f61d65..6d2fba2 100644
--- a/quickstep/res/values-fr/strings.xml
+++ b/quickstep/res/values-fr/strings.xml
@@ -22,8 +22,7 @@
<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>
- <!-- no translation found for recent_task_option_external_display (4533840664313389484) -->
- <skip />
+ <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="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>
@@ -156,6 +155,5 @@
<string name="bubble_bar_action_dismiss_all" msgid="3290722022983403060">"Tout fermer"</string>
<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>
- <!-- no translation found for search_gesture_feature_title (1294044108313175306) -->
- <skip />
+ <string name="search_gesture_feature_title" msgid="1294044108313175306">"Entourer pour chercher"</string>
</resources>
diff --git a/quickstep/res/values-gl/strings.xml b/quickstep/res/values-gl/strings.xml
index d9d06a1..d9a78ee 100644
--- a/quickstep/res/values-gl/strings.xml
+++ b/quickstep/res/values-gl/strings.xml
@@ -22,8 +22,7 @@
<string name="recent_task_option_pin" msgid="7929860679018978258">"Fixar"</string>
<string name="recent_task_option_freeform" msgid="48863056265284071">"Forma libre"</string>
<string name="recent_task_option_desktop" msgid="8280879717125435668">"Escritorio"</string>
- <!-- no translation found for recent_task_option_external_display (4533840664313389484) -->
- <skip />
+ <string name="recent_task_option_external_display" msgid="4533840664313389484">"Mover á pantalla externa"</string>
<string name="recent_task_desktop" msgid="8081113562549637334">"Ordenador"</string>
<string name="recents_empty_message" msgid="7040467240571714191">"Non hai elementos recentes"</string>
<string name="accessibility_app_usage_settings" msgid="6312864233673544149">"Configuración do uso de aplicacións"</string>
@@ -156,6 +155,5 @@
<string name="bubble_bar_action_dismiss_all" msgid="3290722022983403060">"Pechar todo"</string>
<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>
- <!-- no translation found for search_gesture_feature_title (1294044108313175306) -->
- <skip />
+ <string name="search_gesture_feature_title" msgid="1294044108313175306">"Rodear para buscar"</string>
</resources>
diff --git a/quickstep/res/values-gu/strings.xml b/quickstep/res/values-gu/strings.xml
index 7716d4d..1bdcaa1 100644
--- a/quickstep/res/values-gu/strings.xml
+++ b/quickstep/res/values-gu/strings.xml
@@ -22,8 +22,7 @@
<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>
- <!-- no translation found for recent_task_option_external_display (4533840664313389484) -->
- <skip />
+ <string name="recent_task_option_external_display" msgid="4533840664313389484">"બાહ્ય ડિસ્પ્લે પર ખસેડો"</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>
@@ -156,6 +155,5 @@
<string name="bubble_bar_action_dismiss_all" msgid="3290722022983403060">"તમામ છોડી દો"</string>
<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>
- <!-- no translation found for search_gesture_feature_title (1294044108313175306) -->
- <skip />
+ <string name="search_gesture_feature_title" msgid="1294044108313175306">"શોધવા માટે વર્તુળ દોરો"</string>
</resources>
diff --git a/quickstep/res/values-hi/strings.xml b/quickstep/res/values-hi/strings.xml
index 02e23ec..e97aa78 100644
--- a/quickstep/res/values-hi/strings.xml
+++ b/quickstep/res/values-hi/strings.xml
@@ -22,8 +22,7 @@
<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>
- <!-- no translation found for recent_task_option_external_display (4533840664313389484) -->
- <skip />
+ <string name="recent_task_option_external_display" msgid="4533840664313389484">"बाहरी डिसप्ले पर जाएं"</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>
@@ -156,6 +155,5 @@
<string name="bubble_bar_action_dismiss_all" msgid="3290722022983403060">"सभी खारिज करें"</string>
<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>
- <!-- no translation found for search_gesture_feature_title (1294044108313175306) -->
- <skip />
+ <string name="search_gesture_feature_title" msgid="1294044108313175306">"सर्कल बनाकर ढूंढें"</string>
</resources>
diff --git a/quickstep/res/values-hr/strings.xml b/quickstep/res/values-hr/strings.xml
index a742c01..c350bc5 100644
--- a/quickstep/res/values-hr/strings.xml
+++ b/quickstep/res/values-hr/strings.xml
@@ -22,8 +22,7 @@
<string name="recent_task_option_pin" msgid="7929860679018978258">"Prikvači"</string>
<string name="recent_task_option_freeform" msgid="48863056265284071">"Slobodni oblik"</string>
<string name="recent_task_option_desktop" msgid="8280879717125435668">"Računalo"</string>
- <!-- no translation found for recent_task_option_external_display (4533840664313389484) -->
- <skip />
+ <string name="recent_task_option_external_display" msgid="4533840664313389484">"Premještanje na vanjski zaslon"</string>
<string name="recent_task_desktop" msgid="8081113562549637334">"Radna površina"</string>
<string name="recents_empty_message" msgid="7040467240571714191">"Nema nedavnih stavki"</string>
<string name="accessibility_app_usage_settings" msgid="6312864233673544149">"Postavke upotrebe aplikacija"</string>
@@ -156,6 +155,5 @@
<string name="bubble_bar_action_dismiss_all" msgid="3290722022983403060">"Odbaci sve"</string>
<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>
- <!-- no translation found for search_gesture_feature_title (1294044108313175306) -->
- <skip />
+ <string name="search_gesture_feature_title" msgid="1294044108313175306">"Zaokružite i potražite"</string>
</resources>
diff --git a/quickstep/res/values-hu/strings.xml b/quickstep/res/values-hu/strings.xml
index 439d6ed..ea29620 100644
--- a/quickstep/res/values-hu/strings.xml
+++ b/quickstep/res/values-hu/strings.xml
@@ -22,8 +22,7 @@
<string name="recent_task_option_pin" msgid="7929860679018978258">"Kitűzés"</string>
<string name="recent_task_option_freeform" msgid="48863056265284071">"Szabad forma"</string>
<string name="recent_task_option_desktop" msgid="8280879717125435668">"Asztali"</string>
- <!-- no translation found for recent_task_option_external_display (4533840664313389484) -->
- <skip />
+ <string name="recent_task_option_external_display" msgid="4533840664313389484">"Áthelyezés külső kijelzőre"</string>
<string name="recent_task_desktop" msgid="8081113562549637334">"Asztali"</string>
<string name="recents_empty_message" msgid="7040467240571714191">"Nincsenek mostanában használt elemek"</string>
<string name="accessibility_app_usage_settings" msgid="6312864233673544149">"Alkalmazáshasználati beállítások"</string>
@@ -156,6 +155,5 @@
<string name="bubble_bar_action_dismiss_all" msgid="3290722022983403060">"Az összes elvetése"</string>
<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>
- <!-- no translation found for search_gesture_feature_title (1294044108313175306) -->
- <skip />
+ <string name="search_gesture_feature_title" msgid="1294044108313175306">"Bekarikázással keresés"</string>
</resources>
diff --git a/quickstep/res/values-hy/strings.xml b/quickstep/res/values-hy/strings.xml
index 87681c0..14d715d 100644
--- a/quickstep/res/values-hy/strings.xml
+++ b/quickstep/res/values-hy/strings.xml
@@ -22,8 +22,7 @@
<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>
- <!-- no translation found for recent_task_option_external_display (4533840664313389484) -->
- <skip />
+ <string name="recent_task_option_external_display" msgid="4533840664313389484">"Տեղափոխել արտաքին էկրան"</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>
@@ -156,6 +155,5 @@
<string name="bubble_bar_action_dismiss_all" msgid="3290722022983403060">"Փակել բոլորը"</string>
<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>
- <!-- no translation found for search_gesture_feature_title (1294044108313175306) -->
- <skip />
+ <string name="search_gesture_feature_title" msgid="1294044108313175306">"Շրջագծել որոնելու համար"</string>
</resources>
diff --git a/quickstep/res/values-in/strings.xml b/quickstep/res/values-in/strings.xml
index 119ed6b..e1400a9 100644
--- a/quickstep/res/values-in/strings.xml
+++ b/quickstep/res/values-in/strings.xml
@@ -22,8 +22,7 @@
<string name="recent_task_option_pin" msgid="7929860679018978258">"Sematkan"</string>
<string name="recent_task_option_freeform" msgid="48863056265284071">"Format bebas"</string>
<string name="recent_task_option_desktop" msgid="8280879717125435668">"Desktop"</string>
- <!-- no translation found for recent_task_option_external_display (4533840664313389484) -->
- <skip />
+ <string name="recent_task_option_external_display" msgid="4533840664313389484">"Pindahkan ke layar eksternal"</string>
<string name="recent_task_desktop" msgid="8081113562549637334">"Desktop"</string>
<string name="recents_empty_message" msgid="7040467240571714191">"Tidak ada item yang baru dibuka"</string>
<string name="accessibility_app_usage_settings" msgid="6312864233673544149">"Setelan penggunaan aplikasi"</string>
@@ -156,6 +155,5 @@
<string name="bubble_bar_action_dismiss_all" msgid="3290722022983403060">"Tutup semua"</string>
<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>
- <!-- no translation found for search_gesture_feature_title (1294044108313175306) -->
- <skip />
+ <string name="search_gesture_feature_title" msgid="1294044108313175306">"Lingkari untuk Menelusuri"</string>
</resources>
diff --git a/quickstep/res/values-is/strings.xml b/quickstep/res/values-is/strings.xml
index 68f4656..bf2a211 100644
--- a/quickstep/res/values-is/strings.xml
+++ b/quickstep/res/values-is/strings.xml
@@ -22,8 +22,7 @@
<string name="recent_task_option_pin" msgid="7929860679018978258">"Festa"</string>
<string name="recent_task_option_freeform" msgid="48863056265284071">"Frjálst snið"</string>
<string name="recent_task_option_desktop" msgid="8280879717125435668">"Tölva"</string>
- <!-- no translation found for recent_task_option_external_display (4533840664313389484) -->
- <skip />
+ <string name="recent_task_option_external_display" msgid="4533840664313389484">"Færa í annað tæki"</string>
<string name="recent_task_desktop" msgid="8081113562549637334">"Tölva"</string>
<string name="recents_empty_message" msgid="7040467240571714191">"Engin nýleg atriði"</string>
<string name="accessibility_app_usage_settings" msgid="6312864233673544149">"Notkunarstillingar forrits"</string>
@@ -156,6 +155,5 @@
<string name="bubble_bar_action_dismiss_all" msgid="3290722022983403060">"Hunsa allt"</string>
<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>
- <!-- no translation found for search_gesture_feature_title (1294044108313175306) -->
- <skip />
+ <string name="search_gesture_feature_title" msgid="1294044108313175306">"Circle to Search"</string>
</resources>
diff --git a/quickstep/res/values-it/strings.xml b/quickstep/res/values-it/strings.xml
index 0498c4e..af77be4 100644
--- a/quickstep/res/values-it/strings.xml
+++ b/quickstep/res/values-it/strings.xml
@@ -22,8 +22,7 @@
<string name="recent_task_option_pin" msgid="7929860679018978258">"Blocca su schermo"</string>
<string name="recent_task_option_freeform" msgid="48863056265284071">"Forma libera"</string>
<string name="recent_task_option_desktop" msgid="8280879717125435668">"Desktop"</string>
- <!-- no translation found for recent_task_option_external_display (4533840664313389484) -->
- <skip />
+ <string name="recent_task_option_external_display" msgid="4533840664313389484">"Sposta sul display esterno"</string>
<string name="recent_task_desktop" msgid="8081113562549637334">"Desktop"</string>
<string name="recents_empty_message" msgid="7040467240571714191">"Nessun elemento recente"</string>
<string name="accessibility_app_usage_settings" msgid="6312864233673544149">"Impostazioni di utilizzo delle app"</string>
@@ -156,6 +155,5 @@
<string name="bubble_bar_action_dismiss_all" msgid="3290722022983403060">"Ignora tutte"</string>
<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>
- <!-- no translation found for search_gesture_feature_title (1294044108313175306) -->
- <skip />
+ <string name="search_gesture_feature_title" msgid="1294044108313175306">"Cerchia e Cerca"</string>
</resources>
diff --git a/quickstep/res/values-iw/strings.xml b/quickstep/res/values-iw/strings.xml
index ad52560..ad26421 100644
--- a/quickstep/res/values-iw/strings.xml
+++ b/quickstep/res/values-iw/strings.xml
@@ -22,8 +22,7 @@
<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>
- <!-- no translation found for recent_task_option_external_display (4533840664313389484) -->
- <skip />
+ <string name="recent_task_option_external_display" msgid="4533840664313389484">"העברה למסך חיצוני"</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>
@@ -156,6 +155,5 @@
<string name="bubble_bar_action_dismiss_all" msgid="3290722022983403060">"ביטול של הכול"</string>
<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>
- <!-- no translation found for search_gesture_feature_title (1294044108313175306) -->
- <skip />
+ <string name="search_gesture_feature_title" msgid="1294044108313175306">"מקיפים ומחפשים"</string>
</resources>
diff --git a/quickstep/res/values-ja/strings.xml b/quickstep/res/values-ja/strings.xml
index 4cfe9ed..890959a 100644
--- a/quickstep/res/values-ja/strings.xml
+++ b/quickstep/res/values-ja/strings.xml
@@ -156,6 +156,5 @@
<string name="bubble_bar_action_dismiss_all" msgid="3290722022983403060">"すべて解除"</string>
<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>
- <!-- no translation found for search_gesture_feature_title (1294044108313175306) -->
- <skip />
+ <string name="search_gesture_feature_title" msgid="1294044108313175306">"かこって検索"</string>
</resources>
diff --git a/quickstep/res/values-ka/strings.xml b/quickstep/res/values-ka/strings.xml
index c02e9ad..1f877e9 100644
--- a/quickstep/res/values-ka/strings.xml
+++ b/quickstep/res/values-ka/strings.xml
@@ -22,8 +22,7 @@
<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>
- <!-- no translation found for recent_task_option_external_display (4533840664313389484) -->
- <skip />
+ <string name="recent_task_option_external_display" msgid="4533840664313389484">"გარე ეკრანზე გადასვლა"</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>
@@ -156,6 +155,5 @@
<string name="bubble_bar_action_dismiss_all" msgid="3290722022983403060">"ყველას დახურვა"</string>
<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>
- <!-- no translation found for search_gesture_feature_title (1294044108313175306) -->
- <skip />
+ <string name="search_gesture_feature_title" msgid="1294044108313175306">"ძიება წრის მოხაზვით"</string>
</resources>
diff --git a/quickstep/res/values-kk/strings.xml b/quickstep/res/values-kk/strings.xml
index 64b3e53..5fd172e 100644
--- a/quickstep/res/values-kk/strings.xml
+++ b/quickstep/res/values-kk/strings.xml
@@ -22,8 +22,7 @@
<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>
- <!-- no translation found for recent_task_option_external_display (4533840664313389484) -->
- <skip />
+ <string name="recent_task_option_external_display" msgid="4533840664313389484">"Сыртқы дисплейге ауыстыру"</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>
@@ -156,6 +155,5 @@
<string name="bubble_bar_action_dismiss_all" msgid="3290722022983403060">"Барлығын жабу"</string>
<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>
- <!-- no translation found for search_gesture_feature_title (1294044108313175306) -->
- <skip />
+ <string name="search_gesture_feature_title" msgid="1294044108313175306">"Қоршау арқылы іздеу"</string>
</resources>
diff --git a/quickstep/res/values-km/strings.xml b/quickstep/res/values-km/strings.xml
index d962ba5..4c8227e 100644
--- a/quickstep/res/values-km/strings.xml
+++ b/quickstep/res/values-km/strings.xml
@@ -22,8 +22,7 @@
<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>
- <!-- no translation found for recent_task_option_external_display (4533840664313389484) -->
- <skip />
+ <string name="recent_task_option_external_display" msgid="4533840664313389484">"ផ្លាស់ទីទៅផ្ទាំងអេក្រង់ខាងក្រៅ"</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>
@@ -156,6 +155,5 @@
<string name="bubble_bar_action_dismiss_all" msgid="3290722022983403060">"ច្រានចោលទាំងអស់"</string>
<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>
- <!-- no translation found for search_gesture_feature_title (1294044108313175306) -->
- <skip />
+ <string name="search_gesture_feature_title" msgid="1294044108313175306">"គូររង្វង់ដើម្បីស្វែងរក"</string>
</resources>
diff --git a/quickstep/res/values-kn/strings.xml b/quickstep/res/values-kn/strings.xml
index 3a05e21..afd53ac 100644
--- a/quickstep/res/values-kn/strings.xml
+++ b/quickstep/res/values-kn/strings.xml
@@ -22,8 +22,7 @@
<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>
- <!-- no translation found for recent_task_option_external_display (4533840664313389484) -->
- <skip />
+ <string name="recent_task_option_external_display" msgid="4533840664313389484">"ಬಾಹ್ಯ ಡಿಸ್ಪ್ಲೇಗೆ ಸರಿಸಿ"</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>
@@ -156,6 +155,5 @@
<string name="bubble_bar_action_dismiss_all" msgid="3290722022983403060">"ಎಲ್ಲವನ್ನು ವಜಾಗೊಳಿಸಿ"</string>
<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>
- <!-- no translation found for search_gesture_feature_title (1294044108313175306) -->
- <skip />
+ <string name="search_gesture_feature_title" msgid="1294044108313175306">"ಹುಡುಕಲು ಒಂದು ಸರ್ಕಲ್ ರಚಿಸಿ"</string>
</resources>
diff --git a/quickstep/res/values-ko/strings.xml b/quickstep/res/values-ko/strings.xml
index 6a7ba74..d602482 100644
--- a/quickstep/res/values-ko/strings.xml
+++ b/quickstep/res/values-ko/strings.xml
@@ -22,8 +22,7 @@
<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>
- <!-- no translation found for recent_task_option_external_display (4533840664313389484) -->
- <skip />
+ <string name="recent_task_option_external_display" msgid="4533840664313389484">"외부 디스플레이로 이동"</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>
@@ -156,6 +155,5 @@
<string name="bubble_bar_action_dismiss_all" msgid="3290722022983403060">"모두 닫기"</string>
<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>
- <!-- no translation found for search_gesture_feature_title (1294044108313175306) -->
- <skip />
+ <string name="search_gesture_feature_title" msgid="1294044108313175306">"서클 투 서치"</string>
</resources>
diff --git a/quickstep/res/values-ky/strings.xml b/quickstep/res/values-ky/strings.xml
index e92b920..e5fed79 100644
--- a/quickstep/res/values-ky/strings.xml
+++ b/quickstep/res/values-ky/strings.xml
@@ -22,8 +22,7 @@
<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>
- <!-- no translation found for recent_task_option_external_display (4533840664313389484) -->
- <skip />
+ <string name="recent_task_option_external_display" msgid="4533840664313389484">"Тышкы экранга жылдыруу"</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>
@@ -156,6 +155,5 @@
<string name="bubble_bar_action_dismiss_all" msgid="3290722022983403060">"Баарын четке кагуу"</string>
<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>
- <!-- no translation found for search_gesture_feature_title (1294044108313175306) -->
- <skip />
+ <string name="search_gesture_feature_title" msgid="1294044108313175306">"Тегеректеп издөө"</string>
</resources>
diff --git a/quickstep/res/values-lo/strings.xml b/quickstep/res/values-lo/strings.xml
index f45c8ce..2df1a49 100644
--- a/quickstep/res/values-lo/strings.xml
+++ b/quickstep/res/values-lo/strings.xml
@@ -22,8 +22,7 @@
<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>
- <!-- no translation found for recent_task_option_external_display (4533840664313389484) -->
- <skip />
+ <string name="recent_task_option_external_display" msgid="4533840664313389484">"ຍ້າຍໄປຫາຈໍສະແດງຜົນພາຍນອກ"</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>
@@ -156,6 +155,5 @@
<string name="bubble_bar_action_dismiss_all" msgid="3290722022983403060">"ປິດທັງໝົດ"</string>
<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>
- <!-- no translation found for search_gesture_feature_title (1294044108313175306) -->
- <skip />
+ <string name="search_gesture_feature_title" msgid="1294044108313175306">"ແຕ້ມວົງມົນເພື່ອຊອກຫາ"</string>
</resources>
diff --git a/quickstep/res/values-lt/strings.xml b/quickstep/res/values-lt/strings.xml
index c488859..1d29f57 100644
--- a/quickstep/res/values-lt/strings.xml
+++ b/quickstep/res/values-lt/strings.xml
@@ -22,8 +22,7 @@
<string name="recent_task_option_pin" msgid="7929860679018978258">"Prisegti"</string>
<string name="recent_task_option_freeform" msgid="48863056265284071">"Laisva forma"</string>
<string name="recent_task_option_desktop" msgid="8280879717125435668">"Stalinis kompiuteris"</string>
- <!-- no translation found for recent_task_option_external_display (4533840664313389484) -->
- <skip />
+ <string name="recent_task_option_external_display" msgid="4533840664313389484">"Perkelkite į išorinį ekraną"</string>
<string name="recent_task_desktop" msgid="8081113562549637334">"Stalinis kompiuteris"</string>
<string name="recents_empty_message" msgid="7040467240571714191">"Nėra jokių naujausių elementų"</string>
<string name="accessibility_app_usage_settings" msgid="6312864233673544149">"Programos naudojimo nustatymai"</string>
diff --git a/quickstep/res/values-lv/strings.xml b/quickstep/res/values-lv/strings.xml
index 23e64a7..805a598 100644
--- a/quickstep/res/values-lv/strings.xml
+++ b/quickstep/res/values-lv/strings.xml
@@ -22,8 +22,7 @@
<string name="recent_task_option_pin" msgid="7929860679018978258">"Piespraust"</string>
<string name="recent_task_option_freeform" msgid="48863056265284071">"Brīva forma"</string>
<string name="recent_task_option_desktop" msgid="8280879717125435668">"Dators"</string>
- <!-- no translation found for recent_task_option_external_display (4533840664313389484) -->
- <skip />
+ <string name="recent_task_option_external_display" msgid="4533840664313389484">"Pārvietošana uz ārējo displeju"</string>
<string name="recent_task_desktop" msgid="8081113562549637334">"Darbvirsma"</string>
<string name="recents_empty_message" msgid="7040467240571714191">"Nav nesenu vienumu."</string>
<string name="accessibility_app_usage_settings" msgid="6312864233673544149">"Lietotņu izmantošanas iestatījumi"</string>
@@ -156,6 +155,5 @@
<string name="bubble_bar_action_dismiss_all" msgid="3290722022983403060">"Nerādīt nevienu"</string>
<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>
- <!-- no translation found for search_gesture_feature_title (1294044108313175306) -->
- <skip />
+ <string name="search_gesture_feature_title" msgid="1294044108313175306">"Apvilkt un meklēt"</string>
</resources>
diff --git a/quickstep/res/values-mk/strings.xml b/quickstep/res/values-mk/strings.xml
index f0588e8..d5216a5 100644
--- a/quickstep/res/values-mk/strings.xml
+++ b/quickstep/res/values-mk/strings.xml
@@ -156,6 +156,5 @@
<string name="bubble_bar_action_dismiss_all" msgid="3290722022983403060">"Отфрли ги сите"</string>
<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>
- <!-- no translation found for search_gesture_feature_title (1294044108313175306) -->
- <skip />
+ <string name="search_gesture_feature_title" msgid="1294044108313175306">"Пребарување со заокружување"</string>
</resources>
diff --git a/quickstep/res/values-ml/strings.xml b/quickstep/res/values-ml/strings.xml
index 833090c..92cad89 100644
--- a/quickstep/res/values-ml/strings.xml
+++ b/quickstep/res/values-ml/strings.xml
@@ -22,8 +22,7 @@
<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>
- <!-- no translation found for recent_task_option_external_display (4533840664313389484) -->
- <skip />
+ <string name="recent_task_option_external_display" msgid="4533840664313389484">"ബാഹ്യ ഡിസ്പ്ലേയിലേക്ക് നീക്കുക"</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>
@@ -156,6 +155,5 @@
<string name="bubble_bar_action_dismiss_all" msgid="3290722022983403060">"എല്ലാം ഡിസ്മിസ് ചെയ്യുക"</string>
<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>
- <!-- no translation found for search_gesture_feature_title (1294044108313175306) -->
- <skip />
+ <string name="search_gesture_feature_title" msgid="1294044108313175306">"തിരയാൻ വട്ടം വരയ്ക്കൽ"</string>
</resources>
diff --git a/quickstep/res/values-mn/strings.xml b/quickstep/res/values-mn/strings.xml
index 100b8ed..539e104 100644
--- a/quickstep/res/values-mn/strings.xml
+++ b/quickstep/res/values-mn/strings.xml
@@ -22,8 +22,7 @@
<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>
- <!-- no translation found for recent_task_option_external_display (4533840664313389484) -->
- <skip />
+ <string name="recent_task_option_external_display" msgid="4533840664313389484">"Гадаад дэлгэц рүү зөөх"</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>
@@ -156,6 +155,5 @@
<string name="bubble_bar_action_dismiss_all" msgid="3290722022983403060">"Бүгдийг үл хэрэгсэх"</string>
<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>
- <!-- no translation found for search_gesture_feature_title (1294044108313175306) -->
- <skip />
+ <string name="search_gesture_feature_title" msgid="1294044108313175306">"Тойруулж зураад хай"</string>
</resources>
diff --git a/quickstep/res/values-mr/strings.xml b/quickstep/res/values-mr/strings.xml
index 870cf4e..dd2003f 100644
--- a/quickstep/res/values-mr/strings.xml
+++ b/quickstep/res/values-mr/strings.xml
@@ -22,8 +22,7 @@
<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>
- <!-- no translation found for recent_task_option_external_display (4533840664313389484) -->
- <skip />
+ <string name="recent_task_option_external_display" msgid="4533840664313389484">"बाह्य डिस्प्लेवर हलवा"</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>
@@ -156,6 +155,5 @@
<string name="bubble_bar_action_dismiss_all" msgid="3290722022983403060">"सर्व डिसमिस करा"</string>
<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>
- <!-- no translation found for search_gesture_feature_title (1294044108313175306) -->
- <skip />
+ <string name="search_gesture_feature_title" msgid="1294044108313175306">"शोधण्यासाठी वर्तुळ करा"</string>
</resources>
diff --git a/quickstep/res/values-ms/strings.xml b/quickstep/res/values-ms/strings.xml
index bed2fce..af388bc 100644
--- a/quickstep/res/values-ms/strings.xml
+++ b/quickstep/res/values-ms/strings.xml
@@ -22,8 +22,7 @@
<string name="recent_task_option_pin" msgid="7929860679018978258">"Semat"</string>
<string name="recent_task_option_freeform" msgid="48863056265284071">"Bentuk bebas"</string>
<string name="recent_task_option_desktop" msgid="8280879717125435668">"Desktop"</string>
- <!-- no translation found for recent_task_option_external_display (4533840664313389484) -->
- <skip />
+ <string name="recent_task_option_external_display" msgid="4533840664313389484">"Alihkan kepada paparan luaran"</string>
<string name="recent_task_desktop" msgid="8081113562549637334">"Desktop"</string>
<string name="recents_empty_message" msgid="7040467240571714191">"Tiada item terbaharu"</string>
<string name="accessibility_app_usage_settings" msgid="6312864233673544149">"Tetapan penggunaan apl"</string>
@@ -156,6 +155,5 @@
<string name="bubble_bar_action_dismiss_all" msgid="3290722022983403060">"Ketepikan semua"</string>
<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>
- <!-- no translation found for search_gesture_feature_title (1294044108313175306) -->
- <skip />
+ <string name="search_gesture_feature_title" msgid="1294044108313175306">"Bulatkan untuk Membuat Carian"</string>
</resources>
diff --git a/quickstep/res/values-my/strings.xml b/quickstep/res/values-my/strings.xml
index ae0f66d..55b65c8 100644
--- a/quickstep/res/values-my/strings.xml
+++ b/quickstep/res/values-my/strings.xml
@@ -22,8 +22,7 @@
<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>
- <!-- no translation found for recent_task_option_external_display (4533840664313389484) -->
- <skip />
+ <string name="recent_task_option_external_display" msgid="4533840664313389484">"ပြင်ပဖန်သားပြင်သို့ ရွှေ့ရန်"</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>
@@ -156,6 +155,5 @@
<string name="bubble_bar_action_dismiss_all" msgid="3290722022983403060">"အားလုံးကို ပယ်ရန်"</string>
<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>
- <!-- no translation found for search_gesture_feature_title (1294044108313175306) -->
- <skip />
+ <string name="search_gesture_feature_title" msgid="1294044108313175306">"ရှာရန် ကွက်၍ဝိုင်းလိုက်ပါ"</string>
</resources>
diff --git a/quickstep/res/values-nb/strings.xml b/quickstep/res/values-nb/strings.xml
index 1ce18c1..077bc0a 100644
--- a/quickstep/res/values-nb/strings.xml
+++ b/quickstep/res/values-nb/strings.xml
@@ -22,8 +22,7 @@
<string name="recent_task_option_pin" msgid="7929860679018978258">"Fest"</string>
<string name="recent_task_option_freeform" msgid="48863056265284071">"Fritt format"</string>
<string name="recent_task_option_desktop" msgid="8280879717125435668">"Skrivebord"</string>
- <!-- no translation found for recent_task_option_external_display (4533840664313389484) -->
- <skip />
+ <string name="recent_task_option_external_display" msgid="4533840664313389484">"Flytt til ekstern skjerm"</string>
<string name="recent_task_desktop" msgid="8081113562549637334">"Skrivebord"</string>
<string name="recents_empty_message" msgid="7040467240571714191">"Ingen nylige elementer"</string>
<string name="accessibility_app_usage_settings" msgid="6312864233673544149">"Innstillinger for appbruk"</string>
@@ -156,6 +155,5 @@
<string name="bubble_bar_action_dismiss_all" msgid="3290722022983403060">"Lukk alle"</string>
<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>
- <!-- no translation found for search_gesture_feature_title (1294044108313175306) -->
- <skip />
+ <string name="search_gesture_feature_title" msgid="1294044108313175306">"Circle to Search"</string>
</resources>
diff --git a/quickstep/res/values-ne/strings.xml b/quickstep/res/values-ne/strings.xml
index 1921fed..49d1664 100644
--- a/quickstep/res/values-ne/strings.xml
+++ b/quickstep/res/values-ne/strings.xml
@@ -22,8 +22,7 @@
<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>
- <!-- no translation found for recent_task_option_external_display (4533840664313389484) -->
- <skip />
+ <string name="recent_task_option_external_display" msgid="4533840664313389484">"सारेर बाह्य डिस्प्लेमा लैजानुहोस्"</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>
@@ -156,6 +155,5 @@
<string name="bubble_bar_action_dismiss_all" msgid="3290722022983403060">"सबै हटाउनुहोस्"</string>
<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>
- <!-- no translation found for search_gesture_feature_title (1294044108313175306) -->
- <skip />
+ <string name="search_gesture_feature_title" msgid="1294044108313175306">"खोज्न सर्कल बनाउनुहोस्"</string>
</resources>
diff --git a/quickstep/res/values-nl/strings.xml b/quickstep/res/values-nl/strings.xml
index 995d8d4..529516c 100644
--- a/quickstep/res/values-nl/strings.xml
+++ b/quickstep/res/values-nl/strings.xml
@@ -22,8 +22,7 @@
<string name="recent_task_option_pin" msgid="7929860679018978258">"Vastzetten"</string>
<string name="recent_task_option_freeform" msgid="48863056265284071">"Vrije vorm"</string>
<string name="recent_task_option_desktop" msgid="8280879717125435668">"Desktop"</string>
- <!-- no translation found for recent_task_option_external_display (4533840664313389484) -->
- <skip />
+ <string name="recent_task_option_external_display" msgid="4533840664313389484">"Verplaatsen naar extern scherm"</string>
<string name="recent_task_desktop" msgid="8081113562549637334">"Desktop"</string>
<string name="recents_empty_message" msgid="7040467240571714191">"Geen recente items"</string>
<string name="accessibility_app_usage_settings" msgid="6312864233673544149">"Instellingen voor app-gebruik"</string>
@@ -156,6 +155,5 @@
<string name="bubble_bar_action_dismiss_all" msgid="3290722022983403060">"Alles sluiten"</string>
<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>
- <!-- no translation found for search_gesture_feature_title (1294044108313175306) -->
- <skip />
+ <string name="search_gesture_feature_title" msgid="1294044108313175306">"Circle to Search"</string>
</resources>
diff --git a/quickstep/res/values-or/strings.xml b/quickstep/res/values-or/strings.xml
index 430058b..afc909d 100644
--- a/quickstep/res/values-or/strings.xml
+++ b/quickstep/res/values-or/strings.xml
@@ -22,8 +22,7 @@
<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>
- <!-- no translation found for recent_task_option_external_display (4533840664313389484) -->
- <skip />
+ <string name="recent_task_option_external_display" msgid="4533840664313389484">"ଏକ୍ସଟର୍ନଲ ଡିସପ୍ଲେକୁ ମୁଭ କରନ୍ତୁ"</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>
@@ -156,6 +155,5 @@
<string name="bubble_bar_action_dismiss_all" msgid="3290722022983403060">"ସବୁ ଖାରଜ କରନ୍ତୁ"</string>
<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>
- <!-- no translation found for search_gesture_feature_title (1294044108313175306) -->
- <skip />
+ <string name="search_gesture_feature_title" msgid="1294044108313175306">"ସର୍ଚ୍ଚ କରିବାକୁ ସର୍କଲ କରନ୍ତୁ"</string>
</resources>
diff --git a/quickstep/res/values-pa/strings.xml b/quickstep/res/values-pa/strings.xml
index d8d0907..69b33f9 100644
--- a/quickstep/res/values-pa/strings.xml
+++ b/quickstep/res/values-pa/strings.xml
@@ -22,8 +22,7 @@
<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>
- <!-- no translation found for recent_task_option_external_display (4533840664313389484) -->
- <skip />
+ <string name="recent_task_option_external_display" msgid="4533840664313389484">"ਬਾਹਰੀ ਡਿਸਪਲੇ \'ਤੇ ਜਾਓ"</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>
@@ -156,6 +155,5 @@
<string name="bubble_bar_action_dismiss_all" msgid="3290722022983403060">"ਸਭ ਖਾਰਜ ਕਰੋ"</string>
<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>
- <!-- no translation found for search_gesture_feature_title (1294044108313175306) -->
- <skip />
+ <string name="search_gesture_feature_title" msgid="1294044108313175306">"ਖੋਜਣ ਲਈ ਚੱਕਰ ਬਣਾਓ"</string>
</resources>
diff --git a/quickstep/res/values-pl/strings.xml b/quickstep/res/values-pl/strings.xml
index 957e5c4..88b5053 100644
--- a/quickstep/res/values-pl/strings.xml
+++ b/quickstep/res/values-pl/strings.xml
@@ -22,8 +22,7 @@
<string name="recent_task_option_pin" msgid="7929860679018978258">"Przypnij"</string>
<string name="recent_task_option_freeform" msgid="48863056265284071">"Tryb dowolny"</string>
<string name="recent_task_option_desktop" msgid="8280879717125435668">"Pulpit"</string>
- <!-- no translation found for recent_task_option_external_display (4533840664313389484) -->
- <skip />
+ <string name="recent_task_option_external_display" msgid="4533840664313389484">"Przenieś na wyświetlacz zewnętrzny"</string>
<string name="recent_task_desktop" msgid="8081113562549637334">"Pulpit"</string>
<string name="recents_empty_message" msgid="7040467240571714191">"Brak ostatnich elementów"</string>
<string name="accessibility_app_usage_settings" msgid="6312864233673544149">"Ustawienia użycia aplikacji"</string>
@@ -156,6 +155,5 @@
<string name="bubble_bar_action_dismiss_all" msgid="3290722022983403060">"Zamknij wszystkie"</string>
<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>
- <!-- no translation found for search_gesture_feature_title (1294044108313175306) -->
- <skip />
+ <string name="search_gesture_feature_title" msgid="1294044108313175306">"Zaznacz, aby wyszukać"</string>
</resources>
diff --git a/quickstep/res/values-pt-rPT/strings.xml b/quickstep/res/values-pt-rPT/strings.xml
index ca7cd58..84120a1 100644
--- a/quickstep/res/values-pt-rPT/strings.xml
+++ b/quickstep/res/values-pt-rPT/strings.xml
@@ -22,8 +22,7 @@
<string name="recent_task_option_pin" msgid="7929860679018978258">"Fixar"</string>
<string name="recent_task_option_freeform" msgid="48863056265284071">"Forma livre"</string>
<string name="recent_task_option_desktop" msgid="8280879717125435668">"Computador"</string>
- <!-- no translation found for recent_task_option_external_display (4533840664313389484) -->
- <skip />
+ <string name="recent_task_option_external_display" msgid="4533840664313389484">"Mover para o ecrã externo"</string>
<string name="recent_task_desktop" msgid="8081113562549637334">"Computador"</string>
<string name="recents_empty_message" msgid="7040467240571714191">"Nenhum item recente"</string>
<string name="accessibility_app_usage_settings" msgid="6312864233673544149">"Definições de utilização de aplicações"</string>
@@ -156,6 +155,5 @@
<string name="bubble_bar_action_dismiss_all" msgid="3290722022983403060">"Ignorar tudo"</string>
<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>
- <!-- no translation found for search_gesture_feature_title (1294044108313175306) -->
- <skip />
+ <string name="search_gesture_feature_title" msgid="1294044108313175306">"Circundar para Pesquisar"</string>
</resources>
diff --git a/quickstep/res/values-pt/strings.xml b/quickstep/res/values-pt/strings.xml
index aee1c8d..3238c99 100644
--- a/quickstep/res/values-pt/strings.xml
+++ b/quickstep/res/values-pt/strings.xml
@@ -22,8 +22,7 @@
<string name="recent_task_option_pin" msgid="7929860679018978258">"Fixar"</string>
<string name="recent_task_option_freeform" msgid="48863056265284071">"Forma livre"</string>
<string name="recent_task_option_desktop" msgid="8280879717125435668">"Modo área de trabalho"</string>
- <!-- no translation found for recent_task_option_external_display (4533840664313389484) -->
- <skip />
+ <string name="recent_task_option_external_display" msgid="4533840664313389484">"Mover para a tela externa"</string>
<string name="recent_task_desktop" msgid="8081113562549637334">"Computador"</string>
<string name="recents_empty_message" msgid="7040467240571714191">"Nenhum item recente"</string>
<string name="accessibility_app_usage_settings" msgid="6312864233673544149">"Configurações de uso do app"</string>
@@ -156,6 +155,5 @@
<string name="bubble_bar_action_dismiss_all" msgid="3290722022983403060">"Dispensar todos"</string>
<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>
- <!-- no translation found for search_gesture_feature_title (1294044108313175306) -->
- <skip />
+ <string name="search_gesture_feature_title" msgid="1294044108313175306">"Circule para pesquisar"</string>
</resources>
diff --git a/quickstep/res/values-ro/strings.xml b/quickstep/res/values-ro/strings.xml
index c05b85b..e6aad47 100644
--- a/quickstep/res/values-ro/strings.xml
+++ b/quickstep/res/values-ro/strings.xml
@@ -22,8 +22,7 @@
<string name="recent_task_option_pin" msgid="7929860679018978258">"Fixează"</string>
<string name="recent_task_option_freeform" msgid="48863056265284071">"Formă liberă"</string>
<string name="recent_task_option_desktop" msgid="8280879717125435668">"Desktop"</string>
- <!-- no translation found for recent_task_option_external_display (4533840664313389484) -->
- <skip />
+ <string name="recent_task_option_external_display" msgid="4533840664313389484">"Mută pe ecranul extern"</string>
<string name="recent_task_desktop" msgid="8081113562549637334">"Computer"</string>
<string name="recents_empty_message" msgid="7040467240571714191">"Niciun element recent"</string>
<string name="accessibility_app_usage_settings" msgid="6312864233673544149">"Setări de utilizare a aplicației"</string>
@@ -156,6 +155,5 @@
<string name="bubble_bar_action_dismiss_all" msgid="3290722022983403060">"Închide-le pe toate"</string>
<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>
- <!-- no translation found for search_gesture_feature_title (1294044108313175306) -->
- <skip />
+ <string name="search_gesture_feature_title" msgid="1294044108313175306">"Încercuiește și caută"</string>
</resources>
diff --git a/quickstep/res/values-ru/strings.xml b/quickstep/res/values-ru/strings.xml
index fca0a05..297ae02 100644
--- a/quickstep/res/values-ru/strings.xml
+++ b/quickstep/res/values-ru/strings.xml
@@ -22,8 +22,7 @@
<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>
- <!-- no translation found for recent_task_option_external_display (4533840664313389484) -->
- <skip />
+ <string name="recent_task_option_external_display" msgid="4533840664313389484">"Перенести на внешний дисплей"</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>
@@ -156,6 +155,5 @@
<string name="bubble_bar_action_dismiss_all" msgid="3290722022983403060">"Закрыть все"</string>
<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>
- <!-- no translation found for search_gesture_feature_title (1294044108313175306) -->
- <skip />
+ <string name="search_gesture_feature_title" msgid="1294044108313175306">"Обвести и найти"</string>
</resources>
diff --git a/quickstep/res/values-si/strings.xml b/quickstep/res/values-si/strings.xml
index cfbf1dd..2c7c672 100644
--- a/quickstep/res/values-si/strings.xml
+++ b/quickstep/res/values-si/strings.xml
@@ -22,8 +22,7 @@
<string name="recent_task_option_pin" msgid="7929860679018978258">"අමුණන්න"</string>
<string name="recent_task_option_freeform" msgid="48863056265284071">"Freeform"</string>
<string name="recent_task_option_desktop" msgid="8280879717125435668">"ඩෙස්ක්ටොපය"</string>
- <!-- no translation found for recent_task_option_external_display (4533840664313389484) -->
- <skip />
+ <string name="recent_task_option_external_display" msgid="4533840664313389484">"බාහිර සංදර්ශකය වෙත ගෙන යන්න"</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>
@@ -156,6 +155,5 @@
<string name="bubble_bar_action_dismiss_all" msgid="3290722022983403060">"සියල්ල ඉවතලන්න"</string>
<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>
- <!-- no translation found for search_gesture_feature_title (1294044108313175306) -->
- <skip />
+ <string name="search_gesture_feature_title" msgid="1294044108313175306">"සෙවීමට කවයසෙවීමට කවය අදින්න"</string>
</resources>
diff --git a/quickstep/res/values-sk/strings.xml b/quickstep/res/values-sk/strings.xml
index b3145de..638e88a 100644
--- a/quickstep/res/values-sk/strings.xml
+++ b/quickstep/res/values-sk/strings.xml
@@ -22,8 +22,7 @@
<string name="recent_task_option_pin" msgid="7929860679018978258">"Pripnúť"</string>
<string name="recent_task_option_freeform" msgid="48863056265284071">"Voľný režim"</string>
<string name="recent_task_option_desktop" msgid="8280879717125435668">"Počítač"</string>
- <!-- no translation found for recent_task_option_external_display (4533840664313389484) -->
- <skip />
+ <string name="recent_task_option_external_display" msgid="4533840664313389484">"Presunúť na externú obrazovku"</string>
<string name="recent_task_desktop" msgid="8081113562549637334">"Počítač"</string>
<string name="recents_empty_message" msgid="7040467240571714191">"Žiadne nedávne položky"</string>
<string name="accessibility_app_usage_settings" msgid="6312864233673544149">"Nastavenia využívania aplikácie"</string>
@@ -156,6 +155,5 @@
<string name="bubble_bar_action_dismiss_all" msgid="3290722022983403060">"Zavrieť všetko"</string>
<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>
- <!-- no translation found for search_gesture_feature_title (1294044108313175306) -->
- <skip />
+ <string name="search_gesture_feature_title" msgid="1294044108313175306">"Vyhľadávanie krúžením"</string>
</resources>
diff --git a/quickstep/res/values-sl/strings.xml b/quickstep/res/values-sl/strings.xml
index d72436a..30d2c03 100644
--- a/quickstep/res/values-sl/strings.xml
+++ b/quickstep/res/values-sl/strings.xml
@@ -22,8 +22,7 @@
<string name="recent_task_option_pin" msgid="7929860679018978258">"Pripni"</string>
<string name="recent_task_option_freeform" msgid="48863056265284071">"Prosta oblika"</string>
<string name="recent_task_option_desktop" msgid="8280879717125435668">"Namizni računalnik"</string>
- <!-- no translation found for recent_task_option_external_display (4533840664313389484) -->
- <skip />
+ <string name="recent_task_option_external_display" msgid="4533840664313389484">"Premik v zunanji zaslon"</string>
<string name="recent_task_desktop" msgid="8081113562549637334">"Namizni način"</string>
<string name="recents_empty_message" msgid="7040467240571714191">"Ni nedavnih elementov"</string>
<string name="accessibility_app_usage_settings" msgid="6312864233673544149">"Nastavitve uporabe aplikacij"</string>
@@ -156,6 +155,5 @@
<string name="bubble_bar_action_dismiss_all" msgid="3290722022983403060">"Opusti vse"</string>
<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>
- <!-- no translation found for search_gesture_feature_title (1294044108313175306) -->
- <skip />
+ <string name="search_gesture_feature_title" msgid="1294044108313175306">"Iskanje z obkroževanjem"</string>
</resources>
diff --git a/quickstep/res/values-sq/strings.xml b/quickstep/res/values-sq/strings.xml
index 30ba61d..b4b6711 100644
--- a/quickstep/res/values-sq/strings.xml
+++ b/quickstep/res/values-sq/strings.xml
@@ -22,8 +22,7 @@
<string name="recent_task_option_pin" msgid="7929860679018978258">"Gozhdo"</string>
<string name="recent_task_option_freeform" msgid="48863056265284071">"Formë e lirë"</string>
<string name="recent_task_option_desktop" msgid="8280879717125435668">"Desktopi"</string>
- <!-- no translation found for recent_task_option_external_display (4533840664313389484) -->
- <skip />
+ <string name="recent_task_option_external_display" msgid="4533840664313389484">"Zhvendose tek ekrani i jashtëm"</string>
<string name="recent_task_desktop" msgid="8081113562549637334">"Desktopi"</string>
<string name="recents_empty_message" msgid="7040467240571714191">"Nuk ka asnjë artikull të fundit"</string>
<string name="accessibility_app_usage_settings" msgid="6312864233673544149">"Cilësimet e përdorimit të aplikacionit"</string>
@@ -156,6 +155,5 @@
<string name="bubble_bar_action_dismiss_all" msgid="3290722022983403060">"Hiqi të gjitha"</string>
<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>
- <!-- no translation found for search_gesture_feature_title (1294044108313175306) -->
- <skip />
+ <string name="search_gesture_feature_title" msgid="1294044108313175306">"Qarko për të kërkuar"</string>
</resources>
diff --git a/quickstep/res/values-sr/strings.xml b/quickstep/res/values-sr/strings.xml
index b83a4f2..6622217 100644
--- a/quickstep/res/values-sr/strings.xml
+++ b/quickstep/res/values-sr/strings.xml
@@ -22,8 +22,7 @@
<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>
- <!-- no translation found for recent_task_option_external_display (4533840664313389484) -->
- <skip />
+ <string name="recent_task_option_external_display" msgid="4533840664313389484">"Преместите на спољни екран"</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>
@@ -156,6 +155,5 @@
<string name="bubble_bar_action_dismiss_all" msgid="3290722022983403060">"Одбаци све"</string>
<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>
- <!-- no translation found for search_gesture_feature_title (1294044108313175306) -->
- <skip />
+ <string name="search_gesture_feature_title" msgid="1294044108313175306">"Претрага заокруживањем"</string>
</resources>
diff --git a/quickstep/res/values-sv/strings.xml b/quickstep/res/values-sv/strings.xml
index 5ab3866..089d1b5 100644
--- a/quickstep/res/values-sv/strings.xml
+++ b/quickstep/res/values-sv/strings.xml
@@ -22,8 +22,7 @@
<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>
- <!-- no translation found for recent_task_option_external_display (4533840664313389484) -->
- <skip />
+ <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="recents_empty_message" msgid="7040467240571714191">"Listan är tom"</string>
<string name="accessibility_app_usage_settings" msgid="6312864233673544149">"Inställningar för appanvändning"</string>
@@ -156,6 +155,5 @@
<string name="bubble_bar_action_dismiss_all" msgid="3290722022983403060">"Stäng alla"</string>
<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>
- <!-- no translation found for search_gesture_feature_title (1294044108313175306) -->
- <skip />
+ <string name="search_gesture_feature_title" msgid="1294044108313175306">"Circle to Search"</string>
</resources>
diff --git a/quickstep/res/values-sw/strings.xml b/quickstep/res/values-sw/strings.xml
index 9d13df8..821797b 100644
--- a/quickstep/res/values-sw/strings.xml
+++ b/quickstep/res/values-sw/strings.xml
@@ -22,8 +22,7 @@
<string name="recent_task_option_pin" msgid="7929860679018978258">"Bandika"</string>
<string name="recent_task_option_freeform" msgid="48863056265284071">"Muundo huru"</string>
<string name="recent_task_option_desktop" msgid="8280879717125435668">"Kompyuta ya mezani"</string>
- <!-- no translation found for recent_task_option_external_display (4533840664313389484) -->
- <skip />
+ <string name="recent_task_option_external_display" msgid="4533840664313389484">"Hamishia programu kwenye skrini ya nje"</string>
<string name="recent_task_desktop" msgid="8081113562549637334">"Kompyuta ya Mezani"</string>
<string name="recents_empty_message" msgid="7040467240571714191">"Hakuna vipengee vya hivi karibuni"</string>
<string name="accessibility_app_usage_settings" msgid="6312864233673544149">"Mipangilio ya matumizi ya programu"</string>
@@ -156,6 +155,5 @@
<string name="bubble_bar_action_dismiss_all" msgid="3290722022983403060">"Ondoa vyote"</string>
<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>
- <!-- no translation found for search_gesture_feature_title (1294044108313175306) -->
- <skip />
+ <string name="search_gesture_feature_title" msgid="1294044108313175306">"Chora Mviringo ili Kutafuta"</string>
</resources>
diff --git a/quickstep/res/values-ta/strings.xml b/quickstep/res/values-ta/strings.xml
index 8ac0ff8..7bbfaba 100644
--- a/quickstep/res/values-ta/strings.xml
+++ b/quickstep/res/values-ta/strings.xml
@@ -22,8 +22,7 @@
<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>
- <!-- no translation found for recent_task_option_external_display (4533840664313389484) -->
- <skip />
+ <string name="recent_task_option_external_display" msgid="4533840664313389484">"வெளிப்புற டிஸ்ப்ளேவிற்கு நகர்த்துதல்"</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>
@@ -156,6 +155,5 @@
<string name="bubble_bar_action_dismiss_all" msgid="3290722022983403060">"அனைத்தையும் மூடும்"</string>
<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>
- <!-- no translation found for search_gesture_feature_title (1294044108313175306) -->
- <skip />
+ <string name="search_gesture_feature_title" msgid="1294044108313175306">"வட்டமிட்டுத் தேடல்"</string>
</resources>
diff --git a/quickstep/res/values-te/strings.xml b/quickstep/res/values-te/strings.xml
index 4ae7a58..5439e80 100644
--- a/quickstep/res/values-te/strings.xml
+++ b/quickstep/res/values-te/strings.xml
@@ -22,8 +22,7 @@
<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>
- <!-- no translation found for recent_task_option_external_display (4533840664313389484) -->
- <skip />
+ <string name="recent_task_option_external_display" msgid="4533840664313389484">"ఎక్స్టర్నల్ డిస్ప్లేకు తరలించండి"</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>
@@ -156,6 +155,5 @@
<string name="bubble_bar_action_dismiss_all" msgid="3290722022983403060">"అన్నింటినీ విస్మరించండి"</string>
<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>
- <!-- no translation found for search_gesture_feature_title (1294044108313175306) -->
- <skip />
+ <string name="search_gesture_feature_title" msgid="1294044108313175306">"సెర్చ్ చేయడానికి సర్కిల్ గీయండి"</string>
</resources>
diff --git a/quickstep/res/values-th/strings.xml b/quickstep/res/values-th/strings.xml
index 210e996..1f93cb6 100644
--- a/quickstep/res/values-th/strings.xml
+++ b/quickstep/res/values-th/strings.xml
@@ -156,6 +156,5 @@
<string name="bubble_bar_action_dismiss_all" msgid="3290722022983403060">"ปิดทั้งหมด"</string>
<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>
- <!-- no translation found for search_gesture_feature_title (1294044108313175306) -->
- <skip />
+ <string name="search_gesture_feature_title" msgid="1294044108313175306">"วงเพื่อค้นหา"</string>
</resources>
diff --git a/quickstep/res/values-tl/strings.xml b/quickstep/res/values-tl/strings.xml
index 13d89a2..583f419 100644
--- a/quickstep/res/values-tl/strings.xml
+++ b/quickstep/res/values-tl/strings.xml
@@ -22,8 +22,7 @@
<string name="recent_task_option_pin" msgid="7929860679018978258">"I-pin"</string>
<string name="recent_task_option_freeform" msgid="48863056265284071">"Freeform"</string>
<string name="recent_task_option_desktop" msgid="8280879717125435668">"Desktop"</string>
- <!-- no translation found for recent_task_option_external_display (4533840664313389484) -->
- <skip />
+ <string name="recent_task_option_external_display" msgid="4533840664313389484">"Ilipat sa external na display"</string>
<string name="recent_task_desktop" msgid="8081113562549637334">"Desktop"</string>
<string name="recents_empty_message" msgid="7040467240571714191">"Walang kamakailang item"</string>
<string name="accessibility_app_usage_settings" msgid="6312864233673544149">"Mga setting ng paggamit ng app"</string>
@@ -156,6 +155,5 @@
<string name="bubble_bar_action_dismiss_all" msgid="3290722022983403060">"I-dismiss lahat"</string>
<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>
- <!-- no translation found for search_gesture_feature_title (1294044108313175306) -->
- <skip />
+ <string name="search_gesture_feature_title" msgid="1294044108313175306">"Circle to Search"</string>
</resources>
diff --git a/quickstep/res/values-tr/strings.xml b/quickstep/res/values-tr/strings.xml
index 1cb1fa7..c50c1f8 100644
--- a/quickstep/res/values-tr/strings.xml
+++ b/quickstep/res/values-tr/strings.xml
@@ -22,8 +22,7 @@
<string name="recent_task_option_pin" msgid="7929860679018978258">"Sabitle"</string>
<string name="recent_task_option_freeform" msgid="48863056265284071">"Serbest çalışma"</string>
<string name="recent_task_option_desktop" msgid="8280879717125435668">"Masaüstü"</string>
- <!-- no translation found for recent_task_option_external_display (4533840664313389484) -->
- <skip />
+ <string name="recent_task_option_external_display" msgid="4533840664313389484">"Harici ekrana taşı"</string>
<string name="recent_task_desktop" msgid="8081113562549637334">"Masaüstü"</string>
<string name="recents_empty_message" msgid="7040467240571714191">"Yeni öğe yok"</string>
<string name="accessibility_app_usage_settings" msgid="6312864233673544149">"Uygulama kullanım ayarları"</string>
@@ -156,6 +155,5 @@
<string name="bubble_bar_action_dismiss_all" msgid="3290722022983403060">"Tümünü kapat"</string>
<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>
- <!-- no translation found for search_gesture_feature_title (1294044108313175306) -->
- <skip />
+ <string name="search_gesture_feature_title" msgid="1294044108313175306">"Seçerek Arat"</string>
</resources>
diff --git a/quickstep/res/values-uk/strings.xml b/quickstep/res/values-uk/strings.xml
index 84ddd81..d75f8b4 100644
--- a/quickstep/res/values-uk/strings.xml
+++ b/quickstep/res/values-uk/strings.xml
@@ -22,8 +22,7 @@
<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>
- <!-- no translation found for recent_task_option_external_display (4533840664313389484) -->
- <skip />
+ <string name="recent_task_option_external_display" msgid="4533840664313389484">"Перемістити на зовнішній екран"</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>
@@ -156,6 +155,5 @@
<string name="bubble_bar_action_dismiss_all" msgid="3290722022983403060">"Закрити все"</string>
<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>
- <!-- no translation found for search_gesture_feature_title (1294044108313175306) -->
- <skip />
+ <string name="search_gesture_feature_title" msgid="1294044108313175306">"Обвести й знайти"</string>
</resources>
diff --git a/quickstep/res/values-ur/strings.xml b/quickstep/res/values-ur/strings.xml
index 43e97c2..68f838f 100644
--- a/quickstep/res/values-ur/strings.xml
+++ b/quickstep/res/values-ur/strings.xml
@@ -22,8 +22,7 @@
<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>
- <!-- no translation found for recent_task_option_external_display (4533840664313389484) -->
- <skip />
+ <string name="recent_task_option_external_display" msgid="4533840664313389484">"بیرونی ڈسپلے پر متقل کریں"</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>
@@ -156,6 +155,5 @@
<string name="bubble_bar_action_dismiss_all" msgid="3290722022983403060">"سبھی کو برخاست کریں"</string>
<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>
- <!-- no translation found for search_gesture_feature_title (1294044108313175306) -->
- <skip />
+ <string name="search_gesture_feature_title" msgid="1294044108313175306">"تلاش کرنے کیلئے دائرہ بنائیں"</string>
</resources>
diff --git a/quickstep/res/values-uz/strings.xml b/quickstep/res/values-uz/strings.xml
index 090753f..294be84 100644
--- a/quickstep/res/values-uz/strings.xml
+++ b/quickstep/res/values-uz/strings.xml
@@ -22,8 +22,7 @@
<string name="recent_task_option_pin" msgid="7929860679018978258">"Qadash"</string>
<string name="recent_task_option_freeform" msgid="48863056265284071">"Erkin shakl"</string>
<string name="recent_task_option_desktop" msgid="8280879717125435668">"Desktop"</string>
- <!-- no translation found for recent_task_option_external_display (4533840664313389484) -->
- <skip />
+ <string name="recent_task_option_external_display" msgid="4533840664313389484">"Tashqi displeyga olish"</string>
<string name="recent_task_desktop" msgid="8081113562549637334">"Desktop"</string>
<string name="recents_empty_message" msgid="7040467240571714191">"Yaqinda ishlatilgan ilovalar yo‘q"</string>
<string name="accessibility_app_usage_settings" msgid="6312864233673544149">"Ilovadan foydalanish sozlamalari"</string>
@@ -156,6 +155,5 @@
<string name="bubble_bar_action_dismiss_all" msgid="3290722022983403060">"Hammasini yopish"</string>
<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>
- <!-- no translation found for search_gesture_feature_title (1294044108313175306) -->
- <skip />
+ <string name="search_gesture_feature_title" msgid="1294044108313175306">"Chizib qidirish"</string>
</resources>
diff --git a/quickstep/res/values-vi/strings.xml b/quickstep/res/values-vi/strings.xml
index b0d31cb..2bf4a13 100644
--- a/quickstep/res/values-vi/strings.xml
+++ b/quickstep/res/values-vi/strings.xml
@@ -156,6 +156,5 @@
<string name="bubble_bar_action_dismiss_all" msgid="3290722022983403060">"Đóng tất cả"</string>
<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>
- <!-- no translation found for search_gesture_feature_title (1294044108313175306) -->
- <skip />
+ <string name="search_gesture_feature_title" msgid="1294044108313175306">"Khoanh tròn để tìm kiếm"</string>
</resources>
diff --git a/quickstep/res/values-zh-rCN/strings.xml b/quickstep/res/values-zh-rCN/strings.xml
index 73121b4..eee46bb 100644
--- a/quickstep/res/values-zh-rCN/strings.xml
+++ b/quickstep/res/values-zh-rCN/strings.xml
@@ -22,8 +22,7 @@
<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>
- <!-- no translation found for recent_task_option_external_display (4533840664313389484) -->
- <skip />
+ <string name="recent_task_option_external_display" msgid="4533840664313389484">"移至外接显示屏"</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>
@@ -156,6 +155,5 @@
<string name="bubble_bar_action_dismiss_all" msgid="3290722022983403060">"全部关闭"</string>
<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>
- <!-- no translation found for search_gesture_feature_title (1294044108313175306) -->
- <skip />
+ <string name="search_gesture_feature_title" msgid="1294044108313175306">"圈定即搜"</string>
</resources>
diff --git a/quickstep/res/values-zh-rHK/strings.xml b/quickstep/res/values-zh-rHK/strings.xml
index b934dfc..c8d18eb 100644
--- a/quickstep/res/values-zh-rHK/strings.xml
+++ b/quickstep/res/values-zh-rHK/strings.xml
@@ -22,8 +22,7 @@
<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>
- <!-- no translation found for recent_task_option_external_display (4533840664313389484) -->
- <skip />
+ <string name="recent_task_option_external_display" msgid="4533840664313389484">"移至外部顯示屏"</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>
@@ -156,6 +155,5 @@
<string name="bubble_bar_action_dismiss_all" msgid="3290722022983403060">"全部關閉"</string>
<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>
- <!-- no translation found for search_gesture_feature_title (1294044108313175306) -->
- <skip />
+ <string name="search_gesture_feature_title" msgid="1294044108313175306">"一圈即搜"</string>
</resources>
diff --git a/quickstep/res/values-zh-rTW/strings.xml b/quickstep/res/values-zh-rTW/strings.xml
index 1cba819..fd132d2 100644
--- a/quickstep/res/values-zh-rTW/strings.xml
+++ b/quickstep/res/values-zh-rTW/strings.xml
@@ -22,8 +22,7 @@
<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>
- <!-- no translation found for recent_task_option_external_display (4533840664313389484) -->
- <skip />
+ <string name="recent_task_option_external_display" msgid="4533840664313389484">"移至外接螢幕"</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>
@@ -156,6 +155,5 @@
<string name="bubble_bar_action_dismiss_all" msgid="3290722022983403060">"全部關閉"</string>
<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>
- <!-- no translation found for search_gesture_feature_title (1294044108313175306) -->
- <skip />
+ <string name="search_gesture_feature_title" msgid="1294044108313175306">"畫圈搜尋"</string>
</resources>
diff --git a/quickstep/res/values-zu/strings.xml b/quickstep/res/values-zu/strings.xml
index ee6b3b7..46dbbd5 100644
--- a/quickstep/res/values-zu/strings.xml
+++ b/quickstep/res/values-zu/strings.xml
@@ -22,8 +22,7 @@
<string name="recent_task_option_pin" msgid="7929860679018978258">"Phina"</string>
<string name="recent_task_option_freeform" msgid="48863056265284071">"I-Freeform"</string>
<string name="recent_task_option_desktop" msgid="8280879717125435668">"Ideskithophu"</string>
- <!-- no translation found for recent_task_option_external_display (4533840664313389484) -->
- <skip />
+ <string name="recent_task_option_external_display" msgid="4533840664313389484">"Hambisa esibonisini sangaphandle"</string>
<string name="recent_task_desktop" msgid="8081113562549637334">"Ideskithophu"</string>
<string name="recents_empty_message" msgid="7040467240571714191">"Azikho izinto zakamuva"</string>
<string name="accessibility_app_usage_settings" msgid="6312864233673544149">"Izilungiselelo zokusetshenziswa kohlelo lokusebenza"</string>
@@ -156,6 +155,5 @@
<string name="bubble_bar_action_dismiss_all" msgid="3290722022983403060">"Chitha konke"</string>
<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>
- <!-- no translation found for search_gesture_feature_title (1294044108313175306) -->
- <skip />
+ <string name="search_gesture_feature_title" msgid="1294044108313175306">"Khethela Ukusesha"</string>
</resources>
diff --git a/quickstep/res/values/colors.xml b/quickstep/res/values/colors.xml
index 4c48bd3..62873d6 100644
--- a/quickstep/res/values/colors.xml
+++ b/quickstep/res/values/colors.xml
@@ -31,7 +31,6 @@
<color name="taskbar_nav_icon_dark_color_on_home">#99000000</color>
<color name="taskbar_stashed_handle_light_color">#EBffffff</color>
<color name="taskbar_stashed_handle_dark_color">#99000000</color>
- <color name="taskbar_running_app_indicator_color">#646464</color>
<!-- Floating rotation button -->
<color name="floating_rotation_button_light_color">#ffffff</color>
diff --git a/quickstep/res/values/config.xml b/quickstep/res/values/config.xml
index 41b2384..db5ff19 100644
--- a/quickstep/res/values/config.xml
+++ b/quickstep/res/values/config.xml
@@ -33,7 +33,6 @@
<string name="taskbar_model_callbacks_factory_class" translatable="false">com.android.launcher3.taskbar.TaskbarModelCallbacksFactory</string>
<string name="taskbar_view_callbacks_factory_class" translatable="false">com.android.launcher3.taskbar.TaskbarViewCallbacksFactory</string>
<string name="launcher_restore_event_logger_class" translatable="false">com.android.quickstep.LauncherRestoreEventLoggerImpl</string>
- <string name="plugin_manager_wrapper_class" translatable="false">com.android.launcher3.uioverrides.plugins.PluginManagerWrapperImpl</string>
<string name="taskbar_edu_tooltip_controller_class" translatable="false">com.android.launcher3.taskbar.TaskbarEduTooltipController</string>
<string name="contextual_edu_manager_class" translatable="false">com.android.quickstep.contextualeducation.SystemContextualEduStatsManager</string>
<string name="nav_handle_long_press_handler_class" translatable="false"></string>
diff --git a/quickstep/res/values/dimens.xml b/quickstep/res/values/dimens.xml
index 8957e0d..5f35007 100644
--- a/quickstep/res/values/dimens.xml
+++ b/quickstep/res/values/dimens.xml
@@ -356,12 +356,10 @@
<dimen name="taskbar_back_button_suw_start_margin">48dp</dimen>
<dimen name="taskbar_back_button_suw_bottom_margin">1dp</dimen>
<dimen name="taskbar_back_button_suw_height">72dp</dimen>
- <dimen name="taskbar_running_app_indicator_height">4dp</dimen>
- <dimen name="taskbar_running_app_indicator_width">14dp</dimen>
- <dimen name="taskbar_running_app_indicator_top_margin">2dp</dimen>
- <dimen name="taskbar_minimized_app_indicator_height">2dp</dimen>
- <dimen name="taskbar_minimized_app_indicator_width">12dp</dimen>
- <dimen name="taskbar_minimized_app_indicator_top_margin">2dp</dimen>
+ <dimen name="taskbar_running_app_indicator_height">2dp</dimen>
+ <dimen name="taskbar_running_app_indicator_width">12dp</dimen>
+ <dimen name="taskbar_running_app_indicator_top_margin">4dp</dimen>
+ <dimen name="taskbar_minimized_app_indicator_width">6dp</dimen>
<!-- Transient taskbar -->
<dimen name="transient_taskbar_padding">12dp</dimen>
@@ -424,6 +422,7 @@
<!--- Taskbar Pinning -->
<dimen name="taskbar_pinning_popup_menu_width">300dp</dimen>
<dimen name="taskbar_pinning_popup_menu_vertical_margin">16dp</dimen>
+ <dimen name="taskbar_pinning_popup_menu_min_padding_from_screen_edge">16dp</dimen>
<!--- Floating Ime Inset height-->
<dimen name="floating_ime_inset_height">60dp</dimen>
diff --git a/quickstep/res/values/ids.xml b/quickstep/res/values/ids.xml
index 3091d9e..c71bb76 100644
--- a/quickstep/res/values/ids.xml
+++ b/quickstep/res/values/ids.xml
@@ -19,4 +19,6 @@
<item type="id" name="action_move_left" />
<item type="id" name="action_move_right" />
<item type="id" name="action_dismiss_all" />
+
+ <item type="id" name="bubble_bar_flyout_view" />
</resources>
\ No newline at end of file
diff --git a/quickstep/src/com/android/launcher3/LauncherInitListener.java b/quickstep/src/com/android/launcher3/LauncherInitListener.java
index 523923d..4e4ffe7 100644
--- a/quickstep/src/com/android/launcher3/LauncherInitListener.java
+++ b/quickstep/src/com/android/launcher3/LauncherInitListener.java
@@ -15,11 +15,11 @@
*/
package com.android.launcher3;
-import com.android.quickstep.util.ActivityInitListener;
+import com.android.quickstep.util.ContextInitListener;
import java.util.function.BiPredicate;
-public class LauncherInitListener extends ActivityInitListener<Launcher> {
+public class LauncherInitListener extends ContextInitListener<Launcher> {
/**
* @param onInitListener a callback made when the activity is initialized. The callback should
@@ -31,8 +31,8 @@
}
@Override
- public boolean handleInit(Launcher launcher, boolean alreadyOnHome) {
+ public boolean handleInit(Launcher launcher, boolean isHomeStarted) {
launcher.deferOverlayCallbacksUntilNextResumeOrStop();
- return super.handleInit(launcher, alreadyOnHome);
+ return super.handleInit(launcher, isHomeStarted);
}
}
diff --git a/quickstep/src/com/android/launcher3/desktop/DesktopAppLaunchTransition.kt b/quickstep/src/com/android/launcher3/desktop/DesktopAppLaunchTransition.kt
new file mode 100644
index 0000000..dd2ff2d
--- /dev/null
+++ b/quickstep/src/com/android/launcher3/desktop/DesktopAppLaunchTransition.kt
@@ -0,0 +1,166 @@
+/*
+ * Copyright (C) 2024 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.launcher3.desktop
+
+import android.animation.Animator
+import android.animation.AnimatorSet
+import android.animation.ValueAnimator
+import android.content.Context
+import android.os.IBinder
+import android.view.SurfaceControl.Transaction
+import android.view.WindowManager.TRANSIT_OPEN
+import android.view.WindowManager.TRANSIT_TO_BACK
+import android.view.WindowManager.TRANSIT_TO_FRONT
+import android.window.IRemoteTransitionFinishedCallback
+import android.window.RemoteTransitionStub
+import android.window.TransitionInfo
+import android.window.TransitionInfo.Change
+import androidx.core.animation.addListener
+import com.android.app.animation.Interpolators
+import com.android.quickstep.RemoteRunnable
+import java.util.concurrent.Executor
+
+/**
+ * [android.window.RemoteTransition] for Desktop app launches.
+ *
+ * This transition supports minimize-changes, i.e. in a launch-transition, if a window is moved back
+ * ([android.view.WindowManager.TRANSIT_TO_BACK]) this transition will apply a minimize animation to
+ * that window.
+ */
+class DesktopAppLaunchTransition(private val context: Context, private val mainExecutor: Executor) :
+ RemoteTransitionStub() {
+
+ override fun startAnimation(
+ token: IBinder,
+ info: TransitionInfo,
+ t: Transaction,
+ transitionFinishedCallback: IRemoteTransitionFinishedCallback,
+ ) {
+ val safeTransitionFinishedCallback = RemoteRunnable {
+ transitionFinishedCallback.onTransitionFinished(/* wct= */ null, /* sct= */ null)
+ }
+ mainExecutor.execute {
+ runAnimators(info, safeTransitionFinishedCallback)
+ t.apply()
+ }
+ }
+
+ private fun runAnimators(info: TransitionInfo, finishedCallback: RemoteRunnable) {
+ val animators = mutableListOf<Animator>()
+ val animatorFinishedCallback: (Animator) -> Unit = { animator ->
+ animators -= animator
+ if (animators.isEmpty()) finishedCallback.run()
+ }
+ animators += createAnimators(info, animatorFinishedCallback)
+ animators.forEach { it.start() }
+ }
+
+ private fun createAnimators(
+ info: TransitionInfo,
+ finishCallback: (Animator) -> Unit,
+ ): List<Animator> {
+ val transaction = Transaction()
+ val launchAnimator =
+ createLaunchAnimator(getLaunchChange(info), transaction, finishCallback)
+ val minimizeChange = getMinimizeChange(info) ?: return listOf(launchAnimator)
+ val minimizeAnimator = createMinimizeAnimator(minimizeChange, transaction, finishCallback)
+ return listOf(launchAnimator, minimizeAnimator)
+ }
+
+ private fun getLaunchChange(info: TransitionInfo): Change =
+ requireNotNull(info.changes.firstOrNull { change -> change.mode in LAUNCH_CHANGE_MODES }) {
+ "expected an app launch Change"
+ }
+
+ private fun getMinimizeChange(info: TransitionInfo): Change? =
+ info.changes.firstOrNull { change -> change.mode == TRANSIT_TO_BACK }
+
+ private fun createLaunchAnimator(
+ change: Change,
+ transaction: Transaction,
+ onAnimFinish: (Animator) -> Unit,
+ ): Animator {
+ val boundsAnimator =
+ WindowAnimator.createBoundsAnimator(
+ context,
+ launchBoundsAnimationDef,
+ change,
+ transaction,
+ )
+ val alphaAnimator =
+ ValueAnimator.ofFloat(0f, 1f).apply {
+ duration = LAUNCH_ANIM_ALPHA_DURATION_MS
+ interpolator = Interpolators.LINEAR
+ addUpdateListener { animation ->
+ transaction.setAlpha(change.leash, animation.animatedValue as Float).apply()
+ }
+ }
+ return AnimatorSet().apply {
+ playTogether(boundsAnimator, alphaAnimator)
+ addListener(onEnd = { animation -> onAnimFinish(animation) })
+ }
+ }
+
+ private fun createMinimizeAnimator(
+ change: Change,
+ transaction: Transaction,
+ onAnimFinish: (Animator) -> Unit,
+ ): Animator {
+ val boundsAnimator =
+ WindowAnimator.createBoundsAnimator(
+ context,
+ minimizeBoundsAnimationDef,
+ change,
+ transaction,
+ )
+ val alphaAnimator =
+ ValueAnimator.ofFloat(1f, 0f).apply {
+ duration = MINIMIZE_ANIM_ALPHA_DURATION_MS
+ interpolator = Interpolators.LINEAR
+ addUpdateListener { animation ->
+ transaction.setAlpha(change.leash, animation.animatedValue as Float).apply()
+ }
+ }
+ return AnimatorSet().apply {
+ playTogether(boundsAnimator, alphaAnimator)
+ addListener(onEnd = { animation -> onAnimFinish(animation) })
+ }
+ }
+
+ companion object {
+ private val LAUNCH_CHANGE_MODES = intArrayOf(TRANSIT_OPEN, TRANSIT_TO_FRONT)
+
+ private const val LAUNCH_ANIM_ALPHA_DURATION_MS = 100L
+ private const val MINIMIZE_ANIM_ALPHA_DURATION_MS = 100L
+
+ private val launchBoundsAnimationDef =
+ WindowAnimator.BoundsAnimationParams(
+ durationMs = 300,
+ startOffsetYDp = 12f,
+ startScale = 0.97f,
+ interpolator = Interpolators.STANDARD_DECELERATE,
+ )
+
+ private val minimizeBoundsAnimationDef =
+ WindowAnimator.BoundsAnimationParams(
+ durationMs = 200,
+ endOffsetYDp = 12f,
+ endScale = 0.97f,
+ interpolator = Interpolators.STANDARD_ACCELERATE,
+ )
+ }
+}
diff --git a/quickstep/src/com/android/launcher3/desktop/WindowAnimator.kt b/quickstep/src/com/android/launcher3/desktop/WindowAnimator.kt
new file mode 100644
index 0000000..1a99a36
--- /dev/null
+++ b/quickstep/src/com/android/launcher3/desktop/WindowAnimator.kt
@@ -0,0 +1,100 @@
+/*
+ * Copyright (C) 2024 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.launcher3.desktop
+
+import android.animation.RectEvaluator
+import android.animation.ValueAnimator
+import android.content.Context
+import android.graphics.Rect
+import android.util.TypedValue
+import android.view.SurfaceControl
+import android.view.animation.Interpolator
+import android.window.TransitionInfo
+
+/** Creates animations that can be applied to windows/surfaces. */
+object WindowAnimator {
+
+ /** Parameters defining a window bounds animation. */
+ data class BoundsAnimationParams(
+ val durationMs: Long,
+ val startOffsetYDp: Float = 0f,
+ val endOffsetYDp: Float = 0f,
+ val startScale: Float = 1f,
+ val endScale: Float = 1f,
+ val interpolator: Interpolator,
+ )
+
+ /**
+ * Creates an animator to reposition and scale the bounds of the leash of the given change.
+ *
+ * @param boundsAnimDef the parameters for the animation itself (duration, scale, position)
+ * @param change the change to which the animation should be applied
+ * @param transaction the transaction to apply the animation to
+ */
+ fun createBoundsAnimator(
+ context: Context,
+ boundsAnimDef: BoundsAnimationParams,
+ change: TransitionInfo.Change,
+ transaction: SurfaceControl.Transaction,
+ ): ValueAnimator {
+ val startBounds =
+ createBounds(
+ context,
+ change.startAbsBounds,
+ boundsAnimDef.startScale,
+ boundsAnimDef.startOffsetYDp,
+ )
+ val leash = change.leash
+ val endBounds =
+ createBounds(
+ context,
+ change.startAbsBounds,
+ boundsAnimDef.endScale,
+ boundsAnimDef.endOffsetYDp,
+ )
+ return ValueAnimator.ofObject(RectEvaluator(), startBounds, endBounds).apply {
+ duration = boundsAnimDef.durationMs
+ interpolator = boundsAnimDef.interpolator
+ addUpdateListener { animation ->
+ val animBounds = animation.animatedValue as Rect
+ val animScale = 1 - (1 - boundsAnimDef.endScale) * animation.animatedFraction
+ transaction
+ .setPosition(leash, animBounds.left.toFloat(), animBounds.top.toFloat())
+ .setScale(leash, animScale, animScale)
+ .apply()
+ }
+ }
+ }
+
+ private fun createBounds(context: Context, origBounds: Rect, scale: Float, offsetYDp: Float) =
+ Rect(origBounds).apply {
+ check(scale in 0.0..1.0)
+ // Scale the bounds down with an anchor in the center
+ inset(
+ (origBounds.width().toFloat() * (1 - scale) / 2).toInt(),
+ (origBounds.height().toFloat() * (1 - scale) / 2).toInt(),
+ )
+ val offsetYPx =
+ TypedValue.applyDimension(
+ TypedValue.COMPLEX_UNIT_DIP,
+ offsetYDp,
+ context.resources.displayMetrics,
+ )
+ .toInt()
+ offset(/* dx= */ 0, offsetYPx)
+ }
+}
diff --git a/quickstep/src/com/android/launcher3/model/WellbeingModel.java b/quickstep/src/com/android/launcher3/model/WellbeingModel.java
index 94a1814..0f3aaa6 100644
--- a/quickstep/src/com/android/launcher3/model/WellbeingModel.java
+++ b/quickstep/src/com/android/launcher3/model/WellbeingModel.java
@@ -51,7 +51,6 @@
import com.android.launcher3.popup.SystemShortcut;
import com.android.launcher3.util.DaggerSingletonObject;
import com.android.launcher3.util.DaggerSingletonTracker;
-import com.android.launcher3.util.ExecutorUtil;
import com.android.launcher3.util.Executors;
import com.android.launcher3.util.Preconditions;
import com.android.launcher3.util.SafeCloseable;
@@ -122,7 +121,7 @@
}
};
mWorkerHandler.post(this::initializeInBackground);
- ExecutorUtil.executeSyncOnMainOrFail(() -> tracker.addCloseable(this));
+ tracker.addCloseable(this);
}
@WorkerThread
diff --git a/quickstep/src/com/android/launcher3/statehandlers/DesktopVisibilityController.java b/quickstep/src/com/android/launcher3/statehandlers/DesktopVisibilityController.java
index 2ac87ff..5744464 100644
--- a/quickstep/src/com/android/launcher3/statehandlers/DesktopVisibilityController.java
+++ b/quickstep/src/com/android/launcher3/statehandlers/DesktopVisibilityController.java
@@ -384,7 +384,7 @@
Log.d(TAG, "markLauncherPaused " + Debug.getCaller());
}
StatefulActivity<LauncherState> activity =
- QuickstepLauncher.ACTIVITY_TRACKER.getCreatedActivity();
+ QuickstepLauncher.ACTIVITY_TRACKER.getCreatedContext();
if (activity != null) {
activity.setPaused();
}
@@ -404,7 +404,7 @@
Log.d(TAG, "markLauncherResumed " + Debug.getCaller());
}
StatefulActivity<LauncherState> activity =
- QuickstepLauncher.ACTIVITY_TRACKER.getCreatedActivity();
+ QuickstepLauncher.ACTIVITY_TRACKER.getCreatedContext();
// Check activity state before calling setResumed(). Launcher may have been actually
// paused (eg fullscreen task moved to front).
// In this case we should not mark the activity as resumed.
diff --git a/quickstep/src/com/android/launcher3/taskbar/KeyboardQuickSwitchView.java b/quickstep/src/com/android/launcher3/taskbar/KeyboardQuickSwitchView.java
index fc8204a..50a253c 100644
--- a/quickstep/src/com/android/launcher3/taskbar/KeyboardQuickSwitchView.java
+++ b/quickstep/src/com/android/launcher3/taskbar/KeyboardQuickSwitchView.java
@@ -17,8 +17,6 @@
import static androidx.constraintlayout.widget.ConstraintLayout.LayoutParams.PARENT_ID;
-import static com.android.launcher3.taskbar.KeyboardQuickSwitchController.MAX_TASKS;
-
import android.animation.Animator;
import android.animation.AnimatorListenerAdapter;
import android.animation.AnimatorSet;
@@ -200,7 +198,7 @@
View previousTaskView = null;
LayoutInflater layoutInflater = LayoutInflater.from(context);
- int tasksToDisplay = Math.min(MAX_TASKS, groupTasks.size());
+ int tasksToDisplay = groupTasks.size();
for (int i = 0; i < tasksToDisplay; i++) {
GroupTask groupTask = groupTasks.get(i);
KeyboardQuickSwitchTaskView currentTaskView = createAndAddTaskView(
diff --git a/quickstep/src/com/android/launcher3/taskbar/KeyboardQuickSwitchViewController.java b/quickstep/src/com/android/launcher3/taskbar/KeyboardQuickSwitchViewController.java
index 1c8a094..a80c11c 100644
--- a/quickstep/src/com/android/launcher3/taskbar/KeyboardQuickSwitchViewController.java
+++ b/quickstep/src/com/android/launcher3/taskbar/KeyboardQuickSwitchViewController.java
@@ -15,6 +15,7 @@
*/
package com.android.launcher3.taskbar;
+import static com.android.launcher3.util.Executors.MAIN_EXECUTOR;
import static com.android.launcher3.util.Executors.UI_HELPER_EXECUTOR;
import android.animation.Animator;
@@ -31,6 +32,7 @@
import com.android.internal.jank.Cuj;
import com.android.launcher3.Utilities;
import com.android.launcher3.anim.AnimatorListeners;
+import com.android.launcher3.desktop.DesktopAppLaunchTransition;
import com.android.launcher3.taskbar.overlay.TaskbarOverlayContext;
import com.android.launcher3.taskbar.overlay.TaskbarOverlayDragLayer;
import com.android.launcher3.views.BaseDragLayer;
@@ -41,6 +43,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.window.flags.Flags;
import java.io.PrintWriter;
import java.util.List;
@@ -181,7 +184,7 @@
Runnable onFinishCallback = () -> InteractionJankMonitorWrapper.end(
Cuj.CUJ_LAUNCHER_KEYBOARD_QUICK_SWITCH_APP_LAUNCH);
TaskbarActivityContext context = mControllers.taskbarActivityContext;
- RemoteTransition remoteTransition = new RemoteTransition(new SlideInRemoteTransition(
+ final RemoteTransition slideInTransition = new RemoteTransition(new SlideInRemoteTransition(
Utilities.isRtl(mControllers.taskbarActivityContext.getResources()),
context.getDeviceProfile().overviewPageSpacing,
QuickStepContract.getWindowCornerRadius(context),
@@ -195,7 +198,7 @@
SystemUiProxy.INSTANCE.get(mKeyboardQuickSwitchView.getContext())
.showDesktopApps(
mKeyboardQuickSwitchView.getDisplay().getDisplayId(),
- remoteTransition));
+ slideInTransition));
return -1;
}
// Even with a valid index, this can be null if the user tries to quick switch before the
@@ -208,6 +211,13 @@
// Ignore attempts to run the selected task if it is already running.
return -1;
}
+ RemoteTransition remoteTransition = slideInTransition;
+ if (mOnDesktop && task.task1.isMinimized
+ && Flags.enableDesktopAppLaunchAlttabTransitions()) {
+ // This app is being unminimized - use our own transition runner.
+ remoteTransition = new RemoteTransition(
+ new DesktopAppLaunchTransition(context, MAIN_EXECUTOR));
+ }
mControllers.taskbarActivityContext.handleGroupTaskLaunch(
task,
remoteTransition,
diff --git a/quickstep/src/com/android/launcher3/taskbar/LauncherTaskbarUIController.java b/quickstep/src/com/android/launcher3/taskbar/LauncherTaskbarUIController.java
index 0b850bd..042bc9a 100644
--- a/quickstep/src/com/android/launcher3/taskbar/LauncherTaskbarUIController.java
+++ b/quickstep/src/com/android/launcher3/taskbar/LauncherTaskbarUIController.java
@@ -154,6 +154,12 @@
}
}
+ @Override
+ protected boolean isTaskbarTouchable() {
+ return !(mTaskbarLauncherStateController.isAnimatingToLauncher()
+ && mTaskbarLauncherStateController.isTaskbarAlignedWithHotseat());
+ }
+
public void setShouldDelayLauncherStateAnim(boolean shouldDelayLauncherStateAnim) {
mTaskbarLauncherStateController.setShouldDelayLauncherStateAnim(
shouldDelayLauncherStateAnim);
@@ -447,16 +453,6 @@
}
@Override
- public boolean isHotseatVisibleForTaskBarAlignment() {
- return mTaskbarLauncherStateController.isHotseatVisibleForTaskbarAlignment();
- }
-
- @Override
- public boolean isAnimatingToLauncher() {
- return mTaskbarLauncherStateController.isAnimatingToLauncher();
- }
-
- @Override
protected boolean isInOverviewUi() {
return mTaskbarLauncherStateController.isInOverviewUi();
}
diff --git a/quickstep/src/com/android/launcher3/taskbar/TaskbarActivityContext.java b/quickstep/src/com/android/launcher3/taskbar/TaskbarActivityContext.java
index 3606615..f3741b2 100644
--- a/quickstep/src/com/android/launcher3/taskbar/TaskbarActivityContext.java
+++ b/quickstep/src/com/android/launcher3/taskbar/TaskbarActivityContext.java
@@ -1240,7 +1240,8 @@
}
} else if (tag instanceof TaskItemInfo info) {
UI_HELPER_EXECUTOR.execute(() ->
- SystemUiProxy.INSTANCE.get(this).showDesktopApp(info.getTaskId()));
+ SystemUiProxy.INSTANCE.get(this).showDesktopApp(
+ info.getTaskId(), /* remoteTransition= */ null));
mControllers.taskbarStashController.updateAndAnimateTransientTaskbar(
/* stash= */ true);
} else if (tag instanceof WorkspaceItemInfo) {
@@ -1331,7 +1332,8 @@
GroupTask task,
@Nullable RemoteTransition remoteTransition,
boolean onDesktop) {
- handleGroupTaskLaunch(task, remoteTransition, onDesktop, null, null);
+ handleGroupTaskLaunch(task, remoteTransition, onDesktop,
+ /* onStartCallback= */ null, /* onFinishCallback= */ null);
}
/**
@@ -1355,17 +1357,24 @@
UI_HELPER_EXECUTOR.execute(() ->
SystemUiProxy.INSTANCE.get(this).showDesktopApps(getDisplay().getDisplayId(),
remoteTransition));
- } else if (onDesktop) {
+ return;
+ }
+ if (onDesktop) {
+ boolean useRemoteTransition = task.task1.isMinimized
+ && com.android.window.flags.Flags.enableDesktopAppLaunchAlttabTransitions();
UI_HELPER_EXECUTOR.execute(() -> {
if (onStartCallback != null) {
onStartCallback.run();
}
- SystemUiProxy.INSTANCE.get(this).showDesktopApp(task.task1.key.id);
+ SystemUiProxy.INSTANCE.get(this).showDesktopApp(
+ task.task1.key.id, useRemoteTransition ? remoteTransition : null);
if (onFinishCallback != null) {
onFinishCallback.run();
}
});
- } else if (task.task2 == null) {
+ return;
+ }
+ if (task.task2 == null) {
UI_HELPER_EXECUTOR.execute(() -> {
ActivityOptions activityOptions =
makeDefaultActivityOptions(SPLASH_SCREEN_STYLE_UNDEFINED).options;
@@ -1374,9 +1383,9 @@
ActivityManagerWrapper.getInstance().startActivityFromRecents(
task.task1.key, activityOptions);
});
- } else {
- mControllers.uiController.launchSplitTasks(task, remoteTransition);
+ return;
}
+ mControllers.uiController.launchSplitTasks(task, remoteTransition);
}
/**
@@ -1695,7 +1704,7 @@
duration);
View allAppsButton = mControllers.taskbarViewController.getAllAppsButtonView();
- if (allAppsButton != null && !FeatureFlags.enableAllAppsButtonInHotseat()) {
+ if (!FeatureFlags.enableAllAppsButtonInHotseat()) {
ValueAnimator alphaOverride = ValueAnimator.ofFloat(0, 1);
alphaOverride.setDuration(duration);
alphaOverride.addUpdateListener(a -> {
diff --git a/quickstep/src/com/android/launcher3/taskbar/TaskbarDividerPopupView.kt b/quickstep/src/com/android/launcher3/taskbar/TaskbarDividerPopupView.kt
index b5a3314..3f6ebe2 100644
--- a/quickstep/src/com/android/launcher3/taskbar/TaskbarDividerPopupView.kt
+++ b/quickstep/src/com/android/launcher3/taskbar/TaskbarDividerPopupView.kt
@@ -31,21 +31,21 @@
import android.widget.Switch
import androidx.core.view.postDelayed
import com.android.app.animation.Interpolators.EMPHASIZED_ACCELERATE
+import com.android.launcher3.Flags
import com.android.launcher3.R
import com.android.launcher3.popup.ArrowPopup
import com.android.launcher3.popup.RoundedArrowDrawable
import com.android.launcher3.util.DisplayController
import com.android.launcher3.util.Themes
import com.android.launcher3.views.ActivityContext
+import kotlin.math.max
+import kotlin.math.min
/** Popup view with arrow for taskbar pinning */
class TaskbarDividerPopupView<T : TaskbarActivityContext>
@JvmOverloads
-constructor(
- context: Context,
- attrs: AttributeSet? = null,
- defStyleAttr: Int = 0,
-) : ArrowPopup<T>(context, attrs, defStyleAttr) {
+constructor(context: Context, attrs: AttributeSet? = null, defStyleAttr: Int = 0) :
+ ArrowPopup<T>(context, attrs, defStyleAttr) {
companion object {
private const val TAG = "TaskbarDividerPopupView"
private const val DIVIDER_POPUP_CLOSING_DELAY = 333L
@@ -55,24 +55,28 @@
fun createAndPopulate(
view: View,
taskbarActivityContext: TaskbarActivityContext,
+ horizontalPosition: Float,
): TaskbarDividerPopupView<*> {
val taskMenuViewWithArrow =
taskbarActivityContext.layoutInflater.inflate(
R.layout.taskbar_divider_popup_menu,
taskbarActivityContext.dragLayer,
- false
+ false,
) as TaskbarDividerPopupView<*>
- return taskMenuViewWithArrow.populateForView(view)
+ return taskMenuViewWithArrow.populateForView(view, horizontalPosition)
}
}
private lateinit var dividerView: View
+ private var horizontalPosition = 0.0f
private val popupCornerRadius = Themes.getDialogCornerRadius(context)
private val arrowWidth = resources.getDimension(R.dimen.popup_arrow_width)
private val arrowHeight = resources.getDimension(R.dimen.popup_arrow_height)
private val arrowPointRadius = resources.getDimension(R.dimen.popup_arrow_corner_radius)
+ private val minPaddingFromScreenEdge =
+ resources.getDimension(R.dimen.taskbar_pinning_popup_menu_min_padding_from_screen_edge)
private var alwaysShowTaskbarOn = !DisplayController.isTransientTaskbar(context)
private var didPreferenceChange = false
@@ -128,7 +132,36 @@
/** Orient object as usual and then center object horizontally. */
override fun orientAboutObject() {
super.orientAboutObject()
- x = mTempRect.centerX() - measuredWidth / 2f
+ x =
+ if (Flags.showTaskbarPinningPopupFromAnywhere()) {
+ val xForCenterAlignment = horizontalPosition - measuredWidth / 2f
+ val maxX = popupContainer.getWidth() - measuredWidth - minPaddingFromScreenEdge
+ when {
+ // Left-aligned popup and its arrow pointing to the event position if there is
+ // not enough space to center it.
+ xForCenterAlignment < minPaddingFromScreenEdge ->
+ max(
+ minPaddingFromScreenEdge,
+ horizontalPosition - mArrowOffsetHorizontal - mArrowWidth / 2,
+ )
+
+ // Right-aligned popup and its arrow pointing to the event position if there
+ // is not enough space to center it.
+ xForCenterAlignment > maxX ->
+ min(
+ horizontalPosition - measuredWidth +
+ mArrowOffsetHorizontal +
+ mArrowWidth / 2,
+ popupContainer.getWidth() - measuredWidth - minPaddingFromScreenEdge,
+ )
+
+ // Default alignment where the popup and its arrow are centered relative to the
+ // event position.
+ else -> xForCenterAlignment
+ }
+ } else {
+ mTempRect.centerX() - measuredWidth / 2f
+ }
}
override fun onControllerInterceptTouchEvent(ev: MotionEvent?): Boolean {
@@ -142,8 +175,9 @@
return false
}
- private fun populateForView(view: View): TaskbarDividerPopupView<*> {
+ private fun populateForView(view: View, horizontalPosition: Float): TaskbarDividerPopupView<*> {
dividerView = view
+ this@TaskbarDividerPopupView.horizontalPosition = horizontalPosition
tryUpdateBackground()
return this
}
@@ -169,15 +203,31 @@
override fun addArrow() {
super.addArrow()
- val location = IntArray(2)
- popupContainer.getLocationInDragLayer(dividerView, location)
- val dividerViewX = location[0].toFloat()
- // Change arrow location to the middle of popup.
- mArrow.x = (dividerViewX + dividerView.width / 2) - (mArrowWidth / 2)
+ if (Flags.showTaskbarPinningPopupFromAnywhere()) {
+ mArrow.x =
+ min(
+ max(
+ minPaddingFromScreenEdge + mArrowOffsetHorizontal,
+ horizontalPosition - mArrowWidth / 2,
+ ),
+ popupContainer.getWidth() -
+ minPaddingFromScreenEdge -
+ mArrowOffsetHorizontal -
+ mArrowWidth,
+ )
+ } else {
+ val location = IntArray(2)
+ popupContainer.getLocationInDragLayer(dividerView, location)
+ val dividerViewX = location[0].toFloat()
+ // Change arrow location to the middle of popup.
+ mArrow.x = (dividerViewX + dividerView.width / 2) - (mArrowWidth / 2)
+ }
}
override fun updateArrowColor() {
- if (!Gravity.isVertical(mGravity)) {
+ if (Flags.showTaskbarPinningPopupFromAnywhere()) {
+ super.updateArrowColor()
+ } else if (!Gravity.isVertical(mGravity)) {
mArrow.background =
RoundedArrowDrawable(
arrowWidth,
@@ -213,7 +263,7 @@
/** Aligning the view pivot to center for animation. */
override fun setPivotForOpenCloseAnimation() {
- pivotX = measuredWidth / 2f
+ pivotX = mArrow.x + mArrowWidth / 2 - x
pivotY = measuredHeight.toFloat()
}
@@ -227,13 +277,13 @@
ObjectAnimator.ofFloat(
this,
TRANSLATION_Y,
- *floatArrayOf(this.translationY, this.translationY + translateYValue)
+ *floatArrayOf(this.translationY, this.translationY + translateYValue),
)
val arrowTranslateY =
ObjectAnimator.ofFloat(
mArrow,
TRANSLATION_Y,
- *floatArrayOf(mArrow.translationY, mArrow.translationY + translateYValue)
+ *floatArrayOf(mArrow.translationY, mArrow.translationY + translateYValue),
)
val animatorSet = AnimatorSet()
animatorSet.playTogether(alpha, arrowAlpha, translateY, arrowTranslateY)
@@ -243,7 +293,7 @@
private fun getAnimatorOfFloat(
view: View,
property: Property<View, Float>,
- vararg values: Float
+ vararg values: Float,
): Animator {
val animator: Animator = ObjectAnimator.ofFloat(view, property, *values)
animator.setDuration(DIVIDER_POPUP_CLOSING_ANIMATION_DURATION)
diff --git a/quickstep/src/com/android/launcher3/taskbar/TaskbarInsetsController.kt b/quickstep/src/com/android/launcher3/taskbar/TaskbarInsetsController.kt
index 1141a01..058dd07 100644
--- a/quickstep/src/com/android/launcher3/taskbar/TaskbarInsetsController.kt
+++ b/quickstep/src/com/android/launcher3/taskbar/TaskbarInsetsController.kt
@@ -47,7 +47,6 @@
import com.android.internal.policy.GestureNavigationSettingsObserver
import com.android.launcher3.DeviceProfile
import com.android.launcher3.R
-import com.android.launcher3.Utilities
import com.android.launcher3.anim.AlphaUpdateListener
import com.android.launcher3.config.FeatureFlags.ENABLE_TASKBAR_NAVBAR_UNIFICATION
import com.android.launcher3.config.FeatureFlags.enableTaskbarNoRecreate
@@ -134,6 +133,9 @@
}
val bubbleControllers = controllers.bubbleControllers.getOrNull()
+ val taskbarTouchableHeight = taskbarStashController.touchableHeight
+ val bubblesTouchableHeight =
+ bubbleControllers?.bubbleStashController?.getTouchableHeight() ?: 0
// reset touch bounds
defaultTouchableRegion.setEmpty()
if (bubbleControllers != null) {
@@ -145,45 +147,16 @@
defaultTouchableRegion.addBoundsToRegion(bubbleBarViewController.bubbleBarBounds)
}
}
- val uiController = controllers.uiController
if (
- !uiController.isHotseatVisibleForTaskBarAlignment ||
+ taskbarStashController.isInApp ||
+ taskbarStashController.isInOverview ||
DisplayController.showLockedTaskbarOnHome(context)
) {
- // adding the taskbar touch region
- val touchableHeight: Int
- var left = 0
- var right = context.deviceProfile.widthPx
- var bubbleBarAdjustment = 0
- if (uiController.isAnimatingToLauncher) {
- val dp = controllers.taskbarActivityContext.deviceProfile
- touchableHeight = windowLayoutParams.height
- if (dp.isQsbInline) {
- // if Qsb is inline need to exclude search icon from touch region
- val isRtl = Utilities.isRtl(context.resources)
- bubbleControllers?.bubbleBarViewController?.let {
- if (dp.shouldAdjustHotseatOnBubblesLocationUpdate(context)) {
- val isBubblesOnLeft = it.bubbleBarLocation.isOnLeft(isRtl)
- bubbleBarAdjustment =
- dp.getHotseatTranslationXForBubbleBar(isBubblesOnLeft, isRtl)
- }
- }
- val hotseatPadding: Rect = dp.getHotseatLayoutPadding(context)
- val borderSpacing: Int = dp.hotseatBorderSpace
- if (isRtl) {
- right =
- dp.widthPx - hotseatPadding.right + borderSpacing + bubbleBarAdjustment
- } else {
- left = hotseatPadding.left - borderSpacing + bubbleBarAdjustment
- }
- }
- } else {
- // if not animating to launcher use the taskbar touchanle height
- touchableHeight = taskbarStashController.touchableHeight
- }
+ // only add the taskbar touch region if not on home
val bottom = windowLayoutParams.height
- val top = bottom - touchableHeight
- defaultTouchableRegion.addBoundsToRegion(Rect(left, top, right, bottom))
+ val top = bottom - taskbarTouchableHeight
+ val right = context.deviceProfile.widthPx
+ defaultTouchableRegion.addBoundsToRegion(Rect(/* left= */ 0, top, right, bottom))
}
// Pre-calculate insets for different providers across different rotations for this gravity
@@ -395,6 +368,10 @@
// Let touches pass through us.
insetsInfo.setTouchableInsets(TOUCHABLE_INSETS_REGION)
debugTouchableRegion.lastSetTouchableReason = "Stashed over IME"
+ } else if (!controllers.uiController.isTaskbarTouchable) {
+ // Let touches pass through us.
+ insetsInfo.setTouchableInsets(TOUCHABLE_INSETS_REGION)
+ debugTouchableRegion.lastSetTouchableReason = "Taskbar is not touchable"
} else if (controllers.taskbarDragController.isSystemDragInProgress) {
// Let touches pass through us.
insetsInfo.setTouchableInsets(TOUCHABLE_INSETS_REGION)
diff --git a/quickstep/src/com/android/launcher3/taskbar/TaskbarLauncherStateController.java b/quickstep/src/com/android/launcher3/taskbar/TaskbarLauncherStateController.java
index 39aef28..fa04739 100644
--- a/quickstep/src/com/android/launcher3/taskbar/TaskbarLauncherStateController.java
+++ b/quickstep/src/com/android/launcher3/taskbar/TaskbarLauncherStateController.java
@@ -16,6 +16,7 @@
package com.android.launcher3.taskbar;
import static com.android.app.animation.Interpolators.EMPHASIZED;
+import static com.android.app.animation.Interpolators.FINAL_FRAME;
import static com.android.launcher3.Flags.enableScalingRevealHomeAnimation;
import static com.android.launcher3.Hotseat.ALPHA_CHANNEL_TASKBAR_ALIGNMENT;
import static com.android.launcher3.Hotseat.ALPHA_CHANNEL_TASKBAR_STASH;
@@ -31,11 +32,8 @@
import static com.android.launcher3.taskbar.bubbles.BubbleBarView.FADE_OUT_ANIM_POSITION_DURATION_MS;
import static com.android.launcher3.util.FlagDebugUtils.appendFlag;
import static com.android.launcher3.util.FlagDebugUtils.formatFlagChange;
+import static com.android.quickstep.util.SystemUiFlagUtils.isTaskbarHidden;
import static com.android.systemui.shared.system.QuickStepContract.SYSUI_STATE_AWAKE;
-import static com.android.systemui.shared.system.QuickStepContract.SYSUI_STATE_COMMUNAL_HUB_SHOWING;
-import static com.android.systemui.shared.system.QuickStepContract.SYSUI_STATE_DEVICE_DREAMING;
-import static com.android.systemui.shared.system.QuickStepContract.SYSUI_STATE_WAKEFULNESS_MASK;
-import static com.android.systemui.shared.system.QuickStepContract.WAKEFULNESS_AWAKE;
import android.animation.Animator;
import android.animation.AnimatorListenerAdapter;
@@ -192,8 +190,6 @@
private boolean mIsQsbInline;
- private boolean mIsHotseatVisibleForTaskbarAlignment;
-
private final DeviceProfile.OnDeviceProfileChangeListener mOnDeviceProfileChangeListener =
new DeviceProfile.OnDeviceProfileChangeListener() {
@Override
@@ -380,16 +376,7 @@
updateStateForFlag(FLAG_DEVICE_LOCKED, SystemUiFlagUtils.isLocked(systemUiStateFlags));
- // Taskbar is hidden whenever the device is dreaming. The dreaming state includes the
- // interactive dreams, AoD, screen off. Since the SYSUI_STATE_DEVICE_DREAMING only kicks in
- // when the device is asleep, the second condition extends ensures that the transition from
- // and to the WAKEFULNESS_ASLEEP state also hide the taskbar, and improves the taskbar
- // hide/reveal animation timings. The Taskbar can show when dreaming if the glanceable hub
- // is showing on top.
- boolean isTaskbarHidden = (hasAnyFlag(systemUiStateFlags, SYSUI_STATE_DEVICE_DREAMING)
- && !hasAnyFlag(systemUiStateFlags, SYSUI_STATE_COMMUNAL_HUB_SHOWING))
- || (systemUiStateFlags & SYSUI_STATE_WAKEFULNESS_MASK) != WAKEFULNESS_AWAKE;
- updateStateForFlag(FLAG_TASKBAR_HIDDEN, isTaskbarHidden);
+ updateStateForFlag(FLAG_TASKBAR_HIDDEN, isTaskbarHidden(systemUiStateFlags));
if (applyState) {
applyState();
@@ -684,7 +671,11 @@
+ mIconAlignment.value
+ " -> " + toAlignment + ": " + duration);
}
- animatorSet.play(iconAlignAnim);
+ if (hasAnyFlag(FLAG_TASKBAR_HIDDEN)) {
+ iconAlignAnim.setInterpolator(FINAL_FRAME);
+ } else {
+ animatorSet.play(iconAlignAnim);
+ }
}
Interpolator interpolator = enableScalingRevealHomeAnimation()
@@ -740,7 +731,6 @@
boolean committed) {
boolean isInStashedState = mLauncherState.isTaskbarStashed(mLauncher);
TaskbarStashController stashController = mControllers.taskbarStashController;
- TaskbarInsetsController insetsController = mControllers.taskbarInsetsController;
stashController.updateStateForFlag(FLAG_IN_STASHED_LAUNCHER_STATE, isInStashedState);
Animator stashAnimator = stashController.createApplyStateAnimator(duration);
if (stashAnimator != null) {
@@ -749,11 +739,7 @@
public void onAnimationEnd(Animator animation) {
if (isInStashedState && committed) {
// Reset hotseat alpha to default
- updateIconAlphaForHome(
- /* taskbarAlpha = */ 0,
- ALPHA_CHANNEL_TASKBAR_ALIGNMENT,
- /* updateTaskbarAlpha = */ false
- );
+ mLauncher.getHotseat().setIconsAlpha(1, ALPHA_CHANNEL_TASKBAR_ALIGNMENT);
}
}
@@ -878,14 +864,6 @@
if (mIsQsbInline) {
mLauncher.getHotseat().setQsbAlpha(targetAlpha, alphaChannel);
}
- if (alphaChannel == ALPHA_CHANNEL_TASKBAR_ALIGNMENT) {
- boolean isHotseatVisibleForTaskbarAlignment = isHotseatVisibleForTaskbarAlignment();
- if (mIsHotseatVisibleForTaskbarAlignment != isHotseatVisibleForTaskbarAlignment) {
- mIsHotseatVisibleForTaskbarAlignment = isHotseatVisibleForTaskbarAlignment;
- mControllers.taskbarInsetsController
- .onTaskbarOrBubblebarWindowHeightOrInsetsChanged();
- }
- }
}
/** Updates launcher home screen appearance accordingly to the bubble bar location. */
@@ -893,19 +871,18 @@
mBubbleBarLocation = location;
if (location == null) {
// bubble bar is not present, hence no location, resetting the hotseat
- updateHotseatAndQsbTranslationX(0, animate);
+ updateHotseatAndQsbTranslationX(/* targetValue = */ 0, animate);
mBubbleBarLocation = null;
return;
}
DeviceProfile deviceProfile = mLauncher.getDeviceProfile();
- if (!deviceProfile.shouldAdjustHotseatOnBubblesLocationUpdate(
+ if (!deviceProfile.shouldAdjustHotseatOnNavBarLocationUpdate(
mControllers.taskbarActivityContext)) {
return;
}
- boolean isRtl = isRtl(mLauncher.getResources());
- boolean isBubblesOnLeft = location.isOnLeft(isRtl);
+ boolean isBubblesOnLeft = location.isOnLeft(isRtl(mLauncher.getResources()));
int targetX = deviceProfile
- .getHotseatTranslationXForBubbleBar(isBubblesOnLeft, isRtl);
+ .getHotseatTranslationXForNavBar(mLauncher, isBubblesOnLeft);
updateHotseatAndQsbTranslationX(targetX, animate);
}
@@ -947,13 +924,6 @@
translationXAnimation.start();
}
- /** Returns true if hotseat icons visible for the taskbar alignment */
- public boolean isHotseatVisibleForTaskbarAlignment() {
- return mLauncher.getHotseat()
- .getIconsAlpha(ALPHA_CHANNEL_TASKBAR_ALIGNMENT).getValue() == 1;
- }
-
-
private final class TaskBarRecentsAnimationListener implements
RecentsAnimationCallbacks.RecentsAnimationListener {
private final RecentsAnimationCallbacks mCallbacks;
diff --git a/quickstep/src/com/android/launcher3/taskbar/TaskbarPinningController.kt b/quickstep/src/com/android/launcher3/taskbar/TaskbarPinningController.kt
index 1867cd0..7848b7e 100644
--- a/quickstep/src/com/android/launcher3/taskbar/TaskbarPinningController.kt
+++ b/quickstep/src/com/android/launcher3/taskbar/TaskbarPinningController.kt
@@ -76,10 +76,10 @@
}
}
- fun showPinningView(view: View) {
+ fun showPinningView(view: View, horizontalPosition: Float = -1f) {
context.isTaskbarWindowFullscreen = true
view.post {
- val popupView = getPopupView(view)
+ val popupView = getPopupView(view, horizontalPosition)
popupView.requestFocus()
popupView.onCloseCallback = onCloseCallback
context.onPopupVisibilityChanged(true)
@@ -89,8 +89,8 @@
}
@VisibleForTesting
- fun getPopupView(view: View): TaskbarDividerPopupView<*> {
- return createAndPopulate(view, context)
+ fun getPopupView(view: View, horizontalPosition: Float = -1f): TaskbarDividerPopupView<*> {
+ return createAndPopulate(view, context, horizontalPosition)
}
@VisibleForTesting
diff --git a/quickstep/src/com/android/launcher3/taskbar/TaskbarStashController.java b/quickstep/src/com/android/launcher3/taskbar/TaskbarStashController.java
index 8991965..b19da6b 100644
--- a/quickstep/src/com/android/launcher3/taskbar/TaskbarStashController.java
+++ b/quickstep/src/com/android/launcher3/taskbar/TaskbarStashController.java
@@ -30,6 +30,7 @@
import static com.android.launcher3.util.FlagDebugUtils.appendFlag;
import static com.android.launcher3.util.FlagDebugUtils.formatFlagChange;
import static com.android.quickstep.util.SystemActionConstants.SYSTEM_ACTION_ID_TASKBAR;
+import static com.android.quickstep.util.SystemUiFlagUtils.isTaskbarHidden;
import static com.android.systemui.shared.system.QuickStepContract.SYSUI_STATE_BUBBLES_EXPANDED;
import static com.android.systemui.shared.system.QuickStepContract.SYSUI_STATE_DIALOG_SHOWING;
import static com.android.systemui.shared.system.QuickStepContract.SYSUI_STATE_IME_SHOWING;
@@ -104,6 +105,7 @@
// An internal no-op flag to determine whether we should delay the taskbar background animation
private static final int FLAG_DELAY_TASKBAR_BG_TAG = 1 << 12;
public static final int FLAG_STASHED_FOR_BUBBLES = 1 << 13; // show handle for stashed hotseat
+ public static final int FLAG_TASKBAR_HIDDEN = 1 << 14; // taskbar hidden during dream, etc...
// If any of these flags are enabled, isInApp should return true.
private static final int FLAGS_IN_APP = FLAG_IN_APP | FLAG_IN_SETUP;
@@ -215,6 +217,13 @@
*/
private static final int TRANSITION_UNSTASH_SUW_MANUAL = 3;
+ /**
+ * total duration of entering dream state animation, which we use as start delay to
+ * applyState() when SYSUI_STATE_DEVICE_DREAMING flag is present. Keep this in sync with
+ * DreamAnimationController.TOTAL_ANIM_DURATION.
+ */
+ private static final int SKIP_TOTAL_DREAM_ANIM_DURATION = 450;
+
@Retention(RetentionPolicy.SOURCE)
@IntDef(value = {
TRANSITION_DEFAULT,
@@ -1123,7 +1132,13 @@
startDelay = getTaskbarStashStartDelayForIme();
}
- applyState(skipAnim ? 0 : animDuration, skipAnim ? 0 : startDelay);
+ if (isTaskbarHidden(systemUiStateFlags) && !hasAnyFlag(FLAG_TASKBAR_HIDDEN)) {
+ updateStateForFlag(FLAG_TASKBAR_HIDDEN, isTaskbarHidden(systemUiStateFlags));
+ applyState(0, SKIP_TOTAL_DREAM_ANIM_DURATION);
+ } else {
+ updateStateForFlag(FLAG_TASKBAR_HIDDEN, isTaskbarHidden(systemUiStateFlags));
+ applyState(skipAnim ? 0 : animDuration, skipAnim ? 0 : startDelay);
+ }
}
/**
diff --git a/quickstep/src/com/android/launcher3/taskbar/TaskbarUIController.java b/quickstep/src/com/android/launcher3/taskbar/TaskbarUIController.java
index db69e8f..7030088 100644
--- a/quickstep/src/com/android/launcher3/taskbar/TaskbarUIController.java
+++ b/quickstep/src/com/android/launcher3/taskbar/TaskbarUIController.java
@@ -75,14 +75,8 @@
mControllers = null;
}
- /** Returns true if transition animation to launcher home is being played. */
- public boolean isAnimatingToLauncher() {
- return false;
- }
-
- /** Returns true if hotseat icons visible for the taskbar alignment. */
- public boolean isHotseatVisibleForTaskBarAlignment() {
- return false;
+ protected boolean isTaskbarTouchable() {
+ return true;
}
/**
diff --git a/quickstep/src/com/android/launcher3/taskbar/TaskbarView.java b/quickstep/src/com/android/launcher3/taskbar/TaskbarView.java
index d757180..fcb583a 100644
--- a/quickstep/src/com/android/launcher3/taskbar/TaskbarView.java
+++ b/quickstep/src/com/android/launcher3/taskbar/TaskbarView.java
@@ -100,7 +100,7 @@
@Nullable private FolderIcon mLeaveBehindFolderIcon;
// Only non-null when device supports having an All Apps button.
- @Nullable private final TaskbarAllAppsButtonContainer mAllAppsButtonContainer;
+ private final TaskbarAllAppsButtonContainer mAllAppsButtonContainer;
// Only non-null when device supports having a Divider button.
@Nullable private TaskbarDividerContainer mTaskbarDividerContainer;
@@ -185,6 +185,7 @@
resources.getDrawable(R.drawable.taskbar_overflow_icon));
mTaskbarOverflowView.setPadding(mItemPadding, mItemPadding, mItemPadding, mItemPadding);
}
+ // TODO: Disable touch events on QSB otherwise it can crash.
mQsb = LayoutInflater.from(context).inflate(R.layout.search_container_hotseat, this, false);
mMaxNumIcons = calculateMaxNumIcons();
@@ -217,16 +218,14 @@
// All apps icon takes less space compared to normal icon size, reserve space for the icon
// separately.
- if (mAllAppsButtonContainer != null) {
- boolean forceTransientTaskbarSize =
- enableTaskbarPinning() && !mActivityContext.isThreeButtonNav();
- availableWidth -= iconSize - (int) getResources().getDimension(
- mAllAppsButtonContainer.getAllAppsButtonTranslationXOffset(
- forceTransientTaskbarSize || (
- DisplayController.isTransientTaskbar(mActivityContext)
- && !mActivityContext.isPhoneMode())));
- ++additionalIcons;
- }
+ boolean forceTransientTaskbarSize =
+ enableTaskbarPinning() && !mActivityContext.isThreeButtonNav();
+ availableWidth -= iconSize - (int) getResources().getDimension(
+ mAllAppsButtonContainer.getAllAppsButtonTranslationXOffset(
+ forceTransientTaskbarSize || (
+ DisplayController.isTransientTaskbar(mActivityContext)
+ && !mActivityContext.isPhoneMode())));
+ ++additionalIcons;
return Math.floorDiv(availableWidth, iconSize) + additionalIcons;
}
@@ -313,10 +312,9 @@
mIconClickListener = mControllerCallbacks.getIconOnClickListener();
mIconLongClickListener = mControllerCallbacks.getIconOnLongClickListener();
- if (mAllAppsButtonContainer != null) {
- mAllAppsButtonContainer.setUpCallbacks(callbacks);
- }
- if (mTaskbarDividerContainer != null && callbacks.supportsDividerLongPress()) {
+ mAllAppsButtonContainer.setUpCallbacks(callbacks);
+ if (mTaskbarDividerContainer != null
+ && mActivityContext.getTaskbarFeatureEvaluator().getSupportsPinningPopup()) {
mTaskbarDividerContainer.setUpCallbacks(callbacks);
}
if (mTaskbarOverflowView != null) {
@@ -325,6 +323,10 @@
mTaskbarOverflowView.setOnLongClickListener(
mControllerCallbacks.getOverflowOnLongClickListener());
}
+ if (Flags.showTaskbarPinningPopupFromAnywhere()
+ && mActivityContext.getTaskbarFeatureEvaluator().getSupportsPinningPopup()) {
+ setOnTouchListener(mControllerCallbacks.getTaskbarTouchListener());
+ }
}
private void removeAndRecycle(View view) {
@@ -345,12 +347,10 @@
int numViewsAnimated = 0;
mAddedDividerForRecents = false;
- if (mAllAppsButtonContainer != null) {
- removeView(mAllAppsButtonContainer);
+ removeView(mAllAppsButtonContainer);
- if (mTaskbarDividerContainer != null) {
- removeView(mTaskbarDividerContainer);
- }
+ if (mTaskbarDividerContainer != null) {
+ removeView(mTaskbarDividerContainer);
}
if (mTaskbarOverflowView != null) {
removeView(mTaskbarOverflowView);
@@ -527,17 +527,16 @@
removeAndRecycle(getChildAt(nextViewIndex));
}
- if (mAllAppsButtonContainer != null) {
- addView(mAllAppsButtonContainer, mIsRtl ? hotseatItemInfos.length : 0);
+ addView(mAllAppsButtonContainer, mIsRtl ? hotseatItemInfos.length : 0);
- // If there are no recent tasks, add divider after All Apps (unless it's the only view).
- if (!mAddedDividerForRecents
- && mTaskbarDividerContainer != null
- && getChildCount() > 1) {
- addView(mTaskbarDividerContainer, mIsRtl ? (getChildCount() - 1) : 1);
- }
+ // If there are no recent tasks, add divider after All Apps (unless it's the only view).
+ if (!mAddedDividerForRecents
+ && mTaskbarDividerContainer != null
+ && getChildCount() > 1) {
+ addView(mTaskbarDividerContainer, mIsRtl ? (getChildCount() - 1) : 1);
}
+
if (mActivityContext.getDeviceProfile().isQsbInline) {
addView(mQsb, mIsRtl ? getChildCount() : 0);
// Always set QSB to invisible after re-adding.
@@ -774,7 +773,6 @@
/**
* Returns the all apps button in the taskbar.
*/
- @Nullable
public TaskbarAllAppsButtonContainer getAllAppsButtonContainer() {
return mAllAppsButtonContainer;
}
diff --git a/quickstep/src/com/android/launcher3/taskbar/TaskbarViewCallbacks.java b/quickstep/src/com/android/launcher3/taskbar/TaskbarViewCallbacks.java
index 8bc1e12..4591f9b 100644
--- a/quickstep/src/com/android/launcher3/taskbar/TaskbarViewCallbacks.java
+++ b/quickstep/src/com/android/launcher3/taskbar/TaskbarViewCallbacks.java
@@ -19,15 +19,19 @@
import static com.android.launcher3.logging.StatsLogManager.LauncherEvent.LAUNCHER_TASKBAR_ALLAPPS_BUTTON_LONG_PRESS;
import static com.android.launcher3.logging.StatsLogManager.LauncherEvent.LAUNCHER_TASKBAR_ALLAPPS_BUTTON_TAP;
+import android.annotation.SuppressLint;
import android.content.Context;
+import android.view.GestureDetector;
import android.view.InputDevice;
import android.view.MotionEvent;
import android.view.View;
+import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import com.android.internal.jank.Cuj;
import com.android.launcher3.taskbar.bubbles.BubbleBarViewController;
+import com.android.launcher3.util.DisplayController;
import com.android.systemui.shared.system.InteractionJankMonitorWrapper;
import com.android.wm.shell.Flags;
import com.android.wm.shell.shared.bubbles.BubbleBarLocation;
@@ -40,12 +44,14 @@
private final TaskbarActivityContext mActivity;
private final TaskbarControllers mControllers;
private final TaskbarView mTaskbarView;
+ private final GestureDetector mGestureDetector;
public TaskbarViewCallbacks(TaskbarActivityContext activity, TaskbarControllers controllers,
TaskbarView taskbarView) {
mActivity = activity;
mControllers = controllers;
mTaskbarView = taskbarView;
+ mGestureDetector = new GestureDetector(activity, new TaskbarViewGestureListener());
}
public View.OnClickListener getIconOnClickListener() {
@@ -70,23 +76,23 @@
return false;
}
- public View.OnLongClickListener getTaskbarDividerLongClickListener() {
- return v -> {
- mControllers.taskbarPinningController.showPinningView(v);
- return true;
- };
+ @SuppressLint("ClickableViewAccessibility")
+ public View.OnTouchListener getTaskbarTouchListener() {
+ return (view, event) -> mGestureDetector.onTouchEvent(event);
}
- /** Check to see if we support long press on taskbar divider */
- public boolean supportsDividerLongPress() {
- return !mActivity.isThreeButtonNav();
+ public View.OnLongClickListener getTaskbarDividerLongClickListener() {
+ return v -> {
+ mControllers.taskbarPinningController.showPinningView(v, getDividerCenterX());
+ return true;
+ };
}
public View.OnTouchListener getTaskbarDividerRightClickListener() {
return (v, event) -> {
if (event.isFromSource(InputDevice.SOURCE_MOUSE)
&& event.getButtonState() == MotionEvent.BUTTON_SECONDARY) {
- mControllers.taskbarPinningController.showPinningView(v);
+ mControllers.taskbarPinningController.showPinningView(v, getDividerCenterX());
return true;
}
return false;
@@ -159,4 +165,32 @@
}
};
}
+
+ private float getDividerCenterX() {
+ View divider = mTaskbarView.getTaskbarDividerViewContainer();
+ if (divider == null) {
+ return 0.0f;
+ }
+ return divider.getX() + (float) divider.getWidth() / 2;
+ }
+
+ private class TaskbarViewGestureListener extends GestureDetector.SimpleOnGestureListener {
+ @Override
+ public boolean onDown(@NonNull MotionEvent event) {
+ return true;
+ }
+
+ @Override
+ public boolean onSingleTapUp(@NonNull MotionEvent event) {
+ return true;
+ }
+
+ @Override
+ public void onLongPress(MotionEvent event) {
+ if (DisplayController.isPinnedTaskbar(mActivity)) {
+ mControllers.taskbarPinningController.showPinningView(mTaskbarView,
+ event.getRawX());
+ }
+ }
+ }
}
diff --git a/quickstep/src/com/android/launcher3/taskbar/TaskbarViewController.java b/quickstep/src/com/android/launcher3/taskbar/TaskbarViewController.java
index c275536..253d025 100644
--- a/quickstep/src/com/android/launcher3/taskbar/TaskbarViewController.java
+++ b/quickstep/src/com/android/launcher3/taskbar/TaskbarViewController.java
@@ -367,7 +367,6 @@
return mTaskbarView.getIconViews();
}
- @Nullable
public View getAllAppsButtonView() {
return mTaskbarView.getAllAppsButtonContainer();
}
@@ -837,12 +836,11 @@
int firstRecentTaskIndex = -1;
int hotseatNavBarTranslationX = 0;
- if (mCurrentBubbleBarLocation != null
- && taskbarDp.shouldAdjustHotseatOnBubblesLocationUpdate(mActivity)) {
- boolean isRtl = mTaskbarView.isLayoutRtl();
- boolean isBubblesOnLeft = mCurrentBubbleBarLocation.isOnLeft(isRtl);
+ if (mCurrentBubbleBarLocation != null) {
+ boolean isBubblesOnLeft = mCurrentBubbleBarLocation
+ .isOnLeft(mTaskbarView.isLayoutRtl());
hotseatNavBarTranslationX = taskbarDp
- .getHotseatTranslationXForBubbleBar(isBubblesOnLeft, isRtl);
+ .getHotseatTranslationXForNavBar(mActivity, isBubblesOnLeft);
}
for (int i = 0; i < mTaskbarView.getChildCount(); i++) {
View child = mTaskbarView.getChildAt(i);
diff --git a/quickstep/src/com/android/launcher3/taskbar/bubbles/BubbleBarController.java b/quickstep/src/com/android/launcher3/taskbar/bubbles/BubbleBarController.java
index 51e09ab..b22fd6f 100644
--- a/quickstep/src/com/android/launcher3/taskbar/bubbles/BubbleBarController.java
+++ b/quickstep/src/com/android/launcher3/taskbar/bubbles/BubbleBarController.java
@@ -377,8 +377,6 @@
// Updates mean the dot state may have changed; any other changes were updated in
// the populateBubble step.
BubbleBarBubble bb = mBubbles.get(update.updatedBubble.getKey());
- // If we're not stashed, we're visible so animate
- bb.getView().updateDotVisibility(!mBubbleStashController.isStashed() /* animate */);
mBubbleBarViewController.animateBubbleNotification(
bb, /* isExpanding= */ false, /* isUpdate= */ true);
}
diff --git a/quickstep/src/com/android/launcher3/taskbar/bubbles/BubbleBarViewController.java b/quickstep/src/com/android/launcher3/taskbar/bubbles/BubbleBarViewController.java
index 63f101f..76d3606 100644
--- a/quickstep/src/com/android/launcher3/taskbar/bubbles/BubbleBarViewController.java
+++ b/quickstep/src/com/android/launcher3/taskbar/bubbles/BubbleBarViewController.java
@@ -148,7 +148,8 @@
mBubbleBarFlyoutController = new BubbleBarFlyoutController(
mBubbleBarContainer, createFlyoutPositioner(), createFlyoutTopBoundaryListener());
mBubbleBarViewAnimator = new BubbleBarViewAnimator(
- mBarView, mBubbleStashController, mBubbleBarController::showExpandedView);
+ mBarView, mBubbleStashController, mBubbleBarFlyoutController,
+ mBubbleBarController::showExpandedView);
mTaskbarViewPropertiesProvider = taskbarViewPropertiesProvider;
onBubbleBarConfigurationChanged(/* animate= */ false);
mActivity.addOnDeviceProfileChangeListener(
@@ -781,6 +782,11 @@
/** Animates the bubble bar to notify the user about a bubble change. */
public void animateBubbleNotification(BubbleBarBubble bubble, boolean isExpanding,
boolean isUpdate) {
+ // if we're expanded, don't animate the bubble bar. just show the notification dot.
+ if (isExpanded()) {
+ bubble.getView().updateDotVisibility(/* animate= */ true);
+ return;
+ }
boolean isInApp = mTaskbarStashController.isInApp();
// if this is the first bubble, animate to the initial state.
if (mBarView.getBubbleChildCount() == 1 && !isUpdate) {
@@ -789,13 +795,12 @@
}
boolean persistentTaskbarOrOnHome = mBubbleStashController.isBubblesShowingOnHome()
|| !mBubbleStashController.isTransientTaskBar();
- if (persistentTaskbarOrOnHome && !isExpanded()) {
+ if (persistentTaskbarOrOnHome) {
mBubbleBarViewAnimator.animateBubbleBarForCollapsed(bubble, isExpanding);
return;
}
- // only animate the new bubble if we're in an app, have handle view and not auto expanding
- if (isInApp && mBubbleStashController.getHasHandleView() && !isExpanded()) {
+ if (isInApp && mBubbleStashController.getHasHandleView()) {
mBubbleBarViewAnimator.animateBubbleInForStashed(bubble, isExpanding);
}
}
diff --git a/quickstep/src/com/android/launcher3/taskbar/bubbles/BubbleView.java b/quickstep/src/com/android/launcher3/taskbar/bubbles/BubbleView.java
index 707655c..4f3e1ae 100644
--- a/quickstep/src/com/android/launcher3/taskbar/bubbles/BubbleView.java
+++ b/quickstep/src/com/android/launcher3/taskbar/bubbles/BubbleView.java
@@ -301,7 +301,7 @@
void updateDotVisibility(boolean animate) {
if (mDotSuppressedForBubbleUpdate) {
- // if the dot is suppressed for
+ // if the dot is suppressed for an update, there's nothing to do
return;
}
final float targetScale = hasUnseenContent() ? 1f : 0f;
diff --git a/quickstep/src/com/android/launcher3/taskbar/bubbles/animation/BubbleBarViewAnimator.kt b/quickstep/src/com/android/launcher3/taskbar/bubbles/animation/BubbleBarViewAnimator.kt
index 6a955d9..8a52ca9 100644
--- a/quickstep/src/com/android/launcher3/taskbar/bubbles/animation/BubbleBarViewAnimator.kt
+++ b/quickstep/src/com/android/launcher3/taskbar/bubbles/animation/BubbleBarViewAnimator.kt
@@ -27,6 +27,8 @@
import com.android.launcher3.taskbar.bubbles.BubbleBarBubble
import com.android.launcher3.taskbar.bubbles.BubbleBarView
import com.android.launcher3.taskbar.bubbles.BubbleView
+import com.android.launcher3.taskbar.bubbles.flyout.BubbleBarFlyoutController
+import com.android.launcher3.taskbar.bubbles.flyout.BubbleBarFlyoutMessage
import com.android.launcher3.taskbar.bubbles.stashing.BubbleStashController
import com.android.wm.shell.shared.animation.PhysicsAnimator
@@ -36,8 +38,9 @@
constructor(
private val bubbleBarView: BubbleBarView,
private val bubbleStashController: BubbleStashController,
+ private val bubbleBarFlyoutController: BubbleBarFlyoutController,
private val onExpanded: Runnable,
- private val scheduler: Scheduler = HandlerScheduler(bubbleBarView)
+ private val scheduler: Scheduler = HandlerScheduler(bubbleBarView),
) {
private var animatingBubble: AnimatingBubble? = null
@@ -54,7 +57,7 @@
private companion object {
/** The time to show the flyout. */
- const val FLYOUT_DELAY_MS: Long = 2500
+ const val FLYOUT_DELAY_MS: Long = 3000
/** The initial scale Y value that the new bubble is set to before the animation starts. */
const val BUBBLE_ANIMATION_INITIAL_SCALE_Y = 0.3f
/** The minimum alpha value to make the bubble bar touchable. */
@@ -69,7 +72,7 @@
val showAnimation: Runnable,
val hideAnimation: Runnable,
val expand: Boolean,
- val state: State = State.CREATED
+ val state: State = State.CREATED,
) {
/**
@@ -91,7 +94,7 @@
/** The bubble notification is now fully showing and waiting to be hidden. */
IN,
/** The bubble notification is animating out. */
- ANIMATING_OUT
+ ANIMATING_OUT,
}
}
@@ -127,7 +130,7 @@
private val springConfig =
PhysicsAnimator.SpringConfig(
stiffness = SpringForce.STIFFNESS_LOW,
- dampingRatio = SpringForce.DAMPING_RATIO_MEDIUM_BOUNCY
+ dampingRatio = SpringForce.DAMPING_RATIO_MEDIUM_BOUNCY,
)
/** Animates a bubble for the state where the bubble bar is stashed. */
@@ -137,8 +140,9 @@
val bubbleView = b.view
val animator = PhysicsAnimator.getInstance(bubbleView)
if (animator.isRunning()) animator.cancel()
- // the animation of a new bubble is divided into 2 parts. The first part shows the bubble
- // and the second part hides it after a delay.
+ // the animation of a new bubble is divided into 2 parts. The first part transforms the
+ // handle to the bubble bar and then shows the flyout. The second part hides the flyout and
+ // transforms the bubble bar back to the handle.
val showAnimation = buildHandleToBubbleBarAnimation()
val hideAnimation = if (isExpanding) Runnable {} else buildBubbleBarToHandleAnimation()
animatingBubble =
@@ -243,7 +247,8 @@
cancelHideAnimation()
return@addEndListener
}
- moveToState(AnimatingBubble.State.IN)
+ setupAndShowFlyout()
+
// the bubble bar is now fully settled in. update taskbar touch region so it's touchable
bubbleStashController.updateTaskbarTouchRegion()
}
@@ -316,7 +321,17 @@
bubbleBarView.scaleY = 1f
bubbleStashController.updateTaskbarTouchRegion()
}
- animator.start()
+
+ val bubble = animatingBubble?.bubbleView?.bubble as? BubbleBarBubble
+ val flyout = bubble?.flyoutMessage
+ if (flyout != null) {
+ bubbleBarFlyoutController.collapseFlyout {
+ onFlyoutRemoved(bubble.view)
+ animator.start()
+ }
+ } else {
+ animator.start()
+ }
}
/** Animates to the initial state of the bubble bar, when there are no previous bubbles. */
@@ -326,16 +341,16 @@
val bubbleView = b.view
val animator = PhysicsAnimator.getInstance(bubbleView)
if (animator.isRunning()) animator.cancel()
- // the animation of a new bubble is divided into 2 parts. The first part shows the bubble
- // and the second part hides it after a delay if we are in an app.
+ // the animation of a new bubble is divided into 2 parts. The first part slides in the
+ // bubble bar and shows the flyout. The second part hides the flyout and transforms the
+ // bubble bar to the handle if we're in an app.
val showAnimation = buildBubbleBarSpringInAnimation()
val hideAnimation =
if (isInApp && !isExpanding) {
buildBubbleBarToHandleAnimation()
} else {
- // in this case the bubble bar remains visible so not much to do. once we implement
- // the flyout we'll update this runnable to hide it.
Runnable {
+ bubbleBarFlyoutController.collapseFlyout { onFlyoutRemoved(bubbleView) }
animatingBubble = null
bubbleStashController.showBubbleBarImmediate()
bubbleStashController.updateTaskbarTouchRegion()
@@ -370,7 +385,7 @@
if (animatingBubble?.expand == true) {
cancelHideAnimation()
} else {
- moveToState(AnimatingBubble.State.IN)
+ setupAndShowFlyout()
}
// the bubble bar is now fully settled in. update taskbar touch region so it's touchable
bubbleStashController.updateTaskbarTouchRegion()
@@ -384,8 +399,10 @@
val bubbleView = b.view
val animator = PhysicsAnimator.getInstance(bubbleView)
if (animator.isRunning()) animator.cancel()
+ // first bounce the bubble bar and show the flyout. Then hide the flyout.
val showAnimation = buildBubbleBarBounceAnimation()
val hideAnimation = Runnable {
+ bubbleBarFlyoutController.collapseFlyout { onFlyoutRemoved(bubbleView) }
animatingBubble = null
bubbleStashController.showBubbleBarImmediate()
bubbleStashController.updateTaskbarTouchRegion()
@@ -413,7 +430,7 @@
expandBubbleBar()
cancelHideAnimation()
} else {
- moveToState(AnimatingBubble.State.IN)
+ setupAndShowFlyout()
}
}
@@ -427,10 +444,38 @@
.start()
}
+ private fun setupAndShowFlyout() {
+ val bubbleView = animatingBubble?.bubbleView
+ val bubble = bubbleView?.bubble as? BubbleBarBubble
+ val flyout = bubble?.flyoutMessage
+ if (flyout != null) {
+ bubbleView.suppressDotForBubbleUpdate(true)
+ bubbleBarFlyoutController.setUpAndShowFlyout(
+ BubbleBarFlyoutMessage(flyout.icon, flyout.title, flyout.message)
+ ) {
+ moveToState(AnimatingBubble.State.IN)
+ bubbleStashController.updateTaskbarTouchRegion()
+ }
+ } else {
+ moveToState(AnimatingBubble.State.IN)
+ }
+ }
+
+ private fun cancelFlyout() {
+ val bubbleView = animatingBubble?.bubbleView
+ bubbleBarFlyoutController.cancelFlyout { onFlyoutRemoved(bubbleView) }
+ }
+
+ private fun onFlyoutRemoved(bubbleView: BubbleView?) {
+ bubbleView?.suppressDotForBubbleUpdate(false)
+ bubbleStashController.updateTaskbarTouchRegion()
+ }
+
/** Handles touching the animating bubble bar. */
fun onBubbleBarTouchedWhileAnimating() {
PhysicsAnimator.getInstance(bubbleBarView).cancelIfRunning()
bubbleStashController.getStashedHandlePhysicsAnimator().cancelIfRunning()
+ cancelFlyout()
val hideAnimation = animatingBubble?.hideAnimation ?: return
scheduler.cancel(hideAnimation)
bubbleBarView.relativePivotY = 1f
@@ -439,6 +484,7 @@
/** Notifies the animator that the taskbar area was touched during an animation. */
fun onStashStateChangingWhileAnimating() {
+ cancelFlyout()
val hideAnimation = animatingBubble?.hideAnimation ?: return
scheduler.cancel(hideAnimation)
animatingBubble = null
@@ -446,7 +492,7 @@
bubbleBarView.relativePivotY = 1f
bubbleStashController.onNewBubbleAnimationInterrupted(
/* isStashed= */ bubbleBarView.alpha == 0f,
- bubbleBarView.translationY
+ bubbleBarView.translationY,
)
}
@@ -455,6 +501,7 @@
this.animatingBubble = animatingBubble.copy(expand = true)
// if we're fully in and waiting to hide, cancel the hide animation and clean up
if (animatingBubble.state == AnimatingBubble.State.IN) {
+ cancelFlyout()
expandBubbleBar()
cancelHideAnimation()
}
diff --git a/quickstep/src/com/android/launcher3/taskbar/bubbles/flyout/BubbleBarFlyoutController.kt b/quickstep/src/com/android/launcher3/taskbar/bubbles/flyout/BubbleBarFlyoutController.kt
index c431deb..d6400bb 100644
--- a/quickstep/src/com/android/launcher3/taskbar/bubbles/flyout/BubbleBarFlyoutController.kt
+++ b/quickstep/src/com/android/launcher3/taskbar/bubbles/flyout/BubbleBarFlyoutController.kt
@@ -21,8 +21,8 @@
import android.widget.FrameLayout
import androidx.core.animation.ValueAnimator
import com.android.launcher3.R
+import com.android.systemui.util.addListener
import com.android.systemui.util.doOnEnd
-import com.android.systemui.util.doOnStart
/** Creates and manages the visibility of the [BubbleBarFlyoutView]. */
class BubbleBarFlyoutController
@@ -35,14 +35,19 @@
) {
private companion object {
- const val EXPAND_COLLAPSE_ANIMATION_DURATION_MS = 250L
+ const val ANIMATION_DURATION_MS = 250L
}
private var flyout: BubbleBarFlyoutView? = null
private val horizontalMargin =
container.context.resources.getDimensionPixelSize(R.dimen.transient_taskbar_bottom_margin)
- fun setUpFlyout(message: BubbleBarFlyoutMessage) {
+ private enum class AnimationType {
+ COLLAPSE,
+ FADE,
+ }
+
+ fun setUpAndShowFlyout(message: BubbleBarFlyoutMessage, onEnd: () -> Unit) {
flyout?.let(container::removeView)
val flyout = BubbleBarFlyoutView(container.context, positioner, flyoutScheduler)
@@ -58,27 +63,42 @@
lp.marginEnd = horizontalMargin
container.addView(flyout, lp)
- val animator =
- ValueAnimator.ofFloat(0f, 1f).setDuration(EXPAND_COLLAPSE_ANIMATION_DURATION_MS)
+ val animator = ValueAnimator.ofFloat(0f, 1f).setDuration(ANIMATION_DURATION_MS)
animator.addUpdateListener { _ ->
flyout.updateExpansionProgress(animator.animatedValue as Float)
}
- animator.doOnStart {
- val flyoutTop = flyout.top + flyout.translationY
- // If the top position of the flyout is negative, then it's bleeding over the
- // top boundary of its parent view
- if (flyoutTop < 0) topBoundaryListener.extendTopBoundary(space = -flyoutTop.toInt())
- }
+ animator.addListener(
+ onStart = {
+ val flyoutTop = flyout.top + flyout.translationY
+ // If the top position of the flyout is negative, then it's bleeding over the
+ // top boundary of its parent view
+ if (flyoutTop < 0) topBoundaryListener.extendTopBoundary(space = -flyoutTop.toInt())
+ },
+ onEnd = { onEnd() },
+ )
flyout.showFromCollapsed(message) { animator.start() }
this.flyout = flyout
}
- fun hideFlyout(endAction: () -> Unit) {
+ fun cancelFlyout(endAction: () -> Unit) {
+ hideFlyout(AnimationType.FADE, endAction)
+ }
+
+ fun collapseFlyout(endAction: () -> Unit) {
+ hideFlyout(AnimationType.COLLAPSE, endAction)
+ }
+
+ private fun hideFlyout(animationType: AnimationType, endAction: () -> Unit) {
+ // TODO: b/277815200 - stop the current animation if it's running
val flyout = this.flyout ?: return
- val animator =
- ValueAnimator.ofFloat(1f, 0f).setDuration(EXPAND_COLLAPSE_ANIMATION_DURATION_MS)
- animator.addUpdateListener { _ ->
- flyout.updateExpansionProgress(animator.animatedValue as Float)
+ val animator = ValueAnimator.ofFloat(1f, 0f).setDuration(ANIMATION_DURATION_MS)
+ when (animationType) {
+ AnimationType.FADE ->
+ animator.addUpdateListener { _ -> flyout.alpha = animator.animatedValue as Float }
+ AnimationType.COLLAPSE ->
+ animator.addUpdateListener { _ ->
+ flyout.updateExpansionProgress(animator.animatedValue as Float)
+ }
}
animator.doOnEnd {
container.removeView(flyout)
diff --git a/quickstep/src/com/android/launcher3/taskbar/bubbles/flyout/BubbleBarFlyoutView.kt b/quickstep/src/com/android/launcher3/taskbar/bubbles/flyout/BubbleBarFlyoutView.kt
index c60fba2..6903c87 100644
--- a/quickstep/src/com/android/launcher3/taskbar/bubbles/flyout/BubbleBarFlyoutView.kt
+++ b/quickstep/src/com/android/launcher3/taskbar/bubbles/flyout/BubbleBarFlyoutView.kt
@@ -140,6 +140,7 @@
init {
LayoutInflater.from(context).inflate(R.layout.bubblebar_flyout, this, true)
+ id = R.id.bubble_bar_flyout_view
val ta = context.obtainStyledAttributes(intArrayOf(android.R.attr.dialogCornerRadius))
cornerRadius = ta.getDimensionPixelSize(0, 0).toFloat()
diff --git a/quickstep/src/com/android/launcher3/taskbar/customization/TaskbarFeatureEvaluator.kt b/quickstep/src/com/android/launcher3/taskbar/customization/TaskbarFeatureEvaluator.kt
index 7739a0e..f130d29 100644
--- a/quickstep/src/com/android/launcher3/taskbar/customization/TaskbarFeatureEvaluator.kt
+++ b/quickstep/src/com/android/launcher3/taskbar/customization/TaskbarFeatureEvaluator.kt
@@ -23,9 +23,7 @@
/** Evaluates all the features taskbar can have. */
class TaskbarFeatureEvaluator
-private constructor(
- private val taskbarActivityContext: TaskbarActivityContext,
-) {
+private constructor(private val taskbarActivityContext: TaskbarActivityContext) {
val hasAllApps = true
val hasAppIcons = true
val hasBubbles = false
@@ -43,6 +41,9 @@
val isLandscape: Boolean
get() = taskbarActivityContext.deviceProfile.isLandscape
+ val supportsPinningPopup: Boolean
+ get() = !hasNavButtons
+
fun onDestroy() {
taskbarFeatureEvaluator = null
}
@@ -51,9 +52,7 @@
@Volatile private var taskbarFeatureEvaluator: TaskbarFeatureEvaluator? = null
@JvmStatic
- fun getInstance(
- taskbarActivityContext: TaskbarActivityContext,
- ): TaskbarFeatureEvaluator {
+ fun getInstance(taskbarActivityContext: TaskbarActivityContext): TaskbarFeatureEvaluator {
synchronized(this) {
if (taskbarFeatureEvaluator == null) {
taskbarFeatureEvaluator = TaskbarFeatureEvaluator(taskbarActivityContext)
diff --git a/quickstep/src/com/android/launcher3/uioverrides/QuickstepLauncher.java b/quickstep/src/com/android/launcher3/uioverrides/QuickstepLauncher.java
index acdff71..4ad65e1 100644
--- a/quickstep/src/com/android/launcher3/uioverrides/QuickstepLauncher.java
+++ b/quickstep/src/com/android/launcher3/uioverrides/QuickstepLauncher.java
@@ -1101,10 +1101,9 @@
if (isBubbleBarEnabled()
&& enableBubbleBarInPersistentTaskBar()
&& mBubbleBarLocation != null) {
- boolean isRtl = isRtl(getResources());
- boolean isBubblesOnLeft = mBubbleBarLocation.isOnLeft(isRtl);
+ boolean isBubblesOnLeft = mBubbleBarLocation.isOnLeft(isRtl(getResources()));
translationX += mDeviceProfile
- .getHotseatTranslationXForBubbleBar(isBubblesOnLeft, isRtl);
+ .getHotseatTranslationXForNavBar(this, isBubblesOnLeft);
}
if (isBubbleBarEnabled()
&& mDeviceProfile.shouldAdjustHotseatForBubbleBar(getContext(), hasBubbles())) {
diff --git a/quickstep/src/com/android/launcher3/uioverrides/plugins/PluginManagerWrapperImpl.java b/quickstep/src/com/android/launcher3/uioverrides/plugins/PluginManagerWrapperImpl.java
index 74572c4..3aa1963 100644
--- a/quickstep/src/com/android/launcher3/uioverrides/plugins/PluginManagerWrapperImpl.java
+++ b/quickstep/src/com/android/launcher3/uioverrides/plugins/PluginManagerWrapperImpl.java
@@ -27,6 +27,8 @@
import android.content.pm.ResolveInfo;
import com.android.launcher3.BuildConfig;
+import com.android.launcher3.dagger.ApplicationContext;
+import com.android.launcher3.dagger.LauncherAppSingleton;
import com.android.launcher3.util.PluginManagerWrapper;
import com.android.systemui.plugins.Plugin;
import com.android.systemui.plugins.PluginListener;
@@ -34,7 +36,6 @@
import com.android.systemui.shared.plugins.PluginInstance;
import com.android.systemui.shared.plugins.PluginManagerImpl;
import com.android.systemui.shared.plugins.PluginPrefs;
-import com.android.systemui.shared.system.UncaughtExceptionPreHandlerManager;
import java.io.PrintWriter;
import java.util.ArrayList;
@@ -42,16 +43,17 @@
import java.util.List;
import java.util.Set;
-public class PluginManagerWrapperImpl extends PluginManagerWrapper {
+import javax.inject.Inject;
- private static final UncaughtExceptionPreHandlerManager UNCAUGHT_EXCEPTION_PRE_HANDLER_MANAGER =
- new UncaughtExceptionPreHandlerManager();
+@LauncherAppSingleton
+public class PluginManagerWrapperImpl extends PluginManagerWrapper {
private final Context mContext;
private final PluginManagerImpl mPluginManager;
private final PluginEnablerImpl mPluginEnabler;
- public PluginManagerWrapperImpl(Context c) {
+ @Inject
+ public PluginManagerWrapperImpl(@ApplicationContext Context c) {
mContext = c;
mPluginEnabler = new PluginEnablerImpl(c);
List<String> privilegedPlugins = Collections.emptyList();
@@ -64,9 +66,11 @@
c.getSystemService(NotificationManager.class), mPluginEnabler,
privilegedPlugins, instanceFactory);
+ // Use null preHandlerManager, as the handler is never unregistered which can cause leaks
+ // when using multiple dagger graphs.
mPluginManager = new PluginManagerImpl(c, instanceManagerFactory,
BuildConfig.IS_DEBUG_DEVICE,
- UNCAUGHT_EXCEPTION_PRE_HANDLER_MANAGER, mPluginEnabler,
+ null /* preHandlerManager */, mPluginEnabler,
new PluginPrefs(c), privilegedPlugins);
}
diff --git a/quickstep/src/com/android/quickstep/AbsSwipeUpHandler.java b/quickstep/src/com/android/quickstep/AbsSwipeUpHandler.java
index fbb2c06..97d7179 100644
--- a/quickstep/src/com/android/quickstep/AbsSwipeUpHandler.java
+++ b/quickstep/src/com/android/quickstep/AbsSwipeUpHandler.java
@@ -100,7 +100,6 @@
import com.android.internal.util.LatencyTracker;
import com.android.launcher3.AbstractFloatingView;
import com.android.launcher3.DeviceProfile;
-import com.android.launcher3.Flags;
import com.android.launcher3.R;
import com.android.launcher3.Utilities;
import com.android.launcher3.anim.AnimationSuccessListener;
@@ -125,8 +124,8 @@
import com.android.quickstep.util.ActiveGestureErrorDetector;
import com.android.quickstep.util.ActiveGestureLog;
import com.android.quickstep.util.ActiveGestureProtoLogProxy;
-import com.android.quickstep.util.ActivityInitListener;
import com.android.quickstep.util.AnimatorControllerWithResistance;
+import com.android.quickstep.util.ContextInitListener;
import com.android.quickstep.util.InputConsumerProxy;
import com.android.quickstep.util.InputProxyHandlerFactory;
import com.android.quickstep.util.MotionPauseDetector;
@@ -156,8 +155,6 @@
import com.android.wm.shell.shared.desktopmode.DesktopModeStatus;
import com.android.wm.shell.shared.startingsurface.SplashScreenExitAnimationUtils;
-import kotlin.Unit;
-
import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashMap;
@@ -167,6 +164,8 @@
import java.util.OptionalInt;
import java.util.function.Consumer;
+import kotlin.Unit;
+
/**
* Handles the navigation gestures when Launcher is the default home activity.
*/
@@ -184,7 +183,7 @@
protected final BaseContainerInterface<STATE, RECENTS_CONTAINER> mContainerInterface;
protected final InputConsumerProxy mInputConsumerProxy;
- protected final ActivityInitListener mActivityInitListener;
+ protected final ContextInitListener mContextInitListener;
// Callbacks to be made once the recents animation starts
private final ArrayList<Runnable> mRecentsAnimationStartCallbacks = new ArrayList<>();
private final OnScrollChangedListener mOnRecentsScrollListener = this::onRecentsViewScroll;
@@ -357,10 +356,7 @@
InputConsumerController inputConsumer, RecentsWindowManager recentsWindowManager) {
super(context, deviceState, gestureState);
mContainerInterface = gestureState.getContainerInterface();
- if (recentsWindowManager != null && Flags.enableFallbackOverviewInWindow()) {
- recentsWindowManager.registerInitListener(this::onActivityInit);
- }
- mActivityInitListener =
+ mContextInitListener =
mContainerInterface.createActivityInitListener(this::onActivityInit);
mInputConsumerProxy =
new InputConsumerProxy(context, /* rotationSupplier = */ () -> {
@@ -482,7 +478,7 @@
this::resetStateForAnimationCancel);
}
- protected boolean onActivityInit(Boolean alreadyOnHome) {
+ protected boolean onActivityInit(Boolean isHomeStarted) {
if (mStateCallback.hasStates(STATE_HANDLER_INVALIDATED)) {
return false;
}
@@ -510,11 +506,11 @@
initStateCallbacks();
mStateCallback.setState(oldState);
}
- mWasLauncherAlreadyVisible = alreadyOnHome;
+ mWasLauncherAlreadyVisible = isHomeStarted;
mContainer = container;
// Override the visibility of the activity until the gesture actually starts and we swipe
// up, or until we transition home and the home animation is composed
- if (alreadyOnHome) {
+ if (isHomeStarted) {
mContainer.clearForceInvisibleFlag(STATE_HANDLER_INVISIBILITY_FLAGS);
} else {
mContainer.addForceInvisibleFlag(STATE_HANDLER_INVISIBILITY_FLAGS);
@@ -524,7 +520,7 @@
mRecentsView.setOnPageTransitionEndCallback(null);
mStateCallback.setState(STATE_LAUNCHER_PRESENT);
- if (alreadyOnHome) {
+ if (isHomeStarted) {
onLauncherStart();
} else {
container.addEventCallback(EVENT_STARTED, mLauncherOnStartCallback);
@@ -985,7 +981,7 @@
@Override
public void onRecentsAnimationCanceled(HashMap<Integer, ThumbnailData> thumbnailDatas) {
ActiveGestureProtoLogProxy.logAbsSwipeUpHandlerOnRecentsAnimationCanceled();
- mActivityInitListener.unregister("AbsSwipeUpHandler.onRecentsAnimationCanceled");
+ mContextInitListener.unregister("AbsSwipeUpHandler.onRecentsAnimationCanceled");
mStateCallback.setStateOnUiThread(STATE_GESTURE_CANCELLED | STATE_HANDLER_INVALIDATED);
// Defer clearing the controller and the targets until after we've updated the state
mRecentsAnimationController = null;
@@ -1989,7 +1985,7 @@
// Cleanup when switching handlers
mInputConsumerProxy.unregisterOnTouchDownCallback();
- mActivityInitListener.unregister("AbsSwipeUpHandler.cancelCurrentAnimation");
+ mContextInitListener.unregister("AbsSwipeUpHandler.cancelCurrentAnimation");
TaskStackChangeListeners.getInstance().unregisterTaskStackListener(
mActivityRestartListener);
mTaskSnapshotCache.clear();
@@ -2007,7 +2003,7 @@
mGestureEndCallback.run();
}
- mActivityInitListener.unregister("AbsSwipeUpHandler.invalidateHandler");
+ mContextInitListener.unregister("AbsSwipeUpHandler.invalidateHandler");
TaskStackChangeListeners.getInstance().unregisterTaskStackListener(
mActivityRestartListener);
mTaskSnapshotCache.clear();
@@ -2516,7 +2512,7 @@
// Preload the plan
RecentsModel.INSTANCE.get(mContext).getTasks(null);
- mActivityInitListener.register(reasonString);
+ mContextInitListener.register(reasonString);
}
private boolean shouldFadeOutTargetsForKeyboardQuickSwitch(
diff --git a/quickstep/src/com/android/quickstep/BaseContainerInterface.java b/quickstep/src/com/android/quickstep/BaseContainerInterface.java
index 143ef12..a3953ca 100644
--- a/quickstep/src/com/android/quickstep/BaseContainerInterface.java
+++ b/quickstep/src/com/android/quickstep/BaseContainerInterface.java
@@ -47,8 +47,8 @@
import com.android.launcher3.util.WindowBounds;
import com.android.launcher3.views.ScrimView;
import com.android.quickstep.orientation.RecentsPagedOrientationHandler;
-import com.android.quickstep.util.ActivityInitListener;
import com.android.quickstep.util.AnimatorControllerWithResistance;
+import com.android.quickstep.util.ContextInitListener;
import com.android.quickstep.views.RecentsView;
import com.android.quickstep.views.RecentsViewContainer;
import com.android.systemui.shared.recents.model.ThumbnailData;
@@ -134,7 +134,7 @@
RecentsAnimationDeviceState deviceState, boolean activityVisible,
Consumer<AnimatorControllerWithResistance> callback);
- public abstract ActivityInitListener createActivityInitListener(
+ public abstract ContextInitListener createActivityInitListener(
Predicate<Boolean> onInitListener);
/**
* Returns the expected STATE_TYPE from the provided GestureEndTarget.
diff --git a/quickstep/src/com/android/quickstep/FallbackActivityInterface.java b/quickstep/src/com/android/quickstep/FallbackActivityInterface.java
index df83eb2..b787399 100644
--- a/quickstep/src/com/android/quickstep/FallbackActivityInterface.java
+++ b/quickstep/src/com/android/quickstep/FallbackActivityInterface.java
@@ -36,8 +36,8 @@
import com.android.quickstep.GestureState.GestureEndTarget;
import com.android.quickstep.fallback.RecentsState;
import com.android.quickstep.orientation.RecentsPagedOrientationHandler;
-import com.android.quickstep.util.ActivityInitListener;
import com.android.quickstep.util.AnimatorControllerWithResistance;
+import com.android.quickstep.util.ContextInitListener;
import com.android.quickstep.views.RecentsView;
import java.util.function.Consumer;
@@ -88,16 +88,16 @@
}
@Override
- public ActivityInitListener createActivityInitListener(
+ public ContextInitListener<RecentsActivity> createActivityInitListener(
Predicate<Boolean> onInitListener) {
- return new ActivityInitListener<>((activity, alreadyOnHome) ->
+ return new ContextInitListener<>((activity, alreadyOnHome) ->
onInitListener.test(alreadyOnHome), RecentsActivity.ACTIVITY_TRACKER);
}
@Nullable
@Override
public RecentsActivity getCreatedContainer() {
- return RecentsActivity.ACTIVITY_TRACKER.getCreatedActivity();
+ return RecentsActivity.ACTIVITY_TRACKER.getCreatedContext();
}
@Override
diff --git a/quickstep/src/com/android/quickstep/FallbackWindowInterface.java b/quickstep/src/com/android/quickstep/FallbackWindowInterface.java
index ea478dd..832c093 100644
--- a/quickstep/src/com/android/quickstep/FallbackWindowInterface.java
+++ b/quickstep/src/com/android/quickstep/FallbackWindowInterface.java
@@ -37,8 +37,8 @@
import com.android.quickstep.fallback.RecentsState;
import com.android.quickstep.fallback.window.RecentsWindowManager;
import com.android.quickstep.orientation.RecentsPagedOrientationHandler;
-import com.android.quickstep.util.ActivityInitListener;
import com.android.quickstep.util.AnimatorControllerWithResistance;
+import com.android.quickstep.util.ContextInitListener;
import com.android.quickstep.views.RecentsView;
import java.util.function.Consumer;
@@ -111,11 +111,11 @@
}
@Override
- public ActivityInitListener createActivityInitListener(
+ public ContextInitListener<RecentsWindowManager> createActivityInitListener(
Predicate<Boolean> onInitListener) {
- //todo figure out how to properly replace this
- return new ActivityInitListener<>((activity, alreadyOnHome) ->
- onInitListener.test(alreadyOnHome), RecentsActivity.ACTIVITY_TRACKER);
+ return new ContextInitListener<>(
+ (activity, alreadyOnHome) -> onInitListener.test(alreadyOnHome),
+ RecentsWindowManager.getRecentsWindowTracker());
}
@Nullable
diff --git a/quickstep/src/com/android/quickstep/LauncherActivityInterface.java b/quickstep/src/com/android/quickstep/LauncherActivityInterface.java
index 85312e4..ef6a09d 100644
--- a/quickstep/src/com/android/quickstep/LauncherActivityInterface.java
+++ b/quickstep/src/com/android/quickstep/LauncherActivityInterface.java
@@ -47,7 +47,6 @@
import com.android.launcher3.util.NavigationMode;
import com.android.quickstep.GestureState.GestureEndTarget;
import com.android.quickstep.orientation.RecentsPagedOrientationHandler;
-import com.android.quickstep.util.ActivityInitListener;
import com.android.quickstep.util.AnimatorControllerWithResistance;
import com.android.quickstep.util.LayoutUtils;
import com.android.quickstep.views.RecentsView;
@@ -134,7 +133,7 @@
}
@Override
- public ActivityInitListener createActivityInitListener(Predicate<Boolean> onInitListener) {
+ public LauncherInitListener createActivityInitListener(Predicate<Boolean> onInitListener) {
return new LauncherInitListener((activity, alreadyOnHome) ->
onInitListener.test(alreadyOnHome));
}
@@ -151,7 +150,7 @@
@Nullable
@Override
public QuickstepLauncher getCreatedContainer() {
- return QuickstepLauncher.ACTIVITY_TRACKER.getCreatedActivity();
+ return QuickstepLauncher.ACTIVITY_TRACKER.getCreatedContext();
}
@Nullable
diff --git a/quickstep/src/com/android/quickstep/OverviewCommandHelper.kt b/quickstep/src/com/android/quickstep/OverviewCommandHelper.kt
index e23947b..461f963 100644
--- a/quickstep/src/com/android/quickstep/OverviewCommandHelper.kt
+++ b/quickstep/src/com/android/quickstep/OverviewCommandHelper.kt
@@ -53,7 +53,6 @@
import com.android.systemui.shared.system.InteractionJankMonitorWrapper
import java.io.PrintWriter
import java.util.concurrent.ConcurrentLinkedDeque
-import java.util.concurrent.Executor
import kotlin.coroutines.resume
import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.SupervisorJob
@@ -70,7 +69,6 @@
private val overviewComponentObserver: OverviewComponentObserver,
private val taskAnimationManager: TaskAnimationManager,
private val dispatcherProvider: DispatcherProvider = ProductionDispatchers,
- private val uiExecutor: Executor = Executors.MAIN_EXECUTOR,
) {
private val coroutineScope = CoroutineScope(SupervisorJob() + dispatcherProvider.default)
@@ -87,7 +85,7 @@
get() = overviewComponentObserver.containerInterface
private val visibleRecentsView: RecentsView<*, *>?
- get() = containerInterface.getVisibleRecentsView()
+ get() = containerInterface.getVisibleRecentsView<RecentsView<*, *>>()
/**
* Adds a command to be executed next, after all pending tasks are completed. Max commands that
@@ -107,7 +105,11 @@
if (commandQueue.size == 1) {
Log.d(TAG, "execute: $command - queue size: ${commandQueue.size}")
- uiExecutor.execute { processNextCommand() }
+ if (enableOverviewCommandHelperTimeout()) {
+ coroutineScope.launch(dispatcherProvider.main) { processNextCommand() }
+ } else {
+ Executors.MAIN_EXECUTOR.execute { processNextCommand() }
+ }
} else {
Log.d(TAG, "not executed: $command - queue size: ${commandQueue.size}")
}
diff --git a/quickstep/src/com/android/quickstep/RecentsActivity.java b/quickstep/src/com/android/quickstep/RecentsActivity.java
index 9ac4141..324ca1b 100644
--- a/quickstep/src/com/android/quickstep/RecentsActivity.java
+++ b/quickstep/src/com/android/quickstep/RecentsActivity.java
@@ -71,7 +71,7 @@
import com.android.launcher3.taskbar.FallbackTaskbarUIController;
import com.android.launcher3.taskbar.TaskbarManager;
import com.android.launcher3.util.ActivityOptionsWrapper;
-import com.android.launcher3.util.ActivityTracker;
+import com.android.launcher3.util.ContextTracker;
import com.android.launcher3.util.RunnableList;
import com.android.launcher3.util.SystemUiController;
import com.android.launcher3.util.Themes;
@@ -102,8 +102,8 @@
RecentsViewContainer {
private static final String TAG = "RecentsActivity";
- public static final ActivityTracker<RecentsActivity> ACTIVITY_TRACKER =
- new ActivityTracker<>();
+ public static final ContextTracker.ActivityTracker<RecentsActivity> ACTIVITY_TRACKER =
+ new ContextTracker.ActivityTracker<>();
private Handler mUiHandler = new Handler(Looper.getMainLooper());
@@ -421,7 +421,7 @@
@Override
protected void onDestroy() {
super.onDestroy();
- ACTIVITY_TRACKER.onActivityDestroyed(this);
+ ACTIVITY_TRACKER.onContextDestroyed(this);
mActivityLaunchAnimationRunner = null;
mSplitSelectStateController.onDestroy();
mTISBindHelper.onDestroy();
diff --git a/quickstep/src/com/android/quickstep/SystemUiProxy.java b/quickstep/src/com/android/quickstep/SystemUiProxy.java
index 14b4d60..c1d7ffa 100644
--- a/quickstep/src/com/android/quickstep/SystemUiProxy.java
+++ b/quickstep/src/com/android/quickstep/SystemUiProxy.java
@@ -1426,10 +1426,10 @@
/**
* If task with the given id is on the desktop, bring it to front
*/
- public void showDesktopApp(int taskId) {
+ public void showDesktopApp(int taskId, @Nullable RemoteTransition transition) {
if (mDesktopMode != null) {
try {
- mDesktopMode.showDesktopApp(taskId);
+ mDesktopMode.showDesktopApp(taskId, transition);
} catch (RemoteException e) {
Log.w(TAG, "Failed call showDesktopApp", e);
}
diff --git a/quickstep/src/com/android/quickstep/TaskIconCache.java b/quickstep/src/com/android/quickstep/TaskIconCache.java
index 91fa72d..c4221a1 100644
--- a/quickstep/src/com/android/quickstep/TaskIconCache.java
+++ b/quickstep/src/com/android/quickstep/TaskIconCache.java
@@ -116,6 +116,10 @@
() -> getCacheEntry(task),
MAIN_EXECUTOR,
result -> {
+ task.icon = result.icon;
+ task.titleDescription = result.contentDescription;
+ task.title = result.title;
+
callback.onTaskIconReceived(
result.icon,
result.contentDescription,
diff --git a/quickstep/src/com/android/quickstep/TouchInteractionService.java b/quickstep/src/com/android/quickstep/TouchInteractionService.java
index 41a8a31..1481ef2 100644
--- a/quickstep/src/com/android/quickstep/TouchInteractionService.java
+++ b/quickstep/src/com/android/quickstep/TouchInteractionService.java
@@ -607,6 +607,9 @@
this::createFallbackSwipeHandler;
private final AbsSwipeUpHandler.Factory mRecentsWindowSwipeHandlerFactory =
this::createRecentsWindowSwipeHandler;
+ // This needs to be a member to be queued and potentially removed later if the service is
+ // destroyed before the user is unlocked
+ private final Runnable mUserUnlockedRunnable = this::onUserUnlocked;
private final ScreenOnTracker.ScreenOnListener mScreenOnListener = this::onScreenOnChanged;
@@ -678,8 +681,7 @@
mInputConsumer = InputConsumerController.getRecentsAnimationInputConsumer();
// Call runOnUserUnlocked() before any other callbacks to ensure everything is initialized.
- LockedUserState.get(this).runOnUserUnlocked(this::onUserUnlocked);
- LockedUserState.get(this).runOnUserUnlocked(mTaskbarManager::onUserUnlocked);
+ LockedUserState.get(this).runOnUserUnlocked(mUserUnlockedRunnable);
mDeviceState.addNavigationModeChangedCallback(this::onNavigationModeChanged);
sConnected = true;
@@ -746,6 +748,8 @@
mOverviewComponentObserver.setOverviewChangeListener(this::onOverviewTargetChange);
onOverviewTargetChange(mOverviewComponentObserver.isHomeAndOverviewSame());
+
+ mTaskbarManager.onUserUnlocked();
}
public OverviewCommandHelper getOverviewCommandHelper() {
@@ -836,6 +840,7 @@
mDesktopVisibilityController.onDestroy();
sConnected = false;
+ LockedUserState.get(this).removeOnUserUnlockedRunnable(mUserUnlockedRunnable);
ScreenOnTracker.INSTANCE.get(this).removeListener(mScreenOnListener);
super.onDestroy();
}
diff --git a/quickstep/src/com/android/quickstep/dagger/QuickStepModule.java b/quickstep/src/com/android/quickstep/dagger/QuickStepModule.java
index 08345b8..ab77a7f 100644
--- a/quickstep/src/com/android/quickstep/dagger/QuickStepModule.java
+++ b/quickstep/src/com/android/quickstep/dagger/QuickStepModule.java
@@ -15,8 +15,14 @@
*/
package com.android.quickstep.dagger;
+import com.android.launcher3.uioverrides.plugins.PluginManagerWrapperImpl;
+import com.android.launcher3.util.PluginManagerWrapper;
+
+import dagger.Binds;
import dagger.Module;
@Module
-public class QuickStepModule {
+public abstract class QuickStepModule {
+
+ @Binds abstract PluginManagerWrapper bindPluginManagerWrapper(PluginManagerWrapperImpl impl);
}
diff --git a/quickstep/src/com/android/quickstep/dagger/QuickstepBaseAppComponent.java b/quickstep/src/com/android/quickstep/dagger/QuickstepBaseAppComponent.java
index 335161b..977c036 100644
--- a/quickstep/src/com/android/quickstep/dagger/QuickstepBaseAppComponent.java
+++ b/quickstep/src/com/android/quickstep/dagger/QuickstepBaseAppComponent.java
@@ -19,9 +19,7 @@
import com.android.launcher3.dagger.LauncherAppComponent;
import com.android.launcher3.dagger.LauncherBaseAppComponent;
import com.android.launcher3.model.WellbeingModel;
-import com.android.quickstep.logging.SettingsChangeLogger;
import com.android.quickstep.util.AsyncClockEventDelegate;
-import com.android.quickstep.util.ContextualSearchHapticManager;
/**
* Launcher Quickstep base component for Dagger injection.
@@ -32,11 +30,8 @@
* See {@link LauncherAppComponent} for the one actually used.
*/
public interface QuickstepBaseAppComponent extends LauncherBaseAppComponent {
- SettingsChangeLogger getSettingsChangeLogger();
WellbeingModel getWellbeingModel();
AsyncClockEventDelegate getAsyncClockEventDelegate();
-
- ContextualSearchHapticManager getContextualSearchHapticManager();
}
diff --git a/quickstep/src/com/android/quickstep/fallback/window/RecentsWindowManager.kt b/quickstep/src/com/android/quickstep/fallback/window/RecentsWindowManager.kt
index fbf671f..3017df2 100644
--- a/quickstep/src/com/android/quickstep/fallback/window/RecentsWindowManager.kt
+++ b/quickstep/src/com/android/quickstep/fallback/window/RecentsWindowManager.kt
@@ -39,6 +39,7 @@
import com.android.launcher3.statemanager.StateManager
import com.android.launcher3.statemanager.StateManager.AtomicAnimationFactory
import com.android.launcher3.statemanager.StatefulContainer
+import com.android.launcher3.util.ContextTracker
import com.android.launcher3.util.DisplayController
import com.android.launcher3.util.RunnableList
import com.android.launcher3.util.SystemUiController
@@ -89,6 +90,14 @@
companion object {
private const val HOME_APPEAR_DURATION: Long = 250
private const val TAG = "RecentsWindowManager"
+
+ class RecentsWindowTracker : ContextTracker<RecentsWindowManager?>() {
+ override fun isHomeStarted(context: RecentsWindowManager?): Boolean {
+ return true
+ }
+ }
+
+ @JvmStatic val recentsWindowTracker = RecentsWindowTracker()
}
protected var recentsView: FallbackRecentsView<RecentsWindowManager>? = null
@@ -147,6 +156,7 @@
FallbackWindowInterface.getInstance()?.destroy()
TaskStackChangeListeners.getInstance().unregisterTaskStackListener(taskStackChangeListener)
callbacks?.removeListener(recentsAnimationListener)
+ recentsWindowTracker.onContextDestroyed(this)
}
override fun startHome() {
@@ -254,7 +264,7 @@
actionsView?.updateVerticalMargin(DisplayController.getNavigationMode(this))
mSystemUiController = SystemUiController(windowView)
- onInitListener?.test(true)
+ recentsWindowTracker.handleCreate(this)
this.callbacks = callbacks
callbacks?.addListener(recentsAnimationListener)
diff --git a/quickstep/src/com/android/quickstep/fallback/window/RecentsWindowSwipeHandler.java b/quickstep/src/com/android/quickstep/fallback/window/RecentsWindowSwipeHandler.java
index 34b3d74..4f9d837 100644
--- a/quickstep/src/com/android/quickstep/fallback/window/RecentsWindowSwipeHandler.java
+++ b/quickstep/src/com/android/quickstep/fallback/window/RecentsWindowSwipeHandler.java
@@ -27,7 +27,6 @@
import static com.android.launcher3.GestureNavContract.EXTRA_REMOTE_CALLBACK;
import static com.android.launcher3.anim.AnimatorListeners.forEndCallback;
-import android.animation.ObjectAnimator;
import android.app.ActivityManager.RunningTaskInfo;
import android.content.Context;
import android.content.Intent;
@@ -62,16 +61,15 @@
import com.android.launcher3.util.DisplayController;
import com.android.quickstep.AbsSwipeUpHandler;
import com.android.quickstep.GestureState;
+import com.android.quickstep.RecentsAnimationController;
import com.android.quickstep.RecentsAnimationDeviceState;
-import com.android.quickstep.RemoteAnimationTargets;
+import com.android.quickstep.RecentsAnimationTargets;
import com.android.quickstep.TaskAnimationManager;
import com.android.quickstep.fallback.FallbackRecentsView;
import com.android.quickstep.fallback.RecentsState;
-import com.android.quickstep.util.ActiveGestureLog;
import com.android.quickstep.util.RectFSpringAnim;
import com.android.quickstep.util.SurfaceTransaction.SurfaceProperties;
import com.android.quickstep.util.TransformParams;
-import com.android.quickstep.util.TransformParams.BuilderProxy;
import com.android.quickstep.views.TaskView;
import com.android.systemui.shared.recents.model.Task.TaskKey;
import com.android.systemui.shared.system.InputConsumerController;
@@ -115,12 +113,25 @@
mRunningOverHome = mGestureState.getRunningTask() != null
&& mGestureState.getRunningTask().isHomeTask();
- if (mRunningOverHome) {
- runActionOnRemoteHandles(remoteTargetHandle ->
- remoteTargetHandle.getTransformParams().setHomeBuilderProxy(
- RecentsWindowSwipeHandler.
- this::updateHomeActivityTransformDuringSwipeUp));
+
+ initTransformParams();
+ }
+
+ @Override
+ public void onRecentsAnimationStart(RecentsAnimationController controller,
+ RecentsAnimationTargets targets) {
+ super.onRecentsAnimationStart(controller, targets);
+ initTransformParams();
+ }
+
+ private void initTransformParams() {
+ if (mActiveAnimationFactory != null) {
+ mActiveAnimationFactory.initTransformParams();
+ return;
}
+ runActionOnRemoteHandles(remoteTargetHandle ->
+ remoteTargetHandle.getTransformParams().setHomeBuilderProxy(
+ RecentsWindowSwipeHandler.this::updateHomeActivityTransformDuringSwipeUp));
}
@Override
@@ -135,12 +146,17 @@
private void updateHomeActivityTransformDuringSwipeUp(SurfaceProperties builder,
RemoteAnimationTarget app, TransformParams params) {
- setHomeScaleAndAlpha(builder, app, mCurrentShift.value,
- Utilities.boundToRange(1 - mCurrentShift.value, 0, 1));
+ if (mActiveAnimationFactory != null) {
+ return;
+ }
+ setHomeScaleAndAlpha(builder, app, mCurrentShift.value, 0);
}
private void setHomeScaleAndAlpha(SurfaceProperties builder,
RemoteAnimationTarget app, float verticalShift, float alpha) {
+ if (app.windowConfiguration.getActivityType() != ACTIVITY_TYPE_HOME) {
+ return;
+ }
float scale = Utilities.mapRange(verticalShift, 1, mMaxLauncherScale);
mTmpMatrix.setScale(scale, scale,
app.localBounds.exactCenterX(), app.localBounds.exactCenterY());
@@ -163,25 +179,13 @@
mActiveAnimationFactory = new FallbackHomeAnimationFactory(duration);
//todo: b/368410893 follow up on this as its intent focused and seems to cut immediately
Intent intent = new Intent(mGestureState.getHomeIntent());
- if (mActiveAnimationFactory != null && runningTaskTarget != null) {
+ if (runningTaskTarget != null) {
mActiveAnimationFactory.addGestureContract(intent, runningTaskTarget.taskInfo);
}
return mActiveAnimationFactory;
}
@Override
- protected boolean handleTaskAppeared(@NonNull RemoteAnimationTarget[] appearedTaskTargets,
- @NonNull ActiveGestureLog.CompoundString failureReason) {
- if (mActiveAnimationFactory != null
- && mActiveAnimationFactory.handleHomeTaskAppeared(appearedTaskTargets)) {
- mActiveAnimationFactory = null;
- return false;
- }
-
- return super.handleTaskAppeared(appearedTaskTargets, failureReason);
- }
-
- @Override
protected void finishRecentsControllerToHome(Runnable callback) {
final Runnable recentsCallback;
if (mAppCanEnterPip) {
@@ -236,11 +240,12 @@
private class FallbackHomeAnimationFactory extends HomeAnimationFactory
implements Consumer<Message> {
private final Rect mTempRect = new Rect();
- private final TransformParams mHomeAlphaParams = new TransformParams();
- private final AnimatedFloat mHomeAlpha;
- private final AnimatedFloat mVerticalShiftForScale = new AnimatedFloat();
- private final AnimatedFloat mRecentsAlpha = new AnimatedFloat();
+ private final TransformParams mTransformParams = new TransformParams();
+ private final AnimatedFloat mHomeAlpha = new AnimatedFloat(this::updateAppTransforms);
+ private final AnimatedFloat mVerticalShiftForScale =
+ new AnimatedFloat(this::updateAppTransforms);
+ private final AnimatedFloat mRecentsAlpha = new AnimatedFloat(this:: updateAppTransforms);
private final RectF mTargetRect = new RectF();
private SurfaceControl mSurfaceControl;
@@ -255,25 +260,12 @@
mDuration = duration;
if (mRunningOverHome) {
- mHomeAlpha = new AnimatedFloat();
- mHomeAlpha.value = Utilities.boundToRange(1 - mCurrentShift.value, 0, 1);
mVerticalShiftForScale.value = mCurrentShift.value;
- runActionOnRemoteHandles(remoteTargetHandle ->
- remoteTargetHandle.getTransformParams().setHomeBuilderProxy(
- FallbackHomeAnimationFactory.this
- ::updateHomeActivityTransformDuringHomeAnim));
- } else {
- mHomeAlpha = new AnimatedFloat(this::updateHomeAlpha);
- mHomeAlpha.value = 0;
- mHomeAlphaParams.setHomeBuilderProxy(
- this::updateHomeActivityTransformDuringHomeAnim);
}
-
mRecentsAlpha.value = 1;
- runActionOnRemoteHandles(remoteTargetHandle ->
- remoteTargetHandle.getTransformParams().setBaseBuilderProxy(
- FallbackHomeAnimationFactory.this
- ::updateRecentsActivityTransformDuringHomeAnim));
+ mHomeAlpha.value = 0;
+
+ initTransformParams();
}
@NonNull
@@ -285,63 +277,30 @@
return mTargetRect;
}
- private void updateRecentsActivityTransformDuringHomeAnim(SurfaceProperties builder,
- RemoteAnimationTarget app, TransformParams params) {
- builder.setAlpha(mRecentsAlpha.value);
- }
-
- private void updateHomeActivityTransformDuringHomeAnim(SurfaceProperties builder,
- RemoteAnimationTarget app, TransformParams params) {
- setHomeScaleAndAlpha(builder, app, mVerticalShiftForScale.value, mHomeAlpha.value);
- }
-
@NonNull
@Override
public AnimatorPlaybackController createActivityAnimationToHome() {
PendingAnimation pa = new PendingAnimation(mDuration);
pa.setFloat(mRecentsAlpha, AnimatedFloat.VALUE, 0, ACCELERATE);
+ pa.setFloat(mHomeAlpha, AnimatedFloat.VALUE, 1, ACCELERATE);
return pa.createPlaybackController();
}
- private void updateHomeAlpha() {
- if (mHomeAlphaParams.getTargetSet() != null) {
- mHomeAlphaParams.applySurfaceParams(
- mHomeAlphaParams.createSurfaceParams(BuilderProxy.NO_OP));
- }
- }
-
- public boolean handleHomeTaskAppeared(RemoteAnimationTarget[] appearedTaskTargets) {
- RemoteAnimationTarget appearedTaskTarget = appearedTaskTargets[0];
- if (appearedTaskTarget.windowConfiguration.getActivityType() == ACTIVITY_TYPE_HOME) {
- RemoteAnimationTargets targets = new RemoteAnimationTargets(
- new RemoteAnimationTarget[] {appearedTaskTarget},
- new RemoteAnimationTarget[0], new RemoteAnimationTarget[0],
- appearedTaskTarget.mode);
- mHomeAlphaParams.setTargetSet(targets);
- updateHomeAlpha();
- return true;
- }
- return false;
- }
-
@Override
public void playAtomicAnimation(float velocity) {
- ObjectAnimator alphaAnim = mHomeAlpha.animateToValue(mHomeAlpha.value, 1);
- alphaAnim.setDuration(mDuration).setInterpolator(ACCELERATE);
- alphaAnim.start();
-
- if (mRunningOverHome) {
- // Spring back launcher scale
- new SpringAnimationBuilder(mContext)
- .setStartValue(mVerticalShiftForScale.value)
- .setEndValue(0)
- .setStartVelocity(-velocity / mTransitionDragLength)
- .setMinimumVisibleChange(1f / mDp.heightPx)
- .setDampingRatio(0.6f)
- .setStiffness(800)
- .build(mVerticalShiftForScale, AnimatedFloat.VALUE)
- .start();
+ if (!mRunningOverHome) {
+ return;
}
+ // Spring back launcher scale
+ new SpringAnimationBuilder(mContext)
+ .setStartValue(mVerticalShiftForScale.value)
+ .setEndValue(0)
+ .setStartVelocity(-velocity / mTransitionDragLength)
+ .setMinimumVisibleChange(1f / mDp.heightPx)
+ .setDampingRatio(0.6f)
+ .setStiffness(800)
+ .build(mVerticalShiftForScale, AnimatedFloat.VALUE)
+ .start();
}
@Override
@@ -350,6 +309,34 @@
mSpringAnim.addAnimatorListener(forEndCallback(this::onRectAnimationEnd));
}
+ private void initTransformParams() {
+ runActionOnRemoteHandles(remoteTargetHandle ->
+ remoteTargetHandle.getTransformParams().setHomeBuilderProxy(
+ FallbackHomeAnimationFactory.this
+ ::updateHomeActivityTransformDuringHomeAnim));
+
+ mTransformParams.setTargetSet(mRecentsAnimationTargets);
+ }
+
+ private void updateRecentsActivityTransformDuringHomeAnim(SurfaceProperties builder,
+ RemoteAnimationTarget app, TransformParams params) {
+ if (app.mode != mRecentsAnimationTargets.targetMode) {
+ return;
+ }
+ builder.setAlpha(mRecentsAlpha.value);
+ }
+
+ private void updateAppTransforms() {
+ mTransformParams.applySurfaceParams(
+ mTransformParams.createSurfaceParams(FallbackHomeAnimationFactory.this
+ ::updateRecentsActivityTransformDuringHomeAnim));
+ }
+
+ private void updateHomeActivityTransformDuringHomeAnim(SurfaceProperties builder,
+ RemoteAnimationTarget app, TransformParams params) {
+ setHomeScaleAndAlpha(builder, app, mVerticalShiftForScale.value, mHomeAlpha.value);
+ }
+
private void onRectAnimationEnd() {
mAnimationFinished = true;
maybeSendEndMessage();
diff --git a/quickstep/src/com/android/quickstep/inputconsumers/NavHandleLongPressHandler.java b/quickstep/src/com/android/quickstep/inputconsumers/NavHandleLongPressHandler.java
index 1a825a4..155d095 100644
--- a/quickstep/src/com/android/quickstep/inputconsumers/NavHandleLongPressHandler.java
+++ b/quickstep/src/com/android/quickstep/inputconsumers/NavHandleLongPressHandler.java
@@ -30,7 +30,6 @@
import androidx.annotation.Nullable;
import androidx.annotation.VisibleForTesting;
-import com.android.launcher3.LauncherApplication;
import com.android.launcher3.R;
import com.android.launcher3.logging.InstanceId;
import com.android.launcher3.logging.InstanceIdSequence;
@@ -62,8 +61,7 @@
mContext = context;
mStatsLogManager = StatsLogManager.newInstance(context);
mVibratorWrapper = VibratorWrapper.INSTANCE.get(mContext);
- mContextualSearchHapticManager = ((LauncherApplication) context.getApplicationContext())
- .getAppComponent().getContextualSearchHapticManager();
+ mContextualSearchHapticManager = ContextualSearchHapticManager.INSTANCE.get(context);
mContextualSearchInvoker = ContextualSearchInvoker.newInstance(mContext);
}
diff --git a/quickstep/src/com/android/quickstep/logging/SettingsChangeLogger.java b/quickstep/src/com/android/quickstep/logging/SettingsChangeLogger.java
index 995635f..dd721e1 100644
--- a/quickstep/src/com/android/quickstep/logging/SettingsChangeLogger.java
+++ b/quickstep/src/com/android/quickstep/logging/SettingsChangeLogger.java
@@ -44,20 +44,16 @@
import com.android.launcher3.LauncherPrefs;
import com.android.launcher3.R;
import com.android.launcher3.dagger.ApplicationContext;
-import com.android.launcher3.dagger.LauncherAppSingleton;
import com.android.launcher3.logging.InstanceId;
import com.android.launcher3.logging.StatsLogManager;
import com.android.launcher3.logging.StatsLogManager.StatsLogger;
import com.android.launcher3.model.DeviceGridState;
-import com.android.launcher3.util.DaggerSingletonObject;
-import com.android.launcher3.util.DaggerSingletonTracker;
import com.android.launcher3.util.DisplayController;
import com.android.launcher3.util.DisplayController.Info;
-import com.android.launcher3.util.ExecutorUtil;
+import com.android.launcher3.util.MainThreadInitializedObject;
import com.android.launcher3.util.NavigationMode;
import com.android.launcher3.util.SafeCloseable;
import com.android.launcher3.util.SettingsCache;
-import com.android.quickstep.dagger.QuickstepBaseAppComponent;
import org.xmlpull.v1.XmlPullParser;
import org.xmlpull.v1.XmlPullParserException;
@@ -65,12 +61,9 @@
import java.io.IOException;
import java.util.Optional;
-import javax.inject.Inject;
-
/**
* Utility class to log launcher settings changes
*/
-@LauncherAppSingleton
public class SettingsChangeLogger implements
DisplayController.DisplayInfoChangeListener, OnSharedPreferenceChangeListener,
SafeCloseable {
@@ -78,8 +71,8 @@
/**
* Singleton instance
*/
- public static DaggerSingletonObject<SettingsChangeLogger> INSTANCE =
- new DaggerSingletonObject<>(QuickstepBaseAppComponent::getSettingsChangeLogger);
+ public static MainThreadInitializedObject<SettingsChangeLogger> INSTANCE =
+ new MainThreadInitializedObject<>(SettingsChangeLogger::new);
private static final String TAG = "SettingsChangeLogger";
private static final String BOOLEAN_PREF = "SwitchPreference";
@@ -92,31 +85,26 @@
private StatsLogManager.LauncherEvent mNotificationDotsEvent;
private StatsLogManager.LauncherEvent mHomeScreenSuggestionEvent;
- @Inject
- SettingsChangeLogger(@ApplicationContext Context context, DaggerSingletonTracker tracker) {
- this(context, StatsLogManager.newInstance(context), tracker);
+ SettingsChangeLogger(@ApplicationContext Context context) {
+ this(context, StatsLogManager.newInstance(context));
}
@VisibleForTesting
- SettingsChangeLogger(Context context, StatsLogManager statsLogManager,
- DaggerSingletonTracker tracker) {
+ SettingsChangeLogger(Context context, StatsLogManager statsLogManager) {
mContext = context;
mStatsLogManager = statsLogManager;
mLoggablePrefs = loadPrefKeys(context);
- ExecutorUtil.executeSyncOnMainOrFail(() -> {
- DisplayController.INSTANCE.get(context).addChangeListener(this);
- mNavMode = DisplayController.getNavigationMode(context);
+ DisplayController.INSTANCE.get(context).addChangeListener(this);
+ mNavMode = DisplayController.getNavigationMode(context);
- getPrefs(context).registerOnSharedPreferenceChangeListener(this);
- getDevicePrefs(context).registerOnSharedPreferenceChangeListener(this);
+ getPrefs(context).registerOnSharedPreferenceChangeListener(this);
+ getDevicePrefs(context).registerOnSharedPreferenceChangeListener(this);
- SettingsCache settingsCache = SettingsCache.INSTANCE.get(context);
- settingsCache.register(NOTIFICATION_BADGING_URI,
- this::onNotificationDotsChanged);
- onNotificationDotsChanged(settingsCache.getValue(NOTIFICATION_BADGING_URI));
- tracker.addCloseable(this);
- });
+ SettingsCache settingsCache = SettingsCache.INSTANCE.get(context);
+ settingsCache.register(NOTIFICATION_BADGING_URI,
+ this::onNotificationDotsChanged);
+ onNotificationDotsChanged(settingsCache.getValue(NOTIFICATION_BADGING_URI));
}
private static ArrayMap<String, LoggablePref> loadPrefKeys(Context context) {
@@ -223,8 +211,6 @@
public void close() {
getPrefs(mContext).unregisterOnSharedPreferenceChangeListener(this);
getDevicePrefs(mContext).unregisterOnSharedPreferenceChangeListener(this);
- SettingsCache settingsCache = SettingsCache.INSTANCE.get(mContext);
- settingsCache.unregister(NOTIFICATION_BADGING_URI, this::onNotificationDotsChanged);
}
@VisibleForTesting
diff --git a/quickstep/src/com/android/quickstep/recents/data/RecentTasksRepository.kt b/quickstep/src/com/android/quickstep/recents/data/RecentTasksRepository.kt
index 9c4248c..3b59864 100644
--- a/quickstep/src/com/android/quickstep/recents/data/RecentTasksRepository.kt
+++ b/quickstep/src/com/android/quickstep/recents/data/RecentTasksRepository.kt
@@ -40,5 +40,5 @@
* Sets the tasks that are visible, indicating that properties relating to visuals need to be
* populated e.g. icons/thumbnails etc.
*/
- fun setVisibleTasks(visibleTaskIdList: List<Int>)
+ fun setVisibleTasks(visibleTaskIdList: Set<Int>)
}
diff --git a/quickstep/src/com/android/quickstep/recents/data/TasksRepository.kt b/quickstep/src/com/android/quickstep/recents/data/TasksRepository.kt
index dc8d537..4f38ec7 100644
--- a/quickstep/src/com/android/quickstep/recents/data/TasksRepository.kt
+++ b/quickstep/src/com/android/quickstep/recents/data/TasksRepository.kt
@@ -23,147 +23,147 @@
import com.android.quickstep.recents.data.TaskVisualsChangedDelegate.TaskThumbnailChangedCallback
import com.android.quickstep.task.thumbnail.data.TaskIconDataSource
import com.android.quickstep.task.thumbnail.data.TaskThumbnailDataSource
-import com.android.quickstep.util.GroupTask
import com.android.systemui.shared.recents.model.Task
import com.android.systemui.shared.recents.model.ThumbnailData
import kotlin.coroutines.resume
import kotlinx.coroutines.CoroutineScope
-import kotlinx.coroutines.ExperimentalCoroutinesApi
-import kotlinx.coroutines.channels.awaitClose
+import kotlinx.coroutines.Job
import kotlinx.coroutines.flow.Flow
import kotlinx.coroutines.flow.MutableStateFlow
-import kotlinx.coroutines.flow.SharingStarted
-import kotlinx.coroutines.flow.callbackFlow
-import kotlinx.coroutines.flow.combine
-import kotlinx.coroutines.flow.distinctUntilChanged
import kotlinx.coroutines.flow.distinctUntilChangedBy
-import kotlinx.coroutines.flow.flatMapLatest
-import kotlinx.coroutines.flow.flowOf
-import kotlinx.coroutines.flow.flowOn
import kotlinx.coroutines.flow.map
-import kotlinx.coroutines.flow.shareIn
+import kotlinx.coroutines.flow.update
import kotlinx.coroutines.launch
import kotlinx.coroutines.suspendCancellableCoroutine
import kotlinx.coroutines.withContext
-@OptIn(ExperimentalCoroutinesApi::class)
class TasksRepository(
private val recentsModel: RecentTasksDataSource,
private val taskThumbnailDataSource: TaskThumbnailDataSource,
private val taskIconDataSource: TaskIconDataSource,
private val taskVisualsChangedDelegate: TaskVisualsChangedDelegate,
- recentsCoroutineScope: CoroutineScope,
+ private val recentsCoroutineScope: CoroutineScope,
private val dispatcherProvider: DispatcherProvider,
) : RecentTasksRepository {
- private val groupedTaskData = MutableStateFlow(emptyList<GroupTask>())
- private val visibleTaskIds = MutableStateFlow(emptySet<Int>())
-
- private val taskData =
- groupedTaskData.map { groupTaskList -> groupTaskList.flatMap { it.tasks } }
- private val visibleTasks =
- combine(taskData, visibleTaskIds) { tasks, visibleIds ->
- tasks.filter { it.key.id in visibleIds }
- }
-
- private val iconQueryResults: Flow<Map<Int, TaskIconQueryResponse?>> =
- visibleTasks
- .map { visibleTasksList -> visibleTasksList.map(::getIconDataRequest) }
- .flatMapLatest { iconRequestFlows: List<IconDataRequest> ->
- if (iconRequestFlows.isEmpty()) {
- flowOf(emptyMap())
- } else {
- combine(iconRequestFlows) { it.toMap() }
- }
- }
- .distinctUntilChanged()
-
- private val thumbnailQueryResults: Flow<Map<Int, ThumbnailData?>> =
- visibleTasks
- .map { visibleTasksList -> visibleTasksList.map(::getThumbnailDataRequest) }
- .flatMapLatest { thumbnailRequestFlows: List<ThumbnailDataRequest> ->
- if (thumbnailRequestFlows.isEmpty()) {
- flowOf(emptyMap())
- } else {
- combine(thumbnailRequestFlows) { it.toMap() }
- }
- }
- .distinctUntilChanged()
-
- private val augmentedTaskData: Flow<List<Task>> =
- combine(taskData, thumbnailQueryResults, iconQueryResults) {
- tasks,
- thumbnailQueryResults,
- iconQueryResults ->
- tasks.onEach { task ->
- // Add retrieved thumbnails + remove unnecessary thumbnails (e.g. invisible)
- task.thumbnail = thumbnailQueryResults[task.key.id]
-
- // TODO(b/352331675) don't load icons for DesktopTaskView
- // Add retrieved icons + remove unnecessary icons
- val iconQueryResult = iconQueryResults[task.key.id]
- task.icon = iconQueryResult?.icon
- task.titleDescription = iconQueryResult?.contentDescription
- task.title = iconQueryResult?.title
- }
- }
- .flowOn(dispatcherProvider.io)
- .shareIn(recentsCoroutineScope, SharingStarted.WhileSubscribed(5000), replay = 1)
+ private val tasks = MutableStateFlow(MapForStateFlow<Int, Task>(emptyMap()))
+ private val taskRequests = HashMap<Int, Pair<Task.TaskKey, Job>>()
override fun getAllTaskData(forceRefresh: Boolean): Flow<List<Task>> {
if (forceRefresh) {
- recentsModel.getTasks { groupedTaskData.value = it }
+ recentsModel.getTasks { result ->
+ tasks.value =
+ MapForStateFlow(
+ result
+ .flatMap { groupTask -> groupTask.tasks }
+ .associateBy { it.key.id }
+ .also {
+ // Clean tasks that are not in the latest group tasks list.
+ val tasksNoLongerVisible = it.keys.subtract(tasks.value.keys)
+ removeTasks(tasksNoLongerVisible)
+ }
+ )
+ }
}
- return augmentedTaskData
+ return tasks.map { it.values.toList() }
}
- override fun getTaskDataById(taskId: Int): Flow<Task?> =
- augmentedTaskData.map { taskList -> taskList.firstOrNull { it.key.id == taskId } }
+ override fun getTaskDataById(taskId: Int) = tasks.map { it[taskId] }
- override fun getThumbnailById(taskId: Int): Flow<ThumbnailData?> =
+ override fun getThumbnailById(taskId: Int) =
getTaskDataById(taskId).map { it?.thumbnail }.distinctUntilChangedBy { it?.snapshotId }
- override fun setVisibleTasks(visibleTaskIdList: List<Int>) {
+ override fun setVisibleTasks(visibleTaskIdList: Set<Int>) {
Log.d(TAG, "setVisibleTasks: $visibleTaskIdList")
- this.visibleTaskIds.value = visibleTaskIdList.toSet()
+
+ // Remove tasks are no longer visible
+ val tasksNoLongerVisible = taskRequests.keys.subtract(visibleTaskIdList)
+ removeTasks(tasksNoLongerVisible)
+ // Add new tasks to be requested
+ visibleTaskIdList.subtract(taskRequests.keys).forEach { taskId -> requestTaskData(taskId) }
}
- /** Flow wrapper for [TaskThumbnailDataSource.getThumbnailInBackground] api */
- private fun getThumbnailDataRequest(task: Task): ThumbnailDataRequest = callbackFlow {
- trySend(task.key.id to task.thumbnail)
- trySend(task.key.id to getThumbnailFromDataSource(task))
+ private fun requestTaskData(taskId: Int) {
+ Log.i(TAG, "requestTaskData: $taskId")
+ val task = tasks.value[taskId] ?: return
+ taskRequests[taskId] =
+ Pair(
+ task.key,
+ recentsCoroutineScope.launch {
+ fetchIcon(task)
+ fetchThumbnail(task)
+ },
+ )
+ }
- val callback =
+ private fun removeTasks(tasksToRemove: Set<Int>) {
+ if (tasksToRemove.isEmpty()) return
+
+ tasksToRemove.forEach { taskId ->
+ Log.i(TAG, "removeTask: $taskId")
+ val request = taskRequests.remove(taskId) ?: return
+ val (taskKey, job) = request
+ job.cancel()
+
+ // un-registering callbacks
+ taskVisualsChangedDelegate.unregisterTaskIconChangedCallback(taskKey)
+ taskVisualsChangedDelegate.unregisterTaskThumbnailChangedCallback(taskKey)
+
+ // Clearing Task to reduce memory footprint
+ tasks.value[taskId]?.apply {
+ thumbnail = null
+ icon = null
+ title = null
+ titleDescription = null
+ }
+ }
+ tasks.update { oldValue -> MapForStateFlow(oldValue) }
+ }
+
+ private suspend fun fetchIcon(task: Task) {
+ updateIcon(task.key.id, getIconFromDataSource(task)) // Fetch icon from cache
+ taskVisualsChangedDelegate.registerTaskIconChangedCallback(
+ task.key,
+ object : TaskIconChangedCallback {
+ override fun onTaskIconChanged() {
+ recentsCoroutineScope.launch {
+ updateIcon(task.key.id, getIconFromDataSource(task))
+ }
+ }
+ },
+ )
+ }
+
+ private suspend fun fetchThumbnail(task: Task) {
+ updateThumbnail(task.key.id, getThumbnailFromDataSource(task))
+ taskVisualsChangedDelegate.registerTaskThumbnailChangedCallback(
+ task.key,
object : TaskThumbnailChangedCallback {
override fun onTaskThumbnailChanged(thumbnailData: ThumbnailData?) {
- trySend(task.key.id to thumbnailData)
+ updateThumbnail(task.key.id, thumbnailData)
}
override fun onHighResLoadingStateChanged() {
- launch { trySend(task.key.id to getThumbnailFromDataSource(task)) }
+ recentsCoroutineScope.launch {
+ updateThumbnail(task.key.id, getThumbnailFromDataSource(task))
+ }
}
- }
- taskVisualsChangedDelegate.registerTaskThumbnailChangedCallback(task.key, callback)
- awaitClose { taskVisualsChangedDelegate.unregisterTaskThumbnailChangedCallback(task.key) }
+ },
+ )
}
- /** Flow wrapper for [TaskIconDataSource.getIconInBackground] api */
- private fun getIconDataRequest(task: Task): IconDataRequest =
- callbackFlow {
- trySend(task.key.id to task.getTaskIconQueryResponse())
- trySend(task.key.id to getIconFromDataSource(task))
+ private fun updateIcon(taskId: Int, iconData: IconData) {
+ val task = tasks.value[taskId] ?: return
+ task.icon = iconData.icon
+ task.titleDescription = iconData.contentDescription
+ task.title = iconData.title
+ tasks.update { oldValue -> MapForStateFlow(oldValue + (taskId to task)) }
+ }
- val callback =
- object : TaskIconChangedCallback {
- override fun onTaskIconChanged() {
- launch { trySend(task.key.id to getIconFromDataSource(task)) }
- }
- }
- taskVisualsChangedDelegate.registerTaskIconChangedCallback(task.key, callback)
- awaitClose {
- taskVisualsChangedDelegate.unregisterTaskIconChangedCallback(task.key)
- }
- }
- .distinctUntilChanged()
+ private fun updateThumbnail(taskId: Int, thumbnail: ThumbnailData?) {
+ val task = tasks.value[taskId] ?: return
+ task.thumbnail = thumbnail
+ tasks.update { oldValue -> MapForStateFlow(oldValue + (taskId to task)) }
+ }
private suspend fun getThumbnailFromDataSource(task: Task) =
withContext(dispatcherProvider.main) {
@@ -184,11 +184,7 @@
->
icon.constantState?.let {
continuation.resume(
- TaskIconQueryResponse(
- it.newDrawable().mutate(),
- contentDescription,
- title,
- )
+ IconData(it.newDrawable().mutate(), contentDescription, title)
)
}
}
@@ -199,22 +195,16 @@
companion object {
private const val TAG = "TasksRepository"
}
+
+ /** Helper class to support StateFlow emissions when using a Map with a MutableStateFlow. */
+ private data class MapForStateFlow<K, T>(
+ private val backingMap: Map<K, T>,
+ private val updated: Long = System.nanoTime(),
+ ) : Map<K, T> by backingMap
+
+ private data class IconData(
+ val icon: Drawable,
+ val contentDescription: String,
+ val title: String,
+ )
}
-
-data class TaskIconQueryResponse(
- val icon: Drawable,
- val contentDescription: String,
- val title: String,
-)
-
-private fun Task.getTaskIconQueryResponse(): TaskIconQueryResponse? {
- val iconVal = icon ?: return null
- val titleDescriptionVal = titleDescription ?: return null
- val titleVal = title ?: return null
-
- return TaskIconQueryResponse(iconVal, titleDescriptionVal, titleVal)
-}
-
-private typealias ThumbnailDataRequest = Flow<Pair<Int, ThumbnailData?>>
-
-private typealias IconDataRequest = Flow<Pair<Int, TaskIconQueryResponse?>>
diff --git a/quickstep/src/com/android/quickstep/recents/viewmodel/RecentsViewModel.kt b/quickstep/src/com/android/quickstep/recents/viewmodel/RecentsViewModel.kt
index 5cf6823..c511005 100644
--- a/quickstep/src/com/android/quickstep/recents/viewmodel/RecentsViewModel.kt
+++ b/quickstep/src/com/android/quickstep/recents/viewmodel/RecentsViewModel.kt
@@ -31,7 +31,7 @@
}
fun updateVisibleTasks(visibleTaskIdList: List<Int>) {
- recentsTasksRepository.setVisibleTasks(visibleTaskIdList)
+ recentsTasksRepository.setVisibleTasks(visibleTaskIdList.toSet())
}
fun updateScale(scale: Float) {
diff --git a/quickstep/src/com/android/quickstep/util/AsyncClockEventDelegate.java b/quickstep/src/com/android/quickstep/util/AsyncClockEventDelegate.java
index 4a84b1b..54f6443 100644
--- a/quickstep/src/com/android/quickstep/util/AsyncClockEventDelegate.java
+++ b/quickstep/src/com/android/quickstep/util/AsyncClockEventDelegate.java
@@ -34,11 +34,8 @@
import com.android.launcher3.dagger.ApplicationContext;
import com.android.launcher3.dagger.LauncherAppSingleton;
-import com.android.launcher3.dagger.LauncherBaseAppComponent;
import com.android.launcher3.util.DaggerSingletonObject;
import com.android.launcher3.util.DaggerSingletonTracker;
-import com.android.launcher3.util.ExecutorUtil;
-import com.android.launcher3.util.MainThreadInitializedObject;
import com.android.launcher3.util.SafeCloseable;
import com.android.launcher3.util.SettingsCache;
import com.android.launcher3.util.SettingsCache.OnChangeListener;
@@ -61,6 +58,7 @@
new DaggerSingletonObject<>(QuickstepBaseAppComponent::getAsyncClockEventDelegate);
private final Context mContext;
+ private final SettingsCache mSettingsCache;
private final SimpleBroadcastReceiver mReceiver =
new SimpleBroadcastReceiver(UI_HELPER_EXECUTOR, this::onClockEventReceived);
@@ -72,11 +70,14 @@
private boolean mDestroyed = false;
@Inject
- AsyncClockEventDelegate(@ApplicationContext Context context, DaggerSingletonTracker tracker) {
+ AsyncClockEventDelegate(@ApplicationContext Context context,
+ DaggerSingletonTracker tracker,
+ SettingsCache settingsCache) {
super(context);
mContext = context;
+ mSettingsCache = settingsCache;
mReceiver.register(mContext, ACTION_TIME_CHANGED, ACTION_TIMEZONE_CHANGED);
- ExecutorUtil.executeSyncOnMainOrFail(() -> tracker.addCloseable(this));
+ tracker.addCloseable(this);
}
@Override
@@ -100,7 +101,7 @@
}
synchronized (mFormatObservers) {
if (!mFormatRegistered && !mDestroyed) {
- SettingsCache.INSTANCE.get(mContext).register(mFormatUri, this);
+ mSettingsCache.register(mFormatUri, this);
mFormatRegistered = true;
}
mFormatObservers.add(observer);
@@ -136,7 +137,7 @@
@Override
public void close() {
mDestroyed = true;
- SettingsCache.INSTANCE.get(mContext).unregister(mFormatUri, this);
+ mSettingsCache.unregister(mFormatUri, this);
mReceiver.unregisterReceiverSafely(mContext);
}
}
diff --git a/quickstep/src/com/android/quickstep/util/ActivityInitListener.java b/quickstep/src/com/android/quickstep/util/ContextInitListener.java
similarity index 64%
rename from quickstep/src/com/android/quickstep/util/ActivityInitListener.java
rename to quickstep/src/com/android/quickstep/util/ContextInitListener.java
index 5efbb40..49f1463 100644
--- a/quickstep/src/com/android/quickstep/util/ActivityInitListener.java
+++ b/quickstep/src/com/android/quickstep/util/ContextInitListener.java
@@ -15,17 +15,17 @@
*/
package com.android.quickstep.util;
-import com.android.launcher3.BaseActivity;
-import com.android.launcher3.util.ActivityTracker;
-import com.android.launcher3.util.ActivityTracker.SchedulerCallback;
+import com.android.launcher3.util.ContextTracker;
+import com.android.launcher3.util.ContextTracker.SchedulerCallback;
+import com.android.launcher3.views.ActivityContext;
import java.util.function.BiPredicate;
-public class ActivityInitListener<T extends BaseActivity> implements
- SchedulerCallback<T> {
+public class ContextInitListener<CONTEXT extends ActivityContext> implements
+ SchedulerCallback<CONTEXT> {
- private BiPredicate<T, Boolean> mOnInitListener;
- private final ActivityTracker<T> mActivityTracker;
+ private BiPredicate<CONTEXT, Boolean> mOnInitListener;
+ private final ContextTracker<CONTEXT> mContextTracker;
private boolean mIsRegistered = false;
@@ -34,23 +34,23 @@
* return true to continue receiving callbacks (ie. for if the activity is
* recreated).
*/
- public ActivityInitListener(BiPredicate<T, Boolean> onInitListener,
- ActivityTracker<T> tracker) {
+ public ContextInitListener(BiPredicate<CONTEXT, Boolean> onInitListener,
+ ContextTracker<CONTEXT> tracker) {
mOnInitListener = onInitListener;
- mActivityTracker = tracker;
+ mContextTracker = tracker;
}
@Override
- public final boolean init(T activity, boolean alreadyOnHome) {
+ public final boolean init(CONTEXT activity, boolean isHomeStarted) {
if (!mIsRegistered) {
// Don't receive any more updates
return false;
}
- return handleInit(activity, alreadyOnHome);
+ return handleInit(activity, isHomeStarted);
}
- protected boolean handleInit(T activity, boolean alreadyOnHome) {
- return mOnInitListener.test(activity, alreadyOnHome);
+ protected boolean handleInit(CONTEXT activity, boolean isHomeStarted) {
+ return mOnInitListener.test(activity, isHomeStarted);
}
/**
@@ -59,14 +59,14 @@
*/
public void register(String reasonString) {
mIsRegistered = true;
- mActivityTracker.registerCallback(this, reasonString);
+ mContextTracker.registerCallback(this, reasonString);
}
/**
* After calling this, we won't {@link #init} even when the activity is ready.
*/
public void unregister(String reasonString) {
- mActivityTracker.unregisterCallback(this, reasonString);
+ mContextTracker.unregisterCallback(this, reasonString);
mIsRegistered = false;
mOnInitListener = null;
}
diff --git a/quickstep/src/com/android/quickstep/util/ContextualSearchHapticManager.kt b/quickstep/src/com/android/quickstep/util/ContextualSearchHapticManager.kt
index 8c246a5..286b77a 100644
--- a/quickstep/src/com/android/quickstep/util/ContextualSearchHapticManager.kt
+++ b/quickstep/src/com/android/quickstep/util/ContextualSearchHapticManager.kt
@@ -21,17 +21,15 @@
import android.os.VibrationEffect.Composition
import android.os.Vibrator
import com.android.launcher3.dagger.ApplicationContext
-import com.android.launcher3.dagger.LauncherAppSingleton
+import com.android.launcher3.util.MainThreadInitializedObject
+import com.android.launcher3.util.SafeCloseable
import com.android.launcher3.util.VibratorWrapper
import com.android.quickstep.DeviceConfigWrapper.Companion.get
-import javax.inject.Inject
import kotlin.math.pow
/** Manages haptics relating to Contextual Search invocations. */
-@LauncherAppSingleton
class ContextualSearchHapticManager
-@Inject
-internal constructor(@ApplicationContext private val context: Context) {
+internal constructor(@ApplicationContext private val context: Context) : SafeCloseable {
private var searchEffect = createSearchEffect()
private var contextualSearchStateManager = ContextualSearchStateManager.INSTANCE[context]
@@ -98,4 +96,10 @@
VibratorWrapper.INSTANCE[context].vibrate(composition.compose())
}
}
+
+ override fun close() {}
+
+ companion object {
+ @JvmField val INSTANCE = MainThreadInitializedObject { ContextualSearchHapticManager(it) }
+ }
}
diff --git a/quickstep/src/com/android/quickstep/util/ContextualSearchInvoker.kt b/quickstep/src/com/android/quickstep/util/ContextualSearchInvoker.kt
index dcb72aa..bd454c0 100644
--- a/quickstep/src/com/android/quickstep/util/ContextualSearchInvoker.kt
+++ b/quickstep/src/com/android/quickstep/util/ContextualSearchInvoker.kt
@@ -22,7 +22,6 @@
import android.content.Context
import android.util.Log
import com.android.internal.app.AssistUtils
-import com.android.launcher3.LauncherApplication
import com.android.launcher3.R
import com.android.launcher3.logging.StatsLogManager
import com.android.launcher3.logging.StatsLogManager.LauncherEvent.LAUNCHER_LAUNCH_ASSISTANT_FAILED_SERVICE_ERROR
@@ -57,9 +56,7 @@
TopTaskTracker.INSTANCE[context],
SystemUiProxy.INSTANCE[context],
StatsLogManager.newInstance(context),
- (context.applicationContext as LauncherApplication)
- .appComponent
- .contextualSearchHapticManager,
+ ContextualSearchHapticManager.INSTANCE[context],
context.getSystemService(ContextualSearchManager::class.java),
)
diff --git a/quickstep/src/com/android/quickstep/util/SystemUiFlagUtils.kt b/quickstep/src/com/android/quickstep/util/SystemUiFlagUtils.kt
index 5f4388c..1ff05da 100644
--- a/quickstep/src/com/android/quickstep/util/SystemUiFlagUtils.kt
+++ b/quickstep/src/com/android/quickstep/util/SystemUiFlagUtils.kt
@@ -47,6 +47,22 @@
!hasAnyFlag(flags, QuickStepContract.SYSUI_STATE_STATUS_BAR_KEYGUARD_GOING_AWAY)
}
+ /**
+ * Taskbar is hidden whenever the device is dreaming. The dreaming state includes the
+ * interactive dreams, AoD, screen off. Since the SYSUI_STATE_DEVICE_DREAMING only kicks in when
+ * the device is asleep, the second condition extends ensures that the transition from and to
+ * the WAKEFULNESS_ASLEEP state also hide the taskbar, and improves the taskbar hide/reveal
+ * animation timings. The Taskbar can show when dreaming if the glanceable hub is showing on
+ * top.
+ */
+ @JvmStatic
+ fun isTaskbarHidden(@SystemUiStateFlags flags: Long): Boolean {
+ return ((hasAnyFlag(flags, QuickStepContract.SYSUI_STATE_DEVICE_DREAMING) &&
+ !hasAnyFlag(flags, QuickStepContract.SYSUI_STATE_COMMUNAL_HUB_SHOWING)) ||
+ (flags and QuickStepContract.SYSUI_STATE_WAKEFULNESS_MASK) !=
+ QuickStepContract.WAKEFULNESS_AWAKE)
+ }
+
private fun hasAnyFlag(@SystemUiStateFlags flags: Long, flagMask: Long): Boolean {
return (flags and flagMask) != 0L
}
diff --git a/quickstep/src/com/android/quickstep/util/TransformParams.java b/quickstep/src/com/android/quickstep/util/TransformParams.java
index ebcef30..401eccc 100644
--- a/quickstep/src/com/android/quickstep/util/TransformParams.java
+++ b/quickstep/src/com/android/quickstep/util/TransformParams.java
@@ -143,18 +143,15 @@
for (int i = 0; i < targets.unfilteredApps.length; i++) {
RemoteAnimationTarget app = targets.unfilteredApps[i];
SurfaceProperties builder = transaction.forSurface(app.leash);
+ BuilderProxy targetProxy =
+ app.windowConfiguration.getActivityType() == ACTIVITY_TYPE_HOME
+ ? mHomeBuilderProxy
+ : (app.mode == targets.targetMode ? proxy : mBaseBuilderProxy);
if (app.mode == targets.targetMode) {
- int activityType = app.windowConfiguration.getActivityType();
- if (activityType == ACTIVITY_TYPE_HOME) {
- mHomeBuilderProxy.onBuildTargetParams(builder, app, this);
- } else {
- builder.setAlpha(getTargetAlpha());
- proxy.onBuildTargetParams(builder, app, this);
- }
- } else {
- mBaseBuilderProxy.onBuildTargetParams(builder, app, this);
+ builder.setAlpha(getTargetAlpha());
}
+ targetProxy.onBuildTargetParams(builder, app, this);
}
// always put wallpaper layer to bottom.
diff --git a/quickstep/src/com/android/quickstep/views/RecentsView.java b/quickstep/src/com/android/quickstep/views/RecentsView.java
index b18af65..b38d0d7 100644
--- a/quickstep/src/com/android/quickstep/views/RecentsView.java
+++ b/quickstep/src/com/android/quickstep/views/RecentsView.java
@@ -1935,6 +1935,9 @@
// Keep same previous focused task
TaskView newFocusedTaskView = getTaskViewByTaskIds(focusedTaskIds);
+ if (enableLargeDesktopWindowingTile() && newFocusedTaskView instanceof DesktopTaskView) {
+ newFocusedTaskView = null;
+ }
// If the list changed, maybe the focused task doesn't exist anymore
int newFocusedTaskViewIndex = mUtils.getFocusedTaskIndex(taskGroups);
if (newFocusedTaskView == null && getTaskViewCount() > newFocusedTaskViewIndex) {
@@ -2975,10 +2978,19 @@
boolean runningTaskTileHidden = mRunningTaskTileHidden;
setCurrentTask(runningTaskViewId);
- boolean shouldFocusRunningTask = !(enableGridOnlyOverview()
- || (enableLargeDesktopWindowingTile()
- && getRunningTaskView() instanceof DesktopTaskView));
- setFocusedTaskViewId(shouldFocusRunningTask ? runningTaskViewId : INVALID_TASK_ID);
+ int focusedTaskViewId;
+ if (enableGridOnlyOverview()) {
+ focusedTaskViewId = INVALID_TASK_ID;
+ } else if (enableLargeDesktopWindowingTile()
+ && getRunningTaskView() instanceof DesktopTaskView) {
+ TaskView focusedTaskView = getTaskViewAt(getDesktopTaskViewCount());
+ focusedTaskViewId =
+ focusedTaskView != null ? focusedTaskView.getTaskViewId() : INVALID_TASK_ID;
+ } else {
+ focusedTaskViewId = runningTaskViewId;
+ }
+ setFocusedTaskViewId(focusedTaskViewId);
+
runOnPageScrollsInitialized(() -> setCurrentPage(getRunningTaskIndex()));
setRunningTaskViewShowScreenshot(false);
setRunningTaskHidden(runningTaskTileHidden);
@@ -3810,7 +3822,7 @@
}
} else if (!showAsGrid || (enableLargeDesktopWindowingTile()
&& dismissedTaskView.isLargeTile()
- && nextFocusedTaskView == null)) {
+ && nextFocusedTaskView == null && !dismissingForSplitSelection)) {
int offset = getOffsetToDismissedTask(scrollDiffPerPage, dismissedIndex, taskCount);
int scrollDiff = newScroll[i] - oldScroll[i] + offset;
if (scrollDiff != 0) {
@@ -3939,11 +3951,9 @@
if (shouldRemoveTask) {
if (dismissedTaskView.isRunningTask()) {
finishRecentsAnimation(true /* toRecents */, false /* shouldPip */,
- () -> removeTaskInternal(dismissedTaskViewId,
- dismissedTaskView instanceof DesktopTaskView));
+ () -> removeTaskInternal(dismissedTaskView));
} else {
- removeTaskInternal(dismissedTaskViewId,
- dismissedTaskView instanceof DesktopTaskView);
+ removeTaskInternal(dismissedTaskView);
}
announceForAccessibility(
getResources().getString(R.string.task_view_closed));
@@ -4311,22 +4321,24 @@
return lastVisibleIndex;
}
- private void removeTaskInternal(int dismissedTaskViewId, boolean isDesktop) {
- int[] taskIds = getTaskIdsForTaskViewId(dismissedTaskViewId);
- UI_HELPER_EXECUTOR.getHandler().post(() -> {
- if (DesktopModeFlags.ENABLE_DESKTOP_WINDOWING_BACK_NAVIGATION.isTrue() && isDesktop) {
- // TODO: b/372005228 - Use the api with desktop id instead.
- SystemUiProxy.INSTANCE.get(getContext()).removeDesktop(
- mContainer.getDisplay().getDisplayId());
- } else {
- for (int taskId : taskIds) {
- if (taskId != -1) {
- ActivityManagerWrapper.getInstance().removeTask(taskId);
- }
+ private void removeTaskInternal(@NonNull TaskView dismissedTaskView) {
+ UI_HELPER_EXECUTOR
+ .getHandler()
+ .post(
+ () -> {
+ if (DesktopModeFlags.ENABLE_DESKTOP_WINDOWING_BACK_NAVIGATION.isTrue()
+ && dismissedTaskView instanceof DesktopTaskView) {
+ // TODO: b/362720497 - Use the api with desktop id instead.
+ SystemUiProxy.INSTANCE
+ .get(getContext())
+ .removeDesktop(mContainer.getDisplay().getDisplayId());
+ } else {
+ for (int taskId : dismissedTaskView.getTaskIds()) {
+ ActivityManagerWrapper.getInstance().removeTask(taskId);
}
- }
- });
- }
+ }
+ });
+ }
protected void onDismissAnimationEnds() {
AccessibilityManagerCompat.sendTestProtocolEventToTest(getContext(),
@@ -5045,7 +5057,8 @@
mSplitHiddenTaskView = getTaskViewByTaskId(splitSelectSource.alreadyRunningTaskId);
mSplitHiddenTaskViewIndex = indexOfChild(mSplitHiddenTaskView);
mSplitSelectStateController
- .setAnimateCurrentTaskDismissal(splitSelectSource.animateCurrentTaskDismissal);
+ .setAnimateCurrentTaskDismissal(splitSelectSource.animateCurrentTaskDismissal
+ && mSplitHiddenTaskView != null);
// Prevent dismissing whole task if we're only initiating from one of 2 tasks in split pair
mSplitSelectStateController.setDismissingFromSplitPair(mSplitHiddenTaskView != null
@@ -5430,7 +5443,6 @@
int taskIndex = indexOfChild(taskView);
int centerTaskIndex = getCurrentPage();
- boolean isRunningTask = taskView.isRunningTask();
float toScale = getMaxScaleForFullScreen();
boolean showAsGrid = showAsGrid();
@@ -5450,7 +5462,9 @@
setPivotX(mTempPointF.x);
setPivotY(mTempPointF.y);
- if (!isRunningTask) {
+ // If live tile is not launching, apply pivot to live tile as well and bring it
+ // above RecentsView to avoid wallpaper blur from being applied to it.
+ if (!taskView.isRunningTask()) {
runActionOnRemoteHandles(
remoteTargetHandle -> {
remoteTargetHandle.getTaskViewSimulator().setPivotOverride(
diff --git a/quickstep/tests/multivalentTests/src/com/android/launcher3/taskbar/TaskbarEduTooltipControllerTest.kt b/quickstep/tests/multivalentTests/src/com/android/launcher3/taskbar/TaskbarEduTooltipControllerTest.kt
index e60717b..3c80352 100644
--- a/quickstep/tests/multivalentTests/src/com/android/launcher3/taskbar/TaskbarEduTooltipControllerTest.kt
+++ b/quickstep/tests/multivalentTests/src/com/android/launcher3/taskbar/TaskbarEduTooltipControllerTest.kt
@@ -16,7 +16,6 @@
package com.android.launcher3.taskbar
-import android.util.Log
import com.android.launcher3.Utilities
import com.android.launcher3.taskbar.TaskbarControllerTestUtil.asProperty
import com.android.launcher3.taskbar.TaskbarControllerTestUtil.runOnMainSync
@@ -34,14 +33,12 @@
import com.google.common.truth.Truth.assertThat
import org.junit.After
import org.junit.Before
-import org.junit.Ignore
import org.junit.Rule
import org.junit.Test
import org.junit.runner.RunWith
@RunWith(LauncherMultivalentJUnit::class)
@EmulatedDevices(["pixelFoldable2023", "pixelTablet2023"])
-@Ignore
class TaskbarEduTooltipControllerTest {
@get:Rule(order = 0) val context = TaskbarWindowSandboxContext.create()
@@ -62,7 +59,6 @@
@Before
fun setUp() {
- Log.e("Taskbar", "TaskbarEduTooltipControllerTest test started")
Utilities.disableRunningInTestHarnessForTests()
}
@@ -71,7 +67,6 @@
if (wasInTestHarness) {
Utilities.enableRunningInTestHarnessForTests()
}
- Log.e("Taskbar", "TaskbarEduTooltipControllerTest test completed")
}
@Test
diff --git a/quickstep/tests/multivalentTests/src/com/android/launcher3/taskbar/bubbles/animation/BubbleBarViewAnimatorTest.kt b/quickstep/tests/multivalentTests/src/com/android/launcher3/taskbar/bubbles/animation/BubbleBarViewAnimatorTest.kt
index 7eee4de..b37048a 100644
--- a/quickstep/tests/multivalentTests/src/com/android/launcher3/taskbar/bubbles/animation/BubbleBarViewAnimatorTest.kt
+++ b/quickstep/tests/multivalentTests/src/com/android/launcher3/taskbar/bubbles/animation/BubbleBarViewAnimatorTest.kt
@@ -19,6 +19,7 @@
import android.content.Context
import android.graphics.Color
import android.graphics.Path
+import android.graphics.PointF
import android.graphics.drawable.ColorDrawable
import android.view.LayoutInflater
import android.view.View
@@ -36,6 +37,10 @@
import com.android.launcher3.taskbar.bubbles.BubbleBarOverflow
import com.android.launcher3.taskbar.bubbles.BubbleBarView
import com.android.launcher3.taskbar.bubbles.BubbleView
+import com.android.launcher3.taskbar.bubbles.flyout.BubbleBarFlyoutController
+import com.android.launcher3.taskbar.bubbles.flyout.BubbleBarFlyoutMessage
+import com.android.launcher3.taskbar.bubbles.flyout.BubbleBarFlyoutPositioner
+import com.android.launcher3.taskbar.bubbles.flyout.FlyoutScheduler
import com.android.launcher3.taskbar.bubbles.stashing.BubbleStashController
import com.android.wm.shell.shared.animation.PhysicsAnimator
import com.android.wm.shell.shared.animation.PhysicsAnimatorTestUtils
@@ -63,13 +68,19 @@
private lateinit var bubbleView: BubbleView
private lateinit var bubble: BubbleBarBubble
private lateinit var bubbleBarView: BubbleBarView
+ private lateinit var flyoutContainer: FrameLayout
private lateinit var bubbleStashController: BubbleStashController
+ private lateinit var flyoutController: BubbleBarFlyoutController
private val onExpandedNoOp = Runnable {}
+ private val flyoutView: View?
+ get() = flyoutContainer.findViewById(R.id.bubble_bar_flyout_view)
+
@Before
fun setUp() {
animatorScheduler = TestBubbleBarViewAnimatorScheduler()
PhysicsAnimatorTestUtils.prepareForTest()
+ setupFlyoutController()
}
@Test
@@ -85,6 +96,7 @@
BubbleBarViewAnimator(
bubbleBarView,
bubbleStashController,
+ flyoutController,
onExpandedNoOp,
animatorScheduler,
)
@@ -106,10 +118,14 @@
assertThat(bubbleBarView.translationY).isEqualTo(BAR_TRANSLATION_Y_FOR_TASKBAR)
assertThat(animator.isAnimating).isTrue()
+ waitForFlyoutToShow()
+
// execute the hide bubble animation
assertThat(animatorScheduler.delayedBlock).isNotNull()
InstrumentationRegistry.getInstrumentation().runOnMainSync(animatorScheduler.delayedBlock!!)
+ waitForFlyoutToHide()
+
// let the animation start and wait for it to complete
InstrumentationRegistry.getInstrumentation().runOnMainSync {}
PhysicsAnimatorTestUtils.blockUntilAnimationsEnd(DynamicAnimation.TRANSLATION_Y)
@@ -134,6 +150,7 @@
BubbleBarViewAnimator(
bubbleBarView,
bubbleStashController,
+ flyoutController,
onExpandedNoOp,
animatorScheduler,
)
@@ -157,10 +174,16 @@
verify(bubbleStashController, atLeastOnce()).updateTaskbarTouchRegion()
+ waitForFlyoutToShow()
+
// verify the hide bubble animation is pending
assertThat(animatorScheduler.delayedBlock).isNotNull()
- animator.onBubbleBarTouchedWhileAnimating()
+ InstrumentationRegistry.getInstrumentation().runOnMainSync {
+ animator.onBubbleBarTouchedWhileAnimating()
+ }
+
+ waitForFlyoutToHide()
assertThat(animatorScheduler.delayedBlock).isNull()
assertThat(bubbleBarView.alpha).isEqualTo(1)
@@ -182,6 +205,7 @@
BubbleBarViewAnimator(
bubbleBarView,
bubbleStashController,
+ flyoutController,
onExpandedNoOp,
animatorScheduler,
)
@@ -227,6 +251,7 @@
BubbleBarViewAnimator(
bubbleBarView,
bubbleStashController,
+ flyoutController,
onExpandedNoOp,
animatorScheduler,
)
@@ -239,10 +264,14 @@
InstrumentationRegistry.getInstrumentation().runOnMainSync {}
PhysicsAnimatorTestUtils.blockUntilAnimationsEnd(DynamicAnimation.TRANSLATION_Y)
+ waitForFlyoutToShow()
+
// execute the hide bubble animation
assertThat(animatorScheduler.delayedBlock).isNotNull()
InstrumentationRegistry.getInstrumentation().runOnMainSync(animatorScheduler.delayedBlock!!)
+ waitForFlyoutToHide()
+
// wait for the hide animation to start
InstrumentationRegistry.getInstrumentation().runOnMainSync {}
handleAnimator.assertIsRunning()
@@ -273,6 +302,7 @@
BubbleBarViewAnimator(
bubbleBarView,
bubbleStashController,
+ flyoutController,
onExpandedNoOp,
animatorScheduler,
)
@@ -310,6 +340,7 @@
BubbleBarViewAnimator(
bubbleBarView,
bubbleStashController,
+ flyoutController,
onExpanded,
animatorScheduler,
)
@@ -354,6 +385,7 @@
BubbleBarViewAnimator(
bubbleBarView,
bubbleStashController,
+ flyoutController,
onExpanded,
animatorScheduler,
)
@@ -404,6 +436,7 @@
BubbleBarViewAnimator(
bubbleBarView,
bubbleStashController,
+ flyoutController,
onExpanded,
animatorScheduler,
)
@@ -418,6 +451,9 @@
PhysicsAnimatorTestUtils.blockUntilAnimationsEnd(DynamicAnimation.TRANSLATION_Y)
assertThat(animator.isAnimating).isTrue()
+
+ waitForFlyoutToShow()
+
// verify the hide bubble animation is pending
assertThat(animatorScheduler.delayedBlock).isNotNull()
@@ -428,6 +464,8 @@
// verify that the hide animation was canceled
assertThat(animatorScheduler.delayedBlock).isNull()
+ waitForFlyoutToHide()
+
assertThat(handle.alpha).isEqualTo(0)
assertThat(handle.translationY)
.isEqualTo(DIFF_BETWEEN_HANDLE_AND_BAR_CENTERS + BAR_TRANSLATION_Y_FOR_TASKBAR)
@@ -453,6 +491,7 @@
BubbleBarViewAnimator(
bubbleBarView,
bubbleStashController,
+ flyoutController,
onExpandedNoOp,
animatorScheduler,
)
@@ -469,9 +508,13 @@
assertThat(bubbleBarView.alpha).isEqualTo(1)
assertThat(bubbleBarView.translationY).isEqualTo(BAR_TRANSLATION_Y_FOR_TASKBAR)
+ waitForFlyoutToShow()
+
assertThat(animatorScheduler.delayedBlock).isNotNull()
InstrumentationRegistry.getInstrumentation().runOnMainSync(animatorScheduler.delayedBlock!!)
+ waitForFlyoutToHide()
+
InstrumentationRegistry.getInstrumentation().runOnMainSync {}
PhysicsAnimatorTestUtils.blockUntilAnimationsEnd(DynamicAnimation.TRANSLATION_Y)
@@ -503,6 +546,7 @@
BubbleBarViewAnimator(
bubbleBarView,
bubbleStashController,
+ flyoutController,
onExpanded,
animatorScheduler,
)
@@ -537,6 +581,7 @@
BubbleBarViewAnimator(
bubbleBarView,
bubbleStashController,
+ flyoutController,
onExpandedNoOp,
animatorScheduler,
)
@@ -553,9 +598,13 @@
assertThat(bubbleBarView.alpha).isEqualTo(1)
assertThat(bubbleBarView.translationY).isEqualTo(BAR_TRANSLATION_Y_FOR_HOTSEAT)
+ waitForFlyoutToShow()
+
assertThat(animatorScheduler.delayedBlock).isNotNull()
InstrumentationRegistry.getInstrumentation().runOnMainSync(animatorScheduler.delayedBlock!!)
+ waitForFlyoutToHide()
+
assertThat(animator.isAnimating).isFalse()
assertThat(bubbleBarView.alpha).isEqualTo(1)
assertThat(bubbleBarView.translationY).isEqualTo(BAR_TRANSLATION_Y_FOR_HOTSEAT)
@@ -576,6 +625,7 @@
BubbleBarViewAnimator(
bubbleBarView,
bubbleStashController,
+ flyoutController,
onExpanded,
animatorScheduler,
)
@@ -624,6 +674,7 @@
BubbleBarViewAnimator(
bubbleBarView,
bubbleStashController,
+ flyoutController,
onExpanded,
animatorScheduler,
)
@@ -636,6 +687,8 @@
InstrumentationRegistry.getInstrumentation().runOnMainSync {}
PhysicsAnimatorTestUtils.blockUntilAnimationsEnd(DynamicAnimation.TRANSLATION_Y)
+ waitForFlyoutToShow()
+
assertThat(animator.isAnimating).isTrue()
// verify the hide bubble animation is pending
assertThat(animatorScheduler.delayedBlock).isNotNull()
@@ -644,6 +697,8 @@
animator.expandedWhileAnimating()
}
+ waitForFlyoutToHide()
+
// verify that the hide animation was canceled
assertThat(animatorScheduler.delayedBlock).isNull()
@@ -665,6 +720,7 @@
BubbleBarViewAnimator(
bubbleBarView,
bubbleStashController,
+ flyoutController,
onExpandedNoOp,
animatorScheduler,
)
@@ -687,9 +743,13 @@
barAnimator.assertIsRunning()
PhysicsAnimatorTestUtils.blockUntilAnimationsEnd(DynamicAnimation.TRANSLATION_Y)
+ waitForFlyoutToShow()
+
assertThat(animatorScheduler.delayedBlock).isNotNull()
InstrumentationRegistry.getInstrumentation().runOnMainSync(animatorScheduler.delayedBlock!!)
+ waitForFlyoutToHide()
+
assertThat(animator.isAnimating).isFalse()
// the bubble bar translation y should be back to its initial value
assertThat(bubbleBarView.translationY).isEqualTo(BAR_TRANSLATION_Y_FOR_HOTSEAT)
@@ -712,6 +772,7 @@
BubbleBarViewAnimator(
bubbleBarView,
bubbleStashController,
+ flyoutController,
onExpanded,
animatorScheduler,
)
@@ -759,6 +820,7 @@
BubbleBarViewAnimator(
bubbleBarView,
bubbleStashController,
+ flyoutController,
onExpanded,
animatorScheduler,
)
@@ -817,6 +879,7 @@
BubbleBarViewAnimator(
bubbleBarView,
bubbleStashController,
+ flyoutController,
onExpanded,
animatorScheduler,
)
@@ -843,6 +906,8 @@
assertThat(animatorScheduler.delayedBlock).isNotNull()
assertThat(animator.isAnimating).isTrue()
+ waitForFlyoutToShow()
+
InstrumentationRegistry.getInstrumentation().runOnMainSync {
animator.expandedWhileAnimating()
}
@@ -850,6 +915,8 @@
// verify that the hide animation was canceled
assertThat(animatorScheduler.delayedBlock).isNull()
+ waitForFlyoutToHide()
+
assertThat(animator.isAnimating).isFalse()
assertThat(bubbleBarView.translationY).isEqualTo(BAR_TRANSLATION_Y_FOR_HOTSEAT)
assertThat(bubbleBarView.isExpanded).isTrue()
@@ -894,7 +961,7 @@
Color.WHITE,
Path(),
"",
- null,
+ BubbleBarFlyoutMessage(icon = null, title = "title", message = "message"),
)
bubbleView.setBubble(bubble)
bubbleBarView.addView(bubbleView)
@@ -913,6 +980,34 @@
.thenReturn(BAR_TRANSLATION_Y_FOR_TASKBAR)
}
+ private fun setupFlyoutController() {
+ flyoutContainer = FrameLayout(context)
+ val flyoutPositioner =
+ object : BubbleBarFlyoutPositioner {
+ override val isOnLeft = true
+ override val targetTy = 100f
+ override val distanceToCollapsedPosition = PointF(0f, 0f)
+ override val collapsedSize = 30f
+ override val collapsedColor = Color.BLUE
+ override val collapsedElevation = 1f
+ override val distanceToRevealTriangle = 10f
+ }
+ val topBoundaryListener =
+ object : BubbleBarFlyoutController.TopBoundaryListener {
+ override fun extendTopBoundary(space: Int) {}
+
+ override fun resetTopBoundary() {}
+ }
+ val flyoutScheduler = FlyoutScheduler { block -> block.invoke() }
+ flyoutController =
+ BubbleBarFlyoutController(
+ flyoutContainer,
+ flyoutPositioner,
+ topBoundaryListener,
+ flyoutScheduler,
+ )
+ }
+
private fun verifyBubbleBarIsExpandedWithTranslation(ty: Float) {
assertThat(bubbleBarView.visibility).isEqualTo(VISIBLE)
assertThat(bubbleBarView.scaleX).isEqualTo(1)
@@ -921,6 +1016,20 @@
assertThat(bubbleBarView.isExpanded).isTrue()
}
+ private fun waitForFlyoutToShow() {
+ InstrumentationRegistry.getInstrumentation().runOnMainSync {
+ animatorTestRule.advanceTimeBy(300)
+ }
+ assertThat(flyoutView).isNotNull()
+ }
+
+ private fun waitForFlyoutToHide() {
+ InstrumentationRegistry.getInstrumentation().runOnMainSync {
+ animatorTestRule.advanceTimeBy(300)
+ }
+ assertThat(flyoutView).isNull()
+ }
+
private fun <T> PhysicsAnimator<T>.assertIsRunning() {
InstrumentationRegistry.getInstrumentation().runOnMainSync {
assertThat(isRunning()).isTrue()
diff --git a/quickstep/tests/multivalentTests/src/com/android/launcher3/taskbar/bubbles/flyout/BubbleBarFlyoutControllerTest.kt b/quickstep/tests/multivalentTests/src/com/android/launcher3/taskbar/bubbles/flyout/BubbleBarFlyoutControllerTest.kt
index 3dd7689..527bdaa 100644
--- a/quickstep/tests/multivalentTests/src/com/android/launcher3/taskbar/bubbles/flyout/BubbleBarFlyoutControllerTest.kt
+++ b/quickstep/tests/multivalentTests/src/com/android/launcher3/taskbar/bubbles/flyout/BubbleBarFlyoutControllerTest.kt
@@ -20,6 +20,7 @@
import android.graphics.Color
import android.graphics.PointF
import android.view.Gravity
+import android.view.View
import android.widget.FrameLayout
import android.widget.TextView
import androidx.core.animation.AnimatorTestRule
@@ -80,7 +81,7 @@
@Test
fun flyoutPosition_left() {
InstrumentationRegistry.getInstrumentation().runOnMainSync {
- flyoutController.setUpFlyout(flyoutMessage)
+ flyoutController.setUpAndShowFlyout(flyoutMessage) {}
assertThat(flyoutContainer.childCount).isEqualTo(1)
val flyout = flyoutContainer.getChildAt(0)
val lp = flyout.layoutParams as FrameLayout.LayoutParams
@@ -93,7 +94,7 @@
fun flyoutPosition_right() {
onLeft = false
InstrumentationRegistry.getInstrumentation().runOnMainSync {
- flyoutController.setUpFlyout(flyoutMessage)
+ flyoutController.setUpAndShowFlyout(flyoutMessage) {}
assertThat(flyoutContainer.childCount).isEqualTo(1)
val flyout = flyoutContainer.getChildAt(0)
val lp = flyout.layoutParams as FrameLayout.LayoutParams
@@ -105,7 +106,7 @@
@Test
fun flyoutMessage() {
InstrumentationRegistry.getInstrumentation().runOnMainSync {
- flyoutController.setUpFlyout(flyoutMessage)
+ flyoutController.setUpAndShowFlyout(flyoutMessage) {}
assertThat(flyoutContainer.childCount).isEqualTo(1)
val flyout = flyoutContainer.getChildAt(0)
val sender = flyout.findViewById<TextView>(R.id.bubble_flyout_title)
@@ -118,9 +119,9 @@
@Test
fun hideFlyout_removedFromContainer() {
InstrumentationRegistry.getInstrumentation().runOnMainSync {
- flyoutController.setUpFlyout(flyoutMessage)
+ flyoutController.setUpAndShowFlyout(flyoutMessage) {}
assertThat(flyoutContainer.childCount).isEqualTo(1)
- flyoutController.hideFlyout {}
+ flyoutController.collapseFlyout {}
animatorTestRule.advanceTimeBy(300)
}
assertThat(flyoutContainer.childCount).isEqualTo(0)
@@ -132,7 +133,7 @@
// boundary
flyoutTy = -50f
InstrumentationRegistry.getInstrumentation().runOnMainSync {
- flyoutController.setUpFlyout(flyoutMessage)
+ flyoutController.setUpAndShowFlyout(flyoutMessage) {}
assertThat(flyoutContainer.childCount).isEqualTo(1)
}
InstrumentationRegistry.getInstrumentation().waitForIdleSync()
@@ -145,7 +146,7 @@
@Test
fun showFlyout_withinBoundary() {
InstrumentationRegistry.getInstrumentation().runOnMainSync {
- flyoutController.setUpFlyout(flyoutMessage)
+ flyoutController.setUpAndShowFlyout(flyoutMessage) {}
assertThat(flyoutContainer.childCount).isEqualTo(1)
}
InstrumentationRegistry.getInstrumentation().waitForIdleSync()
@@ -156,16 +157,30 @@
}
@Test
- fun hideFlyout_resetsTopBoundary() {
+ fun collapseFlyout_resetsTopBoundary() {
InstrumentationRegistry.getInstrumentation().runOnMainSync {
- flyoutController.setUpFlyout(flyoutMessage)
+ flyoutController.setUpAndShowFlyout(flyoutMessage) {}
assertThat(flyoutContainer.childCount).isEqualTo(1)
- flyoutController.hideFlyout {}
+ flyoutController.collapseFlyout {}
animatorTestRule.advanceTimeBy(300)
}
assertThat(topBoundaryListener.topBoundaryReset).isTrue()
}
+ @Test
+ fun cancelFlyout_fadesOutFlyout() {
+ InstrumentationRegistry.getInstrumentation().runOnMainSync {
+ flyoutController.setUpAndShowFlyout(flyoutMessage) {}
+ assertThat(flyoutContainer.childCount).isEqualTo(1)
+ val flyoutView = flyoutContainer.findViewById<View>(R.id.bubble_bar_flyout_view)
+ assertThat(flyoutView.alpha).isEqualTo(1f)
+ flyoutController.cancelFlyout {}
+ animatorTestRule.advanceTimeBy(300)
+ assertThat(flyoutView.alpha).isEqualTo(0f)
+ }
+ assertThat(topBoundaryListener.topBoundaryReset).isTrue()
+ }
+
class FakeTopBoundaryListener : BubbleBarFlyoutController.TopBoundaryListener {
var topBoundaryExtendedSpace = 0
diff --git a/quickstep/tests/multivalentTests/src/com/android/quickstep/AbsSwipeUpHandlerTestCase.java b/quickstep/tests/multivalentTests/src/com/android/quickstep/AbsSwipeUpHandlerTestCase.java
index 0bf9886..dc5223c 100644
--- a/quickstep/tests/multivalentTests/src/com/android/quickstep/AbsSwipeUpHandlerTestCase.java
+++ b/quickstep/tests/multivalentTests/src/com/android/quickstep/AbsSwipeUpHandlerTestCase.java
@@ -55,7 +55,7 @@
import com.android.launcher3.statemanager.StatefulContainer;
import com.android.launcher3.util.SystemUiController;
import com.android.quickstep.fallback.window.RecentsWindowManager;
-import com.android.quickstep.util.ActivityInitListener;
+import com.android.quickstep.util.ContextInitListener;
import com.android.quickstep.views.RecentsView;
import com.android.quickstep.views.RecentsViewContainer;
import com.android.systemui.shared.system.InputConsumerController;
@@ -116,7 +116,7 @@
protected TaskAnimationManager mTaskAnimationManager;
@Mock protected CONTAINER_INTERFACE mActivityInterface;
- @Mock protected ActivityInitListener<?> mActivityInitListener;
+ @Mock protected ContextInitListener<?> mContextInitListener;
@Mock protected RecentsAnimationController mRecentsAnimationController;
@Mock protected STATE_TYPE mState;
@Mock protected ViewTreeObserver mViewTreeObserver;
@@ -168,7 +168,7 @@
when(recentsContainer.getRootView()).thenReturn(mRootView);
when(recentsContainer.getSystemUiController()).thenReturn(mSystemUiController);
when(mActivityInterface.createActivityInitListener(any()))
- .thenReturn(mActivityInitListener);
+ .thenReturn(mContextInitListener);
doReturn(recentsContainer).when(mActivityInterface).getCreatedContainer();
doAnswer(answer -> {
answer.<Runnable>getArgument(0).run();
@@ -181,7 +181,7 @@
String reasonString = "because i said so";
createSwipeHandler().initWhenReady(reasonString);
- verify(mActivityInitListener).register(eq(reasonString));
+ verify(mContextInitListener).register(eq(reasonString));
}
@Test
@@ -189,7 +189,7 @@
createSwipeHandler()
.onRecentsAnimationCanceled(new HashMap<>());
- runOnMainSync(() -> verify(mActivityInitListener)
+ runOnMainSync(() -> verify(mContextInitListener)
.unregister(eq("AbsSwipeUpHandler.onRecentsAnimationCanceled")));
}
@@ -197,7 +197,7 @@
public void testOnConsumerAboutToBeSwitched_unregistersActivityInitListener() {
createSwipeHandler().onConsumerAboutToBeSwitched();
- runOnMainSync(() -> verify(mActivityInitListener)
+ runOnMainSync(() -> verify(mContextInitListener)
.unregister("AbsSwipeUpHandler.invalidateHandler"));
}
@@ -206,7 +206,7 @@
createSwipeUpHandlerForGesture(GestureState.GestureEndTarget.NEW_TASK)
.onConsumerAboutToBeSwitched();
- runOnMainSync(() -> verify(mActivityInitListener)
+ runOnMainSync(() -> verify(mContextInitListener)
.unregister(eq("AbsSwipeUpHandler.cancelCurrentAnimation")));
}
diff --git a/quickstep/tests/multivalentTests/src/com/android/quickstep/OverviewCommandHelperTest.kt b/quickstep/tests/multivalentTests/src/com/android/quickstep/OverviewCommandHelperTest.kt
index b0db737..0ae710f 100644
--- a/quickstep/tests/multivalentTests/src/com/android/quickstep/OverviewCommandHelperTest.kt
+++ b/quickstep/tests/multivalentTests/src/com/android/quickstep/OverviewCommandHelperTest.kt
@@ -41,6 +41,7 @@
import org.junit.runner.RunWith
import org.mockito.Mockito.doAnswer
import org.mockito.Mockito.spy
+import org.mockito.Mockito.`when`
import org.mockito.kotlin.any
import org.mockito.kotlin.mock
@@ -55,12 +56,10 @@
private val testScope = TestScope(dispatcher)
private var pendingCallbacksWithDelays = mutableListOf<Long>()
- private lateinit var pendingCommandsToExecute: MutableList<Runnable>
@Suppress("UNCHECKED_CAST")
@Before
fun setup() {
- pendingCommandsToExecute = mutableListOf()
setFlagsRule.setFlags(true, Flags.FLAG_ENABLE_OVERVIEW_COMMAND_HELPER_TIMEOUT)
sut =
@@ -69,8 +68,7 @@
touchInteractionService = mock(),
overviewComponentObserver = mock(),
taskAnimationManager = mock(),
- dispatcherProvider = TestDispatcherProvider(dispatcher),
- uiExecutor = { runnable -> pendingCommandsToExecute += runnable },
+ dispatcherProvider = TestDispatcherProvider(dispatcher)
)
)
@@ -96,21 +94,12 @@
pendingCallbacksWithDelays.add(delayInMillis)
}
- /**
- * This function runs all the pending commands from the Executor for testing purposes. Replacing
- * the uiExecutor allows the test to execute the command queue manually, making it possible to
- * assert each state of the commands in the queue individually.
- */
- private fun executePendingCommands() = pendingCommandsToExecute.forEach { it.run() }
-
@Test
fun whenFirstCommandIsAdded_executeCommandImmediately() =
testScope.runTest {
// Add command to queue
val commandInfo: CommandInfo = sut.addCommand(CommandType.HOME)!!
assertThat(commandInfo.status).isEqualTo(CommandStatus.IDLE)
- executePendingCommands()
- assertThat(commandInfo.status).isEqualTo(CommandStatus.PROCESSING)
runCurrent()
assertThat(commandInfo.status).isEqualTo(CommandStatus.COMPLETED)
}
@@ -125,7 +114,7 @@
val commandInfo: CommandInfo = sut.addCommand(commandType)!!
assertThat(commandInfo.status).isEqualTo(CommandStatus.IDLE)
- executePendingCommands()
+ runCurrent()
assertThat(commandInfo.status).isEqualTo(CommandStatus.PROCESSING)
advanceTimeBy(200L)
@@ -146,14 +135,12 @@
val commandInfo2: CommandInfo = sut.addCommand(commandType2)!!
assertThat(commandInfo2.status).isEqualTo(CommandStatus.IDLE)
- executePendingCommands()
+ runCurrent()
assertThat(commandInfo1.status).isEqualTo(CommandStatus.PROCESSING)
assertThat(commandInfo2.status).isEqualTo(CommandStatus.IDLE)
advanceTimeBy(101L)
assertThat(commandInfo1.status).isEqualTo(CommandStatus.COMPLETED)
-
- executePendingCommands()
assertThat(commandInfo2.status).isEqualTo(CommandStatus.PROCESSING)
advanceTimeBy(101L)
@@ -174,14 +161,12 @@
val commandInfo2: CommandInfo = sut.addCommand(commandType2)!!
assertThat(commandInfo2.status).isEqualTo(CommandStatus.IDLE)
- executePendingCommands()
+ runCurrent()
assertThat(commandInfo1.status).isEqualTo(CommandStatus.PROCESSING)
assertThat(commandInfo2.status).isEqualTo(CommandStatus.IDLE)
advanceTimeBy(QUEUE_TIMEOUT)
assertThat(commandInfo1.status).isEqualTo(CommandStatus.CANCELED)
-
- executePendingCommands()
assertThat(commandInfo2.status).isEqualTo(CommandStatus.PROCESSING)
advanceTimeBy(101)
diff --git a/quickstep/tests/multivalentTests/src/com/android/quickstep/logging/SettingsChangeLoggerTest.kt b/quickstep/tests/multivalentTests/src/com/android/quickstep/logging/SettingsChangeLoggerTest.kt
index 0a60774..7c48ea4 100644
--- a/quickstep/tests/multivalentTests/src/com/android/quickstep/logging/SettingsChangeLoggerTest.kt
+++ b/quickstep/tests/multivalentTests/src/com/android/quickstep/logging/SettingsChangeLoggerTest.kt
@@ -34,7 +34,6 @@
import com.android.launcher3.logging.StatsLogManager.LauncherEvent.LAUNCHER_NOTIFICATION_DOT_ENABLED
import com.android.launcher3.logging.StatsLogManager.LauncherEvent.LAUNCHER_THEMED_ICON_DISABLED
import com.android.launcher3.states.RotationHelper.ALLOW_ROTATION_PREFERENCE_KEY
-import com.android.launcher3.util.DaggerSingletonTracker
import com.google.common.truth.Truth.assertThat
import org.junit.After
import org.junit.Before
@@ -63,7 +62,6 @@
@Mock private lateinit var mMockLogger: StatsLogManager.StatsLogger
@Captor private lateinit var mEventCaptor: ArgumentCaptor<StatsLogManager.EventEnum>
- @Mock private lateinit var mTracker: DaggerSingletonTracker
private var mDefaultThemedIcons = false
private var mDefaultAllowRotation = false
@@ -81,7 +79,7 @@
// To match the default value of ALLOW_ROTATION
LauncherPrefs.get(mContext).put(item = ALLOW_ROTATION, value = false)
- mSystemUnderTest = SettingsChangeLogger(mContext, mStatsLogManager, mTracker)
+ mSystemUnderTest = SettingsChangeLogger(mContext, mStatsLogManager)
}
@After
@@ -92,7 +90,7 @@
@Test
fun loggingPrefs_correctDefaultValue() {
- val systemUnderTest = SettingsChangeLogger(mContext, mStatsLogManager, mTracker)
+ val systemUnderTest = SettingsChangeLogger(mContext, mStatsLogManager)
assertThat(systemUnderTest.loggingPrefs[ALLOW_ROTATION_PREFERENCE_KEY]!!.defaultValue)
.isFalse()
@@ -119,7 +117,7 @@
LauncherPrefs.get(mContext).put(item = ALLOW_ROTATION, value = true)
// This a new object so the values of mLoggablePrefs will be different
- SettingsChangeLogger(mContext, mStatsLogManager, mTracker).logSnapshot(mInstanceId)
+ SettingsChangeLogger(mContext, mStatsLogManager).logSnapshot(mInstanceId)
verify(mMockLogger, atLeastOnce()).log(mEventCaptor.capture())
val capturedEvents = mEventCaptor.allValues
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 7a17872..d6688d6 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
@@ -16,6 +16,7 @@
package com.android.quickstep.recents.data
+import android.graphics.drawable.Drawable
import com.android.systemui.shared.recents.model.Task
import com.android.systemui.shared.recents.model.ThumbnailData
import kotlinx.coroutines.flow.Flow
@@ -25,9 +26,9 @@
class FakeTasksRepository : RecentTasksRepository {
private var thumbnailDataMap: Map<Int, ThumbnailData> = emptyMap()
- private var taskIconDataMap: Map<Int, TaskIconQueryResponse> = emptyMap()
+ private var taskIconDataMap: Map<Int, FakeIconData> = emptyMap()
private var tasks: MutableStateFlow<List<Task>> = MutableStateFlow(emptyList())
- private var visibleTasks: MutableStateFlow<List<Int>> = MutableStateFlow(emptyList())
+ private var visibleTasks: MutableStateFlow<Set<Int>> = MutableStateFlow(emptySet())
override fun getAllTaskData(forceRefresh: Boolean): Flow<List<Task>> = tasks
@@ -48,16 +49,16 @@
override fun getThumbnailById(taskId: Int): Flow<ThumbnailData?> =
getTaskDataById(taskId).map { it?.thumbnail }
- override fun setVisibleTasks(visibleTaskIdList: List<Int>) {
+ override fun setVisibleTasks(visibleTaskIdList: Set<Int>) {
visibleTasks.value = visibleTaskIdList
tasks.value =
tasks.value.map {
it.apply {
thumbnail = thumbnailDataMap[it.key.id]
- taskIconDataMap[it.key.id].let { taskIconData ->
- icon = taskIconData?.icon
- titleDescription = taskIconData?.contentDescription
- title = taskIconData?.title
+ taskIconDataMap[it.key.id].let { data ->
+ title = data?.title
+ titleDescription = data?.titleDescription
+ icon = data?.icon
}
}
}
@@ -71,7 +72,14 @@
this.thumbnailDataMap = thumbnailDataMap
}
- fun seedIconData(iconDataMap: Map<Int, TaskIconQueryResponse>) {
- this.taskIconDataMap = iconDataMap
+ fun seedIconData(id: Int, title: String, contentDescription: String, icon: Drawable) {
+ val iconData = FakeIconData(icon, contentDescription, title)
+ this.taskIconDataMap = mapOf(id to iconData)
}
+
+ private data class FakeIconData(
+ val icon: Drawable,
+ val titleDescription: String,
+ val title: String,
+ )
}
diff --git a/quickstep/tests/multivalentTests/src/com/android/quickstep/recents/data/TasksRepositoryTest.kt b/quickstep/tests/multivalentTests/src/com/android/quickstep/recents/data/TasksRepositoryTest.kt
index d55f2e3..357df6e 100644
--- a/quickstep/tests/multivalentTests/src/com/android/quickstep/recents/data/TasksRepositoryTest.kt
+++ b/quickstep/tests/multivalentTests/src/com/android/quickstep/recents/data/TasksRepositoryTest.kt
@@ -74,7 +74,6 @@
fun getAllTaskDataReturnsFlattenedListOfTasks() =
testScope.runTest {
recentsModel.seedTasks(defaultTaskList)
-
assertThat(systemUnderTest.getAllTaskData(forceRefresh = true).first()).isEqualTo(tasks)
}
@@ -95,7 +94,7 @@
val bitmap2 = taskThumbnailDataSource.taskIdToBitmap[2]
systemUnderTest.getAllTaskData(forceRefresh = true)
- systemUnderTest.setVisibleTasks(listOf(1, 2))
+ systemUnderTest.setVisibleTasks(setOf(1, 2))
assertThat(systemUnderTest.getTaskDataById(1).first()!!.thumbnail!!.thumbnail)
.isEqualTo(bitmap1)
@@ -109,7 +108,7 @@
recentsModel.seedTasks(defaultTaskList)
systemUnderTest.getAllTaskData(forceRefresh = true)
- systemUnderTest.setVisibleTasks(listOf(1, 2))
+ systemUnderTest.setVisibleTasks(setOf(1, 2))
systemUnderTest
.getTaskDataById(1)
@@ -128,14 +127,14 @@
val bitmap2 = taskThumbnailDataSource.taskIdToBitmap[2]
systemUnderTest.getAllTaskData(forceRefresh = true)
- systemUnderTest.setVisibleTasks(listOf(1, 2))
+ systemUnderTest.setVisibleTasks(setOf(1, 2))
assertThat(systemUnderTest.getTaskDataById(2).first()!!.thumbnail!!.thumbnail)
.isEqualTo(bitmap2)
// Prevent new loading of Bitmaps
taskThumbnailDataSource.shouldLoadSynchronously = false
- systemUnderTest.setVisibleTasks(listOf(2, 3))
+ systemUnderTest.setVisibleTasks(setOf(2, 3))
assertThat(systemUnderTest.getTaskDataById(2).first()!!.thumbnail!!.thumbnail)
.isEqualTo(bitmap2)
@@ -147,7 +146,7 @@
recentsModel.seedTasks(defaultTaskList)
systemUnderTest.getAllTaskData(forceRefresh = true)
- systemUnderTest.setVisibleTasks(listOf(1, 2))
+ systemUnderTest.setVisibleTasks(setOf(1, 2))
systemUnderTest
.getTaskDataById(2)
@@ -156,7 +155,7 @@
// Prevent new loading of Drawables
taskThumbnailDataSource.shouldLoadSynchronously = false
- systemUnderTest.setVisibleTasks(listOf(2, 3))
+ systemUnderTest.setVisibleTasks(setOf(2, 3))
systemUnderTest
.getTaskDataById(2)
@@ -171,7 +170,7 @@
val bitmap2 = taskThumbnailDataSource.taskIdToBitmap[2]
systemUnderTest.getAllTaskData(forceRefresh = true)
- systemUnderTest.setVisibleTasks(listOf(1, 2))
+ systemUnderTest.setVisibleTasks(setOf(1, 2))
val task2 = systemUnderTest.getTaskDataById(2).first()!!
assertThat(task2.thumbnail!!.thumbnail).isEqualTo(bitmap2)
@@ -180,7 +179,7 @@
// Prevent new loading of Bitmaps
taskThumbnailDataSource.shouldLoadSynchronously = false
taskIconDataSource.shouldLoadSynchronously = false
- systemUnderTest.setVisibleTasks(listOf(0, 1))
+ systemUnderTest.setVisibleTasks(setOf(0, 1))
val task2AfterVisibleTasksChanged = systemUnderTest.getTaskDataById(2).first()!!
assertThat(task2AfterVisibleTasksChanged.thumbnail).isNull()
@@ -199,7 +198,7 @@
// Setup TasksRepository
systemUnderTest.getAllTaskData(forceRefresh = true)
- systemUnderTest.setVisibleTasks(listOf(1, 2))
+ systemUnderTest.setVisibleTasks(setOf(1, 2))
// Assert there is no bitmap in first emission
assertThat(systemUnderTest.getTaskDataById(2).first()!!.thumbnail).isNull()
@@ -217,8 +216,7 @@
testScope.runTest {
recentsModel.seedTasks(defaultTaskList)
systemUnderTest.getAllTaskData(forceRefresh = true)
-
- systemUnderTest.setVisibleTasks(listOf(1))
+ systemUnderTest.setVisibleTasks(setOf(1))
val expectedThumbnailData = createThumbnailData()
val expectedPreviousBitmap = taskThumbnailDataSource.taskIdToBitmap[1]
@@ -230,7 +228,7 @@
}
taskVisualsChangedDelegate.onTaskThumbnailChanged(1, expectedThumbnailData)
- assertThat(task1ThumbnailValues[1]!!.thumbnail).isEqualTo(expectedPreviousBitmap)
+ assertThat(task1ThumbnailValues.first()!!.thumbnail).isEqualTo(expectedPreviousBitmap)
assertThat(task1ThumbnailValues.last()).isEqualTo(expectedThumbnailData)
}
@@ -240,7 +238,7 @@
recentsModel.seedTasks(defaultTaskList)
systemUnderTest.getAllTaskData(forceRefresh = true)
- systemUnderTest.setVisibleTasks(listOf(1))
+ systemUnderTest.setVisibleTasks(setOf(1))
val expectedBitmap = mock<Bitmap>()
val expectedPreviousBitmap = taskThumbnailDataSource.taskIdToBitmap[1]
@@ -250,10 +248,11 @@
testScope.backgroundScope.launch {
taskDataFlow.map { it?.thumbnail?.thumbnail }.toList(task1ThumbnailValues)
}
+
taskThumbnailDataSource.taskIdToBitmap[1] = expectedBitmap
taskVisualsChangedDelegate.onHighResLoadingStateChanged(true)
- assertThat(task1ThumbnailValues[1]).isEqualTo(expectedPreviousBitmap)
+ assertThat(task1ThumbnailValues.first()).isEqualTo(expectedPreviousBitmap)
assertThat(task1ThumbnailValues.last()).isEqualTo(expectedBitmap)
}
@@ -263,7 +262,7 @@
recentsModel.seedTasks(defaultTaskList)
systemUnderTest.getAllTaskData(forceRefresh = true)
- systemUnderTest.setVisibleTasks(listOf(1))
+ systemUnderTest.setVisibleTasks(setOf(1))
val expectedIcon = FakeTaskIconDataSource.mockCopyableDrawable()
val expectedPreviousIcon = taskIconDataSource.taskIdToDrawable[1]
@@ -276,10 +275,34 @@
taskIconDataSource.taskIdToDrawable[1] = expectedIcon
taskVisualsChangedDelegate.onTaskIconChanged(1)
- assertThat(task1IconValues[1]).isEqualTo(expectedPreviousIcon)
+ assertThat(task1IconValues.first()).isEqualTo(expectedPreviousIcon)
assertThat(task1IconValues.last()).isEqualTo(expectedIcon)
}
+ @Test
+ fun setVisibleTasks_multipleTimesWithDifferentTasks_reusesThumbnailRequests() =
+ testScope.runTest {
+ recentsModel.seedTasks(defaultTaskList)
+ systemUnderTest.getAllTaskData(forceRefresh = true)
+ taskThumbnailDataSource.shouldLoadSynchronously = false
+
+ val taskDataFlow = systemUnderTest.getTaskDataById(1)
+ val task1IconValues = mutableListOf<Drawable?>()
+ testScope.backgroundScope.launch {
+ taskDataFlow.map { it?.icon }.toList(task1IconValues)
+ }
+
+ systemUnderTest.setVisibleTasks(setOf(1))
+ val task1UpdatingTaskOld = taskThumbnailDataSource.taskIdToUpdatingTask[1]
+ println(task1UpdatingTaskOld)
+
+ systemUnderTest.setVisibleTasks(setOf(1, 2))
+ val task1UpdatingTaskNew = taskThumbnailDataSource.taskIdToUpdatingTask[1]
+ println(task1UpdatingTaskNew)
+
+ assertThat(task1UpdatingTaskNew).isEqualTo(task1UpdatingTaskOld)
+ }
+
private fun createTaskWithId(taskId: Int) =
Task(Task.TaskKey(taskId, 0, Intent(), ComponentName("", ""), 0, 2000))
diff --git a/quickstep/tests/multivalentTests/src/com/android/quickstep/recents/usecase/GetThumbnailPositionUseCaseTest.kt b/quickstep/tests/multivalentTests/src/com/android/quickstep/recents/usecase/GetThumbnailPositionUseCaseTest.kt
index 02f1d11..bd7d970 100644
--- a/quickstep/tests/multivalentTests/src/com/android/quickstep/recents/usecase/GetThumbnailPositionUseCaseTest.kt
+++ b/quickstep/tests/multivalentTests/src/com/android/quickstep/recents/usecase/GetThumbnailPositionUseCaseTest.kt
@@ -66,7 +66,7 @@
deviceProfileRepository,
rotationStateRepository,
tasksRepository,
- previewPositionHelper
+ previewPositionHelper,
)
@Test
@@ -80,7 +80,7 @@
@Test
fun visibleTaskWithoutThumbnailData_returnsIdentityMatrix() = runTest {
tasksRepository.seedTasks(listOf(task))
- tasksRepository.setVisibleTasks(listOf(TASK_ID))
+ tasksRepository.setVisibleTasks(setOf(TASK_ID))
assertThat(systemUnderTest.run(TASK_ID, CANVAS_WIDTH, CANVAS_HEIGHT, isRtl = true))
.isInstanceOf(MissingThumbnail::class.java)
@@ -90,7 +90,7 @@
fun visibleTaskWithThumbnailData_returnsTransformedMatrix() = runTest {
tasksRepository.seedThumbnailData(mapOf(TASK_ID to thumbnailData))
tasksRepository.seedTasks(listOf(task))
- tasksRepository.setVisibleTasks(listOf(TASK_ID))
+ tasksRepository.setVisibleTasks(setOf(TASK_ID))
val isLargeScreen = true
deviceProfileRepository.setRecentsDeviceProfile(
@@ -119,7 +119,7 @@
CANVAS_HEIGHT,
isLargeScreen,
activityRotation,
- isRtl
+ isRtl,
)
}
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 12a94cf..73aa460 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
@@ -71,7 +71,7 @@
fun taskVisible_returnsThumbnail() {
tasksRepository.seedTasks(listOf(task))
tasksRepository.seedThumbnailData(mapOf(TaskOverlayViewModelTest.TASK_ID to thumbnailData))
- tasksRepository.setVisibleTasks(listOf(TaskOverlayViewModelTest.TASK_ID))
+ tasksRepository.setVisibleTasks(setOf(TaskOverlayViewModelTest.TASK_ID))
assertThat(systemUnderTest.run(TASK_ID)).isEqualTo(thumbnailData.thumbnail)
}
diff --git a/quickstep/tests/multivalentTests/src/com/android/quickstep/recents/usecase/SysUiStatusNavFlagsUseCaseTest.kt b/quickstep/tests/multivalentTests/src/com/android/quickstep/recents/usecase/SysUiStatusNavFlagsUseCaseTest.kt
index ba4e206..92f2efd 100644
--- a/quickstep/tests/multivalentTests/src/com/android/quickstep/recents/usecase/SysUiStatusNavFlagsUseCaseTest.kt
+++ b/quickstep/tests/multivalentTests/src/com/android/quickstep/recents/usecase/SysUiStatusNavFlagsUseCaseTest.kt
@@ -71,7 +71,7 @@
whenever(width).thenReturn(THUMBNAIL_WIDTH)
whenever(height).thenReturn(THUMBNAIL_HEIGHT)
},
- appearance = APPEARANCE_LIGHT_THEME
+ appearance = APPEARANCE_LIGHT_THEME,
)
val secondTask =
@@ -85,14 +85,14 @@
whenever(width).thenReturn(THUMBNAIL_WIDTH)
whenever(height).thenReturn(THUMBNAIL_HEIGHT)
},
- appearance = APPEARANCE_DARK_THEME
+ appearance = APPEARANCE_DARK_THEME,
)
tasksRepository.seedTasks(listOf(firstTask, secondTask))
tasksRepository.seedThumbnailData(
mapOf(FIRST_TASK_ID to firstThumbnailData, SECOND_TASK_ID to secondThumbnailData)
)
- tasksRepository.setVisibleTasks(listOf(FIRST_TASK_ID, SECOND_TASK_ID))
+ tasksRepository.setVisibleTasks(setOf(FIRST_TASK_ID, SECOND_TASK_ID))
}
companion object {
diff --git a/quickstep/tests/multivalentTests/src/com/android/quickstep/recents/viewmodel/RecentsViewModelTest.kt b/quickstep/tests/multivalentTests/src/com/android/quickstep/recents/viewmodel/RecentsViewModelTest.kt
index 829987c..a32e07d 100644
--- a/quickstep/tests/multivalentTests/src/com/android/quickstep/recents/viewmodel/RecentsViewModelTest.kt
+++ b/quickstep/tests/multivalentTests/src/com/android/quickstep/recents/viewmodel/RecentsViewModelTest.kt
@@ -97,7 +97,7 @@
)
// setVisibleTasks forces FakeTasksRepository to update the flows returned by
// getThumbnailById
- tasksRepository.setVisibleTasks(listOf(1, 2))
+ tasksRepository.setVisibleTasks(setOf(1, 2))
// Then wait for thumbnailData should complete, and the previous getThumbnailById flow
// should return updated values
diff --git a/quickstep/tests/multivalentTests/src/com/android/quickstep/task/thumbnail/SplashAlphaUseCaseTest.kt b/quickstep/tests/multivalentTests/src/com/android/quickstep/task/thumbnail/SplashAlphaUseCaseTest.kt
index a584d71..0767fb9 100644
--- a/quickstep/tests/multivalentTests/src/com/android/quickstep/task/thumbnail/SplashAlphaUseCaseTest.kt
+++ b/quickstep/tests/multivalentTests/src/com/android/quickstep/task/thumbnail/SplashAlphaUseCaseTest.kt
@@ -25,7 +25,6 @@
import android.view.Surface.ROTATION_90
import com.android.quickstep.recents.data.FakeRecentsRotationStateRepository
import com.android.quickstep.recents.data.FakeTasksRepository
-import com.android.quickstep.recents.data.TaskIconQueryResponse
import com.android.quickstep.recents.viewmodel.RecentsViewData
import com.android.quickstep.task.viewmodel.TaskContainerData
import com.android.systemui.shared.recents.model.Task
@@ -49,7 +48,7 @@
taskContainerData,
taskThumbnailViewData,
recentTasksRepository,
- recentsRotationStateRepository
+ recentsRotationStateRepository,
)
@Test
@@ -117,16 +116,16 @@
private fun setupTask(taskId: Int, thumbnailData: ThumbnailData = createThumbnailData()) {
recentTasksRepository.seedThumbnailData(mapOf(taskId to thumbnailData))
- val expectedIconData = createIconData("Task $taskId")
- recentTasksRepository.seedIconData(mapOf(taskId to expectedIconData))
+ val expectedIconData = mock<Drawable>()
+ recentTasksRepository.seedIconData(taskId, "Task $taskId", "", expectedIconData)
recentTasksRepository.seedTasks(tasks)
- recentTasksRepository.setVisibleTasks(listOf(taskId))
+ recentTasksRepository.setVisibleTasks(setOf(taskId))
}
private fun createThumbnailData(
rotation: Int = Surface.ROTATION_0,
width: Int = THUMBNAIL_WIDTH,
- height: Int = THUMBNAIL_HEIGHT
+ height: Int = THUMBNAIL_HEIGHT,
): ThumbnailData {
val bitmap = mock<Bitmap>()
whenever(bitmap.width).thenReturn(width)
@@ -135,8 +134,6 @@
return ThumbnailData(thumbnail = bitmap, rotation = rotation)
}
- private fun createIconData(title: String) = TaskIconQueryResponse(mock<Drawable>(), "", title)
-
private fun createTaskWithId(taskId: Int) =
Task(Task.TaskKey(taskId, 0, Intent(), ComponentName("", ""), 0, 2000)).apply {
colorBackground = Color.argb(taskId, taskId, taskId, taskId)
diff --git a/quickstep/tests/multivalentTests/src/com/android/quickstep/task/thumbnail/TaskThumbnailViewModelImplTest.kt b/quickstep/tests/multivalentTests/src/com/android/quickstep/task/thumbnail/TaskThumbnailViewModelImplTest.kt
index c88a3fc..c541d3d 100644
--- a/quickstep/tests/multivalentTests/src/com/android/quickstep/task/thumbnail/TaskThumbnailViewModelImplTest.kt
+++ b/quickstep/tests/multivalentTests/src/com/android/quickstep/task/thumbnail/TaskThumbnailViewModelImplTest.kt
@@ -25,7 +25,6 @@
import android.view.Surface
import androidx.test.ext.junit.runners.AndroidJUnit4
import com.android.quickstep.recents.data.FakeTasksRepository
-import com.android.quickstep.recents.data.TaskIconQueryResponse
import com.android.quickstep.recents.usecase.GetThumbnailPositionUseCase
import com.android.quickstep.recents.usecase.ThumbnailPositionState.MatrixScaling
import com.android.quickstep.recents.usecase.ThumbnailPositionState.MissingThumbnail
@@ -81,7 +80,7 @@
fun bindRunningTask_thenStateIs_LiveTile() = runTest {
val taskId = 1
tasksRepository.seedTasks(tasks)
- tasksRepository.setVisibleTasks(listOf(taskId))
+ tasksRepository.setVisibleTasks(setOf(taskId))
recentsViewData.runningTaskIds.value = setOf(taskId)
systemUnderTest.bind(taskId)
@@ -93,10 +92,10 @@
val taskId = 1
val expectedThumbnailData = createThumbnailData()
tasksRepository.seedThumbnailData(mapOf(taskId to expectedThumbnailData))
- val expectedIconData = createIconData("Task 1")
- tasksRepository.seedIconData(mapOf(taskId to expectedIconData))
+ val expectedIconData = mock<Drawable>()
+ tasksRepository.seedIconData(taskId, "Task $taskId", "", expectedIconData)
tasksRepository.seedTasks(tasks)
- tasksRepository.setVisibleTasks(listOf(taskId))
+ tasksRepository.setVisibleTasks(setOf(taskId))
recentsViewData.runningTaskIds.value = setOf(taskId)
recentsViewData.runningTaskShowScreenshot.value = true
systemUnderTest.bind(taskId)
@@ -109,7 +108,7 @@
bitmap = expectedThumbnailData.thumbnail!!,
thumbnailRotation = Surface.ROTATION_0,
),
- expectedIconData.icon,
+ expectedIconData,
)
)
}
@@ -151,7 +150,7 @@
val runningTaskId = 1
val stoppedTaskId = 2
tasksRepository.seedTasks(tasks)
- tasksRepository.setVisibleTasks(listOf(runningTaskId, stoppedTaskId))
+ tasksRepository.setVisibleTasks(setOf(runningTaskId, stoppedTaskId))
recentsViewData.runningTaskIds.value = setOf(runningTaskId)
systemUnderTest.bind(runningTaskId)
assertThat(systemUnderTest.uiState.first()).isEqualTo(LiveTile)
@@ -165,7 +164,7 @@
fun bindStoppedTaskWithoutThumbnail_thenStateIs_BackgroundOnly_withAlphaRemoved() = runTest {
val stoppedTaskId = 2
tasksRepository.seedTasks(tasks)
- tasksRepository.setVisibleTasks(listOf(stoppedTaskId))
+ tasksRepository.setVisibleTasks(setOf(stoppedTaskId))
systemUnderTest.bind(stoppedTaskId)
assertThat(systemUnderTest.uiState.first())
@@ -178,7 +177,7 @@
tasksRepository.seedThumbnailData(mapOf(taskId to createThumbnailData()))
tasks[taskId].isLocked = true
tasksRepository.seedTasks(tasks)
- tasksRepository.setVisibleTasks(listOf(taskId))
+ tasksRepository.setVisibleTasks(setOf(taskId))
systemUnderTest.bind(taskId)
assertThat(systemUnderTest.uiState.first())
@@ -190,10 +189,10 @@
val taskId = 2
val expectedThumbnailData = createThumbnailData(rotation = Surface.ROTATION_270)
tasksRepository.seedThumbnailData(mapOf(taskId to expectedThumbnailData))
- val expectedIconData = createIconData("Task 2")
- tasksRepository.seedIconData(mapOf(taskId to expectedIconData))
+ val expectedIconData = mock<Drawable>()
+ tasksRepository.seedIconData(taskId, "Task $taskId", "", expectedIconData)
tasksRepository.seedTasks(tasks)
- tasksRepository.setVisibleTasks(listOf(taskId))
+ tasksRepository.setVisibleTasks(setOf(taskId))
systemUnderTest.bind(taskId)
assertThat(systemUnderTest.uiState.first())
@@ -204,7 +203,7 @@
bitmap = expectedThumbnailData.thumbnail!!,
thumbnailRotation = Surface.ROTATION_270,
),
- expectedIconData.icon,
+ expectedIconData,
)
)
}
@@ -214,14 +213,14 @@
val taskId = 2
val expectedThumbnailData = createThumbnailData()
tasksRepository.seedThumbnailData(mapOf(taskId to expectedThumbnailData))
- val expectedIconData = createIconData("Task 2")
- tasksRepository.seedIconData(mapOf(taskId to expectedIconData))
+ val expectedIconData = mock<Drawable>()
+ tasksRepository.seedIconData(taskId, "Task $taskId", "", expectedIconData)
tasksRepository.seedTasks(tasks)
systemUnderTest.bind(taskId)
assertThat(systemUnderTest.uiState.first()).isEqualTo(Uninitialized)
- tasksRepository.setVisibleTasks(listOf(taskId))
+ tasksRepository.setVisibleTasks(setOf(taskId))
assertThat(systemUnderTest.uiState.first())
.isEqualTo(
SnapshotSplash(
@@ -230,7 +229,7 @@
bitmap = expectedThumbnailData.thumbnail!!,
thumbnailRotation = Surface.ROTATION_0,
),
- expectedIconData.icon,
+ expectedIconData,
)
)
}
@@ -295,8 +294,6 @@
return ThumbnailData(thumbnail = bitmap, rotation = rotation)
}
- private fun createIconData(title: String) = TaskIconQueryResponse(mock<Drawable>(), "", title)
-
companion object {
const val THUMBNAIL_WIDTH = 100
const val THUMBNAIL_HEIGHT = 200
diff --git a/quickstep/tests/multivalentTests/src/com/android/quickstep/task/viewmodel/TaskOverlayViewModelTest.kt b/quickstep/tests/multivalentTests/src/com/android/quickstep/task/viewmodel/TaskOverlayViewModelTest.kt
index d0887df..2e91f5c 100644
--- a/quickstep/tests/multivalentTests/src/com/android/quickstep/task/viewmodel/TaskOverlayViewModelTest.kt
+++ b/quickstep/tests/multivalentTests/src/com/android/quickstep/task/viewmodel/TaskOverlayViewModelTest.kt
@@ -89,12 +89,7 @@
task.isLocked = false
assertThat(systemUnderTest.overlayState.first())
- .isEqualTo(
- Enabled(
- isRealSnapshot = false,
- thumbnail = null,
- )
- )
+ .isEqualTo(Enabled(isRealSnapshot = false, thumbnail = null))
}
@Test
@@ -103,17 +98,12 @@
recentsViewData.settledFullyVisibleTaskIds.value = setOf(TASK_ID)
tasksRepository.seedTasks(listOf(task))
tasksRepository.seedThumbnailData(mapOf(TASK_ID to thumbnailData))
- tasksRepository.setVisibleTasks(listOf(TASK_ID))
+ tasksRepository.setVisibleTasks(setOf(TASK_ID))
thumbnailData.isRealSnapshot = true
task.isLocked = false
assertThat(systemUnderTest.overlayState.first())
- .isEqualTo(
- Enabled(
- isRealSnapshot = true,
- thumbnail = thumbnailData.thumbnail,
- )
- )
+ .isEqualTo(Enabled(isRealSnapshot = true, thumbnail = thumbnailData.thumbnail))
}
@Test
@@ -122,17 +112,12 @@
recentsViewData.settledFullyVisibleTaskIds.value = setOf(TASK_ID)
tasksRepository.seedTasks(listOf(task))
tasksRepository.seedThumbnailData(mapOf(TASK_ID to thumbnailData))
- tasksRepository.setVisibleTasks(listOf(TASK_ID))
+ tasksRepository.setVisibleTasks(setOf(TASK_ID))
thumbnailData.isRealSnapshot = true
task.isLocked = true
assertThat(systemUnderTest.overlayState.first())
- .isEqualTo(
- Enabled(
- isRealSnapshot = false,
- thumbnail = thumbnailData.thumbnail,
- )
- )
+ .isEqualTo(Enabled(isRealSnapshot = false, thumbnail = thumbnailData.thumbnail))
}
@Test
@@ -141,17 +126,12 @@
recentsViewData.settledFullyVisibleTaskIds.value = setOf(TASK_ID)
tasksRepository.seedTasks(listOf(task))
tasksRepository.seedThumbnailData(mapOf(TASK_ID to thumbnailData))
- tasksRepository.setVisibleTasks(listOf(TASK_ID))
+ tasksRepository.setVisibleTasks(setOf(TASK_ID))
thumbnailData.isRealSnapshot = false
task.isLocked = false
assertThat(systemUnderTest.overlayState.first())
- .isEqualTo(
- Enabled(
- isRealSnapshot = false,
- thumbnail = thumbnailData.thumbnail,
- )
- )
+ .isEqualTo(Enabled(isRealSnapshot = false, thumbnail = thumbnailData.thumbnail))
}
@Test
diff --git a/quickstep/tests/src/com/android/quickstep/FallbackRecentsTest.java b/quickstep/tests/src/com/android/quickstep/FallbackRecentsTest.java
index 2858929..1f11c14 100644
--- a/quickstep/tests/src/com/android/quickstep/FallbackRecentsTest.java
+++ b/quickstep/tests/src/com/android/quickstep/FallbackRecentsTest.java
@@ -142,7 +142,7 @@
};
final ViewCaptureRule viewCaptureRule = new ViewCaptureRule(
- RecentsActivity.ACTIVITY_TRACKER::getCreatedActivity);
+ RecentsActivity.ACTIVITY_TRACKER::getCreatedContext);
mOrderSensitiveRules = RuleChain
.outerRule(new SamplerRule())
.around(new TestStabilityRule())
@@ -208,7 +208,7 @@
if (!TestHelpers.isInLauncherProcess()) return null;
Object[] result = new Object[1];
Wait.atMost("Failed to get from recents", () -> MAIN_EXECUTOR.submit(() -> {
- RecentsActivity activity = RecentsActivity.ACTIVITY_TRACKER.getCreatedActivity();
+ RecentsActivity activity = RecentsActivity.ACTIVITY_TRACKER.getCreatedContext();
if (activity == null) {
return false;
}
@@ -231,7 +231,7 @@
private void waitForRecentsActivityStop() {
try {
final boolean recentsActivityIsNull = MAIN_EXECUTOR.submit(
- () -> RecentsActivity.ACTIVITY_TRACKER.getCreatedActivity() == null).get();
+ () -> RecentsActivity.ACTIVITY_TRACKER.getCreatedContext() == null).get();
if (recentsActivityIsNull) {
// Null activity counts as a "stopped" one.
return;
diff --git a/quickstep/tests/src/com/android/quickstep/TaplPrivateSpaceTest.java b/quickstep/tests/src/com/android/quickstep/TaplPrivateSpaceTest.java
index 800fd4a..b15b78e 100644
--- a/quickstep/tests/src/com/android/quickstep/TaplPrivateSpaceTest.java
+++ b/quickstep/tests/src/com/android/quickstep/TaplPrivateSpaceTest.java
@@ -56,8 +56,6 @@
@Override
public void setUp() throws Exception {
super.setUp();
- initialize(this);
-
createAndStartPrivateProfileUser();
mDevice.pressHome();
diff --git a/quickstep/tests/src/com/android/quickstep/desktop/WindowAnimatorTest.kt b/quickstep/tests/src/com/android/quickstep/desktop/WindowAnimatorTest.kt
new file mode 100644
index 0000000..e5e6df3
--- /dev/null
+++ b/quickstep/tests/src/com/android/quickstep/desktop/WindowAnimatorTest.kt
@@ -0,0 +1,139 @@
+/*
+ * Copyright (C) 2024 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.quickstep.desktop
+
+import android.animation.ValueAnimator
+import android.content.Context
+import android.content.res.Resources
+import android.graphics.Rect
+import android.util.DisplayMetrics
+import android.view.SurfaceControl
+import android.window.TransitionInfo
+import androidx.test.ext.junit.runners.AndroidJUnit4
+import androidx.test.filters.SmallTest
+import androidx.test.internal.runner.junit4.statement.UiThreadStatement.runOnUiThread
+import com.android.app.animation.Interpolators
+import com.android.launcher3.desktop.WindowAnimator
+import com.google.common.truth.Truth.assertThat
+import org.junit.Before
+import org.junit.Test
+import org.junit.runner.RunWith
+import org.mockito.ArgumentMatchers.any
+import org.mockito.ArgumentMatchers.anyFloat
+import org.mockito.kotlin.mock
+import org.mockito.kotlin.whenever
+
+@SmallTest
+@RunWith(AndroidJUnit4::class)
+class WindowAnimatorTest {
+
+ private val context = mock<Context>()
+ private val resources = mock<Resources>()
+ private val transaction = mock<SurfaceControl.Transaction>()
+ private val change = mock<TransitionInfo.Change>()
+ private val leash = mock<SurfaceControl>()
+
+ private val displayMetrics = DisplayMetrics().apply { density = 1f }
+
+ @Before
+ fun setup() {
+ whenever(context.resources).thenReturn(resources)
+ whenever(resources.displayMetrics).thenReturn(displayMetrics)
+ whenever(change.leash).thenReturn(leash)
+ whenever(change.startAbsBounds).thenReturn(START_BOUNDS)
+ whenever(transaction.setPosition(any(), anyFloat(), anyFloat())).thenReturn(transaction)
+ whenever(transaction.setScale(any(), anyFloat(), anyFloat())).thenReturn(transaction)
+ }
+
+ @Test
+ fun createBoundsAnimator_returnsCorrectDefaultAnimatorParams() = runOnUiThread {
+ val boundsAnimParams =
+ WindowAnimator.BoundsAnimationParams(
+ durationMs = 100L,
+ interpolator = Interpolators.STANDARD_ACCELERATE,
+ )
+
+ val valueAnimator =
+ WindowAnimator.createBoundsAnimator(context, boundsAnimParams, change, transaction)
+
+ assertThat(valueAnimator.duration).isEqualTo(100L)
+ assertThat(valueAnimator.interpolator).isEqualTo(Interpolators.STANDARD_ACCELERATE)
+ assertStartAndEndBounds(valueAnimator, startBounds = START_BOUNDS, endBounds = START_BOUNDS)
+ }
+
+ @Test
+ fun createBoundsAnimator_startScaleAndOffset_returnsCorrectBounds() = runOnUiThread {
+ val bounds = Rect(/* left= */ 100, /* top= */ 200, /* right= */ 300, /* bottom= */ 400)
+ whenever(change.startAbsBounds).thenReturn(bounds)
+ val boundsAnimParams =
+ WindowAnimator.BoundsAnimationParams(
+ durationMs = 100L,
+ startOffsetYDp = 10f,
+ startScale = 0.5f,
+ interpolator = Interpolators.STANDARD_ACCELERATE,
+ )
+
+ val valueAnimator =
+ WindowAnimator.createBoundsAnimator(context, boundsAnimParams, change, transaction)
+
+ assertStartAndEndBounds(
+ valueAnimator,
+ startBounds =
+ Rect(/* left= */ 150, /* top= */ 260, /* right= */ 250, /* bottom= */ 360),
+ endBounds = bounds,
+ )
+ }
+
+ @Test
+ fun createBoundsAnimator_endScaleAndOffset_returnsCorrectBounds() = runOnUiThread {
+ val bounds = Rect(/* left= */ 100, /* top= */ 200, /* right= */ 300, /* bottom= */ 400)
+ whenever(change.startAbsBounds).thenReturn(bounds)
+ val boundsAnimParams =
+ WindowAnimator.BoundsAnimationParams(
+ durationMs = 100L,
+ endOffsetYDp = 10f,
+ endScale = 0.5f,
+ interpolator = Interpolators.STANDARD_ACCELERATE,
+ )
+
+ val valueAnimator =
+ WindowAnimator.createBoundsAnimator(context, boundsAnimParams, change, transaction)
+
+ assertStartAndEndBounds(
+ valueAnimator,
+ startBounds = bounds,
+ endBounds = Rect(/* left= */ 150, /* top= */ 260, /* right= */ 250, /* bottom= */ 360),
+ )
+ }
+
+ private fun assertStartAndEndBounds(
+ valueAnimator: ValueAnimator,
+ startBounds: Rect,
+ endBounds: Rect,
+ ) {
+ valueAnimator.start()
+ valueAnimator.animatedValue
+ assertThat(valueAnimator.animatedValue).isEqualTo(startBounds)
+ valueAnimator.end()
+ assertThat(valueAnimator.animatedValue).isEqualTo(endBounds)
+ }
+
+ companion object {
+ private val START_BOUNDS =
+ Rect(/* left= */ 10, /* top= */ 20, /* right= */ 30, /* bottom= */ 40)
+ }
+}
diff --git a/res/drawable/bg_letter_list_text.xml b/res/drawable/bg_letter_list_text.xml
index 427702b..bfdd35c 100644
--- a/res/drawable/bg_letter_list_text.xml
+++ b/res/drawable/bg_letter_list_text.xml
@@ -15,7 +15,7 @@
-->
<shape xmlns:android="http://schemas.android.com/apk/res/android"
android:shape="oval">
- <solid android:color="?attr/materialColorSurfaceContainer" />
+ <solid android:color="?attr/materialColorSurface" />
<corners android:radius="100dp"/>
<size
android:width="@dimen/bg_letter_list_text_size"
diff --git a/res/values-fa/strings.xml b/res/values-fa/strings.xml
index 7c6e373..17dd851 100644
--- a/res/values-fa/strings.xml
+++ b/res/values-fa/strings.xml
@@ -102,7 +102,7 @@
<string name="permdesc_write_settings" msgid="726859348127868466">"به برنامه اجازه میدهد تنظیمات و میانبرهای صفحه اصلی را تغییر دهد."</string>
<string name="gadget_error_text" msgid="740356548025791839">"ابزاره را نمیتوان بار کرد"</string>
<string name="gadget_setup_text" msgid="8348374825537681407">"تنظیمات ابزاره"</string>
- <string name="gadget_complete_setup_text" msgid="309040266978007925">"برای تکمیل راهاندازی تکضرب بزنید"</string>
+ <string name="gadget_complete_setup_text" msgid="309040266978007925">"برای تمام کردن راهاندازی تکضرب بزنید"</string>
<string name="uninstall_system_app_text" msgid="4172046090762920660">"این برنامه سیستمی است و حذف نصب نمیشود."</string>
<string name="folder_hint_text" msgid="5174843001373488816">"ویرایش نام"</string>
<string name="disabled_app_label" msgid="6673129024321402780">"<xliff:g id="APP_NAME">%1$s</xliff:g> غیرفعال شد"</string>
diff --git a/res/values/colors.xml b/res/values/colors.xml
index 3f8bede..1eca88d 100644
--- a/res/values/colors.xml
+++ b/res/values/colors.xml
@@ -90,6 +90,7 @@
<color name="drop_target_hover_button_color_dark">#0842A0</color>
<color name="taskbar_running_app_indicator_color">#000000</color>
+ <color name="taskbar_minimized_app_indicator_color">#000000</color>
<color name="preload_icon_accent_color_light">#00668B</color>
<color name="preload_icon_background_color_light">#B5CAD7</color>
diff --git a/res/values/config.xml b/res/values/config.xml
index 701e64a..504218b 100644
--- a/res/values/config.xml
+++ b/res/values/config.xml
@@ -85,7 +85,6 @@
<string name="wallpaper_picker_package" translatable="false"></string>
<string name="local_colors_extraction_class" translatable="false"></string>
<string name="search_session_manager_class" translatable="false"></string>
- <string name="plugin_manager_wrapper_class" translatable="false"></string>
<!-- Scalable Grid configuration -->
<!-- This is a float because it is converted to dp later in DeviceProfile -->
diff --git a/res/values/dimens.xml b/res/values/dimens.xml
index d1e905d..731e24e 100644
--- a/res/values/dimens.xml
+++ b/res/values/dimens.xml
@@ -426,9 +426,7 @@
<dimen name="taskbar_running_app_indicator_height">0dp</dimen>
<dimen name="taskbar_running_app_indicator_width">0dp</dimen>
<dimen name="taskbar_running_app_indicator_top_margin">0dp</dimen>
- <dimen name="taskbar_minimized_app_indicator_height">0dp</dimen>
<dimen name="taskbar_minimized_app_indicator_width">0dp</dimen>
- <dimen name="taskbar_minimized_app_indicator_top_margin">0dp</dimen>
<!-- Transient taskbar (placeholders to compile in Launcher3 without Quickstep) -->
<dimen name="transient_taskbar_padding">0dp</dimen>
diff --git a/src/com/android/launcher3/BubbleTextView.java b/src/com/android/launcher3/BubbleTextView.java
index 76dc770..909272e 100644
--- a/src/com/android/launcher3/BubbleTextView.java
+++ b/src/com/android/launcher3/BubbleTextView.java
@@ -52,7 +52,6 @@
import android.util.AttributeSet;
import android.util.Log;
import android.util.Property;
-import android.util.Size;
import android.util.TypedValue;
import android.view.KeyEvent;
import android.view.MotionEvent;
@@ -187,20 +186,22 @@
@ViewDebug.ExportedProperty(category = "launcher")
private DotInfo mDotInfo;
private DotRenderer mDotRenderer;
- private Locale mCurrentLocale;
+ private String mCurrentLanguage;
@ViewDebug.ExportedProperty(category = "launcher", deepExport = true)
protected DotRenderer.DrawParams mDotParams;
private Animator mDotScaleAnim;
private boolean mForceHideDot;
// These fields, related to showing running apps, are only used for Taskbar.
- private final Size mRunningAppIndicatorSize;
+ private final int mRunningAppIndicatorWidth;
+ private final int mMinimizedAppIndicatorWidth;
+ private final int mRunningAppIndicatorHeight;
private final int mRunningAppIndicatorTopMargin;
- private final Size mMinimizedAppIndicatorSize;
- private final int mMinimizedAppIndicatorTopMargin;
private final Paint mRunningAppIndicatorPaint;
private final Rect mRunningAppIconBounds = new Rect();
private RunningAppState mRunningAppState;
+ private final int mRunningAppIndicatorColor;
+ private final int mMinimizedAppIndicatorColor;
/**
* Various options for the running state of an app.
@@ -277,28 +278,27 @@
defaultIconSize);
a.recycle();
- mRunningAppIndicatorSize = new Size(
- getResources().getDimensionPixelSize(R.dimen.taskbar_running_app_indicator_width),
- getResources().getDimensionPixelSize(R.dimen.taskbar_running_app_indicator_height));
- mMinimizedAppIndicatorSize = new Size(
- getResources().getDimensionPixelSize(R.dimen.taskbar_minimized_app_indicator_width),
- getResources().getDimensionPixelSize(
- R.dimen.taskbar_minimized_app_indicator_height));
+ mRunningAppIndicatorWidth =
+ getResources().getDimensionPixelSize(R.dimen.taskbar_running_app_indicator_width);
+ mMinimizedAppIndicatorWidth =
+ getResources().getDimensionPixelSize(R.dimen.taskbar_minimized_app_indicator_width);
+ mRunningAppIndicatorHeight =
+ getResources().getDimensionPixelSize(R.dimen.taskbar_running_app_indicator_height);
mRunningAppIndicatorTopMargin =
getResources().getDimensionPixelSize(
R.dimen.taskbar_running_app_indicator_top_margin);
- mMinimizedAppIndicatorTopMargin =
- getResources().getDimensionPixelSize(
- R.dimen.taskbar_minimized_app_indicator_top_margin);
+
mRunningAppIndicatorPaint = new Paint();
- mRunningAppIndicatorPaint.setColor(getResources().getColor(
- R.color.taskbar_running_app_indicator_color, context.getTheme()));
+ mRunningAppIndicatorColor = getResources().getColor(
+ R.color.taskbar_running_app_indicator_color, context.getTheme());
+ mMinimizedAppIndicatorColor = getResources().getColor(
+ R.color.taskbar_minimized_app_indicator_color, context.getTheme());
mLongPressHelper = new CheckLongPressHelper(this);
mDotParams = new DotRenderer.DrawParams();
- mCurrentLocale = context.getResources().getConfiguration().locale;
+ mCurrentLanguage = context.getResources().getConfiguration().locale.getLanguage();
setEllipsize(TruncateAt.END);
setAccessibilityDelegate(mActivity.getAccessibilityDelegate());
setTextAlpha(1f);
@@ -494,7 +494,7 @@
}
protected boolean isCurrentLanguageEnglish() {
- return mCurrentLocale.equals(Locale.US);
+ return mCurrentLanguage.equals(Locale.ENGLISH.getLanguage());
}
@UiThread
@@ -716,16 +716,26 @@
return;
}
getIconBounds(mRunningAppIconBounds);
- // TODO(b/333872717): update color, shape, and size of indicator
- boolean isMinimized = mRunningAppState == RunningAppState.MINIMIZED;
- int indicatorTop =
- mRunningAppIconBounds.bottom + (isMinimized ? mMinimizedAppIndicatorTopMargin
- : mRunningAppIndicatorTopMargin);
- final Size indicatorSize =
- isMinimized ? mMinimizedAppIndicatorSize : mRunningAppIndicatorSize;
- canvas.drawRect(mRunningAppIconBounds.centerX() - indicatorSize.getWidth() / 2,
- indicatorTop, mRunningAppIconBounds.centerX() + indicatorSize.getWidth() / 2,
- indicatorTop + indicatorSize.getHeight(), mRunningAppIndicatorPaint);
+ Utilities.scaleRectAboutCenter(
+ mRunningAppIconBounds,
+ IconShape.INSTANCE.get(getContext()).getNormalizationScale());
+
+ final boolean isMinimized = mRunningAppState == RunningAppState.MINIMIZED;
+ final int indicatorTop = mRunningAppIconBounds.bottom + mRunningAppIndicatorTopMargin;
+ final int indicatorWidth =
+ isMinimized ? mMinimizedAppIndicatorWidth : mRunningAppIndicatorWidth;
+ final float cornerRadius = mRunningAppIndicatorHeight / 2f;
+ mRunningAppIndicatorPaint.setColor(
+ isMinimized ? mMinimizedAppIndicatorColor : mRunningAppIndicatorColor);
+
+ canvas.drawRoundRect(
+ mRunningAppIconBounds.centerX() - indicatorWidth / 2f,
+ indicatorTop,
+ mRunningAppIconBounds.centerX() + indicatorWidth / 2f,
+ indicatorTop + mRunningAppIndicatorHeight,
+ cornerRadius,
+ cornerRadius,
+ mRunningAppIndicatorPaint);
}
@Override
@@ -1130,6 +1140,9 @@
if (itemInfo.isDisabled()) {
setContentDescription(getContext().getString(R.string.disabled_app_label,
itemInfo.contentDescription));
+ } else if (itemInfo instanceof WorkspaceItemInfo wai && wai.isArchived()) {
+ setContentDescription(
+ getContext().getString(R.string.app_archived_title, itemInfo.title));
} else if (hasDot()) {
int count = mDotInfo.getNotificationCount();
setContentDescription(
@@ -1142,8 +1155,16 @@
}
private void setDownloadStateContentDescription(ItemInfoWithIcon info, int progressLevel) {
- if ((info.runtimeStatusFlags & ItemInfoWithIcon.FLAG_ARCHIVED) != 0 && progressLevel == 0) {
- setContentDescription(getContext().getString(R.string.app_archived_title, info.title));
+ if ((info.runtimeStatusFlags & ItemInfoWithIcon.FLAG_ARCHIVED) != 0
+ && progressLevel == 0) {
+ if (mIcon instanceof PreloadIconDrawable) {
+ // Tell user that download is pending and not to tap to download again.
+ setContentDescription(getContext().getString(
+ R.string.app_waiting_download_title, info.title));
+ } else {
+ setContentDescription(getContext().getString(
+ R.string.app_archived_title, info.title));
+ }
} else if ((info.runtimeStatusFlags & ItemInfoWithIcon.FLAG_SHOW_DOWNLOAD_PROGRESS_MASK)
!= 0) {
String percentageString = NumberFormat.getPercentInstance()
diff --git a/src/com/android/launcher3/DeviceProfile.java b/src/com/android/launcher3/DeviceProfile.java
index afe0ee1..8862550 100644
--- a/src/com/android/launcher3/DeviceProfile.java
+++ b/src/com/android/launcher3/DeviceProfile.java
@@ -2355,18 +2355,23 @@
/**
* Returns whether Taskbar and Hotseat should adjust horizontally on bubble bar location update.
*/
- public boolean shouldAdjustHotseatOnBubblesLocationUpdate(Context context) {
+ public boolean shouldAdjustHotseatOnNavBarLocationUpdate(Context context) {
return enableBubbleBar()
&& enableBubbleBarInPersistentTaskBar()
&& !DisplayController.getNavigationMode(context).hasGestures;
}
/** Returns hotseat translation X for the bubble bar position. */
- public int getHotseatTranslationXForBubbleBar(boolean isNavbarOnRight, boolean isRtl) {
- if (isNavbarOnRight) {
- return isRtl ? -navButtonsLayoutWidthPx : 0;
+ public int getHotseatTranslationXForNavBar(Context context, boolean isBubblesOnLeft) {
+ if (shouldAdjustHotseatOnNavBarLocationUpdate(context)) {
+ boolean isRtl = Utilities.isRtl(context.getResources());
+ if (isBubblesOnLeft) {
+ return isRtl ? -navButtonsLayoutWidthPx : 0;
+ } else {
+ return isRtl ? 0 : navButtonsLayoutWidthPx;
+ }
} else {
- return isRtl ? 0 : navButtonsLayoutWidthPx;
+ return 0;
}
}
diff --git a/src/com/android/launcher3/Launcher.java b/src/com/android/launcher3/Launcher.java
index a8840fe..8547eb4 100644
--- a/src/com/android/launcher3/Launcher.java
+++ b/src/com/android/launcher3/Launcher.java
@@ -224,10 +224,10 @@
import com.android.launcher3.touch.AllAppsSwipeController;
import com.android.launcher3.touch.ItemLongClickListener;
import com.android.launcher3.util.ActivityResultInfo;
-import com.android.launcher3.util.ActivityTracker;
import com.android.launcher3.util.BackPressHandler;
import com.android.launcher3.util.CannedAnimationCoordinator;
import com.android.launcher3.util.ComponentKey;
+import com.android.launcher3.util.ContextTracker;
import com.android.launcher3.util.IntArray;
import com.android.launcher3.util.IntSet;
import com.android.launcher3.util.ItemInflater;
@@ -292,7 +292,8 @@
PluginListener<LauncherOverlayPlugin> {
public static final String TAG = "Launcher";
- public static final ActivityTracker<Launcher> ACTIVITY_TRACKER = new ActivityTracker<>();
+ public static final ContextTracker.ActivityTracker<Launcher> ACTIVITY_TRACKER =
+ new ContextTracker.ActivityTracker<>();
static final boolean LOGD = false;
@@ -1778,7 +1779,7 @@
@Override
public void onDestroy() {
super.onDestroy();
- ACTIVITY_TRACKER.onActivityDestroyed(this);
+ ACTIVITY_TRACKER.onContextDestroyed(this);
SettingsCache.INSTANCE.get(this).unregister(TOUCHPAD_NATURAL_SCROLLING,
mNaturalScrollingChangedListener);
diff --git a/src/com/android/launcher3/allapps/LetterListTextView.java b/src/com/android/launcher3/allapps/LetterListTextView.java
index 433a7f2..8586078 100644
--- a/src/com/android/launcher3/allapps/LetterListTextView.java
+++ b/src/com/android/launcher3/allapps/LetterListTextView.java
@@ -42,8 +42,6 @@
private final Drawable mLetterBackground;
private final int mLetterListTextWidthAndHeight;
private final int mTextColor;
- private final int mBackgroundColor;
- private final int mSelectedColor;
public LetterListTextView(Context context) {
this(context, null, 0);
@@ -59,8 +57,6 @@
mLetterListTextWidthAndHeight = context.getResources().getDimensionPixelSize(
R.dimen.fastscroll_list_letter_size);
mTextColor = Themes.getAttrColor(context, R.attr.materialColorOnSurface);
- mBackgroundColor = Themes.getAttrColor(context, R.attr.materialColorSurfaceContainer);
- mSelectedColor = Themes.getAttrColor(context, R.attr.materialColorOnSecondary);
}
@Override
@@ -101,26 +97,11 @@
float cutOffMin = currentFingerY - (getHeight() * 2);
float cutOffMax = currentFingerY + (getHeight() * 2);
float cutOffDistance = cutOffMax - cutOffMin;
- // Update the background blend color
boolean isWithinAnimationBounds = getY() < cutOffMax && getY() > cutOffMin;
- if (isWithinAnimationBounds) {
- getBackground().setColorFilter(new PorterDuffColorFilter(
- getBlendColorBasedOnYPosition(currentFingerY, cutOffDistance),
- PorterDuff.Mode.MULTIPLY));
- } else {
- getBackground().setColorFilter(new PorterDuffColorFilter(
- mBackgroundColor, PorterDuff.Mode.MULTIPLY));
- }
translateBasedOnYPosition(currentFingerY, cutOffDistance, isWithinAnimationBounds);
scaleBasedOnYPosition(currentFingerY, cutOffDistance, isWithinAnimationBounds);
}
- private int getBlendColorBasedOnYPosition(int y, float cutOffDistance) {
- float raisedCosineBlend = (float) Math.cos(((y - getY()) / (cutOffDistance)) * Math.PI);
- float blendRatio = Utilities.boundToRange(raisedCosineBlend, 0f, 1f);
- return ColorUtils.blendARGB(mBackgroundColor, mSelectedColor, blendRatio);
- }
-
private void scaleBasedOnYPosition(int y, float cutOffDistance,
boolean isWithinAnimationBounds) {
float raisedCosineScale = (float) Math.cos(((y - getY()) / (cutOffDistance)) * Math.PI)
diff --git a/src/com/android/launcher3/allapps/PrivateProfileManager.java b/src/com/android/launcher3/allapps/PrivateProfileManager.java
index 9c36dc2..21dce14 100644
--- a/src/com/android/launcher3/allapps/PrivateProfileManager.java
+++ b/src/com/android/launcher3/allapps/PrivateProfileManager.java
@@ -220,7 +220,7 @@
* when animation is not running.
*/
public void reset() {
- // Ensure the state of the header views is what it should be before animating.
+ // Ensure the state of the header view is what it should be before animating.
updateView();
getMainRecyclerView().setChildAttachedConsumer(null);
int previousState = getCurrentState();
@@ -435,6 +435,7 @@
lockPill.setVisibility(GONE);
}
}
+ mPSHeader.invalidate();
}
/** Sets the enablement of the profile when header or button is clicked. */
diff --git a/src/com/android/launcher3/allapps/search/AllAppsSearchBarController.java b/src/com/android/launcher3/allapps/search/AllAppsSearchBarController.java
index de3bb9e..7e3e392 100644
--- a/src/com/android/launcher3/allapps/search/AllAppsSearchBarController.java
+++ b/src/com/android/launcher3/allapps/search/AllAppsSearchBarController.java
@@ -118,8 +118,14 @@
@Override
public boolean onEditorAction(TextView v, int actionId, KeyEvent event) {
- if (actionId == EditorInfo.IME_ACTION_SEARCH || actionId == EditorInfo.IME_ACTION_GO) {
- Log.i(TAG, "User tapped ime search button");
+ if (actionId == EditorInfo.IME_ACTION_SEARCH || actionId == EditorInfo.IME_ACTION_GO || (
+ actionId == EditorInfo.IME_NULL && event != null
+ && event.getAction() == KeyEvent.ACTION_DOWN)) {
+ if (actionId == EditorInfo.IME_NULL) {
+ Log.i(TAG, "User pressed ENTER key");
+ } else {
+ Log.i(TAG, "User tapped ime search button");
+ }
// selectFocusedView should return SearchTargetEvent that is passed onto onClick
return mLauncher.getAppsView().getMainAdapterProvider().launchHighlightedItem();
}
diff --git a/src/com/android/launcher3/dagger/LauncherBaseAppComponent.java b/src/com/android/launcher3/dagger/LauncherBaseAppComponent.java
index c3508b7..4537785 100644
--- a/src/com/android/launcher3/dagger/LauncherBaseAppComponent.java
+++ b/src/com/android/launcher3/dagger/LauncherBaseAppComponent.java
@@ -20,8 +20,10 @@
import com.android.launcher3.pm.InstallSessionHelper;
import com.android.launcher3.util.DaggerSingletonTracker;
+import com.android.launcher3.util.PluginManagerWrapper;
import com.android.launcher3.util.ScreenOnTracker;
import com.android.launcher3.util.SettingsCache;
+import com.android.launcher3.util.window.RefreshRateTracker;
import com.android.launcher3.widget.custom.CustomWidgetManager;
import dagger.BindsInstance;
@@ -36,10 +38,12 @@
*/
public interface LauncherBaseAppComponent {
DaggerSingletonTracker getDaggerSingletonTracker();
+ RefreshRateTracker getRefreshRateTracker();
InstallSessionHelper getInstallSessionHelper();
ScreenOnTracker getScreenOnTracker();
SettingsCache getSettingsCache();
CustomWidgetManager getCustomWidgetManager();
+ PluginManagerWrapper getPluginManagerWrapper();
/** Builder for LauncherBaseAppComponent. */
interface Builder {
diff --git a/src/com/android/launcher3/dragndrop/BaseItemDragListener.java b/src/com/android/launcher3/dragndrop/BaseItemDragListener.java
index 981e3a6..43c148a 100644
--- a/src/com/android/launcher3/dragndrop/BaseItemDragListener.java
+++ b/src/com/android/launcher3/dragndrop/BaseItemDragListener.java
@@ -34,7 +34,7 @@
import com.android.launcher3.DragSource;
import com.android.launcher3.DropTarget.DragObject;
import com.android.launcher3.Launcher;
-import com.android.launcher3.util.ActivityTracker.SchedulerCallback;
+import com.android.launcher3.util.ContextTracker.SchedulerCallback;
import com.android.launcher3.widget.PendingItemDragHelper;
import java.util.UUID;
@@ -74,9 +74,9 @@
}
@Override
- public boolean init(Launcher launcher, boolean alreadyOnHome) {
- AbstractFloatingView.closeAllOpenViews(launcher, alreadyOnHome);
- launcher.getStateManager().goToState(NORMAL, alreadyOnHome /* animated */);
+ public boolean init(Launcher launcher, boolean isHomeStarted) {
+ AbstractFloatingView.closeAllOpenViews(launcher, /* animate= */ isHomeStarted);
+ launcher.getStateManager().goToState(NORMAL, /* animated= */ isHomeStarted);
launcher.getDragLayer().setOnDragListener(this);
launcher.getRotationHelper().setStateHandlerRequest(REQUEST_LOCK);
diff --git a/src/com/android/launcher3/model/ItemInstallQueue.java b/src/com/android/launcher3/model/ItemInstallQueue.java
index 59d1d00..49f75eb 100644
--- a/src/com/android/launcher3/model/ItemInstallQueue.java
+++ b/src/com/android/launcher3/model/ItemInstallQueue.java
@@ -121,7 +121,7 @@
@WorkerThread
private void flushQueueInBackground() {
- Launcher launcher = Launcher.ACTIVITY_TRACKER.getCreatedActivity();
+ Launcher launcher = Launcher.ACTIVITY_TRACKER.getCreatedContext();
if (launcher == null) {
// Launcher not loaded
return;
diff --git a/src/com/android/launcher3/states/RotationHelper.java b/src/com/android/launcher3/states/RotationHelper.java
index b3bcada..4c9da5d 100644
--- a/src/com/android/launcher3/states/RotationHelper.java
+++ b/src/com/android/launcher3/states/RotationHelper.java
@@ -36,6 +36,7 @@
import com.android.launcher3.DeviceProfile;
import com.android.launcher3.LauncherPrefChangeListener;
import com.android.launcher3.LauncherPrefs;
+import com.android.launcher3.util.ContextTracker;
import com.android.launcher3.util.DisplayController;
/**
@@ -72,7 +73,7 @@
/**
* Rotation request made by
- * {@link com.android.launcher3.util.ActivityTracker.SchedulerCallback}.
+ * {@link ContextTracker.SchedulerCallback}.
* This supersedes any other request.
*/
private int mStateHandlerRequest = REQUEST_NONE;
diff --git a/src/com/android/launcher3/testing/TestInformationHandler.java b/src/com/android/launcher3/testing/TestInformationHandler.java
index 3a93981..aa3f2f2 100644
--- a/src/com/android/launcher3/testing/TestInformationHandler.java
+++ b/src/com/android/launcher3/testing/TestInformationHandler.java
@@ -246,12 +246,12 @@
case TestProtocol.REQUEST_GET_SPLIT_SELECTION_ACTIVE:
response.putBoolean(TEST_INFO_RESPONSE_FIELD, enableSplitContextually()
- && Launcher.ACTIVITY_TRACKER.getCreatedActivity().isSplitSelectionActive());
+ && Launcher.ACTIVITY_TRACKER.getCreatedContext().isSplitSelectionActive());
return response;
case TestProtocol.REQUEST_ENABLE_ROTATION:
MAIN_EXECUTOR.submit(() ->
- Launcher.ACTIVITY_TRACKER.getCreatedActivity().getRotationHelper()
+ Launcher.ACTIVITY_TRACKER.getCreatedContext().getRotationHelper()
.forceAllowRotationForTesting(Boolean.parseBoolean(arg)));
return response;
@@ -475,12 +475,12 @@
}
protected boolean isLauncherInitialized() {
- return Launcher.ACTIVITY_TRACKER.getCreatedActivity() == null
+ return Launcher.ACTIVITY_TRACKER.getCreatedContext() == null
|| LauncherAppState.getInstance(mContext).getModel().isModelLoaded();
}
protected WindowInsets getWindowInsets(){
- return Launcher.ACTIVITY_TRACKER.getCreatedActivity().getWindow().getDecorView()
+ return Launcher.ACTIVITY_TRACKER.getCreatedContext().getWindow().getDecorView()
.getRootWindowInsets();
}
@@ -489,7 +489,7 @@
*/
public static <T> Bundle getLauncherUIProperty(
BundleSetter<T> bundleSetter, Function<Launcher, T> provider) {
- return getUIProperty(bundleSetter, provider, Launcher.ACTIVITY_TRACKER::getCreatedActivity);
+ return getUIProperty(bundleSetter, provider, Launcher.ACTIVITY_TRACKER::getCreatedContext);
}
/**
diff --git a/src/com/android/launcher3/util/ActivityTracker.java b/src/com/android/launcher3/util/ActivityTracker.java
deleted file mode 100644
index b2d0d75..0000000
--- a/src/com/android/launcher3/util/ActivityTracker.java
+++ /dev/null
@@ -1,117 +0,0 @@
-/*
- * Copyright (C) 2019 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 android.util.Log;
-
-import androidx.annotation.Nullable;
-
-import com.android.launcher3.BaseActivity;
-
-import java.io.PrintWriter;
-import java.lang.ref.WeakReference;
-import java.util.concurrent.CopyOnWriteArrayList;
-
-/**
- * Helper class to statically track activity creation
- * @param <T> The activity type to track
- */
-public final class ActivityTracker<T extends BaseActivity> {
-
- private static final String TAG = "ActivityTracker";
-
- private WeakReference<T> mCurrentActivity = new WeakReference<>(null);
- private CopyOnWriteArrayList<SchedulerCallback<T>> mCallbacks = new CopyOnWriteArrayList<>();
-
- @Nullable
- public <R extends T> R getCreatedActivity() {
- return (R) mCurrentActivity.get();
- }
-
- public void onActivityDestroyed(T activity) {
- if (mCurrentActivity.get() == activity) {
- mCurrentActivity.clear();
- }
- }
-
- /**
- * Call {@link SchedulerCallback#init(BaseActivity, boolean)} when the
- * activity is ready. If the activity is already created, this is called immediately.
- *
- * The tracker maintains a strong ref to the callback, so it is up to the caller to return
- * {@code false} in the callback OR to unregister the callback explicitly.
- *
- * @param callback The callback to call init() on when the activity is ready.
- */
- public void registerCallback(SchedulerCallback<T> callback, String reasonString) {
- Log.d(TAG, "Registering callback: " + callback + ", reason=" + reasonString);
- T activity = mCurrentActivity.get();
- mCallbacks.add(callback);
- if (activity != null) {
- if (!callback.init(activity, activity.isStarted())) {
- unregisterCallback(callback, "ActivityTracker.registerCallback: Intent handled");
- }
- }
- }
-
- /**
- * Unregisters a registered callback.
- */
- public void unregisterCallback(SchedulerCallback<T> callback, String reasonString) {
- Log.d(TAG, "Unregistering callback: " + callback + ", reason=" + reasonString);
- mCallbacks.remove(callback);
- }
-
- public boolean handleCreate(T activity) {
- mCurrentActivity = new WeakReference<>(activity);
- return handleIntent(activity, false /* alreadyOnHome */);
- }
-
- public boolean handleNewIntent(T activity) {
- return handleIntent(activity, activity.isStarted());
- }
-
- private boolean handleIntent(T activity, boolean alreadyOnHome) {
- boolean handled = false;
- if (!mCallbacks.isEmpty()) {
- Log.d(TAG, "handleIntent: mCallbacks=" + mCallbacks);
- }
- for (SchedulerCallback<T> cb : mCallbacks) {
- if (!cb.init(activity, alreadyOnHome)) {
- // Callback doesn't want any more updates
- unregisterCallback(cb, "ActivityTracker.handleIntent: Intent handled");
- }
- handled = true;
- }
- return handled;
- }
-
- public void dump(String prefix, PrintWriter writer) {
- writer.println(prefix + "ActivityTracker:");
- writer.println(prefix + "\tmCurrentActivity=" + mCurrentActivity.get());
- writer.println(prefix + "\tmCallbacks=" + mCallbacks);
- }
-
- public interface SchedulerCallback<T extends BaseActivity> {
-
- /**
- * Called when the activity is ready.
- * @param alreadyOnHome Whether the activity is already started.
- * @return Whether to continue receiving callbacks (i.e. if the activity is recreated).
- */
- boolean init(T activity, boolean alreadyOnHome);
- }
-}
diff --git a/src/com/android/launcher3/util/ContextTracker.java b/src/com/android/launcher3/util/ContextTracker.java
new file mode 100644
index 0000000..c729b4b
--- /dev/null
+++ b/src/com/android/launcher3/util/ContextTracker.java
@@ -0,0 +1,129 @@
+/*
+ * Copyright (C) 2019 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 android.util.Log;
+
+import androidx.annotation.Nullable;
+
+import com.android.launcher3.BaseActivity;
+import com.android.launcher3.views.ActivityContext;
+
+import java.io.PrintWriter;
+import java.lang.ref.WeakReference;
+import java.util.concurrent.CopyOnWriteArrayList;
+
+/**
+ * Helper class to statically track activity creation
+ * @param <CONTEXT> The context type to track
+ */
+public abstract class ContextTracker<CONTEXT extends ActivityContext> {
+
+ private static final String TAG = "ContextTracker";
+
+ private WeakReference<CONTEXT> mCurrentContext = new WeakReference<>(null);
+ private CopyOnWriteArrayList<SchedulerCallback<CONTEXT>> mCallbacks =
+ new CopyOnWriteArrayList<>();
+
+ @Nullable
+ public <R extends CONTEXT> R getCreatedContext() {
+ return (R) mCurrentContext.get();
+ }
+
+ public void onContextDestroyed(CONTEXT context) {
+ if (mCurrentContext.get() == context) {
+ mCurrentContext.clear();
+ }
+ }
+
+ public abstract boolean isHomeStarted(CONTEXT context);
+
+ /**
+ * Call {@link SchedulerCallback#init(ActivityContext, boolean)} when the
+ * context is ready. If the context is already created, this is called immediately.
+ *
+ * The tracker maintains a strong ref to the callback, so it is up to the caller to return
+ * {@code false} in the callback OR to unregister the callback explicitly.
+ *
+ * @param callback The callback to call init() on when the context is ready.
+ */
+ public void registerCallback(SchedulerCallback<CONTEXT> callback, String reasonString) {
+ Log.d(TAG, "Registering callback: " + callback + ", reason=" + reasonString);
+ CONTEXT context = mCurrentContext.get();
+ mCallbacks.add(callback);
+ if (context != null) {
+ if (!callback.init(context, isHomeStarted(context))) {
+ unregisterCallback(callback, "ContextTracker.registerCallback: Intent handled");
+ }
+ }
+ }
+
+ /**
+ * Unregisters a registered callback.
+ */
+ public void unregisterCallback(SchedulerCallback<CONTEXT> callback, String reasonString) {
+ Log.d(TAG, "Unregistering callback: " + callback + ", reason=" + reasonString);
+ mCallbacks.remove(callback);
+ }
+
+ public boolean handleCreate(CONTEXT context) {
+ mCurrentContext = new WeakReference<>(context);
+ return handleCreate(context, /* alreadyOnHome= */ false);
+ }
+
+ public boolean handleNewIntent(CONTEXT context) {
+ return handleCreate(context, isHomeStarted(context));
+ }
+
+ private boolean handleCreate(CONTEXT context, boolean isHomeStarted) {
+ boolean handled = false;
+ if (!mCallbacks.isEmpty()) {
+ Log.d(TAG, "handleIntent: mCallbacks=" + mCallbacks);
+ }
+ for (SchedulerCallback<CONTEXT> cb : mCallbacks) {
+ if (!cb.init(context, isHomeStarted)) {
+ // Callback doesn't want any more updates
+ unregisterCallback(cb, "ContextTracker.handleIntent: Intent handled");
+ }
+ handled = true;
+ }
+ return handled;
+ }
+
+ public void dump(String prefix, PrintWriter writer) {
+ writer.println(prefix + "ContextTracker:");
+ writer.println(prefix + "\tmCurrentContext=" + mCurrentContext.get());
+ writer.println(prefix + "\tmCallbacks=" + mCallbacks);
+ }
+
+ public interface SchedulerCallback<T extends ActivityContext> {
+
+ /**
+ * Called when the context is ready.
+ * @param isHomeStarted Whether the home activity is already started.
+ * @return Whether to continue receiving callbacks (i.e. if the context is recreated).
+ */
+ boolean init(T context, boolean isHomeStarted);
+ }
+
+ public static final class ActivityTracker<T extends BaseActivity> extends ContextTracker<T> {
+
+ @Override
+ public boolean isHomeStarted(T context) {
+ return context.isStarted();
+ }
+ }
+}
diff --git a/src/com/android/launcher3/util/DaggerSingletonTracker.java b/src/com/android/launcher3/util/DaggerSingletonTracker.java
index 2946da1..b7a88db 100644
--- a/src/com/android/launcher3/util/DaggerSingletonTracker.java
+++ b/src/com/android/launcher3/util/DaggerSingletonTracker.java
@@ -16,6 +16,8 @@
package com.android.launcher3.util;
+import static com.android.launcher3.util.Executors.MAIN_EXECUTOR;
+
import com.android.launcher3.dagger.LauncherAppSingleton;
import java.util.ArrayList;
@@ -31,7 +33,9 @@
@LauncherAppSingleton
public class DaggerSingletonTracker implements SafeCloseable {
- private final ArrayList<SafeCloseable> mLauncherAppSingletons = new ArrayList<>();
+ private final ArrayList<SafeCloseable> mCloseables = new ArrayList<>();
+
+ private boolean mClosed = false;
@Inject
DaggerSingletonTracker() {
@@ -44,14 +48,21 @@
* {@link MainThreadInitializedObject.SandboxContext#onDestroy()}
*/
public void addCloseable(SafeCloseable closeable) {
- mLauncherAppSingletons.add(closeable);
+ MAIN_EXECUTOR.execute(() -> {
+ if (mClosed) {
+ closeable.close();
+ } else {
+ mCloseables.add(closeable);
+ }
+ });
}
@Override
public void close() {
+ mClosed = true;
// Destroy in reverse order
- for (int i = mLauncherAppSingletons.size() - 1; i >= 0; i--) {
- mLauncherAppSingletons.get(i).close();
+ for (int i = mCloseables.size() - 1; i >= 0; i--) {
+ mCloseables.get(i).close();
}
}
}
diff --git a/src/com/android/launcher3/util/ExecutorUtil.java b/src/com/android/launcher3/util/ExecutorUtil.java
deleted file mode 100644
index efc0eec..0000000
--- a/src/com/android/launcher3/util/ExecutorUtil.java
+++ /dev/null
@@ -1,37 +0,0 @@
-/*
- * Copyright (C) 2024 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.launcher3.util;
-
-import static com.android.launcher3.util.Executors.MAIN_EXECUTOR;
-
-import android.os.Looper;
-
-import java.util.concurrent.ExecutionException;
-
-public final class ExecutorUtil {
-
- /**
- * Executes runnable on {@link Looper#getMainLooper()}, otherwise fails with an exception.
- */
- public static void executeSyncOnMainOrFail(Runnable runnable) {
- try {
- MAIN_EXECUTOR.submit(runnable).get();
- } catch (InterruptedException | ExecutionException e) {
- throw new RuntimeException(e);
- }
- }
-}
diff --git a/src/com/android/launcher3/util/LockedUserState.kt b/src/com/android/launcher3/util/LockedUserState.kt
index 10559f3..c8d86d4 100644
--- a/src/com/android/launcher3/util/LockedUserState.kt
+++ b/src/com/android/launcher3/util/LockedUserState.kt
@@ -88,6 +88,13 @@
mUserUnlockedActions.add(action)
}
+ /**
+ * Removes a previously queued `Runnable` to be run when the user is unlocked.
+ */
+ fun removeOnUserUnlockedRunnable(action: Runnable) {
+ mUserUnlockedActions.remove(action)
+ }
+
companion object {
@VisibleForTesting
@JvmField
diff --git a/src/com/android/launcher3/util/PluginManagerWrapper.java b/src/com/android/launcher3/util/PluginManagerWrapper.java
index b27aa12..5b28570 100644
--- a/src/com/android/launcher3/util/PluginManagerWrapper.java
+++ b/src/com/android/launcher3/util/PluginManagerWrapper.java
@@ -15,32 +15,39 @@
*/
package com.android.launcher3.util;
-import static com.android.launcher3.util.MainThreadInitializedObject.forOverride;
+import androidx.annotation.AnyThread;
-import com.android.launcher3.R;
+import com.android.launcher3.dagger.LauncherAppSingleton;
+import com.android.launcher3.dagger.LauncherBaseAppComponent;
import com.android.systemui.plugins.Plugin;
import com.android.systemui.plugins.PluginListener;
import java.io.PrintWriter;
-public class PluginManagerWrapper implements ResourceBasedOverride, SafeCloseable {
+import javax.inject.Inject;
- public static final MainThreadInitializedObject<PluginManagerWrapper> INSTANCE =
- forOverride(PluginManagerWrapper.class, R.string.plugin_manager_wrapper_class);
+@LauncherAppSingleton
+public class PluginManagerWrapper{
+ public static final DaggerSingletonObject<PluginManagerWrapper> INSTANCE =
+ new DaggerSingletonObject<>(LauncherBaseAppComponent::getPluginManagerWrapper);
+
+ @Inject
+ public PluginManagerWrapper() { }
+
+ @AnyThread
public <T extends Plugin> void addPluginListener(
PluginListener<T> listener, Class<T> pluginClass) {
addPluginListener(listener, pluginClass, false);
}
+ @AnyThread
public <T extends Plugin> void addPluginListener(
PluginListener<T> listener, Class<T> pluginClass, boolean allowMultiple) {
}
+ @AnyThread
public void removePluginListener(PluginListener<? extends Plugin> listener) { }
- @Override
- public void close() { }
-
public void dump(PrintWriter pw) { }
}
diff --git a/src/com/android/launcher3/util/ScreenOnTracker.java b/src/com/android/launcher3/util/ScreenOnTracker.java
index 3582ad8..50be98b 100644
--- a/src/com/android/launcher3/util/ScreenOnTracker.java
+++ b/src/com/android/launcher3/util/ScreenOnTracker.java
@@ -68,7 +68,7 @@
private void init(DaggerSingletonTracker tracker) {
mIsScreenOn = true;
mReceiver.register(mContext, ACTION_SCREEN_ON, ACTION_SCREEN_OFF, ACTION_USER_PRESENT);
- ExecutorUtil.executeSyncOnMainOrFail(() -> tracker.addCloseable(this));
+ tracker.addCloseable(this);
}
@Override
diff --git a/src/com/android/launcher3/util/SettingsCache.java b/src/com/android/launcher3/util/SettingsCache.java
index a1ed499..29d5032 100644
--- a/src/com/android/launcher3/util/SettingsCache.java
+++ b/src/com/android/launcher3/util/SettingsCache.java
@@ -94,7 +94,7 @@
SettingsCache(@ApplicationContext Context context, DaggerSingletonTracker tracker) {
super(new Handler(Looper.getMainLooper()));
mResolver = context.getContentResolver();
- ExecutorUtil.executeSyncOnMainOrFail(() -> tracker.addCloseable(this));
+ tracker.addCloseable(this);
}
@Override
diff --git a/src/com/android/launcher3/util/window/RefreshRateTracker.java b/src/com/android/launcher3/util/window/RefreshRateTracker.java
index 7814617..e3397d4 100644
--- a/src/com/android/launcher3/util/window/RefreshRateTracker.java
+++ b/src/com/android/launcher3/util/window/RefreshRateTracker.java
@@ -26,25 +26,34 @@
import androidx.annotation.WorkerThread;
-import com.android.launcher3.util.MainThreadInitializedObject;
+import com.android.launcher3.dagger.ApplicationContext;
+import com.android.launcher3.dagger.LauncherAppComponent;
+import com.android.launcher3.dagger.LauncherAppSingleton;
+import com.android.launcher3.util.DaggerSingletonObject;
+import com.android.launcher3.util.DaggerSingletonTracker;
import com.android.launcher3.util.SafeCloseable;
+import javax.inject.Inject;
+
/**
* Utility class to track refresh rate of the current device
*/
+@LauncherAppSingleton
public class RefreshRateTracker implements DisplayListener, SafeCloseable {
- private static final MainThreadInitializedObject<RefreshRateTracker> INSTANCE =
- new MainThreadInitializedObject<>(RefreshRateTracker::new);
+ private static final DaggerSingletonObject<RefreshRateTracker> INSTANCE =
+ new DaggerSingletonObject<>(LauncherAppComponent::getRefreshRateTracker);
private int mSingleFrameMs = 1;
private final DisplayManager mDM;
- private RefreshRateTracker(Context context) {
+ @Inject
+ RefreshRateTracker(@ApplicationContext Context context, DaggerSingletonTracker tracker) {
mDM = context.getSystemService(DisplayManager.class);
updateSingleFrameMs();
mDM.registerDisplayListener(this, UI_HELPER_EXECUTOR.getHandler());
+ tracker.addCloseable(this);
}
/**
diff --git a/src/com/android/launcher3/widget/RoundedCornerEnforcement.java b/src/com/android/launcher3/widget/RoundedCornerEnforcement.java
index cadaf89..e190dc3 100644
--- a/src/com/android/launcher3/widget/RoundedCornerEnforcement.java
+++ b/src/com/android/launcher3/widget/RoundedCornerEnforcement.java
@@ -16,6 +16,8 @@
package com.android.launcher3.widget;
+import static com.android.launcher3.Flags.enforceSystemRadiusForAppWidgets;
+
import android.appwidget.AppWidgetHostView;
import android.content.Context;
import android.content.res.Resources;
@@ -97,6 +99,10 @@
public static float computeEnforcedRadius(@NonNull Context context) {
Resources res = context.getResources();
float systemRadius = res.getDimension(android.R.dimen.system_app_widget_background_radius);
+ if (enforceSystemRadiusForAppWidgets()) {
+ return systemRadius;
+ }
+
float defaultRadius = res.getDimension(R.dimen.enforced_rounded_corner_max_radius);
return Math.min(defaultRadius, systemRadius);
}
diff --git a/src/com/android/launcher3/widget/custom/CustomWidgetManager.java b/src/com/android/launcher3/widget/custom/CustomWidgetManager.java
index 0778172..9dddc18 100644
--- a/src/com/android/launcher3/widget/custom/CustomWidgetManager.java
+++ b/src/com/android/launcher3/widget/custom/CustomWidgetManager.java
@@ -18,6 +18,7 @@
import static com.android.launcher3.Flags.enableSmartspaceAsAWidget;
import static com.android.launcher3.model.data.LauncherAppWidgetInfo.CUSTOM_WIDGET_ID;
+import static com.android.launcher3.util.Executors.MAIN_EXECUTOR;
import static com.android.launcher3.widget.LauncherAppWidgetProviderInfo.CLS_CUSTOM_WIDGET_PREFIX;
import android.appwidget.AppWidgetManager;
@@ -38,10 +39,8 @@
import com.android.launcher3.dagger.LauncherBaseAppComponent;
import com.android.launcher3.util.DaggerSingletonObject;
import com.android.launcher3.util.DaggerSingletonTracker;
-import com.android.launcher3.util.ExecutorUtil;
import com.android.launcher3.util.PackageUserKey;
import com.android.launcher3.util.PluginManagerWrapper;
-import com.android.launcher3.util.SafeCloseable;
import com.android.launcher3.widget.LauncherAppWidgetHostView;
import com.android.launcher3.widget.LauncherAppWidgetProviderInfo;
import com.android.systemui.plugins.CustomWidgetPlugin;
@@ -61,7 +60,7 @@
* CustomWidgetManager handles custom widgets implemented as a plugin.
*/
@LauncherAppSingleton
-public class CustomWidgetManager implements PluginListener<CustomWidgetPlugin>, SafeCloseable {
+public class CustomWidgetManager implements PluginListener<CustomWidgetPlugin> {
public static final DaggerSingletonObject<CustomWidgetManager> INSTANCE =
new DaggerSingletonObject<>(LauncherBaseAppComponent::getCustomWidgetManager);
@@ -75,12 +74,14 @@
private final @NonNull AppWidgetManager mAppWidgetManager;
@Inject
- CustomWidgetManager(@ApplicationContext Context context, DaggerSingletonTracker tracker) {
- this(context, AppWidgetManager.getInstance(context), tracker);
+ CustomWidgetManager(@ApplicationContext Context context, PluginManagerWrapper pluginManager,
+ DaggerSingletonTracker tracker) {
+ this(context, pluginManager, AppWidgetManager.getInstance(context), tracker);
}
@VisibleForTesting
CustomWidgetManager(@ApplicationContext Context context,
+ PluginManagerWrapper pluginManager,
@NonNull AppWidgetManager widgetManager,
DaggerSingletonTracker tracker) {
mContext = context;
@@ -88,35 +89,24 @@
mPlugins = new HashMap<>();
mCustomWidgets = new ArrayList<>();
-
- ExecutorUtil.executeSyncOnMainOrFail(() -> {
- PluginManagerWrapper.INSTANCE.get(context)
- .addPluginListener(this, CustomWidgetPlugin.class, true);
-
- if (enableSmartspaceAsAWidget()) {
- for (String s: context.getResources()
- .getStringArray(R.array.custom_widget_providers)) {
- try {
- Class<?> cls = Class.forName(s);
- CustomWidgetPlugin plugin = (CustomWidgetPlugin)
- cls.getDeclaredConstructor(Context.class).newInstance(context);
- onPluginConnected(plugin, context);
- } catch (ClassNotFoundException | InstantiationException
- | IllegalAccessException
- | ClassCastException | NoSuchMethodException
- | InvocationTargetException e) {
- Log.e(TAG, "Exception found when trying to add custom widgets: " + e);
- }
+ pluginManager.addPluginListener(this, CustomWidgetPlugin.class, true);
+ if (enableSmartspaceAsAWidget()) {
+ for (String s: context.getResources()
+ .getStringArray(R.array.custom_widget_providers)) {
+ try {
+ Class<?> cls = Class.forName(s);
+ CustomWidgetPlugin plugin = (CustomWidgetPlugin)
+ cls.getDeclaredConstructor(Context.class).newInstance(context);
+ MAIN_EXECUTOR.execute(() -> onPluginConnected(plugin, context));
+ } catch (ClassNotFoundException | InstantiationException
+ | IllegalAccessException
+ | ClassCastException | NoSuchMethodException
+ | InvocationTargetException e) {
+ Log.e(TAG, "Exception found when trying to add custom widgets: " + e);
}
}
-
- tracker.addCloseable(this);
- });
- }
-
- @Override
- public void close() {
- PluginManagerWrapper.INSTANCE.get(mContext).removePluginListener(this);
+ }
+ tracker.addCloseable(() -> pluginManager.removePluginListener(this));
}
@Override
diff --git a/tests/Android.bp b/tests/Android.bp
index 9f62d02..9667277 100644
--- a/tests/Android.bp
+++ b/tests/Android.bp
@@ -98,6 +98,8 @@
"com_android_launcher3_flags_lib",
"com_android_wm_shell_flags_lib",
"android.appwidget.flags-aconfig-java",
+ "platform-parametric-runner-lib",
+ "kotlin-reflect",
],
manifest: "AndroidManifest-common.xml",
platform_apis: true,
@@ -111,6 +113,9 @@
asset_dirs: ["assets"],
// TODO(b/319712088): re-enable use_resource_processor
use_resource_processor: false,
+ static_libs: [
+ "kotlin-reflect",
+ ],
}
android_test {
@@ -193,10 +198,7 @@
name: "Launcher3RoboTests",
srcs: [
":launcher3-robo-src",
-
- // Test util classes
":launcher-testing-helpers-robo",
- ":launcher-testing-shared",
],
exclude_srcs: [
//"src/com/android/launcher3/util/CellContentDimensionsTest.kt", // Failing - b/316553889
diff --git a/tests/multivalentTests/src/com/android/launcher3/util/DaggerSingletonDeadlockTest.kt b/tests/multivalentTests/src/com/android/launcher3/util/DaggerSingletonDeadlockTest.kt
new file mode 100644
index 0000000..642c628
--- /dev/null
+++ b/tests/multivalentTests/src/com/android/launcher3/util/DaggerSingletonDeadlockTest.kt
@@ -0,0 +1,77 @@
+/*
+ * Copyright (C) 2024 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.launcher3.util
+
+import androidx.test.filters.SmallTest
+import com.android.launcher3.dagger.LauncherAppComponent
+import com.android.launcher3.util.LauncherModelHelper.SandboxModelContext
+import java.util.concurrent.TimeUnit.SECONDS
+import kotlin.reflect.KFunction
+import kotlin.reflect.full.memberFunctions
+import org.junit.After
+import org.junit.Assert
+import org.junit.Test
+import org.junit.runner.RunWith
+import platform.test.runner.parameterized.ParameterizedAndroidJunit4
+import platform.test.runner.parameterized.Parameters
+
+@SmallTest
+@RunWith(ParameterizedAndroidJunit4::class)
+class DaggerSingletonDeadlockTest(val method: KFunction<*>, val methodName: String) {
+
+ private val context = SandboxModelContext()
+
+ @After
+ fun tearDown() {
+ context.onDestroy()
+ }
+
+ /** Test to verify that the object can be created successfully on the main thread. */
+ @Test
+ fun objectCreationOnMainThread() {
+ Executors.MAIN_EXECUTOR.submit {
+ method.call(context.appComponent).also(Assert::assertNotNull)
+ }
+ .get(10, SECONDS)
+ }
+
+ /**
+ * Test to verify that the object can be created successfully on the background thread, when the
+ * main thread is blocked.
+ */
+ @Test
+ fun objectCreationOnBackgroundThread() {
+ TestUtil.runOnExecutorSync(Executors.MAIN_EXECUTOR) {
+ Executors.THREAD_POOL_EXECUTOR.submit {
+ method.call(context.appComponent).also(Assert::assertNotNull)
+ }
+ .get(10, SECONDS)
+ }
+ }
+
+ companion object {
+ @Parameters(name = "{1}")
+ @JvmStatic
+ fun getTestMethods() =
+ LauncherAppComponent::class
+ .memberFunctions
+ .filter { it.parameters.size == 1 }
+ .map {
+ arrayOf(it, if (it.name.startsWith("get")) it.name.substring(3) else it.name)
+ }
+ }
+}
diff --git a/tests/multivalentTests/src/com/android/launcher3/widget/RoundedCornerEnforcementTest.kt b/tests/multivalentTests/src/com/android/launcher3/widget/RoundedCornerEnforcementTest.kt
index db77702..c82e84c 100644
--- a/tests/multivalentTests/src/com/android/launcher3/widget/RoundedCornerEnforcementTest.kt
+++ b/tests/multivalentTests/src/com/android/launcher3/widget/RoundedCornerEnforcementTest.kt
@@ -19,14 +19,19 @@
import android.content.Context
import android.content.res.Resources
import android.graphics.Rect
+import android.platform.test.annotations.DisableFlags
+import android.platform.test.annotations.EnableFlags
+import android.platform.test.flag.junit.SetFlagsRule
import android.view.View
import android.view.ViewGroup
import androidx.test.ext.junit.runners.AndroidJUnit4
import androidx.test.filters.SmallTest
+import com.android.launcher3.Flags
import com.android.launcher3.R
import org.junit.Assert.assertEquals
import org.junit.Assert.assertSame
import org.junit.Assert.assertTrue
+import org.junit.Rule
import org.junit.Test
import org.junit.runner.RunWith
import org.mockito.Mockito.mock
@@ -38,6 +43,8 @@
@RunWith(AndroidJUnit4::class)
class RoundedCornerEnforcementTest {
+ @get:Rule val setFlagsRule: SetFlagsRule = SetFlagsRule()
+
@Test
fun `Widget view has one background`() {
val mockWidgetView = mock(LauncherAppWidgetHostView::class.java)
@@ -72,14 +79,15 @@
RoundedCornerEnforcement.computeRoundedRectangle(
mockWidgetView,
mockBackgroundView,
- testRect
+ testRect,
)
assertEquals(Rect(50, 75, 250, 275), testRect)
}
@Test
- fun `Compute system radius`() {
+ @DisableFlags(Flags.FLAG_ENFORCE_SYSTEM_RADIUS_FOR_APP_WIDGETS)
+ fun `Compute system radius when smaller`() {
val mockContext = mock(Context::class.java)
val mockRes = mock(Resources::class.java)
@@ -94,6 +102,41 @@
assertEquals(RADIUS, RoundedCornerEnforcement.computeEnforcedRadius(mockContext))
}
+ @Test
+ @DisableFlags(Flags.FLAG_ENFORCE_SYSTEM_RADIUS_FOR_APP_WIDGETS)
+ fun `Compute launcher radius when smaller`() {
+ val mockContext = mock(Context::class.java)
+ val mockRes = mock(Resources::class.java)
+
+ doReturn(mockRes).whenever(mockContext).resources
+ doReturn(LAUNCHER_RADIUS + 8f)
+ .whenever(mockRes)
+ .getDimension(eq(android.R.dimen.system_app_widget_background_radius))
+ doReturn(LAUNCHER_RADIUS)
+ .whenever(mockRes)
+ .getDimension(eq(R.dimen.enforced_rounded_corner_max_radius))
+
+ assertEquals(LAUNCHER_RADIUS, RoundedCornerEnforcement.computeEnforcedRadius(mockContext))
+ }
+
+ @Test
+ @EnableFlags(Flags.FLAG_ENFORCE_SYSTEM_RADIUS_FOR_APP_WIDGETS)
+ fun `Compute system radius ignoring launcher radius`() {
+ val mockContext = mock(Context::class.java)
+ val mockRes = mock(Resources::class.java)
+
+ doReturn(mockRes).whenever(mockContext).resources
+ val systemRadius = LAUNCHER_RADIUS + 8f
+ doReturn(systemRadius)
+ .whenever(mockRes)
+ .getDimension(eq(android.R.dimen.system_app_widget_background_radius))
+ doReturn(LAUNCHER_RADIUS)
+ .whenever(mockRes)
+ .getDimension(eq(R.dimen.enforced_rounded_corner_max_radius))
+
+ assertEquals(systemRadius, RoundedCornerEnforcement.computeEnforcedRadius(mockContext))
+ }
+
companion object {
const val WIDTH = 200
const val HEIGHT = 200
diff --git a/tests/multivalentTests/src/com/android/launcher3/widget/custom/CustomWidgetManagerTest.kt b/tests/multivalentTests/src/com/android/launcher3/widget/custom/CustomWidgetManagerTest.kt
index 82f56b8..1c25db9 100644
--- a/tests/multivalentTests/src/com/android/launcher3/widget/custom/CustomWidgetManagerTest.kt
+++ b/tests/multivalentTests/src/com/android/launcher3/widget/custom/CustomWidgetManagerTest.kt
@@ -26,17 +26,19 @@
import com.android.launcher3.util.DaggerSingletonTracker
import com.android.launcher3.util.LauncherModelHelper.SandboxModelContext
import com.android.launcher3.util.PluginManagerWrapper
+import com.android.launcher3.util.SafeCloseable
import com.android.launcher3.util.WidgetUtils
import com.android.launcher3.widget.LauncherAppWidgetHostView
import com.android.launcher3.widget.LauncherAppWidgetProviderInfo
import com.android.systemui.plugins.CustomWidgetPlugin
-import org.junit.After
import org.junit.Assert.assertEquals
import org.junit.Assert.assertTrue
import org.junit.Before
import org.junit.Rule
import org.junit.Test
import org.junit.runner.RunWith
+import org.mockito.ArgumentCaptor
+import org.mockito.Captor
import org.mockito.Mock
import org.mockito.Mockito.mock
import org.mockito.MockitoAnnotations
@@ -60,16 +62,12 @@
@Mock private lateinit var mockAppWidgetManager: AppWidgetManager
@Mock private lateinit var tracker: DaggerSingletonTracker
+ @Captor private lateinit var closableCaptor: ArgumentCaptor<SafeCloseable>
+
@Before
fun setUp() {
MockitoAnnotations.initMocks(this)
- context.putObject(PluginManagerWrapper.INSTANCE, pluginManager)
- underTest = CustomWidgetManager(context, mockAppWidgetManager, tracker)
- }
-
- @After
- fun tearDown() {
- underTest.close()
+ underTest = CustomWidgetManager(context, pluginManager, mockAppWidgetManager, tracker)
}
@Test
@@ -80,7 +78,8 @@
@Test
fun close_widget_manager_should_remove_plugin_listener() {
- underTest.close()
+ verify(tracker).addCloseable(closableCaptor.capture())
+ closableCaptor.allValues.forEach(SafeCloseable::close)
verify(pluginManager).removePluginListener(same(underTest))
}
diff --git a/tests/src/com/android/launcher3/ui/AbstractLauncherUiTest.java b/tests/src/com/android/launcher3/ui/AbstractLauncherUiTest.java
index df5c80d..206647a 100644
--- a/tests/src/com/android/launcher3/ui/AbstractLauncherUiTest.java
+++ b/tests/src/com/android/launcher3/ui/AbstractLauncherUiTest.java
@@ -257,7 +257,7 @@
protected TestRule getRulesInsideActivityMonitor() {
final ViewCaptureRule viewCaptureRule = new ViewCaptureRule(
- Launcher.ACTIVITY_TRACKER::getCreatedActivity);
+ Launcher.ACTIVITY_TRACKER::getCreatedContext);
final RuleChain inner = RuleChain
.outerRule(new PortraitLandscapeRunner<LAUNCHER_TYPE>(this))
.around(new FailureWatcher(mLauncher, viewCaptureRule::getViewCaptureData))
@@ -414,6 +414,7 @@
public void verifyLauncherState() {
try {
// Limits UI tests affecting tests running after them.
+ mDevice.pressHome();
mLauncher.waitForLauncherInitialized();
if (mLauncherPid != 0) {
assertEquals("Launcher crashed, pid mismatch:",
@@ -455,7 +456,7 @@
protected <T> T getFromLauncher(Function<LAUNCHER_TYPE, T> f) {
if (!TestHelpers.isInLauncherProcess()) return null;
- return getOnUiThread(() -> f.apply(Launcher.ACTIVITY_TRACKER.getCreatedActivity()));
+ return getOnUiThread(() -> f.apply(Launcher.ACTIVITY_TRACKER.getCreatedContext()));
}
protected void executeOnLauncher(Consumer<LAUNCHER_TYPE> f) {
diff --git a/tests/src/com/android/launcher3/ui/TaplWorkProfileTest.java b/tests/src/com/android/launcher3/ui/TaplWorkProfileTest.java
index b38dd4b..a45e3bb 100644
--- a/tests/src/com/android/launcher3/ui/TaplWorkProfileTest.java
+++ b/tests/src/com/android/launcher3/ui/TaplWorkProfileTest.java
@@ -70,7 +70,6 @@
@Override
public void setUp() throws Exception {
super.setUp();
- initialize(this);
String output =
mDevice.executeShellCommand(
"pm create-user --profileOf 0 --managed TestProfile");
diff --git a/tests/src/com/android/launcher3/ui/widget/TaplAddConfigWidgetTest.java b/tests/src/com/android/launcher3/ui/widget/TaplAddConfigWidgetTest.java
index 961e7fc..7ff4f22 100644
--- a/tests/src/com/android/launcher3/ui/widget/TaplAddConfigWidgetTest.java
+++ b/tests/src/com/android/launcher3/ui/widget/TaplAddConfigWidgetTest.java
@@ -136,7 +136,7 @@
@Override
public boolean isTrue() throws Throwable {
return mMainThreadExecutor.submit(() -> {
- Launcher l = Launcher.ACTIVITY_TRACKER.getCreatedActivity();
+ Launcher l = Launcher.ACTIVITY_TRACKER.getCreatedContext();
return l != null && l.getWorkspace().getFirstMatch(this) != null;
}).get();
}
diff --git a/tests/src/com/android/launcher3/ui/widget/TaplRequestPinItemTest.java b/tests/src/com/android/launcher3/ui/widget/TaplRequestPinItemTest.java
index 74047f0..35c7cab 100644
--- a/tests/src/com/android/launcher3/ui/widget/TaplRequestPinItemTest.java
+++ b/tests/src/com/android/launcher3/ui/widget/TaplRequestPinItemTest.java
@@ -187,7 +187,7 @@
@Override
public boolean isTrue() throws Throwable {
return mMainThreadExecutor.submit(() -> {
- Launcher l = Launcher.ACTIVITY_TRACKER.getCreatedActivity();
+ Launcher l = Launcher.ACTIVITY_TRACKER.getCreatedContext();
return l != null && l.getWorkspace().getFirstMatch(mOp) != null;
}).get();
}
diff --git a/tests/src/com/android/launcher3/ui/workspace/TaplWorkspaceTest.java b/tests/src/com/android/launcher3/ui/workspace/TaplWorkspaceTest.java
index 490cff2..237f2a9 100644
--- a/tests/src/com/android/launcher3/ui/workspace/TaplWorkspaceTest.java
+++ b/tests/src/com/android/launcher3/ui/workspace/TaplWorkspaceTest.java
@@ -32,7 +32,6 @@
import com.android.launcher3.util.rule.ScreenRecordRule.ScreenRecord;
import org.junit.After;
-import org.junit.Before;
import org.junit.Test;
/**
@@ -50,12 +49,6 @@
return launcher.getWorkspace().getCurrentPage();
}
- @Before
- public void setUp() throws Exception {
- super.setUp();
- initialize(this);
- }
-
@After
public void tearDown() throws Exception {
if (mLauncherLayout != null) {