Merge "Animate the bubble notification in overview" into main
diff --git a/Android.bp b/Android.bp
index 223e2c2..73d0fce 100644
--- a/Android.bp
+++ b/Android.bp
@@ -387,6 +387,7 @@
"//frameworks/libs/systemui:view_capture",
"//frameworks/libs/systemui:animationlib",
"//frameworks/libs/systemui:contextualeducationlib",
+ "//frameworks/libs/systemui:msdl",
"SystemUI-statsd",
"launcher-testing-shared",
"androidx.lifecycle_lifecycle-common-java8",
diff --git a/aconfig/launcher.aconfig b/aconfig/launcher.aconfig
index 949acc1..878aa6e 100644
--- a/aconfig/launcher.aconfig
+++ b/aconfig/launcher.aconfig
@@ -311,6 +311,13 @@
}
flag {
+ name: "all_apps_sheet_for_handheld"
+ namespace: "launcher"
+ description: "All Apps will be presented on a bottom sheet in handheld mode"
+ bug: "374186088"
+}
+
+flag {
name: "multiline_search_bar"
namespace: "launcher"
description: "Search bar can wrap to multi-line"
@@ -506,3 +513,17 @@
description: "Enable launcher app contrast tiles."
bug: "341217082"
}
+
+flag {
+ name: "msdl_feedback"
+ namespace: "launcher"
+ description: "Enable MSDL feedback for Launcher interactions"
+ bug: "377496684"
+}
+
+flag {
+ name: "taskbar_recents_layout_transition"
+ namespace: "launcher"
+ description: "Enable Taskbar LayoutTransition for Recent Apps"
+ bug: "343521765"
+}
\ No newline at end of file
diff --git a/aconfig/launcher_overview.aconfig b/aconfig/launcher_overview.aconfig
index 4335f76..93d8d54 100644
--- a/aconfig/launcher_overview.aconfig
+++ b/aconfig/launcher_overview.aconfig
@@ -54,4 +54,11 @@
namespace: "launcher_overview"
description: "Makes the desktop windowing task carousel detaches from fullscreen task carousel during quickswitch."
bug: "353947917"
+}
+
+flag {
+ name: "enable_desktop_exploded_view"
+ namespace: "launcher_overview"
+ description: "Enables the non-overlapping layout for desktop windows in Overview mode."
+ bug: "378011776"
}
\ No newline at end of file
diff --git a/go/quickstep/res/values-ne/strings.xml b/go/quickstep/res/values-ne/strings.xml
index e66f063..4f771c3 100644
--- a/go/quickstep/res/values-ne/strings.xml
+++ b/go/quickstep/res/values-ne/strings.xml
@@ -9,11 +9,11 @@
<string name="dialog_cancel" msgid="6464336969134856366">"रद्द गर्नुहोस्"</string>
<string name="dialog_settings" msgid="6564397136021186148">"सेटिङ"</string>
<string name="niu_actions_confirmation_title" msgid="3863451714863526143">"स्क्रिनमा देखिने पाठ अनुवाद गर्नुहोस् वा पढेर सुनाउनुहोस्"</string>
- <string name="niu_actions_confirmation_text" msgid="2105271481950866089">"तपाईंको स्क्रिनमा देखिने पाठ, वेब ठेगाना र स्क्रिनसटलगायतका जानकारी Google सँग सेयर गर्न सकिन्छ।\n\nकुन कुन जानकारी सेयर गर्न दिने भन्ने सेटिङ बदल्न "<b>"सेटिङ > एप > डिफल्ट एप > डिजिटल सहायक एप"</b>" मा जानुहोस्।"</string>
+ <string name="niu_actions_confirmation_text" msgid="2105271481950866089">"तपाईंको स्क्रिनमा देखिने पाठ, वेब ठेगाना र स्क्रिनसटलगायतका जानकारी Google सँग सेयर गर्न सकिन्छ।\n\nकुन कुन जानकारी सेयर गर्न दिने भन्ने सेटिङ बदल्न "<b>"सेटिङ > एप > डिफल्ट एप > डिजिटल एसिस्टेन्ट एप"</b>" मा जानुहोस्।"</string>
<string name="assistant_not_selected_title" msgid="5017072974603345228">"तपाईं यो सुविधा चलाउन चाहनुहुन्छ भने कुनै सहायक छनौट गर्नुहोस्"</string>
- <string name="assistant_not_selected_text" msgid="3244613673884359276">"तपाईं आफ्नो स्क्रिनमा देखिने पाठ सुन्न वा अनुवाद गर्न चाहनुहुन्छ भने सेटिङमा गई कुनै डिजिटल सहायक एप छनौट गर्नुहोस्"</string>
+ <string name="assistant_not_selected_text" msgid="3244613673884359276">"तपाईं आफ्नो स्क्रिनमा देखिने पाठ सुन्न वा अनुवाद गर्न चाहनुहुन्छ भने सेटिङमा गई कुनै डिजिटल एसिस्टेन्ट एप छनौट गर्नुहोस्"</string>
<string name="assistant_not_supported_title" msgid="1675788067597484142">"तपाईं यो सुविधा चलाउन चाहनुहुन्छ भने आफ्नो सहायक परिवर्तन गर्नुहोस्"</string>
- <string name="assistant_not_supported_text" msgid="1708031078549268884">"तपाईं आफ्नो स्क्रिनमा देखिने पाठ सुन्न वा अनुवाद गर्न चाहनुहुन्छ भने सेटिङमा गई कुनै डिजिटल सहायक एप परिर्वर्तन गर्नुहोस्"</string>
+ <string name="assistant_not_supported_text" msgid="1708031078549268884">"तपाईं आफ्नो स्क्रिनमा देखिने पाठ सुन्न वा अनुवाद गर्न चाहनुहुन्छ भने सेटिङमा गई कुनै डिजिटल एसिस्टेन्ट एप परिर्वर्तन गर्नुहोस्"</string>
<string name="tooltip_listen" msgid="7634466447860989102">"तपाईं यो स्क्रिनमा देखिने पाठ सुन्न चाहनुहुन्छ यहाँ ट्याप गर्नुहोस्"</string>
<string name="tooltip_translate" msgid="4184845868901542567">"तपाईं यो स्क्रिनमा देखिने पाठ अनुवाद गर्न चाहनुहुन्छ यहाँ ट्याप गर्नुहोस्"</string>
<string name="toast_p2p_app_not_shareable" msgid="7229739094132131536">"यो एप अरूलाई चलाउन दिन मिल्दैन"</string>
diff --git a/quickstep/res/layout/task_desktop.xml b/quickstep/res/layout/task_desktop.xml
index 1564653..0472007 100644
--- a/quickstep/res/layout/task_desktop.xml
+++ b/quickstep/res/layout/task_desktop.xml
@@ -19,16 +19,11 @@
android:id="@+id/task_view_desktop"
android:layout_width="match_parent"
android:layout_height="match_parent"
- android:clipChildren="true"
- android:clipToPadding="true"
android:contentDescription="@string/recent_task_desktop"
android:defaultFocusHighlightEnabled="false"
android:focusable="true"
- android:padding="0.1dp"
launcher:focusBorderColor="?attr/materialColorOutline"
launcher:hoverBorderColor="?attr/materialColorPrimary">
- <!-- Setting a padding of 0.1 dp since android:clipToPadding needs a non-zero value for
- padding to work-->
<View
android:id="@+id/background"
android:layout_width="match_parent"
@@ -40,4 +35,9 @@
android:layout_height="wrap_content"
android:inflatedId="@id/icon" />
+ <com.android.quickstep.views.DesktopTaskContentView
+ android:id="@+id/desktop_content"
+ android:layout_width="match_parent"
+ android:layout_height="match_parent" />
+
</com.android.quickstep.views.DesktopTaskView>
diff --git a/quickstep/res/values-az/strings.xml b/quickstep/res/values-az/strings.xml
index a87ed44..6c5748d 100644
--- a/quickstep/res/values-az/strings.xml
+++ b/quickstep/res/values-az/strings.xml
@@ -69,7 +69,7 @@
<string name="home_gesture_intro_title" msgid="836590312858441830">"Əsas səhifəyə keçmək üçün sürüşdürün"</string>
<string name="home_gesture_intro_subtitle" msgid="2632238748497975326">"Ekranın aşağısından yuxarısına sürüşdürün. Bu jest həmişə Əsas səhifəyə aparır."</string>
<string name="home_gesture_spoken_intro_subtitle" msgid="1030987707382031750">"2 barmaqla ekranın aşağısından yuxarısına sürüşdürün. Bu jest həmişə Əsas səhifəyə aparır."</string>
- <string name="home_gesture_tutorial_title" msgid="3126834347496917376">"Əsas səhifəyə qayıdın"</string>
+ <string name="home_gesture_tutorial_title" msgid="3126834347496917376">"Əsas səhifəyə keçin"</string>
<string name="home_gesture_tutorial_subtitle" msgid="7245995490408668778">"Ekranın aşağısından yuxarı sürüşdürün"</string>
<string name="home_gesture_tutorial_success" msgid="1736295017642244751">"Əla!"</string>
<string name="overview_gesture_feedback_swipe_too_far_from_edge" msgid="6402349235265407385">"Ekranın aşağı kənarından yuxarı sürüşdürün"</string>
diff --git a/quickstep/res/values-cs/strings.xml b/quickstep/res/values-cs/strings.xml
index f868baa..de550d1 100644
--- a/quickstep/res/values-cs/strings.xml
+++ b/quickstep/res/values-cs/strings.xml
@@ -52,8 +52,8 @@
<string name="back_gesture_feedback_swipe_too_far_from_edge" msgid="4175100312909721217">"Přejeďte prstem z úplného pravého nebo levého okraje obrazovky"</string>
<string name="back_gesture_feedback_cancelled" msgid="762621530959111290">"Přejeďte prstem z pravého nebo levého okraje doprostřed obrazovky a zdvihněte prst"</string>
<string name="back_gesture_feedback_complete_with_overview_follow_up" msgid="9176400654037014471">"Naučili jste se, jak se vrátit zpět přejetím prstem zprava. Teď se naučíte přepínat mezi aplikacemi."</string>
- <string name="back_gesture_feedback_complete_with_follow_up" msgid="8653374779579748392">"Dokončili jste gesto pro přechod zpět. Teď se naučíte přepínat aplikace."</string>
- <string name="back_gesture_feedback_complete_without_follow_up" msgid="197189945858268342">"Dokončili jste gesto pro přechod zpět"</string>
+ <string name="back_gesture_feedback_complete_with_follow_up" msgid="8653374779579748392">"Provedli jste gesto pro přechod zpět. Teď se naučíte přepínat aplikace."</string>
+ <string name="back_gesture_feedback_complete_without_follow_up" msgid="197189945858268342">"Provedli jste gesto pro přechod zpět"</string>
<string name="back_gesture_feedback_swipe_in_nav_bar" msgid="9157480023651452969">"Dejte pozor, abyste prstem nepřejížděli moc blízko ke spodnímu okraji obrazovky"</string>
<string name="back_gesture_tutorial_confirm_subtitle" msgid="5181305411668713250">"Citlivost gesta pro přechod zpět můžete změnit v Nastavení"</string>
<string name="back_gesture_intro_title" msgid="19551256430224428">"Přejetím prstem se vrátíte zpět"</string>
@@ -64,8 +64,8 @@
<string name="home_gesture_feedback_swipe_too_far_from_edge" msgid="4816365433160895458">"Přejeďte prstem nahoru z dolního okraje obrazovky"</string>
<string name="home_gesture_feedback_overview_detected" msgid="5177627157303895077">"Před zdvihnutím prstu nedělejte pauzu"</string>
<string name="home_gesture_feedback_wrong_swipe_direction" msgid="8328465201424027148">"Přejeďte prstem přímo nahoru"</string>
- <string name="home_gesture_feedback_complete_with_follow_up" msgid="8766981412895888417">"Dokončili jste gesto pro přechod na plochu. Teď se naučíte vrátit se zpět."</string>
- <string name="home_gesture_feedback_complete_without_follow_up" msgid="2978063221383413443">"Dokončili jste gesto pro přechod na plochu"</string>
+ <string name="home_gesture_feedback_complete_with_follow_up" msgid="8766981412895888417">"Provedli jste gesto pro přechod na plochu. Teď se naučíte vrátit se zpět."</string>
+ <string name="home_gesture_feedback_complete_without_follow_up" msgid="2978063221383413443">"Provedli jste gesto pro přechod na plochu"</string>
<string name="home_gesture_intro_title" msgid="836590312858441830">"Přechod na plochu přejetím prstem"</string>
<string name="home_gesture_intro_subtitle" msgid="2632238748497975326">"Přejeďte prstem ze spodní části obrazovky nahoru. Tímto gestem se vždy dostanete na plochu."</string>
<string name="home_gesture_spoken_intro_subtitle" msgid="1030987707382031750">"Přejeďte dvěma prsty z dolního okraje obrazovky nahoru. Tímto gestem se vždy dostanete na plochu."</string>
@@ -76,7 +76,7 @@
<string name="overview_gesture_feedback_home_detected" msgid="663432226180397138">"Zkuste podržet okno delší dobu, než ho uvolníte"</string>
<string name="overview_gesture_feedback_wrong_swipe_direction" msgid="1191055451018584958">"Přejeďte prstem přímo nahoru a pak udělejte pauzu"</string>
<string name="overview_gesture_feedback_complete_with_follow_up" msgid="3544611727467765026">"Naučili jste se používat gesta. Vypnout je můžete v Nastavení."</string>
- <string name="overview_gesture_feedback_complete_without_follow_up" msgid="2903050864432331629">"Dokončili jste gesto pro přepínání aplikací"</string>
+ <string name="overview_gesture_feedback_complete_without_follow_up" msgid="2903050864432331629">"Provedli jste gesto pro přepínání aplikací"</string>
<string name="overview_gesture_intro_title" msgid="2902054412868489378">"Přepínání aplikací přejetím prstem"</string>
<string name="overview_gesture_intro_subtitle" msgid="4968091015637850859">"Přejeďte nahoru z dolního okraje obrazovky, podržte obrazovku a uvolněte."</string>
<string name="overview_gesture_spoken_intro_subtitle" msgid="3853371838260201751">"Přepínání mezi aplikacemi: Přejeďte dvěma prsty nahoru z dolního okraje obrazovky, podržte obrazovku a uvolněte."</string>
diff --git a/quickstep/res/values-da/strings.xml b/quickstep/res/values-da/strings.xml
index 07ab18b..b022172 100644
--- a/quickstep/res/values-da/strings.xml
+++ b/quickstep/res/values-da/strings.xml
@@ -52,8 +52,8 @@
<string name="back_gesture_feedback_swipe_too_far_from_edge" msgid="4175100312909721217">"Stryg fra kanten yderst til højre eller venstre"</string>
<string name="back_gesture_feedback_cancelled" msgid="762621530959111290">"Stryg fra højre eller venstre kant mod midten af skærmen, og løft fingeren"</string>
<string name="back_gesture_feedback_complete_with_overview_follow_up" msgid="9176400654037014471">"Du har lært, hvordan du stryger fra højre for at gå tilbage. Nu skal du se, hvordan du skifter app."</string>
- <string name="back_gesture_feedback_complete_with_follow_up" msgid="8653374779579748392">"Du har fuldført bevægelsen for Gå tilbage. Som det næste kan du se, hvordan du skifter app."</string>
- <string name="back_gesture_feedback_complete_without_follow_up" msgid="197189945858268342">"Du har fuldført bevægelsen for Gå tilbage"</string>
+ <string name="back_gesture_feedback_complete_with_follow_up" msgid="8653374779579748392">"Du har udført bevægelsen for Gå tilbage. Som det næste kan du se, hvordan du skifter app."</string>
+ <string name="back_gesture_feedback_complete_without_follow_up" msgid="197189945858268342">"Du har udført bevægelsen for Gå tilbage"</string>
<string name="back_gesture_feedback_swipe_in_nav_bar" msgid="9157480023651452969">"Undgå at stryge for tæt på bunden af skærmen"</string>
<string name="back_gesture_tutorial_confirm_subtitle" msgid="5181305411668713250">"Juster følsomheden for bevægelsen Gå tilbage i Indstillinger"</string>
<string name="back_gesture_intro_title" msgid="19551256430224428">"Stryg for at gå tilbage"</string>
@@ -64,8 +64,8 @@
<string name="home_gesture_feedback_swipe_too_far_from_edge" msgid="4816365433160895458">"Stryg opad fra bunden af skærmen"</string>
<string name="home_gesture_feedback_overview_detected" msgid="5177627157303895077">"Undlad at holde fingeren stille, indtil du løfter fingeren"</string>
<string name="home_gesture_feedback_wrong_swipe_direction" msgid="8328465201424027148">"Stryg lige opad"</string>
- <string name="home_gesture_feedback_complete_with_follow_up" msgid="8766981412895888417">"Du har fuldført bevægelsen for Gå til startskærmen. Som det næste kan du se, hvordan du går tilbage."</string>
- <string name="home_gesture_feedback_complete_without_follow_up" msgid="2978063221383413443">"Du har fuldført bevægelsen for Gå til startskærmen"</string>
+ <string name="home_gesture_feedback_complete_with_follow_up" msgid="8766981412895888417">"Du har udført bevægelsen for Gå til startskærmen. Som det næste kan du se, hvordan du går tilbage."</string>
+ <string name="home_gesture_feedback_complete_without_follow_up" msgid="2978063221383413443">"Du har udført bevægelsen for Gå til startskærmen"</string>
<string name="home_gesture_intro_title" msgid="836590312858441830">"Stryg for at gå til startskærmen"</string>
<string name="home_gesture_intro_subtitle" msgid="2632238748497975326">"Stryg opad fra bunden af skærmen. Denne bevægelse åbner altid startskærmen."</string>
<string name="home_gesture_spoken_intro_subtitle" msgid="1030987707382031750">"Stryg opad med 2 fingre fra bunden af skærmen. Denne bevægelse åbner altid startskærmen."</string>
@@ -76,7 +76,7 @@
<string name="overview_gesture_feedback_home_detected" msgid="663432226180397138">"Prøv at holde fingeren nede på vinduet i længere tid, inden du løfter den"</string>
<string name="overview_gesture_feedback_wrong_swipe_direction" msgid="1191055451018584958">"Stryg lige opad, og hold derefter fingeren stille"</string>
<string name="overview_gesture_feedback_complete_with_follow_up" msgid="3544611727467765026">"Du har lært, hvordan du bruger bevægelser. Du kan aktivere bevægelser i Indstillinger."</string>
- <string name="overview_gesture_feedback_complete_without_follow_up" msgid="2903050864432331629">"Du har fuldført bevægelsen for at skifte mellem apps"</string>
+ <string name="overview_gesture_feedback_complete_without_follow_up" msgid="2903050864432331629">"Du har udført bevægelsen for at skifte mellem apps"</string>
<string name="overview_gesture_intro_title" msgid="2902054412868489378">"Stryg for at skifte app"</string>
<string name="overview_gesture_intro_subtitle" msgid="4968091015637850859">"Skift mellem apps ved at stryge opad fra bunden af skærmen, holde fingeren stille og løfte den."</string>
<string name="overview_gesture_spoken_intro_subtitle" msgid="3853371838260201751">"Skift mellem apps ved at stryge opad fra bunden af skærmen med 2 fingre, holde dem nede og slippe."</string>
diff --git a/quickstep/res/values-ne/strings.xml b/quickstep/res/values-ne/strings.xml
index 49d1664..0f374ba 100644
--- a/quickstep/res/values-ne/strings.xml
+++ b/quickstep/res/values-ne/strings.xml
@@ -52,8 +52,8 @@
<string name="back_gesture_feedback_swipe_too_far_from_edge" msgid="4175100312909721217">"स्क्रिनको सबैभन्दा दायाँ किनारा वा सबैभन्दा बायाँ किनाराबाट स्वाइप गर्नुहोस्"</string>
<string name="back_gesture_feedback_cancelled" msgid="762621530959111290">"स्क्रिनको दायाँ वा बायाँ किनाराबाट मध्य भागसम्म स्वाइप गर्नुहोस् अनि औँला उठाउनुहोस्"</string>
<string name="back_gesture_feedback_complete_with_overview_follow_up" msgid="9176400654037014471">"तपाईंले स्क्रिनको दायाँ किनाराबाट स्वाइप गरेर अघिल्लो स्क्रिनमा फर्कने तरिका सिक्नुभयो। अब एउटा एपबाट अर्को एपमा जाने तरिका सिक्नुहोस्।"</string>
- <string name="back_gesture_feedback_complete_with_follow_up" msgid="8653374779579748392">"तपाईंले \'पछाडि जानुहोस्\' नामक इसारा प्रयोग गर्ने तरिका सिक्नुभयो। अब एउटा एपबाट अर्को एपमा जाने तरिका सिक्नुहोस्।"</string>
- <string name="back_gesture_feedback_complete_without_follow_up" msgid="197189945858268342">"तपाईंले \"पछाडि जानुहोस्\" नामक इसारा प्रयोग गर्ने तरिका सिक्नुभयो"</string>
+ <string name="back_gesture_feedback_complete_with_follow_up" msgid="8653374779579748392">"तपाईंले जेस्चर प्रयोग गरी पछाडि जाने तरिका सिक्नुभएको छ। अब एउटा एपबाट अर्को एपमा जाने तरिका सिक्नुहोस्।"</string>
+ <string name="back_gesture_feedback_complete_without_follow_up" msgid="197189945858268342">"तपाईंले जेस्चर प्रयोग गरी पछाडि जाने तरिका सिक्नुभएको छ"</string>
<string name="back_gesture_feedback_swipe_in_nav_bar" msgid="9157480023651452969">"स्क्रिनको फेदको धेरै नजिकसम्म स्वाइप नगर्नुहोस्"</string>
<string name="back_gesture_tutorial_confirm_subtitle" msgid="5181305411668713250">"\'पछाडि\' नामक इसाराको संवेदनशीलता बदल्न सेटिङमा जानुहोस्"</string>
<string name="back_gesture_intro_title" msgid="19551256430224428">"पछाडि जान स्वाइप गर्नुहोस्"</string>
@@ -64,7 +64,7 @@
<string name="home_gesture_feedback_swipe_too_far_from_edge" msgid="4816365433160895458">"स्क्रिनको फेदबाट माथितिर स्वाइप गर्नुहोस्"</string>
<string name="home_gesture_feedback_overview_detected" msgid="5177627157303895077">"औँला उठाउनुअघि नरोकिनुहोस्"</string>
<string name="home_gesture_feedback_wrong_swipe_direction" msgid="8328465201424027148">"सीधै माथितिर स्वाइप गर्नुहोस्"</string>
- <string name="home_gesture_feedback_complete_with_follow_up" msgid="8766981412895888417">"तपाईंले \"होम स्क्रिनमा जानुहोस्\" नामक इसारा प्रयोग गर्ने तरिका सिक्नुभयो। अब पछाडि जाने तरिका सिक्नुहोस्।"</string>
+ <string name="home_gesture_feedback_complete_with_follow_up" msgid="8766981412895888417">"तपाईंले जेस्चर प्रयोग गरी होम स्क्रिनमा जाने तरिका सिक्नुभएको छ। अब पछाडि जाने तरिका सिक्नुहोस्।"</string>
<string name="home_gesture_feedback_complete_without_follow_up" msgid="2978063221383413443">"तपाईंले \"होम स्क्रिनमा जानुहोस्\" नामक इसारा प्रयोग गर्ने तरिका सिक्नुभयो"</string>
<string name="home_gesture_intro_title" msgid="836590312858441830">"होम स्क्रिनमा जान स्वाइप गर्नुहोस्"</string>
<string name="home_gesture_intro_subtitle" msgid="2632238748497975326">"स्क्रिनको फेदबाट माथितिर स्वाइप गर्नुहोस्। यो इसारा प्रयोग गर्दा सधैँ होम स्क्रिन खुल्छ।"</string>
diff --git a/quickstep/res/values-night/colors.xml b/quickstep/res/values-night/colors.xml
index 98e4871..a1e9c70 100644
--- a/quickstep/res/values-night/colors.xml
+++ b/quickstep/res/values-night/colors.xml
@@ -26,6 +26,4 @@
<!-- Turn on work apps button -->
<color name="work_turn_on_stroke">?attr/materialColorPrimary</color>
- <color name="work_fab_bg_color">?attr/materialColorPrimaryFixedDim</color>
- <color name="work_fab_icon_color">?attr/materialColorOnPrimaryFixed</color>
</resources>
\ No newline at end of file
diff --git a/quickstep/res/values-th/strings.xml b/quickstep/res/values-th/strings.xml
index 99b53d9..30e73e6 100644
--- a/quickstep/res/values-th/strings.xml
+++ b/quickstep/res/values-th/strings.xml
@@ -52,8 +52,8 @@
<string name="back_gesture_feedback_swipe_too_far_from_edge" msgid="4175100312909721217">"ปัดจากขอบด้านขวาสุดหรือซ้ายสุด"</string>
<string name="back_gesture_feedback_cancelled" msgid="762621530959111290">"ตรวจสอบว่าปัดจากขอบด้านขวาหรือซ้ายไปตรงกลางหน้าจอ แล้วยกนิ้วขึ้น"</string>
<string name="back_gesture_feedback_complete_with_overview_follow_up" msgid="9176400654037014471">"คุณรู้วิธีปัดจากด้านขวาเพื่อย้อนกลับแล้ว ต่อไปดูวิธีสลับแอป"</string>
- <string name="back_gesture_feedback_complete_with_follow_up" msgid="8653374779579748392">"คุณทำท่าทางสัมผัสเพื่อย้อนกลับเสร็จแล้ว ต่อไปดูวิธีสลับแอป"</string>
- <string name="back_gesture_feedback_complete_without_follow_up" msgid="197189945858268342">"คุณทำท่าทางสัมผัสเพื่อย้อนกลับเสร็จแล้ว"</string>
+ <string name="back_gesture_feedback_complete_with_follow_up" msgid="8653374779579748392">"คุณทำท่าทางสัมผัสเพื่อย้อนกลับสำเร็จแล้ว ต่อไปดูวิธีสลับแอป"</string>
+ <string name="back_gesture_feedback_complete_without_follow_up" msgid="197189945858268342">"คุณทำท่าทางสัมผัสเพื่อย้อนกลับสำเร็จแล้ว"</string>
<string name="back_gesture_feedback_swipe_in_nav_bar" msgid="9157480023651452969">"ไม่ปัดใกล้กับด้านล่างของหน้าจอมากเกินไป"</string>
<string name="back_gesture_tutorial_confirm_subtitle" msgid="5181305411668713250">"เปลี่ยนความไวของท่าทางสัมผัสเพื่อย้อนกลับได้ที่การตั้งค่า"</string>
<string name="back_gesture_intro_title" msgid="19551256430224428">"ปัดเพื่อย้อนกลับ"</string>
@@ -64,8 +64,8 @@
<string name="home_gesture_feedback_swipe_too_far_from_edge" msgid="4816365433160895458">"ปัดขึ้นจากขอบด้านล่างของหน้าจอ"</string>
<string name="home_gesture_feedback_overview_detected" msgid="5177627157303895077">"ไม่ต้องหยุดชั่วคราวก่อนยกนิ้วขึ้น"</string>
<string name="home_gesture_feedback_wrong_swipe_direction" msgid="8328465201424027148">"ปัดขึ้นในแนวตรง"</string>
- <string name="home_gesture_feedback_complete_with_follow_up" msgid="8766981412895888417">"คุณทำท่าทางสัมผัสเพื่อไปที่หน้าแรกเสร็จแล้ว ต่อไปดูวิธีย้อนกลับ"</string>
- <string name="home_gesture_feedback_complete_without_follow_up" msgid="2978063221383413443">"คุณทำท่าทางสัมผัสเพื่อไปที่หน้าแรกเสร็จแล้ว"</string>
+ <string name="home_gesture_feedback_complete_with_follow_up" msgid="8766981412895888417">"คุณทำท่าทางสัมผัสเพื่อไปที่หน้าแรกสำเร็จแล้ว ต่อไปดูวิธีย้อนกลับ"</string>
+ <string name="home_gesture_feedback_complete_without_follow_up" msgid="2978063221383413443">"คุณทำท่าทางสัมผัสเพื่อไปที่หน้าแรกสำเร็จแล้ว"</string>
<string name="home_gesture_intro_title" msgid="836590312858441830">"ปัดเพื่อไปที่หน้าแรก"</string>
<string name="home_gesture_intro_subtitle" msgid="2632238748497975326">"ปัดขึ้นจากด้านล่างของหน้าจอ ท่าทางสัมผัสนี้จะนำคุณไปที่หน้าจอหลักเสมอ"</string>
<string name="home_gesture_spoken_intro_subtitle" msgid="1030987707382031750">"ใช้ 2 นิ้วปัดขึ้นจากด้านล่างของหน้าจอ ท่าทางสัมผัสนี้จะนำคุณไปที่หน้าจอหลักเสมอ"</string>
@@ -76,7 +76,7 @@
<string name="overview_gesture_feedback_home_detected" msgid="663432226180397138">"ลองแตะหน้าต่างค้างไว้นานขึ้นก่อนปล่อยนิ้ว"</string>
<string name="overview_gesture_feedback_wrong_swipe_direction" msgid="1191055451018584958">"ปัดขึ้นในแนวตรง แล้วหยุดชั่วคราว"</string>
<string name="overview_gesture_feedback_complete_with_follow_up" msgid="3544611727467765026">"คุณรู้วิธีใช้ท่าทางสัมผัสแล้ว หากต้องการปิดท่าทางสัมผัส ให้ไปที่การตั้งค่า"</string>
- <string name="overview_gesture_feedback_complete_without_follow_up" msgid="2903050864432331629">"คุณทำท่าทางสัมผัสเพื่อสลับแอปเสร็จแล้ว"</string>
+ <string name="overview_gesture_feedback_complete_without_follow_up" msgid="2903050864432331629">"คุณทำท่าทางสัมผัสเพื่อสลับแอปสำเร็จแล้ว"</string>
<string name="overview_gesture_intro_title" msgid="2902054412868489378">"ปัดเพื่อสลับแอป"</string>
<string name="overview_gesture_intro_subtitle" msgid="4968091015637850859">"หากต้องการสลับระหว่างแอปต่างๆ ให้ปัดขึ้นจากด้านล่างของหน้าจอ ค้างไว้ แล้วปล่อย"</string>
<string name="overview_gesture_spoken_intro_subtitle" msgid="3853371838260201751">"หากต้องการสลับระหว่างแอป ให้ใช้ 2 นิ้วปัดขึ้นจากด้านล่างของหน้าจอค้างไว้แล้วปล่อย"</string>
diff --git a/quickstep/res/values-vi/strings.xml b/quickstep/res/values-vi/strings.xml
index 3a32551..7eeacde 100644
--- a/quickstep/res/values-vi/strings.xml
+++ b/quickstep/res/values-vi/strings.xml
@@ -53,7 +53,7 @@
<string name="back_gesture_feedback_cancelled" msgid="762621530959111290">"Hãy vuốt từ mép phải hoặc mép trái tới giữa màn hình rồi nhấc ngón tay ra"</string>
<string name="back_gesture_feedback_complete_with_overview_follow_up" msgid="9176400654037014471">"Bạn đã học được cách vuốt từ mép phải để quay lại. Tiếp theo, hãy tìm hiểu cách chuyển đổi ứng dụng."</string>
<string name="back_gesture_feedback_complete_with_follow_up" msgid="8653374779579748392">"Bạn đã thực hiện xong cử chỉ quay lại. Tiếp theo, hãy tìm hiểu cách chuyển đổi ứng dụng."</string>
- <string name="back_gesture_feedback_complete_without_follow_up" msgid="197189945858268342">"Bạn đã thực hiện xong cử chỉ quay lại"</string>
+ <string name="back_gesture_feedback_complete_without_follow_up" msgid="197189945858268342">"Bạn đã hoàn tất cử chỉ quay lại"</string>
<string name="back_gesture_feedback_swipe_in_nav_bar" msgid="9157480023651452969">"Hãy nhớ không được vuốt quá gần phần dưới cùng của màn hình"</string>
<string name="back_gesture_tutorial_confirm_subtitle" msgid="5181305411668713250">"Để thay đổi độ nhạy của cử chỉ quay lại, hãy vào mục Cài đặt"</string>
<string name="back_gesture_intro_title" msgid="19551256430224428">"Vuốt để quay lại"</string>
diff --git a/quickstep/res/values-zh-rCN/strings.xml b/quickstep/res/values-zh-rCN/strings.xml
index eee46bb..dc16036 100644
--- a/quickstep/res/values-zh-rCN/strings.xml
+++ b/quickstep/res/values-zh-rCN/strings.xml
@@ -140,7 +140,7 @@
<string name="always_show_taskbar" msgid="3608801276107751229">"始终显示任务栏"</string>
<string name="change_navigation_mode" msgid="9088393078736808968">"更改导航模式"</string>
<string name="taskbar_divider_a11y_title" msgid="6608690309720242080">"任务栏分隔线"</string>
- <string name="taskbar_overflow_a11y_title" msgid="7960342079198820179">"溢出式任务栏"</string>
+ <string name="taskbar_overflow_a11y_title" msgid="7960342079198820179">"任务栏溢出图标"</string>
<string name="move_drop_target_top_or_left" msgid="2988702185049595807">"移到顶部/左侧"</string>
<string name="move_drop_target_bottom_or_right" msgid="5431393418797620162">"移到底部/右侧"</string>
<string name="quick_switch_overflow" msgid="3679780650881041632">"{count,plural, =1{多个应用}other{多个应用}}"</string>
diff --git a/quickstep/res/values/colors.xml b/quickstep/res/values/colors.xml
index 62873d6..668bce7 100644
--- a/quickstep/res/values/colors.xml
+++ b/quickstep/res/values/colors.xml
@@ -94,6 +94,4 @@
<!-- Turn on work apps button -->
<color name="work_turn_on_stroke">?attr/materialColorPrimary</color>
- <color name="work_fab_bg_color">?attr/materialColorPrimaryFixedDim</color>
- <color name="work_fab_icon_color">?attr/materialColorOnPrimaryFixed</color>
</resources>
\ No newline at end of file
diff --git a/quickstep/res/values/config.xml b/quickstep/res/values/config.xml
index 3ae2b89..f3c9467 100644
--- a/quickstep/res/values/config.xml
+++ b/quickstep/res/values/config.xml
@@ -34,7 +34,6 @@
<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="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>
<string name="contextual_search_invoker_class" translatable="false"></string>
<string name="contextual_search_state_manager_class" translatable="false"></string>
@@ -53,6 +52,11 @@
<integer name="max_depth_blur_radius">23</integer>
+ <!-- If predicted widgets from prediction service are less than this number, additional
+ eligible widgets may be added locally by launcher. When set to 0, no widgets will be added
+ locally. -->
+ <integer name="widget_predictions_min_count">6</integer>
+
<!-- Accessibility actions -->
<item type="id" name="action_move_to_top_or_left" />
<item type="id" name="action_move_to_bottom_or_right" />
diff --git a/quickstep/src/com/android/launcher3/WidgetPickerActivity.java b/quickstep/src/com/android/launcher3/WidgetPickerActivity.java
index 955388d..dc0f899 100644
--- a/quickstep/src/com/android/launcher3/WidgetPickerActivity.java
+++ b/quickstep/src/com/android/launcher3/WidgetPickerActivity.java
@@ -23,6 +23,8 @@
import static com.android.launcher3.util.Executors.MAIN_EXECUTOR;
import static com.android.launcher3.util.Executors.MODEL_EXECUTOR;
+import static java.util.Collections.emptyList;
+
import android.appwidget.AppWidgetManager;
import android.appwidget.AppWidgetProviderInfo;
import android.content.ClipData;
@@ -44,6 +46,7 @@
import com.android.launcher3.model.StringCache;
import com.android.launcher3.model.WidgetItem;
import com.android.launcher3.model.WidgetPredictionsRequester;
+import com.android.launcher3.model.WidgetsFilterDataProvider;
import com.android.launcher3.model.WidgetsModel;
import com.android.launcher3.model.data.ItemInfo;
import com.android.launcher3.model.data.PackageItemInfo;
@@ -52,6 +55,7 @@
import com.android.launcher3.widget.model.WidgetsListBaseEntry;
import com.android.launcher3.widget.picker.WidgetsFullSheet;
import com.android.launcher3.widget.picker.model.WidgetPickerDataProvider;
+import com.android.systemui.animation.back.FlingOnBackAnimationCallback;
import java.util.ArrayList;
import java.util.HashSet;
@@ -112,6 +116,7 @@
private WidgetPredictionsRequester mWidgetPredictionsRequester;
private final WidgetPickerDataProvider mWidgetPickerDataProvider =
new WidgetPickerDataProvider();
+ private WidgetsFilterDataProvider mWidgetsFilterDataProvider;
private int mDesiredWidgetWidth;
private int mDesiredWidgetHeight;
@@ -133,13 +138,13 @@
@Nullable
private WidgetsFullSheet mWidgetSheet;
- private final Predicate<WidgetItem> mWidgetsFilter = widget -> {
+ private final Predicate<WidgetItem> mNoShortcutsFilter = widget -> {
final WidgetAcceptabilityVerdict verdict =
isWidgetAcceptable(widget, /* applySizeFilter=*/ false);
verdict.maybeLogVerdict();
return verdict.isAcceptable;
};
- private final Predicate<WidgetItem> mDefaultWidgetsFilter = widget -> {
+ private final Predicate<WidgetItem> mHostSizeAndNoShortcutsFilter = widget -> {
final WidgetAcceptabilityVerdict verdict =
isWidgetAcceptable(widget, /* applySizeFilter=*/ true);
verdict.maybeLogVerdict();
@@ -157,6 +162,7 @@
InvariantDeviceProfile idp = mApp.getInvariantDeviceProfile();
mDeviceProfile = idp.getDeviceProfile(this);
mModel = new WidgetsModel();
+ mWidgetsFilterDataProvider = WidgetsFilterDataProvider.Companion.newInstance(this);
setContentView(R.layout.widget_picker_activity);
mDragLayer = findViewById(R.id.drag_layer);
@@ -288,13 +294,16 @@
private void refreshAndBindWidgets() {
MODEL_EXECUTOR.execute(() -> {
LauncherAppState app = LauncherAppState.getInstance(this);
+ // Don't have to setup filters - its setup when launcher loads
+ // Just refresh filters with available cached info.
+ mModel.updateWidgetFilters(mWidgetsFilterDataProvider);
mModel.update(app, null);
StringCache stringCache = new StringCache();
stringCache.loadStrings(this);
bindStringCache(stringCache);
- bindWidgets(mModel.getWidgetsByPackageItem());
+ bindWidgets(mModel.getWidgetsByPackageItem(), mModel.getDefaultWidgetsFilter());
// Open sheet once widgets are available, so that it doesn't interrupt the open
// animation.
openWidgetsSheet();
@@ -310,14 +319,23 @@
MAIN_EXECUTOR.execute(() -> mStringCache = stringCache);
}
- private void bindWidgets(Map<PackageItemInfo, List<WidgetItem>> widgets) {
+ private void bindWidgets(Map<PackageItemInfo, List<WidgetItem>> widgets,
+ @Nullable Predicate<WidgetItem> defaultWidgetsFilter) {
WidgetsListBaseEntriesBuilder builder = new WidgetsListBaseEntriesBuilder(
mApp.getContext());
- final List<WidgetsListBaseEntry> allWidgets = builder.build(widgets, mWidgetsFilter);
- final List<WidgetsListBaseEntry> defaultWidgets =
- shouldShowDefaultWidgets() ? builder.build(widgets,
- mDefaultWidgetsFilter) : List.of();
+ final List<WidgetsListBaseEntry> allWidgets = builder.build(widgets, mNoShortcutsFilter);
+
+ // Default list is shown if either defaultWidgetsFilter exists or host has additionally
+ // enforced size filtering.
+ @Nullable Predicate<WidgetItem> defaultListFilter =
+ hasHostSizeFilters() ? mHostSizeAndNoShortcutsFilter : null;
+ if (defaultWidgetsFilter != null) {
+ defaultListFilter = defaultListFilter != null ? defaultListFilter.and(
+ defaultWidgetsFilter) : defaultWidgetsFilter;
+ }
+ final List<WidgetsListBaseEntry> defaultWidgets = defaultListFilter != null ? builder.build(
+ widgets, defaultListFilter) : emptyList();
MAIN_EXECUTOR.execute(
() -> mWidgetPickerDataProvider.setWidgets(allWidgets, defaultWidgets));
@@ -342,6 +360,7 @@
@Override
protected void onDestroy() {
super.onDestroy();
+ MODEL_EXECUTOR.execute(() -> mWidgetsFilterDataProvider.destroy());
if (mWidgetPredictionsRequester != null) {
mWidgetPredictionsRequester.clear();
}
@@ -356,12 +375,12 @@
/**
* Animation callback for different predictive back animation states for the widget picker.
*/
- private class BackAnimationCallback implements OnBackAnimationCallback {
+ private class BackAnimationCallback extends FlingOnBackAnimationCallback {
@Nullable
OnBackAnimationCallback mActiveOnBackAnimationCallback;
@Override
- public void onBackStarted(@NonNull BackEvent backEvent) {
+ public void onBackStartedCompat(@NonNull BackEvent backEvent) {
if (mActiveOnBackAnimationCallback != null) {
mActiveOnBackAnimationCallback.onBackCancelled();
}
@@ -372,7 +391,7 @@
}
@Override
- public void onBackInvoked() {
+ public void onBackInvokedCompat() {
if (mActiveOnBackAnimationCallback == null) {
return;
}
@@ -381,7 +400,7 @@
}
@Override
- public void onBackProgressed(@NonNull BackEvent backEvent) {
+ public void onBackProgressedCompat(@NonNull BackEvent backEvent) {
if (mActiveOnBackAnimationCallback == null) {
return;
}
@@ -389,7 +408,7 @@
}
@Override
- public void onBackCancelled() {
+ public void onBackCancelledCompat() {
if (mActiveOnBackAnimationCallback == null) {
return;
}
@@ -398,7 +417,7 @@
}
}
- private boolean shouldShowDefaultWidgets() {
+ private boolean hasHostSizeFilters() {
// If optional filters such as size filter are present, we display them as default widgets.
return mDesiredWidgetWidth != 0 || mDesiredWidgetHeight != 0;
}
diff --git a/quickstep/src/com/android/launcher3/desktop/DesktopAppLaunchTransition.kt b/quickstep/src/com/android/launcher3/desktop/DesktopAppLaunchTransition.kt
index 6916a1d..e160f82 100644
--- a/quickstep/src/com/android/launcher3/desktop/DesktopAppLaunchTransition.kt
+++ b/quickstep/src/com/android/launcher3/desktop/DesktopAppLaunchTransition.kt
@@ -20,6 +20,7 @@
import android.animation.AnimatorSet
import android.animation.ValueAnimator
import android.content.Context
+import android.graphics.Rect
import android.os.IBinder
import android.view.SurfaceControl.Transaction
import android.view.WindowManager.TRANSIT_OPEN
@@ -31,6 +32,7 @@
import android.window.TransitionInfo.Change
import androidx.core.animation.addListener
import com.android.app.animation.Interpolators
+import com.android.internal.policy.ScreenDecorationsUtils
import com.android.quickstep.RemoteRunnable
import com.android.wm.shell.shared.animation.MinimizeAnimator
import com.android.wm.shell.shared.animation.WindowAnimator
@@ -43,8 +45,19 @@
* ([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() {
+class DesktopAppLaunchTransition(
+ private val context: Context,
+ private val mainExecutor: Executor,
+ private val launchType: AppLaunchType,
+) : RemoteTransitionStub() {
+
+ enum class AppLaunchType(
+ val boundsAnimationParams: WindowAnimator.BoundsAnimationParams,
+ val alphaDurationMs: Long,
+ ) {
+ LAUNCH(launchBoundsAnimationDef, /* alphaDurationMs= */ 200L),
+ UNMINIMIZE(unminimizeBoundsAnimationDef, /* alphaDurationMs= */ 100L),
+ }
override fun startAnimation(
token: IBinder,
@@ -105,18 +118,24 @@
val boundsAnimator =
WindowAnimator.createBoundsAnimator(
context.resources.displayMetrics,
- launchBoundsAnimationDef,
+ launchType.boundsAnimationParams,
change,
transaction,
)
val alphaAnimator =
ValueAnimator.ofFloat(0f, 1f).apply {
- duration = LAUNCH_ANIM_ALPHA_DURATION_MS
+ duration = launchType.alphaDurationMs
interpolator = Interpolators.LINEAR
addUpdateListener { animation ->
transaction.setAlpha(change.leash, animation.animatedValue as Float).apply()
}
}
+ val clipRect = Rect(change.endAbsBounds).apply { offsetTo(0, 0) }
+ transaction.setCrop(change.leash, clipRect)
+ transaction.setCornerRadius(
+ change.leash,
+ ScreenDecorationsUtils.getWindowCornerRadius(context),
+ )
return AnimatorSet().apply {
playTogether(boundsAnimator, alphaAnimator)
addListener(onEnd = { animation -> onAnimFinish(animation) })
@@ -124,13 +143,18 @@
}
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
+ val LAUNCH_CHANGE_MODES = intArrayOf(TRANSIT_OPEN, TRANSIT_TO_FRONT)
private val launchBoundsAnimationDef =
WindowAnimator.BoundsAnimationParams(
+ durationMs = 600,
+ startOffsetYDp = 36f,
+ startScale = 0.95f,
+ interpolator = Interpolators.STANDARD_DECELERATE,
+ )
+
+ private val unminimizeBoundsAnimationDef =
+ WindowAnimator.BoundsAnimationParams(
durationMs = 300,
startOffsetYDp = 12f,
startScale = 0.97f,
diff --git a/quickstep/src/com/android/launcher3/model/WidgetsPredictionUpdateTask.java b/quickstep/src/com/android/launcher3/model/WidgetsPredictionUpdateTask.java
index 0395d32..9d9054e 100644
--- a/quickstep/src/com/android/launcher3/model/WidgetsPredictionUpdateTask.java
+++ b/quickstep/src/com/android/launcher3/model/WidgetsPredictionUpdateTask.java
@@ -16,8 +16,12 @@
package com.android.launcher3.model;
import static com.android.launcher3.Flags.enableCategorizedWidgetSuggestions;
+import static com.android.launcher3.Flags.enableTieredWidgetsByDefaultInPicker;
import static com.android.launcher3.LauncherSettings.Favorites.CONTAINER_WIDGETS_PREDICTION;
+import static java.util.stream.Collectors.groupingBy;
+import static java.util.stream.Collectors.toMap;
+
import android.app.prediction.AppTarget;
import android.content.ComponentName;
import android.content.Context;
@@ -26,6 +30,7 @@
import androidx.annotation.NonNull;
import com.android.launcher3.LauncherModel.ModelUpdateTask;
+import com.android.launcher3.R;
import com.android.launcher3.model.BgDataModel.FixedContainerItems;
import com.android.launcher3.model.QuickstepModelDelegate.PredictorState;
import com.android.launcher3.model.data.ItemInfo;
@@ -34,8 +39,10 @@
import com.android.launcher3.widget.picker.WidgetRecommendationCategoryProvider;
import java.util.ArrayList;
+import java.util.Collections;
import java.util.List;
import java.util.Map;
+import java.util.Random;
import java.util.Set;
import java.util.function.Predicate;
import java.util.stream.Collectors;
@@ -60,33 +67,72 @@
@Override
public void execute(@NonNull ModelTaskController taskController, @NonNull BgDataModel dataModel,
@NonNull AllAppsList apps) {
+ Predicate<WidgetItem> predictedWidgetsFilter = enableTieredWidgetsByDefaultInPicker()
+ ? dataModel.widgetsModel.getPredictedWidgetsFilter() : null;
Set<ComponentKey> widgetsInWorkspace = dataModel.appWidgets.stream().map(
widget -> new ComponentKey(widget.providerName, widget.user)).collect(
Collectors.toSet());
- Predicate<WidgetItem> notOnWorkspace = w -> !widgetsInWorkspace.contains(w);
- Map<ComponentKey, WidgetItem> allWidgets =
- dataModel.widgetsModel.getWidgetsByComponentKey();
+
+ // Widgets (excluding shortcuts & already added widgets) that belong to apps eligible for
+ // being in predictions.
+ Map<ComponentKey, WidgetItem> allEligibleWidgets =
+ dataModel.widgetsModel.getWidgetsByComponentKey()
+ .entrySet()
+ .stream()
+ .filter(entry -> entry.getValue().widgetInfo != null
+ && !widgetsInWorkspace.contains(entry.getValue())
+ && (predictedWidgetsFilter == null
+ || predictedWidgetsFilter.test(entry.getValue()))
+ ).collect(toMap(Map.Entry::getKey, Map.Entry::getValue));
+
+ Context context = taskController.getApp().getContext();
List<WidgetItem> servicePredictedItems = new ArrayList<>();
+ List<String> addedWidgetApps = new ArrayList<>();
for (AppTarget app : mTargets) {
ComponentKey componentKey = new ComponentKey(
new ComponentName(app.getPackageName(), app.getClassName()), app.getUser());
- WidgetItem widget = allWidgets.get(componentKey);
- if (widget == null) {
+ WidgetItem widget = allEligibleWidgets.get(componentKey);
+ if (widget == null) { // widget not eligible.
continue;
}
String className = app.getClassName();
if (!TextUtils.isEmpty(className)) {
- if (notOnWorkspace.test(widget)) {
- servicePredictedItems.add(widget);
- }
+ servicePredictedItems.add(widget);
+ addedWidgetApps.add(componentKey.componentName.getPackageName());
+ }
+ }
+
+ int minPredictionCount = context.getResources().getInteger(
+ R.integer.widget_predictions_min_count);
+ if (enableTieredWidgetsByDefaultInPicker()
+ && servicePredictedItems.size() < minPredictionCount) {
+ // Eligible apps that aren't already part of predictions.
+ Map<String, List<WidgetItem>> eligibleWidgetsByApp =
+ allEligibleWidgets.values().stream()
+ .filter(w -> !addedWidgetApps.contains(
+ w.componentName.getPackageName()))
+ .collect(groupingBy(w -> w.componentName.getPackageName()));
+
+ // Randomize available apps list
+ List<String> appPackages = new ArrayList<>(eligibleWidgetsByApp.keySet());
+ Collections.shuffle(appPackages);
+
+ int widgetsToAdd = minPredictionCount - servicePredictedItems.size();
+ for (String appPackage : appPackages) {
+ if (widgetsToAdd <= 0) break;
+
+ List<WidgetItem> widgetsForApp = eligibleWidgetsByApp.get(appPackage);
+ int index = new Random().nextInt(widgetsForApp.size());
+ // Add a random widget from the app.
+ servicePredictedItems.add(widgetsForApp.get(index));
+ widgetsToAdd--;
}
}
List<ItemInfo> items;
if (enableCategorizedWidgetSuggestions()) {
- Context context = taskController.getApp().getContext();
WidgetRecommendationCategoryProvider categoryProvider =
WidgetRecommendationCategoryProvider.newInstance(context);
items = servicePredictedItems.stream()
diff --git a/quickstep/src/com/android/launcher3/taskbar/FallbackTaskbarUIController.java b/quickstep/src/com/android/launcher3/taskbar/FallbackTaskbarUIController.java
index e3bcb0d..6a908ca 100644
--- a/quickstep/src/com/android/launcher3/taskbar/FallbackTaskbarUIController.java
+++ b/quickstep/src/com/android/launcher3/taskbar/FallbackTaskbarUIController.java
@@ -50,8 +50,12 @@
public void onStateTransitionStart(RecentsState toState) {
animateToRecentsState(toState);
+ RecentsView recentsView = getRecentsView();
+ if (recentsView == null) {
+ return;
+ }
// Handle tapping on live tile.
- getRecentsView().setTaskLaunchListener(toState == RecentsState.DEFAULT
+ recentsView.setTaskLaunchListener(toState == RecentsState.DEFAULT
? (() -> animateToRecentsState(RecentsState.BACKGROUND_APP)) : null);
}
@@ -81,7 +85,10 @@
@Override
protected void onDestroy() {
super.onDestroy();
- getRecentsView().setTaskLaunchListener(null);
+ RecentsView recentsView = getRecentsView();
+ if (recentsView != null) {
+ recentsView.setTaskLaunchListener(null);
+ }
mRecentsContainer.setTaskbarUIController(null);
mRecentsContainer.getStateManager().removeStateListener(mStateListener);
}
@@ -112,7 +119,7 @@
}
@Override
- public RecentsView getRecentsView() {
+ public @Nullable RecentsView getRecentsView() {
return mRecentsContainer.getOverviewPanel();
}
diff --git a/quickstep/src/com/android/launcher3/taskbar/KeyboardQuickSwitchController.java b/quickstep/src/com/android/launcher3/taskbar/KeyboardQuickSwitchController.java
index 711a49a..23a5a27 100644
--- a/quickstep/src/com/android/launcher3/taskbar/KeyboardQuickSwitchController.java
+++ b/quickstep/src/com/android/launcher3/taskbar/KeyboardQuickSwitchController.java
@@ -54,6 +54,8 @@
public static final int MAX_TASKS = 6;
@NonNull private final ControllerCallbacks mControllerCallbacks = new ControllerCallbacks();
+ // Callback used to notify when the KQS view is closed.
+ @Nullable private Runnable mOnClosed;
// Initialized on init
@Nullable private RecentsModel mModel;
@@ -112,8 +114,12 @@
* Opens or closes the view in response to taskbar action. The view shows a filtered list of
* tasks.
* @param taskIdsToExclude A list of tasks to exclude in the opened view.
+ * @param onClosed A callback used to notify when the KQS view is closed.
*/
- void toggleQuickSwitchViewForTaskbar(@NonNull Set<Integer> taskIdsToExclude) {
+ void toggleQuickSwitchViewForTaskbar(@NonNull Set<Integer> taskIdsToExclude,
+ @NonNull Runnable onClosed) {
+ mOnClosed = onClosed;
+
// Close the view if its shown, and was opened from the taskbar.
if (mQuickSwitchViewController != null
&& !mQuickSwitchViewController.isCloseAnimationRunning()
@@ -264,6 +270,10 @@
return;
}
mQuickSwitchViewController.closeQuickSwitchView(animate);
+ if (mOnClosed != null) {
+ mOnClosed.run();
+ mOnClosed = null;
+ }
}
/**
diff --git a/quickstep/src/com/android/launcher3/taskbar/KeyboardQuickSwitchViewController.java b/quickstep/src/com/android/launcher3/taskbar/KeyboardQuickSwitchViewController.java
index 7a63f74..390112e 100644
--- a/quickstep/src/com/android/launcher3/taskbar/KeyboardQuickSwitchViewController.java
+++ b/quickstep/src/com/android/launcher3/taskbar/KeyboardQuickSwitchViewController.java
@@ -36,6 +36,7 @@
import com.android.launcher3.Utilities;
import com.android.launcher3.anim.AnimatorListeners;
import com.android.launcher3.desktop.DesktopAppLaunchTransition;
+import com.android.launcher3.desktop.DesktopAppLaunchTransition.AppLaunchType;
import com.android.launcher3.taskbar.overlay.TaskbarOverlayContext;
import com.android.launcher3.taskbar.overlay.TaskbarOverlayDragLayer;
import com.android.launcher3.util.DisplayController;
@@ -47,7 +48,6 @@
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;
@@ -247,11 +247,13 @@
return -1;
}
RemoteTransition remoteTransition = slideInTransition;
- if (mOnDesktop && task.task1.isMinimized
- && Flags.enableDesktopAppLaunchAlttabTransitions()) {
+ if (mOnDesktop
+ && mControllers.taskbarActivityContext.canUnminimizeDesktopTask(task.task1.key.id)
+ ) {
// This app is being unminimized - use our own transition runner.
remoteTransition = new RemoteTransition(
- new DesktopAppLaunchTransition(context, MAIN_EXECUTOR));
+ new DesktopAppLaunchTransition(
+ context, MAIN_EXECUTOR, AppLaunchType.UNMINIMIZE));
}
mControllers.taskbarActivityContext.handleGroupTaskLaunch(
task,
diff --git a/quickstep/src/com/android/launcher3/taskbar/LauncherTaskbarUIController.java b/quickstep/src/com/android/launcher3/taskbar/LauncherTaskbarUIController.java
index 09dbeb6..b1cb2c6 100644
--- a/quickstep/src/com/android/launcher3/taskbar/LauncherTaskbarUIController.java
+++ b/quickstep/src/com/android/launcher3/taskbar/LauncherTaskbarUIController.java
@@ -372,6 +372,11 @@
* mTaskbarInAppDisplayProgress.value);
mControllers.navbarButtonsViewController
.getOnTaskbarBackgroundNavButtonColorOverride().updateValue(progress);
+
+ if (isBubbleBarEnabled()) {
+ mControllers.bubbleControllers.ifPresent(
+ c -> c.bubbleStashController.setInAppDisplayOverrideProgress(progress));
+ }
}
}
diff --git a/quickstep/src/com/android/launcher3/taskbar/NavbarButtonsViewController.java b/quickstep/src/com/android/launcher3/taskbar/NavbarButtonsViewController.java
index 7d8e93c..fbd1b6e 100644
--- a/quickstep/src/com/android/launcher3/taskbar/NavbarButtonsViewController.java
+++ b/quickstep/src/com/android/launcher3/taskbar/NavbarButtonsViewController.java
@@ -49,6 +49,7 @@
import static com.android.systemui.shared.system.QuickStepContract.SYSUI_STATE_SCREEN_PINNING;
import static com.android.systemui.shared.system.QuickStepContract.SYSUI_STATE_SHORTCUT_HELPER_SHOWING;
import static com.android.systemui.shared.system.QuickStepContract.SYSUI_STATE_VOICE_INTERACTION_WINDOW_SHOWING;
+import static com.android.window.flags.Flags.predictiveBackThreeButtonNav;
import static com.android.wm.shell.Flags.enableBubbleBarInPersistentTaskBar;
import android.animation.Animator;
@@ -71,8 +72,10 @@
import android.graphics.drawable.RotateDrawable;
import android.inputmethodservice.InputMethodService;
import android.os.Handler;
+import android.os.SystemClock;
import android.util.Property;
import android.view.Gravity;
+import android.view.KeyEvent;
import android.view.MotionEvent;
import android.view.View;
import android.view.View.OnAttachStateChangeListener;
@@ -843,12 +846,43 @@
buttonView.setImageResource(drawableId);
buttonView.setContentDescription(parent.getContext().getString(
navButtonController.getButtonContentDescription(buttonType)));
- buttonView.setOnClickListener(view -> navButtonController.onButtonClick(buttonType, view));
- buttonView.setOnLongClickListener(view ->
- navButtonController.onButtonLongClick(buttonType, view));
+ if (predictiveBackThreeButtonNav() && buttonType == BUTTON_BACK) {
+ // set up special touch listener for back button to support predictive back
+ setBackButtonTouchListener(buttonView, navButtonController);
+ } else {
+ buttonView.setOnClickListener(view ->
+ navButtonController.onButtonClick(buttonType, view));
+ buttonView.setOnLongClickListener(view ->
+ navButtonController.onButtonLongClick(buttonType, view));
+ }
return buttonView;
}
+ private void setBackButtonTouchListener(View buttonView,
+ TaskbarNavButtonController navButtonController) {
+ buttonView.setOnTouchListener((v, event) -> {
+ if (event.getAction() == MotionEvent.ACTION_MOVE) return false;
+ long time = SystemClock.uptimeMillis();
+ int action = event.getAction();
+ KeyEvent keyEvent = new KeyEvent(time, time,
+ action == MotionEvent.ACTION_DOWN ? KeyEvent.ACTION_DOWN : KeyEvent.ACTION_UP,
+ KeyEvent.KEYCODE_BACK, 0);
+ if (event.getAction() == MotionEvent.ACTION_CANCEL) {
+ keyEvent.cancel();
+ }
+ navButtonController.executeBack(keyEvent);
+
+ if (action == MotionEvent.ACTION_UP) {
+ buttonView.performClick();
+ }
+ return false;
+ });
+ buttonView.setOnLongClickListener((view) -> {
+ navButtonController.onButtonLongClick(BUTTON_BACK, view);
+ return false;
+ });
+ }
+
private ImageView addButton(ViewGroup parent, @IdRes int id, @LayoutRes int layoutId) {
ImageView buttonView = (ImageView) mContext.getLayoutInflater()
.inflate(layoutId, parent, false);
diff --git a/quickstep/src/com/android/launcher3/taskbar/StashedHandleViewController.java b/quickstep/src/com/android/launcher3/taskbar/StashedHandleViewController.java
index 7273fac..eb47bb0 100644
--- a/quickstep/src/com/android/launcher3/taskbar/StashedHandleViewController.java
+++ b/quickstep/src/com/android/launcher3/taskbar/StashedHandleViewController.java
@@ -192,7 +192,9 @@
public void onDestroy() {
- mRegionSamplingHelper.stopAndDestroy();
+ if (mRegionSamplingHelper != null) {
+ mRegionSamplingHelper.stopAndDestroy();
+ }
mRegionSamplingHelper = null;
}
diff --git a/quickstep/src/com/android/launcher3/taskbar/TaskbarActivityContext.java b/quickstep/src/com/android/launcher3/taskbar/TaskbarActivityContext.java
index e22de06..82acc0c 100644
--- a/quickstep/src/com/android/launcher3/taskbar/TaskbarActivityContext.java
+++ b/quickstep/src/com/android/launcher3/taskbar/TaskbarActivityContext.java
@@ -59,6 +59,7 @@
import android.graphics.PixelFormat;
import android.graphics.Rect;
import android.hardware.display.DisplayManager;
+import android.os.Bundle;
import android.os.IRemoteCallback;
import android.os.Process;
import android.os.Trace;
@@ -72,6 +73,7 @@
import android.view.WindowManager;
import android.widget.FrameLayout;
import android.widget.Toast;
+import android.window.DesktopModeFlags;
import android.window.RemoteTransition;
import androidx.annotation.NonNull;
@@ -89,6 +91,8 @@
import com.android.launcher3.anim.AnimatorPlaybackController;
import com.android.launcher3.apppairs.AppPairIcon;
import com.android.launcher3.config.FeatureFlags;
+import com.android.launcher3.desktop.DesktopAppLaunchTransition;
+import com.android.launcher3.desktop.DesktopAppLaunchTransition.AppLaunchType;
import com.android.launcher3.dot.DotInfo;
import com.android.launcher3.folder.Folder;
import com.android.launcher3.folder.FolderIcon;
@@ -282,6 +286,7 @@
BubbleBarController.onTaskbarRecreated();
if (BubbleBarController.isBubbleBarEnabled()
&& !mDeviceProfile.isPhone
+ && !mDeviceProfile.isVerticalBarLayout()
&& bubbleBarView != null
) {
Optional<BubbleStashedHandleViewController> bubbleHandleController = Optional.empty();
@@ -859,6 +864,33 @@
return makeDefaultActivityOptions(SPLASH_SCREEN_STYLE_UNDEFINED);
}
+ private ActivityOptionsWrapper getActivityLaunchDesktopOptions(ItemInfo info) {
+ if (!DesktopModeFlags.ENABLE_DESKTOP_APP_LAUNCH_TRANSITIONS.isTrue()) {
+ return null;
+ }
+ if (!areDesktopTasksVisible()) {
+ return null;
+ }
+ BubbleTextView.RunningAppState appState =
+ mControllers.taskbarRecentAppsController.getDesktopItemState(info);
+ AppLaunchType launchType = null;
+ switch (appState) {
+ case RUNNING:
+ return null;
+ case MINIMIZED:
+ launchType = AppLaunchType.UNMINIMIZE;
+ break;
+ case NOT_RUNNING:
+ launchType = AppLaunchType.LAUNCH;
+ break;
+ }
+ ActivityOptions options = ActivityOptions.makeRemoteTransition(
+ new RemoteTransition(
+ new DesktopAppLaunchTransition(
+ /* context= */ this, getMainExecutor(), launchType)));
+ return new ActivityOptionsWrapper(options, new RunnableList());
+ }
+
/**
* Sets a new data-source for this taskbar instance
*/
@@ -1219,10 +1251,10 @@
mControllers.keyboardQuickSwitchController.closeQuickSwitchView(false);
if (tag instanceof GroupTask groupTask) {
- handleGroupTaskLaunch(
- groupTask,
- /* remoteTransition= */ null,
- areDesktopTasksVisible());
+ RemoteTransition remoteTransition =
+ (areDesktopTasksVisible() && canUnminimizeDesktopTask(groupTask.task1.key.id))
+ ? createUnminimizeRemoteTransition() : null;
+ handleGroupTaskLaunch(groupTask, remoteTransition, areDesktopTasksVisible());
mControllers.taskbarStashController.updateAndAnimateTransientTaskbar(true);
} else if (tag instanceof FolderInfo) {
// Tapping an expandable folder icon on Taskbar
@@ -1240,9 +1272,11 @@
mControllers.taskbarStashController.updateAndAnimateTransientTaskbar(true);
}
} else if (tag instanceof TaskItemInfo info) {
+ RemoteTransition remoteTransition = canUnminimizeDesktopTask(info.getTaskId())
+ ? createUnminimizeRemoteTransition() : null;
UI_HELPER_EXECUTOR.execute(() ->
SystemUiProxy.INSTANCE.get(this).showDesktopApp(
- info.getTaskId(), /* remoteTransition= */ null));
+ info.getTaskId(), remoteTransition));
mControllers.taskbarStashController.updateAndAnimateTransientTaskbar(
/* stash= */ true);
} else if (tag instanceof WorkspaceItemInfo) {
@@ -1361,8 +1395,7 @@
return;
}
if (onDesktop) {
- boolean useRemoteTransition = task.task1.isMinimized
- && com.android.window.flags.Flags.enableDesktopAppLaunchAlttabTransitions();
+ boolean useRemoteTransition = canUnminimizeDesktopTask(task.task1.key.id);
UI_HELPER_EXECUTOR.execute(() -> {
if (onStartCallback != null) {
onStartCallback.run();
@@ -1389,6 +1422,20 @@
mControllers.uiController.launchSplitTasks(task, remoteTransition);
}
+ /** Returns whether the given task is minimized and can be unminimized. */
+ public boolean canUnminimizeDesktopTask(int taskId) {
+ BubbleTextView.RunningAppState runningAppState =
+ mControllers.taskbarRecentAppsController.getRunningAppState(taskId);
+ return runningAppState == BubbleTextView.RunningAppState.MINIMIZED
+ && DesktopModeFlags.ENABLE_DESKTOP_APP_LAUNCH_ALTTAB_TRANSITIONS.isTrue();
+ }
+
+ private RemoteTransition createUnminimizeRemoteTransition() {
+ return new RemoteTransition(
+ new DesktopAppLaunchTransition(
+ this, getMainExecutor(), AppLaunchType.UNMINIMIZE));
+ }
+
/**
* Runs when the user taps a Taskbar icon in TaskbarActivityContext (Overview or inside an app),
* and calls the appropriate method to animate and launch.
@@ -1487,25 +1534,31 @@
.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
try {
TestLogging.recordEvent(TestProtocol.SEQUENCE_MAIN, "start: taskbarAppIcon");
- if (info.user.equals(Process.myUserHandle())) {
- // TODO(b/216683257): Use startActivityForResult for search results that require it.
- if (taskInRecents != null) {
- // Re launch instance from recents
- ActivityOptionsWrapper opts = getActivityLaunchOptions(null, info);
- opts.options.setLaunchDisplayId(
- getDisplay() == null ? DEFAULT_DISPLAY : getDisplay().getDisplayId());
- if (ActivityManagerWrapper.getInstance()
- .startActivityFromRecents(taskInRecents.key, opts.options)) {
- mControllers.uiController.getRecentsView()
- .addSideTaskLaunchCallback(opts.onEndCallback);
- return;
- }
- }
- startActivity(intent);
- } else {
+ if (!info.user.equals(Process.myUserHandle())) {
+ // TODO b/376819104: support Desktop launch animations for apps in managed profiles
getSystemService(LauncherApps.class).startMainActivity(
intent.getComponent(), info.user, intent.getSourceBounds(), null);
+ return;
}
+ // TODO(b/216683257): Use startActivityForResult for search results that require it.
+ if (taskInRecents != null) {
+ // Re launch instance from recents
+ ActivityOptionsWrapper opts = getActivityLaunchOptions(null, info);
+ opts.options.setLaunchDisplayId(
+ getDisplay() == null ? DEFAULT_DISPLAY : getDisplay().getDisplayId());
+ if (ActivityManagerWrapper.getInstance()
+ .startActivityFromRecents(taskInRecents.key, opts.options)) {
+ mControllers.uiController.getRecentsView()
+ .addSideTaskLaunchCallback(opts.onEndCallback);
+ return;
+ }
+ }
+ ActivityOptionsWrapper opts = null;
+ if (areDesktopTasksVisible()) {
+ opts = getActivityLaunchDesktopOptions(info);
+ }
+ Bundle optionsBundle = opts == null ? null : opts.options.toBundle();
+ startActivity(intent, optionsBundle);
} catch (NullPointerException | ActivityNotFoundException | SecurityException e) {
Toast.makeText(this, R.string.activity_not_found, Toast.LENGTH_SHORT)
.show();
diff --git a/quickstep/src/com/android/launcher3/taskbar/TaskbarForceVisibleImmersiveController.java b/quickstep/src/com/android/launcher3/taskbar/TaskbarForceVisibleImmersiveController.java
index 8a86402..b7f5575 100644
--- a/quickstep/src/com/android/launcher3/taskbar/TaskbarForceVisibleImmersiveController.java
+++ b/quickstep/src/com/android/launcher3/taskbar/TaskbarForceVisibleImmersiveController.java
@@ -108,8 +108,10 @@
/** Clean up animations. */
public void onDestroy() {
startIconUndimming();
- mControllers.navbarButtonsViewController.setHomeButtonAccessibilityDelegate(null);
- mControllers.navbarButtonsViewController.setBackButtonAccessibilityDelegate(null);
+ if (mControllers != null) {
+ mControllers.navbarButtonsViewController.setHomeButtonAccessibilityDelegate(null);
+ mControllers.navbarButtonsViewController.setBackButtonAccessibilityDelegate(null);
+ }
}
private void startIconUndimming() {
diff --git a/quickstep/src/com/android/launcher3/taskbar/TaskbarManager.java b/quickstep/src/com/android/launcher3/taskbar/TaskbarManager.java
index ab4b1b6..0807ee9 100644
--- a/quickstep/src/com/android/launcher3/taskbar/TaskbarManager.java
+++ b/quickstep/src/com/android/launcher3/taskbar/TaskbarManager.java
@@ -175,6 +175,9 @@
+ "onActivityDestroyed.");
mActivity.removeEventCallback(EVENT_DESTROYED, this);
}
+ if (mActivity == mRecentsViewContainer) {
+ mRecentsViewContainer = null;
+ }
mActivity = null;
debugWhyTaskbarNotDestroyed("clearActivity");
if (mTaskbarActivityContext != null) {
@@ -560,25 +563,25 @@
}
}
- public void checkNavBarModes() {
+ public void checkNavBarModes(int displayId) {
if (mTaskbarActivityContext != null) {
mTaskbarActivityContext.checkNavBarModes();
}
}
- public void finishBarAnimations() {
+ public void finishBarAnimations(int displayId) {
if (mTaskbarActivityContext != null) {
mTaskbarActivityContext.finishBarAnimations();
}
}
- public void touchAutoDim(boolean reset) {
+ public void touchAutoDim(int displayId, boolean reset) {
if (mTaskbarActivityContext != null) {
mTaskbarActivityContext.touchAutoDim(reset);
}
}
- public void transitionTo(@BarTransitions.TransitionMode int barMode,
+ public void transitionTo(int displayId, @BarTransitions.TransitionMode int barMode,
boolean animate) {
if (mTaskbarActivityContext != null) {
mTaskbarActivityContext.transitionTo(barMode, animate);
@@ -659,6 +662,7 @@
* Called when the manager is no longer needed
*/
public void destroy() {
+ mRecentsViewContainer = null;
debugWhyTaskbarNotDestroyed("TaskbarManager#destroy()");
removeActivityCallbacksAndListeners();
mTaskbarBroadcastReceiver.unregisterReceiverSafely(mContext);
diff --git a/quickstep/src/com/android/launcher3/taskbar/TaskbarModelCallbacks.java b/quickstep/src/com/android/launcher3/taskbar/TaskbarModelCallbacks.java
index bdefea6..c20617d 100644
--- a/quickstep/src/com/android/launcher3/taskbar/TaskbarModelCallbacks.java
+++ b/quickstep/src/com/android/launcher3/taskbar/TaskbarModelCallbacks.java
@@ -42,7 +42,6 @@
import java.util.HashSet;
import java.util.List;
import java.util.Map;
-import java.util.Set;
import java.util.function.Predicate;
/**
@@ -196,26 +195,21 @@
final TaskbarRecentAppsController recentAppsController =
mControllers.taskbarRecentAppsController;
hotseatItemInfos = recentAppsController.updateHotseatItemInfos(hotseatItemInfos);
- Set<Integer> runningTaskIds = recentAppsController.getRunningTaskIds();
- Set<Integer> minimizedTaskIds = recentAppsController.getMinimizedTaskIds();
if (mDeferUpdatesForSUW) {
ItemInfo[] finalHotseatItemInfos = hotseatItemInfos;
mDeferredUpdates = () ->
commitHotseatItemUpdates(finalHotseatItemInfos,
- recentAppsController.getShownTasks(), runningTaskIds,
- minimizedTaskIds);
+ recentAppsController.getShownTasks());
} else {
- commitHotseatItemUpdates(hotseatItemInfos,
- recentAppsController.getShownTasks(), runningTaskIds, minimizedTaskIds);
+ commitHotseatItemUpdates(hotseatItemInfos, recentAppsController.getShownTasks());
}
}
- private void commitHotseatItemUpdates(ItemInfo[] hotseatItemInfos, List<GroupTask> recentTasks,
- Set<Integer> runningTaskIds, Set<Integer> minimizedTaskIds) {
+ private void commitHotseatItemUpdates(
+ ItemInfo[] hotseatItemInfos, List<GroupTask> recentTasks) {
mContainer.updateHotseatItems(hotseatItemInfos, recentTasks);
- mControllers.taskbarViewController.updateIconViewsRunningStates(
- runningTaskIds, minimizedTaskIds);
+ mControllers.taskbarViewController.updateIconViewsRunningStates();
}
/**
diff --git a/quickstep/src/com/android/launcher3/taskbar/TaskbarNavButtonController.java b/quickstep/src/com/android/launcher3/taskbar/TaskbarNavButtonController.java
index 8947914..0f9ede9 100644
--- a/quickstep/src/com/android/launcher3/taskbar/TaskbarNavButtonController.java
+++ b/quickstep/src/com/android/launcher3/taskbar/TaskbarNavButtonController.java
@@ -16,6 +16,8 @@
package com.android.launcher3.taskbar;
+import static android.view.MotionEvent.ACTION_UP;
+
import static com.android.internal.app.AssistUtils.INVOCATION_TYPE_HOME_BUTTON_LONG_PRESS;
import static com.android.internal.app.AssistUtils.INVOCATION_TYPE_KEY;
import static com.android.launcher3.logging.StatsLogManager.LauncherEvent.LAUNCHER_TASKBAR_A11Y_BUTTON_LONGPRESS;
@@ -31,12 +33,14 @@
import static com.android.systemui.shared.system.ActivityManagerWrapper.CLOSE_SYSTEM_WINDOWS_REASON_HOME_KEY;
import static com.android.systemui.shared.system.ActivityManagerWrapper.CLOSE_SYSTEM_WINDOWS_REASON_RECENTS;
import static com.android.systemui.shared.system.QuickStepContract.SYSUI_STATE_SCREEN_PINNING;
+import static com.android.window.flags.Flags.predictiveBackThreeButtonNav;
import android.content.Context;
import android.os.Bundle;
import android.os.Handler;
import android.util.Log;
import android.view.HapticFeedbackConstants;
+import android.view.KeyEvent;
import android.view.View;
import android.view.inputmethod.Flags;
@@ -141,10 +145,7 @@
view.performHapticFeedback(HapticFeedbackConstants.VIRTUAL_KEY);
switch (buttonType) {
case BUTTON_BACK:
- logEvent(LAUNCHER_TASKBAR_BACK_BUTTON_TAP);
- mContextualEduStatsManager.updateEduStats(/* isTrackpadGesture= */ false,
- GestureType.BACK);
- executeBack();
+ executeBack(/* keyEvent */ null);
break;
case BUTTON_HOME:
logEvent(LAUNCHER_TASKBAR_HOME_BUTTON_TAP);
@@ -182,7 +183,9 @@
// Provide the same haptic feedback that the system offers for long press.
// The haptic feedback from long pressing on the home button is handled by circle to search.
- if (buttonType != BUTTON_HOME) {
+ // There are no haptics for long pressing the back button if predictive back is enabled
+ if (buttonType != BUTTON_HOME
+ && (!predictiveBackThreeButtonNav() || buttonType != BUTTON_BACK)) {
view.performHapticFeedback(HapticFeedbackConstants.LONG_PRESS);
}
switch (buttonType) {
@@ -320,8 +323,13 @@
mCallbacks.onToggleOverview();
}
- private void executeBack() {
- mSystemUiProxy.onBackPressed();
+ void executeBack(@Nullable KeyEvent keyEvent) {
+ if (keyEvent == null || (keyEvent.getAction() == ACTION_UP && !keyEvent.isCanceled())) {
+ logEvent(LAUNCHER_TASKBAR_BACK_BUTTON_TAP);
+ mContextualEduStatsManager.updateEduStats(/* isTrackpadGesture= */ false,
+ GestureType.BACK);
+ }
+ mSystemUiProxy.onBackEvent(keyEvent);
}
private void onImeSwitcherPress() {
diff --git a/quickstep/src/com/android/launcher3/taskbar/TaskbarOverflowView.java b/quickstep/src/com/android/launcher3/taskbar/TaskbarOverflowView.java
index fad5ca3..126e9bb 100644
--- a/quickstep/src/com/android/launcher3/taskbar/TaskbarOverflowView.java
+++ b/quickstep/src/com/android/launcher3/taskbar/TaskbarOverflowView.java
@@ -25,10 +25,13 @@
import android.view.ViewGroup;
import android.widget.FrameLayout;
+import androidx.annotation.NonNull;
+
import com.android.launcher3.R;
import com.android.launcher3.Reorderable;
import com.android.launcher3.Utilities;
import com.android.launcher3.util.MultiTranslateDelegate;
+import com.android.launcher3.util.Themes;
import com.android.systemui.shared.recents.model.Task;
import java.util.ArrayList;
@@ -42,12 +45,22 @@
* each other in counter clockwise manner (icons of tasks partially overlapping with each other).
*/
public class TaskbarOverflowView extends FrameLayout implements Reorderable {
+ private static final int MAX_ITEMS_IN_PREVIEW = 4;
+
+ private boolean mIsRtlLayout;
private final List<Task> mItems = new ArrayList<Task>();
private int mIconSize;
private int mPadding;
private Paint mItemBackgroundPaint;
private final MultiTranslateDelegate mTranslateDelegate = new MultiTranslateDelegate(this);
private float mScaleForReorderBounce = 1f;
+ private int mItemBackgroundColor;
+ private int mLeaveBehindColor;
+ private float mItemPreviewStrokeWidth;
+
+ // Active means the overflow icon has been pressed, which replaces the app icons with the
+ // leave-behind circle and shows the KQS UI.
+ private boolean mIsActive = false;
public TaskbarOverflowView(Context context, AttributeSet attrs) {
super(context, attrs);
@@ -78,22 +91,32 @@
}
private void init() {
+ mIsRtlLayout = Utilities.isRtl(getResources());
mItemBackgroundPaint = new Paint(Paint.ANTI_ALIAS_FLAG);
- mItemBackgroundPaint.setColor(getContext().getColor(R.color.taskbar_background));
+ mItemBackgroundColor = getContext().getColor(R.color.taskbar_background);
+ mLeaveBehindColor = Themes.getAttrColor(getContext(), android.R.attr.textColorTertiary);
+ mItemPreviewStrokeWidth = getResources().getDimension(
+ R.dimen.taskbar_overflow_button_preview_stroke);
setWillNotDraw(false);
}
@Override
- protected void onDraw(Canvas canvas) {
+ protected void onDraw(@NonNull Canvas canvas) {
super.onDraw(canvas);
- boolean isRtlLayout = Utilities.isRtl(getResources());
- float radius = mIconSize / 2.0f - mPadding;
- float itemPreviewStrokeWidth =
- getResources().getDimension(R.dimen.taskbar_overflow_button_preview_stroke);
+ if (mIsActive) {
+ drawLeaveBehindCircle(canvas);
+ } else {
+ drawAppIcons(canvas);
+ }
+ }
- int itemsToShow = Math.min(mItems.size(), 4);
+ private void drawAppIcons(@NonNull Canvas canvas) {
+ mItemBackgroundPaint.setColor(mItemBackgroundColor);
+ float radius = mIconSize / 2f - mPadding;
+
+ int itemsToShow = Math.min(mItems.size(), MAX_ITEMS_IN_PREVIEW);
for (int i = itemsToShow - 1; i >= 0; --i) {
Drawable icon = mItems.get(mItems.size() - i - 1).icon;
if (icon == null) {
@@ -103,11 +126,11 @@
// Set the item icon size so two items fit within the overflow icon with stroke width
// included, and overlap of 4 stroke width sizes between base item preview items.
// 2 * strokeWidth + 2 * itemIconSize - 4 * strokeWidth = iconSize = 2 * radius.
- float itemIconSize = radius + itemPreviewStrokeWidth;
- // Offset item icon from center so item icon stroke edge mateches the parent icon edge.
- float itemCenterOffset = radius - itemIconSize / 2 - itemPreviewStrokeWidth;
+ float itemIconSize = radius + mItemPreviewStrokeWidth;
+ // Offset item icon from center so item icon stroke edge matches the parent icon edge.
+ float itemCenterOffset = radius - itemIconSize / 2 - mItemPreviewStrokeWidth;
- float itemCenterX = getItemXOffset(itemCenterOffset, isRtlLayout, i, itemsToShow);
+ float itemCenterX = getItemXOffset(itemCenterOffset, mIsRtlLayout, i, itemsToShow);
float itemCenterY = getItemYOffset(itemCenterOffset, i, itemsToShow);
Drawable iconCopy = icon.getConstantState().newDrawable().mutate();
@@ -119,12 +142,19 @@
mPadding + itemCenterX + radius - itemIconRadius,
mPadding + itemCenterY + radius - itemIconRadius);
canvas.drawCircle(itemIconRadius, itemIconRadius,
- itemIconRadius + itemPreviewStrokeWidth, mItemBackgroundPaint);
+ itemIconRadius + mItemPreviewStrokeWidth, mItemBackgroundPaint);
iconCopy.draw(canvas);
canvas.restore();
}
}
+ private void drawLeaveBehindCircle(@NonNull Canvas canvas) {
+ mItemBackgroundPaint.setColor(mLeaveBehindColor);
+
+ final var xyCenter = mIconSize / 2f;
+ canvas.drawCircle(xyCenter, xyCenter, mIconSize / 4f, mItemBackgroundPaint);
+ }
+
/**
* Clears the list of tasks tracked by the view.
*/
@@ -153,7 +183,7 @@
for (int i = 0; i < mItems.size(); ++i) {
if (mItems.get(i).key.id == task.key.id) {
mItems.set(i, task);
- if (i >= mItems.size() - 4) {
+ if (i >= mItems.size() - MAX_ITEMS_IN_PREVIEW) {
invalidate();
}
break;
@@ -161,6 +191,24 @@
}
}
+ /**
+ * Returns the view's state (whether it shows a set of app icons or a leave-behind circle).
+ */
+ public boolean getIsActive() {
+ return mIsActive;
+ }
+
+ /**
+ * Updates the view's state to draw either a set of app icons or a leave-behind circle.
+ * @param isActive The next state of the view.
+ */
+ public void setIsActive(boolean isActive) {
+ if (mIsActive != isActive) {
+ mIsActive = isActive;
+ invalidate();
+ }
+ }
+
@Override
public MultiTranslateDelegate getTranslateDelegate() {
return mTranslateDelegate;
diff --git a/quickstep/src/com/android/launcher3/taskbar/TaskbarRecentAppsController.kt b/quickstep/src/com/android/launcher3/taskbar/TaskbarRecentAppsController.kt
index 3e8b615..3d57de4 100644
--- a/quickstep/src/com/android/launcher3/taskbar/TaskbarRecentAppsController.kt
+++ b/quickstep/src/com/android/launcher3/taskbar/TaskbarRecentAppsController.kt
@@ -18,6 +18,7 @@
import android.content.Context
import android.window.DesktopModeFlags
import androidx.annotation.VisibleForTesting
+import com.android.launcher3.BubbleTextView.RunningAppState
import com.android.launcher3.Flags.enableRecentsInTaskbar
import com.android.launcher3.model.data.ItemInfo
import com.android.launcher3.model.data.TaskItemInfo
@@ -72,6 +73,43 @@
var shownTasks: List<GroupTask> = emptyList()
private set
+ /**
+ * Returns the state of the most active Desktop task represented by the given [ItemInfo].
+ *
+ * If there are several tasks represented by the same [ItemInfo] we return the most active one,
+ * i.e. we return [DesktopAppState.RUNNING] over [DesktopAppState.MINIMIZED], and
+ * [DesktopAppState.MINIMIZED] over [DesktopAppState.NOT_RUNNING].
+ */
+ fun getDesktopItemState(itemInfo: ItemInfo?): RunningAppState {
+ val packageName = itemInfo?.getTargetPackage() ?: return RunningAppState.NOT_RUNNING
+ return getDesktopAppState(packageName, itemInfo.user.identifier)
+ }
+
+ private fun getDesktopAppState(packageName: String, userId: Int): RunningAppState {
+ val tasks = desktopTask?.tasks ?: return RunningAppState.NOT_RUNNING
+ val appTasks =
+ tasks.filter { task ->
+ packageName == task.key.packageName && task.key.userId == userId
+ }
+ if (appTasks.find { getRunningAppState(it.key.id) == RunningAppState.RUNNING } != null) {
+ return RunningAppState.RUNNING
+ }
+ if (appTasks.find { getRunningAppState(it.key.id) == RunningAppState.MINIMIZED } != null) {
+ return RunningAppState.MINIMIZED
+ }
+ return RunningAppState.NOT_RUNNING
+ }
+
+ /** Get the [RunningAppState] for the given task. */
+ fun getRunningAppState(taskId: Int): RunningAppState {
+ return when (taskId) {
+ in minimizedTaskIds -> RunningAppState.MINIMIZED
+ in runningTaskIds -> RunningAppState.RUNNING
+ else -> RunningAppState.NOT_RUNNING
+ }
+ }
+
+ @VisibleForTesting
val runningTaskIds: Set<Int>
/**
* Returns the task IDs of apps that should be indicated as "running" to the user.
@@ -88,6 +126,7 @@
return tasks.map { task -> task.key.id }.toSet()
}
+ @VisibleForTesting
val minimizedTaskIds: Set<Int>
/**
* Returns the task IDs for the tasks that should be indicated as "minimized" to the user.
diff --git a/quickstep/src/com/android/launcher3/taskbar/TaskbarScrimViewController.java b/quickstep/src/com/android/launcher3/taskbar/TaskbarScrimViewController.java
index bf086b4..4a7e4f0 100644
--- a/quickstep/src/com/android/launcher3/taskbar/TaskbarScrimViewController.java
+++ b/quickstep/src/com/android/launcher3/taskbar/TaskbarScrimViewController.java
@@ -155,7 +155,7 @@
}
private void onClick() {
- SystemUiProxy.INSTANCE.get(mActivity).onBackPressed();
+ SystemUiProxy.INSTANCE.get(mActivity).onBackEvent(null);
}
@Override
diff --git a/quickstep/src/com/android/launcher3/taskbar/TaskbarViewCallbacks.java b/quickstep/src/com/android/launcher3/taskbar/TaskbarViewCallbacks.java
index 5d769d2..834f92e 100644
--- a/quickstep/src/com/android/launcher3/taskbar/TaskbarViewCallbacks.java
+++ b/quickstep/src/com/android/launcher3/taskbar/TaskbarViewCallbacks.java
@@ -148,8 +148,7 @@
return new View.OnClickListener() {
@Override
public void onClick(View v) {
- mControllers.keyboardQuickSwitchController.toggleQuickSwitchViewForTaskbar(
- mControllers.taskbarViewController.getTaskIdsForPinnedApps());
+ toggleKeyboardQuickSwitchView();
}
};
}
@@ -159,13 +158,28 @@
return new View.OnLongClickListener() {
@Override
public boolean onLongClick(View v) {
- mControllers.keyboardQuickSwitchController.toggleQuickSwitchViewForTaskbar(
- mControllers.taskbarViewController.getTaskIdsForPinnedApps());
+ toggleKeyboardQuickSwitchView();
return true;
}
};
}
+ private void toggleKeyboardQuickSwitchView() {
+ if (mTaskbarView.getTaskbarOverflowView() != null) {
+ mTaskbarView.getTaskbarOverflowView().setIsActive(
+ !mTaskbarView.getTaskbarOverflowView().getIsActive());
+ }
+ mControllers.keyboardQuickSwitchController.toggleQuickSwitchViewForTaskbar(
+ mControllers.taskbarViewController.getTaskIdsForPinnedApps(),
+ this::onKeyboardQuickSwitchViewClosed);
+ }
+
+ private void onKeyboardQuickSwitchViewClosed() {
+ if (mTaskbarView.getTaskbarOverflowView() != null) {
+ mTaskbarView.getTaskbarOverflowView().setIsActive(false);
+ }
+ }
+
private float getDividerCenterX() {
View divider = mTaskbarView.getTaskbarDividerViewContainer();
if (divider == null) {
diff --git a/quickstep/src/com/android/launcher3/taskbar/TaskbarViewController.java b/quickstep/src/com/android/launcher3/taskbar/TaskbarViewController.java
index 87e19be..494c472 100644
--- a/quickstep/src/com/android/launcher3/taskbar/TaskbarViewController.java
+++ b/quickstep/src/com/android/launcher3/taskbar/TaskbarViewController.java
@@ -623,12 +623,10 @@
* Updates which icons are marked as running or minimized given the Sets of currently running
* and minimized tasks.
*/
- public void updateIconViewsRunningStates(Set<Integer> runningTaskIds,
- Set<Integer> minimizedTaskIds) {
+ public void updateIconViewsRunningStates() {
for (View iconView : getIconViews()) {
if (iconView instanceof BubbleTextView btv) {
- btv.updateRunningState(
- getRunningAppState(btv, runningTaskIds, minimizedTaskIds));
+ btv.updateRunningState(getRunningAppState(btv));
}
}
}
@@ -651,26 +649,15 @@
return pinnedAppsWithTasks;
}
- private BubbleTextView.RunningAppState getRunningAppState(
- BubbleTextView btv,
- Set<Integer> runningTaskIds,
- Set<Integer> minimizedTaskIds) {
+ private BubbleTextView.RunningAppState getRunningAppState(BubbleTextView btv) {
Object tag = btv.getTag();
if (tag instanceof TaskItemInfo itemInfo) {
- if (minimizedTaskIds.contains(itemInfo.getTaskId())) {
- return BubbleTextView.RunningAppState.MINIMIZED;
- }
- if (runningTaskIds.contains(itemInfo.getTaskId())) {
- return BubbleTextView.RunningAppState.RUNNING;
- }
+ return mControllers.taskbarRecentAppsController.getRunningAppState(
+ itemInfo.getTaskId());
}
if (tag instanceof GroupTask groupTask && !groupTask.hasMultipleTasks()) {
- if (minimizedTaskIds.contains(groupTask.task1.key.id)) {
- return BubbleTextView.RunningAppState.MINIMIZED;
- }
- if (runningTaskIds.contains(groupTask.task1.key.id)) {
- return BubbleTextView.RunningAppState.RUNNING;
- }
+ return mControllers.taskbarRecentAppsController.getRunningAppState(
+ groupTask.task1.key.id);
}
return BubbleTextView.RunningAppState.NOT_RUNNING;
}
diff --git a/quickstep/src/com/android/launcher3/taskbar/bubbles/BubbleBarController.java b/quickstep/src/com/android/launcher3/taskbar/bubbles/BubbleBarController.java
index 30e4e47..e0814d3 100644
--- a/quickstep/src/com/android/launcher3/taskbar/bubbles/BubbleBarController.java
+++ b/quickstep/src/com/android/launcher3/taskbar/bubbles/BubbleBarController.java
@@ -297,9 +297,7 @@
Log.e(TAG, "Could not instantiate BubbleBarBubble for " + bubbleInfos.get(i));
continue;
}
- addBubbleInternally(bubble, /* showAppBadge = */
- mBubbleBarViewController.isExpanded() || i == 0,
- /* isExpanding = */ false, /* suppressAnimation = */ true);
+ addBubbleInternally(bubble, /* isExpanding= */ false, /* suppressAnimation= */ true);
}
}
@@ -390,8 +388,7 @@
for (int i = update.currentBubbles.size() - 1; i >= 0; i--) {
BubbleBarBubble bubble = update.currentBubbles.get(i);
if (bubble != null) {
- addBubbleInternally(bubble, /* showAppBadge = */ !isCollapsed || i == 0,
- isExpanding, suppressAnimation);
+ addBubbleInternally(bubble, isExpanding, suppressAnimation);
if (isCollapsed) {
// If we're collapsed, the most recently added bubble will be selected.
bubbleToSelect = bubble;
@@ -420,8 +417,13 @@
// Updates mean the dot state may have changed; any other changes were updated in
// the populateBubble step.
BubbleBarBubble bb = mBubbles.get(update.updatedBubble.getKey());
- mBubbleBarViewController.animateBubbleNotification(
- bb, /* isExpanding= */ false, /* isUpdate= */ true);
+ if (suppressAnimation) {
+ // since we're not animating this update, we should update the dot visibility here.
+ bb.getView().updateDotVisibility(/* animate= */ false);
+ } else {
+ mBubbleBarViewController.animateBubbleNotification(
+ bb, /* isExpanding= */ false, /* isUpdate= */ true);
+ }
}
if (update.bubbleKeysInOrder != null && !update.bubbleKeysInOrder.isEmpty()) {
// Create the new list
@@ -526,9 +528,10 @@
* <p>
* Updates the value locally in Launcher and in WMShell.
*/
- public void updateBubbleBarLocation(BubbleBarLocation location) {
+ public void updateBubbleBarLocation(BubbleBarLocation location,
+ @BubbleBarLocation.UpdateSource int source) {
updateBubbleBarLocationInternal(location);
- mSystemUiProxy.setBubbleBarLocation(location);
+ mSystemUiProxy.setBubbleBarLocation(location, source);
}
private void updateBubbleBarLocationInternal(BubbleBarLocation location) {
@@ -563,10 +566,8 @@
}
}
- private void addBubbleInternally(BubbleBarBubble bubble, boolean showAppBadge,
- boolean isExpanding, boolean suppressAnimation) {
- //TODO(b/360652359): remove setting scale to the app badge once issue is fixed
- bubble.getView().setBadgeScale(showAppBadge ? 1 : 0);
+ private void addBubbleInternally(BubbleBarBubble bubble, boolean isExpanding,
+ boolean suppressAnimation) {
mBubbles.put(bubble.getKey(), bubble);
mBubbleBarViewController.addBubble(bubble, isExpanding, suppressAnimation);
}
diff --git a/quickstep/src/com/android/launcher3/taskbar/bubbles/BubbleBarView.java b/quickstep/src/com/android/launcher3/taskbar/bubbles/BubbleBarView.java
index d91d10a..350f56f 100644
--- a/quickstep/src/com/android/launcher3/taskbar/bubbles/BubbleBarView.java
+++ b/quickstep/src/com/android/launcher3/taskbar/bubbles/BubbleBarView.java
@@ -407,11 +407,13 @@
return true;
}
if (action == R.id.action_move_left) {
- mController.updateBubbleBarLocation(BubbleBarLocation.LEFT);
+ mController.updateBubbleBarLocation(BubbleBarLocation.LEFT,
+ BubbleBarLocation.UpdateSource.A11Y_ACTION_BAR);
return true;
}
if (action == R.id.action_move_right) {
- mController.updateBubbleBarLocation(BubbleBarLocation.RIGHT);
+ mController.updateBubbleBarLocation(BubbleBarLocation.RIGHT,
+ BubbleBarLocation.UpdateSource.A11Y_ACTION_BAR);
return true;
}
return false;
@@ -791,6 +793,7 @@
updateLayoutParams();
updateBubbleAccessibilityStates();
updateContentDescription();
+ updateDotsAndBadgesIfCollapsed();
}
/** Removes the given bubble from the bubble bar. */
@@ -856,7 +859,7 @@
updateBubbleAccessibilityStates();
updateContentDescription();
mDismissedByDragBubbleView = null;
- updateNotificationDotsIfCollapsed();
+ updateDotsAndBadgesIfCollapsed();
}
/**
@@ -886,17 +889,23 @@
return childViews;
}
- private void updateNotificationDotsIfCollapsed() {
+ private void updateDotsAndBadgesIfCollapsed() {
if (isExpanded()) {
return;
}
for (int i = 0; i < getChildCount(); i++) {
BubbleView bubbleView = (BubbleView) getChildAt(i);
- // when we're collapsed, the first bubble should show the dot if it has it. the rest of
- // the bubbles should hide their dots.
- if (i == 0 && bubbleView.hasUnseenContent()) {
- bubbleView.showDotIfNeeded(/* animate= */ true);
+ // when we're collapsed, the first bubble should show the badge and the dot if it has
+ // it. the rest of the bubbles should hide their badges and dots.
+ if (i == 0) {
+ bubbleView.showBadge();
+ if (bubbleView.hasUnseenContent()) {
+ bubbleView.showDotIfNeeded(/* animate= */ true);
+ } else {
+ bubbleView.hideDot();
+ }
} else {
+ bubbleView.hideBadge();
bubbleView.hideDot();
}
}
@@ -1100,7 +1109,7 @@
}
updateBubblesLayoutProperties(mBubbleBarLocation);
updateContentDescription();
- updateNotificationDotsIfCollapsed();
+ updateDotsAndBadgesIfCollapsed();
}
}
@@ -1560,6 +1569,7 @@
void dismissBubbleBar();
/** Requests the controller to update bubble bar location to the given value */
- void updateBubbleBarLocation(BubbleBarLocation location);
+ void updateBubbleBarLocation(BubbleBarLocation location,
+ @BubbleBarLocation.UpdateSource int source);
}
}
diff --git a/quickstep/src/com/android/launcher3/taskbar/bubbles/BubbleBarViewController.java b/quickstep/src/com/android/launcher3/taskbar/bubbles/BubbleBarViewController.java
index 6ab78be..2dddb16 100644
--- a/quickstep/src/com/android/launcher3/taskbar/bubbles/BubbleBarViewController.java
+++ b/quickstep/src/com/android/launcher3/taskbar/bubbles/BubbleBarViewController.java
@@ -217,8 +217,9 @@
}
@Override
- public void updateBubbleBarLocation(BubbleBarLocation location) {
- mBubbleBarController.updateBubbleBarLocation(location);
+ public void updateBubbleBarLocation(BubbleBarLocation location,
+ @BubbleBarLocation.UpdateSource int source) {
+ mBubbleBarController.updateBubbleBarLocation(location, source);
}
});
@@ -242,8 +243,9 @@
}
@Override
- public void updateBubbleBarLocation(BubbleBarLocation location) {
- mBubbleBarController.updateBubbleBarLocation(location);
+ public void updateBubbleBarLocation(BubbleBarLocation location,
+ @BubbleBarLocation.UpdateSource int source) {
+ mBubbleBarController.updateBubbleBarLocation(location, source);
}
};
}
diff --git a/quickstep/src/com/android/launcher3/taskbar/bubbles/BubbleDragController.java b/quickstep/src/com/android/launcher3/taskbar/bubbles/BubbleDragController.java
index 42bd197..fd4cf0e 100644
--- a/quickstep/src/com/android/launcher3/taskbar/bubbles/BubbleDragController.java
+++ b/quickstep/src/com/android/launcher3/taskbar/bubbles/BubbleDragController.java
@@ -161,7 +161,8 @@
@Override
void onDragEnd() {
- mBubbleBarController.updateBubbleBarLocation(mReleasedLocation);
+ mBubbleBarController.updateBubbleBarLocation(mReleasedLocation,
+ BubbleBarLocation.UpdateSource.DRAG_BUBBLE);
mBubbleBarViewController.onBubbleDragEnd();
mBubblePinController.setListener(null);
}
@@ -226,7 +227,8 @@
@Override
void onDragEnd() {
// Make sure to update location as the first thing. Pivot update causes a relayout
- mBubbleBarController.updateBubbleBarLocation(mReleasedLocation);
+ mBubbleBarController.updateBubbleBarLocation(mReleasedLocation,
+ BubbleBarLocation.UpdateSource.DRAG_BAR);
bubbleBarView.setIsDragging(false);
// Restoring the initial pivot for the bubble bar view
bubbleBarView.setRelativePivot(initialRelativePivot.x, initialRelativePivot.y);
diff --git a/quickstep/src/com/android/launcher3/taskbar/bubbles/BubbleView.java b/quickstep/src/com/android/launcher3/taskbar/bubbles/BubbleView.java
index 114edf4..c74fa9b 100644
--- a/quickstep/src/com/android/launcher3/taskbar/bubbles/BubbleView.java
+++ b/quickstep/src/com/android/launcher3/taskbar/bubbles/BubbleView.java
@@ -49,6 +49,8 @@
public class BubbleView extends ConstraintLayout {
public static final int DEFAULT_PATH_SIZE = 100;
+ /** Duration for animating the scale of the dot and badge. */
+ private static final int SCALE_ANIMATION_DURATION_MS = 200;
private final ImageView mBubbleIcon;
private final ImageView mAppIcon;
@@ -222,12 +224,14 @@
}
if (action == R.id.action_move_left) {
if (mController != null) {
- mController.updateBubbleBarLocation(BubbleBarLocation.LEFT);
+ mController.updateBubbleBarLocation(BubbleBarLocation.LEFT,
+ BubbleBarLocation.UpdateSource.A11Y_ACTION_BUBBLE);
}
}
if (action == R.id.action_move_right) {
if (mController != null) {
- mController.updateBubbleBarLocation(BubbleBarLocation.RIGHT);
+ mController.updateBubbleBarLocation(BubbleBarLocation.RIGHT,
+ BubbleBarLocation.UpdateSource.A11Y_ACTION_BUBBLE);
}
}
return false;
@@ -316,12 +320,37 @@
}
void setBadgeScale(float fraction) {
- if (mAppIcon.getVisibility() == VISIBLE) {
+ if (hasBadge()) {
mAppIcon.setScaleX(fraction);
mAppIcon.setScaleY(fraction);
}
}
+ void showBadge() {
+ animateBadgeScale(1);
+ }
+
+ void hideBadge() {
+ animateBadgeScale(0);
+ }
+
+ private boolean hasBadge() {
+ return mAppIcon.getVisibility() == VISIBLE;
+ }
+
+ private void animateBadgeScale(float scale) {
+ if (!hasBadge()) {
+ return;
+ }
+ mAppIcon.clearAnimation();
+ mAppIcon.animate()
+ .setDuration(SCALE_ANIMATION_DURATION_MS)
+ .setInterpolator(Interpolators.FAST_OUT_SLOW_IN)
+ .scaleX(scale)
+ .scaleY(scale)
+ .start();
+ }
+
/** Suppresses or un-suppresses drawing the dot due to an update for this bubble. */
public void suppressDotForBubbleUpdate(boolean suppress) {
mDotSuppressedForBubbleUpdate = suppress;
@@ -409,7 +438,7 @@
clearAnimation();
animate()
- .setDuration(200)
+ .setDuration(SCALE_ANIMATION_DURATION_MS)
.setInterpolator(Interpolators.FAST_OUT_SLOW_IN)
.setUpdateListener((valueAnimator) -> {
float fraction = valueAnimator.getAnimatedFraction();
@@ -456,6 +485,7 @@
void collapse();
/** Request bubble bar location to be updated to the given location */
- void updateBubbleBarLocation(BubbleBarLocation location);
+ void updateBubbleBarLocation(BubbleBarLocation location,
+ @BubbleBarLocation.UpdateSource int source);
}
}
diff --git a/quickstep/src/com/android/launcher3/taskbar/bubbles/stashing/BubbleStashController.kt b/quickstep/src/com/android/launcher3/taskbar/bubbles/stashing/BubbleStashController.kt
index 831faa1..d9589bb 100644
--- a/quickstep/src/com/android/launcher3/taskbar/bubbles/stashing/BubbleStashController.kt
+++ b/quickstep/src/com/android/launcher3/taskbar/bubbles/stashing/BubbleStashController.kt
@@ -176,12 +176,18 @@
bubbleBarTranslationYForTaskbar
}
- /** Translation Y to align the bubble bar with the hotseat. */
+ /** Translation Y to align the bubble bar with the taskbar. */
val bubbleBarTranslationYForTaskbar: Float
- /** Return translation Y to align the bubble bar with the taskbar. */
+ /** Return translation Y to align the bubble bar with the hotseat. */
val bubbleBarTranslationYForHotseat: Float
+ /**
+ * Show bubble bar is if it were in-app while launcher state is still on home. Set as a progress
+ * value between 0 and 1: 0 - use home layout, 1 - use in-app layout.
+ */
+ var inAppDisplayOverrideProgress: Float
+
/** Dumps the state of BubbleStashController. */
fun dump(pw: PrintWriter) {
pw.println("Bubble stash controller state:")
diff --git a/quickstep/src/com/android/launcher3/taskbar/bubbles/stashing/PersistentBubbleStashController.kt b/quickstep/src/com/android/launcher3/taskbar/bubbles/stashing/PersistentBubbleStashController.kt
index c117ad4..9a68335 100644
--- a/quickstep/src/com/android/launcher3/taskbar/bubbles/stashing/PersistentBubbleStashController.kt
+++ b/quickstep/src/com/android/launcher3/taskbar/bubbles/stashing/PersistentBubbleStashController.kt
@@ -22,6 +22,8 @@
import android.graphics.Rect
import android.view.MotionEvent
import android.view.View
+import com.android.app.animation.Interpolators
+import com.android.launcher3.Utilities
import com.android.launcher3.anim.AnimatedFloat
import com.android.launcher3.taskbar.TaskbarInsetsController
import com.android.launcher3.taskbar.bubbles.BubbleBarViewController
@@ -97,6 +99,34 @@
return -hotseatVerticalCenter + bubbleBarHeight / 2
}
+ override val bubbleBarTranslationY: Float
+ get() =
+ if (inAppDisplayOverrideProgress > 0f && launcherState == BubbleLauncherState.HOME) {
+ Utilities.mapToRange(
+ inAppDisplayOverrideProgress,
+ /* fromMin = */ 0f,
+ /* fromMax = */ 1f,
+ bubbleBarTranslationYForHotseat,
+ bubbleBarTranslationYForTaskbar,
+ Interpolators.LINEAR,
+ )
+ } else {
+ super.bubbleBarTranslationY
+ }
+
+ override var inAppDisplayOverrideProgress: Float = 0f
+ set(value) {
+ if (field == value) return
+ field = value
+ if (launcherState == BubbleLauncherState.HOME) {
+ bubbleBarViewController.bubbleBarTranslationY.updateValue(bubbleBarTranslationY)
+ if (value == 0f || value == 1f) {
+ // Update insets only when we reach the end values
+ taskbarInsetsController.onTaskbarOrBubblebarWindowHeightOrInsetsChanged()
+ }
+ }
+ }
+
override fun init(
taskbarInsetsController: TaskbarInsetsController,
bubbleBarViewController: BubbleBarViewController,
diff --git a/quickstep/src/com/android/launcher3/taskbar/bubbles/stashing/TransientBubbleStashController.kt b/quickstep/src/com/android/launcher3/taskbar/bubbles/stashing/TransientBubbleStashController.kt
index fbeecaa..71303f8 100644
--- a/quickstep/src/com/android/launcher3/taskbar/bubbles/stashing/TransientBubbleStashController.kt
+++ b/quickstep/src/com/android/launcher3/taskbar/bubbles/stashing/TransientBubbleStashController.kt
@@ -126,6 +126,9 @@
override val bubbleBarTranslationYForTaskbar: Float =
-taskbarHotseatDimensionsProvider.getTaskbarBottomSpace().toFloat()
+ /** Not supported in transient mode */
+ override var inAppDisplayOverrideProgress: Float = 0f
+
/** Check if we have handle view controller */
override val hasHandleView: Boolean
get() = bubbleStashedHandleViewController != null
diff --git a/quickstep/src/com/android/launcher3/taskbar/overlay/TaskbarOverlayController.java b/quickstep/src/com/android/launcher3/taskbar/overlay/TaskbarOverlayController.java
index 7eb34a5..79cb748 100644
--- a/quickstep/src/com/android/launcher3/taskbar/overlay/TaskbarOverlayController.java
+++ b/quickstep/src/com/android/launcher3/taskbar/overlay/TaskbarOverlayController.java
@@ -35,6 +35,7 @@
import com.android.launcher3.AbstractFloatingView;
import com.android.launcher3.DeviceProfile;
+import com.android.launcher3.Flags;
import com.android.launcher3.taskbar.TaskbarActivityContext;
import com.android.launcher3.taskbar.TaskbarControllers;
import com.android.systemui.shared.system.TaskStackChangeListener;
@@ -216,6 +217,13 @@
@Override
protected void handleClose(boolean animate) {
if (!mIsOpen) return;
+ if (Flags.taskbarOverflow()) {
+ // Mark the view closed before attempting to remove it, so the drag layer does not
+ // schedule another call to close. Needed for taskbar overflow in case the KQS
+ // view shown for taskbar overflow needs to be reshown - delayed close call would
+ // would result in reshown KQS view getting hidden.
+ mIsOpen = false;
+ }
mTaskbarContext.getDragLayer().removeView(this);
Optional.ofNullable(mOverlayContext).ifPresent(c -> {
if (canCloseWindow()) {
diff --git a/quickstep/src/com/android/launcher3/uioverrides/QuickstepLauncher.java b/quickstep/src/com/android/launcher3/uioverrides/QuickstepLauncher.java
index fe68ebc..34d9a68 100644
--- a/quickstep/src/com/android/launcher3/uioverrides/QuickstepLauncher.java
+++ b/quickstep/src/com/android/launcher3/uioverrides/QuickstepLauncher.java
@@ -190,6 +190,7 @@
import com.android.quickstep.views.RecentsView;
import com.android.quickstep.views.RecentsViewContainer;
import com.android.quickstep.views.TaskView;
+import com.android.systemui.animation.back.FlingOnBackAnimationCallback;
import com.android.systemui.shared.recents.model.Task;
import com.android.systemui.shared.system.ActivityManagerWrapper;
import com.android.systemui.unfold.RemoteUnfoldSharedComponent;
@@ -900,12 +901,12 @@
protected void registerBackDispatcher() {
getOnBackInvokedDispatcher().registerOnBackInvokedCallback(
OnBackInvokedDispatcher.PRIORITY_DEFAULT,
- new OnBackAnimationCallback() {
+ new FlingOnBackAnimationCallback() {
@Nullable OnBackAnimationCallback mActiveOnBackAnimationCallback;
@Override
- public void onBackStarted(@NonNull BackEvent backEvent) {
+ public void onBackStartedCompat(@NonNull BackEvent backEvent) {
if (mActiveOnBackAnimationCallback != null) {
mActiveOnBackAnimationCallback.onBackCancelled();
}
@@ -915,7 +916,7 @@
@RequiresApi(Build.VERSION_CODES.UPSIDE_DOWN_CAKE)
@Override
- public void onBackInvoked() {
+ public void onBackInvokedCompat() {
// Recreate mActiveOnBackAnimationCallback if necessary to avoid NPE
// because:
// 1. b/260636433: In 3-button-navigation mode, onBackStarted() is not
@@ -931,7 +932,7 @@
}
@Override
- public void onBackProgressed(@NonNull BackEvent backEvent) {
+ public void onBackProgressedCompat(@NonNull BackEvent backEvent) {
if (!FeatureFlags.IS_STUDIO_BUILD
&& mActiveOnBackAnimationCallback == null) {
return;
@@ -940,7 +941,7 @@
}
@Override
- public void onBackCancelled() {
+ public void onBackCancelledCompat() {
if (!FeatureFlags.IS_STUDIO_BUILD
&& mActiveOnBackAnimationCallback == null) {
return;
diff --git a/quickstep/src/com/android/launcher3/uioverrides/states/AllAppsState.java b/quickstep/src/com/android/launcher3/uioverrides/states/AllAppsState.java
index 030a7ac..d387794 100644
--- a/quickstep/src/com/android/launcher3/uioverrides/states/AllAppsState.java
+++ b/quickstep/src/com/android/launcher3/uioverrides/states/AllAppsState.java
@@ -118,7 +118,7 @@
@Override
public ScaleAndTranslation getHotseatScaleAndTranslation(Launcher launcher) {
- if (launcher.getDeviceProfile().isTablet) {
+ if (launcher.getDeviceProfile().shouldShowAllAppsOnSheet()) {
return getWorkspaceScaleAndTranslation(launcher);
} else {
ScaleAndTranslation overviewScaleAndTranslation = LauncherState.OVERVIEW
@@ -133,7 +133,7 @@
@Override
protected <DEVICE_PROFILE_CONTEXT extends Context & ActivityContext>
float getDepthUnchecked(DEVICE_PROFILE_CONTEXT context) {
- if (context.getDeviceProfile().isTablet) {
+ if (context.getDeviceProfile().shouldShowAllAppsOnSheet()) {
return context.getDeviceProfile().bottomSheetDepth;
} else {
// The scrim fades in at approximately 50% of the swipe gesture.
@@ -154,7 +154,7 @@
return new PageAlphaProvider(DECELERATE_2) {
@Override
public float getPageAlpha(int pageIndex) {
- return launcher.getDeviceProfile().isTablet
+ return launcher.getDeviceProfile().shouldShowAllAppsOnSheet()
? superPageAlphaProvider.getPageAlpha(pageIndex)
: 0;
}
@@ -164,8 +164,8 @@
@Override
public int getVisibleElements(Launcher launcher) {
int elements = ALL_APPS_CONTENT | FLOATING_SEARCH_BAR;
- // Only add HOTSEAT_ICONS for tablets in ALL_APPS state.
- if (launcher.getDeviceProfile().isTablet) {
+ // When All Apps is presented on a bottom sheet, HOTSEAT_ICONS are visible.
+ if (launcher.getDeviceProfile().shouldShowAllAppsOnSheet()) {
elements |= HOTSEAT_ICONS;
}
return elements;
@@ -202,7 +202,7 @@
@Override
public int getWorkspaceScrimColor(Launcher launcher) {
- return launcher.getDeviceProfile().isTablet
+ return launcher.getDeviceProfile().shouldShowAllAppsOnSheet()
? launcher.getResources().getColor(R.color.widgets_picker_scrim)
: Themes.getAttrColor(launcher, R.attr.allAppsScrimColor);
}
diff --git a/quickstep/src/com/android/quickstep/RecentTasksList.java b/quickstep/src/com/android/quickstep/RecentTasksList.java
index a5cc32a..714838a 100644
--- a/quickstep/src/com/android/quickstep/RecentTasksList.java
+++ b/quickstep/src/com/android/quickstep/RecentTasksList.java
@@ -20,9 +20,9 @@
import static com.android.launcher3.util.Executors.UI_HELPER_EXECUTOR;
import static com.android.quickstep.util.SplitScreenUtils.convertShellSplitBoundsToLauncher;
-import static com.android.wm.shell.shared.GroupedRecentTaskInfo.TYPE_FREEFORM;
+import static com.android.wm.shell.shared.GroupedTaskInfo.TYPE_FREEFORM;
-import android.app.ActivityManager;
+import android.app.ActivityManager.RunningTaskInfo;
import android.app.KeyguardManager;
import android.app.TaskInfo;
import android.content.ComponentName;
@@ -40,7 +40,7 @@
import com.android.quickstep.util.GroupTask;
import com.android.systemui.shared.recents.model.Task;
import com.android.wm.shell.recents.IRecentTasksListener;
-import com.android.wm.shell.shared.GroupedRecentTaskInfo;
+import com.android.wm.shell.shared.GroupedTaskInfo;
import com.android.wm.shell.shared.desktopmode.DesktopModeStatus;
import java.io.PrintWriter;
@@ -76,7 +76,7 @@
private @Nullable RecentsModel.RunningTasksListener mRunningTasksListener;
private @Nullable RecentsModel.RecentTasksChangedListener mRecentTasksChangedListener;
// Tasks are stored in order of least recently launched to most recently launched.
- private ArrayList<ActivityManager.RunningTaskInfo> mRunningTasks;
+ private ArrayList<RunningTaskInfo> mRunningTasks;
public RecentTasksList(Context context, LooperExecutor mainThreadExecutor,
KeyguardManager keyguardManager, SystemUiProxy sysUiProxy,
@@ -93,35 +93,38 @@
}
@Override
- public void onRunningTaskAppeared(ActivityManager.RunningTaskInfo taskInfo) {
+ public void onRunningTaskAppeared(RunningTaskInfo taskInfo) {
mMainThreadExecutor.execute(() -> {
RecentTasksList.this.onRunningTaskAppeared(taskInfo);
});
}
@Override
- public void onRunningTaskVanished(ActivityManager.RunningTaskInfo taskInfo) {
+ public void onRunningTaskVanished(RunningTaskInfo taskInfo) {
mMainThreadExecutor.execute(() -> {
RecentTasksList.this.onRunningTaskVanished(taskInfo);
});
}
@Override
- public void onRunningTaskChanged(ActivityManager.RunningTaskInfo taskInfo) {
+ public void onRunningTaskChanged(RunningTaskInfo taskInfo) {
mMainThreadExecutor.execute(() -> {
RecentTasksList.this.onRunningTaskChanged(taskInfo);
});
}
@Override
- public void onTaskMovedToFront(ActivityManager.RunningTaskInfo taskInfo) {
+ public void onTaskMovedToFront(GroupedTaskInfo[] visibleTasks) {
mMainThreadExecutor.execute(() -> {
- topTaskTracker.onTaskMovedToFront(taskInfo);
+ // TODO(b/346588978): We currently are only sending a single task, but this will
+ // be updated once we send the full set of visible tasks
+ final TaskInfo info = visibleTasks[0].getTaskInfo1();
+ topTaskTracker.handleTaskMovedToFront(info);
});
}
@Override
- public void onTaskInfoChanged(ActivityManager.RunningTaskInfo taskInfo) {
+ public void onTaskInfoChanged(RunningTaskInfo taskInfo) {
mMainThreadExecutor.execute(() -> topTaskTracker.onTaskChanged(taskInfo));
}
});
@@ -250,7 +253,7 @@
mRecentTasksChangedListener = null;
}
- private void initRunningTasks(ArrayList<ActivityManager.RunningTaskInfo> runningTasks) {
+ private void initRunningTasks(ArrayList<RunningTaskInfo> runningTasks) {
// Tasks are retrieved in order of most recently launched/used to least recently launched.
mRunningTasks = new ArrayList<>(runningTasks);
Collections.reverse(mRunningTasks);
@@ -259,13 +262,13 @@
/**
* Gets the set of running tasks.
*/
- public ArrayList<ActivityManager.RunningTaskInfo> getRunningTasks() {
+ public ArrayList<RunningTaskInfo> getRunningTasks() {
return mRunningTasks;
}
- private void onRunningTaskAppeared(ActivityManager.RunningTaskInfo taskInfo) {
+ private void onRunningTaskAppeared(RunningTaskInfo taskInfo) {
// Make sure this task is not already in the list
- for (ActivityManager.RunningTaskInfo existingTask : mRunningTasks) {
+ for (RunningTaskInfo existingTask : mRunningTasks) {
if (taskInfo.taskId == existingTask.taskId) {
return;
}
@@ -276,9 +279,9 @@
}
}
- private void onRunningTaskVanished(ActivityManager.RunningTaskInfo taskInfo) {
+ private void onRunningTaskVanished(RunningTaskInfo taskInfo) {
// Find the task from the list of running tasks, if it exists
- for (ActivityManager.RunningTaskInfo existingTask : mRunningTasks) {
+ for (RunningTaskInfo existingTask : mRunningTasks) {
if (existingTask.taskId != taskInfo.taskId) continue;
mRunningTasks.remove(existingTask);
@@ -289,9 +292,9 @@
}
}
- private void onRunningTaskChanged(ActivityManager.RunningTaskInfo taskInfo) {
+ private void onRunningTaskChanged(RunningTaskInfo taskInfo) {
// Find the task from the list of running tasks, if it exists
- for (ActivityManager.RunningTaskInfo existingTask : mRunningTasks) {
+ for (RunningTaskInfo existingTask : mRunningTasks) {
if (existingTask.taskId != taskInfo.taskId) continue;
mRunningTasks.remove(existingTask);
@@ -309,7 +312,7 @@
@VisibleForTesting
TaskLoadResult loadTasksInBackground(int numTasks, int requestId, boolean loadKeysOnly) {
int currentUserId = Process.myUserHandle().getIdentifier();
- ArrayList<GroupedRecentTaskInfo> rawTasks;
+ ArrayList<GroupedTaskInfo> rawTasks;
try {
rawTasks = mSysUiProxy.getRecentTasks(numTasks, currentUserId);
} catch (SystemUiProxy.GetRecentTasksException e) {
@@ -332,7 +335,7 @@
TaskLoadResult allTasks = new TaskLoadResult(requestId, loadKeysOnly, rawTasks.size());
int numVisibleTasks = 0;
- for (GroupedRecentTaskInfo rawTask : rawTasks) {
+ for (GroupedTaskInfo rawTask : rawTasks) {
if (rawTask.getType() == TYPE_FREEFORM) {
// TYPE_FREEFORM tasks is only created when desktop mode can be entered,
// leftover TYPE_FREEFORM tasks created when flag was on should be ignored.
@@ -344,14 +347,13 @@
}
continue;
}
- ActivityManager.RecentTaskInfo taskInfo1 = rawTask.getTaskInfo1();
- ActivityManager.RecentTaskInfo taskInfo2 = rawTask.getTaskInfo2();
+ TaskInfo taskInfo1 = rawTask.getTaskInfo1();
+ TaskInfo taskInfo2 = rawTask.getTaskInfo2();
Task.TaskKey task1Key = new Task.TaskKey(taskInfo1);
Task task1 = loadKeysOnly
? new Task(task1Key)
: Task.from(task1Key, taskInfo1,
tmpLockedUsers.get(task1Key.userId) /* isLocked */);
- task1.setLastSnapshotData(taskInfo1);
Task task2 = null;
if (taskInfo2 != null) {
// Is split task
@@ -360,7 +362,6 @@
? new Task(task2Key)
: Task.from(task2Key, taskInfo2,
tmpLockedUsers.get(task2Key.userId) /* isLocked */);
- task2.setLastSnapshotData(taskInfo2);
} else {
// Is fullscreen task
if (numVisibleTasks > 0) {
@@ -384,17 +385,16 @@
return allTasks;
}
- private @Nullable DesktopTask createDesktopTask(GroupedRecentTaskInfo recentTaskInfo) {
+ private @Nullable DesktopTask createDesktopTask(GroupedTaskInfo recentTaskInfo) {
ArrayList<Task> tasks = new ArrayList<>(recentTaskInfo.getTaskInfoList().size());
int[] minimizedTaskIds = recentTaskInfo.getMinimizedTaskIds();
if (minimizedTaskIds.length == recentTaskInfo.getTaskInfoList().size()) {
// All Tasks are minimized -> don't create a DesktopTask
return null;
}
- for (ActivityManager.RecentTaskInfo taskInfo : recentTaskInfo.getTaskInfoList()) {
+ for (TaskInfo taskInfo : recentTaskInfo.getTaskInfoList()) {
Task.TaskKey key = new Task.TaskKey(taskInfo);
Task task = Task.from(key, taskInfo, false);
- task.setLastSnapshotData(taskInfo);
task.positionInParent = taskInfo.positionInParent;
task.appBounds = taskInfo.configuration.windowConfiguration.getAppBounds();
task.isVisible = taskInfo.isVisible;
@@ -429,14 +429,14 @@
}
writer.println(prefix + " ]");
int currentUserId = Process.myUserHandle().getIdentifier();
- ArrayList<GroupedRecentTaskInfo> rawTasks;
+ ArrayList<GroupedTaskInfo> rawTasks;
try {
rawTasks = mSysUiProxy.getRecentTasks(Integer.MAX_VALUE, currentUserId);
} catch (SystemUiProxy.GetRecentTasksException e) {
rawTasks = new ArrayList<>();
}
writer.println(prefix + " rawTasks=[");
- for (GroupedRecentTaskInfo task : rawTasks) {
+ for (GroupedTaskInfo task : rawTasks) {
TaskInfo taskInfo1 = task.getTaskInfo1();
TaskInfo taskInfo2 = task.getTaskInfo2();
ComponentName cn1 = taskInfo1.topActivity;
diff --git a/quickstep/src/com/android/quickstep/SystemUiProxy.java b/quickstep/src/com/android/quickstep/SystemUiProxy.java
index cd39c09..6c4c74c 100644
--- a/quickstep/src/com/android/quickstep/SystemUiProxy.java
+++ b/quickstep/src/com/android/quickstep/SystemUiProxy.java
@@ -43,6 +43,7 @@
import android.os.UserHandle;
import android.util.Log;
import android.view.IRemoteAnimationRunner;
+import android.view.KeyEvent;
import android.view.MotionEvent;
import android.view.RemoteAnimationTarget;
import android.view.SurfaceControl;
@@ -91,7 +92,7 @@
import com.android.wm.shell.recents.IRecentTasksListener;
import com.android.wm.shell.recents.IRecentsAnimationController;
import com.android.wm.shell.recents.IRecentsAnimationRunner;
-import com.android.wm.shell.shared.GroupedRecentTaskInfo;
+import com.android.wm.shell.shared.GroupedTaskInfo;
import com.android.wm.shell.shared.IShellTransitions;
import com.android.wm.shell.shared.bubbles.BubbleBarLocation;
import com.android.wm.shell.shared.desktopmode.DesktopModeStatus;
@@ -210,10 +211,10 @@
}
@Override
- public void onBackPressed() {
+ public void onBackEvent(KeyEvent backEvent) {
if (mSystemUiProxy != null) {
try {
- mSystemUiProxy.onBackPressed();
+ mSystemUiProxy.onBackEvent(backEvent);
} catch (RemoteException e) {
Log.w(TAG, "Failed call onBackPressed", e);
}
@@ -885,10 +886,12 @@
/**
* Tells SysUI to update the bubble bar location to the new location.
* @param location new location for the bubble bar
+ * @param source what triggered the location update
*/
- public void setBubbleBarLocation(BubbleBarLocation location) {
+ public void setBubbleBarLocation(BubbleBarLocation location,
+ @BubbleBarLocation.UpdateSource int source) {
try {
- mBubbles.setBubbleBarLocation(location);
+ mBubbles.setBubbleBarLocation(location, source);
} catch (RemoteException e) {
Log.w(TAG, "Failed call setBubbleBarLocation");
}
@@ -1358,15 +1361,15 @@
* @throws GetRecentTasksException if IRecentTasks is not initialized, or when we get
* RemoteException from server side
*/
- public ArrayList<GroupedRecentTaskInfo> getRecentTasks(int numTasks, int userId)
- throws GetRecentTasksException {
+ public ArrayList<GroupedTaskInfo> getRecentTasks(int numTasks,
+ int userId) throws GetRecentTasksException {
if (mRecentTasks == null) {
Log.e(TAG, "getRecentTasks() failed due to null mRecentTasks");
throw new GetRecentTasksException("null mRecentTasks");
}
try {
- final GroupedRecentTaskInfo[] rawTasks = mRecentTasks.getRecentTasks(numTasks,
- RECENT_IGNORE_UNAVAILABLE, userId);
+ final GroupedTaskInfo[] rawTasks =
+ mRecentTasks.getRecentTasks(numTasks, RECENT_IGNORE_UNAVAILABLE, userId);
if (rawTasks == null) {
return new ArrayList<>();
}
diff --git a/quickstep/src/com/android/quickstep/TaskAnimationManager.java b/quickstep/src/com/android/quickstep/TaskAnimationManager.java
index 0b6794c..0ea128a 100644
--- a/quickstep/src/com/android/quickstep/TaskAnimationManager.java
+++ b/quickstep/src/com/android/quickstep/TaskAnimationManager.java
@@ -201,8 +201,7 @@
// Only finish if the end target is RECENTS. Otherwise, if the target is
// NEW_TASK, startActivityFromRecents will be skipped.
if (mLastGestureState.getEndTarget() == RECENTS) {
- finishRunningRecentsAnimation(false /* toHome */,
- true /* forceFinish */, null /* forceFinishCb */);
+ finishRunningRecentsAnimation(false /* toHome */);
}
});
}
diff --git a/quickstep/src/com/android/quickstep/TopTaskTracker.java b/quickstep/src/com/android/quickstep/TopTaskTracker.java
index 71b6573..c9dfe6d 100644
--- a/quickstep/src/com/android/quickstep/TopTaskTracker.java
+++ b/quickstep/src/com/android/quickstep/TopTaskTracker.java
@@ -27,6 +27,7 @@
import android.annotation.UserIdInt;
import android.app.ActivityManager.RunningTaskInfo;
+import android.app.TaskInfo;
import android.content.Context;
import androidx.annotation.NonNull;
@@ -67,7 +68,7 @@
private static final int HISTORY_SIZE = 5;
// Ordered list with first item being the most recent task.
- private final LinkedList<RunningTaskInfo> mOrderedTaskList = new LinkedList<>();
+ private final LinkedList<TaskInfo> mOrderedTaskList = new LinkedList<>();
private final Context mContext;
private final SplitStageInfo mMainStagePosition = new SplitStageInfo();
@@ -96,6 +97,10 @@
@Override
public void onTaskMovedToFront(RunningTaskInfo taskInfo) {
+ handleTaskMovedToFront(taskInfo);
+ }
+
+ public void handleTaskMovedToFront(TaskInfo taskInfo) {
mOrderedTaskList.removeIf(rto -> rto.taskId == taskInfo.taskId);
mOrderedTaskList.addFirst(taskInfo);
@@ -103,7 +108,7 @@
// display's task to the list, to avoid showing non-home display's task upon going to
// Recents animation.
if (taskInfo.displayId != DEFAULT_DISPLAY) {
- final RunningTaskInfo topTaskOnHomeDisplay = mOrderedTaskList.stream()
+ final TaskInfo topTaskOnHomeDisplay = mOrderedTaskList.stream()
.filter(rto -> rto.displayId == DEFAULT_DISPLAY).findFirst().orElse(null);
if (topTaskOnHomeDisplay != null) {
mOrderedTaskList.removeIf(rto -> rto.taskId == topTaskOnHomeDisplay.taskId);
@@ -113,9 +118,9 @@
if (mOrderedTaskList.size() >= HISTORY_SIZE) {
// If we grow in size, remove the last taskInfo which is not part of the split task.
- Iterator<RunningTaskInfo> itr = mOrderedTaskList.descendingIterator();
+ Iterator<TaskInfo> itr = mOrderedTaskList.descendingIterator();
while (itr.hasNext()) {
- RunningTaskInfo info = itr.next();
+ TaskInfo info = itr.next();
if (info.taskId != taskInfo.taskId
&& info.taskId != mMainStagePosition.taskId
&& info.taskId != mSideStagePosition.taskId) {
@@ -215,13 +220,13 @@
Collections.addAll(mOrderedTaskList, tasks);
}
- ArrayList<RunningTaskInfo> tasks = new ArrayList<>(mOrderedTaskList);
+ ArrayList<TaskInfo> tasks = new ArrayList<>(mOrderedTaskList);
// Strip the pinned task and recents task
tasks.removeIf(t -> t.taskId == mPinnedTaskId || isRecentsTask(t));
return new CachedTaskInfo(tasks);
}
- private static boolean isRecentsTask(RunningTaskInfo task) {
+ private static boolean isRecentsTask(TaskInfo task) {
return task != null && task.configuration.windowConfiguration
.getActivityType() == ACTIVITY_TYPE_RECENTS;
}
@@ -233,10 +238,10 @@
public static class CachedTaskInfo {
@Nullable
- private final RunningTaskInfo mTopTask;
- public final List<RunningTaskInfo> mAllCachedTasks;
+ private final TaskInfo mTopTask;
+ public final List<TaskInfo> mAllCachedTasks;
- CachedTaskInfo(List<RunningTaskInfo> allCachedTasks) {
+ CachedTaskInfo(List<TaskInfo> allCachedTasks) {
mAllCachedTasks = allCachedTasks;
mTopTask = allCachedTasks.isEmpty() ? null : allCachedTasks.get(0);
}
@@ -262,7 +267,7 @@
// Not an excluded task.
return null;
}
- List<RunningTaskInfo> visibleNonExcludedTasks = mAllCachedTasks.stream()
+ List<TaskInfo> visibleNonExcludedTasks = mAllCachedTasks.stream()
.filter(t -> t.isVisible
&& (t.baseIntent.getFlags() & FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS) == 0
&& t.getActivityType() != ACTIVITY_TYPE_HOME
diff --git a/quickstep/src/com/android/quickstep/TouchInteractionService.java b/quickstep/src/com/android/quickstep/TouchInteractionService.java
index e8f38be..fcc5121 100644
--- a/quickstep/src/com/android/quickstep/TouchInteractionService.java
+++ b/quickstep/src/com/android/quickstep/TouchInteractionService.java
@@ -74,6 +74,7 @@
import android.view.View;
import androidx.annotation.BinderThread;
+import androidx.annotation.MainThread;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.annotation.UiThread;
@@ -342,36 +343,36 @@
@BinderThread
@Override
- public void checkNavBarModes() {
- MAIN_EXECUTOR.execute(() -> executeForTouchInteractionService(tis ->
- executeForTaskbarManager(TaskbarManager::checkNavBarModes)
- ));
- }
-
- @BinderThread
- @Override
- public void finishBarAnimations() {
- MAIN_EXECUTOR.execute(() -> executeForTouchInteractionService(tis ->
- executeForTaskbarManager(TaskbarManager::finishBarAnimations)
- ));
- }
-
- @BinderThread
- @Override
- public void touchAutoDim(boolean reset) {
- MAIN_EXECUTOR.execute(() -> executeForTouchInteractionService(tis ->
- executeForTaskbarManager(taskbarManager -> taskbarManager.touchAutoDim(reset))
- ));
- }
-
- @BinderThread
- @Override
- public void transitionTo(@BarTransitions.TransitionMode int barMode,
- boolean animate) {
+ public void checkNavBarModes(int displayId) {
MAIN_EXECUTOR.execute(() -> executeForTouchInteractionService(tis ->
executeForTaskbarManager(
- taskbarManager -> taskbarManager.transitionTo(barMode, animate))
- ));
+ taskbarManager -> taskbarManager.checkNavBarModes(displayId))));
+ }
+
+ @BinderThread
+ @Override
+ public void finishBarAnimations(int displayId) {
+ MAIN_EXECUTOR.execute(() -> executeForTouchInteractionService(
+ tis -> executeForTaskbarManager(
+ taskbarManager -> taskbarManager.finishBarAnimations(displayId))));
+ }
+
+ @BinderThread
+ @Override
+ public void touchAutoDim(int displayId, boolean reset) {
+ MAIN_EXECUTOR.execute(() -> executeForTouchInteractionService(
+ tis -> executeForTaskbarManager(
+ taskbarManager -> taskbarManager.touchAutoDim(displayId, reset))));
+ }
+
+ @BinderThread
+ @Override
+ public void transitionTo(int displayId, @BarTransitions.TransitionMode int barMode,
+ boolean animate) {
+ MAIN_EXECUTOR.execute(() -> executeForTouchInteractionService(
+ tis -> executeForTaskbarManager(
+ taskbarManager -> taskbarManager.transitionTo(displayId, barMode,
+ animate))));
}
@BinderThread
@@ -550,11 +551,15 @@
@Override
public void onInputDeviceAdded(int deviceId) {
if (isTrackpadDevice(deviceId)) {
- boolean wasEmpty = mTrackpadsConnected.isEmpty();
- mTrackpadsConnected.add(deviceId);
- if (wasEmpty) {
- update();
- }
+ // This updates internal TIS state so it needs to also run on the main
+ // thread.
+ MAIN_EXECUTOR.execute(() -> {
+ boolean wasEmpty = mTrackpadsConnected.isEmpty();
+ mTrackpadsConnected.add(deviceId);
+ if (wasEmpty) {
+ update();
+ }
+ });
}
}
@@ -564,12 +569,17 @@
@Override
public void onInputDeviceRemoved(int deviceId) {
- mTrackpadsConnected.remove(deviceId);
- if (mTrackpadsConnected.isEmpty()) {
- update();
- }
+ // This updates internal TIS state so it needs to also run on the main
+ // thread.
+ MAIN_EXECUTOR.execute(() -> {
+ mTrackpadsConnected.remove(deviceId);
+ if (mTrackpadsConnected.isEmpty()) {
+ update();
+ }
+ });
}
+ @MainThread
private void update() {
if (mInputMonitorCompat != null && !mTrackpadsConnected.isEmpty()) {
// Don't destroy and reinitialize input monitor due to trackpad
@@ -580,6 +590,7 @@
}
private boolean isTrackpadDevice(int deviceId) {
+ // This is a blocking binder call that should run on a bg thread.
InputDevice inputDevice = mInputManager.getInputDevice(deviceId);
if (inputDevice == null) {
return false;
diff --git a/quickstep/src/com/android/quickstep/contextualeducation/SystemContextualEduStatsManager.java b/quickstep/src/com/android/quickstep/contextualeducation/SystemContextualEduStatsManager.java
index d470b88..6a72537 100644
--- a/quickstep/src/com/android/quickstep/contextualeducation/SystemContextualEduStatsManager.java
+++ b/quickstep/src/com/android/quickstep/contextualeducation/SystemContextualEduStatsManager.java
@@ -16,29 +16,28 @@
package com.android.quickstep.contextualeducation;
-import android.content.Context;
-
import com.android.launcher3.contextualeducation.ContextualEduStatsManager;
+import com.android.launcher3.dagger.LauncherAppSingleton;
import com.android.quickstep.SystemUiProxy;
import com.android.systemui.contextualeducation.GestureType;
+import javax.inject.Inject;
+
/**
* A class to update contextual education data via {@link SystemUiProxy}
*/
+@LauncherAppSingleton
public class SystemContextualEduStatsManager extends ContextualEduStatsManager {
- private Context mContext;
+ private final SystemUiProxy mSystemUiProxy;
- public SystemContextualEduStatsManager(Context context) {
- mContext = context;
+ @Inject
+ public SystemContextualEduStatsManager(SystemUiProxy systemUiProxy) {
+ mSystemUiProxy = systemUiProxy;
}
@Override
public void updateEduStats(boolean isTrackpadGesture, GestureType gestureType) {
- SystemUiProxy.INSTANCE.get(mContext).updateContextualEduStats(isTrackpadGesture,
+ mSystemUiProxy.updateContextualEduStats(isTrackpadGesture,
gestureType.name());
}
-
- @Override
- public void close() {
- }
}
diff --git a/quickstep/src/com/android/quickstep/dagger/QuickStepModule.java b/quickstep/src/com/android/quickstep/dagger/QuickStepModule.java
index 3870b9b..9f6360b 100644
--- a/quickstep/src/com/android/quickstep/dagger/QuickStepModule.java
+++ b/quickstep/src/com/android/quickstep/dagger/QuickStepModule.java
@@ -15,10 +15,12 @@
*/
package com.android.quickstep.dagger;
+import com.android.launcher3.contextualeducation.ContextualEduStatsManager;
import com.android.launcher3.uioverrides.SystemApiWrapper;
import com.android.launcher3.uioverrides.plugins.PluginManagerWrapperImpl;
import com.android.launcher3.util.ApiWrapper;
import com.android.launcher3.util.PluginManagerWrapper;
+import com.android.quickstep.contextualeducation.SystemContextualEduStatsManager;
import dagger.Binds;
import dagger.Module;
@@ -28,4 +30,6 @@
@Binds abstract PluginManagerWrapper bindPluginManagerWrapper(PluginManagerWrapperImpl impl);
@Binds abstract ApiWrapper bindApiWrapper(SystemApiWrapper systemApiWrapper);
+ @Binds abstract ContextualEduStatsManager bindContextualEduStatsManager(
+ SystemContextualEduStatsManager manager);
}
diff --git a/quickstep/src/com/android/quickstep/fallback/window/RecentsWindowManager.kt b/quickstep/src/com/android/quickstep/fallback/window/RecentsWindowManager.kt
index 78224ae..843ef6c 100644
--- a/quickstep/src/com/android/quickstep/fallback/window/RecentsWindowManager.kt
+++ b/quickstep/src/com/android/quickstep/fallback/window/RecentsWindowManager.kt
@@ -218,6 +218,11 @@
)
}
+ private val onBackInvokedCallback: () -> Unit = {
+ // If we are in live tile mode, launch the live task, otherwise return home
+ recentsView?.runningTaskView?.launchWithAnimation() ?: startHome()
+ }
+
private fun cleanupRecentsWindow() {
RecentsWindowProtoLogProxy.logCleanup(isShowing())
if (isShowing()) {
@@ -241,6 +246,10 @@
}
windowManager.addView(windowView, windowLayoutParams)
+ windowView
+ ?.findOnBackInvokedDispatcher()
+ ?.registerSystemOnBackInvokedCallback(onBackInvokedCallback)
+
windowView?.systemUiVisibility =
(View.SYSTEM_UI_FLAG_LAYOUT_STABLE or
View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN or
diff --git a/quickstep/src/com/android/quickstep/recents/data/TasksRepository.kt b/quickstep/src/com/android/quickstep/recents/data/TasksRepository.kt
index 4f38ec7..275af00 100644
--- a/quickstep/src/com/android/quickstep/recents/data/TasksRepository.kt
+++ b/quickstep/src/com/android/quickstep/recents/data/TasksRepository.kt
@@ -73,13 +73,17 @@
getTaskDataById(taskId).map { it?.thumbnail }.distinctUntilChangedBy { it?.snapshotId }
override fun setVisibleTasks(visibleTaskIdList: Set<Int>) {
- Log.d(TAG, "setVisibleTasks: $visibleTaskIdList")
-
// 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) }
+ val newlyVisibleTasks = visibleTaskIdList.subtract(taskRequests.keys)
+ newlyVisibleTasks.forEach { taskId -> requestTaskData(taskId) }
+
+ if (tasksNoLongerVisible.isNotEmpty() || newlyVisibleTasks.isNotEmpty()) {
+ Log.d(TAG, "setVisibleTasks to: $visibleTaskIdList, " +
+ "removed: $tasksNoLongerVisible, added: $newlyVisibleTasks")
+ }
}
private fun requestTaskData(taskId: Int) {
diff --git a/quickstep/src/com/android/quickstep/util/ScalingWorkspaceRevealAnim.kt b/quickstep/src/com/android/quickstep/util/ScalingWorkspaceRevealAnim.kt
index db02f55..f719bed 100644
--- a/quickstep/src/com/android/quickstep/util/ScalingWorkspaceRevealAnim.kt
+++ b/quickstep/src/com/android/quickstep/util/ScalingWorkspaceRevealAnim.kt
@@ -217,6 +217,11 @@
animation.addListener(
AnimatorListeners.forEndCallback(
Runnable {
+ // The workspace might stay at a transparent state when the animation is
+ // cancelled, and the alpha will not be recovered (this doesn't apply to scales
+ // somehow). Resetting the alpha for the workspace here.
+ workspace.alpha = 1.0F
+
workspace.setLayerType(View.LAYER_TYPE_NONE, null)
hotseat.setLayerType(View.LAYER_TYPE_NONE, null)
diff --git a/quickstep/src/com/android/quickstep/util/SplitToWorkspaceController.java b/quickstep/src/com/android/quickstep/util/SplitToWorkspaceController.java
index 4962367..bdfaa48 100644
--- a/quickstep/src/com/android/quickstep/util/SplitToWorkspaceController.java
+++ b/quickstep/src/com/android/quickstep/util/SplitToWorkspaceController.java
@@ -48,8 +48,11 @@
import com.android.launcher3.uioverrides.QuickstepLauncher;
import com.android.quickstep.views.FloatingTaskView;
import com.android.quickstep.views.RecentsView;
+import com.android.systemui.shared.recents.model.Task;
import com.android.systemui.shared.system.InteractionJankMonitorWrapper;
+import java.util.Collections;
+
/** Handles when the stage split lands on the home screen. */
public class SplitToWorkspaceController {
@@ -133,10 +136,20 @@
// Use Launcher's default click handler
return false;
}
-
- mController.setSecondTask(intent, user, (ItemInfo) tag);
-
- startWorkspaceAnimation(view, null /*bitmap*/, bitmapInfo.newIcon(mLauncher));
+ // Check for background task matching this tag; if we find one, set second task
+ // via task instead of intent so the bounds and windowing mode will be corrected.
+ mController.findLastActiveTasksAndRunCallback(
+ Collections.singletonList(((ItemInfo) tag).getComponentKey()),
+ false /* findExactPairMatch */,
+ foundTasks -> {
+ Task foundTask = foundTasks[0];
+ if (foundTask != null) {
+ mController.setSecondTask(foundTask, (ItemInfo) tag);
+ } else {
+ mController.setSecondTask(intent, user, (ItemInfo) tag);
+ }
+ startWorkspaceAnimation(view, null /*bitmap*/, bitmapInfo.newIcon(mLauncher));
+ });
return true;
}
diff --git a/quickstep/src/com/android/quickstep/views/DesktopTaskContentView.kt b/quickstep/src/com/android/quickstep/views/DesktopTaskContentView.kt
new file mode 100644
index 0000000..481acac
--- /dev/null
+++ b/quickstep/src/com/android/quickstep/views/DesktopTaskContentView.kt
@@ -0,0 +1,52 @@
+/*
+ * 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.views
+
+import android.content.Context
+import android.graphics.Outline
+import android.graphics.Rect
+import android.util.AttributeSet
+import android.view.View
+import android.view.ViewOutlineProvider
+import android.widget.FrameLayout
+import com.android.quickstep.views.TaskView.FullscreenDrawParams
+
+class DesktopTaskContentView
+@JvmOverloads
+constructor(context: Context, attrs: AttributeSet? = null) : FrameLayout(context, attrs) {
+ private val currentFullscreenParams = FullscreenDrawParams(context)
+ private val taskCornerRadius: Float
+ get() = currentFullscreenParams.cornerRadius
+
+ private val bounds = Rect()
+
+ init {
+ clipToOutline = true
+ outlineProvider =
+ object : ViewOutlineProvider() {
+ override fun getOutline(view: View, outline: Outline) {
+ outline.setRoundRect(bounds, taskCornerRadius)
+ }
+ }
+ }
+
+ override fun onSizeChanged(w: Int, h: Int, oldw: Int, oldh: Int) {
+ super.onSizeChanged(w, h, oldw, oldh)
+ bounds.set(0, 0, w, h)
+ invalidateOutline()
+ }
+}
diff --git a/quickstep/src/com/android/quickstep/views/DesktopTaskView.kt b/quickstep/src/com/android/quickstep/views/DesktopTaskView.kt
index 15b0a6b..5e842aa 100644
--- a/quickstep/src/com/android/quickstep/views/DesktopTaskView.kt
+++ b/quickstep/src/com/android/quickstep/views/DesktopTaskView.kt
@@ -26,6 +26,7 @@
import android.util.Log
import android.view.Gravity
import android.view.View
+import android.widget.FrameLayout
import androidx.core.content.res.ResourcesCompat
import androidx.core.view.updateLayoutParams
import com.android.launcher3.Flags.enableRefactorTaskThumbnail
@@ -81,12 +82,12 @@
private val tempRect = Rect()
private lateinit var backgroundView: View
private lateinit var iconView: TaskViewIcon
- private var childCountAtInflation = 0
+ private lateinit var contentView: FrameLayout
override fun onFinishInflate() {
super.onFinishInflate()
backgroundView =
- findViewById<View>(R.id.background)!!.apply {
+ findViewById<View>(R.id.background).apply {
updateLayoutParams<LayoutParams> {
topMargin = container.deviceProfile.overviewTaskThumbnailTopMarginPx
}
@@ -113,7 +114,12 @@
)
setText(resources.getText(R.string.recent_task_desktop))
}
- childCountAtInflation = childCount
+ contentView =
+ findViewById<FrameLayout>(R.id.desktop_content).apply {
+ updateLayoutParams<LayoutParams> {
+ topMargin = container.deviceProfile.overviewTaskThumbnailTopMarginPx
+ }
+ }
}
/** Updates this desktop task to the gives task list defined in `tasks` */
@@ -137,13 +143,8 @@
} else {
taskThumbnailViewDeprecatedPool!!.view
}
+ contentView.addView(snapshotView, 0)
- addView(
- snapshotView,
- // Add snapshotView to the front after initial views e.g. icon and
- // background.
- childCountAtInflation,
- )
TaskContainer(
this,
task,
@@ -164,7 +165,7 @@
super.onRecycle()
visibility = VISIBLE
taskContainers.forEach {
- removeView(it.snapshotView)
+ contentView.removeView(it.snapshotView)
if (enableRefactorTaskThumbnail()) {
taskThumbnailViewPool!!.recycle(it.thumbnailView)
} else {
@@ -227,9 +228,7 @@
width = (taskSize.width() * scaleWidth).toInt()
height = (taskSize.height() * scaleHeight).toInt()
leftMargin = (positionInParent.x * scaleWidth).toInt()
- topMargin =
- (positionInParent.y * scaleHeight).toInt() +
- container.deviceProfile.overviewTaskThumbnailTopMarginPx
+ topMargin = (positionInParent.y * scaleHeight).toInt()
}
if (DEBUG) {
with(it.snapshotView.layoutParams as LayoutParams) {
diff --git a/quickstep/src/com/android/quickstep/views/RecentsView.java b/quickstep/src/com/android/quickstep/views/RecentsView.java
index 9a8041b..839c42e 100644
--- a/quickstep/src/com/android/quickstep/views/RecentsView.java
+++ b/quickstep/src/com/android/quickstep/views/RecentsView.java
@@ -3607,7 +3607,8 @@
* @param dismissingForSplitSelection task dismiss animation is used for entering split
* selection state from app icon
*/
- public void createTaskDismissAnimation(PendingAnimation anim, TaskView dismissedTaskView,
+ public void createTaskDismissAnimation(PendingAnimation anim,
+ @Nullable TaskView dismissedTaskView,
boolean animateTaskView, boolean shouldRemoveTask, long duration,
boolean dismissingForSplitSelection) {
if (mPendingAnimation != null) {
@@ -3622,7 +3623,8 @@
boolean showAsGrid = showAsGrid();
int taskCount = getTaskViewCount();
int dismissedIndex = indexOfChild(dismissedTaskView);
- int dismissedTaskViewId = dismissedTaskView.getTaskViewId();
+ int dismissedTaskViewId =
+ dismissedTaskView != null ? dismissedTaskView.getTaskViewId() : INVALID_TASK_ID;
// Grid specific properties.
boolean isFocusedTaskDismissed = false;
@@ -3637,10 +3639,18 @@
int scrollDiffPerPage = 0;
// Non-grid specific properties.
boolean needsCurveUpdates = false;
+ boolean areAllDesktopTasksDismissed = false;
if (showAsGrid) {
- dismissedTaskWidth = dismissedTaskView.getLayoutParams().width + mPageSpacing;
- isFocusedTaskDismissed = dismissedTaskViewId == mFocusedTaskViewId;
+ if (dismissedTaskView != null) {
+ dismissedTaskWidth = dismissedTaskView.getLayoutParams().width + mPageSpacing;
+ }
+ isFocusedTaskDismissed = dismissedTaskViewId != INVALID_TASK_ID
+ && dismissedTaskViewId == mFocusedTaskViewId;
+ if (dismissingForSplitSelection && getTaskViewAt(
+ mCurrentPage) instanceof DesktopTaskView) {
+ areAllDesktopTasksDismissed = true;
+ }
if (isFocusedTaskDismissed) {
if (isSplitSelectionActive()) {
isStagingFocusedTask = true;
@@ -3812,19 +3822,23 @@
SplitAnimationTimings splitTimings =
AnimUtils.getDeviceOverviewToSplitTimings(mContainer.getDeviceProfile().isTablet);
- int distanceFromDismissedTask = 0;
+ int distanceFromDismissedTask = 1;
+ int stagingTranslation = 0;
+ if (isStagingFocusedTask || areAllDesktopTasksDismissed) {
+ int nextSnappedPage = isStagingFocusedTask
+ ? indexOfChild(mUtils.getFirstSmallTaskView(getTaskViews()))
+ : mUtils.getDesktopTaskViewCount(getTaskViews());
+ stagingTranslation = getPagedOrientationHandler().getPrimaryScroll(this)
+ - getScrollForPage(nextSnappedPage);
+ }
for (int i = 0; i < count; i++) {
View child = getChildAt(i);
if (child == dismissedTaskView) {
- if (animateTaskView) {
- if (dismissingForSplitSelection) {
- createInitialSplitSelectAnimation(anim);
- } else {
- addDismissedTaskAnimations(dismissedTaskView, duration, anim);
- }
+ if (animateTaskView && !dismissingForSplitSelection) {
+ addDismissedTaskAnimations(dismissedTaskView, duration, anim);
}
} else if (!showAsGrid || (enableLargeDesktopWindowingTile()
- && dismissedTaskView.isLargeTile()
+ && dismissedTaskView != null && dismissedTaskView.isLargeTile()
&& nextFocusedTaskView == null && !dismissingForSplitSelection)) {
int offset = getOffsetToDismissedTask(scrollDiffPerPage, dismissedIndex, taskCount);
int scrollDiff = newScroll[i] - oldScroll[i] + offset;
@@ -3838,19 +3852,9 @@
needsCurveUpdates = true;
}
} else if (child instanceof TaskView taskView) {
- if (isFocusedTaskDismissed) {
- if (nextFocusedTaskView != null &&
- !isSameGridRow(taskView, nextFocusedTaskView)) {
- continue;
- }
- } else if (i < dismissedIndex || !isSameGridRow(taskView, dismissedTaskView)) {
- continue;
- }
-
// Animate task with index >= dismissed index and in the same row as the
// dismissed index or next focused index. Offset successive task dismissal
// durations for a staggered effect.
- distanceFromDismissedTask++;
int staggerColumn = isStagingFocusedTask
? (int) Math.ceil(distanceFromDismissedTask / 2f)
: distanceFromDismissedTask;
@@ -3877,16 +3881,15 @@
: dismissTranslationInterpolationEnd;
Interpolator dismissInterpolator = isStagingFocusedTask ? OVERSHOOT_0_75 : LINEAR;
+ float primaryTranslation = 0;
if (taskView == nextFocusedTaskView) {
// Enlarge the task to be focused next, and translate into focus position.
float scale = mTaskWidth / (float) mLastComputedGridTaskSize.width();
anim.setFloat(taskView, TaskView.DISMISS_SCALE, scale,
clampToProgress(LINEAR, animationStartProgress,
dismissTranslationInterpolationEnd));
- anim.setFloat(taskView, taskView.getPrimaryDismissTranslationProperty(),
- mIsRtl ? dismissedTaskWidth : -dismissedTaskWidth,
- clampToProgress(LINEAR, animationStartProgress,
- dismissTranslationInterpolationEnd));
+ primaryTranslation += mIsRtl ? dismissedTaskWidth : -dismissedTaskWidth;
+ animationEndProgress = dismissTranslationInterpolationEnd;
float secondaryTranslation = -mTaskGridVerticalDiff;
if (!nextFocusedTaskFromTop) {
secondaryTranslation -= mTopBottomRowHeightDiff;
@@ -3896,25 +3899,27 @@
dismissTranslationInterpolationEnd));
anim.add(taskView.getFocusTransitionScaleAndDimOutAnimator(),
clampToProgress(LINEAR, 0f, ANIMATION_DISMISS_PROGRESS_MIDPOINT));
- } else {
- float primaryTranslation =
+ } else if ((isFocusedTaskDismissed && nextFocusedTaskView != null && isSameGridRow(
+ taskView, nextFocusedTaskView))
+ || (!isFocusedTaskDismissed && i >= dismissedIndex && isSameGridRow(
+ taskView, dismissedTaskView))) {
+ primaryTranslation +=
nextFocusedTaskView != null ? nextFocusedTaskWidth : dismissedTaskWidth;
- if (isStagingFocusedTask) {
- // Moves less if focused task is not in scroll position.
- int focusedTaskScroll = getScrollForPage(dismissedIndex);
- int primaryScroll = getPagedOrientationHandler().getPrimaryScroll(this);
- int focusedTaskScrollDiff = primaryScroll - focusedTaskScroll;
- primaryTranslation +=
- mIsRtl ? focusedTaskScrollDiff : -focusedTaskScrollDiff;
- }
+ }
+ primaryTranslation += mIsRtl ? stagingTranslation : -stagingTranslation;
+ if (primaryTranslation != 0) {
anim.setFloat(taskView, taskView.getPrimaryDismissTranslationProperty(),
mIsRtl ? primaryTranslation : -primaryTranslation,
clampToProgress(dismissInterpolator, animationStartProgress,
animationEndProgress));
+ distanceFromDismissedTask++;
}
}
}
+ if (dismissingForSplitSelection) {
+ createInitialSplitSelectAnimation(anim);
+ }
if (needsCurveUpdates) {
anim.addOnFrameCallback(this::updateCurveProperties);
@@ -3923,7 +3928,7 @@
// Add a tiny bit of translation Z, so that it draws on top of other views. This is relevant
// (e.g.) when we dismiss a task by sliding it upward: if there is a row of icons above, we
// want the dragged task to stay above all other views.
- if (animateTaskView) {
+ if (animateTaskView && dismissedTaskView != null) {
dismissedTaskView.setTranslationZ(0.1f);
}
@@ -3935,7 +3940,8 @@
mPendingAnimation.addEndListener(new Consumer<>() {
@Override
public void accept(Boolean success) {
- if (mEnableDrawingLiveTile && dismissedTaskView.isRunningTask() && success) {
+ if (mEnableDrawingLiveTile && dismissedTaskView != null
+ && dismissedTaskView.isRunningTask() && success) {
finishRecentsAnimation(true /* toRecents */, false /* shouldPip */,
() -> onEnd(true));
} else {
@@ -3951,7 +3957,7 @@
if (success) {
mAnyTaskHasBeenDismissed = true;
- if (shouldRemoveTask) {
+ if (shouldRemoveTask && dismissedTaskView != null) {
if (dismissedTaskView.isRunningTask()) {
finishRecentsAnimation(true /* toRecents */, false /* shouldPip */,
() -> removeTaskInternal(dismissedTaskView));
@@ -5080,9 +5086,10 @@
if (enableLargeDesktopWindowingTile()) {
for (TaskView taskView : getTaskViews()) {
if (taskView instanceof DesktopTaskView) {
+ // Correcting the animation for split mode since we hide DW in split.
builder.addFloat(taskView.getSplitAlphaProperty(),
MULTI_PROPERTY_VALUE, 1f, 0f,
- deskTopFadeInterPolator);
+ clampToProgress(deskTopFadeInterPolator, 0f, 0.1f));
}
}
}
@@ -5140,7 +5147,15 @@
true /* dismissingForSplitSelection*/);
} else {
// Splitting from Home
- createInitialSplitSelectAnimation(builder);
+ TaskView currentPageTaskView = getTaskViewAt(mCurrentPage);
+ // When current page is a Desktop task it needs special handling to
+ // display correct animation in split mode
+ if (currentPageTaskView instanceof DesktopTaskView) {
+ createTaskDismissAnimation(builder, null, true, false, duration,
+ true /* dismissingForSplitSelection*/);
+ } else {
+ createInitialSplitSelectAnimation(builder);
+ }
}
}
diff --git a/quickstep/src/com/android/quickstep/views/TaskContainer.kt b/quickstep/src/com/android/quickstep/views/TaskContainer.kt
index 959516f..25aba39 100644
--- a/quickstep/src/com/android/quickstep/views/TaskContainer.kt
+++ b/quickstep/src/com/android/quickstep/views/TaskContainer.kt
@@ -151,7 +151,7 @@
if (enableRefactorTaskThumbnail()) {
bindThumbnailView()
} else {
- thumbnailViewDeprecated.bind(task, overlay)
+ thumbnailViewDeprecated.bind(task, overlay, taskView)
}
overlay.init()
}
diff --git a/quickstep/src/com/android/quickstep/views/TaskThumbnailViewDeprecated.java b/quickstep/src/com/android/quickstep/views/TaskThumbnailViewDeprecated.java
index 56ca043..5dbc2ef 100644
--- a/quickstep/src/com/android/quickstep/views/TaskThumbnailViewDeprecated.java
+++ b/quickstep/src/com/android/quickstep/views/TaskThumbnailViewDeprecated.java
@@ -110,6 +110,7 @@
private TaskView.FullscreenDrawParams mFullscreenParams;
private ImageView mSplashView;
private Drawable mSplashViewDrawable;
+ private TaskView mTaskView;
@Nullable
private Task mTask;
@@ -153,10 +154,11 @@
/**
* Updates the thumbnail to draw the provided task
*/
- public void bind(Task task, TaskOverlay<?> overlay) {
+ public void bind(Task task, TaskOverlay<?> overlay, TaskView taskView) {
mOverlay = overlay;
mOverlay.reset();
mTask = task;
+ mTaskView = taskView;
int color = task == null ? Color.BLACK : task.colorBackground | 0xFF000000;
mPaint.setColor(color);
mBackgroundPaint.setColor(color);
@@ -292,8 +294,8 @@
public void drawOnCanvas(Canvas canvas, float x, float y, float width, float height,
float cornerRadius) {
- if (mTask != null && getTaskView().isRunningTask()
- && !getTaskView().getShouldShowScreenshot()) {
+ if (mTask != null && mTaskView.isRunningTask()
+ && !mTaskView.getShouldShowScreenshot()) {
canvas.drawRoundRect(x, y, width, height, cornerRadius, cornerRadius, mClearPaint);
canvas.drawRoundRect(x, y, width, height, cornerRadius, cornerRadius,
mDimmingPaintAfterClearing);
@@ -334,10 +336,6 @@
}
}
- public TaskView getTaskView() {
- return (TaskView) getParent();
- }
-
public void setOverlayEnabled(boolean overlayEnabled) {
if (mOverlayEnabled != overlayEnabled) {
mOverlayEnabled = overlayEnabled;
@@ -390,9 +388,9 @@
float viewCenterY = viewHeight / 2f;
float centeredDrawableLeft = (viewWidth - drawableWidth) / 2f;
float centeredDrawableTop = (viewHeight - drawableHeight) / 2f;
- float nonGridScale = getTaskView() == null ? 1 : 1 / getTaskView().getNonGridScale();
- float recentsMaxScale = getTaskView() == null || getTaskView().getRecentsView() == null
- ? 1 : 1 / getTaskView().getRecentsView().getMaxScaleForFullScreen();
+ float nonGridScale = mTaskView == null ? 1 : 1 / mTaskView.getNonGridScale();
+ float recentsMaxScale = mTaskView == null || mTaskView.getRecentsView() == null
+ ? 1 : 1 / mTaskView.getRecentsView().getMaxScaleForFullScreen();
float scaleX = nonGridScale * recentsMaxScale * (1 / getScaleX());
float scaleY = nonGridScale * recentsMaxScale * (1 / getScaleY());
@@ -419,7 +417,7 @@
}
private boolean isThumbnailRotationDifferentFromTask() {
- RecentsView recents = getTaskView().getRecentsView();
+ RecentsView recents = mTaskView.getRecentsView();
if (recents == null || mThumbnailData == null) {
return false;
}
@@ -467,7 +465,7 @@
if (mBitmapShader != null && mThumbnailData != null) {
mPreviewRect.set(0, 0, mThumbnailData.getThumbnail().getWidth(),
mThumbnailData.getThumbnail().getHeight());
- int currentRotation = getTaskView().getOrientedState().getRecentsActivityRotation();
+ int currentRotation = mTaskView.getOrientedState().getRecentsActivityRotation();
boolean isRtl = getLayoutDirection() == LAYOUT_DIRECTION_RTL;
mPreviewPositionHelper.updateThumbnailMatrix(mPreviewRect, mThumbnailData,
getMeasuredWidth(), getMeasuredHeight(), dp.isTablet, currentRotation, isRtl);
@@ -475,7 +473,7 @@
mBitmapShader.setLocalMatrix(mPreviewPositionHelper.getMatrix());
mPaint.setShader(mBitmapShader);
}
- getTaskView().updateCurrentFullscreenParams();
+ mTaskView.updateCurrentFullscreenParams();
invalidate();
}
diff --git a/quickstep/src/com/android/quickstep/views/TaskView.kt b/quickstep/src/com/android/quickstep/views/TaskView.kt
index 28ecf96..0760618 100644
--- a/quickstep/src/com/android/quickstep/views/TaskView.kt
+++ b/quickstep/src/com/android/quickstep/views/TaskView.kt
@@ -636,24 +636,29 @@
override fun onInitializeAccessibilityNodeInfo(info: AccessibilityNodeInfo) {
super.onInitializeAccessibilityNodeInfo(info)
with(info) {
- addAction(
- AccessibilityAction(
- R.id.action_close,
- context.getText(R.string.accessibility_close),
+ // Only make actions available if the app icon menu is visible to the user.
+ // When modalness is >0, the user is in select mode and the icon menu is hidden.
+ if (modalness == 0f) {
+ addAction(
+ AccessibilityAction(
+ R.id.action_close,
+ context.getText(R.string.accessibility_close),
+ )
)
- )
- taskContainers.forEach {
- TraceHelper.allowIpcs("TV.a11yInfo") {
- TaskOverlayFactory.getEnabledShortcuts(this@TaskView, it).forEach { shortcut ->
- addAction(shortcut.createAccessibilityAction(context))
+ taskContainers.forEach {
+ TraceHelper.allowIpcs("TV.a11yInfo") {
+ TaskOverlayFactory.getEnabledShortcuts(this@TaskView, it).forEach { shortcut
+ ->
+ addAction(shortcut.createAccessibilityAction(context))
+ }
}
}
- }
- // Add DWB accessibility action at the end of the list
- taskContainers.forEach {
- it.digitalWellBeingToast?.getDWBAccessibilityAction()?.let(::addAction)
+ // Add DWB accessibility action at the end of the list
+ taskContainers.forEach {
+ it.digitalWellBeingToast?.getDWBAccessibilityAction()?.let(::addAction)
+ }
}
recentsView?.let {
diff --git a/quickstep/tests/multivalentTests/src/com/android/launcher3/taskbar/TaskbarNavButtonControllerTest.java b/quickstep/tests/multivalentTests/src/com/android/launcher3/taskbar/TaskbarNavButtonControllerTest.java
index 253d921..4b04dba 100644
--- a/quickstep/tests/multivalentTests/src/com/android/launcher3/taskbar/TaskbarNavButtonControllerTest.java
+++ b/quickstep/tests/multivalentTests/src/com/android/launcher3/taskbar/TaskbarNavButtonControllerTest.java
@@ -115,7 +115,7 @@
@Test
public void testPressBack() {
mNavButtonController.onButtonClick(BUTTON_BACK, mockView);
- verify(mockSystemUiProxy, times(1)).onBackPressed();
+ verify(mockSystemUiProxy, times(1)).onBackEvent(null);
}
@Test
diff --git a/quickstep/tests/multivalentTests/src/com/android/launcher3/taskbar/TaskbarScrimViewControllerTest.kt b/quickstep/tests/multivalentTests/src/com/android/launcher3/taskbar/TaskbarScrimViewControllerTest.kt
index 3912051..4c94067 100644
--- a/quickstep/tests/multivalentTests/src/com/android/launcher3/taskbar/TaskbarScrimViewControllerTest.kt
+++ b/quickstep/tests/multivalentTests/src/com/android/launcher3/taskbar/TaskbarScrimViewControllerTest.kt
@@ -17,9 +17,14 @@
package com.android.launcher3.taskbar
import android.animation.AnimatorTestRule
+import android.platform.test.annotations.DisableFlags
+import android.platform.test.annotations.EnableFlags
+import android.platform.test.flag.junit.SetFlagsRule
+import android.view.KeyEvent
import android.view.View.GONE
import android.view.View.VISIBLE
import androidx.test.platform.app.InstrumentationRegistry.getInstrumentation
+import com.android.launcher3.taskbar.bubbles.stashing.BubbleStashController
import com.android.launcher3.taskbar.rules.TaskbarModeRule
import com.android.launcher3.taskbar.rules.TaskbarModeRule.Mode.PINNED
import com.android.launcher3.taskbar.rules.TaskbarModeRule.Mode.TRANSIENT
@@ -33,6 +38,7 @@
import com.android.systemui.shared.system.QuickStepContract.SYSUI_STATE_BUBBLES_EXPANDED
import com.android.systemui.shared.system.QuickStepContract.SYSUI_STATE_BUBBLES_MANAGE_MENU_EXPANDED
import com.android.systemui.shared.system.QuickStepContract.SYSUI_STATE_NOTIFICATION_PANEL_VISIBLE
+import com.android.wm.shell.Flags.FLAG_ENABLE_BUBBLE_BAR
import com.android.wm.shell.shared.bubbles.BubbleConstants.BUBBLE_EXPANDED_SCRIM_ALPHA
import com.google.common.truth.Truth.assertThat
import org.junit.Rule
@@ -42,21 +48,22 @@
@RunWith(LauncherMultivalentJUnit::class)
@EmulatedDevices(["pixelTablet2023"])
class TaskbarScrimViewControllerTest {
- @get:Rule(order = 0)
+ @get:Rule(order = 0) val setFlagsRule = SetFlagsRule()
+ @get:Rule(order = 1)
val context =
TaskbarWindowSandboxContext.create { builder ->
builder.bindSystemUiProxy(
object : SystemUiProxy(this) {
- override fun onBackPressed() {
- super.onBackPressed()
+ override fun onBackEvent(backEvent: KeyEvent?) {
+ super.onBackEvent(backEvent)
backPressed = true
}
}
)
}
- @get:Rule(order = 1) val taskbarModeRule = TaskbarModeRule(context)
- @get:Rule(order = 2) val animatorTestRule = AnimatorTestRule(this)
- @get:Rule(order = 3) val taskbarUnitTestRule = TaskbarUnitTestRule(this, context)
+ @get:Rule(order = 2) val taskbarModeRule = TaskbarModeRule(context)
+ @get:Rule(order = 3) val animatorTestRule = AnimatorTestRule(this)
+ @get:Rule(order = 4) val taskbarUnitTestRule = TaskbarUnitTestRule(this, context)
@InjectController lateinit var scrimViewController: TaskbarScrimViewController
@@ -89,6 +96,7 @@
}
@Test
+ @DisableFlags(FLAG_ENABLE_BUBBLE_BAR)
@TaskbarMode(PINNED)
fun testOnTaskbarVisibilityChanged_pinnedTaskbarHiddenDuringScrim_hidesScrim() {
getInstrumentation().runOnMainSync {
@@ -105,6 +113,26 @@
}
@Test
+ @EnableFlags(FLAG_ENABLE_BUBBLE_BAR)
+ @TaskbarMode(PINNED)
+ fun testOnTaskbarVisibilityChanged_pinnedTaskbarOnHomeHiddenDuringScrim_hidesScrim() {
+ getInstrumentation().runOnMainSync {
+ scrimViewController.onTaskbarVisibilityChanged(VISIBLE)
+ taskbarUnitTestRule.activityContext.bubbleControllers!!
+ .bubbleStashController
+ .launcherState = BubbleStashController.BubbleLauncherState.HOME
+ scrimViewController.updateStateForSysuiFlags(SYSUI_STATE_BUBBLES_EXPANDED, true)
+ }
+ assertThat(scrimViewController.scrimAlpha).isEqualTo(BUBBLE_EXPANDED_SCRIM_ALPHA)
+
+ getInstrumentation().runOnMainSync {
+ scrimViewController.onTaskbarVisibilityChanged(GONE)
+ animatorTestRule.advanceTimeBy(animationDuration)
+ }
+ assertThat(scrimViewController.scrimAlpha).isEqualTo(0)
+ }
+
+ @Test
@TaskbarMode(PINNED)
fun testOnTaskbarVisibilityChanged_notificationsOverPinnedTaskbarAndBubbles_noScrim() {
getInstrumentation().runOnMainSync {
diff --git a/quickstep/tests/multivalentTests/src/com/android/launcher3/taskbar/bubbles/stashing/PersistentBubbleStashControllerTest.kt b/quickstep/tests/multivalentTests/src/com/android/launcher3/taskbar/bubbles/stashing/PersistentBubbleStashControllerTest.kt
index 00b42bc..e3d41e7 100644
--- a/quickstep/tests/multivalentTests/src/com/android/launcher3/taskbar/bubbles/stashing/PersistentBubbleStashControllerTest.kt
+++ b/quickstep/tests/multivalentTests/src/com/android/launcher3/taskbar/bubbles/stashing/PersistentBubbleStashControllerTest.kt
@@ -38,6 +38,7 @@
import org.mockito.junit.MockitoJUnit
import org.mockito.junit.MockitoRule
import org.mockito.kotlin.clearInvocations
+import org.mockito.kotlin.never
import org.mockito.kotlin.verify
import org.mockito.kotlin.whenever
@@ -228,6 +229,90 @@
.isEqualTo(TASK_BAR_TRANSLATION_Y)
}
+ @Test
+ fun inAppDisplayOverrideProgress_onHome_updatesTranslationFromHomeToInApp() {
+ whenever(bubbleBarViewController.hasBubbles()).thenReturn(false)
+ persistentTaskBarStashController.launcherState = BubbleLauncherState.HOME
+
+ assertThat(persistentTaskBarStashController.bubbleBarTranslationY)
+ .isEqualTo(HOTSEAT_TRANSLATION_Y)
+
+ persistentTaskBarStashController.inAppDisplayOverrideProgress = 0.5f
+
+ val middleBetweenHotseatAndTaskbar = (HOTSEAT_TRANSLATION_Y + TASK_BAR_TRANSLATION_Y) / 2f
+ assertThat(persistentTaskBarStashController.bubbleBarTranslationY)
+ .isWithin(0.1f)
+ .of(middleBetweenHotseatAndTaskbar)
+
+ persistentTaskBarStashController.inAppDisplayOverrideProgress = 1f
+
+ assertThat(persistentTaskBarStashController.bubbleBarTranslationY)
+ .isEqualTo(TASK_BAR_TRANSLATION_Y)
+ }
+
+ @Test
+ fun inAppDisplayOverrideProgress_onHome_updatesInsetsWhenProgressReachesOne() {
+ whenever(bubbleBarViewController.hasBubbles()).thenReturn(false)
+ persistentTaskBarStashController.launcherState = BubbleLauncherState.HOME
+ // Reset invocations to track only changes from in-app display override
+ clearInvocations(taskbarInsetsController)
+
+ // Insets are not updated for values between 0 and 1
+ persistentTaskBarStashController.inAppDisplayOverrideProgress = 0.5f
+ verify(taskbarInsetsController, never()).onTaskbarOrBubblebarWindowHeightOrInsetsChanged()
+
+ // Update insets when progress reaches 1
+ persistentTaskBarStashController.inAppDisplayOverrideProgress = 1f
+ verify(taskbarInsetsController).onTaskbarOrBubblebarWindowHeightOrInsetsChanged()
+ }
+
+ @Test
+ fun inAppDisplayOverrideProgress_onHome_updatesInsetsWhenProgressReachesZero() {
+ whenever(bubbleBarViewController.hasBubbles()).thenReturn(false)
+ persistentTaskBarStashController.launcherState = BubbleLauncherState.HOME
+ persistentTaskBarStashController.inAppDisplayOverrideProgress = 1f
+ // Reset invocations to track only changes from in-app display override
+ clearInvocations(taskbarInsetsController)
+
+ // Insets are not updated for values between 0 and 1
+ persistentTaskBarStashController.inAppDisplayOverrideProgress = 0.5f
+ verify(taskbarInsetsController, never()).onTaskbarOrBubblebarWindowHeightOrInsetsChanged()
+
+ // Update insets when progress reaches 0
+ persistentTaskBarStashController.inAppDisplayOverrideProgress = 0f
+ verify(taskbarInsetsController).onTaskbarOrBubblebarWindowHeightOrInsetsChanged()
+ }
+
+ @Test
+ fun inAppDisplayProgressUpdate_inApp_noTranslationUpdate() {
+ whenever(bubbleBarViewController.hasBubbles()).thenReturn(false)
+ persistentTaskBarStashController.launcherState = BubbleLauncherState.IN_APP
+
+ assertThat(persistentTaskBarStashController.bubbleBarTranslationY)
+ .isEqualTo(TASK_BAR_TRANSLATION_Y)
+
+ persistentTaskBarStashController.inAppDisplayOverrideProgress = 0.5f
+
+ assertThat(persistentTaskBarStashController.bubbleBarTranslationY)
+ .isEqualTo(TASK_BAR_TRANSLATION_Y)
+ }
+
+ @Test
+ fun inAppDisplayOverrideProgress_inApp_noInsetsUpdate() {
+ whenever(bubbleBarViewController.hasBubbles()).thenReturn(false)
+ persistentTaskBarStashController.launcherState = BubbleLauncherState.IN_APP
+
+ // Reset invocations to track only changes from in-app display override
+ clearInvocations(taskbarInsetsController)
+
+ persistentTaskBarStashController.inAppDisplayOverrideProgress = 0.5f
+ persistentTaskBarStashController.inAppDisplayOverrideProgress = 1f
+ persistentTaskBarStashController.inAppDisplayOverrideProgress = 0f
+
+ // Never triggers an update to insets
+ verify(taskbarInsetsController, never()).onTaskbarOrBubblebarWindowHeightOrInsetsChanged()
+ }
+
private fun advanceTimeBy(advanceMs: Long) {
// Advance animator for on-device tests
getInstrumentation().runOnMainSync { animatorTestRule.advanceTimeBy(advanceMs) }
diff --git a/quickstep/tests/multivalentTests/src/com/android/quickstep/LauncherSwipeHandlerV2Test.kt b/quickstep/tests/multivalentTests/src/com/android/quickstep/LauncherSwipeHandlerV2Test.kt
index c3d865f..32b5b85 100644
--- a/quickstep/tests/multivalentTests/src/com/android/quickstep/LauncherSwipeHandlerV2Test.kt
+++ b/quickstep/tests/multivalentTests/src/com/android/quickstep/LauncherSwipeHandlerV2Test.kt
@@ -23,6 +23,7 @@
import com.android.launcher3.dagger.LauncherAppComponent
import com.android.launcher3.dagger.LauncherAppSingleton
import com.android.launcher3.util.LauncherModelHelper
+import com.android.quickstep.dagger.QuickStepModule
import com.android.systemui.contextualeducation.GestureType
import com.android.systemui.shared.system.InputConsumerController
import dagger.BindsInstance
@@ -105,7 +106,7 @@
}
@LauncherAppSingleton
-@Component
+@Component(modules = [QuickStepModule::class])
interface TestComponent : LauncherAppComponent {
@Component.Builder
interface Builder : LauncherAppComponent.Builder {
diff --git a/quickstep/tests/src/com/android/launcher3/model/WidgetsPredicationUpdateTaskTest.java b/quickstep/tests/src/com/android/launcher3/model/WidgetsPredicationUpdateTaskTest.java
index 7b57c81..c53c177 100644
--- a/quickstep/tests/src/com/android/launcher3/model/WidgetsPredicationUpdateTaskTest.java
+++ b/quickstep/tests/src/com/android/launcher3/model/WidgetsPredicationUpdateTaskTest.java
@@ -33,6 +33,7 @@
import static org.mockito.ArgumentMatchers.eq;
import static org.mockito.Mockito.doAnswer;
import static org.mockito.Mockito.doReturn;
+import static org.mockito.Mockito.spy;
import android.app.prediction.AppTarget;
import android.app.prediction.AppTargetId;
@@ -42,6 +43,8 @@
import android.content.pm.ApplicationInfo;
import android.content.pm.LauncherApps;
import android.os.UserHandle;
+import android.platform.test.annotations.DisableFlags;
+import android.platform.test.annotations.EnableFlags;
import android.platform.test.flag.junit.SetFlagsRule;
import android.text.TextUtils;
@@ -62,9 +65,13 @@
import org.junit.Rule;
import org.junit.Test;
import org.junit.runner.RunWith;
+import org.mockito.junit.MockitoJUnit;
+import org.mockito.junit.MockitoRule;
import java.util.Arrays;
import java.util.List;
+import java.util.Set;
+import java.util.function.Predicate;
import java.util.stream.Collectors;
@SmallTest
@@ -72,6 +79,9 @@
public final class WidgetsPredicationUpdateTaskTest {
@Rule
+ public final MockitoRule mocks = MockitoJUnit.rule();
+
+ @Rule
public final SetFlagsRule mSetFlagsRule = new SetFlagsRule();
private AppWidgetProviderInfo mApp1Provider1;
@@ -145,6 +155,7 @@
}
@Test
+ @DisableFlags(Flags.FLAG_ENABLE_TIERED_WIDGETS_BY_DEFAULT_IN_PICKER) // Flag off
public void widgetsRecommendationRan_shouldOnlyReturnNotAddedWidgetsInAppPredictionOrder() {
// Run on model executor so that no other task runs in the middle.
runOnExecutorSync(MODEL_EXECUTOR, () -> {
@@ -184,6 +195,7 @@
}
@Test
+ @DisableFlags(Flags.FLAG_ENABLE_TIERED_WIDGETS_BY_DEFAULT_IN_PICKER) // Flag off
public void widgetsRecommendationRan_shouldReturnEmptyWidgetsWhenEmpty() {
runOnExecutorSync(MODEL_EXECUTOR, () -> {
@@ -213,6 +225,50 @@
});
}
+ @Test
+ @EnableFlags(Flags.FLAG_ENABLE_TIERED_WIDGETS_BY_DEFAULT_IN_PICKER)
+ public void widgetsRecommendationRan_keepsWidgetsNotOnWorkspace_addsWidgetsFromEligibleApps() {
+ runOnExecutorSync(MODEL_EXECUTOR, () -> {
+ WidgetsFilterDataProvider spiedFilterProvider = spy(
+ mModelHelper.getModel().getWidgetsFilterDataProvider());
+ doAnswer(i -> new Predicate<WidgetItem>() {
+ @Override
+ public boolean test(WidgetItem widgetItem) {
+ // app5's widget is already on workspace, but, app2 is not.
+ // And app4's second widget is also not on workspace.
+ return Set.of("app5", "app2", "app4").contains(
+ widgetItem.componentName.getPackageName());
+ }
+ }).when(spiedFilterProvider).getPredictedWidgetsFilter();
+ mModelHelper.getBgDataModel().widgetsModel.updateWidgetFilters(spiedFilterProvider);
+ // App5's widget that's already on workspace.
+ AppTarget widget1 = new AppTarget(new AppTargetId("app5"), "app5", "provider1",
+ mUserHandle);
+ // App4's widget eligible and not on workspace.
+ AppTarget widget2 = new AppTarget(new AppTargetId("app4"), "app4", "provider2",
+ mUserHandle);
+
+ mCallback.mRecommendedWidgets = null;
+ mModelHelper.getModel().enqueueModelUpdateTask(
+ newWidgetsPredicationTask(List.of(widget1, widget2)));
+ runOnExecutorSync(MAIN_EXECUTOR, () -> {
+ });
+
+ List<PendingAddWidgetInfo> recommendedWidgets = mCallback.mRecommendedWidgets.items
+ .stream()
+ .map(itemInfo -> (PendingAddWidgetInfo) itemInfo)
+ .collect(Collectors.toList());
+ assertThat(recommendedWidgets).hasSize(2);
+ List<ComponentName> componentNames = recommendedWidgets.stream().map(
+ w -> w.componentName).toList();
+ assertThat(componentNames).containsExactly(
+ // Locally added, not on workspace, eligible app per filter
+ mApp2Provider1.provider,
+ // From prediction service, not on workspace, eligible app per filter
+ mApp4Provider2.provider);
+ });
+ }
+
private void assertWidgetInfo(
LauncherAppWidgetProviderInfo actual, AppWidgetProviderInfo expected) {
assertThat(actual.provider).isEqualTo(expected.provider);
diff --git a/quickstep/tests/src/com/android/launcher3/taskbar/TaskbarRecentAppsControllerTest.kt b/quickstep/tests/src/com/android/launcher3/taskbar/TaskbarRecentAppsControllerTest.kt
index b67bc5a..066ddc0 100644
--- a/quickstep/tests/src/com/android/launcher3/taskbar/TaskbarRecentAppsControllerTest.kt
+++ b/quickstep/tests/src/com/android/launcher3/taskbar/TaskbarRecentAppsControllerTest.kt
@@ -26,11 +26,13 @@
import android.platform.test.rule.TestWatcher
import android.testing.AndroidTestingRunner
import com.android.internal.R
+import com.android.launcher3.BubbleTextView.RunningAppState
import com.android.launcher3.LauncherSettings.Favorites.CONTAINER_HOTSEAT
import com.android.launcher3.LauncherSettings.Favorites.CONTAINER_HOTSEAT_PREDICTION
import com.android.launcher3.model.data.AppInfo
import com.android.launcher3.model.data.ItemInfo
import com.android.launcher3.model.data.TaskItemInfo
+import com.android.launcher3.model.data.WorkspaceItemInfo
import com.android.quickstep.RecentsModel
import com.android.quickstep.RecentsModel.RecentTasksChangedListener
import com.android.quickstep.TaskIconCache
@@ -77,7 +79,9 @@
private var taskListChangeId: Int = 1
private lateinit var recentAppsController: TaskbarRecentAppsController
- private lateinit var userHandle: UserHandle
+ private lateinit var myUserHandle: UserHandle
+ private val USER_HANDLE_1 = UserHandle.of(1)
+ private val USER_HANDLE_2 = UserHandle.of(2)
private var canShowRunningAndRecentAppsAtInit = true
private var recentTasksChangedListener: RecentTasksChangedListener? = null
@@ -85,7 +89,7 @@
@Before
fun setUp() {
super.setup()
- userHandle = Process.myUserHandle()
+ myUserHandle = Process.myUserHandle()
// Set desktop mode supported
whenever(mockContext.getResources()).thenReturn(mockResources)
@@ -148,6 +152,115 @@
}
@Test
+ fun getDesktopItemState_nullItemInfo_returnsNotRunning() {
+ setInDesktopMode(true)
+ assertThat(recentAppsController.getDesktopItemState(/* itemInfo= */ null))
+ .isEqualTo(RunningAppState.NOT_RUNNING)
+ }
+
+ @Test
+ fun getDesktopItemState_noItemPackage_returnsNotRunning() {
+ setInDesktopMode(true)
+ assertThat(recentAppsController.getDesktopItemState(ItemInfo()))
+ .isEqualTo(RunningAppState.NOT_RUNNING)
+ }
+
+ @Test
+ fun getDesktopItemState_noMatchingTasks_returnsNotRunning() {
+ setInDesktopMode(true)
+ val itemInfo = createItemInfo("package")
+ assertThat(recentAppsController.getDesktopItemState(itemInfo))
+ .isEqualTo(RunningAppState.NOT_RUNNING)
+ }
+
+ @Test
+ fun getDesktopItemState_matchingVisibleTask_returnsVisible() {
+ setInDesktopMode(true)
+ val visibleTask = createTask(id = 1, "visiblePackage", isVisible = true)
+ updateRecentTasks(runningTasks = listOf(visibleTask), recentTaskPackages = emptyList())
+ val itemInfo = createItemInfo("visiblePackage")
+
+ assertThat(recentAppsController.getDesktopItemState(itemInfo))
+ .isEqualTo(RunningAppState.RUNNING)
+ }
+
+ @Test
+ fun getDesktopItemState_matchingMinimizedTask_returnsMinimized() {
+ setInDesktopMode(true)
+ val minimizedTask = createTask(id = 1, "minimizedPackage", isVisible = false)
+ updateRecentTasks(runningTasks = listOf(minimizedTask), recentTaskPackages = emptyList())
+ val itemInfo = createItemInfo("minimizedPackage")
+
+ assertThat(recentAppsController.getDesktopItemState(itemInfo))
+ .isEqualTo(RunningAppState.MINIMIZED)
+ }
+
+ @Test
+ fun getDesktopItemState_matchingMinimizedAndRunningTask_returnsVisible() {
+ setInDesktopMode(true)
+ updateRecentTasks(
+ runningTasks =
+ listOf(
+ createTask(id = 1, "package", isVisible = false),
+ createTask(id = 2, "package", isVisible = true),
+ ),
+ recentTaskPackages = emptyList(),
+ )
+ val itemInfo = createItemInfo("package")
+
+ assertThat(recentAppsController.getDesktopItemState(itemInfo))
+ .isEqualTo(RunningAppState.RUNNING)
+ }
+
+ @Test
+ fun getDesktopItemState_noMatchingUserId_returnsNotRunning() {
+ setInDesktopMode(true)
+ updateRecentTasks(
+ runningTasks =
+ listOf(
+ createTask(id = 1, "package", isVisible = false, USER_HANDLE_1),
+ createTask(id = 2, "package", isVisible = true, USER_HANDLE_1),
+ ),
+ recentTaskPackages = emptyList(),
+ )
+ val itemInfo = createItemInfo("package", USER_HANDLE_2)
+
+ assertThat(recentAppsController.getDesktopItemState(itemInfo))
+ .isEqualTo(RunningAppState.NOT_RUNNING)
+ }
+
+ @Test
+ fun getRunningAppState_taskNotRunningOrMinimized_returnsNotRunning() {
+ setInDesktopMode(true)
+ updateRecentTasks(runningTasks = emptyList(), recentTaskPackages = emptyList())
+
+ assertThat(recentAppsController.getRunningAppState(taskId = 1))
+ .isEqualTo(RunningAppState.NOT_RUNNING)
+ }
+
+ @Test
+ fun getRunningAppState_taskNotVisible_returnsMinimized() {
+ setInDesktopMode(true)
+ val task1 = createTask(id = 1, packageName = RUNNING_APP_PACKAGE_1, isVisible = false)
+ val task2 = createTask(id = 2, packageName = RUNNING_APP_PACKAGE_1, isVisible = true)
+ updateRecentTasks(runningTasks = listOf(task1, task2), recentTaskPackages = emptyList())
+
+ assertThat(recentAppsController.getRunningAppState(taskId = 1))
+ .isEqualTo(RunningAppState.MINIMIZED)
+ }
+
+ @Test
+ fun getRunningAppState_taskVisible_returnsRunning() {
+ setInDesktopMode(true)
+ val task1 = createTask(id = 1, packageName = RUNNING_APP_PACKAGE_1, isVisible = false)
+ val task2 = createTask(id = 2, packageName = RUNNING_APP_PACKAGE_1, isVisible = true)
+ updateRecentTasks(runningTasks = listOf(task1, task2), recentTaskPackages = emptyList())
+
+ assertThat(recentAppsController.getRunningAppState(taskId = 2))
+ .isEqualTo(RunningAppState.RUNNING)
+ }
+
+ @Test
fun updateHotseatItemInfos_cantShowRunning_inDesktopMode_returnsAllHotseatItems() {
recentAppsController.canShowRunningApps = false
setInDesktopMode(true)
@@ -782,7 +895,13 @@
private fun createTestAppInfo(
packageName: String = "testPackageName",
className: String = "testClassName",
- ) = AppInfo(ComponentName(packageName, className), className /* title */, userHandle, Intent())
+ ) =
+ AppInfo(
+ ComponentName(packageName, className),
+ className /* title */,
+ myUserHandle,
+ Intent(),
+ )
private fun createRecentTasksFromPackageNames(packageNames: List<String>): List<GroupTask> {
return packageNames.map { packageName ->
@@ -801,14 +920,19 @@
}
}
- private fun createTask(id: Int, packageName: String, isVisible: Boolean = true): Task {
+ private fun createTask(
+ id: Int,
+ packageName: String,
+ isVisible: Boolean = true,
+ localUserHandle: UserHandle? = null,
+ ): Task {
return Task(
Task.TaskKey(
id,
WINDOWING_MODE_FREEFORM,
Intent().apply { `package` = packageName },
ComponentName(packageName, "TestActivity"),
- userHandle.identifier,
+ localUserHandle?.identifier ?: myUserHandle.identifier,
0,
)
)
@@ -820,6 +944,16 @@
.thenReturn(inDesktopMode)
}
+ private fun createItemInfo(
+ packageName: String,
+ userHandle: UserHandle = myUserHandle,
+ ): ItemInfo {
+ val appInfo = AppInfo()
+ appInfo.intent = Intent().setComponent(ComponentName(packageName, "className"))
+ appInfo.user = userHandle
+ return WorkspaceItemInfo(appInfo)
+ }
+
private val GroupTask.packageNames: List<String>
get() = tasks.map { task -> task.key.packageName }
diff --git a/quickstep/tests/src/com/android/quickstep/AbstractQuickStepTest.java b/quickstep/tests/src/com/android/quickstep/AbstractQuickStepTest.java
index 44c23ba..6a7b6f8 100644
--- a/quickstep/tests/src/com/android/quickstep/AbstractQuickStepTest.java
+++ b/quickstep/tests/src/com/android/quickstep/AbstractQuickStepTest.java
@@ -26,6 +26,7 @@
import com.android.launcher3.tapl.LaunchedAppState;
import com.android.launcher3.ui.AbstractLauncherUiTest;
import com.android.launcher3.uioverrides.QuickstepLauncher;
+import com.android.launcher3.util.TestUtil;
import com.android.quickstep.views.RecentsView;
import org.junit.rules.RuleChain;
@@ -56,7 +57,7 @@
protected void assertTestActivityIsRunning(int activityNumber, String message) {
assertTrue(message, mDevice.wait(
Until.hasObject(By.pkg(getAppPackageName()).text("TestActivity" + activityNumber)),
- DEFAULT_UI_TIMEOUT));
+ TestUtil.DEFAULT_UI_TIMEOUT));
}
protected LaunchedAppState getAndAssertLaunchedApp() {
diff --git a/quickstep/tests/src/com/android/quickstep/TaplDigitalWellBeingToastTest.java b/quickstep/tests/src/com/android/quickstep/DigitalWellBeingToastTest.java
similarity index 73%
rename from quickstep/tests/src/com/android/quickstep/TaplDigitalWellBeingToastTest.java
rename to quickstep/tests/src/com/android/quickstep/DigitalWellBeingToastTest.java
index e981570..5b46dc8 100644
--- a/quickstep/tests/src/com/android/quickstep/TaplDigitalWellBeingToastTest.java
+++ b/quickstep/tests/src/com/android/quickstep/DigitalWellBeingToastTest.java
@@ -15,7 +15,9 @@
*/
package com.android.quickstep;
-import static androidx.test.InstrumentationRegistry.getInstrumentation;
+import static androidx.test.platform.app.InstrumentationRegistry.getInstrumentation;
+
+import static com.android.launcher3.util.TestUtil.resolveSystemAppInfo;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertFalse;
@@ -25,10 +27,13 @@
import android.app.usage.UsageStatsManager;
import android.content.Intent;
+import androidx.test.ext.junit.runners.AndroidJUnit4;
import androidx.test.filters.LargeTest;
-import androidx.test.runner.AndroidJUnit4;
import com.android.launcher3.Launcher;
+import com.android.launcher3.LauncherState;
+import com.android.launcher3.uioverrides.QuickstepLauncher;
+import com.android.launcher3.util.BaseLauncherActivityTest;
import com.android.quickstep.views.DigitalWellBeingToast;
import com.android.quickstep.views.RecentsView;
import com.android.quickstep.views.TaskContainer;
@@ -41,30 +46,31 @@
@LargeTest
@RunWith(AndroidJUnit4.class)
-public class TaplDigitalWellBeingToastTest extends AbstractQuickStepTest {
- private static final String CALCULATOR_PACKAGE =
- resolveSystemApp(Intent.CATEGORY_APP_CALCULATOR);
+public class DigitalWellBeingToastTest extends BaseLauncherActivityTest<QuickstepLauncher> {
+
+ public final String calculatorPackage =
+ resolveSystemAppInfo(Intent.CATEGORY_APP_CALCULATOR).packageName;
@Test
- public void testToast() throws Exception {
- startAppFast(CALCULATOR_PACKAGE);
+ public void testToast() {
+ startAppFast(calculatorPackage);
final UsageStatsManager usageStatsManager =
- mTargetContext.getSystemService(UsageStatsManager.class);
+ targetContext().getSystemService(UsageStatsManager.class);
final int observerId = 0;
try {
- final String[] packages = new String[]{CALCULATOR_PACKAGE};
+ final String[] packages = new String[]{calculatorPackage};
// Set time limit for app.
runWithShellPermission(() ->
usageStatsManager.registerAppUsageLimitObserver(observerId, packages,
Duration.ofSeconds(600), Duration.ofSeconds(300),
- PendingIntent.getActivity(mTargetContext, -1, new Intent()
- .setPackage(mTargetContext.getPackageName()),
+ PendingIntent.getActivity(targetContext(), -1, new Intent()
+ .setPackage(targetContext().getPackageName()),
PendingIntent.FLAG_MUTABLE)));
- mLauncher.goHome();
+ loadLauncherSync();
final DigitalWellBeingToast toast = getToast();
waitForLauncherCondition("Toast is not visible", launcher -> toast.getHasLimit());
@@ -74,7 +80,7 @@
runWithShellPermission(
() -> usageStatsManager.unregisterAppUsageLimitObserver(observerId));
- mLauncher.goHome();
+ goToState(LauncherState.NORMAL);
assertFalse("Toast is visible", getToast().getHasLimit());
} finally {
runWithShellPermission(
@@ -83,12 +89,12 @@
}
private DigitalWellBeingToast getToast() {
- mLauncher.getWorkspace().switchToOverview();
+ goToState(LauncherState.OVERVIEW);
final TaskView task = getOnceNotNull("No latest task", launcher -> getLatestTask(launcher));
return getFromLauncher(launcher -> {
TaskContainer taskContainer = task.getTaskContainers().get(0);
- assertTrue("Latest task is not Calculator", CALCULATOR_PACKAGE.equals(
+ assertTrue("Latest task is not Calculator", calculatorPackage.equals(
taskContainer.getTask().getTopComponent().getPackageName()));
return taskContainer.getDigitalWellBeingToast();
});
@@ -105,6 +111,5 @@
} finally {
getInstrumentation().getUiAutomation().dropShellPermissionIdentity();
}
-
}
}
diff --git a/quickstep/tests/src/com/android/quickstep/FallbackRecentsTest.java b/quickstep/tests/src/com/android/quickstep/FallbackRecentsTest.java
index 1f11c14..aa105f9 100644
--- a/quickstep/tests/src/com/android/quickstep/FallbackRecentsTest.java
+++ b/quickstep/tests/src/com/android/quickstep/FallbackRecentsTest.java
@@ -22,9 +22,7 @@
import static com.android.launcher3.tapl.LauncherInstrumentation.WAIT_TIME_MS;
import static com.android.launcher3.tapl.TestHelpers.getHomeIntentInPackage;
import static com.android.launcher3.tapl.TestHelpers.getLauncherInMyProcess;
-import static com.android.launcher3.ui.AbstractLauncherUiTest.DEFAULT_ACTIVITY_TIMEOUT;
import static com.android.launcher3.ui.AbstractLauncherUiTest.DEFAULT_BROADCAST_TIMEOUT_SECS;
-import static com.android.launcher3.ui.AbstractLauncherUiTest.DEFAULT_UI_TIMEOUT;
import static com.android.launcher3.ui.AbstractLauncherUiTest.resolveSystemApp;
import static com.android.launcher3.ui.AbstractLauncherUiTest.startAppFast;
import static com.android.launcher3.ui.AbstractLauncherUiTest.startTestActivity;
@@ -56,6 +54,7 @@
import com.android.launcher3.tapl.TestHelpers;
import com.android.launcher3.testcomponent.TestCommandReceiver;
import com.android.launcher3.ui.AbstractLauncherUiTest;
+import com.android.launcher3.util.TestUtil;
import com.android.launcher3.util.Wait;
import com.android.launcher3.util.rule.ExtendedLongPressTimeoutRule;
import com.android.launcher3.util.rule.FailureWatcher;
@@ -214,7 +213,7 @@
}
result[0] = f.apply(activity);
return true;
- }).get(), DEFAULT_UI_TIMEOUT, mLauncher);
+ }).get(), mLauncher);
return (T) result[0];
}
@@ -244,7 +243,7 @@
Wait.atMost("Recents activity didn't stop",
() -> getFromRecents(recents -> !recents.isStarted()),
- DEFAULT_UI_TIMEOUT, mLauncher);
+ mLauncher);
}
@Test
@@ -254,7 +253,8 @@
startTestActivity(2);
waitForRecentsActivityStop();
Wait.atMost("Expected three apps in the task list",
- () -> mLauncher.getRecentTasks().size() >= 3, DEFAULT_ACTIVITY_TIMEOUT, mLauncher);
+ () -> mLauncher.getRecentTasks().size() >= 3,
+ mLauncher);
checkTestLauncher();
BaseOverview overview = mLauncher.getLaunchedAppState().switchToOverview();
@@ -282,7 +282,7 @@
assertNotNull("OverviewTask.open returned null", task.open());
assertTrue("Test activity didn't open from Overview", TestHelpers.wait(Until.hasObject(
By.pkg(getAppPackageName()).text("TestActivity2")),
- DEFAULT_UI_TIMEOUT));
+ TestUtil.DEFAULT_UI_TIMEOUT));
// Test dismissing a task.
diff --git a/quickstep/tests/src/com/android/quickstep/NavigationModeSwitchRule.java b/quickstep/tests/src/com/android/quickstep/NavigationModeSwitchRule.java
index 4459ed6..77f4c05 100644
--- a/quickstep/tests/src/com/android/quickstep/NavigationModeSwitchRule.java
+++ b/quickstep/tests/src/com/android/quickstep/NavigationModeSwitchRule.java
@@ -57,8 +57,6 @@
static final String TAG = "QuickStepOnOffRule";
- public static final int WAIT_TIME_MS = 10000;
-
public enum Mode {
THREE_BUTTON, ZERO_BUTTON, ALL
}
@@ -179,12 +177,13 @@
}
Wait.atMost("Couldn't switch to " + overlayPackage,
- () -> launcher.getNavigationModel() == expectedMode, WAIT_TIME_MS, launcher);
+ () -> launcher.getNavigationModel() == expectedMode,
+ launcher);
Wait.atMost(() -> "Switching nav mode: "
+ launcher.getNavigationModeMismatchError(false),
() -> launcher.getNavigationModeMismatchError(false) == null,
- WAIT_TIME_MS, launcher);
+ launcher);
AbstractLauncherUiTest.checkDetectedLeaks(launcher, false);
return true;
}
diff --git a/quickstep/tests/src/com/android/quickstep/RecentTasksListTest.java b/quickstep/tests/src/com/android/quickstep/RecentTasksListTest.java
index 244b897..b3c486c 100644
--- a/quickstep/tests/src/com/android/quickstep/RecentTasksListTest.java
+++ b/quickstep/tests/src/com/android/quickstep/RecentTasksListTest.java
@@ -28,7 +28,9 @@
import static org.mockito.Mockito.when;
import android.app.ActivityManager;
+import android.app.ActivityManager.RecentTaskInfo;
import android.app.KeyguardManager;
+import android.app.TaskInfo;
import android.content.Context;
import android.content.res.Resources;
@@ -39,7 +41,7 @@
import com.android.quickstep.util.GroupTask;
import com.android.quickstep.views.TaskViewType;
import com.android.systemui.shared.recents.model.Task;
-import com.android.wm.shell.shared.GroupedRecentTaskInfo;
+import com.android.wm.shell.shared.GroupedTaskInfo;
import org.junit.Before;
import org.junit.Test;
@@ -91,8 +93,8 @@
@Test
public void loadTasksInBackground_onlyKeys_noValidTaskDescription() throws Exception {
- GroupedRecentTaskInfo recentTaskInfos = GroupedRecentTaskInfo.forSplitTasks(
- new ActivityManager.RecentTaskInfo(), new ActivityManager.RecentTaskInfo(), null);
+ GroupedTaskInfo recentTaskInfos = GroupedTaskInfo.forSplitTasks(
+ new RecentTaskInfo(), new RecentTaskInfo(), null);
when(mSystemUiProxy.getRecentTasks(anyInt(), anyInt()))
.thenReturn(new ArrayList<>(Collections.singletonList(recentTaskInfos)));
@@ -119,12 +121,11 @@
@Test
public void loadTasksInBackground_moreThanKeys_hasValidTaskDescription() throws Exception {
String taskDescription = "Wheeee!";
- ActivityManager.RecentTaskInfo task1 = new ActivityManager.RecentTaskInfo();
+ RecentTaskInfo task1 = new RecentTaskInfo();
task1.taskDescription = new ActivityManager.TaskDescription(taskDescription);
- ActivityManager.RecentTaskInfo task2 = new ActivityManager.RecentTaskInfo();
+ RecentTaskInfo task2 = new RecentTaskInfo();
task2.taskDescription = new ActivityManager.TaskDescription();
- GroupedRecentTaskInfo recentTaskInfos = GroupedRecentTaskInfo.forSplitTasks(task1, task2,
- null);
+ GroupedTaskInfo recentTaskInfos = GroupedTaskInfo.forSplitTasks(task1, task2, null);
when(mSystemUiProxy.getRecentTasks(anyInt(), anyInt()))
.thenReturn(new ArrayList<>(Collections.singletonList(recentTaskInfos)));
@@ -138,11 +139,11 @@
@Test
public void loadTasksInBackground_freeformTask_createsDesktopTask() throws Exception {
- ActivityManager.RecentTaskInfo[] tasks = {
+ List<TaskInfo> tasks = Arrays.asList(
createRecentTaskInfo(1 /* taskId */),
createRecentTaskInfo(4 /* taskId */),
- createRecentTaskInfo(5 /* taskId */)};
- GroupedRecentTaskInfo recentTaskInfos = GroupedRecentTaskInfo.forFreeformTasks(
+ createRecentTaskInfo(5 /* taskId */));
+ GroupedTaskInfo recentTaskInfos = GroupedTaskInfo.forFreeformTasks(
tasks, Collections.emptySet() /* minimizedTaskIds */);
when(mSystemUiProxy.getRecentTasks(anyInt(), anyInt()))
.thenReturn(new ArrayList<>(Collections.singletonList(recentTaskInfos)));
@@ -162,14 +163,13 @@
@Test
public void loadTasksInBackground_freeformTask_onlyMinimizedTasks_doesNotCreateDesktopTask()
throws Exception {
- ActivityManager.RecentTaskInfo[] tasks = {
+ List<TaskInfo> tasks = Arrays.asList(
createRecentTaskInfo(1 /* taskId */),
createRecentTaskInfo(4 /* taskId */),
- createRecentTaskInfo(5 /* taskId */)};
+ createRecentTaskInfo(5 /* taskId */));
Set<Integer> minimizedTaskIds =
Arrays.stream(new Integer[]{1, 4, 5}).collect(Collectors.toSet());
- GroupedRecentTaskInfo recentTaskInfos =
- GroupedRecentTaskInfo.forFreeformTasks(tasks, minimizedTaskIds);
+ GroupedTaskInfo recentTaskInfos = GroupedTaskInfo.forFreeformTasks(tasks, minimizedTaskIds);
when(mSystemUiProxy.getRecentTasks(anyInt(), anyInt()))
.thenReturn(new ArrayList<>(Collections.singletonList(recentTaskInfos)));
@@ -179,8 +179,8 @@
assertEquals(0, taskList.size());
}
- private ActivityManager.RecentTaskInfo createRecentTaskInfo(int taskId) {
- ActivityManager.RecentTaskInfo recentTaskInfo = new ActivityManager.RecentTaskInfo();
+ private TaskInfo createRecentTaskInfo(int taskId) {
+ RecentTaskInfo recentTaskInfo = new RecentTaskInfo();
recentTaskInfo.taskId = taskId;
return recentTaskInfo;
}
diff --git a/quickstep/tests/src/com/android/quickstep/TaplTestsOverviewDesktop.kt b/quickstep/tests/src/com/android/quickstep/TaplTestsOverviewDesktop.kt
index 2a8afbf..f58c84e 100644
--- a/quickstep/tests/src/com/android/quickstep/TaplTestsOverviewDesktop.kt
+++ b/quickstep/tests/src/com/android/quickstep/TaplTestsOverviewDesktop.kt
@@ -26,6 +26,7 @@
import com.android.launcher3.ui.AbstractLauncherUiTest
import com.android.launcher3.ui.PortraitLandscapeRunner.PortraitLandscape
import com.android.launcher3.uioverrides.QuickstepLauncher
+import com.android.launcher3.util.TestUtil
import com.google.common.truth.Truth.assertWithMessage
import org.junit.Before
import org.junit.Test
@@ -104,28 +105,36 @@
@Test
@PortraitLandscape
- fun dismissFocusedTask_thenDesktopTask_thenFocusedTaskIsCentered() {
+ fun dismissTasks_whenDesktopTask_IsInTheCenter() {
// Create extra activity to be DesktopTaskView
startTestActivity(TEST_ACTIVITY_EXTRA)
mLauncher.goHome().switchToOverview()
+
val desktop = moveTaskToDesktop(TEST_ACTIVITY_EXTRA)
+ var overview = desktop.switchToOverview()
- val overview = desktop.switchToOverview()
+ // Open focused task and go back to Overview to validate whether it has adjacent tasks in
+ // its both sides (grid task on left and desktop tasks at its right side)
+ val focusedTaskOpened = overview.getTestActivityTask(TEST_ACTIVITY_2).open()
- // Dismiss focused task
- val focusedTask1 = overview.getTestActivityTask(TEST_ACTIVITY_2)
- assertTaskContentDescription(focusedTask1, TEST_ACTIVITY_2)
- focusedTask1.dismiss()
-
- // Dismiss DesktopTaskView
+ // Fling to desktop task and dismiss the focused task to check repositioning of
+ // grid tasks.
+ overview = focusedTaskOpened.switchToOverview().apply { flingBackward() }
val desktopTask = overview.currentTask
assertWithMessage("The current task is not a Desktop.").that(desktopTask.isDesktop).isTrue()
+
+ // Get focused task (previously opened task) then dismiss this task
+ val focusedTaskInOverview = overview.getTestActivityTask(TEST_ACTIVITY_2)
+ assertTaskContentDescription(focusedTaskInOverview, TEST_ACTIVITY_2)
+ focusedTaskInOverview.dismiss()
+
+ // Dismiss DesktopTask to validate whether the new focused task will take its position
desktopTask.dismiss()
- // Dismiss focused task
- val focusedTask2 = overview.currentTask
- assertTaskContentDescription(focusedTask2, TEST_ACTIVITY_1)
- focusedTask2.dismiss()
+ // Dismiss last focused task
+ val lastFocusedTask = overview.currentTask
+ assertTaskContentDescription(lastFocusedTask, TEST_ACTIVITY_1)
+ lastFocusedTask.dismiss()
assertWithMessage("Still have tasks after dismissing all the tasks")
.that(mLauncher.workspace.switchToOverview().hasTasks())
@@ -164,7 +173,7 @@
.that(
mDevice.wait(
Until.hasObject(By.pkg(getAppPackageName()).text("TestActivity$index")),
- DEFAULT_UI_TIMEOUT,
+ TestUtil.DEFAULT_UI_TIMEOUT,
)
)
.isTrue()
diff --git a/quickstep/tests/src/com/android/quickstep/TaplTestsQuickstep.java b/quickstep/tests/src/com/android/quickstep/TaplTestsQuickstep.java
index 5ff2af7..f1fe2d2 100644
--- a/quickstep/tests/src/com/android/quickstep/TaplTestsQuickstep.java
+++ b/quickstep/tests/src/com/android/quickstep/TaplTestsQuickstep.java
@@ -47,6 +47,7 @@
import com.android.launcher3.tapl.SelectModeButtons;
import com.android.launcher3.tapl.Workspace;
import com.android.launcher3.ui.PortraitLandscapeRunner.PortraitLandscape;
+import com.android.launcher3.util.TestUtil;
import com.android.launcher3.util.Wait;
import com.android.launcher3.util.rule.ScreenRecordRule.ScreenRecord;
import com.android.launcher3.util.rule.TestStabilityRule;
@@ -145,7 +146,7 @@
assertNotNull("OverviewTask.open returned null", task.open());
assertTrue("Test activity didn't open from Overview", mDevice.wait(Until.hasObject(
By.pkg(getAppPackageName()).text("TestActivity2")),
- DEFAULT_UI_TIMEOUT));
+ TestUtil.DEFAULT_UI_TIMEOUT));
executeOnLauncher(launcher -> assertTrue(
"Launcher activity is the top activity; expecting another activity to be the top "
+ "one",
@@ -448,7 +449,7 @@
mDevice.wait(Until.hasObject(By.pkg(getAppPackageName()).text(
mLauncher.isGridOnlyOverviewEnabled() ? "TestActivity12"
: "TestActivity13")),
- DEFAULT_UI_TIMEOUT));
+ TestUtil.DEFAULT_UI_TIMEOUT));
// Scroll the task offscreen as it is now first
overview = mLauncher.goHome().switchToOverview();
@@ -563,7 +564,7 @@
mLauncher.getDevice().setOrientationLeft();
startTestActivity(7);
Wait.atMost("Device should not be in natural orientation",
- () -> !mDevice.isNaturalOrientation(), DEFAULT_UI_TIMEOUT, mLauncher);
+ () -> !mDevice.isNaturalOrientation(), mLauncher);
mLauncher.goHome();
} finally {
mLauncher.setExpectedRotationCheckEnabled(true);
diff --git a/res/drawable/bg_widgets_header_states_two_pane.xml b/res/drawable/bg_widgets_header_states_two_pane.xml
index 5f4b8c6..1ec41a9 100644
--- a/res/drawable/bg_widgets_header_states_two_pane.xml
+++ b/res/drawable/bg_widgets_header_states_two_pane.xml
@@ -14,18 +14,16 @@
limitations under the License.
-->
<selector xmlns:android="http://schemas.android.com/apk/res/android">
-
- <item android:state_expanded="true">
- <shape android:shape="rectangle">
- <solid android:color="?attr/widgetPickerHeaderBackgroundColor" />
- <corners android:radius="@dimen/widget_list_top_bottom_corner_radius" />
- </shape>
+ <item android:state_expanded="true" android:state_focused="false">
+ <ripple android:color="@color/accent_ripple_color">
+ <item android:drawable="@drawable/bg_widgets_header_two_pane_expanded_unfocused" />
+ </ripple>
</item>
-
- <item android:state_expanded="false">
- <shape android:shape="rectangle">
- <solid android:color="@android:color/transparent" />
- <corners android:radius="@dimen/widget_list_top_bottom_corner_radius" />
- </shape>
+ <item android:state_expanded="false" android:state_focused="false">
+ <ripple android:color="@color/accent_ripple_color">
+ <item android:drawable="@drawable/bg_widgets_header_two_pane_unexpanded_unfocused" />
+ </ripple>
</item>
+ <item android:drawable="@drawable/bg_widgets_header_two_pane_expanded_focused" android:state_expanded="true" android:state_focused="true" />
+ <item android:drawable="@drawable/bg_widgets_header_two_pane_unexpanded_focused" android:state_expanded="false" android:state_focused="true" />
</selector>
diff --git a/res/drawable/bg_widgets_header_two_pane.xml b/res/drawable/bg_widgets_header_two_pane.xml
index ca3feef..e237002 100644
--- a/res/drawable/bg_widgets_header_two_pane.xml
+++ b/res/drawable/bg_widgets_header_two_pane.xml
@@ -14,13 +14,10 @@
limitations under the License.
-->
<inset xmlns:android="http://schemas.android.com/apk/res/android"
- android:insetTop="@dimen/widget_list_entry_spacing" >
- <ripple
- android:color="@color/accent_ripple_color"
- android:paddingTop="@dimen/widget_list_header_view_vertical_padding"
- android:paddingBottom="@dimen/widget_list_header_view_vertical_padding" >
- <item android:id="@android:id/mask"
- android:drawable="@drawable/bg_widgets_header_states_two_pane" />
+ android:insetTop="@dimen/widget_list_entry_spacing">
+ <layer-list
+ android:paddingBottom="@dimen/widget_list_header_view_vertical_padding"
+ android:paddingTop="@dimen/widget_list_header_view_vertical_padding">
<item android:drawable="@drawable/bg_widgets_header_states_two_pane" />
- </ripple>
-</inset>
+ </layer-list>
+</inset>
\ No newline at end of file
diff --git a/res/drawable/bg_widgets_header_two_pane_expanded_focused.xml b/res/drawable/bg_widgets_header_two_pane_expanded_focused.xml
new file mode 100644
index 0000000..0ee3d14
--- /dev/null
+++ b/res/drawable/bg_widgets_header_two_pane_expanded_focused.xml
@@ -0,0 +1,38 @@
+<?xml version="1.0" encoding="utf-8"?><!--
+ ~ Copyright (C) 2024 The Android Open Source Project
+ ~
+ ~ Licensed under the Apache License, Version 2.0 (the "License");
+ ~ you may not use this file except in compliance with the License.
+ ~ You may obtain a copy of the License at
+ ~
+ ~ http://www.apache.org/licenses/LICENSE-2.0
+ ~
+ ~ Unless required by applicable law or agreed to in writing, software
+ ~ distributed under the License is distributed on an "AS IS" BASIS,
+ ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ ~ See the License for the specific language governing permissions and
+ ~ limitations under the License.
+ -->
+<layer-list xmlns:android="http://schemas.android.com/apk/res/android">
+ <!-- Draw the focus ring -->
+ <item>
+ <shape>
+ <corners android:radius="@dimen/widget_focus_ring_corner_radius" />
+ <stroke
+ android:width="@dimen/widget_header_focus_ring_width"
+ android:color="?attr/widgetPickerTabBackgroundSelected" />
+ </shape>
+ </item>
+
+ <!-- Draw the background with padding to make it spaced within the focus ring. -->
+ <item
+ android:bottom="@dimen/widget_header_background_border"
+ android:end="@dimen/widget_header_background_border"
+ android:start="@dimen/widget_header_background_border"
+ android:top="@dimen/widget_header_background_border">
+ <shape android:shape="rectangle">
+ <corners android:radius="@dimen/widget_list_top_bottom_corner_radius" />
+ <solid android:color="?attr/widgetPickerHeaderBackgroundColor" />
+ </shape>
+ </item>
+</layer-list>
\ No newline at end of file
diff --git a/res/drawable/bg_widgets_header_two_pane_expanded_unfocused.xml b/res/drawable/bg_widgets_header_two_pane_expanded_unfocused.xml
new file mode 100644
index 0000000..9028ebe
--- /dev/null
+++ b/res/drawable/bg_widgets_header_two_pane_expanded_unfocused.xml
@@ -0,0 +1,25 @@
+<?xml version="1.0" encoding="utf-8"?><!--
+ ~ Copyright (C) 2024 The Android Open Source Project
+ ~
+ ~ Licensed under the Apache License, Version 2.0 (the "License");
+ ~ you may not use this file except in compliance with the License.
+ ~ You may obtain a copy of the License at
+ ~
+ ~ http://www.apache.org/licenses/LICENSE-2.0
+ ~
+ ~ Unless required by applicable law or agreed to in writing, software
+ ~ distributed under the License is distributed on an "AS IS" BASIS,
+ ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ ~ See the License for the specific language governing permissions and
+ ~ limitations under the License.
+ -->
+<layer-list xmlns:android="http://schemas.android.com/apk/res/android"
+ android:paddingBottom="@dimen/widget_list_header_view_vertical_padding"
+ android:paddingTop="@dimen/widget_list_header_view_vertical_padding">
+ <item>
+ <shape android:shape="rectangle">
+ <corners android:radius="@dimen/widget_list_top_bottom_corner_radius" />
+ <solid android:color="?attr/widgetPickerHeaderBackgroundColor" />
+ </shape>
+ </item>
+</layer-list>
\ No newline at end of file
diff --git a/res/drawable/bg_widgets_header_two_pane_unexpanded_focused.xml b/res/drawable/bg_widgets_header_two_pane_unexpanded_focused.xml
new file mode 100644
index 0000000..12dc907
--- /dev/null
+++ b/res/drawable/bg_widgets_header_two_pane_unexpanded_focused.xml
@@ -0,0 +1,27 @@
+<?xml version="1.0" encoding="utf-8"?><!--
+ ~ Copyright (C) 2024 The Android Open Source Project
+ ~
+ ~ Licensed under the Apache License, Version 2.0 (the "License");
+ ~ you may not use this file except in compliance with the License.
+ ~ You may obtain a copy of the License at
+ ~
+ ~ http://www.apache.org/licenses/LICENSE-2.0
+ ~
+ ~ Unless required by applicable law or agreed to in writing, software
+ ~ distributed under the License is distributed on an "AS IS" BASIS,
+ ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ ~ See the License for the specific language governing permissions and
+ ~ limitations under the License.
+ -->
+<layer-list xmlns:android="http://schemas.android.com/apk/res/android">
+ <!-- Draw the focus ring and a transparent background -->
+ <item>
+ <shape>
+ <corners android:radius="@dimen/widget_focus_ring_corner_radius" />
+ <solid android:color="@android:color/transparent" />
+ <stroke
+ android:width="@dimen/widget_header_focus_ring_width"
+ android:color="?attr/widgetPickerTabBackgroundSelected" />
+ </shape>
+ </item>
+</layer-list>
\ No newline at end of file
diff --git a/res/drawable/bg_widgets_header_two_pane_unexpanded_unfocused.xml b/res/drawable/bg_widgets_header_two_pane_unexpanded_unfocused.xml
new file mode 100644
index 0000000..ba26f9f
--- /dev/null
+++ b/res/drawable/bg_widgets_header_two_pane_unexpanded_unfocused.xml
@@ -0,0 +1,23 @@
+<?xml version="1.0" encoding="utf-8"?><!--
+ ~ Copyright (C) 2024 The Android Open Source Project
+ ~
+ ~ Licensed under the Apache License, Version 2.0 (the "License");
+ ~ you may not use this file except in compliance with the License.
+ ~ You may obtain a copy of the License at
+ ~
+ ~ http://www.apache.org/licenses/LICENSE-2.0
+ ~
+ ~ Unless required by applicable law or agreed to in writing, software
+ ~ distributed under the License is distributed on an "AS IS" BASIS,
+ ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ ~ See the License for the specific language governing permissions and
+ ~ limitations under the License.
+ -->
+<layer-list xmlns:android="http://schemas.android.com/apk/res/android">
+ <item>
+ <shape android:shape="rectangle">
+ <corners android:radius="@dimen/widget_list_top_bottom_corner_radius" />
+ <solid android:color="@android:color/transparent" />
+ </shape>
+ </item>
+</layer-list>
\ No newline at end of file
diff --git a/res/drawable/ic_corp_off.xml b/res/drawable/ic_corp_off.xml
index 117258e..d4bb2f3 100644
--- a/res/drawable/ic_corp_off.xml
+++ b/res/drawable/ic_corp_off.xml
@@ -16,9 +16,9 @@
android:width="24dp"
android:height="24dp"
android:viewportWidth="24"
- android:viewportHeight="24"
- android:tint="?android:attr/textColorHint">
+ android:viewportHeight="24">
<path
- android:fillColor="@android:color/white"
- android:pathData="M20,6h-4L16,4c0,-1.11 -0.89,-2 -2,-2h-4c-1.11,0 -2,0.89 -2,2v1.17L10.83,8L20,8v9.17l1.98,1.98c0,-0.05 0.02,-0.1 0.02,-0.16L22,8c0,-1.11 -0.89,-2 -2,-2zM14,6h-4L10,4h4v2zM19,19L8,8 6,6 2.81,2.81 1.39,4.22 3.3,6.13C2.54,6.41 2.01,7.14 2.01,8L2,19c0,1.11 0.89,2 2,2h14.17l1.61,1.61 1.41,-1.41 -0.37,-0.37L19,19zM4,19L4,8h1.17l11,11L4,19z" />
-</vector>
\ No newline at end of file
+ android:pathData="M16,6H20C21.11,6 22,6.89 22,8V18.99C22,19.021 21.994,19.05 21.989,19.077C21.984,19.102 21.98,19.126 21.98,19.15L20,17.17V8H10.83L8,5.17V4C8,2.89 8.89,2 10,2H14C15.11,2 16,2.89 16,4V6ZM10,6H14V4H10V6ZM19,19L8,8L6,6L2.81,2.81L1.39,4.22L3.3,6.13C2.54,6.41 2.01,7.14 2.01,8L2,19C2,20.11 2.89,21 4,21H18.17L19.78,22.61L21.19,21.2L20.82,20.83L19,19ZM4,8V19H16.17L5.17,8H4Z"
+ android:fillColor="?attr/materialColorOnPrimary"
+ android:fillType="evenOdd"/>
+</vector>
diff --git a/res/drawable/ic_more_horiz_24.xml b/res/drawable/ic_more_horiz_24.xml
new file mode 100644
index 0000000..d46827c
--- /dev/null
+++ b/res/drawable/ic_more_horiz_24.xml
@@ -0,0 +1,26 @@
+<!--
+ ~ Copyright (C) 2024 The Android Open Source Project
+ ~
+ ~ Licensed under the Apache License, Version 2.0 (the "License");
+ ~ you may not use this file except in compliance with the License.
+ ~ You may obtain a copy of the License at
+ ~
+ ~ http://www.apache.org/licenses/LICENSE-2.0
+ ~
+ ~ Unless required by applicable law or agreed to in writing, software
+ ~ distributed under the License is distributed on an "AS IS" BASIS,
+ ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ ~ See the License for the specific language governing permissions and
+ ~ limitations under the License.
+ -->
+
+<vector xmlns:android="http://schemas.android.com/apk/res/android"
+ android:width="24dp"
+ android:height="24dp"
+ android:tint="#000000"
+ android:viewportHeight="24"
+ android:viewportWidth="24">
+ <path
+ android:fillColor="@android:color/white"
+ android:pathData="M6,10c-1.1,0 -2,0.9 -2,2s0.9,2 2,2 2,-0.9 2,-2 -0.9,-2 -2,-2zM18,10c-1.1,0 -2,0.9 -2,2s0.9,2 2,2 2,-0.9 2,-2 -0.9,-2 -2,-2zM12,10c-1.1,0 -2,0.9 -2,2s0.9,2 2,2 2,-0.9 2,-2 -0.9,-2 -2,-2z" />
+</vector>
diff --git a/res/drawable/ic_schedule.xml b/res/drawable/ic_schedule.xml
new file mode 100644
index 0000000..3eeb6a2
--- /dev/null
+++ b/res/drawable/ic_schedule.xml
@@ -0,0 +1,25 @@
+<?xml version="1.0" encoding="utf-8"?><!--
+ ~ Copyright (C) 2024 The Android Open Source Project
+ ~
+ ~ Licensed under the Apache License, Version 2.0 (the "License");
+ ~ you may not use this file except in compliance with the License.
+ ~ You may obtain a copy of the License at
+ ~
+ ~ http://www.apache.org/licenses/LICENSE-2.0
+ ~
+ ~ Unless required by applicable law or agreed to in writing, software
+ ~ distributed under the License is distributed on an "AS IS" BASIS,
+ ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ ~ See the License for the specific language governing permissions and
+ ~ limitations under the License.
+ -->
+<vector xmlns:android="http://schemas.android.com/apk/res/android"
+ android:width="24dp"
+ android:height="24dp"
+ android:viewportWidth="960"
+ android:viewportHeight="960"
+ android:tint="?attr/colorControlNormal">
+ <path
+ android:fillColor="?attr/materialColorOnPrimary"
+ android:pathData="M612,668L668,612L520,464L520,280L440,280L440,496L612,668ZM480,880Q397,880 324,848.5Q251,817 197,763Q143,709 111.5,636Q80,563 80,480Q80,397 111.5,324Q143,251 197,197Q251,143 324,111.5Q397,80 480,80Q563,80 636,111.5Q709,143 763,197Q817,251 848.5,324Q880,397 880,480Q880,563 848.5,636Q817,709 763,763Q709,817 636,848.5Q563,880 480,880Z"/>
+</vector>
diff --git a/res/drawable/widgets_list_expand_button_background.xml b/res/drawable/widgets_list_expand_button_background.xml
new file mode 100644
index 0000000..068b26d
--- /dev/null
+++ b/res/drawable/widgets_list_expand_button_background.xml
@@ -0,0 +1,25 @@
+<?xml version="1.0" encoding="utf-8"?><!--
+ ~ Copyright (C) 2024 The Android Open Source Project
+ ~
+ ~ Licensed under the Apache License, Version 2.0 (the "License");
+ ~ you may not use this file except in compliance with the License.
+ ~ You may obtain a copy of the License at
+ ~
+ ~ http://www.apache.org/licenses/LICENSE-2.0
+ ~
+ ~ Unless required by applicable law or agreed to in writing, software
+ ~ distributed under the License is distributed on an "AS IS" BASIS,
+ ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ ~ See the License for the specific language governing permissions and
+ ~ limitations under the License.
+ -->
+<inset xmlns:android="http://schemas.android.com/apk/res/android">
+ <ripple android:color="?android:attr/colorControlHighlight">
+ <item>
+ <shape android:shape="rectangle">
+ <corners android:radius="50dp" />
+ <solid android:color="?attr/widgetPickerExpandButtonBackgroundColor" />
+ </shape>
+ </item>
+ </ripple>
+</inset>
\ No newline at end of file
diff --git a/res/drawable/work_mode_fab_background.xml b/res/drawable/work_mode_fab_background.xml
index fd948d1..5bad965 100644
--- a/res/drawable/work_mode_fab_background.xml
+++ b/res/drawable/work_mode_fab_background.xml
@@ -18,7 +18,7 @@
<item>
<shape android:shape="rectangle">
<corners android:radius="@dimen/work_fab_radius" />
- <solid android:color="@color/work_fab_bg_color" />
+ <solid android:color="?attr/materialColorPrimary" />
<padding
android:left="@dimen/work_mode_fab_background_horizontal_padding"
android:right="@dimen/work_mode_fab_background_horizontal_padding"/>
diff --git a/res/drawable/work_scheduler_background.xml b/res/drawable/work_scheduler_background.xml
new file mode 100644
index 0000000..6bbf029
--- /dev/null
+++ b/res/drawable/work_scheduler_background.xml
@@ -0,0 +1,26 @@
+<?xml version="1.0" encoding="utf-8"?><!--
+ ~ Copyright (C) 2024 The Android Open Source Project
+ ~
+ ~ Licensed under the Apache License, Version 2.0 (the "License");
+ ~ you may not use this file except in compliance with the License.
+ ~ You may obtain a copy of the License at
+ ~
+ ~ http://www.apache.org/licenses/LICENSE-2.0
+ ~
+ ~ Unless required by applicable law or agreed to in writing, software
+ ~ distributed under the License is distributed on an "AS IS" BASIS,
+ ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ ~ See the License for the specific language governing permissions and
+ ~ limitations under the License.
+ -->
+<ripple xmlns:android="http://schemas.android.com/apk/res/android"
+ android:color="@color/accent_ripple_color">
+ <item>
+ <shape android:shape="rectangle">
+ <corners android:radius="@dimen/work_fab_radius" />
+ <solid android:color="?attr/materialColorPrimary" />
+ <padding
+ android:padding="@dimen/work_scheduler_background_padding" />
+ </shape>
+ </item>
+</ripple>
\ No newline at end of file
diff --git a/res/layout/widgets_list_expand_button.xml b/res/layout/widgets_list_expand_button.xml
new file mode 100644
index 0000000..17c19ac
--- /dev/null
+++ b/res/layout/widgets_list_expand_button.xml
@@ -0,0 +1,33 @@
+<?xml version="1.0" encoding="utf-8"?><!--
+ ~ Copyright (C) 2024 The Android Open Source Project
+ ~
+ ~ Licensed under the Apache License, Version 2.0 (the "License");
+ ~ you may not use this file except in compliance with the License.
+ ~ You may obtain a copy of the License at
+ ~
+ ~ http://www.apache.org/licenses/LICENSE-2.0
+ ~
+ ~ Unless required by applicable law or agreed to in writing, software
+ ~ distributed under the License is distributed on an "AS IS" BASIS,
+ ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ ~ See the License for the specific language governing permissions and
+ ~ limitations under the License.
+ -->
+
+<Button xmlns:android="http://schemas.android.com/apk/res/android"
+ style="@style/Button.Rounded.Colored"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:layout_marginTop="@dimen/widgets_list_expand_button_top_margin"
+ android:background="@drawable/widgets_list_expand_button_background"
+ android:drawablePadding="@dimen/widgets_list_expand_button_drawable_padding"
+ android:drawableStart="@drawable/ic_more_horiz_24"
+ android:drawableTint="?attr/widgetPickerExpandButtonTextColor"
+ android:maxLines="1"
+ android:minHeight="48dp"
+ android:paddingEnd="@dimen/widgets_list_expand_button_end_padding"
+ android:paddingStart="@dimen/widgets_list_expand_button_start_padding"
+ android:paddingVertical="@dimen/widgets_list_expand_button_vertical_padding"
+ android:text="@string/widgets_list_expand_button_label"
+ android:contentDescription="@string/widgets_list_expand_button_content_description"
+ android:textColor="?attr/widgetPickerExpandButtonTextColor" />
\ No newline at end of file
diff --git a/res/layout/widgets_two_pane_sheet.xml b/res/layout/widgets_two_pane_sheet.xml
index 8235875..5dc1b47 100644
--- a/res/layout/widgets_two_pane_sheet.xml
+++ b/res/layout/widgets_two_pane_sheet.xml
@@ -70,7 +70,7 @@
android:layout_height="match_parent"
android:clipChildren="false"
android:clipToPadding="false"
- android:paddingBottom="24dp"
+ android:paddingBottom="8dp"
android:layout_gravity="start"
android:layout_weight="0.33">
<TextView
@@ -84,14 +84,6 @@
android:layout_width="@dimen/fastscroll_width"
android:layout_height="match_parent"
android:layout_marginEnd="@dimen/fastscroll_end_margin" />
-
- <com.android.launcher3.widget.picker.WidgetsRecyclerView
- android:id="@+id/search_widgets_list_view"
- android:layout_width="match_parent"
- android:layout_height="wrap_content"
- android:clipToPadding="false"
- android:paddingHorizontal="@dimen/widget_list_horizontal_margin_two_pane"
- android:visibility="gone" />
</FrameLayout>
<FrameLayout
diff --git a/res/layout/widgets_two_pane_sheet_paged_view.xml b/res/layout/widgets_two_pane_sheet_paged_view.xml
index 33a50b0..0528d3b 100644
--- a/res/layout/widgets_two_pane_sheet_paged_view.xml
+++ b/res/layout/widgets_two_pane_sheet_paged_view.xml
@@ -143,5 +143,13 @@
android:clipToPadding="false" />
</com.android.launcher3.widget.picker.WidgetPagedView>
+
+ <com.android.launcher3.widget.picker.WidgetsRecyclerView
+ android:id="@+id/search_widgets_list_view"
+ android:layout_width="match_parent"
+ android:layout_height="match_parent"
+ android:clipToPadding="false"
+ android:paddingHorizontal="@dimen/widget_list_horizontal_margin_two_pane"
+ android:visibility="gone" />
</LinearLayout>
</merge>
diff --git a/res/layout/widgets_two_pane_sheet_recyclerview.xml b/res/layout/widgets_two_pane_sheet_recyclerview.xml
index 94f141b..45a9ac0 100644
--- a/res/layout/widgets_two_pane_sheet_recyclerview.xml
+++ b/res/layout/widgets_two_pane_sheet_recyclerview.xml
@@ -85,5 +85,13 @@
android:layout_height="match_parent"
android:layout_marginHorizontal="@dimen/widget_list_horizontal_margin_two_pane"
android:clipToPadding="false" />
+
+ <com.android.launcher3.widget.picker.WidgetsRecyclerView
+ android:id="@+id/search_widgets_list_view"
+ android:layout_width="match_parent"
+ android:layout_height="match_parent"
+ android:clipToPadding="false"
+ android:paddingHorizontal="@dimen/widget_list_horizontal_margin_two_pane"
+ android:visibility="gone" />
</LinearLayout>
</merge>
\ No newline at end of file
diff --git a/res/layout/work_mode_fab.xml b/res/layout/work_mode_fab.xml
index fc59e56..46f2d8a 100644
--- a/res/layout/work_mode_fab.xml
+++ b/res/layout/work_mode_fab.xml
@@ -12,11 +12,9 @@
See the License for the specific language governing permissions and
limitations under the License.
-->
-<com.android.launcher3.allapps.WorkModeSwitch
+<LinearLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/work_mode_toggle"
- android:layout_alignParentBottom="true"
- android:layout_alignParentEnd="true"
android:layout_height="@dimen/work_fab_height"
android:layout_width="wrap_content"
android:minHeight="@dimen/work_fab_height"
@@ -31,7 +29,6 @@
android:layout_marginVertical="@dimen/work_fab_icon_vertical_margin"
android:importantForAccessibility="no"
android:src="@drawable/ic_corp_off"
- android:tint="@color/work_fab_icon_color"
android:layout_marginStart="@dimen/work_fab_icon_start_margin_expanded"
android:scaleType="center"/>
<TextView
@@ -39,7 +36,7 @@
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:maxWidth="@dimen/work_fab_width"
- android:textColor="@color/work_fab_icon_color"
+ android:textColor="?attr/materialColorOnPrimary"
android:textSize="14sp"
android:includeFontPadding="false"
android:textDirection="locale"
@@ -48,4 +45,4 @@
android:layout_marginEnd="@dimen/work_fab_text_end_margin"
android:maxLines="1"
style="@style/TextHeadline"/>
-</com.android.launcher3.allapps.WorkModeSwitch>
+</LinearLayout>
diff --git a/res/layout/work_mode_utility_view.xml b/res/layout/work_mode_utility_view.xml
new file mode 100644
index 0000000..fc112ce
--- /dev/null
+++ b/res/layout/work_mode_utility_view.xml
@@ -0,0 +1,32 @@
+<!--
+ ~ 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.
+ -->
+<com.android.launcher3.allapps.WorkUtilityView xmlns:android="http://schemas.android.com/apk/res/android"
+ android:layout_height="wrap_content"
+ android:layout_width="wrap_content"
+ android:orientation="vertical"
+ android:layout_alignParentBottom="true"
+ android:layout_alignParentEnd="true">
+ <ImageButton
+ android:id="@+id/work_scheduler"
+ android:layout_width="@dimen/work_scheduler_size"
+ android:layout_height="@dimen/work_scheduler_size"
+ android:layout_marginBottom="@dimen/work_scheduler_bottom_margin"
+ android:contentDescription="@string/work_scheduler_button_content_description"
+ android:src="@drawable/ic_schedule"
+ android:layout_gravity="end"
+ android:background="@drawable/work_scheduler_background" />
+ <include layout="@layout/work_mode_fab" />
+</com.android.launcher3.allapps.WorkUtilityView>
diff --git a/res/values-af/strings.xml b/res/values-af/strings.xml
index e5c1b61..5181bb7 100644
--- a/res/values-af/strings.xml
+++ b/res/values-af/strings.xml
@@ -69,6 +69,12 @@
<string name="widget_category_note_taking" msgid="3469689394504266039">"Neem notas"</string>
<string name="widget_add_button_label" msgid="2761267068711937179">"Voeg by"</string>
<string name="widget_add_button_content_description" msgid="1810530016360039643">"Voeg <xliff:g id="WIDGET_NAME">%1$s</xliff:g>-legstuk by"</string>
+ <!-- no translation found for widgets_list_expand_button_label (7912016136574932622) -->
+ <skip />
+ <!-- no translation found for widgets_list_expand_button_content_description (4600513860973450888) -->
+ <skip />
+ <!-- no translation found for widgets_list_expanded (7374857868788557730) -->
+ <skip />
<string name="reconfigurable_widget_education_tip" msgid="6336962690888067057">"Tik om legstukinstellings te verander"</string>
<string name="widget_reconfigure_button_content_description" msgid="8811472721881205250">"Verander legstukinstellings"</string>
<string name="all_apps_search_bar_hint" msgid="1390553134053255246">"Deursoek programme"</string>
@@ -124,6 +130,10 @@
<string name="msg_disabled_by_admin" msgid="6898038085516271325">"Gedeaktiveer deur jou administrateur"</string>
<string name="allow_rotation_title" msgid="7222049633713050106">"Laat toe dat tuisskerm gedraai word"</string>
<string name="allow_rotation_desc" msgid="8662546029078692509">"Wanneer foon gedraai word"</string>
+ <!-- no translation found for landscape_mode_title (5138814555934843926) -->
+ <skip />
+ <!-- no translation found for landscape_mode_desc (7372569859592816793) -->
+ <skip />
<string name="notification_dots_title" msgid="9062440428204120317">"Kennisgewingkolle"</string>
<string name="notification_dots_desc_on" msgid="1679848116452218908">"Aan"</string>
<string name="notification_dots_desc_off" msgid="1760796511504341095">"Af"</string>
@@ -142,7 +152,8 @@
<string name="app_installing_title" msgid="5864044122733792085">"<xliff:g id="NAME">%1$s</xliff:g> installeer tans; <xliff:g id="PROGRESS">%2$s</xliff:g> voltooi"</string>
<string name="app_downloading_title" msgid="8336702962104482644">"<xliff:g id="NAME">%1$s</xliff:g> laai tans af, <xliff:g id="PROGRESS">%2$s</xliff:g> voltooid"</string>
<string name="app_waiting_download_title" msgid="7053938513995617849">"<xliff:g id="NAME">%1$s</xliff:g> wag tans om te installeer"</string>
- <string name="app_archived_title" msgid="7717956158562544081">"<xliff:g id="NAME">%1$s</xliff:g> is geargiveer. Tik om af te laai en terug te stel."</string>
+ <string name="app_archived_title" msgid="4548283110222420708">"<xliff:g id="NAME">%1$s</xliff:g> is geargiveer."</string>
+ <string name="app_unarchiving_action" msgid="5736107006413929484">"laai af en stel terug"</string>
<string name="dialog_update_title" msgid="114234265740994042">"Programopdatering word vereis"</string>
<string name="dialog_update_message" msgid="4176784553982226114">"Die program vir hierdie ikoon is nie opgedateer nie. Jy kan dit handmatig opdateer om hierdie kortpad weer te aktiveer, of die ikoon verwyder."</string>
<string name="dialog_update" msgid="2178028071796141234">"Dateer op"</string>
@@ -187,6 +198,8 @@
<string name="work_apps_paused_edu_accept" msgid="6377476824357318532">"Het dit"</string>
<string name="work_apps_pause_btn_text" msgid="4669288269140620646">"Onderbreek werkprogramme"</string>
<string name="work_apps_enable_btn_text" msgid="1736198302467317371">"Hervat"</string>
+ <!-- no translation found for work_scheduler_button_content_description (917340740986764967) -->
+ <skip />
<string name="developer_options_filter_hint" msgid="5896817443635989056">"Filter"</string>
<string name="remote_action_failed" msgid="1383965239183576790">"Misluk: <xliff:g id="WHAT">%1$s</xliff:g>"</string>
<string name="private_space_label" msgid="2359721649407947001">"Privaat ruimte"</string>
diff --git a/res/values-am/strings.xml b/res/values-am/strings.xml
index 53dc4ba..a217bb6 100644
--- a/res/values-am/strings.xml
+++ b/res/values-am/strings.xml
@@ -69,6 +69,12 @@
<string name="widget_category_note_taking" msgid="3469689394504266039">"የማስታወሻ አያያዝ"</string>
<string name="widget_add_button_label" msgid="2761267068711937179">"አክል"</string>
<string name="widget_add_button_content_description" msgid="1810530016360039643">"ምግብር <xliff:g id="WIDGET_NAME">%1$s</xliff:g>ን አክል"</string>
+ <!-- no translation found for widgets_list_expand_button_label (7912016136574932622) -->
+ <skip />
+ <!-- no translation found for widgets_list_expand_button_content_description (4600513860973450888) -->
+ <skip />
+ <!-- no translation found for widgets_list_expanded (7374857868788557730) -->
+ <skip />
<string name="reconfigurable_widget_education_tip" msgid="6336962690888067057">"የምግብር ቅንብሮችን ለመለወጥ መታ ያድርጉ"</string>
<string name="widget_reconfigure_button_content_description" msgid="8811472721881205250">"የምግብር ቅንብሮችን ይለውጡ"</string>
<string name="all_apps_search_bar_hint" msgid="1390553134053255246">"መተግበሪያዎችን ፈልግ"</string>
@@ -124,6 +130,10 @@
<string name="msg_disabled_by_admin" msgid="6898038085516271325">"በእርስዎ አስተዳዳሪ የተሰናከለ"</string>
<string name="allow_rotation_title" msgid="7222049633713050106">"የመነሻ ማያ ገፅ ማሽከርከርን ይፍቀዱ"</string>
<string name="allow_rotation_desc" msgid="8662546029078692509">"ስልኩ ሲዞር"</string>
+ <!-- no translation found for landscape_mode_title (5138814555934843926) -->
+ <skip />
+ <!-- no translation found for landscape_mode_desc (7372569859592816793) -->
+ <skip />
<string name="notification_dots_title" msgid="9062440428204120317">"የማሳወቂያ ነጥቦች"</string>
<string name="notification_dots_desc_on" msgid="1679848116452218908">"አብራ"</string>
<string name="notification_dots_desc_off" msgid="1760796511504341095">"ጠፍቷል"</string>
@@ -142,7 +152,8 @@
<string name="app_installing_title" msgid="5864044122733792085">"<xliff:g id="NAME">%1$s</xliff:g> በመጫን ላይ፣ <xliff:g id="PROGRESS">%2$s</xliff:g> ተጠናቅቋል"</string>
<string name="app_downloading_title" msgid="8336702962104482644">"<xliff:g id="NAME">%1$s</xliff:g> በመውረድ ላይ፣ <xliff:g id="PROGRESS">%2$s</xliff:g> ተጠናቋል"</string>
<string name="app_waiting_download_title" msgid="7053938513995617849">"<xliff:g id="NAME">%1$s</xliff:g> ለመጫን በመጠበቅ ላይ"</string>
- <string name="app_archived_title" msgid="7717956158562544081">"<xliff:g id="NAME">%1$s</xliff:g> በማህደር ተቀምጧል። ለማወረድ እና ወደነበረበት ለመመለስ መታ ያድርጉ።"</string>
+ <string name="app_archived_title" msgid="4548283110222420708">"<xliff:g id="NAME">%1$s</xliff:g> በማህደር ተቀምጧል።"</string>
+ <string name="app_unarchiving_action" msgid="5736107006413929484">"አውርድ እና ወደነበረበት መልስ"</string>
<string name="dialog_update_title" msgid="114234265740994042">"መተግበሪያ ማዘመን አስፈላጊ ነው"</string>
<string name="dialog_update_message" msgid="4176784553982226114">"የዚህ አዶ መተግበሪያ አልተዘመነም። ይህን አቋራጭ ዳግም ለማንቃት በራስዎ ማዘመን ወይም አዶውን ማስወገድ ይችላሉ።"</string>
<string name="dialog_update" msgid="2178028071796141234">"አዘምን"</string>
@@ -187,6 +198,8 @@
<string name="work_apps_paused_edu_accept" msgid="6377476824357318532">"ገባኝ"</string>
<string name="work_apps_pause_btn_text" msgid="4669288269140620646">"የሥራ መተግበሪያዎችን ባሉበት አቁም"</string>
<string name="work_apps_enable_btn_text" msgid="1736198302467317371">"ካቆመበት ቀጥል"</string>
+ <!-- no translation found for work_scheduler_button_content_description (917340740986764967) -->
+ <skip />
<string name="developer_options_filter_hint" msgid="5896817443635989056">"አጣራ"</string>
<string name="remote_action_failed" msgid="1383965239183576790">"አልተሳካም፦ <xliff:g id="WHAT">%1$s</xliff:g>"</string>
<string name="private_space_label" msgid="2359721649407947001">"የግል ቦታ"</string>
diff --git a/res/values-ar/strings.xml b/res/values-ar/strings.xml
index b15d525..c08254a 100644
--- a/res/values-ar/strings.xml
+++ b/res/values-ar/strings.xml
@@ -69,6 +69,12 @@
<string name="widget_category_note_taking" msgid="3469689394504266039">"تدوين الملاحظات"</string>
<string name="widget_add_button_label" msgid="2761267068711937179">"إضافة"</string>
<string name="widget_add_button_content_description" msgid="1810530016360039643">"إضافة التطبيق المصغّر \"<xliff:g id="WIDGET_NAME">%1$s</xliff:g>\""</string>
+ <!-- no translation found for widgets_list_expand_button_label (7912016136574932622) -->
+ <skip />
+ <!-- no translation found for widgets_list_expand_button_content_description (4600513860973450888) -->
+ <skip />
+ <!-- no translation found for widgets_list_expanded (7374857868788557730) -->
+ <skip />
<string name="reconfigurable_widget_education_tip" msgid="6336962690888067057">"انقر لتغيير إعدادات الأداة"</string>
<string name="widget_reconfigure_button_content_description" msgid="8811472721881205250">"تغيير إعدادات الأداة"</string>
<string name="all_apps_search_bar_hint" msgid="1390553134053255246">"بحث في التطبيقات"</string>
@@ -124,6 +130,10 @@
<string name="msg_disabled_by_admin" msgid="6898038085516271325">"أوقف المشرف هذه الميزة"</string>
<string name="allow_rotation_title" msgid="7222049633713050106">"السماح بتدوير الشاشة الرئيسية"</string>
<string name="allow_rotation_desc" msgid="8662546029078692509">"عند تدوير الهاتف"</string>
+ <!-- no translation found for landscape_mode_title (5138814555934843926) -->
+ <skip />
+ <!-- no translation found for landscape_mode_desc (7372569859592816793) -->
+ <skip />
<string name="notification_dots_title" msgid="9062440428204120317">"نقاط الإشعارات"</string>
<string name="notification_dots_desc_on" msgid="1679848116452218908">"الإعداد مفعّل"</string>
<string name="notification_dots_desc_off" msgid="1760796511504341095">"غير مفعّل"</string>
@@ -142,7 +152,8 @@
<string name="app_installing_title" msgid="5864044122733792085">"جارٍ تثبيت <xliff:g id="NAME">%1$s</xliff:g>، مستوى التقدم: <xliff:g id="PROGRESS">%2$s</xliff:g>"</string>
<string name="app_downloading_title" msgid="8336702962104482644">"جارٍ تنزيل <xliff:g id="NAME">%1$s</xliff:g>، اكتمل <xliff:g id="PROGRESS">%2$s</xliff:g>"</string>
<string name="app_waiting_download_title" msgid="7053938513995617849">"<xliff:g id="NAME">%1$s</xliff:g> في انتظار التثبيت"</string>
- <string name="app_archived_title" msgid="7717956158562544081">"تمت أرشفة تطبيق \"<xliff:g id="NAME">%1$s</xliff:g>\". انقر لتنزيله واستعادته."</string>
+ <string name="app_archived_title" msgid="4548283110222420708">"تمت أرشفة \"<xliff:g id="NAME">%1$s</xliff:g>\"."</string>
+ <string name="app_unarchiving_action" msgid="5736107006413929484">"تنزيل التطبيق واستعادته"</string>
<string name="dialog_update_title" msgid="114234265740994042">"مطلوب تحديث التطبيق"</string>
<string name="dialog_update_message" msgid="4176784553982226114">"لم يتمّ تحديث التطبيق الخاص بهذا الرمز. يمكنك تحديث التطبيق يدويًا لإعادة تفعيل هذا الاختصار أو إزالة الرمز."</string>
<string name="dialog_update" msgid="2178028071796141234">"تحديث"</string>
@@ -187,6 +198,8 @@
<string name="work_apps_paused_edu_accept" msgid="6377476824357318532">"حسنًا"</string>
<string name="work_apps_pause_btn_text" msgid="4669288269140620646">"إيقاف تطبيقات العمل مؤقتًا"</string>
<string name="work_apps_enable_btn_text" msgid="1736198302467317371">"إلغاء الإيقاف المؤقت"</string>
+ <!-- no translation found for work_scheduler_button_content_description (917340740986764967) -->
+ <skip />
<string name="developer_options_filter_hint" msgid="5896817443635989056">"فلتر"</string>
<string name="remote_action_failed" msgid="1383965239183576790">"تعذَّر <xliff:g id="WHAT">%1$s</xliff:g>."</string>
<string name="private_space_label" msgid="2359721649407947001">"مساحة خاصة"</string>
diff --git a/res/values-as/strings.xml b/res/values-as/strings.xml
index d8783a6..ccfb10e 100644
--- a/res/values-as/strings.xml
+++ b/res/values-as/strings.xml
@@ -69,6 +69,12 @@
<string name="widget_category_note_taking" msgid="3469689394504266039">"টোকা গ্ৰহণ কৰা"</string>
<string name="widget_add_button_label" msgid="2761267068711937179">"যোগ দিয়ক"</string>
<string name="widget_add_button_content_description" msgid="1810530016360039643">"<xliff:g id="WIDGET_NAME">%1$s</xliff:g> ৱিজেট যোগ দিয়ক"</string>
+ <!-- no translation found for widgets_list_expand_button_label (7912016136574932622) -->
+ <skip />
+ <!-- no translation found for widgets_list_expand_button_content_description (4600513860973450888) -->
+ <skip />
+ <!-- no translation found for widgets_list_expanded (7374857868788557730) -->
+ <skip />
<string name="reconfigurable_widget_education_tip" msgid="6336962690888067057">"ৱিজেটৰ ছেটিং সলনি কৰিবলৈ টিপক"</string>
<string name="widget_reconfigure_button_content_description" msgid="8811472721881205250">"ৱিজেটৰ ছেটিং সলনি কৰক"</string>
<string name="all_apps_search_bar_hint" msgid="1390553134053255246">"এপ্সমূহ সন্ধান কৰক"</string>
@@ -124,6 +130,10 @@
<string name="msg_disabled_by_admin" msgid="6898038085516271325">"আপোনাৰ প্ৰশাসকে অক্ষম কৰি ৰাখিছে"</string>
<string name="allow_rotation_title" msgid="7222049633713050106">"গৃহ স্ক্ৰীন ঘূৰোৱাৰ অনুমতি দিয়ক"</string>
<string name="allow_rotation_desc" msgid="8662546029078692509">"ফ\'নটো যেতিয়া ঘূৰোৱা হয়"</string>
+ <!-- no translation found for landscape_mode_title (5138814555934843926) -->
+ <skip />
+ <!-- no translation found for landscape_mode_desc (7372569859592816793) -->
+ <skip />
<string name="notification_dots_title" msgid="9062440428204120317">"জাননী বিন্দু"</string>
<string name="notification_dots_desc_on" msgid="1679848116452218908">"অন কৰা আছে"</string>
<string name="notification_dots_desc_off" msgid="1760796511504341095">"অফ আছে"</string>
@@ -142,7 +152,8 @@
<string name="app_installing_title" msgid="5864044122733792085">"<xliff:g id="NAME">%1$s</xliff:g> ইনষ্টল কৰি থকা হৈছে, <xliff:g id="PROGRESS">%2$s</xliff:g> সম্পূৰ্ণ হৈছে"</string>
<string name="app_downloading_title" msgid="8336702962104482644">"<xliff:g id="NAME">%1$s</xliff:g> ডাউনল’ড কৰি থকা হৈছে, <xliff:g id="PROGRESS">%2$s</xliff:g> সম্পূৰ্ণ হ’ল"</string>
<string name="app_waiting_download_title" msgid="7053938513995617849">"<xliff:g id="NAME">%1$s</xliff:g> ইনষ্টল হোৱালৈ অপেক্ষা কৰি থকা হৈছে"</string>
- <string name="app_archived_title" msgid="7717956158562544081">"<xliff:g id="NAME">%1$s</xliff:g> আৰ্কাইভ কৰা হৈছে। ডাউনল’ড আৰু পুনঃস্থাপন কৰিবলৈ টিপক।"</string>
+ <string name="app_archived_title" msgid="4548283110222420708">"<xliff:g id="NAME">%1$s</xliff:g> আৰ্কাইভ কৰা হৈছে।"</string>
+ <string name="app_unarchiving_action" msgid="5736107006413929484">"ডাউনল’ড আৰু পুনঃস্থাপন কৰক"</string>
<string name="dialog_update_title" msgid="114234265740994042">"এপ্টো আপডে’ট কৰা প্ৰয়োজন"</string>
<string name="dialog_update_message" msgid="4176784553982226114">"এই চিহ্নটোৰ এপ্টো আপডে’ট কৰা হোৱা নাই। আপুনি এই শ্বৰ্টকাটটো পুনৰ সক্ষম কৰিবলৈ মেনুৱেলী আপডে’ট কৰিব পাৰে অথবা চিহ্নটো আঁতৰাব পাৰে।"</string>
<string name="dialog_update" msgid="2178028071796141234">"আপডে’ট কৰক"</string>
@@ -187,6 +198,8 @@
<string name="work_apps_paused_edu_accept" msgid="6377476824357318532">"বুজি পালোঁ"</string>
<string name="work_apps_pause_btn_text" msgid="4669288269140620646">"কৰ্মস্থানৰ এপ্ পজ কৰক"</string>
<string name="work_apps_enable_btn_text" msgid="1736198302467317371">"আনপজ কৰক"</string>
+ <!-- no translation found for work_scheduler_button_content_description (917340740986764967) -->
+ <skip />
<string name="developer_options_filter_hint" msgid="5896817443635989056">"ফিল্টাৰ"</string>
<string name="remote_action_failed" msgid="1383965239183576790">"বিফল: <xliff:g id="WHAT">%1$s</xliff:g>"</string>
<string name="private_space_label" msgid="2359721649407947001">"প্ৰাইভেট স্পে\'চ"</string>
diff --git a/res/values-az/strings.xml b/res/values-az/strings.xml
index 5b86fac..c85f271 100644
--- a/res/values-az/strings.xml
+++ b/res/values-az/strings.xml
@@ -69,6 +69,12 @@
<string name="widget_category_note_taking" msgid="3469689394504266039">"Qeydgötürmə"</string>
<string name="widget_add_button_label" msgid="2761267068711937179">"Əlavə edin"</string>
<string name="widget_add_button_content_description" msgid="1810530016360039643">"<xliff:g id="WIDGET_NAME">%1$s</xliff:g> vidcet əlavə edin"</string>
+ <!-- no translation found for widgets_list_expand_button_label (7912016136574932622) -->
+ <skip />
+ <!-- no translation found for widgets_list_expand_button_content_description (4600513860973450888) -->
+ <skip />
+ <!-- no translation found for widgets_list_expanded (7374857868788557730) -->
+ <skip />
<string name="reconfigurable_widget_education_tip" msgid="6336962690888067057">"Vidcet ayarlarını dəyişmək üçün toxunun"</string>
<string name="widget_reconfigure_button_content_description" msgid="8811472721881205250">"Vidcet ayarlarını dəyişin"</string>
<string name="all_apps_search_bar_hint" msgid="1390553134053255246">"Tətbiqləri axtarın"</string>
@@ -124,6 +130,10 @@
<string name="msg_disabled_by_admin" msgid="6898038085516271325">"Admininiz tərəfindən deaktiv edilib"</string>
<string name="allow_rotation_title" msgid="7222049633713050106">"Əsas ekran çevrilsin"</string>
<string name="allow_rotation_desc" msgid="8662546029078692509">"Telefon çevrilən zaman"</string>
+ <!-- no translation found for landscape_mode_title (5138814555934843926) -->
+ <skip />
+ <!-- no translation found for landscape_mode_desc (7372569859592816793) -->
+ <skip />
<string name="notification_dots_title" msgid="9062440428204120317">"Bildiriş nöqtələri"</string>
<string name="notification_dots_desc_on" msgid="1679848116452218908">"Aktiv"</string>
<string name="notification_dots_desc_off" msgid="1760796511504341095">"Deaktiv"</string>
@@ -142,7 +152,8 @@
<string name="app_installing_title" msgid="5864044122733792085">"<xliff:g id="NAME">%1$s</xliff:g> quraşdırır, <xliff:g id="PROGRESS">%2$s</xliff:g> tamamlanıb"</string>
<string name="app_downloading_title" msgid="8336702962104482644">"<xliff:g id="NAME">%1$s</xliff:g> endirilir, <xliff:g id="PROGRESS">%2$s</xliff:g> tamamlandı"</string>
<string name="app_waiting_download_title" msgid="7053938513995617849">"<xliff:g id="NAME">%1$s</xliff:g> yüklənmək üçün gözləyir"</string>
- <string name="app_archived_title" msgid="7717956158562544081">"<xliff:g id="NAME">%1$s</xliff:g> arxivləndi. Toxunaraq endirin və bərpa edin."</string>
+ <string name="app_archived_title" msgid="4548283110222420708">"<xliff:g id="NAME">%1$s</xliff:g> arxivləndi."</string>
+ <string name="app_unarchiving_action" msgid="5736107006413929484">"endirin və bərpa edin"</string>
<string name="dialog_update_title" msgid="114234265740994042">"Tətbiqin güncəllənməsi tələb edilir"</string>
<string name="dialog_update_message" msgid="4176784553982226114">"Bu ikona üçün tətbiq güncəllənməyib. Bu qısayolu yenidən aktivləşdirmək üçün manual olaraq güncəlləyə və ya ikonanı silə bilərsiniz."</string>
<string name="dialog_update" msgid="2178028071796141234">"Güncəlləyin"</string>
@@ -187,6 +198,8 @@
<string name="work_apps_paused_edu_accept" msgid="6377476824357318532">"Anladım"</string>
<string name="work_apps_pause_btn_text" msgid="4669288269140620646">"İş tətbiqlərini durdurun"</string>
<string name="work_apps_enable_btn_text" msgid="1736198302467317371">"Davam etdirin"</string>
+ <!-- no translation found for work_scheduler_button_content_description (917340740986764967) -->
+ <skip />
<string name="developer_options_filter_hint" msgid="5896817443635989056">"Filtr"</string>
<string name="remote_action_failed" msgid="1383965239183576790">"Alınmadı: <xliff:g id="WHAT">%1$s</xliff:g>"</string>
<string name="private_space_label" msgid="2359721649407947001">"Məxfi sahə"</string>
diff --git a/res/values-b+sr+Latn/strings.xml b/res/values-b+sr+Latn/strings.xml
index 002c800..e8b55b7 100644
--- a/res/values-b+sr+Latn/strings.xml
+++ b/res/values-b+sr+Latn/strings.xml
@@ -69,6 +69,12 @@
<string name="widget_category_note_taking" msgid="3469689394504266039">"Pravljenje beležaka"</string>
<string name="widget_add_button_label" msgid="2761267068711937179">"Dodaj"</string>
<string name="widget_add_button_content_description" msgid="1810530016360039643">"Dodajte vidžet <xliff:g id="WIDGET_NAME">%1$s</xliff:g>"</string>
+ <!-- no translation found for widgets_list_expand_button_label (7912016136574932622) -->
+ <skip />
+ <!-- no translation found for widgets_list_expand_button_content_description (4600513860973450888) -->
+ <skip />
+ <!-- no translation found for widgets_list_expanded (7374857868788557730) -->
+ <skip />
<string name="reconfigurable_widget_education_tip" msgid="6336962690888067057">"Dodirnite da biste promenili podešavanja vidžeta"</string>
<string name="widget_reconfigure_button_content_description" msgid="8811472721881205250">"Promenite podešavanja vidžeta"</string>
<string name="all_apps_search_bar_hint" msgid="1390553134053255246">"Pretražite aplikacije"</string>
@@ -124,6 +130,10 @@
<string name="msg_disabled_by_admin" msgid="6898038085516271325">"Administrator je onemogućio"</string>
<string name="allow_rotation_title" msgid="7222049633713050106">"Dozvoli rotaciju početnog ekrana"</string>
<string name="allow_rotation_desc" msgid="8662546029078692509">"Kada se telefon rotira"</string>
+ <!-- no translation found for landscape_mode_title (5138814555934843926) -->
+ <skip />
+ <!-- no translation found for landscape_mode_desc (7372569859592816793) -->
+ <skip />
<string name="notification_dots_title" msgid="9062440428204120317">"Tačke za obaveštenja"</string>
<string name="notification_dots_desc_on" msgid="1679848116452218908">"Uključeno"</string>
<string name="notification_dots_desc_off" msgid="1760796511504341095">"Isključeno"</string>
@@ -142,7 +152,8 @@
<string name="app_installing_title" msgid="5864044122733792085">"<xliff:g id="NAME">%1$s</xliff:g> se instalira, <xliff:g id="PROGRESS">%2$s</xliff:g> gotovo"</string>
<string name="app_downloading_title" msgid="8336702962104482644">"<xliff:g id="NAME">%1$s</xliff:g> se preuzima, završeno je <xliff:g id="PROGRESS">%2$s</xliff:g>"</string>
<string name="app_waiting_download_title" msgid="7053938513995617849">"<xliff:g id="NAME">%1$s</xliff:g> čeka na instaliranje"</string>
- <string name="app_archived_title" msgid="7717956158562544081">"Aplikacija <xliff:g id="NAME">%1$s</xliff:g> je arhivirana. Dodirnite da biste je preuzeli i vratili."</string>
+ <string name="app_archived_title" msgid="4548283110222420708">"Aplikacija <xliff:g id="NAME">%1$s</xliff:g> je arhivirana."</string>
+ <string name="app_unarchiving_action" msgid="5736107006413929484">"preuzmite i vratite"</string>
<string name="dialog_update_title" msgid="114234265740994042">"Treba da ažurirate aplikaciju"</string>
<string name="dialog_update_message" msgid="4176784553982226114">"Aplikacija za ovu ikonu nije ažurirana. Možete da je ručno ažurirate da biste ponovo omogućili ovu prečicu ili uklonite ikonu."</string>
<string name="dialog_update" msgid="2178028071796141234">"Ažuriraj"</string>
@@ -187,6 +198,8 @@
<string name="work_apps_paused_edu_accept" msgid="6377476824357318532">"Važi"</string>
<string name="work_apps_pause_btn_text" msgid="4669288269140620646">"Pauziraj poslovne aplikacije"</string>
<string name="work_apps_enable_btn_text" msgid="1736198302467317371">"Ponovo aktiviraj"</string>
+ <!-- no translation found for work_scheduler_button_content_description (917340740986764967) -->
+ <skip />
<string name="developer_options_filter_hint" msgid="5896817443635989056">"Filter"</string>
<string name="remote_action_failed" msgid="1383965239183576790">"Nije uspelo: <xliff:g id="WHAT">%1$s</xliff:g>"</string>
<string name="private_space_label" msgid="2359721649407947001">"Privatni prostor"</string>
diff --git a/res/values-be/strings.xml b/res/values-be/strings.xml
index 0984f32..6d714bc 100644
--- a/res/values-be/strings.xml
+++ b/res/values-be/strings.xml
@@ -69,6 +69,12 @@
<string name="widget_category_note_taking" msgid="3469689394504266039">"Стварэнне нататак"</string>
<string name="widget_add_button_label" msgid="2761267068711937179">"Дадаць"</string>
<string name="widget_add_button_content_description" msgid="1810530016360039643">"Дадаць віджэт \"<xliff:g id="WIDGET_NAME">%1$s</xliff:g>\""</string>
+ <!-- no translation found for widgets_list_expand_button_label (7912016136574932622) -->
+ <skip />
+ <!-- no translation found for widgets_list_expand_button_content_description (4600513860973450888) -->
+ <skip />
+ <!-- no translation found for widgets_list_expanded (7374857868788557730) -->
+ <skip />
<string name="reconfigurable_widget_education_tip" msgid="6336962690888067057">"Націсніце, каб змяніць налады віджэта"</string>
<string name="widget_reconfigure_button_content_description" msgid="8811472721881205250">"Змяніць налады віджэта"</string>
<string name="all_apps_search_bar_hint" msgid="1390553134053255246">"Пошук праграм"</string>
@@ -124,6 +130,10 @@
<string name="msg_disabled_by_admin" msgid="6898038085516271325">"Адключаная адміністратарам"</string>
<string name="allow_rotation_title" msgid="7222049633713050106">"Дазволіць паварот галоўнага экрана"</string>
<string name="allow_rotation_desc" msgid="8662546029078692509">"Пры павароце тэлефона"</string>
+ <!-- no translation found for landscape_mode_title (5138814555934843926) -->
+ <skip />
+ <!-- no translation found for landscape_mode_desc (7372569859592816793) -->
+ <skip />
<string name="notification_dots_title" msgid="9062440428204120317">"Значкі апавяшчэнняў"</string>
<string name="notification_dots_desc_on" msgid="1679848116452218908">"Уключана"</string>
<string name="notification_dots_desc_off" msgid="1760796511504341095">"Выкл."</string>
@@ -142,7 +152,8 @@
<string name="app_installing_title" msgid="5864044122733792085">"Усталёўваецца праграма \"<xliff:g id="NAME">%1$s</xliff:g>\", завершана <xliff:g id="PROGRESS">%2$s</xliff:g>"</string>
<string name="app_downloading_title" msgid="8336702962104482644">"Ідзе спампоўка <xliff:g id="NAME">%1$s</xliff:g>, <xliff:g id="PROGRESS">%2$s</xliff:g> завершана"</string>
<string name="app_waiting_download_title" msgid="7053938513995617849">"<xliff:g id="NAME">%1$s</xliff:g> чакае ўсталёўкі"</string>
- <string name="app_archived_title" msgid="7717956158562544081">"Праграма \"<xliff:g id="NAME">%1$s</xliff:g>\" знаходзіцца ў архіве. Націсніце, каб спампаваць яе і аднавіць."</string>
+ <string name="app_archived_title" msgid="4548283110222420708">"Праграма \"<xliff:g id="NAME">%1$s</xliff:g>\" знаходзіцца ў архіве."</string>
+ <string name="app_unarchiving_action" msgid="5736107006413929484">"спампаваць і аднавіць"</string>
<string name="dialog_update_title" msgid="114234265740994042">"Неабходна абнавіць праграму"</string>
<string name="dialog_update_message" msgid="4176784553982226114">"Гэта версія праграмы састарэла. Абнавіце праграму ўручную, каб зноў карыстацца гэтым ярлыком, або выдаліце значок."</string>
<string name="dialog_update" msgid="2178028071796141234">"Абнавіць"</string>
@@ -187,6 +198,8 @@
<string name="work_apps_paused_edu_accept" msgid="6377476824357318532">"Зразумела"</string>
<string name="work_apps_pause_btn_text" msgid="4669288269140620646">"Прыпыніць працоўныя праграмы"</string>
<string name="work_apps_enable_btn_text" msgid="1736198302467317371">"Актываваць"</string>
+ <!-- no translation found for work_scheduler_button_content_description (917340740986764967) -->
+ <skip />
<string name="developer_options_filter_hint" msgid="5896817443635989056">"Фільтр"</string>
<string name="remote_action_failed" msgid="1383965239183576790">"Не ўдалося: <xliff:g id="WHAT">%1$s</xliff:g>"</string>
<string name="private_space_label" msgid="2359721649407947001">"Прыватная прастора"</string>
diff --git a/res/values-bg/strings.xml b/res/values-bg/strings.xml
index b321b42..191ef03 100644
--- a/res/values-bg/strings.xml
+++ b/res/values-bg/strings.xml
@@ -69,6 +69,12 @@
<string name="widget_category_note_taking" msgid="3469689394504266039">"Водене на бележки"</string>
<string name="widget_add_button_label" msgid="2761267068711937179">"Добавяне"</string>
<string name="widget_add_button_content_description" msgid="1810530016360039643">"Добавяне на приспособлението „<xliff:g id="WIDGET_NAME">%1$s</xliff:g>“"</string>
+ <!-- no translation found for widgets_list_expand_button_label (7912016136574932622) -->
+ <skip />
+ <!-- no translation found for widgets_list_expand_button_content_description (4600513860973450888) -->
+ <skip />
+ <!-- no translation found for widgets_list_expanded (7374857868788557730) -->
+ <skip />
<string name="reconfigurable_widget_education_tip" msgid="6336962690888067057">"Докоснете, за да промените настройките на приспособлението"</string>
<string name="widget_reconfigure_button_content_description" msgid="8811472721881205250">"Промяна на настройките на приспособлението"</string>
<string name="all_apps_search_bar_hint" msgid="1390553134053255246">"Търсене в приложенията"</string>
@@ -124,6 +130,10 @@
<string name="msg_disabled_by_admin" msgid="6898038085516271325">"Деактивирано от администратора ви"</string>
<string name="allow_rotation_title" msgid="7222049633713050106">"Разрешаване на завъртането на началния екран"</string>
<string name="allow_rotation_desc" msgid="8662546029078692509">"При завъртане на телефона"</string>
+ <!-- no translation found for landscape_mode_title (5138814555934843926) -->
+ <skip />
+ <!-- no translation found for landscape_mode_desc (7372569859592816793) -->
+ <skip />
<string name="notification_dots_title" msgid="9062440428204120317">"Точки за известия"</string>
<string name="notification_dots_desc_on" msgid="1679848116452218908">"Вкл."</string>
<string name="notification_dots_desc_off" msgid="1760796511504341095">"Изкл."</string>
@@ -142,7 +152,8 @@
<string name="app_installing_title" msgid="5864044122733792085">"<xliff:g id="NAME">%1$s</xliff:g> се инсталира, <xliff:g id="PROGRESS">%2$s</xliff:g> завършено"</string>
<string name="app_downloading_title" msgid="8336702962104482644">"<xliff:g id="NAME">%1$s</xliff:g> се изтегля. Завършено: <xliff:g id="PROGRESS">%2$s</xliff:g>"</string>
<string name="app_waiting_download_title" msgid="7053938513995617849">"<xliff:g id="NAME">%1$s</xliff:g> изчаква инсталиране"</string>
- <string name="app_archived_title" msgid="7717956158562544081">"Приложението <xliff:g id="NAME">%1$s</xliff:g> е архивирано. Докоснете за изтегляне и възстановяване."</string>
+ <string name="app_archived_title" msgid="4548283110222420708">"Приложението <xliff:g id="NAME">%1$s</xliff:g> е архивирано."</string>
+ <string name="app_unarchiving_action" msgid="5736107006413929484">"изтегляне и възстановяване"</string>
<string name="dialog_update_title" msgid="114234265740994042">"Изисква се актуализация на приложението"</string>
<string name="dialog_update_message" msgid="4176784553982226114">"Приложението за тази икона не е актуализирано. Можете да го актуализирате ръчно, за да активирате отново този пряк път, или да премахнете иконата."</string>
<string name="dialog_update" msgid="2178028071796141234">"Актуализиране"</string>
@@ -187,6 +198,8 @@
<string name="work_apps_paused_edu_accept" msgid="6377476824357318532">"Разбрах"</string>
<string name="work_apps_pause_btn_text" msgid="4669288269140620646">"Поставяне на пауза на служебните приложения"</string>
<string name="work_apps_enable_btn_text" msgid="1736198302467317371">"Отмяна на паузата"</string>
+ <!-- no translation found for work_scheduler_button_content_description (917340740986764967) -->
+ <skip />
<string name="developer_options_filter_hint" msgid="5896817443635989056">"Филтър"</string>
<string name="remote_action_failed" msgid="1383965239183576790">"Неуспешно: <xliff:g id="WHAT">%1$s</xliff:g>"</string>
<string name="private_space_label" msgid="2359721649407947001">"Частно пространство"</string>
diff --git a/res/values-bn/strings.xml b/res/values-bn/strings.xml
index 0722e84..43834af 100644
--- a/res/values-bn/strings.xml
+++ b/res/values-bn/strings.xml
@@ -69,6 +69,12 @@
<string name="widget_category_note_taking" msgid="3469689394504266039">"নোট নেওয়া"</string>
<string name="widget_add_button_label" msgid="2761267068711937179">"যোগ করুন"</string>
<string name="widget_add_button_content_description" msgid="1810530016360039643">"<xliff:g id="WIDGET_NAME">%1$s</xliff:g> উইজেট যোগ করুন"</string>
+ <!-- no translation found for widgets_list_expand_button_label (7912016136574932622) -->
+ <skip />
+ <!-- no translation found for widgets_list_expand_button_content_description (4600513860973450888) -->
+ <skip />
+ <!-- no translation found for widgets_list_expanded (7374857868788557730) -->
+ <skip />
<string name="reconfigurable_widget_education_tip" msgid="6336962690888067057">"উইজেট সেটিংস পরিবর্তন করতে ট্যাপ করুন"</string>
<string name="widget_reconfigure_button_content_description" msgid="8811472721881205250">"উইজেট সেটিংস পরিবর্তন করুন"</string>
<string name="all_apps_search_bar_hint" msgid="1390553134053255246">"অ্যাপ খুঁজুন"</string>
@@ -124,6 +130,10 @@
<string name="msg_disabled_by_admin" msgid="6898038085516271325">"আপনার প্রশাসক দ্বারা অক্ষম করা হয়েছে"</string>
<string name="allow_rotation_title" msgid="7222049633713050106">"হোম স্ক্রিন রোটেট করার অনুমতি দিন"</string>
<string name="allow_rotation_desc" msgid="8662546029078692509">"যখন ফোনটি ঘোরানো হয়"</string>
+ <!-- no translation found for landscape_mode_title (5138814555934843926) -->
+ <skip />
+ <!-- no translation found for landscape_mode_desc (7372569859592816793) -->
+ <skip />
<string name="notification_dots_title" msgid="9062440428204120317">"বিজ্ঞপ্তি ডট"</string>
<string name="notification_dots_desc_on" msgid="1679848116452218908">"চালু করা আছে"</string>
<string name="notification_dots_desc_off" msgid="1760796511504341095">"বন্ধ"</string>
@@ -142,7 +152,8 @@
<string name="app_installing_title" msgid="5864044122733792085">"<xliff:g id="NAME">%1$s</xliff:g> ইনস্টল করা হচ্ছে, <xliff:g id="PROGRESS">%2$s</xliff:g> সম্পূর্ণ হয়েছে"</string>
<string name="app_downloading_title" msgid="8336702962104482644">"<xliff:g id="NAME">%1$s</xliff:g> ডাউনলোড হচ্ছে <xliff:g id="PROGRESS">%2$s</xliff:g> সম্পন্ন হয়েছে"</string>
<string name="app_waiting_download_title" msgid="7053938513995617849">"<xliff:g id="NAME">%1$s</xliff:g> ইনস্টলের অপেক্ষায় রয়েছে"</string>
- <string name="app_archived_title" msgid="7717956158562544081">"<xliff:g id="NAME">%1$s</xliff:g> আর্কাইভ করা হয়েছে। ডাউনলোড করতে এবং ফিরিয়ে আনতে ট্যাপ করুন।"</string>
+ <string name="app_archived_title" msgid="4548283110222420708">"<xliff:g id="NAME">%1$s</xliff:g> আর্কাইভ করা হয়েছে।"</string>
+ <string name="app_unarchiving_action" msgid="5736107006413929484">"ডাউনলোড করুন ও ফিরিয়ে আনুন"</string>
<string name="dialog_update_title" msgid="114234265740994042">"অ্যাপটি আপডেট করা প্রয়োজন"</string>
<string name="dialog_update_message" msgid="4176784553982226114">"এই আইকনের জন্য অ্যাপটি আপডেট করা নেই। এই শর্টকার্ট আবার চালু করতে, আপনি ম্যানুয়ালি আপডেট করতে বা সরিয়ে দিতে পারবেন।"</string>
<string name="dialog_update" msgid="2178028071796141234">"আপডেট করুন"</string>
@@ -187,6 +198,8 @@
<string name="work_apps_paused_edu_accept" msgid="6377476824357318532">"বুঝেছি"</string>
<string name="work_apps_pause_btn_text" msgid="4669288269140620646">"অফিসের অ্যাপ পজ করুন"</string>
<string name="work_apps_enable_btn_text" msgid="1736198302467317371">"আনপজ করুন"</string>
+ <!-- no translation found for work_scheduler_button_content_description (917340740986764967) -->
+ <skip />
<string name="developer_options_filter_hint" msgid="5896817443635989056">"ফিল্টার"</string>
<string name="remote_action_failed" msgid="1383965239183576790">"কাজটি করা যায়নি: <xliff:g id="WHAT">%1$s</xliff:g>"</string>
<string name="private_space_label" msgid="2359721649407947001">"ব্যক্তিগত স্পেস"</string>
diff --git a/res/values-bs/strings.xml b/res/values-bs/strings.xml
index 2b168f6..0beeafe 100644
--- a/res/values-bs/strings.xml
+++ b/res/values-bs/strings.xml
@@ -69,6 +69,12 @@
<string name="widget_category_note_taking" msgid="3469689394504266039">"Pisanje bilješki"</string>
<string name="widget_add_button_label" msgid="2761267068711937179">"Dodajte"</string>
<string name="widget_add_button_content_description" msgid="1810530016360039643">"Dodavanje vidžeta <xliff:g id="WIDGET_NAME">%1$s</xliff:g>"</string>
+ <!-- no translation found for widgets_list_expand_button_label (7912016136574932622) -->
+ <skip />
+ <!-- no translation found for widgets_list_expand_button_content_description (4600513860973450888) -->
+ <skip />
+ <!-- no translation found for widgets_list_expanded (7374857868788557730) -->
+ <skip />
<string name="reconfigurable_widget_education_tip" msgid="6336962690888067057">"Dodirnite da promijenite postavke vidžeta"</string>
<string name="widget_reconfigure_button_content_description" msgid="8811472721881205250">"Promjena postavki vidžeta"</string>
<string name="all_apps_search_bar_hint" msgid="1390553134053255246">"Pretražite aplikacije"</string>
@@ -124,6 +130,10 @@
<string name="msg_disabled_by_admin" msgid="6898038085516271325">"Onemogućio vaš administrator"</string>
<string name="allow_rotation_title" msgid="7222049633713050106">"Dozvoli rotiranje početnog ekrana"</string>
<string name="allow_rotation_desc" msgid="8662546029078692509">"Kada se telefon zarotira"</string>
+ <!-- no translation found for landscape_mode_title (5138814555934843926) -->
+ <skip />
+ <!-- no translation found for landscape_mode_desc (7372569859592816793) -->
+ <skip />
<string name="notification_dots_title" msgid="9062440428204120317">"Tačke za obavještenja"</string>
<string name="notification_dots_desc_on" msgid="1679848116452218908">"Uključeno"</string>
<string name="notification_dots_desc_off" msgid="1760796511504341095">"Isključeno"</string>
@@ -142,7 +152,8 @@
<string name="app_installing_title" msgid="5864044122733792085">"Instaliranje aplikacije <xliff:g id="NAME">%1$s</xliff:g>, završeno je <xliff:g id="PROGRESS">%2$s</xliff:g>"</string>
<string name="app_downloading_title" msgid="8336702962104482644">"<xliff:g id="NAME">%1$s</xliff:g> se preuzima, završeno <xliff:g id="PROGRESS">%2$s</xliff:g>"</string>
<string name="app_waiting_download_title" msgid="7053938513995617849">"<xliff:g id="NAME">%1$s</xliff:g> čeka da se instalira"</string>
- <string name="app_archived_title" msgid="7717956158562544081">"Arhivirana je aplikacija <xliff:g id="NAME">%1$s</xliff:g>. Dodirnite da je preuzmete i vratite."</string>
+ <string name="app_archived_title" msgid="4548283110222420708">"Arhivirana je aplikacija <xliff:g id="NAME">%1$s</xliff:g>."</string>
+ <string name="app_unarchiving_action" msgid="5736107006413929484">"preuzimanje i vraćanje"</string>
<string name="dialog_update_title" msgid="114234265740994042">"Potrebno je ažurirati aplikaciju"</string>
<string name="dialog_update_message" msgid="4176784553982226114">"Aplikacija za ovu ikonu nije ažurirana. Možete je ažurirati ručno da ponovo omogućite ovu prečicu ili možete ukloniti ikonu."</string>
<string name="dialog_update" msgid="2178028071796141234">"Ažuriraj"</string>
@@ -187,6 +198,8 @@
<string name="work_apps_paused_edu_accept" msgid="6377476824357318532">"Razumijem"</string>
<string name="work_apps_pause_btn_text" msgid="4669288269140620646">"Pauziraj poslovne aplikacije"</string>
<string name="work_apps_enable_btn_text" msgid="1736198302467317371">"Ponovo pokreni"</string>
+ <!-- no translation found for work_scheduler_button_content_description (917340740986764967) -->
+ <skip />
<string name="developer_options_filter_hint" msgid="5896817443635989056">"Filtrirajte"</string>
<string name="remote_action_failed" msgid="1383965239183576790">"Nije uspjelo: <xliff:g id="WHAT">%1$s</xliff:g>"</string>
<string name="private_space_label" msgid="2359721649407947001">"Privatni prostor"</string>
diff --git a/res/values-ca/strings.xml b/res/values-ca/strings.xml
index 6d30ec1..94a7b41 100644
--- a/res/values-ca/strings.xml
+++ b/res/values-ca/strings.xml
@@ -69,6 +69,12 @@
<string name="widget_category_note_taking" msgid="3469689394504266039">"Presa de notes"</string>
<string name="widget_add_button_label" msgid="2761267068711937179">"Afegeix"</string>
<string name="widget_add_button_content_description" msgid="1810530016360039643">"Afegeix el widget <xliff:g id="WIDGET_NAME">%1$s</xliff:g>"</string>
+ <!-- no translation found for widgets_list_expand_button_label (7912016136574932622) -->
+ <skip />
+ <!-- no translation found for widgets_list_expand_button_content_description (4600513860973450888) -->
+ <skip />
+ <!-- no translation found for widgets_list_expanded (7374857868788557730) -->
+ <skip />
<string name="reconfigurable_widget_education_tip" msgid="6336962690888067057">"Toca per canviar la configuració del widget"</string>
<string name="widget_reconfigure_button_content_description" msgid="8811472721881205250">"Canvia la configuració del widget"</string>
<string name="all_apps_search_bar_hint" msgid="1390553134053255246">"Cerca aplicacions"</string>
@@ -124,6 +130,10 @@
<string name="msg_disabled_by_admin" msgid="6898038085516271325">"Desactivada per l\'administrador"</string>
<string name="allow_rotation_title" msgid="7222049633713050106">"Permet la rotació de la pantalla d\'inici"</string>
<string name="allow_rotation_desc" msgid="8662546029078692509">"En girar el telèfon"</string>
+ <!-- no translation found for landscape_mode_title (5138814555934843926) -->
+ <skip />
+ <!-- no translation found for landscape_mode_desc (7372569859592816793) -->
+ <skip />
<string name="notification_dots_title" msgid="9062440428204120317">"Punts de notificació"</string>
<string name="notification_dots_desc_on" msgid="1679848116452218908">"Activats"</string>
<string name="notification_dots_desc_off" msgid="1760796511504341095">"Desactivats"</string>
@@ -142,7 +152,8 @@
<string name="app_installing_title" msgid="5864044122733792085">"S\'està instal·lant <xliff:g id="NAME">%1$s</xliff:g>; s\'ha completat un <xliff:g id="PROGRESS">%2$s</xliff:g>"</string>
<string name="app_downloading_title" msgid="8336702962104482644">"S\'està baixant <xliff:g id="NAME">%1$s</xliff:g>, <xliff:g id="PROGRESS">%2$s</xliff:g> completat"</string>
<string name="app_waiting_download_title" msgid="7053938513995617849">"S\'està esperant per instal·lar <xliff:g id="NAME">%1$s</xliff:g>"</string>
- <string name="app_archived_title" msgid="7717956158562544081">"L\'aplicació <xliff:g id="NAME">%1$s</xliff:g> està arxivada. Toca per baixar-la i restaurar-la."</string>
+ <string name="app_archived_title" msgid="4548283110222420708">"L\'aplicació <xliff:g id="NAME">%1$s</xliff:g> està arxivada."</string>
+ <string name="app_unarchiving_action" msgid="5736107006413929484">"baixa i restaura"</string>
<string name="dialog_update_title" msgid="114234265740994042">"Cal actualitzar l\'aplicació"</string>
<string name="dialog_update_message" msgid="4176784553982226114">"L\'aplicació d\'aquesta icona no està actualitzada. Pots actualitzar-la manualment per tornar a activar aquesta drecera o pots suprimir la icona."</string>
<string name="dialog_update" msgid="2178028071796141234">"Actualitza"</string>
@@ -187,6 +198,8 @@
<string name="work_apps_paused_edu_accept" msgid="6377476824357318532">"Entesos"</string>
<string name="work_apps_pause_btn_text" msgid="4669288269140620646">"Posa en pausa les aplicacions de treball"</string>
<string name="work_apps_enable_btn_text" msgid="1736198302467317371">"Reactiva"</string>
+ <!-- no translation found for work_scheduler_button_content_description (917340740986764967) -->
+ <skip />
<string name="developer_options_filter_hint" msgid="5896817443635989056">"Filtra"</string>
<string name="remote_action_failed" msgid="1383965239183576790">"Error: <xliff:g id="WHAT">%1$s</xliff:g>"</string>
<string name="private_space_label" msgid="2359721649407947001">"Espai privat"</string>
diff --git a/res/values-cs/strings.xml b/res/values-cs/strings.xml
index 732343d..93017bf 100644
--- a/res/values-cs/strings.xml
+++ b/res/values-cs/strings.xml
@@ -69,6 +69,12 @@
<string name="widget_category_note_taking" msgid="3469689394504266039">"Psaní poznámek"</string>
<string name="widget_add_button_label" msgid="2761267068711937179">"Přidat"</string>
<string name="widget_add_button_content_description" msgid="1810530016360039643">"Přidat widget <xliff:g id="WIDGET_NAME">%1$s</xliff:g>"</string>
+ <!-- no translation found for widgets_list_expand_button_label (7912016136574932622) -->
+ <skip />
+ <!-- no translation found for widgets_list_expand_button_content_description (4600513860973450888) -->
+ <skip />
+ <!-- no translation found for widgets_list_expanded (7374857868788557730) -->
+ <skip />
<string name="reconfigurable_widget_education_tip" msgid="6336962690888067057">"Klepnutím změníte nastavení widgetu"</string>
<string name="widget_reconfigure_button_content_description" msgid="8811472721881205250">"Změnit nastavení widgetu"</string>
<string name="all_apps_search_bar_hint" msgid="1390553134053255246">"Hledat v aplikacích"</string>
@@ -124,6 +130,10 @@
<string name="msg_disabled_by_admin" msgid="6898038085516271325">"Zakázáno administrátorem"</string>
<string name="allow_rotation_title" msgid="7222049633713050106">"Povolit otáčení plochy"</string>
<string name="allow_rotation_desc" msgid="8662546029078692509">"Při otočení telefonu"</string>
+ <!-- no translation found for landscape_mode_title (5138814555934843926) -->
+ <skip />
+ <!-- no translation found for landscape_mode_desc (7372569859592816793) -->
+ <skip />
<string name="notification_dots_title" msgid="9062440428204120317">"Puntíky s oznámením"</string>
<string name="notification_dots_desc_on" msgid="1679848116452218908">"Zapnuto"</string>
<string name="notification_dots_desc_off" msgid="1760796511504341095">"Vypnuto"</string>
@@ -142,7 +152,8 @@
<string name="app_installing_title" msgid="5864044122733792085">"Instalace aplikace <xliff:g id="NAME">%1$s</xliff:g>, dokončeno <xliff:g id="PROGRESS">%2$s</xliff:g>"</string>
<string name="app_downloading_title" msgid="8336702962104482644">"Stahování aplikace <xliff:g id="NAME">%1$s</xliff:g> (dokončeno <xliff:g id="PROGRESS">%2$s</xliff:g>)"</string>
<string name="app_waiting_download_title" msgid="7053938513995617849">"Instalace aplikace <xliff:g id="NAME">%1$s</xliff:g> čeká na zahájení"</string>
- <string name="app_archived_title" msgid="7717956158562544081">"Aplikace <xliff:g id="NAME">%1$s</xliff:g> je archivována. Klepnutím ji můžete stáhnout a obnovit."</string>
+ <string name="app_archived_title" msgid="4548283110222420708">"Aplikace <xliff:g id="NAME">%1$s</xliff:g> je archivována."</string>
+ <string name="app_unarchiving_action" msgid="5736107006413929484">"stáhnout a obnovit"</string>
<string name="dialog_update_title" msgid="114234265740994042">"Je nutná aktualizace aplikace"</string>
<string name="dialog_update_message" msgid="4176784553982226114">"Aplikace pro tuto ikonu není nainstalována. Můžete ji ručně aktualizovat, aby zkratka znovu fungovala, případně můžete ikonu odstranit."</string>
<string name="dialog_update" msgid="2178028071796141234">"Aktualizovat"</string>
@@ -187,6 +198,8 @@
<string name="work_apps_paused_edu_accept" msgid="6377476824357318532">"OK"</string>
<string name="work_apps_pause_btn_text" msgid="4669288269140620646">"Pozastavit pracovní aplikace"</string>
<string name="work_apps_enable_btn_text" msgid="1736198302467317371">"Zrušit pozastavení"</string>
+ <!-- no translation found for work_scheduler_button_content_description (917340740986764967) -->
+ <skip />
<string name="developer_options_filter_hint" msgid="5896817443635989056">"Filtr"</string>
<string name="remote_action_failed" msgid="1383965239183576790">"Selhalo: <xliff:g id="WHAT">%1$s</xliff:g>"</string>
<string name="private_space_label" msgid="2359721649407947001">"Soukromý prostor"</string>
diff --git a/res/values-da/strings.xml b/res/values-da/strings.xml
index 0d78d90..c22d0dc 100644
--- a/res/values-da/strings.xml
+++ b/res/values-da/strings.xml
@@ -69,6 +69,12 @@
<string name="widget_category_note_taking" msgid="3469689394504266039">"Notetagning"</string>
<string name="widget_add_button_label" msgid="2761267068711937179">"Tilføj"</string>
<string name="widget_add_button_content_description" msgid="1810530016360039643">"Tilføj <xliff:g id="WIDGET_NAME">%1$s</xliff:g>-widget"</string>
+ <!-- no translation found for widgets_list_expand_button_label (7912016136574932622) -->
+ <skip />
+ <!-- no translation found for widgets_list_expand_button_content_description (4600513860973450888) -->
+ <skip />
+ <!-- no translation found for widgets_list_expanded (7374857868788557730) -->
+ <skip />
<string name="reconfigurable_widget_education_tip" msgid="6336962690888067057">"Tryk for at ændre widgetindstillinger"</string>
<string name="widget_reconfigure_button_content_description" msgid="8811472721881205250">"Skift widgetindstillinger"</string>
<string name="all_apps_search_bar_hint" msgid="1390553134053255246">"Søg efter apps"</string>
@@ -124,6 +130,10 @@
<string name="msg_disabled_by_admin" msgid="6898038085516271325">"Deaktiveret af din administrator"</string>
<string name="allow_rotation_title" msgid="7222049633713050106">"Tillad rotation af startskærmen"</string>
<string name="allow_rotation_desc" msgid="8662546029078692509">"Når telefonen roteres"</string>
+ <!-- no translation found for landscape_mode_title (5138814555934843926) -->
+ <skip />
+ <!-- no translation found for landscape_mode_desc (7372569859592816793) -->
+ <skip />
<string name="notification_dots_title" msgid="9062440428204120317">"Notifikationsprikker"</string>
<string name="notification_dots_desc_on" msgid="1679848116452218908">"Til"</string>
<string name="notification_dots_desc_off" msgid="1760796511504341095">"Fra"</string>
@@ -142,7 +152,8 @@
<string name="app_installing_title" msgid="5864044122733792085">"<xliff:g id="NAME">%1$s</xliff:g> installeres. <xliff:g id="PROGRESS">%2$s</xliff:g> fuldført"</string>
<string name="app_downloading_title" msgid="8336702962104482644">"<xliff:g id="NAME">%1$s</xliff:g> downloades. <xliff:g id="PROGRESS">%2$s</xliff:g> er gennemført"</string>
<string name="app_waiting_download_title" msgid="7053938513995617849">"<xliff:g id="NAME">%1$s</xliff:g> venter på at installere"</string>
- <string name="app_archived_title" msgid="7717956158562544081">"<xliff:g id="NAME">%1$s</xliff:g> er arkiveret Tryk for at downloade og gendanne."</string>
+ <string name="app_archived_title" msgid="4548283110222420708">"<xliff:g id="NAME">%1$s</xliff:g> er arkiveret."</string>
+ <string name="app_unarchiving_action" msgid="5736107006413929484">"download og gendan"</string>
<string name="dialog_update_title" msgid="114234265740994042">"Appen skal opdateres"</string>
<string name="dialog_update_message" msgid="4176784553982226114">"Appen, der tilhører dette ikon, er ikke opdateret. Du kan opdatere appen manuelt for at genaktivere denne genvej, eller du kan fjerne ikonet."</string>
<string name="dialog_update" msgid="2178028071796141234">"Opdater"</string>
@@ -187,6 +198,8 @@
<string name="work_apps_paused_edu_accept" msgid="6377476824357318532">"OK"</string>
<string name="work_apps_pause_btn_text" msgid="4669288269140620646">"Sæt arbejdsapps på pause"</string>
<string name="work_apps_enable_btn_text" msgid="1736198302467317371">"Genoptag"</string>
+ <!-- no translation found for work_scheduler_button_content_description (917340740986764967) -->
+ <skip />
<string name="developer_options_filter_hint" msgid="5896817443635989056">"Filter"</string>
<string name="remote_action_failed" msgid="1383965239183576790">"Mislykket: <xliff:g id="WHAT">%1$s</xliff:g>"</string>
<string name="private_space_label" msgid="2359721649407947001">"Privat område"</string>
diff --git a/res/values-de/strings.xml b/res/values-de/strings.xml
index c90cf84..21ada28 100644
--- a/res/values-de/strings.xml
+++ b/res/values-de/strings.xml
@@ -69,6 +69,12 @@
<string name="widget_category_note_taking" msgid="3469689394504266039">"Notizen"</string>
<string name="widget_add_button_label" msgid="2761267068711937179">"Hinzufügen"</string>
<string name="widget_add_button_content_description" msgid="1810530016360039643">"Widget „<xliff:g id="WIDGET_NAME">%1$s</xliff:g>“ hinzufügen"</string>
+ <!-- no translation found for widgets_list_expand_button_label (7912016136574932622) -->
+ <skip />
+ <!-- no translation found for widgets_list_expand_button_content_description (4600513860973450888) -->
+ <skip />
+ <!-- no translation found for widgets_list_expanded (7374857868788557730) -->
+ <skip />
<string name="reconfigurable_widget_education_tip" msgid="6336962690888067057">"Tippen, um die Widget-Einstellungen zu ändern"</string>
<string name="widget_reconfigure_button_content_description" msgid="8811472721881205250">"Widget-Einstellungen ändern"</string>
<string name="all_apps_search_bar_hint" msgid="1390553134053255246">"Apps finden"</string>
@@ -124,6 +130,10 @@
<string name="msg_disabled_by_admin" msgid="6898038085516271325">"Von deinem Administrator deaktiviert"</string>
<string name="allow_rotation_title" msgid="7222049633713050106">"Drehen des Startbildschirms zulassen"</string>
<string name="allow_rotation_desc" msgid="8662546029078692509">"Beim Drehen des Smartphones"</string>
+ <!-- no translation found for landscape_mode_title (5138814555934843926) -->
+ <skip />
+ <!-- no translation found for landscape_mode_desc (7372569859592816793) -->
+ <skip />
<string name="notification_dots_title" msgid="9062440428204120317">"App-Benachrichtigungspunkte"</string>
<string name="notification_dots_desc_on" msgid="1679848116452218908">"An"</string>
<string name="notification_dots_desc_off" msgid="1760796511504341095">"Aus"</string>
@@ -142,7 +152,8 @@
<string name="app_installing_title" msgid="5864044122733792085">"<xliff:g id="NAME">%1$s</xliff:g> wird installiert, <xliff:g id="PROGRESS">%2$s</xliff:g> abgeschlossen"</string>
<string name="app_downloading_title" msgid="8336702962104482644">"<xliff:g id="NAME">%1$s</xliff:g> wird heruntergeladen, <xliff:g id="PROGRESS">%2$s</xliff:g> abgeschlossen"</string>
<string name="app_waiting_download_title" msgid="7053938513995617849">"Warten auf Installation von <xliff:g id="NAME">%1$s</xliff:g>"</string>
- <string name="app_archived_title" msgid="7717956158562544081">"<xliff:g id="NAME">%1$s</xliff:g> ist archiviert. Tippe, um die App herunterzuladen und wiederherzustellen."</string>
+ <string name="app_archived_title" msgid="4548283110222420708">"<xliff:g id="NAME">%1$s</xliff:g> ist archiviert."</string>
+ <string name="app_unarchiving_action" msgid="5736107006413929484">"herunterladen und wiederherstellen"</string>
<string name="dialog_update_title" msgid="114234265740994042">"App-Update erforderlich"</string>
<string name="dialog_update_message" msgid="4176784553982226114">"Die App für dieses Symbol wurde noch nicht aktualisiert. Du kannst sie manuell aktualisieren, um die Verknüpfung wieder zu aktivieren, oder das Symbol entfernen."</string>
<string name="dialog_update" msgid="2178028071796141234">"Aktualisieren"</string>
@@ -187,6 +198,8 @@
<string name="work_apps_paused_edu_accept" msgid="6377476824357318532">"OK"</string>
<string name="work_apps_pause_btn_text" msgid="4669288269140620646">"Geschäftliche Apps pausieren"</string>
<string name="work_apps_enable_btn_text" msgid="1736198302467317371">"Nicht mehr pausieren"</string>
+ <!-- no translation found for work_scheduler_button_content_description (917340740986764967) -->
+ <skip />
<string name="developer_options_filter_hint" msgid="5896817443635989056">"Filter"</string>
<string name="remote_action_failed" msgid="1383965239183576790">"Fehler: <xliff:g id="WHAT">%1$s</xliff:g>"</string>
<string name="private_space_label" msgid="2359721649407947001">"Vertrauliches Profil"</string>
diff --git a/res/values-el/strings.xml b/res/values-el/strings.xml
index cd1a1e0..1e18977 100644
--- a/res/values-el/strings.xml
+++ b/res/values-el/strings.xml
@@ -69,6 +69,12 @@
<string name="widget_category_note_taking" msgid="3469689394504266039">"Δημιουργία σημειώσεων"</string>
<string name="widget_add_button_label" msgid="2761267068711937179">"Προσθήκη"</string>
<string name="widget_add_button_content_description" msgid="1810530016360039643">"Προσθήκη του γραφικού στοιχείου <xliff:g id="WIDGET_NAME">%1$s</xliff:g>"</string>
+ <!-- no translation found for widgets_list_expand_button_label (7912016136574932622) -->
+ <skip />
+ <!-- no translation found for widgets_list_expand_button_content_description (4600513860973450888) -->
+ <skip />
+ <!-- no translation found for widgets_list_expanded (7374857868788557730) -->
+ <skip />
<string name="reconfigurable_widget_education_tip" msgid="6336962690888067057">"Πατήστε για αλλαγή των ρυθμίσεων του γραφικού στοιχείου"</string>
<string name="widget_reconfigure_button_content_description" msgid="8811472721881205250">"Αλλαγή ρυθμίσεων γραφικού στοιχείου"</string>
<string name="all_apps_search_bar_hint" msgid="1390553134053255246">"Αναζήτηση εφαρμογών"</string>
@@ -124,6 +130,10 @@
<string name="msg_disabled_by_admin" msgid="6898038085516271325">"Απενεργοποιήθηκε από τον διαχειριστή σας"</string>
<string name="allow_rotation_title" msgid="7222049633713050106">"Να επιτρέπεται η περιστροφή της αρχικής οθόνης"</string>
<string name="allow_rotation_desc" msgid="8662546029078692509">"Όταν το τηλέφωνο περιστρέφεται"</string>
+ <!-- no translation found for landscape_mode_title (5138814555934843926) -->
+ <skip />
+ <!-- no translation found for landscape_mode_desc (7372569859592816793) -->
+ <skip />
<string name="notification_dots_title" msgid="9062440428204120317">"Κουκκίδες ειδοποίησης"</string>
<string name="notification_dots_desc_on" msgid="1679848116452218908">"Ενεργοποίηση"</string>
<string name="notification_dots_desc_off" msgid="1760796511504341095">"Απενεργοποίηση"</string>
@@ -142,7 +152,8 @@
<string name="app_installing_title" msgid="5864044122733792085">"Έχει ολοκληρωθεί το <xliff:g id="PROGRESS">%2$s</xliff:g> της εγκατάστασης της εφαρμογής <xliff:g id="NAME">%1$s</xliff:g>"</string>
<string name="app_downloading_title" msgid="8336702962104482644">"Λήψη <xliff:g id="NAME">%1$s</xliff:g>, ολοκληρώθηκε <xliff:g id="PROGRESS">%2$s</xliff:g>"</string>
<string name="app_waiting_download_title" msgid="7053938513995617849">"<xliff:g id="NAME">%1$s</xliff:g> σε αναμονή για εγκατάσταση"</string>
- <string name="app_archived_title" msgid="7717956158562544081">"Η εφαρμογή <xliff:g id="NAME">%1$s</xliff:g> είναι αρχειοθετημένη. Πατήστε για λήψη και επαναφορά."</string>
+ <string name="app_archived_title" msgid="4548283110222420708">"Η εφαρμογή <xliff:g id="NAME">%1$s</xliff:g> είναι αρχειοθετημένη."</string>
+ <string name="app_unarchiving_action" msgid="5736107006413929484">"λήψη και επαναφορά"</string>
<string name="dialog_update_title" msgid="114234265740994042">"Απαιτείται ενημέρωση της εφαρμογής"</string>
<string name="dialog_update_message" msgid="4176784553982226114">"Η εφαρμογή για αυτό το εικονίδιο δεν έχει ενημερωθεί. Μπορείτε να την ενημερώσετε μη αυτόματα για να ενεργοποιήσετε ξανά τη συγκεκριμένη συντόμευση ή να καταργήσετε το εικονίδιο."</string>
<string name="dialog_update" msgid="2178028071796141234">"Ενημέρωση"</string>
@@ -187,6 +198,8 @@
<string name="work_apps_paused_edu_accept" msgid="6377476824357318532">"Το κατάλαβα"</string>
<string name="work_apps_pause_btn_text" msgid="4669288269140620646">"Παύση εφαρμογών εργασιών"</string>
<string name="work_apps_enable_btn_text" msgid="1736198302467317371">"Αναίρεση παύσης"</string>
+ <!-- no translation found for work_scheduler_button_content_description (917340740986764967) -->
+ <skip />
<string name="developer_options_filter_hint" msgid="5896817443635989056">"Φίλτρο"</string>
<string name="remote_action_failed" msgid="1383965239183576790">"Αποτυχία: <xliff:g id="WHAT">%1$s</xliff:g>"</string>
<string name="private_space_label" msgid="2359721649407947001">"Ιδιωτικός χώρος"</string>
diff --git a/res/values-en-rAU/strings.xml b/res/values-en-rAU/strings.xml
index f7b04a3..a2a4145 100644
--- a/res/values-en-rAU/strings.xml
+++ b/res/values-en-rAU/strings.xml
@@ -69,6 +69,12 @@
<string name="widget_category_note_taking" msgid="3469689394504266039">"Note-taking"</string>
<string name="widget_add_button_label" msgid="2761267068711937179">"Add"</string>
<string name="widget_add_button_content_description" msgid="1810530016360039643">"Add <xliff:g id="WIDGET_NAME">%1$s</xliff:g> widget"</string>
+ <!-- no translation found for widgets_list_expand_button_label (7912016136574932622) -->
+ <skip />
+ <!-- no translation found for widgets_list_expand_button_content_description (4600513860973450888) -->
+ <skip />
+ <!-- no translation found for widgets_list_expanded (7374857868788557730) -->
+ <skip />
<string name="reconfigurable_widget_education_tip" msgid="6336962690888067057">"Tap to change widget settings"</string>
<string name="widget_reconfigure_button_content_description" msgid="8811472721881205250">"Change widget settings"</string>
<string name="all_apps_search_bar_hint" msgid="1390553134053255246">"Search apps"</string>
@@ -124,6 +130,10 @@
<string name="msg_disabled_by_admin" msgid="6898038085516271325">"Disabled by your admin"</string>
<string name="allow_rotation_title" msgid="7222049633713050106">"Allow home screen rotation"</string>
<string name="allow_rotation_desc" msgid="8662546029078692509">"When phone is rotated"</string>
+ <!-- no translation found for landscape_mode_title (5138814555934843926) -->
+ <skip />
+ <!-- no translation found for landscape_mode_desc (7372569859592816793) -->
+ <skip />
<string name="notification_dots_title" msgid="9062440428204120317">"Notification dots"</string>
<string name="notification_dots_desc_on" msgid="1679848116452218908">"On"</string>
<string name="notification_dots_desc_off" msgid="1760796511504341095">"Off"</string>
@@ -142,7 +152,8 @@
<string name="app_installing_title" msgid="5864044122733792085">"<xliff:g id="NAME">%1$s</xliff:g> installing, <xliff:g id="PROGRESS">%2$s</xliff:g> complete"</string>
<string name="app_downloading_title" msgid="8336702962104482644">"<xliff:g id="NAME">%1$s</xliff:g> downloading, <xliff:g id="PROGRESS">%2$s</xliff:g> complete"</string>
<string name="app_waiting_download_title" msgid="7053938513995617849">"<xliff:g id="NAME">%1$s</xliff:g> waiting to install"</string>
- <string name="app_archived_title" msgid="7717956158562544081">"<xliff:g id="NAME">%1$s</xliff:g> is archived. Tap to download and restore."</string>
+ <string name="app_archived_title" msgid="4548283110222420708">"<xliff:g id="NAME">%1$s</xliff:g> is archived."</string>
+ <string name="app_unarchiving_action" msgid="5736107006413929484">"download and restore"</string>
<string name="dialog_update_title" msgid="114234265740994042">"App update required"</string>
<string name="dialog_update_message" msgid="4176784553982226114">"The app for this icon isn\'t updated. You can update manually to re-enable this shortcut or remove the icon."</string>
<string name="dialog_update" msgid="2178028071796141234">"Update"</string>
@@ -187,6 +198,8 @@
<string name="work_apps_paused_edu_accept" msgid="6377476824357318532">"OK"</string>
<string name="work_apps_pause_btn_text" msgid="4669288269140620646">"Pause work apps"</string>
<string name="work_apps_enable_btn_text" msgid="1736198302467317371">"Unpause"</string>
+ <!-- no translation found for work_scheduler_button_content_description (917340740986764967) -->
+ <skip />
<string name="developer_options_filter_hint" msgid="5896817443635989056">"Filter"</string>
<string name="remote_action_failed" msgid="1383965239183576790">"Failed: <xliff:g id="WHAT">%1$s</xliff:g>"</string>
<string name="private_space_label" msgid="2359721649407947001">"Private space"</string>
diff --git a/res/values-en-rCA/strings.xml b/res/values-en-rCA/strings.xml
index 8feccb0..c600680 100644
--- a/res/values-en-rCA/strings.xml
+++ b/res/values-en-rCA/strings.xml
@@ -69,6 +69,9 @@
<string name="widget_category_note_taking" msgid="3469689394504266039">"Note-taking"</string>
<string name="widget_add_button_label" msgid="2761267068711937179">"Add"</string>
<string name="widget_add_button_content_description" msgid="1810530016360039643">"Add <xliff:g id="WIDGET_NAME">%1$s</xliff:g> widget"</string>
+ <string name="widgets_list_expand_button_label" msgid="7912016136574932622">"Show all"</string>
+ <string name="widgets_list_expand_button_content_description" msgid="4600513860973450888">"Show all widgets"</string>
+ <string name="widgets_list_expanded" msgid="7374857868788557730">"Showing all widgets"</string>
<string name="reconfigurable_widget_education_tip" msgid="6336962690888067057">"Tap to change widget settings"</string>
<string name="widget_reconfigure_button_content_description" msgid="8811472721881205250">"Change widget settings"</string>
<string name="all_apps_search_bar_hint" msgid="1390553134053255246">"Search apps"</string>
@@ -124,6 +127,8 @@
<string name="msg_disabled_by_admin" msgid="6898038085516271325">"Disabled by your admin"</string>
<string name="allow_rotation_title" msgid="7222049633713050106">"Allow home screen rotation"</string>
<string name="allow_rotation_desc" msgid="8662546029078692509">"When phone is rotated"</string>
+ <string name="landscape_mode_title" msgid="5138814555934843926">"Landscape mode"</string>
+ <string name="landscape_mode_desc" msgid="7372569859592816793">"Set phone into landscape mode"</string>
<string name="notification_dots_title" msgid="9062440428204120317">"Notification dots"</string>
<string name="notification_dots_desc_on" msgid="1679848116452218908">"On"</string>
<string name="notification_dots_desc_off" msgid="1760796511504341095">"Off"</string>
@@ -142,7 +147,8 @@
<string name="app_installing_title" msgid="5864044122733792085">"<xliff:g id="NAME">%1$s</xliff:g> installing, <xliff:g id="PROGRESS">%2$s</xliff:g> complete"</string>
<string name="app_downloading_title" msgid="8336702962104482644">"<xliff:g id="NAME">%1$s</xliff:g> downloading, <xliff:g id="PROGRESS">%2$s</xliff:g> complete"</string>
<string name="app_waiting_download_title" msgid="7053938513995617849">"<xliff:g id="NAME">%1$s</xliff:g> waiting to install"</string>
- <string name="app_archived_title" msgid="7717956158562544081">"<xliff:g id="NAME">%1$s</xliff:g> is archived. Tap to download and restore."</string>
+ <string name="app_archived_title" msgid="4548283110222420708">"<xliff:g id="NAME">%1$s</xliff:g> is archived."</string>
+ <string name="app_unarchiving_action" msgid="5736107006413929484">"download and restore"</string>
<string name="dialog_update_title" msgid="114234265740994042">"App update required"</string>
<string name="dialog_update_message" msgid="4176784553982226114">"The app for this icon isn\'t updated. You can update manually to re-enable this shortcut, or remove the icon."</string>
<string name="dialog_update" msgid="2178028071796141234">"Update"</string>
@@ -187,6 +193,7 @@
<string name="work_apps_paused_edu_accept" msgid="6377476824357318532">"Got it"</string>
<string name="work_apps_pause_btn_text" msgid="4669288269140620646">"Pause work apps"</string>
<string name="work_apps_enable_btn_text" msgid="1736198302467317371">"Unpause"</string>
+ <string name="work_scheduler_button_content_description" msgid="917340740986764967">"Work apps schedule"</string>
<string name="developer_options_filter_hint" msgid="5896817443635989056">"Filter"</string>
<string name="remote_action_failed" msgid="1383965239183576790">"Failed: <xliff:g id="WHAT">%1$s</xliff:g>"</string>
<string name="private_space_label" msgid="2359721649407947001">"Private space"</string>
diff --git a/res/values-en-rGB/strings.xml b/res/values-en-rGB/strings.xml
index f7b04a3..a2a4145 100644
--- a/res/values-en-rGB/strings.xml
+++ b/res/values-en-rGB/strings.xml
@@ -69,6 +69,12 @@
<string name="widget_category_note_taking" msgid="3469689394504266039">"Note-taking"</string>
<string name="widget_add_button_label" msgid="2761267068711937179">"Add"</string>
<string name="widget_add_button_content_description" msgid="1810530016360039643">"Add <xliff:g id="WIDGET_NAME">%1$s</xliff:g> widget"</string>
+ <!-- no translation found for widgets_list_expand_button_label (7912016136574932622) -->
+ <skip />
+ <!-- no translation found for widgets_list_expand_button_content_description (4600513860973450888) -->
+ <skip />
+ <!-- no translation found for widgets_list_expanded (7374857868788557730) -->
+ <skip />
<string name="reconfigurable_widget_education_tip" msgid="6336962690888067057">"Tap to change widget settings"</string>
<string name="widget_reconfigure_button_content_description" msgid="8811472721881205250">"Change widget settings"</string>
<string name="all_apps_search_bar_hint" msgid="1390553134053255246">"Search apps"</string>
@@ -124,6 +130,10 @@
<string name="msg_disabled_by_admin" msgid="6898038085516271325">"Disabled by your admin"</string>
<string name="allow_rotation_title" msgid="7222049633713050106">"Allow home screen rotation"</string>
<string name="allow_rotation_desc" msgid="8662546029078692509">"When phone is rotated"</string>
+ <!-- no translation found for landscape_mode_title (5138814555934843926) -->
+ <skip />
+ <!-- no translation found for landscape_mode_desc (7372569859592816793) -->
+ <skip />
<string name="notification_dots_title" msgid="9062440428204120317">"Notification dots"</string>
<string name="notification_dots_desc_on" msgid="1679848116452218908">"On"</string>
<string name="notification_dots_desc_off" msgid="1760796511504341095">"Off"</string>
@@ -142,7 +152,8 @@
<string name="app_installing_title" msgid="5864044122733792085">"<xliff:g id="NAME">%1$s</xliff:g> installing, <xliff:g id="PROGRESS">%2$s</xliff:g> complete"</string>
<string name="app_downloading_title" msgid="8336702962104482644">"<xliff:g id="NAME">%1$s</xliff:g> downloading, <xliff:g id="PROGRESS">%2$s</xliff:g> complete"</string>
<string name="app_waiting_download_title" msgid="7053938513995617849">"<xliff:g id="NAME">%1$s</xliff:g> waiting to install"</string>
- <string name="app_archived_title" msgid="7717956158562544081">"<xliff:g id="NAME">%1$s</xliff:g> is archived. Tap to download and restore."</string>
+ <string name="app_archived_title" msgid="4548283110222420708">"<xliff:g id="NAME">%1$s</xliff:g> is archived."</string>
+ <string name="app_unarchiving_action" msgid="5736107006413929484">"download and restore"</string>
<string name="dialog_update_title" msgid="114234265740994042">"App update required"</string>
<string name="dialog_update_message" msgid="4176784553982226114">"The app for this icon isn\'t updated. You can update manually to re-enable this shortcut or remove the icon."</string>
<string name="dialog_update" msgid="2178028071796141234">"Update"</string>
@@ -187,6 +198,8 @@
<string name="work_apps_paused_edu_accept" msgid="6377476824357318532">"OK"</string>
<string name="work_apps_pause_btn_text" msgid="4669288269140620646">"Pause work apps"</string>
<string name="work_apps_enable_btn_text" msgid="1736198302467317371">"Unpause"</string>
+ <!-- no translation found for work_scheduler_button_content_description (917340740986764967) -->
+ <skip />
<string name="developer_options_filter_hint" msgid="5896817443635989056">"Filter"</string>
<string name="remote_action_failed" msgid="1383965239183576790">"Failed: <xliff:g id="WHAT">%1$s</xliff:g>"</string>
<string name="private_space_label" msgid="2359721649407947001">"Private space"</string>
diff --git a/res/values-en-rIN/strings.xml b/res/values-en-rIN/strings.xml
index f7b04a3..a2a4145 100644
--- a/res/values-en-rIN/strings.xml
+++ b/res/values-en-rIN/strings.xml
@@ -69,6 +69,12 @@
<string name="widget_category_note_taking" msgid="3469689394504266039">"Note-taking"</string>
<string name="widget_add_button_label" msgid="2761267068711937179">"Add"</string>
<string name="widget_add_button_content_description" msgid="1810530016360039643">"Add <xliff:g id="WIDGET_NAME">%1$s</xliff:g> widget"</string>
+ <!-- no translation found for widgets_list_expand_button_label (7912016136574932622) -->
+ <skip />
+ <!-- no translation found for widgets_list_expand_button_content_description (4600513860973450888) -->
+ <skip />
+ <!-- no translation found for widgets_list_expanded (7374857868788557730) -->
+ <skip />
<string name="reconfigurable_widget_education_tip" msgid="6336962690888067057">"Tap to change widget settings"</string>
<string name="widget_reconfigure_button_content_description" msgid="8811472721881205250">"Change widget settings"</string>
<string name="all_apps_search_bar_hint" msgid="1390553134053255246">"Search apps"</string>
@@ -124,6 +130,10 @@
<string name="msg_disabled_by_admin" msgid="6898038085516271325">"Disabled by your admin"</string>
<string name="allow_rotation_title" msgid="7222049633713050106">"Allow home screen rotation"</string>
<string name="allow_rotation_desc" msgid="8662546029078692509">"When phone is rotated"</string>
+ <!-- no translation found for landscape_mode_title (5138814555934843926) -->
+ <skip />
+ <!-- no translation found for landscape_mode_desc (7372569859592816793) -->
+ <skip />
<string name="notification_dots_title" msgid="9062440428204120317">"Notification dots"</string>
<string name="notification_dots_desc_on" msgid="1679848116452218908">"On"</string>
<string name="notification_dots_desc_off" msgid="1760796511504341095">"Off"</string>
@@ -142,7 +152,8 @@
<string name="app_installing_title" msgid="5864044122733792085">"<xliff:g id="NAME">%1$s</xliff:g> installing, <xliff:g id="PROGRESS">%2$s</xliff:g> complete"</string>
<string name="app_downloading_title" msgid="8336702962104482644">"<xliff:g id="NAME">%1$s</xliff:g> downloading, <xliff:g id="PROGRESS">%2$s</xliff:g> complete"</string>
<string name="app_waiting_download_title" msgid="7053938513995617849">"<xliff:g id="NAME">%1$s</xliff:g> waiting to install"</string>
- <string name="app_archived_title" msgid="7717956158562544081">"<xliff:g id="NAME">%1$s</xliff:g> is archived. Tap to download and restore."</string>
+ <string name="app_archived_title" msgid="4548283110222420708">"<xliff:g id="NAME">%1$s</xliff:g> is archived."</string>
+ <string name="app_unarchiving_action" msgid="5736107006413929484">"download and restore"</string>
<string name="dialog_update_title" msgid="114234265740994042">"App update required"</string>
<string name="dialog_update_message" msgid="4176784553982226114">"The app for this icon isn\'t updated. You can update manually to re-enable this shortcut or remove the icon."</string>
<string name="dialog_update" msgid="2178028071796141234">"Update"</string>
@@ -187,6 +198,8 @@
<string name="work_apps_paused_edu_accept" msgid="6377476824357318532">"OK"</string>
<string name="work_apps_pause_btn_text" msgid="4669288269140620646">"Pause work apps"</string>
<string name="work_apps_enable_btn_text" msgid="1736198302467317371">"Unpause"</string>
+ <!-- no translation found for work_scheduler_button_content_description (917340740986764967) -->
+ <skip />
<string name="developer_options_filter_hint" msgid="5896817443635989056">"Filter"</string>
<string name="remote_action_failed" msgid="1383965239183576790">"Failed: <xliff:g id="WHAT">%1$s</xliff:g>"</string>
<string name="private_space_label" msgid="2359721649407947001">"Private space"</string>
diff --git a/res/values-es-rUS/strings.xml b/res/values-es-rUS/strings.xml
index 0125ae5..44147c2 100644
--- a/res/values-es-rUS/strings.xml
+++ b/res/values-es-rUS/strings.xml
@@ -69,6 +69,12 @@
<string name="widget_category_note_taking" msgid="3469689394504266039">"Tomar notas"</string>
<string name="widget_add_button_label" msgid="2761267068711937179">"Agregar"</string>
<string name="widget_add_button_content_description" msgid="1810530016360039643">"Agregar widget <xliff:g id="WIDGET_NAME">%1$s</xliff:g>"</string>
+ <!-- no translation found for widgets_list_expand_button_label (7912016136574932622) -->
+ <skip />
+ <!-- no translation found for widgets_list_expand_button_content_description (4600513860973450888) -->
+ <skip />
+ <!-- no translation found for widgets_list_expanded (7374857868788557730) -->
+ <skip />
<string name="reconfigurable_widget_education_tip" msgid="6336962690888067057">"Presiona para cambiar la configuración del widget"</string>
<string name="widget_reconfigure_button_content_description" msgid="8811472721881205250">"Cambiar la configuración del widget"</string>
<string name="all_apps_search_bar_hint" msgid="1390553134053255246">"Buscar apps"</string>
@@ -124,6 +130,10 @@
<string name="msg_disabled_by_admin" msgid="6898038085516271325">"El administrador inhabilitó esta función"</string>
<string name="allow_rotation_title" msgid="7222049633713050106">"Permitir la rotación de la pantalla principal"</string>
<string name="allow_rotation_desc" msgid="8662546029078692509">"Al girar el teléfono"</string>
+ <!-- no translation found for landscape_mode_title (5138814555934843926) -->
+ <skip />
+ <!-- no translation found for landscape_mode_desc (7372569859592816793) -->
+ <skip />
<string name="notification_dots_title" msgid="9062440428204120317">"Puntos de notificación"</string>
<string name="notification_dots_desc_on" msgid="1679848116452218908">"Activados"</string>
<string name="notification_dots_desc_off" msgid="1760796511504341095">"Desactivados"</string>
@@ -142,7 +152,8 @@
<string name="app_installing_title" msgid="5864044122733792085">"Se está instalando <xliff:g id="NAME">%1$s</xliff:g>; <xliff:g id="PROGRESS">%2$s</xliff:g> completado"</string>
<string name="app_downloading_title" msgid="8336702962104482644">"Se completó el <xliff:g id="PROGRESS">%2$s</xliff:g> de la descarga de <xliff:g id="NAME">%1$s</xliff:g>"</string>
<string name="app_waiting_download_title" msgid="7053938513995617849">"Instalación de <xliff:g id="NAME">%1$s</xliff:g> en espera"</string>
- <string name="app_archived_title" msgid="7717956158562544081">"<xliff:g id="NAME">%1$s</xliff:g> está archivada. Presiona para descargar y restablecer."</string>
+ <string name="app_archived_title" msgid="4548283110222420708">"<xliff:g id="NAME">%1$s</xliff:g> está archivada."</string>
+ <string name="app_unarchiving_action" msgid="5736107006413929484">"descargar y restablecer"</string>
<string name="dialog_update_title" msgid="114234265740994042">"Es necesario actualizar la app"</string>
<string name="dialog_update_message" msgid="4176784553982226114">"No se actualizó la app de este ícono. Puedes actualizarla manualmente para rehabilitar el acceso directo, o bien quitar el ícono."</string>
<string name="dialog_update" msgid="2178028071796141234">"Actualizar"</string>
@@ -187,6 +198,8 @@
<string name="work_apps_paused_edu_accept" msgid="6377476824357318532">"Entendido"</string>
<string name="work_apps_pause_btn_text" msgid="4669288269140620646">"Detener apps de trabajo"</string>
<string name="work_apps_enable_btn_text" msgid="1736198302467317371">"Reanudar"</string>
+ <!-- no translation found for work_scheduler_button_content_description (917340740986764967) -->
+ <skip />
<string name="developer_options_filter_hint" msgid="5896817443635989056">"Filtro"</string>
<string name="remote_action_failed" msgid="1383965239183576790">"Error: <xliff:g id="WHAT">%1$s</xliff:g>"</string>
<string name="private_space_label" msgid="2359721649407947001">"Espacio privado"</string>
diff --git a/res/values-es/strings.xml b/res/values-es/strings.xml
index ddcee65..40e04d5 100644
--- a/res/values-es/strings.xml
+++ b/res/values-es/strings.xml
@@ -69,6 +69,12 @@
<string name="widget_category_note_taking" msgid="3469689394504266039">"Toma de notas"</string>
<string name="widget_add_button_label" msgid="2761267068711937179">"Añadir"</string>
<string name="widget_add_button_content_description" msgid="1810530016360039643">"Añadir widget <xliff:g id="WIDGET_NAME">%1$s</xliff:g>"</string>
+ <!-- no translation found for widgets_list_expand_button_label (7912016136574932622) -->
+ <skip />
+ <!-- no translation found for widgets_list_expand_button_content_description (4600513860973450888) -->
+ <skip />
+ <!-- no translation found for widgets_list_expanded (7374857868788557730) -->
+ <skip />
<string name="reconfigurable_widget_education_tip" msgid="6336962690888067057">"Toca para cambiar los ajustes del widget"</string>
<string name="widget_reconfigure_button_content_description" msgid="8811472721881205250">"Cambiar ajustes del widget"</string>
<string name="all_apps_search_bar_hint" msgid="1390553134053255246">"Buscar aplicaciones"</string>
@@ -124,6 +130,10 @@
<string name="msg_disabled_by_admin" msgid="6898038085516271325">"Inhabilitado por el administrador"</string>
<string name="allow_rotation_title" msgid="7222049633713050106">"Permitir rotación de la pantalla de inicio"</string>
<string name="allow_rotation_desc" msgid="8662546029078692509">"Al girar el teléfono"</string>
+ <!-- no translation found for landscape_mode_title (5138814555934843926) -->
+ <skip />
+ <!-- no translation found for landscape_mode_desc (7372569859592816793) -->
+ <skip />
<string name="notification_dots_title" msgid="9062440428204120317">"Burbujas de notificación"</string>
<string name="notification_dots_desc_on" msgid="1679848116452218908">"Activado"</string>
<string name="notification_dots_desc_off" msgid="1760796511504341095">"Desactivadas"</string>
@@ -142,7 +152,8 @@
<string name="app_installing_title" msgid="5864044122733792085">"Instalando <xliff:g id="NAME">%1$s</xliff:g>, <xliff:g id="PROGRESS">%2$s</xliff:g> completado"</string>
<string name="app_downloading_title" msgid="8336702962104482644">"Descargando <xliff:g id="NAME">%1$s</xliff:g> (<xliff:g id="PROGRESS">%2$s</xliff:g> completado)"</string>
<string name="app_waiting_download_title" msgid="7053938513995617849">"Esperando para instalar <xliff:g id="NAME">%1$s</xliff:g>"</string>
- <string name="app_archived_title" msgid="7717956158562544081">"<xliff:g id="NAME">%1$s</xliff:g> está archivada. Toca para descargar y restaurar."</string>
+ <string name="app_archived_title" msgid="4548283110222420708">"<xliff:g id="NAME">%1$s</xliff:g> está archivada."</string>
+ <string name="app_unarchiving_action" msgid="5736107006413929484">"descargar y restaurar"</string>
<string name="dialog_update_title" msgid="114234265740994042">"Debes actualizar la aplicación"</string>
<string name="dialog_update_message" msgid="4176784553982226114">"La aplicación de este icono no está actualizada. Puedes actualizarla manualmente para volver a habilitar este acceso directo o puedes eliminar el icono."</string>
<string name="dialog_update" msgid="2178028071796141234">"Actualizar"</string>
@@ -187,6 +198,8 @@
<string name="work_apps_paused_edu_accept" msgid="6377476824357318532">"Entendido"</string>
<string name="work_apps_pause_btn_text" msgid="4669288269140620646">"Pausar aplicaciones de trabajo"</string>
<string name="work_apps_enable_btn_text" msgid="1736198302467317371">"Reanudar"</string>
+ <!-- no translation found for work_scheduler_button_content_description (917340740986764967) -->
+ <skip />
<string name="developer_options_filter_hint" msgid="5896817443635989056">"Filtro"</string>
<string name="remote_action_failed" msgid="1383965239183576790">"Se ha producido un error: <xliff:g id="WHAT">%1$s</xliff:g>"</string>
<string name="private_space_label" msgid="2359721649407947001">"Espacio privado"</string>
diff --git a/res/values-et/strings.xml b/res/values-et/strings.xml
index 289b9d9..de62de1 100644
--- a/res/values-et/strings.xml
+++ b/res/values-et/strings.xml
@@ -69,6 +69,12 @@
<string name="widget_category_note_taking" msgid="3469689394504266039">"Märkmete tegemine"</string>
<string name="widget_add_button_label" msgid="2761267068711937179">"Lisa"</string>
<string name="widget_add_button_content_description" msgid="1810530016360039643">"Lisa vidin <xliff:g id="WIDGET_NAME">%1$s</xliff:g>"</string>
+ <!-- no translation found for widgets_list_expand_button_label (7912016136574932622) -->
+ <skip />
+ <!-- no translation found for widgets_list_expand_button_content_description (4600513860973450888) -->
+ <skip />
+ <!-- no translation found for widgets_list_expanded (7374857868788557730) -->
+ <skip />
<string name="reconfigurable_widget_education_tip" msgid="6336962690888067057">"Puudutage vidina seadete muutmiseks"</string>
<string name="widget_reconfigure_button_content_description" msgid="8811472721881205250">"Vidina seadete muutmine"</string>
<string name="all_apps_search_bar_hint" msgid="1390553134053255246">"Otsige rakendusi"</string>
@@ -124,6 +130,10 @@
<string name="msg_disabled_by_admin" msgid="6898038085516271325">"Keelas administraator"</string>
<string name="allow_rotation_title" msgid="7222049633713050106">"Luba avakuva pööramine"</string>
<string name="allow_rotation_desc" msgid="8662546029078692509">"Kui telefoni pööratakse"</string>
+ <!-- no translation found for landscape_mode_title (5138814555934843926) -->
+ <skip />
+ <!-- no translation found for landscape_mode_desc (7372569859592816793) -->
+ <skip />
<string name="notification_dots_title" msgid="9062440428204120317">"Märguandetäpid"</string>
<string name="notification_dots_desc_on" msgid="1679848116452218908">"Sees"</string>
<string name="notification_dots_desc_off" msgid="1760796511504341095">"Väljas"</string>
@@ -142,7 +152,8 @@
<string name="app_installing_title" msgid="5864044122733792085">"Üksust <xliff:g id="NAME">%1$s</xliff:g> installitakse, <xliff:g id="PROGRESS">%2$s</xliff:g> on valmis"</string>
<string name="app_downloading_title" msgid="8336702962104482644">"Rakenduse <xliff:g id="NAME">%1$s</xliff:g> allalaadimine, <xliff:g id="PROGRESS">%2$s</xliff:g> on valmis"</string>
<string name="app_waiting_download_title" msgid="7053938513995617849">"<xliff:g id="NAME">%1$s</xliff:g> on installimise ootel"</string>
- <string name="app_archived_title" msgid="7717956158562544081">"<xliff:g id="NAME">%1$s</xliff:g> on arhiivitud. Puudutage allalaadimiseks ja taastamiseks."</string>
+ <string name="app_archived_title" msgid="4548283110222420708">"<xliff:g id="NAME">%1$s</xliff:g> on arhiivitud."</string>
+ <string name="app_unarchiving_action" msgid="5736107006413929484">"laadi alla ja taasta"</string>
<string name="dialog_update_title" msgid="114234265740994042">"Rakendust tuleb värskendada"</string>
<string name="dialog_update_message" msgid="4176784553982226114">"Selle ikooni rakendust pole värskendatud. Otsetee uuesti lubamiseks võite rakendust käsitsi värskendada või ikooni eemaldada."</string>
<string name="dialog_update" msgid="2178028071796141234">"Värskenda"</string>
@@ -187,6 +198,8 @@
<string name="work_apps_paused_edu_accept" msgid="6377476824357318532">"Selge"</string>
<string name="work_apps_pause_btn_text" msgid="4669288269140620646">"Peata töörakendused"</string>
<string name="work_apps_enable_btn_text" msgid="1736198302467317371">"Lõpeta peatamine"</string>
+ <!-- no translation found for work_scheduler_button_content_description (917340740986764967) -->
+ <skip />
<string name="developer_options_filter_hint" msgid="5896817443635989056">"Filter"</string>
<string name="remote_action_failed" msgid="1383965239183576790">"Nurjus: <xliff:g id="WHAT">%1$s</xliff:g>"</string>
<string name="private_space_label" msgid="2359721649407947001">"Privaatne ruum"</string>
diff --git a/res/values-eu/strings.xml b/res/values-eu/strings.xml
index db99806..27510b3 100644
--- a/res/values-eu/strings.xml
+++ b/res/values-eu/strings.xml
@@ -69,6 +69,12 @@
<string name="widget_category_note_taking" msgid="3469689394504266039">"Oharrak idazteko"</string>
<string name="widget_add_button_label" msgid="2761267068711937179">"Gehitu"</string>
<string name="widget_add_button_content_description" msgid="1810530016360039643">"Gehitu <xliff:g id="WIDGET_NAME">%1$s</xliff:g> widgeta"</string>
+ <!-- no translation found for widgets_list_expand_button_label (7912016136574932622) -->
+ <skip />
+ <!-- no translation found for widgets_list_expand_button_content_description (4600513860973450888) -->
+ <skip />
+ <!-- no translation found for widgets_list_expanded (7374857868788557730) -->
+ <skip />
<string name="reconfigurable_widget_education_tip" msgid="6336962690888067057">"Sakatu hau widgeten ezarpenak aldatzeko"</string>
<string name="widget_reconfigure_button_content_description" msgid="8811472721881205250">"Aldatu widgeten ezarpenak"</string>
<string name="all_apps_search_bar_hint" msgid="1390553134053255246">"Bilatu aplikazioetan"</string>
@@ -124,6 +130,10 @@
<string name="msg_disabled_by_admin" msgid="6898038085516271325">"Administratzaileak desgaitu du"</string>
<string name="allow_rotation_title" msgid="7222049633713050106">"Eman orri nagusia biratzeko baimena"</string>
<string name="allow_rotation_desc" msgid="8662546029078692509">"Telefonoa biratzean"</string>
+ <!-- no translation found for landscape_mode_title (5138814555934843926) -->
+ <skip />
+ <!-- no translation found for landscape_mode_desc (7372569859592816793) -->
+ <skip />
<string name="notification_dots_title" msgid="9062440428204120317">"Jakinarazpen-biribiltxoak"</string>
<string name="notification_dots_desc_on" msgid="1679848116452218908">"Aktibatuta"</string>
<string name="notification_dots_desc_off" msgid="1760796511504341095">"Desaktibatuta"</string>
@@ -142,7 +152,8 @@
<string name="app_installing_title" msgid="5864044122733792085">"<xliff:g id="NAME">%1$s</xliff:g> instalatzen, <xliff:g id="PROGRESS">%2$s</xliff:g> osatuta"</string>
<string name="app_downloading_title" msgid="8336702962104482644">"<xliff:g id="NAME">%1$s</xliff:g> deskargatzen, <xliff:g id="PROGRESS">%2$s</xliff:g> osatuta"</string>
<string name="app_waiting_download_title" msgid="7053938513995617849">"<xliff:g id="NAME">%1$s</xliff:g> instalatzeko zain"</string>
- <string name="app_archived_title" msgid="7717956158562544081">"<xliff:g id="NAME">%1$s</xliff:g> artxibatuta dago. Sakatu deskargatzeko eta leheneratzeko."</string>
+ <string name="app_archived_title" msgid="4548283110222420708">"<xliff:g id="NAME">%1$s</xliff:g> artxibatuta dago."</string>
+ <string name="app_unarchiving_action" msgid="5736107006413929484">"deskargatu eta leheneratu"</string>
<string name="dialog_update_title" msgid="114234265740994042">"Aplikazioa eguneratu egin behar da"</string>
<string name="dialog_update_message" msgid="4176784553982226114">"Ikonoaren aplikazioa ez dago eguneratuta. Lasterbidea berriro gaitzeko, eskuz egunera dezakezu aplikazioa. Bestela, kendu ikonoa."</string>
<string name="dialog_update" msgid="2178028071796141234">"Eguneratu"</string>
@@ -187,6 +198,8 @@
<string name="work_apps_paused_edu_accept" msgid="6377476824357318532">"Ados"</string>
<string name="work_apps_pause_btn_text" msgid="4669288269140620646">"Pausatu laneko aplikazioak"</string>
<string name="work_apps_enable_btn_text" msgid="1736198302467317371">"Aktibatu berriro"</string>
+ <!-- no translation found for work_scheduler_button_content_description (917340740986764967) -->
+ <skip />
<string name="developer_options_filter_hint" msgid="5896817443635989056">"Iragazi"</string>
<string name="remote_action_failed" msgid="1383965239183576790">"Huts egin du: <xliff:g id="WHAT">%1$s</xliff:g>"</string>
<string name="private_space_label" msgid="2359721649407947001">"Eremu pribatua"</string>
diff --git a/res/values-fa/strings.xml b/res/values-fa/strings.xml
index 17dd851..8a21dc7 100644
--- a/res/values-fa/strings.xml
+++ b/res/values-fa/strings.xml
@@ -69,6 +69,12 @@
<string name="widget_category_note_taking" msgid="3469689394504266039">"یادداشتبرداری"</string>
<string name="widget_add_button_label" msgid="2761267068711937179">"افزودن"</string>
<string name="widget_add_button_content_description" msgid="1810530016360039643">"افزودن ابزاره <xliff:g id="WIDGET_NAME">%1$s</xliff:g>"</string>
+ <!-- no translation found for widgets_list_expand_button_label (7912016136574932622) -->
+ <skip />
+ <!-- no translation found for widgets_list_expand_button_content_description (4600513860973450888) -->
+ <skip />
+ <!-- no translation found for widgets_list_expanded (7374857868788557730) -->
+ <skip />
<string name="reconfigurable_widget_education_tip" msgid="6336962690888067057">"برای تغییر تنظیمات ابزاره، تکضرب بزنید"</string>
<string name="widget_reconfigure_button_content_description" msgid="8811472721881205250">"تغییر تنظیمات ابزاره"</string>
<string name="all_apps_search_bar_hint" msgid="1390553134053255246">"جستجوی برنامهها"</string>
@@ -124,6 +130,10 @@
<string name="msg_disabled_by_admin" msgid="6898038085516271325">"توسط سرپرست سیستم غیرفعال شده است"</string>
<string name="allow_rotation_title" msgid="7222049633713050106">"مجاز کردن چرخش صفحه اصلی"</string>
<string name="allow_rotation_desc" msgid="8662546029078692509">"وقتی تلفن چرخانده میشود"</string>
+ <!-- no translation found for landscape_mode_title (5138814555934843926) -->
+ <skip />
+ <!-- no translation found for landscape_mode_desc (7372569859592816793) -->
+ <skip />
<string name="notification_dots_title" msgid="9062440428204120317">"نقطههای اعلان"</string>
<string name="notification_dots_desc_on" msgid="1679848116452218908">"روشن"</string>
<string name="notification_dots_desc_off" msgid="1760796511504341095">"خاموش"</string>
@@ -142,7 +152,8 @@
<string name="app_installing_title" msgid="5864044122733792085">"<xliff:g id="NAME">%1$s</xliff:g> درحال نصب است، <xliff:g id="PROGRESS">%2$s</xliff:g> تکمیل شده است"</string>
<string name="app_downloading_title" msgid="8336702962104482644">"درحال بارگیری <xliff:g id="NAME">%1$s</xliff:g>، <xliff:g id="PROGRESS">%2$s</xliff:g> کامل شد"</string>
<string name="app_waiting_download_title" msgid="7053938513995617849">"<xliff:g id="NAME">%1$s</xliff:g> درانتظار نصب"</string>
- <string name="app_archived_title" msgid="7717956158562544081">"<xliff:g id="NAME">%1$s</xliff:g> بایگانی شده است. برای بارگیری و بازیابی تکضرب بزنید."</string>
+ <string name="app_archived_title" msgid="4548283110222420708">"<xliff:g id="NAME">%1$s</xliff:g> بایگانی شده است."</string>
+ <string name="app_unarchiving_action" msgid="5736107006413929484">"بارگیری و بازیابی کردن"</string>
<string name="dialog_update_title" msgid="114234265740994042">"برنامه باید بهروز شود"</string>
<string name="dialog_update_message" msgid="4176784553982226114">"برنامه برای این نماد بهروز نشده است. میتوانید آن را بهصورت دستی بهروز کنید تا میانبر دوباره فعال شود، یا نماد را بردارید."</string>
<string name="dialog_update" msgid="2178028071796141234">"بهروزرسانی"</string>
@@ -187,6 +198,8 @@
<string name="work_apps_paused_edu_accept" msgid="6377476824357318532">"متوجهام"</string>
<string name="work_apps_pause_btn_text" msgid="4669288269140620646">"توقف موقت برنامههای کاری"</string>
<string name="work_apps_enable_btn_text" msgid="1736198302467317371">"ازسرگیری"</string>
+ <!-- no translation found for work_scheduler_button_content_description (917340740986764967) -->
+ <skip />
<string name="developer_options_filter_hint" msgid="5896817443635989056">"فیلتر"</string>
<string name="remote_action_failed" msgid="1383965239183576790">"ناموفق بود: <xliff:g id="WHAT">%1$s</xliff:g>"</string>
<string name="private_space_label" msgid="2359721649407947001">"فضای خصوصی"</string>
diff --git a/res/values-fi/strings.xml b/res/values-fi/strings.xml
index c61c85a..c778a61 100644
--- a/res/values-fi/strings.xml
+++ b/res/values-fi/strings.xml
@@ -69,6 +69,12 @@
<string name="widget_category_note_taking" msgid="3469689394504266039">"Muistiinpanojen tekeminen"</string>
<string name="widget_add_button_label" msgid="2761267068711937179">"Lisää"</string>
<string name="widget_add_button_content_description" msgid="1810530016360039643">"Lisää widget: <xliff:g id="WIDGET_NAME">%1$s</xliff:g>"</string>
+ <!-- no translation found for widgets_list_expand_button_label (7912016136574932622) -->
+ <skip />
+ <!-- no translation found for widgets_list_expand_button_content_description (4600513860973450888) -->
+ <skip />
+ <!-- no translation found for widgets_list_expanded (7374857868788557730) -->
+ <skip />
<string name="reconfigurable_widget_education_tip" msgid="6336962690888067057">"Napauta, niin voit muuttaa widgetin asetuksia"</string>
<string name="widget_reconfigure_button_content_description" msgid="8811472721881205250">"Muuta widgetin asetuksia"</string>
<string name="all_apps_search_bar_hint" msgid="1390553134053255246">"Hae sovelluksia"</string>
@@ -124,6 +130,10 @@
<string name="msg_disabled_by_admin" msgid="6898038085516271325">"Järjestelmänvalvoja on poistanut toiminnon käytöstä."</string>
<string name="allow_rotation_title" msgid="7222049633713050106">"Salli aloitusnäytön kiertäminen"</string>
<string name="allow_rotation_desc" msgid="8662546029078692509">"Kun puhelinta kierretään"</string>
+ <!-- no translation found for landscape_mode_title (5138814555934843926) -->
+ <skip />
+ <!-- no translation found for landscape_mode_desc (7372569859592816793) -->
+ <skip />
<string name="notification_dots_title" msgid="9062440428204120317">"Pistemerkit"</string>
<string name="notification_dots_desc_on" msgid="1679848116452218908">"Päällä"</string>
<string name="notification_dots_desc_off" msgid="1760796511504341095">"Ei päällä"</string>
@@ -142,7 +152,8 @@
<string name="app_installing_title" msgid="5864044122733792085">"<xliff:g id="NAME">%1$s</xliff:g> asennetaan, <xliff:g id="PROGRESS">%2$s</xliff:g> valmis"</string>
<string name="app_downloading_title" msgid="8336702962104482644">"<xliff:g id="NAME">%1$s</xliff:g> latautuu, valmiina <xliff:g id="PROGRESS">%2$s</xliff:g>"</string>
<string name="app_waiting_download_title" msgid="7053938513995617849">"<xliff:g id="NAME">%1$s</xliff:g> odottaa asennusta"</string>
- <string name="app_archived_title" msgid="7717956158562544081">"<xliff:g id="NAME">%1$s</xliff:g> on arkistoitu. Lataa ja palauta napauttamalla."</string>
+ <string name="app_archived_title" msgid="4548283110222420708">"<xliff:g id="NAME">%1$s</xliff:g> on arkistoitu."</string>
+ <string name="app_unarchiving_action" msgid="5736107006413929484">"lataa ja palauta"</string>
<string name="dialog_update_title" msgid="114234265740994042">"Sovelluspäivitys vaaditaan"</string>
<string name="dialog_update_message" msgid="4176784553982226114">"Kuvakkeen sovellusta ei ole päivitetty. Voit ottaa pikakuvakkeen uudelleen käyttöön päivittämällä sovelluksen tai poistaa kuvakkeen."</string>
<string name="dialog_update" msgid="2178028071796141234">"Päivitä"</string>
@@ -187,6 +198,8 @@
<string name="work_apps_paused_edu_accept" msgid="6377476824357318532">"OK"</string>
<string name="work_apps_pause_btn_text" msgid="4669288269140620646">"Keskeytä työsovellusten käyttö"</string>
<string name="work_apps_enable_btn_text" msgid="1736198302467317371">"Jatka"</string>
+ <!-- no translation found for work_scheduler_button_content_description (917340740986764967) -->
+ <skip />
<string name="developer_options_filter_hint" msgid="5896817443635989056">"Suodatin"</string>
<string name="remote_action_failed" msgid="1383965239183576790">"Epäonnistui: <xliff:g id="WHAT">%1$s</xliff:g>"</string>
<string name="private_space_label" msgid="2359721649407947001">"Yksityinen tila"</string>
diff --git a/res/values-fr-rCA/strings.xml b/res/values-fr-rCA/strings.xml
index a941d88..1f5e264 100644
--- a/res/values-fr-rCA/strings.xml
+++ b/res/values-fr-rCA/strings.xml
@@ -69,6 +69,12 @@
<string name="widget_category_note_taking" msgid="3469689394504266039">"Prise de note"</string>
<string name="widget_add_button_label" msgid="2761267068711937179">"Ajouter"</string>
<string name="widget_add_button_content_description" msgid="1810530016360039643">"Ajoutez le widget <xliff:g id="WIDGET_NAME">%1$s</xliff:g>"</string>
+ <!-- no translation found for widgets_list_expand_button_label (7912016136574932622) -->
+ <skip />
+ <!-- no translation found for widgets_list_expand_button_content_description (4600513860973450888) -->
+ <skip />
+ <!-- no translation found for widgets_list_expanded (7374857868788557730) -->
+ <skip />
<string name="reconfigurable_widget_education_tip" msgid="6336962690888067057">"Touchez pour modifier les paramètres du widget"</string>
<string name="widget_reconfigure_button_content_description" msgid="8811472721881205250">"Modifier les paramètres du widget"</string>
<string name="all_apps_search_bar_hint" msgid="1390553134053255246">"Rechercher dans les applis"</string>
@@ -124,6 +130,10 @@
<string name="msg_disabled_by_admin" msgid="6898038085516271325">"Cette fonction est désactivée par votre administrateur"</string>
<string name="allow_rotation_title" msgid="7222049633713050106">"Autoriser la rotation de l\'écran d\'accueil"</string>
<string name="allow_rotation_desc" msgid="8662546029078692509">"Lorsque vous faites pivoter le téléphone"</string>
+ <!-- no translation found for landscape_mode_title (5138814555934843926) -->
+ <skip />
+ <!-- no translation found for landscape_mode_desc (7372569859592816793) -->
+ <skip />
<string name="notification_dots_title" msgid="9062440428204120317">"Pastilles de notification"</string>
<string name="notification_dots_desc_on" msgid="1679848116452218908">"Activé"</string>
<string name="notification_dots_desc_off" msgid="1760796511504341095">"Désactivé"</string>
@@ -142,7 +152,8 @@
<string name="app_installing_title" msgid="5864044122733792085">"Installation de l\'appli <xliff:g id="NAME">%1$s</xliff:g> en cours, <xliff:g id="PROGRESS">%2$s</xliff:g> terminée"</string>
<string name="app_downloading_title" msgid="8336702962104482644">"Téléchargement de <xliff:g id="NAME">%1$s</xliff:g> : <xliff:g id="PROGRESS">%2$s</xliff:g>"</string>
<string name="app_waiting_download_title" msgid="7053938513995617849">"<xliff:g id="NAME">%1$s</xliff:g> en attente d\'installation"</string>
- <string name="app_archived_title" msgid="7717956158562544081">"L\'appli <xliff:g id="NAME">%1$s</xliff:g> est archivée. Touchez le bouton pour télécharger et restaurer l\'appli."</string>
+ <string name="app_archived_title" msgid="4548283110222420708">"L\'appli <xliff:g id="NAME">%1$s</xliff:g> est archivée."</string>
+ <string name="app_unarchiving_action" msgid="5736107006413929484">"télécharger et restaurer"</string>
<string name="dialog_update_title" msgid="114234265740994042">"Mise à jour de l\'appli requise"</string>
<string name="dialog_update_message" msgid="4176784553982226114">"L\'appli pour cette icône n\'est pas à jour. Vous pouvez soit la mettre à jour manuellement pour réactiver ce raccourci, soit retirer l\'icône."</string>
<string name="dialog_update" msgid="2178028071796141234">"Mettre à jour"</string>
@@ -187,6 +198,8 @@
<string name="work_apps_paused_edu_accept" msgid="6377476824357318532">"OK"</string>
<string name="work_apps_pause_btn_text" msgid="4669288269140620646">"Mettre en pause les applis professionnelles"</string>
<string name="work_apps_enable_btn_text" msgid="1736198302467317371">"Réactiver"</string>
+ <!-- no translation found for work_scheduler_button_content_description (917340740986764967) -->
+ <skip />
<string name="developer_options_filter_hint" msgid="5896817443635989056">"Filtrer"</string>
<string name="remote_action_failed" msgid="1383965239183576790">"Échec : <xliff:g id="WHAT">%1$s</xliff:g>"</string>
<string name="private_space_label" msgid="2359721649407947001">"Espace privé"</string>
diff --git a/res/values-fr/strings.xml b/res/values-fr/strings.xml
index 6cbc921..a5b9a32 100644
--- a/res/values-fr/strings.xml
+++ b/res/values-fr/strings.xml
@@ -69,6 +69,12 @@
<string name="widget_category_note_taking" msgid="3469689394504266039">"Prise de notes"</string>
<string name="widget_add_button_label" msgid="2761267068711937179">"Ajouter"</string>
<string name="widget_add_button_content_description" msgid="1810530016360039643">"Ajoutez un widget <xliff:g id="WIDGET_NAME">%1$s</xliff:g>"</string>
+ <!-- no translation found for widgets_list_expand_button_label (7912016136574932622) -->
+ <skip />
+ <!-- no translation found for widgets_list_expand_button_content_description (4600513860973450888) -->
+ <skip />
+ <!-- no translation found for widgets_list_expanded (7374857868788557730) -->
+ <skip />
<string name="reconfigurable_widget_education_tip" msgid="6336962690888067057">"Appuyez pour modifier les paramètres du widget"</string>
<string name="widget_reconfigure_button_content_description" msgid="8811472721881205250">"Modifier les paramètres du widget"</string>
<string name="all_apps_search_bar_hint" msgid="1390553134053255246">"Rechercher dans les applications"</string>
@@ -124,6 +130,10 @@
<string name="msg_disabled_by_admin" msgid="6898038085516271325">"Désactivé par votre administrateur"</string>
<string name="allow_rotation_title" msgid="7222049633713050106">"Autoriser la rotation de l\'écran d\'accueil"</string>
<string name="allow_rotation_desc" msgid="8662546029078692509">"Lorsque vous faites pivoter le téléphone"</string>
+ <!-- no translation found for landscape_mode_title (5138814555934843926) -->
+ <skip />
+ <!-- no translation found for landscape_mode_desc (7372569859592816793) -->
+ <skip />
<string name="notification_dots_title" msgid="9062440428204120317">"Pastilles de notification"</string>
<string name="notification_dots_desc_on" msgid="1679848116452218908">"Activées"</string>
<string name="notification_dots_desc_off" msgid="1760796511504341095">"Désactivées"</string>
@@ -142,7 +152,8 @@
<string name="app_installing_title" msgid="5864044122733792085">"Installation de <xliff:g id="NAME">%1$s</xliff:g>… (<xliff:g id="PROGRESS">%2$s</xliff:g> terminés)"</string>
<string name="app_downloading_title" msgid="8336702962104482644">"<xliff:g id="NAME">%1$s</xliff:g> en cours de téléchargement, <xliff:g id="PROGRESS">%2$s</xliff:g> effectué(s)"</string>
<string name="app_waiting_download_title" msgid="7053938513995617849">"<xliff:g id="NAME">%1$s</xliff:g> en attente d\'installation"</string>
- <string name="app_archived_title" msgid="7717956158562544081">"L\'application <xliff:g id="NAME">%1$s</xliff:g> est archivée. Appuyez pour la télécharger et la restaurer."</string>
+ <string name="app_archived_title" msgid="4548283110222420708">"L\'application <xliff:g id="NAME">%1$s</xliff:g> est archivée."</string>
+ <string name="app_unarchiving_action" msgid="5736107006413929484">"télécharger et restaurer"</string>
<string name="dialog_update_title" msgid="114234265740994042">"Mise à jour de l\'appli requise"</string>
<string name="dialog_update_message" msgid="4176784553982226114">"L\'appli correspondant à cette icône n\'est pas mise à jour. Vous pouvez la mettre à jour manuellement pour réactiver le raccourci ou supprimer l\'icône."</string>
<string name="dialog_update" msgid="2178028071796141234">"Modifier"</string>
@@ -187,6 +198,8 @@
<string name="work_apps_paused_edu_accept" msgid="6377476824357318532">"OK"</string>
<string name="work_apps_pause_btn_text" msgid="4669288269140620646">"Mettre en pause les applis professionnelles"</string>
<string name="work_apps_enable_btn_text" msgid="1736198302467317371">"Réactiver"</string>
+ <!-- no translation found for work_scheduler_button_content_description (917340740986764967) -->
+ <skip />
<string name="developer_options_filter_hint" msgid="5896817443635989056">"Filtre"</string>
<string name="remote_action_failed" msgid="1383965239183576790">"Échec : <xliff:g id="WHAT">%1$s</xliff:g>"</string>
<string name="private_space_label" msgid="2359721649407947001">"Espace privé"</string>
diff --git a/res/values-gl/strings.xml b/res/values-gl/strings.xml
index 02389c4..ca2861a 100644
--- a/res/values-gl/strings.xml
+++ b/res/values-gl/strings.xml
@@ -69,6 +69,12 @@
<string name="widget_category_note_taking" msgid="3469689394504266039">"Toma de notas"</string>
<string name="widget_add_button_label" msgid="2761267068711937179">"Engadir"</string>
<string name="widget_add_button_content_description" msgid="1810530016360039643">"Engadir o widget <xliff:g id="WIDGET_NAME">%1$s</xliff:g>"</string>
+ <!-- no translation found for widgets_list_expand_button_label (7912016136574932622) -->
+ <skip />
+ <!-- no translation found for widgets_list_expand_button_content_description (4600513860973450888) -->
+ <skip />
+ <!-- no translation found for widgets_list_expanded (7374857868788557730) -->
+ <skip />
<string name="reconfigurable_widget_education_tip" msgid="6336962690888067057">"Toca para cambiar a configuración do widget"</string>
<string name="widget_reconfigure_button_content_description" msgid="8811472721881205250">"Cambiar configuración do widget"</string>
<string name="all_apps_search_bar_hint" msgid="1390553134053255246">"Buscar aplicacións"</string>
@@ -124,6 +130,10 @@
<string name="msg_disabled_by_admin" msgid="6898038085516271325">"Función desactivada polo administrador"</string>
<string name="allow_rotation_title" msgid="7222049633713050106">"Permitir xirar a pantalla de inicio"</string>
<string name="allow_rotation_desc" msgid="8662546029078692509">"Ao xirar o teléfono"</string>
+ <!-- no translation found for landscape_mode_title (5138814555934843926) -->
+ <skip />
+ <!-- no translation found for landscape_mode_desc (7372569859592816793) -->
+ <skip />
<string name="notification_dots_title" msgid="9062440428204120317">"Puntos de notificacións"</string>
<string name="notification_dots_desc_on" msgid="1679848116452218908">"Opción activada"</string>
<string name="notification_dots_desc_off" msgid="1760796511504341095">"Desactivados"</string>
@@ -142,7 +152,8 @@
<string name="app_installing_title" msgid="5864044122733792085">"Instalando <xliff:g id="NAME">%1$s</xliff:g>, <xliff:g id="PROGRESS">%2$s</xliff:g> completado"</string>
<string name="app_downloading_title" msgid="8336702962104482644">"Descargando <xliff:g id="NAME">%1$s</xliff:g> (<xliff:g id="PROGRESS">%2$s</xliff:g> completado)"</string>
<string name="app_waiting_download_title" msgid="7053938513995617849">"Esperando para instalar <xliff:g id="NAME">%1$s</xliff:g>"</string>
- <string name="app_archived_title" msgid="7717956158562544081">"<xliff:g id="NAME">%1$s</xliff:g> está no arquivo. Toca para descargar e restaurar."</string>
+ <string name="app_archived_title" msgid="4548283110222420708">"<xliff:g id="NAME">%1$s</xliff:g> está arquivada."</string>
+ <string name="app_unarchiving_action" msgid="5736107006413929484">"descargar e restaurar"</string>
<string name="dialog_update_title" msgid="114234265740994042">"É necesario actualizar a aplicación"</string>
<string name="dialog_update_message" msgid="4176784553982226114">"A aplicación á que corresponde esta icona non está actualizada. Podes actualizala manualmente para activar de novo este atallo, ou ben quitar a icona."</string>
<string name="dialog_update" msgid="2178028071796141234">"Actualizar"</string>
@@ -187,6 +198,8 @@
<string name="work_apps_paused_edu_accept" msgid="6377476824357318532">"Entendido"</string>
<string name="work_apps_pause_btn_text" msgid="4669288269140620646">"Pór en pausa aplicacións do traballo"</string>
<string name="work_apps_enable_btn_text" msgid="1736198302467317371">"Volver activar"</string>
+ <!-- no translation found for work_scheduler_button_content_description (917340740986764967) -->
+ <skip />
<string name="developer_options_filter_hint" msgid="5896817443635989056">"Filtra"</string>
<string name="remote_action_failed" msgid="1383965239183576790">"Erro: <xliff:g id="WHAT">%1$s</xliff:g>"</string>
<string name="private_space_label" msgid="2359721649407947001">"Espazo privado"</string>
diff --git a/res/values-gu/strings.xml b/res/values-gu/strings.xml
index aca3054..59e3134 100644
--- a/res/values-gu/strings.xml
+++ b/res/values-gu/strings.xml
@@ -69,6 +69,12 @@
<string name="widget_category_note_taking" msgid="3469689394504266039">"નોંધ લેવી"</string>
<string name="widget_add_button_label" msgid="2761267068711937179">"ઉમેરો"</string>
<string name="widget_add_button_content_description" msgid="1810530016360039643">"<xliff:g id="WIDGET_NAME">%1$s</xliff:g> વિજેટ ઉમેરો"</string>
+ <!-- no translation found for widgets_list_expand_button_label (7912016136574932622) -->
+ <skip />
+ <!-- no translation found for widgets_list_expand_button_content_description (4600513860973450888) -->
+ <skip />
+ <!-- no translation found for widgets_list_expanded (7374857868788557730) -->
+ <skip />
<string name="reconfigurable_widget_education_tip" msgid="6336962690888067057">"વિજેટના સેટિંગ બદલવા માટે ટૅપ કરો"</string>
<string name="widget_reconfigure_button_content_description" msgid="8811472721881205250">"વિજેટના સેટિંગ બદલો"</string>
<string name="all_apps_search_bar_hint" msgid="1390553134053255246">"ઍપ શોધો"</string>
@@ -124,6 +130,10 @@
<string name="msg_disabled_by_admin" msgid="6898038085516271325">"તમારા વ્યવસ્થાપક દ્વારા અક્ષમ કરેલ"</string>
<string name="allow_rotation_title" msgid="7222049633713050106">"હોમ સ્ક્રીનને ફેરવવાની મંજૂરી આપો"</string>
<string name="allow_rotation_desc" msgid="8662546029078692509">"જ્યારે ફોન ફેરવવામાં આવે ત્યારે"</string>
+ <!-- no translation found for landscape_mode_title (5138814555934843926) -->
+ <skip />
+ <!-- no translation found for landscape_mode_desc (7372569859592816793) -->
+ <skip />
<string name="notification_dots_title" msgid="9062440428204120317">"નોટિફિકેશન માટેના ચિહ્નો"</string>
<string name="notification_dots_desc_on" msgid="1679848116452218908">"ચાલુ છે"</string>
<string name="notification_dots_desc_off" msgid="1760796511504341095">"બંધ છે"</string>
@@ -142,7 +152,8 @@
<string name="app_installing_title" msgid="5864044122733792085">"<xliff:g id="NAME">%1$s</xliff:g> ઇન્સ્ટૉલ કરી રહ્યાં છીએ, <xliff:g id="PROGRESS">%2$s</xliff:g> પૂર્ણ થયું"</string>
<string name="app_downloading_title" msgid="8336702962104482644">"<xliff:g id="NAME">%1$s</xliff:g> ડાઉનલોડ કરી રહ્યાં છે, <xliff:g id="PROGRESS">%2$s</xliff:g> પૂર્ણ"</string>
<string name="app_waiting_download_title" msgid="7053938513995617849">"<xliff:g id="NAME">%1$s</xliff:g>, ઇન્સ્ટૉલ થવાની રાહ જોઈ રહ્યું છે"</string>
- <string name="app_archived_title" msgid="7717956158562544081">"<xliff:g id="NAME">%1$s</xliff:g>ને આર્કાઇવ કર્યું છે. ડાઉનલોડ અને રિસ્ટોર કરવા માટે ટૅપ કરો."</string>
+ <string name="app_archived_title" msgid="4548283110222420708">"<xliff:g id="NAME">%1$s</xliff:g>ને આર્કાઇવ કર્યું છે."</string>
+ <string name="app_unarchiving_action" msgid="5736107006413929484">"ડાઉનલોડ અને રિસ્ટોર કરો"</string>
<string name="dialog_update_title" msgid="114234265740994042">"ઍપને અપડેટ કરવી જરૂરી છે"</string>
<string name="dialog_update_message" msgid="4176784553982226114">"આ આઇકન માટે ઍપ અપડેટ કરવામાં આવી નથી. તમે આ શૉર્ટકટ ફરી ચાલુ કરવા અથવા આઇકન કાઢી નાખવા માટે ઍપને મેન્યુઅલી અપડેટ કરી શકો છો."</string>
<string name="dialog_update" msgid="2178028071796141234">"અપડેટ કરો"</string>
@@ -187,6 +198,8 @@
<string name="work_apps_paused_edu_accept" msgid="6377476824357318532">"સમજાઈ ગયું"</string>
<string name="work_apps_pause_btn_text" msgid="4669288269140620646">"ઑફિસની ઍપ થોભાવો"</string>
<string name="work_apps_enable_btn_text" msgid="1736198302467317371">"ફરી ચાલુ કરો"</string>
+ <!-- no translation found for work_scheduler_button_content_description (917340740986764967) -->
+ <skip />
<string name="developer_options_filter_hint" msgid="5896817443635989056">"ફિલ્ટર કરો"</string>
<string name="remote_action_failed" msgid="1383965239183576790">"નિષ્ફળ: <xliff:g id="WHAT">%1$s</xliff:g>"</string>
<string name="private_space_label" msgid="2359721649407947001">"ખાનગી સ્પેસ"</string>
diff --git a/res/values-hi/strings.xml b/res/values-hi/strings.xml
index 00726ea..c26cafb 100644
--- a/res/values-hi/strings.xml
+++ b/res/values-hi/strings.xml
@@ -69,6 +69,12 @@
<string name="widget_category_note_taking" msgid="3469689394504266039">"नोट बनाने से जुड़े विजेट"</string>
<string name="widget_add_button_label" msgid="2761267068711937179">"जोड़ें"</string>
<string name="widget_add_button_content_description" msgid="1810530016360039643">"<xliff:g id="WIDGET_NAME">%1$s</xliff:g> विजेट जोड़ें"</string>
+ <!-- no translation found for widgets_list_expand_button_label (7912016136574932622) -->
+ <skip />
+ <!-- no translation found for widgets_list_expand_button_content_description (4600513860973450888) -->
+ <skip />
+ <!-- no translation found for widgets_list_expanded (7374857868788557730) -->
+ <skip />
<string name="reconfigurable_widget_education_tip" msgid="6336962690888067057">"विजेट की सेटिंग में बदलाव करने के लिए टैप करें"</string>
<string name="widget_reconfigure_button_content_description" msgid="8811472721881205250">"विजेट की सेटिंग में बदलाव करें"</string>
<string name="all_apps_search_bar_hint" msgid="1390553134053255246">"ऐप्लिकेशन खोजें"</string>
@@ -124,6 +130,10 @@
<string name="msg_disabled_by_admin" msgid="6898038085516271325">"आपके एडमिन ने बंद किया हुआ है"</string>
<string name="allow_rotation_title" msgid="7222049633713050106">"होम स्क्रीन घुमाने की अनुमति दें"</string>
<string name="allow_rotation_desc" msgid="8662546029078692509">"फ़ोन घुुमाए जाने पर"</string>
+ <!-- no translation found for landscape_mode_title (5138814555934843926) -->
+ <skip />
+ <!-- no translation found for landscape_mode_desc (7372569859592816793) -->
+ <skip />
<string name="notification_dots_title" msgid="9062440428204120317">"सूचनाएं बताने वाला डॉट"</string>
<string name="notification_dots_desc_on" msgid="1679848116452218908">"चालू है"</string>
<string name="notification_dots_desc_off" msgid="1760796511504341095">"चालू"</string>
@@ -142,7 +152,8 @@
<string name="app_installing_title" msgid="5864044122733792085">"<xliff:g id="NAME">%1$s</xliff:g> इंस्टॉल किया जा रहा है, <xliff:g id="PROGRESS">%2$s</xliff:g> पूरा हो गया"</string>
<string name="app_downloading_title" msgid="8336702962104482644">"<xliff:g id="NAME">%1$s</xliff:g> डाउनलोड हो रहा है, <xliff:g id="PROGRESS">%2$s</xliff:g> पूरी हुई"</string>
<string name="app_waiting_download_title" msgid="7053938513995617849">"<xliff:g id="NAME">%1$s</xliff:g> के इंस्टॉल होने की प्रतीक्षा की जा रही है"</string>
- <string name="app_archived_title" msgid="7717956158562544081">"<xliff:g id="NAME">%1$s</xliff:g> को संग्रहित किया गया. ऐप्लिकेशन को वापस लाने और डाउनलोड करने के लिए टैप करें."</string>
+ <string name="app_archived_title" msgid="4548283110222420708">"<xliff:g id="NAME">%1$s</xliff:g> को संग्रहित किया गया."</string>
+ <string name="app_unarchiving_action" msgid="5736107006413929484">"डाउनलोड करें और वापस लाएं"</string>
<string name="dialog_update_title" msgid="114234265740994042">"ऐप्लिकेशन को अपडेट करना ज़रूरी है"</string>
<string name="dialog_update_message" msgid="4176784553982226114">"इस आइकॉन का ऐप्लिकेशन अपडेट नहीं है. इस शॉर्टकट को फिर से चालू करने या आइकॉन को हटाने के लिए, ऐप्लिकेशन को मैन्युअल रूप से अपडेट किया जा सकता है."</string>
<string name="dialog_update" msgid="2178028071796141234">"अपडेट करें"</string>
@@ -187,6 +198,8 @@
<string name="work_apps_paused_edu_accept" msgid="6377476824357318532">"ठीक है"</string>
<string name="work_apps_pause_btn_text" msgid="4669288269140620646">"वर्क ऐप्लिकेशन रोकें"</string>
<string name="work_apps_enable_btn_text" msgid="1736198302467317371">"चालू करें"</string>
+ <!-- no translation found for work_scheduler_button_content_description (917340740986764967) -->
+ <skip />
<string name="developer_options_filter_hint" msgid="5896817443635989056">"फ़िल्टर"</string>
<string name="remote_action_failed" msgid="1383965239183576790">"पूरा नहीं हुआ: <xliff:g id="WHAT">%1$s</xliff:g>"</string>
<string name="private_space_label" msgid="2359721649407947001">"प्राइवेट स्पेस"</string>
diff --git a/res/values-hr/strings.xml b/res/values-hr/strings.xml
index a9fd14e..4a29979 100644
--- a/res/values-hr/strings.xml
+++ b/res/values-hr/strings.xml
@@ -69,6 +69,12 @@
<string name="widget_category_note_taking" msgid="3469689394504266039">"Pisanje bilježaka"</string>
<string name="widget_add_button_label" msgid="2761267068711937179">"Dodaj"</string>
<string name="widget_add_button_content_description" msgid="1810530016360039643">"Dodaj widget <xliff:g id="WIDGET_NAME">%1$s</xliff:g>"</string>
+ <!-- no translation found for widgets_list_expand_button_label (7912016136574932622) -->
+ <skip />
+ <!-- no translation found for widgets_list_expand_button_content_description (4600513860973450888) -->
+ <skip />
+ <!-- no translation found for widgets_list_expanded (7374857868788557730) -->
+ <skip />
<string name="reconfigurable_widget_education_tip" msgid="6336962690888067057">"Dodirnite da biste promijenili postavke widgeta"</string>
<string name="widget_reconfigure_button_content_description" msgid="8811472721881205250">"Promijenite postavke widgeta"</string>
<string name="all_apps_search_bar_hint" msgid="1390553134053255246">"Pretraži aplikacije"</string>
@@ -124,6 +130,10 @@
<string name="msg_disabled_by_admin" msgid="6898038085516271325">"Onemogućio administrator"</string>
<string name="allow_rotation_title" msgid="7222049633713050106">"Dopusti zakretanje početnog zaslona"</string>
<string name="allow_rotation_desc" msgid="8662546029078692509">"Kada se telefon zakrene"</string>
+ <!-- no translation found for landscape_mode_title (5138814555934843926) -->
+ <skip />
+ <!-- no translation found for landscape_mode_desc (7372569859592816793) -->
+ <skip />
<string name="notification_dots_title" msgid="9062440428204120317">"Točke obavijesti"</string>
<string name="notification_dots_desc_on" msgid="1679848116452218908">"Uključeno"</string>
<string name="notification_dots_desc_off" msgid="1760796511504341095">"Isključeno"</string>
@@ -142,7 +152,8 @@
<string name="app_installing_title" msgid="5864044122733792085">"Instaliranje aplikacije <xliff:g id="NAME">%1$s</xliff:g>, <xliff:g id="PROGRESS">%2$s</xliff:g> dovršeno"</string>
<string name="app_downloading_title" msgid="8336702962104482644">"Preuzimanje aplikacije <xliff:g id="NAME">%1$s</xliff:g>, dovršeno <xliff:g id="PROGRESS">%2$s</xliff:g>"</string>
<string name="app_waiting_download_title" msgid="7053938513995617849">"Čekanje na instaliranje aplikacije <xliff:g id="NAME">%1$s</xliff:g>"</string>
- <string name="app_archived_title" msgid="7717956158562544081">"Aplikacija <xliff:g id="NAME">%1$s</xliff:g> je arhivirana. Dodirnite da biste je preuzeli i vratili."</string>
+ <string name="app_archived_title" msgid="4548283110222420708">"Aplikacija <xliff:g id="NAME">%1$s</xliff:g> je arhivirana."</string>
+ <string name="app_unarchiving_action" msgid="5736107006413929484">"preuzmi i vrati"</string>
<string name="dialog_update_title" msgid="114234265740994042">"Aplikacija se treba ažurirati"</string>
<string name="dialog_update_message" msgid="4176784553982226114">"Aplikacija ove ikone nije ažurirana. Možete ručno ažurirati da biste ponovo omogućili ovaj prečac ili uklonite ikonu."</string>
<string name="dialog_update" msgid="2178028071796141234">"Ažuriraj"</string>
@@ -187,6 +198,8 @@
<string name="work_apps_paused_edu_accept" msgid="6377476824357318532">"Shvaćam"</string>
<string name="work_apps_pause_btn_text" msgid="4669288269140620646">"Pauziraj poslovne aplikacije"</string>
<string name="work_apps_enable_btn_text" msgid="1736198302467317371">"Ponovno pokreni"</string>
+ <!-- no translation found for work_scheduler_button_content_description (917340740986764967) -->
+ <skip />
<string name="developer_options_filter_hint" msgid="5896817443635989056">"Filtrirajte"</string>
<string name="remote_action_failed" msgid="1383965239183576790">"Nije uspjelo: <xliff:g id="WHAT">%1$s</xliff:g>"</string>
<string name="private_space_label" msgid="2359721649407947001">"Privatni prostor"</string>
diff --git a/res/values-hu/strings.xml b/res/values-hu/strings.xml
index a0c089e..aa1167d 100644
--- a/res/values-hu/strings.xml
+++ b/res/values-hu/strings.xml
@@ -69,6 +69,12 @@
<string name="widget_category_note_taking" msgid="3469689394504266039">"Jegyzetelés"</string>
<string name="widget_add_button_label" msgid="2761267068711937179">"Hozzáadás"</string>
<string name="widget_add_button_content_description" msgid="1810530016360039643">"<xliff:g id="WIDGET_NAME">%1$s</xliff:g> modul hozzáadása"</string>
+ <!-- no translation found for widgets_list_expand_button_label (7912016136574932622) -->
+ <skip />
+ <!-- no translation found for widgets_list_expand_button_content_description (4600513860973450888) -->
+ <skip />
+ <!-- no translation found for widgets_list_expanded (7374857868788557730) -->
+ <skip />
<string name="reconfigurable_widget_education_tip" msgid="6336962690888067057">"Ide koppintva módosíthatja a modulbeállításokat"</string>
<string name="widget_reconfigure_button_content_description" msgid="8811472721881205250">"A modulbeállítások módosítása"</string>
<string name="all_apps_search_bar_hint" msgid="1390553134053255246">"Alkalmazások keresése"</string>
@@ -124,6 +130,10 @@
<string name="msg_disabled_by_admin" msgid="6898038085516271325">"A rendszergazda letiltotta"</string>
<string name="allow_rotation_title" msgid="7222049633713050106">"A kezdőképernyő elforgatásának engedélyezése"</string>
<string name="allow_rotation_desc" msgid="8662546029078692509">"A telefon elforgatásakor"</string>
+ <!-- no translation found for landscape_mode_title (5138814555934843926) -->
+ <skip />
+ <!-- no translation found for landscape_mode_desc (7372569859592816793) -->
+ <skip />
<string name="notification_dots_title" msgid="9062440428204120317">"Értesítési pöttyök"</string>
<string name="notification_dots_desc_on" msgid="1679848116452218908">"Be"</string>
<string name="notification_dots_desc_off" msgid="1760796511504341095">"Ki"</string>
@@ -142,7 +152,8 @@
<string name="app_installing_title" msgid="5864044122733792085">"Folyamatban van a(z) <xliff:g id="NAME">%1$s</xliff:g> telepítése, <xliff:g id="PROGRESS">%2$s</xliff:g> kész"</string>
<string name="app_downloading_title" msgid="8336702962104482644">"A(z) <xliff:g id="NAME">%1$s</xliff:g> letöltése, <xliff:g id="PROGRESS">%2$s</xliff:g> kész"</string>
<string name="app_waiting_download_title" msgid="7053938513995617849">"A(z) <xliff:g id="NAME">%1$s</xliff:g> telepítésre vár"</string>
- <string name="app_archived_title" msgid="7717956158562544081">"<xliff:g id="NAME">%1$s</xliff:g> archiválva. Koppintson a letöltéshez és a visszaállításhoz."</string>
+ <string name="app_archived_title" msgid="4548283110222420708">"<xliff:g id="NAME">%1$s</xliff:g> archiválva."</string>
+ <string name="app_unarchiving_action" msgid="5736107006413929484">"letöltés és visszaállítás"</string>
<string name="dialog_update_title" msgid="114234265740994042">"Alkalmazásfrissítés szükséges"</string>
<string name="dialog_update_message" msgid="4176784553982226114">"Az ikonhoz tartozó alkalmazás nincs frissítve. A parancsikon újbóli engedélyezéséhez frissítse az alkalmazást, vagy távolítsa ez az ikont."</string>
<string name="dialog_update" msgid="2178028071796141234">"Frissítés"</string>
@@ -187,6 +198,8 @@
<string name="work_apps_paused_edu_accept" msgid="6377476824357318532">"Értem"</string>
<string name="work_apps_pause_btn_text" msgid="4669288269140620646">"Munkahelyi alkalmazások szüneteltetése"</string>
<string name="work_apps_enable_btn_text" msgid="1736198302467317371">"Folytatás"</string>
+ <!-- no translation found for work_scheduler_button_content_description (917340740986764967) -->
+ <skip />
<string name="developer_options_filter_hint" msgid="5896817443635989056">"Szűrő"</string>
<string name="remote_action_failed" msgid="1383965239183576790">"Sikertelen: <xliff:g id="WHAT">%1$s</xliff:g>"</string>
<string name="private_space_label" msgid="2359721649407947001">"Privát terület"</string>
diff --git a/res/values-hy/strings.xml b/res/values-hy/strings.xml
index ba2edb1..692984e 100644
--- a/res/values-hy/strings.xml
+++ b/res/values-hy/strings.xml
@@ -69,6 +69,12 @@
<string name="widget_category_note_taking" msgid="3469689394504266039">"Նշումների ստեղծում"</string>
<string name="widget_add_button_label" msgid="2761267068711937179">"Ավելացնել"</string>
<string name="widget_add_button_content_description" msgid="1810530016360039643">"Ավելացնել <xliff:g id="WIDGET_NAME">%1$s</xliff:g> վիջեթը"</string>
+ <!-- no translation found for widgets_list_expand_button_label (7912016136574932622) -->
+ <skip />
+ <!-- no translation found for widgets_list_expand_button_content_description (4600513860973450888) -->
+ <skip />
+ <!-- no translation found for widgets_list_expanded (7374857868788557730) -->
+ <skip />
<string name="reconfigurable_widget_education_tip" msgid="6336962690888067057">"Հպեք՝ վիջեթի կարգավորումները փոփոխելու համար"</string>
<string name="widget_reconfigure_button_content_description" msgid="8811472721881205250">"Փոխել վիջեթի կարգավորումները"</string>
<string name="all_apps_search_bar_hint" msgid="1390553134053255246">"Որոնել հավելվածներ"</string>
@@ -124,6 +130,10 @@
<string name="msg_disabled_by_admin" msgid="6898038085516271325">"Անջատվել է ձեր ադմինիստրատորի կողմից"</string>
<string name="allow_rotation_title" msgid="7222049633713050106">"Թույլ տալ հիմնական էկրանի պտտումը"</string>
<string name="allow_rotation_desc" msgid="8662546029078692509">"Հեռախոսը պտտելու դեպքում"</string>
+ <!-- no translation found for landscape_mode_title (5138814555934843926) -->
+ <skip />
+ <!-- no translation found for landscape_mode_desc (7372569859592816793) -->
+ <skip />
<string name="notification_dots_title" msgid="9062440428204120317">"Ծանուցումների կետիկներ"</string>
<string name="notification_dots_desc_on" msgid="1679848116452218908">"Միացված է"</string>
<string name="notification_dots_desc_off" msgid="1760796511504341095">"Անջատված է"</string>
@@ -142,7 +152,8 @@
<string name="app_installing_title" msgid="5864044122733792085">"<xliff:g id="NAME">%1$s</xliff:g> հավելվածը տեղադրվում է, կատարված է <xliff:g id="PROGRESS">%2$s</xliff:g>-ը"</string>
<string name="app_downloading_title" msgid="8336702962104482644">"<xliff:g id="NAME">%1$s</xliff:g>–ի ներբեռնում (<xliff:g id="PROGRESS">%2$s</xliff:g>)"</string>
<string name="app_waiting_download_title" msgid="7053938513995617849">"<xliff:g id="NAME">%1$s</xliff:g>-ի տեղադրման սպասում"</string>
- <string name="app_archived_title" msgid="7717956158562544081">"<xliff:g id="NAME">%1$s</xliff:g> հավելվածն արխիվացված է։ Հպեք՝ ներբեռնելու և վերականգնելու համար։"</string>
+ <string name="app_archived_title" msgid="4548283110222420708">"<xliff:g id="NAME">%1$s</xliff:g> հավելվածն արխիվացված է։"</string>
+ <string name="app_unarchiving_action" msgid="5736107006413929484">"ներբեռնել և վերականգնել"</string>
<string name="dialog_update_title" msgid="114234265740994042">"Պահանջվում է թարմացնել հավելվածը"</string>
<string name="dialog_update_message" msgid="4176784553982226114">"Հավելվածը հնացել է։ Թարմացրեք այն ձեռքով, որպեսզի շարունակեք օգտագործել դյուրանցումը, կամ հեռացրեք հավելվածի պատկերակը։"</string>
<string name="dialog_update" msgid="2178028071796141234">"Թարմացնել"</string>
@@ -187,6 +198,8 @@
<string name="work_apps_paused_edu_accept" msgid="6377476824357318532">"Եղավ"</string>
<string name="work_apps_pause_btn_text" msgid="4669288269140620646">"Դադարեցնել աշխատանքային հավելվածները"</string>
<string name="work_apps_enable_btn_text" msgid="1736198302467317371">"Վերսկսել"</string>
+ <!-- no translation found for work_scheduler_button_content_description (917340740986764967) -->
+ <skip />
<string name="developer_options_filter_hint" msgid="5896817443635989056">"Զտեք"</string>
<string name="remote_action_failed" msgid="1383965239183576790">"Չհաջողվեց կատարել գործողությունը (<xliff:g id="WHAT">%1$s</xliff:g>)"</string>
<string name="private_space_label" msgid="2359721649407947001">"Անձնական տարածք"</string>
diff --git a/res/values-in/strings.xml b/res/values-in/strings.xml
index 40f2e57..1870055 100644
--- a/res/values-in/strings.xml
+++ b/res/values-in/strings.xml
@@ -69,6 +69,12 @@
<string name="widget_category_note_taking" msgid="3469689394504266039">"Pembuatan catatan"</string>
<string name="widget_add_button_label" msgid="2761267068711937179">"Tambahkan"</string>
<string name="widget_add_button_content_description" msgid="1810530016360039643">"Tambahkan widget <xliff:g id="WIDGET_NAME">%1$s</xliff:g>"</string>
+ <!-- no translation found for widgets_list_expand_button_label (7912016136574932622) -->
+ <skip />
+ <!-- no translation found for widgets_list_expand_button_content_description (4600513860973450888) -->
+ <skip />
+ <!-- no translation found for widgets_list_expanded (7374857868788557730) -->
+ <skip />
<string name="reconfigurable_widget_education_tip" msgid="6336962690888067057">"Ketuk untuk mengubah setelan widget"</string>
<string name="widget_reconfigure_button_content_description" msgid="8811472721881205250">"Ubah setelan widget"</string>
<string name="all_apps_search_bar_hint" msgid="1390553134053255246">"Telusuri aplikasi"</string>
@@ -124,6 +130,10 @@
<string name="msg_disabled_by_admin" msgid="6898038085516271325">"Dinonaktifkan oleh admin"</string>
<string name="allow_rotation_title" msgid="7222049633713050106">"Izinkan layar utama diputar"</string>
<string name="allow_rotation_desc" msgid="8662546029078692509">"Saat ponsel diputar"</string>
+ <!-- no translation found for landscape_mode_title (5138814555934843926) -->
+ <skip />
+ <!-- no translation found for landscape_mode_desc (7372569859592816793) -->
+ <skip />
<string name="notification_dots_title" msgid="9062440428204120317">"Titik notifikasi"</string>
<string name="notification_dots_desc_on" msgid="1679848116452218908">"Aktif"</string>
<string name="notification_dots_desc_off" msgid="1760796511504341095">"Nonaktif"</string>
@@ -142,7 +152,8 @@
<string name="app_installing_title" msgid="5864044122733792085">"<xliff:g id="NAME">%1$s</xliff:g> sedang diinstal, <xliff:g id="PROGRESS">%2$s</xliff:g> selesai"</string>
<string name="app_downloading_title" msgid="8336702962104482644">"<xliff:g id="NAME">%1$s</xliff:g> sedang didownload, <xliff:g id="PROGRESS">%2$s</xliff:g> selesai"</string>
<string name="app_waiting_download_title" msgid="7053938513995617849">"<xliff:g id="NAME">%1$s</xliff:g> menunggu dipasang"</string>
- <string name="app_archived_title" msgid="7717956158562544081">"<xliff:g id="NAME">%1$s</xliff:g> diarsipkan. Ketuk untuk mendownload dan memulihkan."</string>
+ <string name="app_archived_title" msgid="4548283110222420708">"<xliff:g id="NAME">%1$s</xliff:g> diarsipkan."</string>
+ <string name="app_unarchiving_action" msgid="5736107006413929484">"download dan pulihkan"</string>
<string name="dialog_update_title" msgid="114234265740994042">"Aplikasi perlu diupdate"</string>
<string name="dialog_update_message" msgid="4176784553982226114">"Aplikasi untuk ikon ini belum diupdate. Anda dapat mengupdate secara manual untuk mengaktifkan kembali pintasan ini, atau hapus ikon."</string>
<string name="dialog_update" msgid="2178028071796141234">"Update"</string>
@@ -187,6 +198,8 @@
<string name="work_apps_paused_edu_accept" msgid="6377476824357318532">"Oke"</string>
<string name="work_apps_pause_btn_text" msgid="4669288269140620646">"Jeda aplikasi kerja"</string>
<string name="work_apps_enable_btn_text" msgid="1736198302467317371">"Aktifkan lagi"</string>
+ <!-- no translation found for work_scheduler_button_content_description (917340740986764967) -->
+ <skip />
<string name="developer_options_filter_hint" msgid="5896817443635989056">"Filter"</string>
<string name="remote_action_failed" msgid="1383965239183576790">"Gagal: <xliff:g id="WHAT">%1$s</xliff:g>"</string>
<string name="private_space_label" msgid="2359721649407947001">"Ruang privasi"</string>
diff --git a/res/values-is/strings.xml b/res/values-is/strings.xml
index 0014317..393589a 100644
--- a/res/values-is/strings.xml
+++ b/res/values-is/strings.xml
@@ -69,6 +69,12 @@
<string name="widget_category_note_taking" msgid="3469689394504266039">"Glósugerð"</string>
<string name="widget_add_button_label" msgid="2761267068711937179">"Bæta við"</string>
<string name="widget_add_button_content_description" msgid="1810530016360039643">"Bæta græjunni <xliff:g id="WIDGET_NAME">%1$s</xliff:g> við"</string>
+ <!-- no translation found for widgets_list_expand_button_label (7912016136574932622) -->
+ <skip />
+ <!-- no translation found for widgets_list_expand_button_content_description (4600513860973450888) -->
+ <skip />
+ <!-- no translation found for widgets_list_expanded (7374857868788557730) -->
+ <skip />
<string name="reconfigurable_widget_education_tip" msgid="6336962690888067057">"Ýttu til að breyta græjustillingum"</string>
<string name="widget_reconfigure_button_content_description" msgid="8811472721881205250">"Breyta græjustillingum"</string>
<string name="all_apps_search_bar_hint" msgid="1390553134053255246">"Leita í forritum"</string>
@@ -124,6 +130,10 @@
<string name="msg_disabled_by_admin" msgid="6898038085516271325">"Gert óvirkt af kerfisstjóra"</string>
<string name="allow_rotation_title" msgid="7222049633713050106">"Leyfa snúning á heimaskjá"</string>
<string name="allow_rotation_desc" msgid="8662546029078692509">"Þegar símanum er snúið"</string>
+ <!-- no translation found for landscape_mode_title (5138814555934843926) -->
+ <skip />
+ <!-- no translation found for landscape_mode_desc (7372569859592816793) -->
+ <skip />
<string name="notification_dots_title" msgid="9062440428204120317">"Tilkynningapunktar"</string>
<string name="notification_dots_desc_on" msgid="1679848116452218908">"Kveikt"</string>
<string name="notification_dots_desc_off" msgid="1760796511504341095">"Slökkt"</string>
@@ -142,7 +152,8 @@
<string name="app_installing_title" msgid="5864044122733792085">"Setur upp <xliff:g id="NAME">%1$s</xliff:g>, <xliff:g id="PROGRESS">%2$s</xliff:g> lokið"</string>
<string name="app_downloading_title" msgid="8336702962104482644">"<xliff:g id="NAME">%1$s</xliff:g> í niðurhali, <xliff:g id="PROGRESS">%2$s</xliff:g> lokið"</string>
<string name="app_waiting_download_title" msgid="7053938513995617849">"<xliff:g id="NAME">%1$s</xliff:g> bíður uppsetningar"</string>
- <string name="app_archived_title" msgid="7717956158562544081">"<xliff:g id="NAME">%1$s</xliff:g> er í geymslu. Ýttu til að sækja og endurheimta."</string>
+ <string name="app_archived_title" msgid="4548283110222420708">"<xliff:g id="NAME">%1$s</xliff:g> er í geymslu."</string>
+ <string name="app_unarchiving_action" msgid="5736107006413929484">"sækja og endurheimta"</string>
<string name="dialog_update_title" msgid="114234265740994042">"Uppfæra þarf forritið"</string>
<string name="dialog_update_message" msgid="4176784553982226114">"Forritið fyrir þetta tákn er ekki uppfært. Þú getur uppfært það handvirkt til að kveikja aftur á þessari flýtileið eða fjarlægt táknið."</string>
<string name="dialog_update" msgid="2178028071796141234">"Uppfæra"</string>
@@ -187,6 +198,8 @@
<string name="work_apps_paused_edu_accept" msgid="6377476824357318532">"Ég skil"</string>
<string name="work_apps_pause_btn_text" msgid="4669288269140620646">"Setja vinnuforrit í bið"</string>
<string name="work_apps_enable_btn_text" msgid="1736198302467317371">"Ljúka hléi"</string>
+ <!-- no translation found for work_scheduler_button_content_description (917340740986764967) -->
+ <skip />
<string name="developer_options_filter_hint" msgid="5896817443635989056">"Sía"</string>
<string name="remote_action_failed" msgid="1383965239183576790">"Mistókst: <xliff:g id="WHAT">%1$s</xliff:g>"</string>
<string name="private_space_label" msgid="2359721649407947001">"Leynirými"</string>
diff --git a/res/values-it/strings.xml b/res/values-it/strings.xml
index 9cdb5aa..2a14445 100644
--- a/res/values-it/strings.xml
+++ b/res/values-it/strings.xml
@@ -69,6 +69,12 @@
<string name="widget_category_note_taking" msgid="3469689394504266039">"Aggiunta di note"</string>
<string name="widget_add_button_label" msgid="2761267068711937179">"Aggiungi"</string>
<string name="widget_add_button_content_description" msgid="1810530016360039643">"Aggiungi widget <xliff:g id="WIDGET_NAME">%1$s</xliff:g>"</string>
+ <!-- no translation found for widgets_list_expand_button_label (7912016136574932622) -->
+ <skip />
+ <!-- no translation found for widgets_list_expand_button_content_description (4600513860973450888) -->
+ <skip />
+ <!-- no translation found for widgets_list_expanded (7374857868788557730) -->
+ <skip />
<string name="reconfigurable_widget_education_tip" msgid="6336962690888067057">"Tocca per modificare le impostazioni del widget"</string>
<string name="widget_reconfigure_button_content_description" msgid="8811472721881205250">"Modifica le impostazioni del widget"</string>
<string name="all_apps_search_bar_hint" msgid="1390553134053255246">"Cerca nelle app"</string>
@@ -124,6 +130,10 @@
<string name="msg_disabled_by_admin" msgid="6898038085516271325">"Disattivata dall\'amministratore"</string>
<string name="allow_rotation_title" msgid="7222049633713050106">"Consenti rotazione della schermata Home"</string>
<string name="allow_rotation_desc" msgid="8662546029078692509">"Con il telefono ruotato"</string>
+ <!-- no translation found for landscape_mode_title (5138814555934843926) -->
+ <skip />
+ <!-- no translation found for landscape_mode_desc (7372569859592816793) -->
+ <skip />
<string name="notification_dots_title" msgid="9062440428204120317">"Indicatori di notifica"</string>
<string name="notification_dots_desc_on" msgid="1679848116452218908">"On"</string>
<string name="notification_dots_desc_off" msgid="1760796511504341095">"Off"</string>
@@ -142,7 +152,8 @@
<string name="app_installing_title" msgid="5864044122733792085">"Installazione di <xliff:g id="NAME">%1$s</xliff:g>, completamento: <xliff:g id="PROGRESS">%2$s</xliff:g>"</string>
<string name="app_downloading_title" msgid="8336702962104482644">"Download di <xliff:g id="NAME">%1$s</xliff:g> in corso, <xliff:g id="PROGRESS">%2$s</xliff:g> completato"</string>
<string name="app_waiting_download_title" msgid="7053938513995617849">"<xliff:g id="NAME">%1$s</xliff:g> in attesa di installazione"</string>
- <string name="app_archived_title" msgid="7717956158562544081">"App <xliff:g id="NAME">%1$s</xliff:g> archiviata. Tocca per scaricare e ripristinare."</string>
+ <string name="app_archived_title" msgid="4548283110222420708">"App <xliff:g id="NAME">%1$s</xliff:g> archiviata."</string>
+ <string name="app_unarchiving_action" msgid="5736107006413929484">"download e ripristino"</string>
<string name="dialog_update_title" msgid="114234265740994042">"È necessario aggiornare l\'app"</string>
<string name="dialog_update_message" msgid="4176784553982226114">"L\'app relativa a questa icona non è aggiornata. Puoi eseguire manualmente l\'aggiornamento per riattivare questa scorciatoia oppure rimuovere l\'icona."</string>
<string name="dialog_update" msgid="2178028071796141234">"Aggiorna"</string>
@@ -187,6 +198,8 @@
<string name="work_apps_paused_edu_accept" msgid="6377476824357318532">"OK"</string>
<string name="work_apps_pause_btn_text" msgid="4669288269140620646">"Metti in pausa le app di lavoro"</string>
<string name="work_apps_enable_btn_text" msgid="1736198302467317371">"Riattiva"</string>
+ <!-- no translation found for work_scheduler_button_content_description (917340740986764967) -->
+ <skip />
<string name="developer_options_filter_hint" msgid="5896817443635989056">"Filtra"</string>
<string name="remote_action_failed" msgid="1383965239183576790">"Operazione non riuscita: <xliff:g id="WHAT">%1$s</xliff:g>"</string>
<string name="private_space_label" msgid="2359721649407947001">"Spazio privato"</string>
diff --git a/res/values-iw/strings.xml b/res/values-iw/strings.xml
index 82eb5f8..724742a 100644
--- a/res/values-iw/strings.xml
+++ b/res/values-iw/strings.xml
@@ -69,6 +69,12 @@
<string name="widget_category_note_taking" msgid="3469689394504266039">"כתיבת הערות"</string>
<string name="widget_add_button_label" msgid="2761267068711937179">"הוספה"</string>
<string name="widget_add_button_content_description" msgid="1810530016360039643">"הוספת הווידג\'ט <xliff:g id="WIDGET_NAME">%1$s</xliff:g>"</string>
+ <!-- no translation found for widgets_list_expand_button_label (7912016136574932622) -->
+ <skip />
+ <!-- no translation found for widgets_list_expand_button_content_description (4600513860973450888) -->
+ <skip />
+ <!-- no translation found for widgets_list_expanded (7374857868788557730) -->
+ <skip />
<string name="reconfigurable_widget_education_tip" msgid="6336962690888067057">"אפשר לשנות את הגדרות הווידג\'ט בהקשה"</string>
<string name="widget_reconfigure_button_content_description" msgid="8811472721881205250">"שינוי הגדרות הווידג\'ט"</string>
<string name="all_apps_search_bar_hint" msgid="1390553134053255246">"חיפוש אפליקציות"</string>
@@ -124,6 +130,10 @@
<string name="msg_disabled_by_admin" msgid="6898038085516271325">"הושבת על ידי מנהל המערכת שלך"</string>
<string name="allow_rotation_title" msgid="7222049633713050106">"סיבוב מסך הבית"</string>
<string name="allow_rotation_desc" msgid="8662546029078692509">"כאשר מסובבים את הטלפון"</string>
+ <!-- no translation found for landscape_mode_title (5138814555934843926) -->
+ <skip />
+ <!-- no translation found for landscape_mode_desc (7372569859592816793) -->
+ <skip />
<string name="notification_dots_title" msgid="9062440428204120317">"סימני ההתראות"</string>
<string name="notification_dots_desc_on" msgid="1679848116452218908">"מופעל"</string>
<string name="notification_dots_desc_off" msgid="1760796511504341095">"כבוי"</string>
@@ -142,7 +152,8 @@
<string name="app_installing_title" msgid="5864044122733792085">"<xliff:g id="NAME">%1$s</xliff:g> בתהליך התקנה, <xliff:g id="PROGRESS">%2$s</xliff:g> הושלמו"</string>
<string name="app_downloading_title" msgid="8336702962104482644">"הורדת <xliff:g id="NAME">%1$s</xliff:g> מתבצעת, <xliff:g id="PROGRESS">%2$s</xliff:g> הושלמו"</string>
<string name="app_waiting_download_title" msgid="7053938513995617849">"מחכה להתקנה של <xliff:g id="NAME">%1$s</xliff:g>"</string>
- <string name="app_archived_title" msgid="7717956158562544081">"אפליקציית <xliff:g id="NAME">%1$s</xliff:g> הועברה לארכיון. אפשר להקיש כדי להוריד ולשחזר אותה."</string>
+ <string name="app_archived_title" msgid="4548283110222420708">"אפליקציית <xliff:g id="NAME">%1$s</xliff:g> הועברה לארכיון."</string>
+ <string name="app_unarchiving_action" msgid="5736107006413929484">"הורדה ושחזור"</string>
<string name="dialog_update_title" msgid="114234265740994042">"נדרש עדכון לאפליקציה"</string>
<string name="dialog_update_message" msgid="4176784553982226114">"האפליקציה של הסמל הזה לא מעודכנת. אפשר לעדכן אותה ידנית כדי להפעיל מחדש את קיצור הדרך הזה, או להסיר את הסמל."</string>
<string name="dialog_update" msgid="2178028071796141234">"עדכון"</string>
@@ -187,6 +198,8 @@
<string name="work_apps_paused_edu_accept" msgid="6377476824357318532">"הבנתי"</string>
<string name="work_apps_pause_btn_text" msgid="4669288269140620646">"השהיית האפליקציות לעבודה"</string>
<string name="work_apps_enable_btn_text" msgid="1736198302467317371">"ביטול ההשהיה"</string>
+ <!-- no translation found for work_scheduler_button_content_description (917340740986764967) -->
+ <skip />
<string name="developer_options_filter_hint" msgid="5896817443635989056">"סינון"</string>
<string name="remote_action_failed" msgid="1383965239183576790">"הפעולה נכשלה: <xliff:g id="WHAT">%1$s</xliff:g>"</string>
<string name="private_space_label" msgid="2359721649407947001">"מרחב פרטי"</string>
diff --git a/res/values-ja/strings.xml b/res/values-ja/strings.xml
index fc89041..29dbf26 100644
--- a/res/values-ja/strings.xml
+++ b/res/values-ja/strings.xml
@@ -69,6 +69,12 @@
<string name="widget_category_note_taking" msgid="3469689394504266039">"メモ"</string>
<string name="widget_add_button_label" msgid="2761267068711937179">"追加"</string>
<string name="widget_add_button_content_description" msgid="1810530016360039643">"<xliff:g id="WIDGET_NAME">%1$s</xliff:g>ウィジェットを追加"</string>
+ <!-- no translation found for widgets_list_expand_button_label (7912016136574932622) -->
+ <skip />
+ <!-- no translation found for widgets_list_expand_button_content_description (4600513860973450888) -->
+ <skip />
+ <!-- no translation found for widgets_list_expanded (7374857868788557730) -->
+ <skip />
<string name="reconfigurable_widget_education_tip" msgid="6336962690888067057">"タップしてウィジェットの設定を変更する"</string>
<string name="widget_reconfigure_button_content_description" msgid="8811472721881205250">"ウィジェットの設定を変更します"</string>
<string name="all_apps_search_bar_hint" msgid="1390553134053255246">"アプリを検索"</string>
@@ -124,6 +130,10 @@
<string name="msg_disabled_by_admin" msgid="6898038085516271325">"管理者により無効にされています"</string>
<string name="allow_rotation_title" msgid="7222049633713050106">"ホーム画面の回転を許可"</string>
<string name="allow_rotation_desc" msgid="8662546029078692509">"スマートフォンの向きに合わせます"</string>
+ <!-- no translation found for landscape_mode_title (5138814555934843926) -->
+ <skip />
+ <!-- no translation found for landscape_mode_desc (7372569859592816793) -->
+ <skip />
<string name="notification_dots_title" msgid="9062440428204120317">"通知ドット"</string>
<string name="notification_dots_desc_on" msgid="1679848116452218908">"ON"</string>
<string name="notification_dots_desc_off" msgid="1760796511504341095">"OFF"</string>
@@ -142,7 +152,8 @@
<string name="app_installing_title" msgid="5864044122733792085">"<xliff:g id="NAME">%1$s</xliff:g> をインストールしています: <xliff:g id="PROGRESS">%2$s</xliff:g> 完了"</string>
<string name="app_downloading_title" msgid="8336702962104482644">"<xliff:g id="NAME">%1$s</xliff:g>をダウンロード中、<xliff:g id="PROGRESS">%2$s</xliff:g>完了"</string>
<string name="app_waiting_download_title" msgid="7053938513995617849">"<xliff:g id="NAME">%1$s</xliff:g>のインストール待ち"</string>
- <string name="app_archived_title" msgid="7717956158562544081">"<xliff:g id="NAME">%1$s</xliff:g>はアーカイブ済みです。ダウンロードして復元するには、タップしてください。"</string>
+ <string name="app_archived_title" msgid="4548283110222420708">"<xliff:g id="NAME">%1$s</xliff:g> はアーカイブ済みです。"</string>
+ <string name="app_unarchiving_action" msgid="5736107006413929484">"ダウンロードして復元"</string>
<string name="dialog_update_title" msgid="114234265740994042">"アプリの更新が必要"</string>
<string name="dialog_update_message" msgid="4176784553982226114">"このアイコンのアプリは更新されていません。手動で更新して、このショートカットを再度有効にできます。また、アイコンを削除することもできます。"</string>
<string name="dialog_update" msgid="2178028071796141234">"更新"</string>
@@ -187,6 +198,8 @@
<string name="work_apps_paused_edu_accept" msgid="6377476824357318532">"OK"</string>
<string name="work_apps_pause_btn_text" msgid="4669288269140620646">"仕事用アプリを一時停止"</string>
<string name="work_apps_enable_btn_text" msgid="1736198302467317371">"停止解除"</string>
+ <!-- no translation found for work_scheduler_button_content_description (917340740986764967) -->
+ <skip />
<string name="developer_options_filter_hint" msgid="5896817443635989056">"フィルタ"</string>
<string name="remote_action_failed" msgid="1383965239183576790">"失敗: <xliff:g id="WHAT">%1$s</xliff:g>"</string>
<string name="private_space_label" msgid="2359721649407947001">"プライベート スペース"</string>
diff --git a/res/values-ka/strings.xml b/res/values-ka/strings.xml
index f099bcd..876ab11 100644
--- a/res/values-ka/strings.xml
+++ b/res/values-ka/strings.xml
@@ -69,6 +69,12 @@
<string name="widget_category_note_taking" msgid="3469689394504266039">"ჩანიშვნა"</string>
<string name="widget_add_button_label" msgid="2761267068711937179">"დამატება"</string>
<string name="widget_add_button_content_description" msgid="1810530016360039643">"<xliff:g id="WIDGET_NAME">%1$s</xliff:g> ვიჯეტის დამატება"</string>
+ <!-- no translation found for widgets_list_expand_button_label (7912016136574932622) -->
+ <skip />
+ <!-- no translation found for widgets_list_expand_button_content_description (4600513860973450888) -->
+ <skip />
+ <!-- no translation found for widgets_list_expanded (7374857868788557730) -->
+ <skip />
<string name="reconfigurable_widget_education_tip" msgid="6336962690888067057">"შეეხეთ ვიჯეტის პარამეტრების შესაცვლელად"</string>
<string name="widget_reconfigure_button_content_description" msgid="8811472721881205250">"ვიჯეტის პარამეტრების შეცვლა"</string>
<string name="all_apps_search_bar_hint" msgid="1390553134053255246">"აპების ძიება"</string>
@@ -124,6 +130,10 @@
<string name="msg_disabled_by_admin" msgid="6898038085516271325">"გათიშულია თქვენი ადმინისტრატორის მიერ"</string>
<string name="allow_rotation_title" msgid="7222049633713050106">"მთავარი ეკრანის შეტრიალების დაშვება"</string>
<string name="allow_rotation_desc" msgid="8662546029078692509">"ტელეფონის შეტრიალებისას"</string>
+ <!-- no translation found for landscape_mode_title (5138814555934843926) -->
+ <skip />
+ <!-- no translation found for landscape_mode_desc (7372569859592816793) -->
+ <skip />
<string name="notification_dots_title" msgid="9062440428204120317">"შეტყობინების ნიშნულები"</string>
<string name="notification_dots_desc_on" msgid="1679848116452218908">"ჩართულია"</string>
<string name="notification_dots_desc_off" msgid="1760796511504341095">"გამორთულია"</string>
@@ -142,7 +152,8 @@
<string name="app_installing_title" msgid="5864044122733792085">"ინსტალირდება <xliff:g id="NAME">%1$s</xliff:g>, <xliff:g id="PROGRESS">%2$s</xliff:g> დასრულებულია"</string>
<string name="app_downloading_title" msgid="8336702962104482644">"მიმდინარეობს <xliff:g id="NAME">%1$s</xliff:g>-ის ჩამოტვირთვა, <xliff:g id="PROGRESS">%2$s</xliff:g> დასრულდა"</string>
<string name="app_waiting_download_title" msgid="7053938513995617849">"<xliff:g id="NAME">%1$s</xliff:g> ელოდება ინსტალაციას"</string>
- <string name="app_archived_title" msgid="7717956158562544081">"<xliff:g id="NAME">%1$s</xliff:g> დაარქივებულია. შეეხეთ გადმოსაწერად და აღსადგენად."</string>
+ <string name="app_archived_title" msgid="4548283110222420708">"<xliff:g id="NAME">%1$s</xliff:g> დაარქივებულია."</string>
+ <string name="app_unarchiving_action" msgid="5736107006413929484">"ჩამოტვირთვა და აღდგენა"</string>
<string name="dialog_update_title" msgid="114234265740994042">"საჭიროა აპის განახლება"</string>
<string name="dialog_update_message" msgid="4176784553982226114">"ამ ხატულის აპი განახლებული არ არის. შეგიძლიათ, ხელით განაახლოთ ამ მალსახმობის ხელახლა გასააქტიურებლად, ან ამოშალოთ ხატულა."</string>
<string name="dialog_update" msgid="2178028071796141234">"განახლება"</string>
@@ -187,11 +198,13 @@
<string name="work_apps_paused_edu_accept" msgid="6377476824357318532">"გასაგებია"</string>
<string name="work_apps_pause_btn_text" msgid="4669288269140620646">"სამსახურის აპების დაპაუზება"</string>
<string name="work_apps_enable_btn_text" msgid="1736198302467317371">"პაუზის გაუქმება"</string>
+ <!-- no translation found for work_scheduler_button_content_description (917340740986764967) -->
+ <skip />
<string name="developer_options_filter_hint" msgid="5896817443635989056">"ფილტრი"</string>
<string name="remote_action_failed" msgid="1383965239183576790">"ვერ მოხერხდა: <xliff:g id="WHAT">%1$s</xliff:g>"</string>
<string name="private_space_label" msgid="2359721649407947001">"პირადი სივრცე"</string>
<string name="private_space_secondary_label" msgid="9203933341714508907">"დასაყენებლად ან გასახსნელად შეეხეთ"</string>
- <string name="ps_container_title" msgid="4391796149519594205">"პირადი"</string>
+ <string name="ps_container_title" msgid="4391796149519594205">"კერძო"</string>
<string name="ps_container_settings" msgid="6059734123353320479">"პირადი სივრცის პარამეტრები"</string>
<string name="ps_container_unlock_button_content_description" msgid="9181551784092204234">"პირადი (განბლოკილი)."</string>
<string name="ps_container_lock_button_content_description" msgid="5961993384382649530">"პირადი (ჩაკეტილი)."</string>
diff --git a/res/values-kk/strings.xml b/res/values-kk/strings.xml
index ebaacc9..bc1c380 100644
--- a/res/values-kk/strings.xml
+++ b/res/values-kk/strings.xml
@@ -69,6 +69,12 @@
<string name="widget_category_note_taking" msgid="3469689394504266039">"Ескертпе жазу"</string>
<string name="widget_add_button_label" msgid="2761267068711937179">"Қосу"</string>
<string name="widget_add_button_content_description" msgid="1810530016360039643">"Виджет (<xliff:g id="WIDGET_NAME">%1$s</xliff:g>) қосу"</string>
+ <!-- no translation found for widgets_list_expand_button_label (7912016136574932622) -->
+ <skip />
+ <!-- no translation found for widgets_list_expand_button_content_description (4600513860973450888) -->
+ <skip />
+ <!-- no translation found for widgets_list_expanded (7374857868788557730) -->
+ <skip />
<string name="reconfigurable_widget_education_tip" msgid="6336962690888067057">"Виджет параметрлерін өзгерту үшін түртіңіз."</string>
<string name="widget_reconfigure_button_content_description" msgid="8811472721881205250">"Виджет параметрлерін өзгерту"</string>
<string name="all_apps_search_bar_hint" msgid="1390553134053255246">"Қолданбаларды іздеу"</string>
@@ -124,6 +130,10 @@
<string name="msg_disabled_by_admin" msgid="6898038085516271325">"Әкімші өшірді"</string>
<string name="allow_rotation_title" msgid="7222049633713050106">"Негізгі экранды бұруға рұқсат ету"</string>
<string name="allow_rotation_desc" msgid="8662546029078692509">"Телефон бұрылғанда"</string>
+ <!-- no translation found for landscape_mode_title (5138814555934843926) -->
+ <skip />
+ <!-- no translation found for landscape_mode_desc (7372569859592816793) -->
+ <skip />
<string name="notification_dots_title" msgid="9062440428204120317">"Хабарландыру белгілері"</string>
<string name="notification_dots_desc_on" msgid="1679848116452218908">"Қосулы"</string>
<string name="notification_dots_desc_off" msgid="1760796511504341095">"Өшірулі"</string>
@@ -142,7 +152,8 @@
<string name="app_installing_title" msgid="5864044122733792085">"<xliff:g id="NAME">%1$s</xliff:g> орнатылуда, <xliff:g id="PROGRESS">%2$s</xliff:g> аяқталды"</string>
<string name="app_downloading_title" msgid="8336702962104482644">"<xliff:g id="NAME">%1$s</xliff:g> жүктелуде, <xliff:g id="PROGRESS">%2$s</xliff:g> аяқталды"</string>
<string name="app_waiting_download_title" msgid="7053938513995617849">"<xliff:g id="NAME">%1$s</xliff:g> орнату күтілуде"</string>
- <string name="app_archived_title" msgid="7717956158562544081">"<xliff:g id="NAME">%1$s</xliff:g> мұрағатталды. Жүктеп алу және қалпына келтіру үшін түртіңіз."</string>
+ <string name="app_archived_title" msgid="4548283110222420708">"<xliff:g id="NAME">%1$s</xliff:g> мұрағатталды."</string>
+ <string name="app_unarchiving_action" msgid="5736107006413929484">"жүктеп алу және қалпына келтіру"</string>
<string name="dialog_update_title" msgid="114234265740994042">"Қолданбаны жаңарту қажет"</string>
<string name="dialog_update_message" msgid="4176784553982226114">"Осы белгіше үшін қолданба жаңартылмаған. Оны қолмен жаңартып, осы таңбашаны қайта іске қоса аласыз немесе белгішені өшіріп тастаңыз."</string>
<string name="dialog_update" msgid="2178028071796141234">"Жаңарту"</string>
@@ -187,6 +198,8 @@
<string name="work_apps_paused_edu_accept" msgid="6377476824357318532">"Түсінікті"</string>
<string name="work_apps_pause_btn_text" msgid="4669288269140620646">"Жұмыс қолданбаларын кідірту"</string>
<string name="work_apps_enable_btn_text" msgid="1736198302467317371">"Қайта қосу"</string>
+ <!-- no translation found for work_scheduler_button_content_description (917340740986764967) -->
+ <skip />
<string name="developer_options_filter_hint" msgid="5896817443635989056">"Сүзгі"</string>
<string name="remote_action_failed" msgid="1383965239183576790">"Қате шықты: <xliff:g id="WHAT">%1$s</xliff:g>"</string>
<string name="private_space_label" msgid="2359721649407947001">"Құпия кеңістік"</string>
diff --git a/res/values-km/strings.xml b/res/values-km/strings.xml
index b05eeb0..813b5a2 100644
--- a/res/values-km/strings.xml
+++ b/res/values-km/strings.xml
@@ -69,6 +69,12 @@
<string name="widget_category_note_taking" msgid="3469689394504266039">"ការកត់ត្រា"</string>
<string name="widget_add_button_label" msgid="2761267068711937179">"បញ្ចូល"</string>
<string name="widget_add_button_content_description" msgid="1810530016360039643">"បញ្ចូលធាតុក្រាហ្វិក <xliff:g id="WIDGET_NAME">%1$s</xliff:g>"</string>
+ <!-- no translation found for widgets_list_expand_button_label (7912016136574932622) -->
+ <skip />
+ <!-- no translation found for widgets_list_expand_button_content_description (4600513860973450888) -->
+ <skip />
+ <!-- no translation found for widgets_list_expanded (7374857868788557730) -->
+ <skip />
<string name="reconfigurable_widget_education_tip" msgid="6336962690888067057">"ចុចដើម្បីប្ដូរការកំណត់ធាតុក្រាហ្វិក"</string>
<string name="widget_reconfigure_button_content_description" msgid="8811472721881205250">"ប្ដូរការកំណត់ធាតុក្រាហ្វិក"</string>
<string name="all_apps_search_bar_hint" msgid="1390553134053255246">"ស្វែងរកកម្មវិធី"</string>
@@ -124,6 +130,10 @@
<string name="msg_disabled_by_admin" msgid="6898038085516271325">"បានបិទដំណើរការដោយអ្នកគ្រប់គ្រងរបស់អ្នក"</string>
<string name="allow_rotation_title" msgid="7222049633713050106">"អនុញ្ញាតការបងិ្វលអេក្រង់ដើម"</string>
<string name="allow_rotation_desc" msgid="8662546029078692509">"នៅពេលដែលបង្វិលទូរសព្ទ"</string>
+ <!-- no translation found for landscape_mode_title (5138814555934843926) -->
+ <skip />
+ <!-- no translation found for landscape_mode_desc (7372569859592816793) -->
+ <skip />
<string name="notification_dots_title" msgid="9062440428204120317">"ស្លាកជូនដំណឹង"</string>
<string name="notification_dots_desc_on" msgid="1679848116452218908">"បើក"</string>
<string name="notification_dots_desc_off" msgid="1760796511504341095">"បិទ"</string>
@@ -142,7 +152,8 @@
<string name="app_installing_title" msgid="5864044122733792085">"កំពុងដំឡើង <xliff:g id="NAME">%1$s</xliff:g>, បានបញ្ចប់ <xliff:g id="PROGRESS">%2$s</xliff:g>"</string>
<string name="app_downloading_title" msgid="8336702962104482644">"កំពុងដោនឡូត <xliff:g id="NAME">%1$s</xliff:g> បានបញ្ចប់ <xliff:g id="PROGRESS">%2$s</xliff:g>"</string>
<string name="app_waiting_download_title" msgid="7053938513995617849">"<xliff:g id="NAME">%1$s</xliff:g> កំពុងរង់ចាំការដំឡើង"</string>
- <string name="app_archived_title" msgid="7717956158562544081">"<xliff:g id="NAME">%1$s</xliff:g> ត្រូវបានទុកក្នុងបណ្ណសារ។ សូមចុចដើម្បីទាញយក និងស្ដារ។"</string>
+ <string name="app_archived_title" msgid="4548283110222420708">"<xliff:g id="NAME">%1$s</xliff:g> ត្រូវបានទុកក្នុងបណ្ណសារ។"</string>
+ <string name="app_unarchiving_action" msgid="5736107006413929484">"ទាញយក និងស្ដារ"</string>
<string name="dialog_update_title" msgid="114234265740994042">"តម្រូវឱ្យមានកំណែកម្មវិធីថ្មី"</string>
<string name="dialog_update_message" msgid="4176784553982226114">"កម្មវិធីសម្រាប់រូបតំណាងនេះមិនត្រូវបានដំឡើងកំណែទេ។ អ្នកអាចដំឡើងកំណែដោយផ្ទាល់ ដើម្បីបើកផ្លូវកាត់នេះឡើងវិញ ឬលុបរូបតំណាងនេះ។"</string>
<string name="dialog_update" msgid="2178028071796141234">"ដំឡើងកំណែ"</string>
@@ -187,6 +198,8 @@
<string name="work_apps_paused_edu_accept" msgid="6377476824357318532">"យល់ហើយ"</string>
<string name="work_apps_pause_btn_text" msgid="4669288269140620646">"ផ្អាកកម្មវិធីការងារ"</string>
<string name="work_apps_enable_btn_text" msgid="1736198302467317371">"ឈប់ផ្អាក"</string>
+ <!-- no translation found for work_scheduler_button_content_description (917340740986764967) -->
+ <skip />
<string name="developer_options_filter_hint" msgid="5896817443635989056">"តម្រង"</string>
<string name="remote_action_failed" msgid="1383965239183576790">"បានបរាជ័យ៖ <xliff:g id="WHAT">%1$s</xliff:g>"</string>
<string name="private_space_label" msgid="2359721649407947001">"បន្ទប់ឯកជន"</string>
diff --git a/res/values-kn/strings.xml b/res/values-kn/strings.xml
index 786cea1..b4bc3a1 100644
--- a/res/values-kn/strings.xml
+++ b/res/values-kn/strings.xml
@@ -69,6 +69,12 @@
<string name="widget_category_note_taking" msgid="3469689394504266039">"ಟಿಪ್ಪಣಿ ತೆಗೆದುಕೊಳ್ಳುವುದು"</string>
<string name="widget_add_button_label" msgid="2761267068711937179">"ಸೇರಿಸಿ"</string>
<string name="widget_add_button_content_description" msgid="1810530016360039643">"<xliff:g id="WIDGET_NAME">%1$s</xliff:g> ವಿಜೆಟ್ ಸೇರಿಸಿ"</string>
+ <!-- no translation found for widgets_list_expand_button_label (7912016136574932622) -->
+ <skip />
+ <!-- no translation found for widgets_list_expand_button_content_description (4600513860973450888) -->
+ <skip />
+ <!-- no translation found for widgets_list_expanded (7374857868788557730) -->
+ <skip />
<string name="reconfigurable_widget_education_tip" msgid="6336962690888067057">"ವಿಜೆಟ್ ಸೆಟ್ಟಿಂಗ್ಗಳನ್ನು ಬದಲಾಯಿಸಲು ಟ್ಯಾಪ್ ಮಾಡಿ"</string>
<string name="widget_reconfigure_button_content_description" msgid="8811472721881205250">"ವಿಜೆಟ್ ಸೆಟ್ಟಿಂಗ್ಗಳನ್ನು ಬದಲಾಯಿಸಿ"</string>
<string name="all_apps_search_bar_hint" msgid="1390553134053255246">"ಆ್ಯಪ್ಗಳನ್ನು ಹುಡುಕಿ"</string>
@@ -124,6 +130,10 @@
<string name="msg_disabled_by_admin" msgid="6898038085516271325">"ನಿಮ್ಮ ನಿರ್ವಾಹಕರು ನಿಷ್ಕ್ರಿಯಗೊಳಿಸಿದ್ದಾರೆ"</string>
<string name="allow_rotation_title" msgid="7222049633713050106">"ಹೋಮ್ ಸ್ಕ್ರೀನ್ ತಿರುಗುವಿಕೆಯನ್ನು ಅನುಮತಿಸಿ"</string>
<string name="allow_rotation_desc" msgid="8662546029078692509">"ಫೋನ್ ತಿರುಗಿಸಿದಾಗ"</string>
+ <!-- no translation found for landscape_mode_title (5138814555934843926) -->
+ <skip />
+ <!-- no translation found for landscape_mode_desc (7372569859592816793) -->
+ <skip />
<string name="notification_dots_title" msgid="9062440428204120317">"ನೋಟಿಫಿಕೇಶನ್ ಡಾಟ್ಗಳು"</string>
<string name="notification_dots_desc_on" msgid="1679848116452218908">"ಆನ್ ಆಗಿದೆ"</string>
<string name="notification_dots_desc_off" msgid="1760796511504341095">"ಆಫ್ ಆಗಿದೆ"</string>
@@ -142,7 +152,8 @@
<string name="app_installing_title" msgid="5864044122733792085">"<xliff:g id="NAME">%1$s</xliff:g> ಇನ್ಸ್ಟಾಲ್ ಮಾಡಲಾಗುತ್ತಿದೆ, <xliff:g id="PROGRESS">%2$s</xliff:g> ಪೂರ್ಣಗೊಂಡಿದೆ"</string>
<string name="app_downloading_title" msgid="8336702962104482644">"<xliff:g id="NAME">%1$s</xliff:g> ಡೌನ್ಲೋಡ್ ಮಾಡಲಾಗುತ್ತಿದೆ, <xliff:g id="PROGRESS">%2$s</xliff:g> ಪೂರ್ಣಗೊಂಡಿದೆ"</string>
<string name="app_waiting_download_title" msgid="7053938513995617849">"<xliff:g id="NAME">%1$s</xliff:g> ಸ್ಥಾಪಿಸಲು ಕಾಯಲಾಗುತ್ತಿದೆ"</string>
- <string name="app_archived_title" msgid="7717956158562544081">"<xliff:g id="NAME">%1$s</xliff:g> ಅನ್ನು ಆರ್ಕೈವ್ ಮಾಡಲಾಗಿದೆ. ಡೌನ್ಲೋಡ್ ಮಾಡಲು ಮತ್ತು ಮರುಸ್ಥಾಪಿಸಲು ಟ್ಯಾಪ್ ಮಾಡಿ."</string>
+ <string name="app_archived_title" msgid="4548283110222420708">"<xliff:g id="NAME">%1$s</xliff:g> ಅನ್ನು ಆರ್ಕೈವ್ ಮಾಡಲಾಗಿದೆ."</string>
+ <string name="app_unarchiving_action" msgid="5736107006413929484">"ಡೌನ್ಲೋಡ್ ಮಾಡಿ ಮತ್ತು ಮರುಸ್ಥಾಪಿಸಿ"</string>
<string name="dialog_update_title" msgid="114234265740994042">"ಆ್ಯಪ್ ಅಪ್ಡೇಟ್ ಅಗತ್ಯವಿದೆ"</string>
<string name="dialog_update_message" msgid="4176784553982226114">"ಈ ಐಕಾನ್ಗಾಗಿ ಆ್ಯಪ್ ಅನ್ನು ಅಪ್ಡೇಟ್ ಮಾಡಲಾಗಿಲ್ಲ. ಈ ಶಾರ್ಟ್ಕಟ್ ಅನ್ನು ಮರು-ಸಕ್ರಿಯಗೊಳಿಸಲು ನೀವು ಹಸ್ತಚಾಲಿತವಾಗಿ ಅಪ್ಡೇಟ್ ಮಾಡಬಹುದು ಅಥವಾ ಐಕಾನ್ ಅನ್ನು ತೆಗೆದುಹಾಕಬಹುದು."</string>
<string name="dialog_update" msgid="2178028071796141234">"ಅಪ್ಡೇಟ್ ಮಾಡಿ"</string>
@@ -187,6 +198,8 @@
<string name="work_apps_paused_edu_accept" msgid="6377476824357318532">"ಅರ್ಥವಾಯಿತು"</string>
<string name="work_apps_pause_btn_text" msgid="4669288269140620646">"ಕೆಲಸಕ್ಕೆ ಸಂಬಂಧಿಸಿದ ಆ್ಯಪ್ಗಳನ್ನು ವಿರಾಮಗೊಳಿಸಿ"</string>
<string name="work_apps_enable_btn_text" msgid="1736198302467317371">"ವಿರಾಮವನ್ನು ರದ್ದುಗೊಳಿಸಿ"</string>
+ <!-- no translation found for work_scheduler_button_content_description (917340740986764967) -->
+ <skip />
<string name="developer_options_filter_hint" msgid="5896817443635989056">"ಫಿಲ್ಟರ್"</string>
<string name="remote_action_failed" msgid="1383965239183576790">"ವಿಫಲವಾಗಿದೆ: <xliff:g id="WHAT">%1$s</xliff:g>"</string>
<string name="private_space_label" msgid="2359721649407947001">"ಖಾಸಗಿ ಸ್ಪೇಸ್"</string>
diff --git a/res/values-ko/strings.xml b/res/values-ko/strings.xml
index 0e7ef7b..4baba23 100644
--- a/res/values-ko/strings.xml
+++ b/res/values-ko/strings.xml
@@ -69,6 +69,12 @@
<string name="widget_category_note_taking" msgid="3469689394504266039">"메모"</string>
<string name="widget_add_button_label" msgid="2761267068711937179">"추가"</string>
<string name="widget_add_button_content_description" msgid="1810530016360039643">"<xliff:g id="WIDGET_NAME">%1$s</xliff:g> 위젯 추가"</string>
+ <!-- no translation found for widgets_list_expand_button_label (7912016136574932622) -->
+ <skip />
+ <!-- no translation found for widgets_list_expand_button_content_description (4600513860973450888) -->
+ <skip />
+ <!-- no translation found for widgets_list_expanded (7374857868788557730) -->
+ <skip />
<string name="reconfigurable_widget_education_tip" msgid="6336962690888067057">"탭하여 위젯 설정 변경"</string>
<string name="widget_reconfigure_button_content_description" msgid="8811472721881205250">"위젯 설정 변경"</string>
<string name="all_apps_search_bar_hint" msgid="1390553134053255246">"앱 검색"</string>
@@ -124,6 +130,10 @@
<string name="msg_disabled_by_admin" msgid="6898038085516271325">"관리자가 사용 중지함"</string>
<string name="allow_rotation_title" msgid="7222049633713050106">"홈 화면 회전 허용"</string>
<string name="allow_rotation_desc" msgid="8662546029078692509">"휴대전화 회전 시"</string>
+ <!-- no translation found for landscape_mode_title (5138814555934843926) -->
+ <skip />
+ <!-- no translation found for landscape_mode_desc (7372569859592816793) -->
+ <skip />
<string name="notification_dots_title" msgid="9062440428204120317">"알림 표시 점"</string>
<string name="notification_dots_desc_on" msgid="1679848116452218908">"사용"</string>
<string name="notification_dots_desc_off" msgid="1760796511504341095">"사용 안함"</string>
@@ -142,7 +152,8 @@
<string name="app_installing_title" msgid="5864044122733792085">"<xliff:g id="NAME">%1$s</xliff:g> 설치 중, <xliff:g id="PROGRESS">%2$s</xliff:g> 완료"</string>
<string name="app_downloading_title" msgid="8336702962104482644">"<xliff:g id="NAME">%1$s</xliff:g> 다운로드 중, <xliff:g id="PROGRESS">%2$s</xliff:g> 완료"</string>
<string name="app_waiting_download_title" msgid="7053938513995617849">"<xliff:g id="NAME">%1$s</xliff:g> 설치 대기 중"</string>
- <string name="app_archived_title" msgid="7717956158562544081">"<xliff:g id="NAME">%1$s</xliff:g> 앱이 보관처리되었습니다. 탭하여 다운로드하고 복원하세요"</string>
+ <string name="app_archived_title" msgid="4548283110222420708">"<xliff:g id="NAME">%1$s</xliff:g> 앱이 보관처리되었습니다"</string>
+ <string name="app_unarchiving_action" msgid="5736107006413929484">"다운로드 및 복원"</string>
<string name="dialog_update_title" msgid="114234265740994042">"앱 업데이트 필요"</string>
<string name="dialog_update_message" msgid="4176784553982226114">"바로가기 아이콘의 앱이 업데이트되지 않았습니다. 직접 업데이트하여 앱 바로가기를 다시 사용할 수 있도록 하거나 아이콘을 삭제하세요."</string>
<string name="dialog_update" msgid="2178028071796141234">"업데이트"</string>
@@ -187,6 +198,8 @@
<string name="work_apps_paused_edu_accept" msgid="6377476824357318532">"확인"</string>
<string name="work_apps_pause_btn_text" msgid="4669288269140620646">"직장 앱 일시중지"</string>
<string name="work_apps_enable_btn_text" msgid="1736198302467317371">"일시중지 해제"</string>
+ <!-- no translation found for work_scheduler_button_content_description (917340740986764967) -->
+ <skip />
<string name="developer_options_filter_hint" msgid="5896817443635989056">"필터"</string>
<string name="remote_action_failed" msgid="1383965239183576790">"실패: <xliff:g id="WHAT">%1$s</xliff:g>"</string>
<string name="private_space_label" msgid="2359721649407947001">"비공개 스페이스"</string>
diff --git a/res/values-ky/strings.xml b/res/values-ky/strings.xml
index 753d2dd..83b0fa8 100644
--- a/res/values-ky/strings.xml
+++ b/res/values-ky/strings.xml
@@ -69,6 +69,12 @@
<string name="widget_category_note_taking" msgid="3469689394504266039">"Эскертме жазуу"</string>
<string name="widget_add_button_label" msgid="2761267068711937179">"Кошуу"</string>
<string name="widget_add_button_content_description" msgid="1810530016360039643">"<xliff:g id="WIDGET_NAME">%1$s</xliff:g> виджетин кошуу"</string>
+ <!-- no translation found for widgets_list_expand_button_label (7912016136574932622) -->
+ <skip />
+ <!-- no translation found for widgets_list_expand_button_content_description (4600513860973450888) -->
+ <skip />
+ <!-- no translation found for widgets_list_expanded (7374857868788557730) -->
+ <skip />
<string name="reconfigurable_widget_education_tip" msgid="6336962690888067057">"Виджеттин параметрлерин өзгөртүү үчүн таптап коюңуз"</string>
<string name="widget_reconfigure_button_content_description" msgid="8811472721881205250">"Виджеттин параметрлерин өзгөртүү"</string>
<string name="all_apps_search_bar_hint" msgid="1390553134053255246">"Колдонмолорду издөө"</string>
@@ -124,6 +130,10 @@
<string name="msg_disabled_by_admin" msgid="6898038085516271325">"Администраторуңуз өчүрүп койгон"</string>
<string name="allow_rotation_title" msgid="7222049633713050106">"Башкы экранды бурууга уруксат берүү"</string>
<string name="allow_rotation_desc" msgid="8662546029078692509">"Телефон бурулганда"</string>
+ <!-- no translation found for landscape_mode_title (5138814555934843926) -->
+ <skip />
+ <!-- no translation found for landscape_mode_desc (7372569859592816793) -->
+ <skip />
<string name="notification_dots_title" msgid="9062440428204120317">"Билдирмелер белгилери"</string>
<string name="notification_dots_desc_on" msgid="1679848116452218908">"Күйүк"</string>
<string name="notification_dots_desc_off" msgid="1760796511504341095">"Өчүк"</string>
@@ -142,7 +152,8 @@
<string name="app_installing_title" msgid="5864044122733792085">"<xliff:g id="NAME">%1$s</xliff:g> орнотулууда, <xliff:g id="PROGRESS">%2$s</xliff:g> аткарылды"</string>
<string name="app_downloading_title" msgid="8336702962104482644">"<xliff:g id="NAME">%1$s</xliff:g> жүктөлүп алынууда, <xliff:g id="PROGRESS">%2$s</xliff:g> аяктады"</string>
<string name="app_waiting_download_title" msgid="7053938513995617849">"<xliff:g id="NAME">%1$s</xliff:g> орнотулушу күтүлүүдө"</string>
- <string name="app_archived_title" msgid="7717956158562544081">"<xliff:g id="NAME">%1$s</xliff:g> архивделди. Жүктөп алуу жана калыбына келтирүү үчүн таптаңыз."</string>
+ <string name="app_archived_title" msgid="4548283110222420708">"<xliff:g id="NAME">%1$s</xliff:g> архивделди."</string>
+ <string name="app_unarchiving_action" msgid="5736107006413929484">"жүктөп алуу жана калыбына келтирүү"</string>
<string name="dialog_update_title" msgid="114234265740994042">"Колдонмону жаңыртыңыз"</string>
<string name="dialog_update_message" msgid="4176784553982226114">"Бул сүрөтчөнүн колдонмосу жаңыртылган эмес. Ыкчам баскычты кайра иштетүү үчүн аны кол менен жаңыртып же сүрөтчөнү өчүрүп койсоңуз болот."</string>
<string name="dialog_update" msgid="2178028071796141234">"Жаңыртуу"</string>
@@ -187,6 +198,8 @@
<string name="work_apps_paused_edu_accept" msgid="6377476824357318532">"Түшүндүм"</string>
<string name="work_apps_pause_btn_text" msgid="4669288269140620646">"Жумуш колдонмолорун тындыруу"</string>
<string name="work_apps_enable_btn_text" msgid="1736198302467317371">"Улантуу"</string>
+ <!-- no translation found for work_scheduler_button_content_description (917340740986764967) -->
+ <skip />
<string name="developer_options_filter_hint" msgid="5896817443635989056">"Чыпкалоо"</string>
<string name="remote_action_failed" msgid="1383965239183576790">"Аткарылган жок: <xliff:g id="WHAT">%1$s</xliff:g>"</string>
<string name="private_space_label" msgid="2359721649407947001">"Жеке мейкиндик"</string>
diff --git a/res/values-lo/strings.xml b/res/values-lo/strings.xml
index 9ddf0b3..767c574 100644
--- a/res/values-lo/strings.xml
+++ b/res/values-lo/strings.xml
@@ -69,6 +69,12 @@
<string name="widget_category_note_taking" msgid="3469689394504266039">"ການຈົດບັນທຶກ"</string>
<string name="widget_add_button_label" msgid="2761267068711937179">"ເພີ່ມ"</string>
<string name="widget_add_button_content_description" msgid="1810530016360039643">"ເພີ່ມວິດເຈັດ <xliff:g id="WIDGET_NAME">%1$s</xliff:g>"</string>
+ <!-- no translation found for widgets_list_expand_button_label (7912016136574932622) -->
+ <skip />
+ <!-- no translation found for widgets_list_expand_button_content_description (4600513860973450888) -->
+ <skip />
+ <!-- no translation found for widgets_list_expanded (7374857868788557730) -->
+ <skip />
<string name="reconfigurable_widget_education_tip" msgid="6336962690888067057">"ແຕະເພື່ອປ່ຽນການຕັ້ງຄ່າວິດເຈັດ"</string>
<string name="widget_reconfigure_button_content_description" msgid="8811472721881205250">"ປ່ຽນການຕັ້ງຄ່າວິດເຈັດ"</string>
<string name="all_apps_search_bar_hint" msgid="1390553134053255246">"ຊອກຫາແອັບ"</string>
@@ -124,6 +130,10 @@
<string name="msg_disabled_by_admin" msgid="6898038085516271325">"ຖືກປິດການນຳໃຊ້ໂດຍຜູ້ເບິ່ງແຍງລະບົບຂອງທ່ານ"</string>
<string name="allow_rotation_title" msgid="7222049633713050106">"ອະນຸຍາດໃຫ້ໝຸນໜ້າຈໍຢູ່ໂຮມສະກຣີນໄດ້"</string>
<string name="allow_rotation_desc" msgid="8662546029078692509">"ເມື່ອໝຸນໂທລະສັບ"</string>
+ <!-- no translation found for landscape_mode_title (5138814555934843926) -->
+ <skip />
+ <!-- no translation found for landscape_mode_desc (7372569859592816793) -->
+ <skip />
<string name="notification_dots_title" msgid="9062440428204120317">"ຈຸດການແຈ້ງເຕືອນ"</string>
<string name="notification_dots_desc_on" msgid="1679848116452218908">"ເປີດ"</string>
<string name="notification_dots_desc_off" msgid="1760796511504341095">"ປິດ"</string>
@@ -142,7 +152,8 @@
<string name="app_installing_title" msgid="5864044122733792085">"ກຳລັງຕິດຕັ້ງ <xliff:g id="NAME">%1$s</xliff:g>, <xliff:g id="PROGRESS">%2$s</xliff:g> ສຳເລັດແລ້ວ"</string>
<string name="app_downloading_title" msgid="8336702962104482644">"<xliff:g id="NAME">%1$s</xliff:g> ກຳລັງດາວໂຫຼດ, <xliff:g id="PROGRESS">%2$s</xliff:g> ສຳເລັດ"</string>
<string name="app_waiting_download_title" msgid="7053938513995617849">"<xliff:g id="NAME">%1$s</xliff:g> ກຳລັງລໍຖ້າຕິດຕັ້ງ"</string>
- <string name="app_archived_title" msgid="7717956158562544081">"<xliff:g id="NAME">%1$s</xliff:g> ຖືກເກັບໄວ້ໃນແຟ້ມ. ແຕະເພື່ອດາວໂຫຼດ ແລະ ກູ້ຄືນ."</string>
+ <string name="app_archived_title" msgid="4548283110222420708">"<xliff:g id="NAME">%1$s</xliff:g> ຖືກເກັບໄວ້ໃນແຟ້ມ."</string>
+ <string name="app_unarchiving_action" msgid="5736107006413929484">"ດາວໂຫຼດ ແລະ ກູ້ຄືນ"</string>
<string name="dialog_update_title" msgid="114234265740994042">"ຈຳເປັນຕ້ອງອັບເດດແອັບ"</string>
<string name="dialog_update_message" msgid="4176784553982226114">"ບໍ່ໄດ້ອັບເດດແອັບສຳລັບໄອຄອນນີ້. ທ່ານສາມາດອັບເດດເອງໄດ້ເພື່ອເປີດການນຳໃຊ້ທາງລັດນີ້ຄືນໃໝ່ ຫຼື ລຶບໄອຄອນດັ່ງກ່າວອອກ."</string>
<string name="dialog_update" msgid="2178028071796141234">"ອັບເດດ"</string>
@@ -187,6 +198,8 @@
<string name="work_apps_paused_edu_accept" msgid="6377476824357318532">"ເຂົ້າໃຈແລ້ວ"</string>
<string name="work_apps_pause_btn_text" msgid="4669288269140620646">"ຢຸດແອັບບ່ອນເຮັດວຽກຊົ່ວຄາວ"</string>
<string name="work_apps_enable_btn_text" msgid="1736198302467317371">"ຍົກເລີກການຢຸດຊົ່ວຄາວ"</string>
+ <!-- no translation found for work_scheduler_button_content_description (917340740986764967) -->
+ <skip />
<string name="developer_options_filter_hint" msgid="5896817443635989056">"ກັ່ນຕອງ"</string>
<string name="remote_action_failed" msgid="1383965239183576790">"ບໍ່ສຳເລັດ: <xliff:g id="WHAT">%1$s</xliff:g>"</string>
<string name="private_space_label" msgid="2359721649407947001">"ພື້ນທີ່ສ່ວນຕົວ"</string>
diff --git a/res/values-lt/strings.xml b/res/values-lt/strings.xml
index 6879862..08b603d 100644
--- a/res/values-lt/strings.xml
+++ b/res/values-lt/strings.xml
@@ -69,6 +69,12 @@
<string name="widget_category_note_taking" msgid="3469689394504266039">"Užrašų kūrimas"</string>
<string name="widget_add_button_label" msgid="2761267068711937179">"Pridėti"</string>
<string name="widget_add_button_content_description" msgid="1810530016360039643">"Pridėti valdiklį: <xliff:g id="WIDGET_NAME">%1$s</xliff:g>"</string>
+ <!-- no translation found for widgets_list_expand_button_label (7912016136574932622) -->
+ <skip />
+ <!-- no translation found for widgets_list_expand_button_content_description (4600513860973450888) -->
+ <skip />
+ <!-- no translation found for widgets_list_expanded (7374857868788557730) -->
+ <skip />
<string name="reconfigurable_widget_education_tip" msgid="6336962690888067057">"Palieskite, kad pakeistumėte valdiklio nustatymus"</string>
<string name="widget_reconfigure_button_content_description" msgid="8811472721881205250">"Pakeisti valdiklio nustatymus"</string>
<string name="all_apps_search_bar_hint" msgid="1390553134053255246">"Paieškos programos"</string>
@@ -124,6 +130,10 @@
<string name="msg_disabled_by_admin" msgid="6898038085516271325">"Išjungė administratorius"</string>
<string name="allow_rotation_title" msgid="7222049633713050106">"Leisti pasukti pagrindinį ekraną"</string>
<string name="allow_rotation_desc" msgid="8662546029078692509">"Kai telefonas pasukamas"</string>
+ <!-- no translation found for landscape_mode_title (5138814555934843926) -->
+ <skip />
+ <!-- no translation found for landscape_mode_desc (7372569859592816793) -->
+ <skip />
<string name="notification_dots_title" msgid="9062440428204120317">"Pranešimų taškai"</string>
<string name="notification_dots_desc_on" msgid="1679848116452218908">"Įjungta"</string>
<string name="notification_dots_desc_off" msgid="1760796511504341095">"Išjungta"</string>
@@ -142,7 +152,8 @@
<string name="app_installing_title" msgid="5864044122733792085">"Įdiegiama: „<xliff:g id="NAME">%1$s</xliff:g>“; baigta: <xliff:g id="PROGRESS">%2$s</xliff:g>"</string>
<string name="app_downloading_title" msgid="8336702962104482644">"Atsisiunčiama programa „<xliff:g id="NAME">%1$s</xliff:g>“, <xliff:g id="PROGRESS">%2$s</xliff:g> baigta"</string>
<string name="app_waiting_download_title" msgid="7053938513995617849">"Laukiama, kol bus įdiegta programa „<xliff:g id="NAME">%1$s</xliff:g>“"</string>
- <string name="app_archived_title" msgid="7717956158562544081">"Programa „<xliff:g id="NAME">%1$s</xliff:g>“ suarchyvuota. Palieskite, jei norite atsisiųsti ir atkurti."</string>
+ <string name="app_archived_title" msgid="4548283110222420708">"Programa „<xliff:g id="NAME">%1$s</xliff:g>“ suarchyvuota."</string>
+ <string name="app_unarchiving_action" msgid="5736107006413929484">"atsisiųsti ir atkurti"</string>
<string name="dialog_update_title" msgid="114234265740994042">"Būtina atnaujinti programą"</string>
<string name="dialog_update_message" msgid="4176784553982226114">"Šios piktogramos programa neatnaujinta. Galite patys atnaujinti, kad iš naujo įgalintumėte šį spartųjį klavišą, arba pašalinkite piktogramą."</string>
<string name="dialog_update" msgid="2178028071796141234">"Atnaujinti"</string>
@@ -187,6 +198,8 @@
<string name="work_apps_paused_edu_accept" msgid="6377476824357318532">"Supratau"</string>
<string name="work_apps_pause_btn_text" msgid="4669288269140620646">"Pristabdyti darbo programas"</string>
<string name="work_apps_enable_btn_text" msgid="1736198302467317371">"Atšaukti pristabdymą"</string>
+ <!-- no translation found for work_scheduler_button_content_description (917340740986764967) -->
+ <skip />
<string name="developer_options_filter_hint" msgid="5896817443635989056">"Filtruoti"</string>
<string name="remote_action_failed" msgid="1383965239183576790">"Nepavyko: <xliff:g id="WHAT">%1$s</xliff:g>"</string>
<string name="private_space_label" msgid="2359721649407947001">"Privati erdvė"</string>
diff --git a/res/values-lv/strings.xml b/res/values-lv/strings.xml
index 8166bce..e02abe0 100644
--- a/res/values-lv/strings.xml
+++ b/res/values-lv/strings.xml
@@ -69,6 +69,12 @@
<string name="widget_category_note_taking" msgid="3469689394504266039">"Piezīmju pierakstīšana"</string>
<string name="widget_add_button_label" msgid="2761267068711937179">"Pievienot"</string>
<string name="widget_add_button_content_description" msgid="1810530016360039643">"Pievienot logrīku <xliff:g id="WIDGET_NAME">%1$s</xliff:g>"</string>
+ <!-- no translation found for widgets_list_expand_button_label (7912016136574932622) -->
+ <skip />
+ <!-- no translation found for widgets_list_expand_button_content_description (4600513860973450888) -->
+ <skip />
+ <!-- no translation found for widgets_list_expanded (7374857868788557730) -->
+ <skip />
<string name="reconfigurable_widget_education_tip" msgid="6336962690888067057">"Pieskarieties, lai mainītu logrīka iestatījumus."</string>
<string name="widget_reconfigure_button_content_description" msgid="8811472721881205250">"Mainīt logrīka iestatījumus"</string>
<string name="all_apps_search_bar_hint" msgid="1390553134053255246">"Meklēt lietotnes"</string>
@@ -124,6 +130,10 @@
<string name="msg_disabled_by_admin" msgid="6898038085516271325">"Atspējojis administrators"</string>
<string name="allow_rotation_title" msgid="7222049633713050106">"Atļaut sākuma ekrāna pagriešanu"</string>
<string name="allow_rotation_desc" msgid="8662546029078692509">"Pagriežot tālruni"</string>
+ <!-- no translation found for landscape_mode_title (5138814555934843926) -->
+ <skip />
+ <!-- no translation found for landscape_mode_desc (7372569859592816793) -->
+ <skip />
<string name="notification_dots_title" msgid="9062440428204120317">"Paziņojumu punkti"</string>
<string name="notification_dots_desc_on" msgid="1679848116452218908">"Ieslēgti"</string>
<string name="notification_dots_desc_off" msgid="1760796511504341095">"Izslēgts"</string>
@@ -142,7 +152,8 @@
<string name="app_installing_title" msgid="5864044122733792085">"Notiek lietotnes “<xliff:g id="NAME">%1$s</xliff:g>” instalēšana. Norise: <xliff:g id="PROGRESS">%2$s</xliff:g>."</string>
<string name="app_downloading_title" msgid="8336702962104482644">"Lietotnes <xliff:g id="NAME">%1$s</xliff:g> lejupielāde (<xliff:g id="PROGRESS">%2$s</xliff:g> pabeigti)"</string>
<string name="app_waiting_download_title" msgid="7053938513995617849">"Notiek <xliff:g id="NAME">%1$s</xliff:g> instalēšana"</string>
- <string name="app_archived_title" msgid="7717956158562544081">"Lietotne <xliff:g id="NAME">%1$s</xliff:g> ir arhivēta; lai lejupielādētu un atjaunotu, pieskarieties"</string>
+ <string name="app_archived_title" msgid="4548283110222420708">"Lietotne <xliff:g id="NAME">%1$s</xliff:g> ir arhivēta."</string>
+ <string name="app_unarchiving_action" msgid="5736107006413929484">"lejupielādēt un atjaunot"</string>
<string name="dialog_update_title" msgid="114234265740994042">"Lietotne ir jāatjaunina"</string>
<string name="dialog_update_message" msgid="4176784553982226114">"Šai ikonai paredzētā lietotne nav atjaunināta. Varat to atjaunināt manuāli, lai atkārtoti iespējotu šo saīsni, vai noņemt ikonu."</string>
<string name="dialog_update" msgid="2178028071796141234">"Atjaunināt"</string>
@@ -187,6 +198,8 @@
<string name="work_apps_paused_edu_accept" msgid="6377476824357318532">"Labi"</string>
<string name="work_apps_pause_btn_text" msgid="4669288269140620646">"Pārtraukt darba lietotņu darbību"</string>
<string name="work_apps_enable_btn_text" msgid="1736198302467317371">"Atsākt"</string>
+ <!-- no translation found for work_scheduler_button_content_description (917340740986764967) -->
+ <skip />
<string name="developer_options_filter_hint" msgid="5896817443635989056">"Filtrs"</string>
<string name="remote_action_failed" msgid="1383965239183576790">"Neizdevās: <xliff:g id="WHAT">%1$s</xliff:g>"</string>
<string name="private_space_label" msgid="2359721649407947001">"Privātā telpa"</string>
diff --git a/res/values-mk/strings.xml b/res/values-mk/strings.xml
index 0511c3f..e524d82 100644
--- a/res/values-mk/strings.xml
+++ b/res/values-mk/strings.xml
@@ -69,6 +69,12 @@
<string name="widget_category_note_taking" msgid="3469689394504266039">"Фаќање белешки"</string>
<string name="widget_add_button_label" msgid="2761267068711937179">"Додај"</string>
<string name="widget_add_button_content_description" msgid="1810530016360039643">"Додај го виџетот <xliff:g id="WIDGET_NAME">%1$s</xliff:g>"</string>
+ <!-- no translation found for widgets_list_expand_button_label (7912016136574932622) -->
+ <skip />
+ <!-- no translation found for widgets_list_expand_button_content_description (4600513860973450888) -->
+ <skip />
+ <!-- no translation found for widgets_list_expanded (7374857868788557730) -->
+ <skip />
<string name="reconfigurable_widget_education_tip" msgid="6336962690888067057">"Допрете за да ги промените поставките за виџетот"</string>
<string name="widget_reconfigure_button_content_description" msgid="8811472721881205250">"Промени ги поставките за виџетот"</string>
<string name="all_apps_search_bar_hint" msgid="1390553134053255246">"Пребарувајте апликации"</string>
@@ -124,6 +130,10 @@
<string name="msg_disabled_by_admin" msgid="6898038085516271325">"Оневозможено од администраторот"</string>
<string name="allow_rotation_title" msgid="7222049633713050106">"Дозволи ротирање на почетниот екран"</string>
<string name="allow_rotation_desc" msgid="8662546029078692509">"Кога телефонот се ротира"</string>
+ <!-- no translation found for landscape_mode_title (5138814555934843926) -->
+ <skip />
+ <!-- no translation found for landscape_mode_desc (7372569859592816793) -->
+ <skip />
<string name="notification_dots_title" msgid="9062440428204120317">"Точки за известување"</string>
<string name="notification_dots_desc_on" msgid="1679848116452218908">"Вклучено"</string>
<string name="notification_dots_desc_off" msgid="1760796511504341095">"Исклучено"</string>
@@ -142,7 +152,8 @@
<string name="app_installing_title" msgid="5864044122733792085">"<xliff:g id="NAME">%1$s</xliff:g> се инсталира, <xliff:g id="PROGRESS">%2$s</xliff:g> завршено"</string>
<string name="app_downloading_title" msgid="8336702962104482644">"Се презема <xliff:g id="NAME">%1$s</xliff:g>, <xliff:g id="PROGRESS">%2$s</xliff:g> завршено"</string>
<string name="app_waiting_download_title" msgid="7053938513995617849">"<xliff:g id="NAME">%1$s</xliff:g> чека да се инсталира"</string>
- <string name="app_archived_title" msgid="7717956158562544081">"Апликацијата <xliff:g id="NAME">%1$s</xliff:g> е архивирана. Допрете за да преземете и вратите."</string>
+ <string name="app_archived_title" msgid="4548283110222420708">"Апликацијата <xliff:g id="NAME">%1$s</xliff:g> е архивирана."</string>
+ <string name="app_unarchiving_action" msgid="5736107006413929484">"преземете и вратете"</string>
<string name="dialog_update_title" msgid="114234265740994042">"Потребно е ажурирање на апликацијата"</string>
<string name="dialog_update_message" msgid="4176784553982226114">"Апликацијата за оваа икона не е ажурирана. Може да ажурирате рачно за да повторно се овозможи кратенкава или отстранете ја иконата."</string>
<string name="dialog_update" msgid="2178028071796141234">"Ажурирај"</string>
@@ -187,6 +198,8 @@
<string name="work_apps_paused_edu_accept" msgid="6377476824357318532">"Сфатив"</string>
<string name="work_apps_pause_btn_text" msgid="4669288269140620646">"Паузирај ги работните апликации"</string>
<string name="work_apps_enable_btn_text" msgid="1736198302467317371">"Прекини ја паузата"</string>
+ <!-- no translation found for work_scheduler_button_content_description (917340740986764967) -->
+ <skip />
<string name="developer_options_filter_hint" msgid="5896817443635989056">"Филтер"</string>
<string name="remote_action_failed" msgid="1383965239183576790">"Не успеа: <xliff:g id="WHAT">%1$s</xliff:g>"</string>
<string name="private_space_label" msgid="2359721649407947001">"Приватен простор"</string>
diff --git a/res/values-ml/strings.xml b/res/values-ml/strings.xml
index b9e68e0..e273e14 100644
--- a/res/values-ml/strings.xml
+++ b/res/values-ml/strings.xml
@@ -69,6 +69,12 @@
<string name="widget_category_note_taking" msgid="3469689394504266039">"കുറിപ്പ് രേഖപ്പെടുത്തൽ"</string>
<string name="widget_add_button_label" msgid="2761267068711937179">"ചേർക്കുക"</string>
<string name="widget_add_button_content_description" msgid="1810530016360039643">"<xliff:g id="WIDGET_NAME">%1$s</xliff:g> വിജറ്റ് ചേർക്കുക"</string>
+ <!-- no translation found for widgets_list_expand_button_label (7912016136574932622) -->
+ <skip />
+ <!-- no translation found for widgets_list_expand_button_content_description (4600513860973450888) -->
+ <skip />
+ <!-- no translation found for widgets_list_expanded (7374857868788557730) -->
+ <skip />
<string name="reconfigurable_widget_education_tip" msgid="6336962690888067057">"വിജറ്റ് ക്രമീകരണം മാറ്റാൻ ടാപ്പ് ചെയ്യുക"</string>
<string name="widget_reconfigure_button_content_description" msgid="8811472721881205250">"വിജറ്റ് ക്രമീകരണം മാറ്റുക"</string>
<string name="all_apps_search_bar_hint" msgid="1390553134053255246">"ആപ്പുകൾ തിരയുക"</string>
@@ -124,6 +130,10 @@
<string name="msg_disabled_by_admin" msgid="6898038085516271325">"അഡ്മിൻ പ്രവർത്തനരഹിതമാക്കിയിരിക്കുന്നു"</string>
<string name="allow_rotation_title" msgid="7222049633713050106">"ഹോം സ്ക്രീൻ റൊട്ടേഷൻ അനുവദിക്കുക"</string>
<string name="allow_rotation_desc" msgid="8662546029078692509">"ഫോൺ തിരിച്ച നിലയിലായിരിക്കുമ്പോൾ"</string>
+ <!-- no translation found for landscape_mode_title (5138814555934843926) -->
+ <skip />
+ <!-- no translation found for landscape_mode_desc (7372569859592816793) -->
+ <skip />
<string name="notification_dots_title" msgid="9062440428204120317">"അറിയിപ്പ് ഡോട്ടുകൾ"</string>
<string name="notification_dots_desc_on" msgid="1679848116452218908">"ഓണാണ്"</string>
<string name="notification_dots_desc_off" msgid="1760796511504341095">"ഓഫാണ്"</string>
@@ -142,7 +152,8 @@
<string name="app_installing_title" msgid="5864044122733792085">"<xliff:g id="NAME">%1$s</xliff:g> ഇൻസ്റ്റാൾ ചെയ്യുന്നു, <xliff:g id="PROGRESS">%2$s</xliff:g> പൂർത്തിയായി"</string>
<string name="app_downloading_title" msgid="8336702962104482644">"<xliff:g id="NAME">%1$s</xliff:g> ഡൗൺലോഡ് ചെയ്യുന്നു, <xliff:g id="PROGRESS">%2$s</xliff:g> പൂർത്തിയായി"</string>
<string name="app_waiting_download_title" msgid="7053938513995617849">"ഇൻസ്റ്റാൾ ചെയ്യാൻ <xliff:g id="NAME">%1$s</xliff:g> കാക്കുന്നു"</string>
- <string name="app_archived_title" msgid="7717956158562544081">"<xliff:g id="NAME">%1$s</xliff:g> ആർക്കൈവ് ചെയ്തു. ഡൗൺലോഡ് ചെയ്യാനും പുനഃസ്ഥാപിക്കാനും ടാപ്പ് ചെയ്യുക."</string>
+ <string name="app_archived_title" msgid="4548283110222420708">"<xliff:g id="NAME">%1$s</xliff:g> ആർക്കൈവ് ചെയ്തു."</string>
+ <string name="app_unarchiving_action" msgid="5736107006413929484">"ഡൗൺലോഡ് ചെയ്ത് പുനഃസ്ഥാപിക്കുക"</string>
<string name="dialog_update_title" msgid="114234265740994042">"ആപ്പ് അപ്ഡേറ്റ് ചെയ്യേണ്ടതുണ്ട്"</string>
<string name="dialog_update_message" msgid="4176784553982226114">"ഈ ഐക്കണിനുള്ള ആപ്പ് അപ്ഡേറ്റ് ചെയ്തിട്ടില്ല. ഈ കുറുക്കുവഴി വീണ്ടും പ്രവർത്തനക്ഷമമാക്കാൻ നിങ്ങൾക്ക് നേരിട്ട് അപ്ഡേറ്റ് ചെയ്യാം അല്ലെങ്കിൽ ഐക്കൺ നീക്കം ചെയ്യാം."</string>
<string name="dialog_update" msgid="2178028071796141234">"അപ്ഡേറ്റ് ചെയ്യുക"</string>
@@ -187,6 +198,8 @@
<string name="work_apps_paused_edu_accept" msgid="6377476824357318532">"മനസ്സിലായി"</string>
<string name="work_apps_pause_btn_text" msgid="4669288269140620646">"ഔദ്യോഗിക ആപ്പുകൾ താൽക്കാലികമായി നിർത്തുക"</string>
<string name="work_apps_enable_btn_text" msgid="1736198302467317371">"താൽക്കാലികമായി നിർത്തിയത് മാറ്റുക"</string>
+ <!-- no translation found for work_scheduler_button_content_description (917340740986764967) -->
+ <skip />
<string name="developer_options_filter_hint" msgid="5896817443635989056">"ഫിൽട്ടർ ചെയ്യുക"</string>
<string name="remote_action_failed" msgid="1383965239183576790">"പരാജയപ്പെട്ടു: <xliff:g id="WHAT">%1$s</xliff:g>"</string>
<string name="private_space_label" msgid="2359721649407947001">"സ്വകാര്യ സ്പേസ്"</string>
diff --git a/res/values-mn/strings.xml b/res/values-mn/strings.xml
index 28a1438..7e5ed73 100644
--- a/res/values-mn/strings.xml
+++ b/res/values-mn/strings.xml
@@ -69,6 +69,12 @@
<string name="widget_category_note_taking" msgid="3469689394504266039">"Тэмдэглэл хөтлөх"</string>
<string name="widget_add_button_label" msgid="2761267068711937179">"Нэмэх"</string>
<string name="widget_add_button_content_description" msgid="1810530016360039643">"<xliff:g id="WIDGET_NAME">%1$s</xliff:g> виджетийг нэмэх"</string>
+ <!-- no translation found for widgets_list_expand_button_label (7912016136574932622) -->
+ <skip />
+ <!-- no translation found for widgets_list_expand_button_content_description (4600513860973450888) -->
+ <skip />
+ <!-- no translation found for widgets_list_expanded (7374857868788557730) -->
+ <skip />
<string name="reconfigurable_widget_education_tip" msgid="6336962690888067057">"Жижиг хэрэгслийн тохиргоог өөрчлөхийн тулд товшино уу"</string>
<string name="widget_reconfigure_button_content_description" msgid="8811472721881205250">"Жижиг хэрэгслийн тохиргоог өөрчлөх"</string>
<string name="all_apps_search_bar_hint" msgid="1390553134053255246">"Апп хайх"</string>
@@ -124,6 +130,10 @@
<string name="msg_disabled_by_admin" msgid="6898038085516271325">"Таны админ идэвхгүй болгосон"</string>
<string name="allow_rotation_title" msgid="7222049633713050106">"Үндсэн нүүрийг эргүүлэхийг зөвшөөрөх"</string>
<string name="allow_rotation_desc" msgid="8662546029078692509">"Утсыг эргүүлсэн үед"</string>
+ <!-- no translation found for landscape_mode_title (5138814555934843926) -->
+ <skip />
+ <!-- no translation found for landscape_mode_desc (7372569859592816793) -->
+ <skip />
<string name="notification_dots_title" msgid="9062440428204120317">"Мэдэгдлийн цэг"</string>
<string name="notification_dots_desc_on" msgid="1679848116452218908">"Асаалттай"</string>
<string name="notification_dots_desc_off" msgid="1760796511504341095">"Унтраалттай"</string>
@@ -142,7 +152,8 @@
<string name="app_installing_title" msgid="5864044122733792085">"<xliff:g id="NAME">%1$s</xliff:g>-г суулгаж байна. <xliff:g id="PROGRESS">%2$s</xliff:g> дууссан"</string>
<string name="app_downloading_title" msgid="8336702962104482644">"<xliff:g id="NAME">%1$s</xliff:g>-г татаж байна, <xliff:g id="PROGRESS">%2$s</xliff:g> татсан"</string>
<string name="app_waiting_download_title" msgid="7053938513995617849">"<xliff:g id="NAME">%1$s</xliff:g> нь суулгахыг хүлээж байна"</string>
- <string name="app_archived_title" msgid="7717956158562544081">"<xliff:g id="NAME">%1$s</xliff:g>-г архивласан. Татаж, сэргээхийн тулд товшино уу."</string>
+ <string name="app_archived_title" msgid="4548283110222420708">"<xliff:g id="NAME">%1$s</xliff:g>-г архивласан."</string>
+ <string name="app_unarchiving_action" msgid="5736107006413929484">"татах, сэргээх"</string>
<string name="dialog_update_title" msgid="114234265740994042">"Аппын шинэчлэлт шаардлагатай"</string>
<string name="dialog_update_message" msgid="4176784553982226114">"Энэ дүрс тэмдгийн аппыг шинэчлээгүй. Та энэ товчлолыг дахин идэвхжүүлэх эсвэл дүрсийг хасахын тулд гараар шинэчлэх боломжтой."</string>
<string name="dialog_update" msgid="2178028071796141234">"Шинэчлэх"</string>
@@ -187,6 +198,8 @@
<string name="work_apps_paused_edu_accept" msgid="6377476824357318532">"Ойлголоо"</string>
<string name="work_apps_pause_btn_text" msgid="4669288269140620646">"Ажлын аппуудыг түр зогсоох"</string>
<string name="work_apps_enable_btn_text" msgid="1736198302467317371">"Түр зогсоохоо болих"</string>
+ <!-- no translation found for work_scheduler_button_content_description (917340740986764967) -->
+ <skip />
<string name="developer_options_filter_hint" msgid="5896817443635989056">"Шүүлтүүр"</string>
<string name="remote_action_failed" msgid="1383965239183576790">"Амжилтгүй болсон: <xliff:g id="WHAT">%1$s</xliff:g>"</string>
<string name="private_space_label" msgid="2359721649407947001">"Хувийн орон зай"</string>
diff --git a/res/values-mr/strings.xml b/res/values-mr/strings.xml
index 0190f1f..b5d4f71 100644
--- a/res/values-mr/strings.xml
+++ b/res/values-mr/strings.xml
@@ -69,6 +69,12 @@
<string name="widget_category_note_taking" msgid="3469689394504266039">"टिपा घेणे"</string>
<string name="widget_add_button_label" msgid="2761267068711937179">"जोडा"</string>
<string name="widget_add_button_content_description" msgid="1810530016360039643">"<xliff:g id="WIDGET_NAME">%1$s</xliff:g> विजेट जोडा"</string>
+ <!-- no translation found for widgets_list_expand_button_label (7912016136574932622) -->
+ <skip />
+ <!-- no translation found for widgets_list_expand_button_content_description (4600513860973450888) -->
+ <skip />
+ <!-- no translation found for widgets_list_expanded (7374857868788557730) -->
+ <skip />
<string name="reconfigurable_widget_education_tip" msgid="6336962690888067057">"विजेट सेटिंग्ज बदलण्यासाठी टॅप करा"</string>
<string name="widget_reconfigure_button_content_description" msgid="8811472721881205250">"विजेट सेटिंग्ज बदला"</string>
<string name="all_apps_search_bar_hint" msgid="1390553134053255246">"अॅप्स शोधा"</string>
@@ -124,6 +130,10 @@
<string name="msg_disabled_by_admin" msgid="6898038085516271325">"आपल्या प्रशासकाने अक्षम केले"</string>
<string name="allow_rotation_title" msgid="7222049633713050106">"होम स्क्रीन फिरवण्याची अनुमती द्या"</string>
<string name="allow_rotation_desc" msgid="8662546029078692509">"फोन फिरवला जातो तेव्हा"</string>
+ <!-- no translation found for landscape_mode_title (5138814555934843926) -->
+ <skip />
+ <!-- no translation found for landscape_mode_desc (7372569859592816793) -->
+ <skip />
<string name="notification_dots_title" msgid="9062440428204120317">"नोटिफिकेशन डॉट"</string>
<string name="notification_dots_desc_on" msgid="1679848116452218908">"सुरू"</string>
<string name="notification_dots_desc_off" msgid="1760796511504341095">"बंद"</string>
@@ -142,7 +152,8 @@
<string name="app_installing_title" msgid="5864044122733792085">"<xliff:g id="NAME">%1$s</xliff:g> इंस्टॉल करत आहे, <xliff:g id="PROGRESS">%2$s</xliff:g> पूर्ण झाले"</string>
<string name="app_downloading_title" msgid="8336702962104482644">"<xliff:g id="NAME">%1$s</xliff:g> डाउनलोड होत आहे , <xliff:g id="PROGRESS">%2$s</xliff:g> पूर्ण झाले"</string>
<string name="app_waiting_download_title" msgid="7053938513995617849">"<xliff:g id="NAME">%1$s</xliff:g> इंस्टॉल करण्याची प्रतिक्षा करत आहे"</string>
- <string name="app_archived_title" msgid="7717956158562544081">"<xliff:g id="NAME">%1$s</xliff:g> संग्रहित केले आहे. डाउनलोड करून रिस्टोअर करण्यासाठी टॅप करा."</string>
+ <string name="app_archived_title" msgid="4548283110222420708">"<xliff:g id="NAME">%1$s</xliff:g> संग्रहित केले आहे."</string>
+ <string name="app_unarchiving_action" msgid="5736107006413929484">"डाउनलोड करून रिस्टोअर करा"</string>
<string name="dialog_update_title" msgid="114234265740994042">"अॅप अपडेट करणे आवश्यक आहे"</string>
<string name="dialog_update_message" msgid="4176784553982226114">"या आयकनसाठी अॅप अपडेट केलेले नाही. हा शॉटकर्ट पुन्हा सुरू करण्यासाठी तुम्ही मॅन्युअली अपडेट करू शकता किंवा आयकन काढून टाका."</string>
<string name="dialog_update" msgid="2178028071796141234">"अपडेट करा"</string>
@@ -187,6 +198,8 @@
<string name="work_apps_paused_edu_accept" msgid="6377476824357318532">"समजले"</string>
<string name="work_apps_pause_btn_text" msgid="4669288269140620646">"कार्य ॲप्स थांबवा"</string>
<string name="work_apps_enable_btn_text" msgid="1736198302467317371">"अनपॉझ करा"</string>
+ <!-- no translation found for work_scheduler_button_content_description (917340740986764967) -->
+ <skip />
<string name="developer_options_filter_hint" msgid="5896817443635989056">"फिल्टर"</string>
<string name="remote_action_failed" msgid="1383965239183576790">"हे करता आले नाही: <xliff:g id="WHAT">%1$s</xliff:g>"</string>
<string name="private_space_label" msgid="2359721649407947001">"खाजगी स्पेस"</string>
diff --git a/res/values-ms/strings.xml b/res/values-ms/strings.xml
index 6941139..a48d518 100644
--- a/res/values-ms/strings.xml
+++ b/res/values-ms/strings.xml
@@ -69,6 +69,12 @@
<string name="widget_category_note_taking" msgid="3469689394504266039">"Pengambilan nota"</string>
<string name="widget_add_button_label" msgid="2761267068711937179">"Tambah"</string>
<string name="widget_add_button_content_description" msgid="1810530016360039643">"Tambahkan widget <xliff:g id="WIDGET_NAME">%1$s</xliff:g>"</string>
+ <!-- no translation found for widgets_list_expand_button_label (7912016136574932622) -->
+ <skip />
+ <!-- no translation found for widgets_list_expand_button_content_description (4600513860973450888) -->
+ <skip />
+ <!-- no translation found for widgets_list_expanded (7374857868788557730) -->
+ <skip />
<string name="reconfigurable_widget_education_tip" msgid="6336962690888067057">"Ketik untuk menukar tetapan widget"</string>
<string name="widget_reconfigure_button_content_description" msgid="8811472721881205250">"Tukar tetapan widget"</string>
<string name="all_apps_search_bar_hint" msgid="1390553134053255246">"Cari apl"</string>
@@ -124,6 +130,10 @@
<string name="msg_disabled_by_admin" msgid="6898038085516271325">"Dilumpuhkan oleh pentadbir anda"</string>
<string name="allow_rotation_title" msgid="7222049633713050106">"Benarkan putaran skrin utama"</string>
<string name="allow_rotation_desc" msgid="8662546029078692509">"Apabila telefon diputar"</string>
+ <!-- no translation found for landscape_mode_title (5138814555934843926) -->
+ <skip />
+ <!-- no translation found for landscape_mode_desc (7372569859592816793) -->
+ <skip />
<string name="notification_dots_title" msgid="9062440428204120317">"Titik pemberitahuan"</string>
<string name="notification_dots_desc_on" msgid="1679848116452218908">"Hidup"</string>
<string name="notification_dots_desc_off" msgid="1760796511504341095">"Mati"</string>
@@ -142,7 +152,8 @@
<string name="app_installing_title" msgid="5864044122733792085">"<xliff:g id="NAME">%1$s</xliff:g> dipasang, <xliff:g id="PROGRESS">%2$s</xliff:g> selesai"</string>
<string name="app_downloading_title" msgid="8336702962104482644">"<xliff:g id="NAME">%1$s</xliff:g> memuat turun, <xliff:g id="PROGRESS">%2$s</xliff:g> selesai"</string>
<string name="app_waiting_download_title" msgid="7053938513995617849">"<xliff:g id="NAME">%1$s</xliff:g> menunggu untuk dipasang"</string>
- <string name="app_archived_title" msgid="7717956158562544081">"<xliff:g id="NAME">%1$s</xliff:g> diarkibkan. Ketik untuk memuat turun dan memulihkan apl tersebut."</string>
+ <string name="app_archived_title" msgid="4548283110222420708">"<xliff:g id="NAME">%1$s</xliff:g> diarkibkan."</string>
+ <string name="app_unarchiving_action" msgid="5736107006413929484">"muat turun dan pulihkan"</string>
<string name="dialog_update_title" msgid="114234265740994042">"Kemas kini apl diperlukan"</string>
<string name="dialog_update_message" msgid="4176784553982226114">"Apl untuk ikon ini tidak dikemas kini. Anda boleh mengemas kini secara manual untuk mendayakan semula pintasan atau mengalih keluar ikon."</string>
<string name="dialog_update" msgid="2178028071796141234">"Kemas kini"</string>
@@ -187,6 +198,8 @@
<string name="work_apps_paused_edu_accept" msgid="6377476824357318532">"OK"</string>
<string name="work_apps_pause_btn_text" msgid="4669288269140620646">"Jeda apl kerja"</string>
<string name="work_apps_enable_btn_text" msgid="1736198302467317371">"Nyahjeda"</string>
+ <!-- no translation found for work_scheduler_button_content_description (917340740986764967) -->
+ <skip />
<string name="developer_options_filter_hint" msgid="5896817443635989056">"Tapis"</string>
<string name="remote_action_failed" msgid="1383965239183576790">"Gagal: <xliff:g id="WHAT">%1$s</xliff:g>"</string>
<string name="private_space_label" msgid="2359721649407947001">"Ruang persendirian"</string>
diff --git a/res/values-my/strings.xml b/res/values-my/strings.xml
index 948f2eb..f892a1b 100644
--- a/res/values-my/strings.xml
+++ b/res/values-my/strings.xml
@@ -69,6 +69,12 @@
<string name="widget_category_note_taking" msgid="3469689394504266039">"မှတ်စုလိုက်ခြင်း"</string>
<string name="widget_add_button_label" msgid="2761267068711937179">"ထည့်ရန်"</string>
<string name="widget_add_button_content_description" msgid="1810530016360039643">"<xliff:g id="WIDGET_NAME">%1$s</xliff:g> ဝိဂျက်ထည့်ရန်"</string>
+ <!-- no translation found for widgets_list_expand_button_label (7912016136574932622) -->
+ <skip />
+ <!-- no translation found for widgets_list_expand_button_content_description (4600513860973450888) -->
+ <skip />
+ <!-- no translation found for widgets_list_expanded (7374857868788557730) -->
+ <skip />
<string name="reconfigurable_widget_education_tip" msgid="6336962690888067057">"ဝိဂျက် ဆက်တင်များကို ပြောင်းရန် တို့ပါ"</string>
<string name="widget_reconfigure_button_content_description" msgid="8811472721881205250">"ဝိဂျက် ဆက်တင်များကို ပြောင်းပါ"</string>
<string name="all_apps_search_bar_hint" msgid="1390553134053255246">"ရှာဖွေမှု အက်ပ်များ"</string>
@@ -124,6 +130,10 @@
<string name="msg_disabled_by_admin" msgid="6898038085516271325">"သင့်စီမံခန့်ခွဲသူက ပိတ်လိုက်ပါသည်"</string>
<string name="allow_rotation_title" msgid="7222049633713050106">"ပင်မစာမျက်နှာလှည့်ခြင်းကို ခွင့်ပြုခြင်း"</string>
<string name="allow_rotation_desc" msgid="8662546029078692509">"ဖုန်းကိုလှည့်ထားစဉ်"</string>
+ <!-- no translation found for landscape_mode_title (5138814555934843926) -->
+ <skip />
+ <!-- no translation found for landscape_mode_desc (7372569859592816793) -->
+ <skip />
<string name="notification_dots_title" msgid="9062440428204120317">"သတိပေးချက် အစက်များ"</string>
<string name="notification_dots_desc_on" msgid="1679848116452218908">"ဖွင့်"</string>
<string name="notification_dots_desc_off" msgid="1760796511504341095">"ပိတ်"</string>
@@ -142,7 +152,8 @@
<string name="app_installing_title" msgid="5864044122733792085">"<xliff:g id="NAME">%1$s</xliff:g> ကို ထည့်သွင်းနေသည်၊ <xliff:g id="PROGRESS">%2$s</xliff:g> ပြီးပါပြီ"</string>
<string name="app_downloading_title" msgid="8336702962104482644">"<xliff:g id="NAME">%1$s</xliff:g> ဒေါင်းလုဒ်လုပ်နေသည်၊ <xliff:g id="PROGRESS">%2$s</xliff:g> ပြီးပါပြီ"</string>
<string name="app_waiting_download_title" msgid="7053938513995617849">"<xliff:g id="NAME">%1$s</xliff:g> ကိုထည့်သွင်းရန်စောင့်နေသည်"</string>
- <string name="app_archived_title" msgid="7717956158562544081">"<xliff:g id="NAME">%1$s</xliff:g> ကို သိမ်းထားသည်။ ဒေါင်းလုဒ်လုပ်ပြီး ပြန်ယူရန် တို့ပါ။"</string>
+ <string name="app_archived_title" msgid="4548283110222420708">"<xliff:g id="NAME">%1$s</xliff:g> ကို သိမ်းထားသည်။"</string>
+ <string name="app_unarchiving_action" msgid="5736107006413929484">"ဒေါင်းလုဒ်လုပ်ပြီး ပြန်ယူရန်"</string>
<string name="dialog_update_title" msgid="114234265740994042">"အက်ပ်ကို အပ်ဒိတ်လုပ်ရန် လိုအပ်သည်"</string>
<string name="dialog_update_message" msgid="4176784553982226114">"ဤသင်္ကေတအတွက် အက်ပ်ကို အပ်ဒိတ်လုပ်မထားပါ။ ဤဖြတ်လမ်းလင့်ခ်ကို ပြန်ဖွင့်ရန် ကိုယ်တိုင်အပ်ဒိတ်လုပ်နိုင်သည် (သို့) သင်္ကေတကို ဖယ်ရှားနိုင်သည်။"</string>
<string name="dialog_update" msgid="2178028071796141234">"အပ်ဒိတ်လုပ်ရန်"</string>
@@ -187,6 +198,8 @@
<string name="work_apps_paused_edu_accept" msgid="6377476824357318532">"နားလည်ပြီ"</string>
<string name="work_apps_pause_btn_text" msgid="4669288269140620646">"အလုပ်သုံးအက်ပ်များကို ခဏရပ်ရန်"</string>
<string name="work_apps_enable_btn_text" msgid="1736198302467317371">"ပြန်ဖွင့်ရန်"</string>
+ <!-- no translation found for work_scheduler_button_content_description (917340740986764967) -->
+ <skip />
<string name="developer_options_filter_hint" msgid="5896817443635989056">"စစ်ထုတ်ရန်"</string>
<string name="remote_action_failed" msgid="1383965239183576790">"မအောင်မြင်ပါ− <xliff:g id="WHAT">%1$s</xliff:g>"</string>
<string name="private_space_label" msgid="2359721649407947001">"သီးသန့်ချတ်ခန်း"</string>
diff --git a/res/values-nb/strings.xml b/res/values-nb/strings.xml
index 0dc6160..b9b69a0 100644
--- a/res/values-nb/strings.xml
+++ b/res/values-nb/strings.xml
@@ -69,6 +69,12 @@
<string name="widget_category_note_taking" msgid="3469689394504266039">"Notatskriving"</string>
<string name="widget_add_button_label" msgid="2761267068711937179">"Legg til"</string>
<string name="widget_add_button_content_description" msgid="1810530016360039643">"Legg til <xliff:g id="WIDGET_NAME">%1$s</xliff:g>-modulen"</string>
+ <!-- no translation found for widgets_list_expand_button_label (7912016136574932622) -->
+ <skip />
+ <!-- no translation found for widgets_list_expand_button_content_description (4600513860973450888) -->
+ <skip />
+ <!-- no translation found for widgets_list_expanded (7374857868788557730) -->
+ <skip />
<string name="reconfigurable_widget_education_tip" msgid="6336962690888067057">"Trykk for å endre modulinnstillinger"</string>
<string name="widget_reconfigure_button_content_description" msgid="8811472721881205250">"Endre modulinnstillinger"</string>
<string name="all_apps_search_bar_hint" msgid="1390553134053255246">"Søk etter apper"</string>
@@ -124,6 +130,10 @@
<string name="msg_disabled_by_admin" msgid="6898038085516271325">"Administratoren har slått av funksjonen"</string>
<string name="allow_rotation_title" msgid="7222049633713050106">"Tillat at startskjermen roterer"</string>
<string name="allow_rotation_desc" msgid="8662546029078692509">"Når telefonen roteres"</string>
+ <!-- no translation found for landscape_mode_title (5138814555934843926) -->
+ <skip />
+ <!-- no translation found for landscape_mode_desc (7372569859592816793) -->
+ <skip />
<string name="notification_dots_title" msgid="9062440428204120317">"Varselsprikker"</string>
<string name="notification_dots_desc_on" msgid="1679848116452218908">"På"</string>
<string name="notification_dots_desc_off" msgid="1760796511504341095">"Av"</string>
@@ -142,7 +152,8 @@
<string name="app_installing_title" msgid="5864044122733792085">"<xliff:g id="NAME">%1$s</xliff:g> installerer, <xliff:g id="PROGRESS">%2$s</xliff:g> er fullført"</string>
<string name="app_downloading_title" msgid="8336702962104482644">"Laster ned <xliff:g id="NAME">%1$s</xliff:g>, <xliff:g id="PROGRESS">%2$s</xliff:g> er fullført"</string>
<string name="app_waiting_download_title" msgid="7053938513995617849">"Venter på å installere <xliff:g id="NAME">%1$s</xliff:g>"</string>
- <string name="app_archived_title" msgid="7717956158562544081">"<xliff:g id="NAME">%1$s</xliff:g> er arkivert. Trykk for å laste ned og gjenopprette."</string>
+ <string name="app_archived_title" msgid="4548283110222420708">"<xliff:g id="NAME">%1$s</xliff:g> er arkivert."</string>
+ <string name="app_unarchiving_action" msgid="5736107006413929484">"last ned og gjenopprett"</string>
<string name="dialog_update_title" msgid="114234265740994042">"Appen må oppdateres"</string>
<string name="dialog_update_message" msgid="4176784553982226114">"Appen for dette ikonet er ikke oppdatert. Du kan oppdatere manuelt for å aktivere denne snarveien igjen, eller du kan fjerne ikonet."</string>
<string name="dialog_update" msgid="2178028071796141234">"Oppdater"</string>
@@ -187,6 +198,8 @@
<string name="work_apps_paused_edu_accept" msgid="6377476824357318532">"Greit"</string>
<string name="work_apps_pause_btn_text" msgid="4669288269140620646">"Sett jobbapper på pause"</string>
<string name="work_apps_enable_btn_text" msgid="1736198302467317371">"Gjenoppta"</string>
+ <!-- no translation found for work_scheduler_button_content_description (917340740986764967) -->
+ <skip />
<string name="developer_options_filter_hint" msgid="5896817443635989056">"Filter"</string>
<string name="remote_action_failed" msgid="1383965239183576790">"Mislyktes: <xliff:g id="WHAT">%1$s</xliff:g>"</string>
<string name="private_space_label" msgid="2359721649407947001">"Privat område"</string>
diff --git a/res/values-ne/strings.xml b/res/values-ne/strings.xml
index 4fae68b..6f93761 100644
--- a/res/values-ne/strings.xml
+++ b/res/values-ne/strings.xml
@@ -69,6 +69,12 @@
<string name="widget_category_note_taking" msgid="3469689394504266039">"नोट लेख्ने कार्य"</string>
<string name="widget_add_button_label" msgid="2761267068711937179">"हाल्नुहोस्"</string>
<string name="widget_add_button_content_description" msgid="1810530016360039643">"<xliff:g id="WIDGET_NAME">%1$s</xliff:g> विजेट हाल्नुहोस्"</string>
+ <!-- no translation found for widgets_list_expand_button_label (7912016136574932622) -->
+ <skip />
+ <!-- no translation found for widgets_list_expand_button_content_description (4600513860973450888) -->
+ <skip />
+ <!-- no translation found for widgets_list_expanded (7374857868788557730) -->
+ <skip />
<string name="reconfigurable_widget_education_tip" msgid="6336962690888067057">"विजेटका सेटिङ बदल्न ट्याप गर्नुहोस्"</string>
<string name="widget_reconfigure_button_content_description" msgid="8811472721881205250">"विजेटका सेटिङ बदल्नुहोस्"</string>
<string name="all_apps_search_bar_hint" msgid="1390553134053255246">"एपहरू खोज्नुहोस्"</string>
@@ -124,6 +130,10 @@
<string name="msg_disabled_by_admin" msgid="6898038085516271325">"तपाईँको प्रशासकद्वारा असक्षम गरिएको"</string>
<string name="allow_rotation_title" msgid="7222049633713050106">"होम स्क्रिन रोटेट हुन दिइयोस्"</string>
<string name="allow_rotation_desc" msgid="8662546029078692509">"फोन घुमाउँदा"</string>
+ <!-- no translation found for landscape_mode_title (5138814555934843926) -->
+ <skip />
+ <!-- no translation found for landscape_mode_desc (7372569859592816793) -->
+ <skip />
<string name="notification_dots_title" msgid="9062440428204120317">"नोटिफिकेसन डट"</string>
<string name="notification_dots_desc_on" msgid="1679848116452218908">"सक्रिय"</string>
<string name="notification_dots_desc_off" msgid="1760796511504341095">"निष्क्रिय"</string>
@@ -142,7 +152,8 @@
<string name="app_installing_title" msgid="5864044122733792085">"<xliff:g id="NAME">%1$s</xliff:g> इन्स्टल गरिँदै छ, <xliff:g id="PROGRESS">%2$s</xliff:g> पूरा भयो"</string>
<string name="app_downloading_title" msgid="8336702962104482644">"<xliff:g id="NAME">%1$s</xliff:g> डाउनलोड गर्दै, <xliff:g id="PROGRESS">%2$s</xliff:g> सम्पन्न"</string>
<string name="app_waiting_download_title" msgid="7053938513995617849">"<xliff:g id="NAME">%1$s</xliff:g> स्थापना गर्न प्रतीक्षा गर्दै"</string>
- <string name="app_archived_title" msgid="7717956158562544081">"<xliff:g id="NAME">%1$s</xliff:g> अभिलेखमा राखिएको छ। डाउनलोड गरी रिस्टोर गर्न ट्याप गर्नुहोस्।"</string>
+ <string name="app_archived_title" msgid="4548283110222420708">"<xliff:g id="NAME">%1$s</xliff:g> अभिलेखमा राखिएको छ।"</string>
+ <string name="app_unarchiving_action" msgid="5736107006413929484">"डाउनलोड र रिस्टोर गर्नुहोस्"</string>
<string name="dialog_update_title" msgid="114234265740994042">"एप अपडेट गरिनु पर्छ"</string>
<string name="dialog_update_message" msgid="4176784553982226114">"यो आइकनले जनाउने एप अपडेट गरिएको छैन। तपाईं यो सर्टकट फेरि अन गर्न म्यानुअल रूपमा अपडेट गर्न सक्नुहुन्छ वा आइकन नै हटाउनुहोस्।"</string>
<string name="dialog_update" msgid="2178028071796141234">"अपडेट गर्नुहोस्"</string>
@@ -187,6 +198,8 @@
<string name="work_apps_paused_edu_accept" msgid="6377476824357318532">"बुझेँ"</string>
<string name="work_apps_pause_btn_text" msgid="4669288269140620646">"कामसम्बन्धी एपहरू पज गर्नुहोस्"</string>
<string name="work_apps_enable_btn_text" msgid="1736198302467317371">"सुचारु गर्नुहोस्"</string>
+ <!-- no translation found for work_scheduler_button_content_description (917340740986764967) -->
+ <skip />
<string name="developer_options_filter_hint" msgid="5896817443635989056">"फिल्टर"</string>
<string name="remote_action_failed" msgid="1383965239183576790">"कार्य पूरा गर्न सकिएन: <xliff:g id="WHAT">%1$s</xliff:g>"</string>
<string name="private_space_label" msgid="2359721649407947001">"निजी स्पेस"</string>
diff --git a/res/values-night-v31/colors.xml b/res/values-night-v31/colors.xml
index 0f630e5..d9f9769 100644
--- a/res/values-night-v31/colors.xml
+++ b/res/values-night-v31/colors.xml
@@ -53,10 +53,5 @@
<color name="widget_picker_add_button_text_color_dark">
@android:color/system_accent1_800</color>
- <color name="work_fab_bg_color">
- @android:color/system_accent1_200</color>
- <color name="work_fab_icon_color">
- @android:color/system_accent1_900</color>
-
<color name="material_color_on_surface">@android:color/system_neutral1_100</color>
</resources>
\ No newline at end of file
diff --git a/res/values-nl/strings.xml b/res/values-nl/strings.xml
index 35f8d65..a38971f 100644
--- a/res/values-nl/strings.xml
+++ b/res/values-nl/strings.xml
@@ -69,6 +69,12 @@
<string name="widget_category_note_taking" msgid="3469689394504266039">"Aantekeningen maken"</string>
<string name="widget_add_button_label" msgid="2761267068711937179">"Toevoegen"</string>
<string name="widget_add_button_content_description" msgid="1810530016360039643">"Widget <xliff:g id="WIDGET_NAME">%1$s</xliff:g> toevoegen"</string>
+ <!-- no translation found for widgets_list_expand_button_label (7912016136574932622) -->
+ <skip />
+ <!-- no translation found for widgets_list_expand_button_content_description (4600513860973450888) -->
+ <skip />
+ <!-- no translation found for widgets_list_expanded (7374857868788557730) -->
+ <skip />
<string name="reconfigurable_widget_education_tip" msgid="6336962690888067057">"Tik om de widgetinstellingen te wijzigen"</string>
<string name="widget_reconfigure_button_content_description" msgid="8811472721881205250">"Widgetinstellingen wijzigen"</string>
<string name="all_apps_search_bar_hint" msgid="1390553134053255246">"Apps zoeken"</string>
@@ -124,6 +130,10 @@
<string name="msg_disabled_by_admin" msgid="6898038085516271325">"Uitgezet door je beheerder"</string>
<string name="allow_rotation_title" msgid="7222049633713050106">"Draaien van startscherm toestaan"</string>
<string name="allow_rotation_desc" msgid="8662546029078692509">"Als de telefoon gedraaid is"</string>
+ <!-- no translation found for landscape_mode_title (5138814555934843926) -->
+ <skip />
+ <!-- no translation found for landscape_mode_desc (7372569859592816793) -->
+ <skip />
<string name="notification_dots_title" msgid="9062440428204120317">"Meldingsstipjes"</string>
<string name="notification_dots_desc_on" msgid="1679848116452218908">"Aan"</string>
<string name="notification_dots_desc_off" msgid="1760796511504341095">"Uit"</string>
@@ -142,7 +152,8 @@
<string name="app_installing_title" msgid="5864044122733792085">"<xliff:g id="NAME">%1$s</xliff:g> installeren, <xliff:g id="PROGRESS">%2$s</xliff:g> voltooid"</string>
<string name="app_downloading_title" msgid="8336702962104482644">"<xliff:g id="NAME">%1$s</xliff:g> wordt gedownload, <xliff:g id="PROGRESS">%2$s</xliff:g> voltooid"</string>
<string name="app_waiting_download_title" msgid="7053938513995617849">"<xliff:g id="NAME">%1$s</xliff:g> wacht op installatie"</string>
- <string name="app_archived_title" msgid="7717956158562544081">"<xliff:g id="NAME">%1$s</xliff:g> is gearchiveerd. Tik om te downloaden en te herstellen."</string>
+ <string name="app_archived_title" msgid="4548283110222420708">"<xliff:g id="NAME">%1$s</xliff:g> is gearchiveerd."</string>
+ <string name="app_unarchiving_action" msgid="5736107006413929484">"downloaden en herstellen"</string>
<string name="dialog_update_title" msgid="114234265740994042">"App-update vereist"</string>
<string name="dialog_update_message" msgid="4176784553982226114">"De app voor dit icoon is niet geüpdatet. Je kunt handmatig updaten om deze snelkoppeling weer aan te zetten of het icoon verwijderen."</string>
<string name="dialog_update" msgid="2178028071796141234">"Updaten"</string>
@@ -187,6 +198,8 @@
<string name="work_apps_paused_edu_accept" msgid="6377476824357318532">"OK"</string>
<string name="work_apps_pause_btn_text" msgid="4669288269140620646">"Werk-apps pauzeren"</string>
<string name="work_apps_enable_btn_text" msgid="1736198302467317371">"Hervatten"</string>
+ <!-- no translation found for work_scheduler_button_content_description (917340740986764967) -->
+ <skip />
<string name="developer_options_filter_hint" msgid="5896817443635989056">"Filteren"</string>
<string name="remote_action_failed" msgid="1383965239183576790">"Mislukt: <xliff:g id="WHAT">%1$s</xliff:g>"</string>
<string name="private_space_label" msgid="2359721649407947001">"Privéruimte"</string>
diff --git a/res/values-or/strings.xml b/res/values-or/strings.xml
index abc0787..a20e0fc 100644
--- a/res/values-or/strings.xml
+++ b/res/values-or/strings.xml
@@ -69,6 +69,12 @@
<string name="widget_category_note_taking" msgid="3469689394504266039">"ନୋଟ-ଟେକିଂ"</string>
<string name="widget_add_button_label" msgid="2761267068711937179">"ଯୋଗ କରନ୍ତୁ"</string>
<string name="widget_add_button_content_description" msgid="1810530016360039643">"<xliff:g id="WIDGET_NAME">%1$s</xliff:g> ୱିଜେଟ ଯୋଗ କରନ୍ତୁ"</string>
+ <!-- no translation found for widgets_list_expand_button_label (7912016136574932622) -->
+ <skip />
+ <!-- no translation found for widgets_list_expand_button_content_description (4600513860973450888) -->
+ <skip />
+ <!-- no translation found for widgets_list_expanded (7374857868788557730) -->
+ <skip />
<string name="reconfigurable_widget_education_tip" msgid="6336962690888067057">"ୱିଜେଟ ସେଟିଂସ ପରିବର୍ତ୍ତନ କରିବାକୁ ଟାପ କରନ୍ତୁ"</string>
<string name="widget_reconfigure_button_content_description" msgid="8811472721881205250">"ୱିଜେଟ ସେଟିଂସ ପରିବର୍ତ୍ତନ କରନ୍ତୁ"</string>
<string name="all_apps_search_bar_hint" msgid="1390553134053255246">"ଆପ ସର୍ଚ୍ଚ କରନ୍ତୁ"</string>
@@ -124,6 +130,10 @@
<string name="msg_disabled_by_admin" msgid="6898038085516271325">"ଆପଣଙ୍କ ଆଡମିନଙ୍କ ଦ୍ୱାରା ଅକ୍ଷମ କରାଯାଇଛି"</string>
<string name="allow_rotation_title" msgid="7222049633713050106">"ହୋମ ସ୍କ୍ରିନ ରୋଟେସନକୁ ଅନୁମତି ଦିଅନ୍ତୁ"</string>
<string name="allow_rotation_desc" msgid="8662546029078692509">"ଯେତେବେଳେ ଫୋନକୁ ରୋଟେଟ କରାଯାଇଥାଏ"</string>
+ <!-- no translation found for landscape_mode_title (5138814555934843926) -->
+ <skip />
+ <!-- no translation found for landscape_mode_desc (7372569859592816793) -->
+ <skip />
<string name="notification_dots_title" msgid="9062440428204120317">"ବିଜ୍ଞପ୍ତି ଡଟ୍ସ"</string>
<string name="notification_dots_desc_on" msgid="1679848116452218908">"ଚାଲୁ"</string>
<string name="notification_dots_desc_off" msgid="1760796511504341095">"ବନ୍ଦ କରନ୍ତୁ"</string>
@@ -142,7 +152,8 @@
<string name="app_installing_title" msgid="5864044122733792085">"<xliff:g id="NAME">%1$s</xliff:g> ଇନଷ୍ଟଲ୍ କରାଯାଉଛି, <xliff:g id="PROGRESS">%2$s</xliff:g> ସମ୍ପୂର୍ଣ୍ଣ ହୋଇଛି"</string>
<string name="app_downloading_title" msgid="8336702962104482644">"<xliff:g id="NAME">%1$s</xliff:g> ଡାଉନଲୋଡ୍ ହେଉଛି, <xliff:g id="PROGRESS">%2$s</xliff:g> ସମ୍ପୂର୍ଣ୍ଣ"</string>
<string name="app_waiting_download_title" msgid="7053938513995617849">"<xliff:g id="NAME">%1$s</xliff:g> ଇନଷ୍ଟଲ୍ ହେବାକୁ ଅପେକ୍ଷା କରିଛି"</string>
- <string name="app_archived_title" msgid="7717956158562544081">"<xliff:g id="NAME">%1$s</xliff:g>କୁ ଆର୍କାଇଭ କରାଯାଇଛି। ଡାଉନଲୋଡ ଏବଂ ରିଷ୍ଟୋର କରିବା ପାଇଁ ଟାପ କରନ୍ତୁ।"</string>
+ <string name="app_archived_title" msgid="4548283110222420708">"<xliff:g id="NAME">%1$s</xliff:g>କୁ ଆର୍କାଇଭ କରାଯାଇଛି।"</string>
+ <string name="app_unarchiving_action" msgid="5736107006413929484">"ଡାଉନଲୋଡ ଏବଂ ରିଷ୍ଟୋର କରନ୍ତୁ"</string>
<string name="dialog_update_title" msgid="114234265740994042">"ଆପକୁ ଅପଡେଟ କରିବା ଆବଶ୍ୟକ"</string>
<string name="dialog_update_message" msgid="4176784553982226114">"ଏହି ଆଇକନ ପାଇଁ ଆପକୁ ଅପଡେଟ କରାଯାଇନାହିଁ। ଏହି ସର୍ଟକଟକୁ ପୁଣି-ସକ୍ଷମ କରିବା ପାଇଁ ଆପଣ ମାନୁଆଲୀ ଅପଡେଟ କରିପାରିବେ କିମ୍ବା ଆଇକନଟିକୁ କାଢ଼ି ଦେଇପାରିବେ।"</string>
<string name="dialog_update" msgid="2178028071796141234">"ଅପଡେଟ କରନ୍ତୁ"</string>
@@ -187,6 +198,8 @@
<string name="work_apps_paused_edu_accept" msgid="6377476824357318532">"ବୁଝିଗଲି"</string>
<string name="work_apps_pause_btn_text" msgid="4669288269140620646">"ୱାର୍କ ଆପ୍ସ ବିରତ କରନ୍ତୁ"</string>
<string name="work_apps_enable_btn_text" msgid="1736198302467317371">"ପୁଣି ଚାଲୁ କରନ୍ତୁ"</string>
+ <!-- no translation found for work_scheduler_button_content_description (917340740986764967) -->
+ <skip />
<string name="developer_options_filter_hint" msgid="5896817443635989056">"ଫିଲ୍ଟର୍"</string>
<string name="remote_action_failed" msgid="1383965239183576790">"ବିଫଳ ହୋଇଛି: <xliff:g id="WHAT">%1$s</xliff:g>"</string>
<string name="private_space_label" msgid="2359721649407947001">"ପ୍ରାଇଭେଟ ସ୍ପେସ"</string>
diff --git a/res/values-pa/strings.xml b/res/values-pa/strings.xml
index 715f61b..65187bf 100644
--- a/res/values-pa/strings.xml
+++ b/res/values-pa/strings.xml
@@ -69,6 +69,12 @@
<string name="widget_category_note_taking" msgid="3469689394504266039">"ਨੋਟ ਬਣਾਉਣਾ"</string>
<string name="widget_add_button_label" msgid="2761267068711937179">"ਸ਼ਾਮਲ ਕਰੋ"</string>
<string name="widget_add_button_content_description" msgid="1810530016360039643">"<xliff:g id="WIDGET_NAME">%1$s</xliff:g> ਵਿਜੇਟ ਸ਼ਾਮਲ ਕਰੋ"</string>
+ <!-- no translation found for widgets_list_expand_button_label (7912016136574932622) -->
+ <skip />
+ <!-- no translation found for widgets_list_expand_button_content_description (4600513860973450888) -->
+ <skip />
+ <!-- no translation found for widgets_list_expanded (7374857868788557730) -->
+ <skip />
<string name="reconfigurable_widget_education_tip" msgid="6336962690888067057">"ਵਿਜੇਟ ਸੈਟਿੰਗਾਂ ਨੂੰ ਬਦਲਣ ਲਈ ਟੈਪ ਕਰੋ"</string>
<string name="widget_reconfigure_button_content_description" msgid="8811472721881205250">"ਵਿਜੇਟ ਸੈਟਿੰਗਾਂ ਬਦਲੋ"</string>
<string name="all_apps_search_bar_hint" msgid="1390553134053255246">"ਐਪਾਂ ਖੋਜੋ"</string>
@@ -124,6 +130,10 @@
<string name="msg_disabled_by_admin" msgid="6898038085516271325">"ਤੁਹਾਡੇ ਪ੍ਰਸ਼ਾਸਕ ਦੁਆਰਾ ਅਯੋਗ ਬਣਾਈ ਗਈ"</string>
<string name="allow_rotation_title" msgid="7222049633713050106">"ਹੋਮ ਸਕ੍ਰੀਨ ਨੂੰ ਘੁਮਾਉਣ ਦੀ ਆਗਿਆ ਦਿਓ"</string>
<string name="allow_rotation_desc" msgid="8662546029078692509">"ਜਦੋਂ ਫ਼ੋਨ ਘੁਮਾਇਆ ਜਾਂਦਾ ਹੈ"</string>
+ <!-- no translation found for landscape_mode_title (5138814555934843926) -->
+ <skip />
+ <!-- no translation found for landscape_mode_desc (7372569859592816793) -->
+ <skip />
<string name="notification_dots_title" msgid="9062440428204120317">"ਸੂਚਨਾ ਬਿੰਦੂ"</string>
<string name="notification_dots_desc_on" msgid="1679848116452218908">"ਚਾਲੂ"</string>
<string name="notification_dots_desc_off" msgid="1760796511504341095">"ਬੰਦ"</string>
@@ -142,7 +152,8 @@
<string name="app_installing_title" msgid="5864044122733792085">"<xliff:g id="NAME">%1$s</xliff:g> ਨੂੰ ਸਥਾਪਤ ਕੀਤਾ ਜਾ ਰਿਹਾ ਹੈ, <xliff:g id="PROGRESS">%2$s</xliff:g> ਪੂਰਾ ਹੋਇਆ"</string>
<string name="app_downloading_title" msgid="8336702962104482644">"<xliff:g id="NAME">%1$s</xliff:g> ਡਾਉਨਲੋਡ ਹੋਰ ਰਿਹਾ ਹੈ, <xliff:g id="PROGRESS">%2$s</xliff:g> ਸੰਪੂਰਣ"</string>
<string name="app_waiting_download_title" msgid="7053938513995617849">"<xliff:g id="NAME">%1$s</xliff:g> ਸਥਾਪਤ ਕਰਨ ਦੀ ਉਡੀਕ ਕਰ ਰਿਹਾ ਹੈ"</string>
- <string name="app_archived_title" msgid="7717956158562544081">"<xliff:g id="NAME">%1$s</xliff:g> ਪੁਰਾਲੇਖਬੱਧ ਹੈ। ਡਾਊਨਲੋਡ ਅਤੇ ਮੁੜ-ਬਹਾਲ ਕਰਨ ਲਈ ਟੈਪ ਕਰੋ।"</string>
+ <string name="app_archived_title" msgid="4548283110222420708">"<xliff:g id="NAME">%1$s</xliff:g> ਪੁਰਾਲੇਖਬੱਧ ਹੈ।"</string>
+ <string name="app_unarchiving_action" msgid="5736107006413929484">"ਡਾਊਨਲੋਡ ਕਰ ਕੇ ਮੁੜ-ਬਹਾਲ ਕਰੋ"</string>
<string name="dialog_update_title" msgid="114234265740994042">"ਐਪ ਨੂੰ ਅੱਪਡੇਟ ਕਰਨ ਦੀ ਲੋੜ ਹੈ"</string>
<string name="dialog_update_message" msgid="4176784553982226114">"ਇਸ ਪ੍ਰਤੀਕ ਲਈ ਐਪ ਨੂੰ ਅੱਪਡੇਟ ਨਹੀਂ ਕੀਤਾ ਗਿਆ ਹੈ। ਇਸ ਸ਼ਾਰਟਕੱਟ ਨੂੰ ਮੁੜ-ਚਾਲੂ ਕਰਨ ਜਾਂ ਪ੍ਰਤੀਕ ਨੂੰ ਹਟਾਉਣ ਲਈ ਤੁਸੀਂ ਹੱਥੀਂ ਅੱਪਡੇਟ ਕਰ ਸਕਦੇ ਹੋ।"</string>
<string name="dialog_update" msgid="2178028071796141234">"ਅੱਪਡੇਟ ਕਰੋ"</string>
@@ -187,6 +198,8 @@
<string name="work_apps_paused_edu_accept" msgid="6377476824357318532">"ਸਮਝ ਲਿਆ"</string>
<string name="work_apps_pause_btn_text" msgid="4669288269140620646">"ਕੰਮ ਸੰਬੰਧੀ ਐਪਾਂ ਰੋਕੋ"</string>
<string name="work_apps_enable_btn_text" msgid="1736198302467317371">"ਰੋਕ ਹਟਾਓ"</string>
+ <!-- no translation found for work_scheduler_button_content_description (917340740986764967) -->
+ <skip />
<string name="developer_options_filter_hint" msgid="5896817443635989056">"ਫਿਲਟਰ"</string>
<string name="remote_action_failed" msgid="1383965239183576790">"ਇਹ ਕਾਰਵਾਈ ਅਸਫਲ ਹੋਈ: <xliff:g id="WHAT">%1$s</xliff:g>"</string>
<string name="private_space_label" msgid="2359721649407947001">"ਪ੍ਰਾਈਵੇਟ ਸਪੇਸ"</string>
diff --git a/res/values-pl/strings.xml b/res/values-pl/strings.xml
index 47f8a51..861be1e 100644
--- a/res/values-pl/strings.xml
+++ b/res/values-pl/strings.xml
@@ -69,6 +69,12 @@
<string name="widget_category_note_taking" msgid="3469689394504266039">"Notatki"</string>
<string name="widget_add_button_label" msgid="2761267068711937179">"Dodaj"</string>
<string name="widget_add_button_content_description" msgid="1810530016360039643">"Dodaj widżet <xliff:g id="WIDGET_NAME">%1$s</xliff:g>"</string>
+ <!-- no translation found for widgets_list_expand_button_label (7912016136574932622) -->
+ <skip />
+ <!-- no translation found for widgets_list_expand_button_content_description (4600513860973450888) -->
+ <skip />
+ <!-- no translation found for widgets_list_expanded (7374857868788557730) -->
+ <skip />
<string name="reconfigurable_widget_education_tip" msgid="6336962690888067057">"Kliknij, aby zmienić ustawienia widżetu"</string>
<string name="widget_reconfigure_button_content_description" msgid="8811472721881205250">"Zmień ustawienia widżetu"</string>
<string name="all_apps_search_bar_hint" msgid="1390553134053255246">"Wyszukaj aplikacje"</string>
@@ -124,6 +130,10 @@
<string name="msg_disabled_by_admin" msgid="6898038085516271325">"Funkcja wyłączona przez administratora"</string>
<string name="allow_rotation_title" msgid="7222049633713050106">"Zezwalaj na obrót ekranu głównego"</string>
<string name="allow_rotation_desc" msgid="8662546029078692509">"Po obróceniu telefonu"</string>
+ <!-- no translation found for landscape_mode_title (5138814555934843926) -->
+ <skip />
+ <!-- no translation found for landscape_mode_desc (7372569859592816793) -->
+ <skip />
<string name="notification_dots_title" msgid="9062440428204120317">"Kropki powiadomień"</string>
<string name="notification_dots_desc_on" msgid="1679848116452218908">"Włączone"</string>
<string name="notification_dots_desc_off" msgid="1760796511504341095">"Wyłączone"</string>
@@ -142,7 +152,8 @@
<string name="app_installing_title" msgid="5864044122733792085">"Instaluję aplikację <xliff:g id="NAME">%1$s</xliff:g>, postęp: <xliff:g id="PROGRESS">%2$s</xliff:g>"</string>
<string name="app_downloading_title" msgid="8336702962104482644">"Pobieranie elementu <xliff:g id="NAME">%1$s</xliff:g>, ukończono: <xliff:g id="PROGRESS">%2$s</xliff:g>"</string>
<string name="app_waiting_download_title" msgid="7053938513995617849">"<xliff:g id="NAME">%1$s</xliff:g> oczekuje na instalację"</string>
- <string name="app_archived_title" msgid="7717956158562544081">"Aplikacja <xliff:g id="NAME">%1$s</xliff:g> jest zarchiwizowana. Kliknij, aby ją pobrać i przywrócić."</string>
+ <string name="app_archived_title" msgid="4548283110222420708">"Aplikacja <xliff:g id="NAME">%1$s</xliff:g> jest zarchiwizowana."</string>
+ <string name="app_unarchiving_action" msgid="5736107006413929484">"pobierz i przywróć"</string>
<string name="dialog_update_title" msgid="114234265740994042">"Wymagana aktualizacja aplikacji"</string>
<string name="dialog_update_message" msgid="4176784553982226114">"Aplikacja z tą ikoną nie jest aktualizowana. Możesz zaktualizować ją ręcznie, aby ponownie uruchomić ten skrót, lub usunąć ikonę."</string>
<string name="dialog_update" msgid="2178028071796141234">"Aktualizuj"</string>
@@ -187,6 +198,8 @@
<string name="work_apps_paused_edu_accept" msgid="6377476824357318532">"OK"</string>
<string name="work_apps_pause_btn_text" msgid="4669288269140620646">"Wstrzymaj aplikacje służbowe"</string>
<string name="work_apps_enable_btn_text" msgid="1736198302467317371">"Cofnij wstrzymywanie"</string>
+ <!-- no translation found for work_scheduler_button_content_description (917340740986764967) -->
+ <skip />
<string name="developer_options_filter_hint" msgid="5896817443635989056">"Filtruj"</string>
<string name="remote_action_failed" msgid="1383965239183576790">"Niepowodzenie: <xliff:g id="WHAT">%1$s</xliff:g>"</string>
<string name="private_space_label" msgid="2359721649407947001">"Przestrzeń prywatna"</string>
diff --git a/res/values-pt-rPT/strings.xml b/res/values-pt-rPT/strings.xml
index d2b214e..04bff1f 100644
--- a/res/values-pt-rPT/strings.xml
+++ b/res/values-pt-rPT/strings.xml
@@ -69,6 +69,12 @@
<string name="widget_category_note_taking" msgid="3469689394504266039">"Tomar notas"</string>
<string name="widget_add_button_label" msgid="2761267068711937179">"Adicionar"</string>
<string name="widget_add_button_content_description" msgid="1810530016360039643">"Adicione o widget <xliff:g id="WIDGET_NAME">%1$s</xliff:g>"</string>
+ <!-- no translation found for widgets_list_expand_button_label (7912016136574932622) -->
+ <skip />
+ <!-- no translation found for widgets_list_expand_button_content_description (4600513860973450888) -->
+ <skip />
+ <!-- no translation found for widgets_list_expanded (7374857868788557730) -->
+ <skip />
<string name="reconfigurable_widget_education_tip" msgid="6336962690888067057">"Toque para alterar as definições do widget"</string>
<string name="widget_reconfigure_button_content_description" msgid="8811472721881205250">"Alterar definições do widget"</string>
<string name="all_apps_search_bar_hint" msgid="1390553134053255246">"Pesquisar apps"</string>
@@ -124,6 +130,10 @@
<string name="msg_disabled_by_admin" msgid="6898038085516271325">"Desativada pelo gestor"</string>
<string name="allow_rotation_title" msgid="7222049633713050106">"Permitir rotação do ecrã principal"</string>
<string name="allow_rotation_desc" msgid="8662546029078692509">"Quando o telemóvel é rodado"</string>
+ <!-- no translation found for landscape_mode_title (5138814555934843926) -->
+ <skip />
+ <!-- no translation found for landscape_mode_desc (7372569859592816793) -->
+ <skip />
<string name="notification_dots_title" msgid="9062440428204120317">"Pontos de notificação"</string>
<string name="notification_dots_desc_on" msgid="1679848116452218908">"Ativados"</string>
<string name="notification_dots_desc_off" msgid="1760796511504341095">"Desativados"</string>
@@ -142,7 +152,8 @@
<string name="app_installing_title" msgid="5864044122733792085">"A instalar <xliff:g id="NAME">%1$s</xliff:g>, <xliff:g id="PROGRESS">%2$s</xliff:g> concluído"</string>
<string name="app_downloading_title" msgid="8336702962104482644">"A transferir o <xliff:g id="NAME">%1$s</xliff:g>, <xliff:g id="PROGRESS">%2$s</xliff:g> concluído"</string>
<string name="app_waiting_download_title" msgid="7053938513995617849">"A aguardar a instalação do <xliff:g id="NAME">%1$s</xliff:g>"</string>
- <string name="app_archived_title" msgid="7717956158562544081">"A app <xliff:g id="NAME">%1$s</xliff:g> está arquivada. Toque para transferir e restaurar."</string>
+ <string name="app_archived_title" msgid="4548283110222420708">"A app <xliff:g id="NAME">%1$s</xliff:g> está arquivada."</string>
+ <string name="app_unarchiving_action" msgid="5736107006413929484">"transferir e restaurar"</string>
<string name="dialog_update_title" msgid="114234265740994042">"Atualização da app necessária"</string>
<string name="dialog_update_message" msgid="4176784553982226114">"A app deste ícone não está atualizada. Pode atualizar manualmente para reativar este atalho ou remover o ícone."</string>
<string name="dialog_update" msgid="2178028071796141234">"Atualizar"</string>
@@ -187,6 +198,8 @@
<string name="work_apps_paused_edu_accept" msgid="6377476824357318532">"OK"</string>
<string name="work_apps_pause_btn_text" msgid="4669288269140620646">"Pausar apps de trabalho"</string>
<string name="work_apps_enable_btn_text" msgid="1736198302467317371">"Retomar"</string>
+ <!-- no translation found for work_scheduler_button_content_description (917340740986764967) -->
+ <skip />
<string name="developer_options_filter_hint" msgid="5896817443635989056">"Filtrar"</string>
<string name="remote_action_failed" msgid="1383965239183576790">"Falhou: <xliff:g id="WHAT">%1$s</xliff:g>"</string>
<string name="private_space_label" msgid="2359721649407947001">"Espaço privado"</string>
diff --git a/res/values-pt/strings.xml b/res/values-pt/strings.xml
index f864b3e..20cc9fb 100644
--- a/res/values-pt/strings.xml
+++ b/res/values-pt/strings.xml
@@ -69,6 +69,12 @@
<string name="widget_category_note_taking" msgid="3469689394504266039">"Anotações"</string>
<string name="widget_add_button_label" msgid="2761267068711937179">"Adicionar"</string>
<string name="widget_add_button_content_description" msgid="1810530016360039643">"Adicionar o widget <xliff:g id="WIDGET_NAME">%1$s</xliff:g>"</string>
+ <!-- no translation found for widgets_list_expand_button_label (7912016136574932622) -->
+ <skip />
+ <!-- no translation found for widgets_list_expand_button_content_description (4600513860973450888) -->
+ <skip />
+ <!-- no translation found for widgets_list_expanded (7374857868788557730) -->
+ <skip />
<string name="reconfigurable_widget_education_tip" msgid="6336962690888067057">"Toque para mudar as configurações do widget"</string>
<string name="widget_reconfigure_button_content_description" msgid="8811472721881205250">"Mudar as configurações do widget"</string>
<string name="all_apps_search_bar_hint" msgid="1390553134053255246">"Pesquisar apps"</string>
@@ -124,6 +130,10 @@
<string name="msg_disabled_by_admin" msgid="6898038085516271325">"Desativado pelo administrador"</string>
<string name="allow_rotation_title" msgid="7222049633713050106">"Permitir a rotação da tela inicial"</string>
<string name="allow_rotation_desc" msgid="8662546029078692509">"Quando o smartphone for girado"</string>
+ <!-- no translation found for landscape_mode_title (5138814555934843926) -->
+ <skip />
+ <!-- no translation found for landscape_mode_desc (7372569859592816793) -->
+ <skip />
<string name="notification_dots_title" msgid="9062440428204120317">"Pontos de notificação"</string>
<string name="notification_dots_desc_on" msgid="1679848116452218908">"Ativados"</string>
<string name="notification_dots_desc_off" msgid="1760796511504341095">"Desativado"</string>
@@ -142,7 +152,8 @@
<string name="app_installing_title" msgid="5864044122733792085">"Instalando <xliff:g id="NAME">%1$s</xliff:g>. <xliff:g id="PROGRESS">%2$s</xliff:g> concluído"</string>
<string name="app_downloading_title" msgid="8336702962104482644">"Fazendo download de <xliff:g id="NAME">%1$s</xliff:g>, <xliff:g id="PROGRESS">%2$s</xliff:g> concluído"</string>
<string name="app_waiting_download_title" msgid="7053938513995617849">"Aguardando instalação de <xliff:g id="NAME">%1$s</xliff:g>"</string>
- <string name="app_archived_title" msgid="7717956158562544081">"O app <xliff:g id="NAME">%1$s</xliff:g> está arquivado. Toque para baixar e restaurar."</string>
+ <string name="app_archived_title" msgid="4548283110222420708">"O app <xliff:g id="NAME">%1$s</xliff:g> está arquivado."</string>
+ <string name="app_unarchiving_action" msgid="5736107006413929484">"baixar e restaurar"</string>
<string name="dialog_update_title" msgid="114234265740994042">"Atualização obrigatória do app"</string>
<string name="dialog_update_message" msgid="4176784553982226114">"O app desse ícone não está atualizado. Você pode remover o ícone ou atualizar o app manualmente para reativar esse atalho."</string>
<string name="dialog_update" msgid="2178028071796141234">"Atualizar"</string>
@@ -187,6 +198,8 @@
<string name="work_apps_paused_edu_accept" msgid="6377476824357318532">"Ok"</string>
<string name="work_apps_pause_btn_text" msgid="4669288269140620646">"Pausar apps de trabalho"</string>
<string name="work_apps_enable_btn_text" msgid="1736198302467317371">"Ativar"</string>
+ <!-- no translation found for work_scheduler_button_content_description (917340740986764967) -->
+ <skip />
<string name="developer_options_filter_hint" msgid="5896817443635989056">"Filtrar"</string>
<string name="remote_action_failed" msgid="1383965239183576790">"Falha: <xliff:g id="WHAT">%1$s</xliff:g>"</string>
<string name="private_space_label" msgid="2359721649407947001">"Espaço privado"</string>
diff --git a/res/values-ro/strings.xml b/res/values-ro/strings.xml
index 30e33dc..4226920 100644
--- a/res/values-ro/strings.xml
+++ b/res/values-ro/strings.xml
@@ -69,6 +69,12 @@
<string name="widget_category_note_taking" msgid="3469689394504266039">"Luare de notițe"</string>
<string name="widget_add_button_label" msgid="2761267068711937179">"Adaugă"</string>
<string name="widget_add_button_content_description" msgid="1810530016360039643">"Adaugă widgetul <xliff:g id="WIDGET_NAME">%1$s</xliff:g>"</string>
+ <!-- no translation found for widgets_list_expand_button_label (7912016136574932622) -->
+ <skip />
+ <!-- no translation found for widgets_list_expand_button_content_description (4600513860973450888) -->
+ <skip />
+ <!-- no translation found for widgets_list_expanded (7374857868788557730) -->
+ <skip />
<string name="reconfigurable_widget_education_tip" msgid="6336962690888067057">"Atinge ca să schimbi setările pentru widgeturi"</string>
<string name="widget_reconfigure_button_content_description" msgid="8811472721881205250">"Modifică setările pentru widgeturi"</string>
<string name="all_apps_search_bar_hint" msgid="1390553134053255246">"Caută aplicații"</string>
@@ -124,6 +130,10 @@
<string name="msg_disabled_by_admin" msgid="6898038085516271325">"Dezactivată de administrator"</string>
<string name="allow_rotation_title" msgid="7222049633713050106">"Permite rotirea ecranului de pornire"</string>
<string name="allow_rotation_desc" msgid="8662546029078692509">"Când telefonul este rotit"</string>
+ <!-- no translation found for landscape_mode_title (5138814555934843926) -->
+ <skip />
+ <!-- no translation found for landscape_mode_desc (7372569859592816793) -->
+ <skip />
<string name="notification_dots_title" msgid="9062440428204120317">"Puncte de notificare"</string>
<string name="notification_dots_desc_on" msgid="1679848116452218908">"Activate"</string>
<string name="notification_dots_desc_off" msgid="1760796511504341095">"Dezactivate"</string>
@@ -142,7 +152,8 @@
<string name="app_installing_title" msgid="5864044122733792085">"<xliff:g id="NAME">%1$s</xliff:g> se instalează, <xliff:g id="PROGRESS">%2$s</xliff:g> finalizat"</string>
<string name="app_downloading_title" msgid="8336702962104482644">"<xliff:g id="NAME">%1$s</xliff:g> se descarcă (finalizat <xliff:g id="PROGRESS">%2$s</xliff:g>)"</string>
<string name="app_waiting_download_title" msgid="7053938513995617849">"<xliff:g id="NAME">%1$s</xliff:g> așteaptă instalarea"</string>
- <string name="app_archived_title" msgid="7717956158562544081">"<xliff:g id="NAME">%1$s</xliff:g> s-a arhivat. Atinge pentru a descărca și restabili."</string>
+ <string name="app_archived_title" msgid="4548283110222420708">"<xliff:g id="NAME">%1$s</xliff:g> s-a arhivat."</string>
+ <string name="app_unarchiving_action" msgid="5736107006413929484">"descarcă și restabilește"</string>
<string name="dialog_update_title" msgid="114234265740994042">"Este necesară actualizarea aplicației"</string>
<string name="dialog_update_message" msgid="4176784553982226114">"Aplicația pentru această pictogramă nu este actualizată. Poți să actualizezi manual ca să reactivezi comanda rapidă sau să elimini pictograma."</string>
<string name="dialog_update" msgid="2178028071796141234">"Actualizează"</string>
@@ -187,6 +198,8 @@
<string name="work_apps_paused_edu_accept" msgid="6377476824357318532">"OK"</string>
<string name="work_apps_pause_btn_text" msgid="4669288269140620646">"Întrerupe aplicațiile pentru lucru"</string>
<string name="work_apps_enable_btn_text" msgid="1736198302467317371">"Anulează întreruperea"</string>
+ <!-- no translation found for work_scheduler_button_content_description (917340740986764967) -->
+ <skip />
<string name="developer_options_filter_hint" msgid="5896817443635989056">"Filtru"</string>
<string name="remote_action_failed" msgid="1383965239183576790">"Eșuare: <xliff:g id="WHAT">%1$s</xliff:g>"</string>
<string name="private_space_label" msgid="2359721649407947001">"Spațiu privat"</string>
diff --git a/res/values-ru/strings.xml b/res/values-ru/strings.xml
index 126e3ad..2b827ef 100644
--- a/res/values-ru/strings.xml
+++ b/res/values-ru/strings.xml
@@ -69,6 +69,12 @@
<string name="widget_category_note_taking" msgid="3469689394504266039">"Создание заметок"</string>
<string name="widget_add_button_label" msgid="2761267068711937179">"Добавить"</string>
<string name="widget_add_button_content_description" msgid="1810530016360039643">"Добавить виджет \"<xliff:g id="WIDGET_NAME">%1$s</xliff:g>\""</string>
+ <!-- no translation found for widgets_list_expand_button_label (7912016136574932622) -->
+ <skip />
+ <!-- no translation found for widgets_list_expand_button_content_description (4600513860973450888) -->
+ <skip />
+ <!-- no translation found for widgets_list_expanded (7374857868788557730) -->
+ <skip />
<string name="reconfigurable_widget_education_tip" msgid="6336962690888067057">"Нажмите, чтобы изменить настройки виджета"</string>
<string name="widget_reconfigure_button_content_description" msgid="8811472721881205250">"Изменить настройки виджета"</string>
<string name="all_apps_search_bar_hint" msgid="1390553134053255246">"Поиск приложений"</string>
@@ -124,6 +130,10 @@
<string name="msg_disabled_by_admin" msgid="6898038085516271325">"Функция отключена администратором"</string>
<string name="allow_rotation_title" msgid="7222049633713050106">"Разрешить поворачивать главный экран"</string>
<string name="allow_rotation_desc" msgid="8662546029078692509">"При повороте телефона"</string>
+ <!-- no translation found for landscape_mode_title (5138814555934843926) -->
+ <skip />
+ <!-- no translation found for landscape_mode_desc (7372569859592816793) -->
+ <skip />
<string name="notification_dots_title" msgid="9062440428204120317">"Значки уведомлений"</string>
<string name="notification_dots_desc_on" msgid="1679848116452218908">"Включены"</string>
<string name="notification_dots_desc_off" msgid="1760796511504341095">"Отключены"</string>
@@ -142,7 +152,8 @@
<string name="app_installing_title" msgid="5864044122733792085">"Установка приложения \"<xliff:g id="NAME">%1$s</xliff:g>\" (выполнено <xliff:g id="PROGRESS">%2$s</xliff:g>)"</string>
<string name="app_downloading_title" msgid="8336702962104482644">"Скачивается \"<xliff:g id="NAME">%1$s</xliff:g>\" (<xliff:g id="PROGRESS">%2$s</xliff:g>)"</string>
<string name="app_waiting_download_title" msgid="7053938513995617849">"Ожидание установки \"<xliff:g id="NAME">%1$s</xliff:g>\""</string>
- <string name="app_archived_title" msgid="7717956158562544081">"Приложение \"<xliff:g id="NAME">%1$s</xliff:g>\" находится в архиве. Нажмите, чтобы скачать его и восстановить"</string>
+ <string name="app_archived_title" msgid="4548283110222420708">"Приложение \"<xliff:g id="NAME">%1$s</xliff:g>\" находится в архиве."</string>
+ <string name="app_unarchiving_action" msgid="5736107006413929484">"скачать и восстановить"</string>
<string name="dialog_update_title" msgid="114234265740994042">"Обновите приложение"</string>
<string name="dialog_update_message" msgid="4176784553982226114">"Эта версия приложения устарела. Обновите его вручную, чтобы снова пользоваться ярлыком, или удалите значок."</string>
<string name="dialog_update" msgid="2178028071796141234">"Обновить"</string>
@@ -187,6 +198,8 @@
<string name="work_apps_paused_edu_accept" msgid="6377476824357318532">"ОК"</string>
<string name="work_apps_pause_btn_text" msgid="4669288269140620646">"Приостановить рабочие приложения"</string>
<string name="work_apps_enable_btn_text" msgid="1736198302467317371">"Возобновить"</string>
+ <!-- no translation found for work_scheduler_button_content_description (917340740986764967) -->
+ <skip />
<string name="developer_options_filter_hint" msgid="5896817443635989056">"Фильтр"</string>
<string name="remote_action_failed" msgid="1383965239183576790">"Не удалось выполнить действие (<xliff:g id="WHAT">%1$s</xliff:g>)."</string>
<string name="private_space_label" msgid="2359721649407947001">"Частное пространство"</string>
diff --git a/res/values-si/strings.xml b/res/values-si/strings.xml
index 328f2f5..646443e 100644
--- a/res/values-si/strings.xml
+++ b/res/values-si/strings.xml
@@ -69,6 +69,12 @@
<string name="widget_category_note_taking" msgid="3469689394504266039">"සටහන් කර ගැනීම"</string>
<string name="widget_add_button_label" msgid="2761267068711937179">"එක් කරන්න"</string>
<string name="widget_add_button_content_description" msgid="1810530016360039643">"<xliff:g id="WIDGET_NAME">%1$s</xliff:g> විජට්ටුව එක් කරන්න"</string>
+ <!-- no translation found for widgets_list_expand_button_label (7912016136574932622) -->
+ <skip />
+ <!-- no translation found for widgets_list_expand_button_content_description (4600513860973450888) -->
+ <skip />
+ <!-- no translation found for widgets_list_expanded (7374857868788557730) -->
+ <skip />
<string name="reconfigurable_widget_education_tip" msgid="6336962690888067057">"විජට් සැකසීම් වෙනස් කිරීමට තට්ටු කරන්න"</string>
<string name="widget_reconfigure_button_content_description" msgid="8811472721881205250">"විජට් සැකසීම් වෙනස් කරන්න"</string>
<string name="all_apps_search_bar_hint" msgid="1390553134053255246">"යෙදුම් සොයන්න"</string>
@@ -124,6 +130,10 @@
<string name="msg_disabled_by_admin" msgid="6898038085516271325">"ඔබගේ පරිපාලක විසින් අබල කරන ලදී"</string>
<string name="allow_rotation_title" msgid="7222049633713050106">"මුල් තිරය කරකැවීමට ඉඩ දෙන්න"</string>
<string name="allow_rotation_desc" msgid="8662546029078692509">"දුරකථනය කරකවන විට"</string>
+ <!-- no translation found for landscape_mode_title (5138814555934843926) -->
+ <skip />
+ <!-- no translation found for landscape_mode_desc (7372569859592816793) -->
+ <skip />
<string name="notification_dots_title" msgid="9062440428204120317">"දැනුම්දීම් තිත්"</string>
<string name="notification_dots_desc_on" msgid="1679848116452218908">"ක්රියාත්මකයි"</string>
<string name="notification_dots_desc_off" msgid="1760796511504341095">"ක්රියාවිරහිතයි"</string>
@@ -142,7 +152,8 @@
<string name="app_installing_title" msgid="5864044122733792085">"<xliff:g id="NAME">%1$s</xliff:g> ස්ථාපනය කරමින්, <xliff:g id="PROGRESS">%2$s</xliff:g> සම්පූර්ණයි"</string>
<string name="app_downloading_title" msgid="8336702962104482644">"<xliff:g id="NAME">%1$s</xliff:g> බාගත කරමින්, <xliff:g id="PROGRESS">%2$s</xliff:g> සම්පූර්ණයි"</string>
<string name="app_waiting_download_title" msgid="7053938513995617849">"<xliff:g id="NAME">%1$s</xliff:g> ස්ථාපනය කිරීමට බලා සිටිමින්"</string>
- <string name="app_archived_title" msgid="7717956158562544081">"<xliff:g id="NAME">%1$s</xliff:g> සංරක්ෂිතයි. බා ගෙන ප්රතිසාධන කිරීමට තට්ටු කරන්න."</string>
+ <string name="app_archived_title" msgid="4548283110222420708">"<xliff:g id="NAME">%1$s</xliff:g> ලේඛනාරක්ෂණය කර ඇත."</string>
+ <string name="app_unarchiving_action" msgid="5736107006413929484">"බාගත කර ප්රතිසාධනය කරන්න"</string>
<string name="dialog_update_title" msgid="114234265740994042">"යෙදුම් යාවත්කාලීනයක් අවශ්යයි"</string>
<string name="dialog_update_message" msgid="4176784553982226114">"මෙම නිරූපකය සඳහා යෙදුම යාවත්කාලීන කර නැත. ඔබට මෙම කෙටි මඟ යළි සබල කිරීමට හෝ නිරූපකය ඉවත් කිරීමට හස්තීයව යාවත්කාලීන කළ හැකිය."</string>
<string name="dialog_update" msgid="2178028071796141234">"යාවත්කාලීන කරන්න"</string>
@@ -187,6 +198,8 @@
<string name="work_apps_paused_edu_accept" msgid="6377476824357318532">"තේරුණා"</string>
<string name="work_apps_pause_btn_text" msgid="4669288269140620646">"කාර්යාල යෙදුම් විරාම කරන්න"</string>
<string name="work_apps_enable_btn_text" msgid="1736198302467317371">"විරාම නොකරන්න"</string>
+ <!-- no translation found for work_scheduler_button_content_description (917340740986764967) -->
+ <skip />
<string name="developer_options_filter_hint" msgid="5896817443635989056">"පෙරහන"</string>
<string name="remote_action_failed" msgid="1383965239183576790">"අසාර්ථකයි: <xliff:g id="WHAT">%1$s</xliff:g>"</string>
<string name="private_space_label" msgid="2359721649407947001">"පෞද්ගලික ඉඩ"</string>
diff --git a/res/values-sk/strings.xml b/res/values-sk/strings.xml
index 88cb1b1..f9245cd 100644
--- a/res/values-sk/strings.xml
+++ b/res/values-sk/strings.xml
@@ -69,6 +69,12 @@
<string name="widget_category_note_taking" msgid="3469689394504266039">"Zapisovanie poznámok"</string>
<string name="widget_add_button_label" msgid="2761267068711937179">"Pridať"</string>
<string name="widget_add_button_content_description" msgid="1810530016360039643">"Pridať miniaplikáciu <xliff:g id="WIDGET_NAME">%1$s</xliff:g>"</string>
+ <!-- no translation found for widgets_list_expand_button_label (7912016136574932622) -->
+ <skip />
+ <!-- no translation found for widgets_list_expand_button_content_description (4600513860973450888) -->
+ <skip />
+ <!-- no translation found for widgets_list_expanded (7374857868788557730) -->
+ <skip />
<string name="reconfigurable_widget_education_tip" msgid="6336962690888067057">"Klepnutím zmeňte nastavenia miniaplikácie"</string>
<string name="widget_reconfigure_button_content_description" msgid="8811472721881205250">"Zmena nastavení miniaplikácie"</string>
<string name="all_apps_search_bar_hint" msgid="1390553134053255246">"Hľadať aplikácie"</string>
@@ -124,6 +130,10 @@
<string name="msg_disabled_by_admin" msgid="6898038085516271325">"Zakázané vaším správcom"</string>
<string name="allow_rotation_title" msgid="7222049633713050106">"Povoliť otáčanie plochy"</string>
<string name="allow_rotation_desc" msgid="8662546029078692509">"Pri otočení telefónu"</string>
+ <!-- no translation found for landscape_mode_title (5138814555934843926) -->
+ <skip />
+ <!-- no translation found for landscape_mode_desc (7372569859592816793) -->
+ <skip />
<string name="notification_dots_title" msgid="9062440428204120317">"Bodky upozornení"</string>
<string name="notification_dots_desc_on" msgid="1679848116452218908">"Zapnuté"</string>
<string name="notification_dots_desc_off" msgid="1760796511504341095">"Vypnuté"</string>
@@ -142,7 +152,8 @@
<string name="app_installing_title" msgid="5864044122733792085">"Inštaluje sa <xliff:g id="NAME">%1$s</xliff:g>. Dokončené: <xliff:g id="PROGRESS">%2$s</xliff:g>."</string>
<string name="app_downloading_title" msgid="8336702962104482644">"Sťahuje sa aplikácia <xliff:g id="NAME">%1$s</xliff:g>. Stiahnuté: <xliff:g id="PROGRESS">%2$s</xliff:g>"</string>
<string name="app_waiting_download_title" msgid="7053938513995617849">"Aplikácia <xliff:g id="NAME">%1$s</xliff:g> čaká na inštaláciu"</string>
- <string name="app_archived_title" msgid="7717956158562544081">"Aplikácia <xliff:g id="NAME">%1$s</xliff:g> je archivovaná. Klepnutím ju stiahnite a obnovte."</string>
+ <string name="app_archived_title" msgid="4548283110222420708">"Aplikácia <xliff:g id="NAME">%1$s</xliff:g> je archivovaná."</string>
+ <string name="app_unarchiving_action" msgid="5736107006413929484">"stiahnuť a obnoviť"</string>
<string name="dialog_update_title" msgid="114234265740994042">"Vyžaduje sa aktualizácia aplikácie"</string>
<string name="dialog_update_message" msgid="4176784553982226114">"Aplikácia, ktorú zastupuje táto ikona, nie je aktualizovaná. Môžete ju ručne aktualizovať, aby odkaz znova fungoval, prípadne môžete ikonu odstrániť."</string>
<string name="dialog_update" msgid="2178028071796141234">"Aktualizovať"</string>
@@ -187,6 +198,8 @@
<string name="work_apps_paused_edu_accept" msgid="6377476824357318532">"Dobre"</string>
<string name="work_apps_pause_btn_text" msgid="4669288269140620646">"Pozastaviť pracovné aplikácie"</string>
<string name="work_apps_enable_btn_text" msgid="1736198302467317371">"Zrušiť pozastavenie"</string>
+ <!-- no translation found for work_scheduler_button_content_description (917340740986764967) -->
+ <skip />
<string name="developer_options_filter_hint" msgid="5896817443635989056">"Filtrujte"</string>
<string name="remote_action_failed" msgid="1383965239183576790">"Zlyhalo: <xliff:g id="WHAT">%1$s</xliff:g>"</string>
<string name="private_space_label" msgid="2359721649407947001">"Súkromný priestor"</string>
diff --git a/res/values-sl/strings.xml b/res/values-sl/strings.xml
index 37a02e4..e8d8702 100644
--- a/res/values-sl/strings.xml
+++ b/res/values-sl/strings.xml
@@ -69,6 +69,12 @@
<string name="widget_category_note_taking" msgid="3469689394504266039">"Ustvarjanje zapiskov"</string>
<string name="widget_add_button_label" msgid="2761267068711937179">"Dodaj"</string>
<string name="widget_add_button_content_description" msgid="1810530016360039643">"Dodajanje pripomočka »<xliff:g id="WIDGET_NAME">%1$s</xliff:g>«"</string>
+ <!-- no translation found for widgets_list_expand_button_label (7912016136574932622) -->
+ <skip />
+ <!-- no translation found for widgets_list_expand_button_content_description (4600513860973450888) -->
+ <skip />
+ <!-- no translation found for widgets_list_expanded (7374857868788557730) -->
+ <skip />
<string name="reconfigurable_widget_education_tip" msgid="6336962690888067057">"Dotaknite se, če želite spremeniti nastavitve pripomočka."</string>
<string name="widget_reconfigure_button_content_description" msgid="8811472721881205250">"Spreminjanje nastavitev pripomočka"</string>
<string name="all_apps_search_bar_hint" msgid="1390553134053255246">"Iskanje programov"</string>
@@ -124,6 +130,10 @@
<string name="msg_disabled_by_admin" msgid="6898038085516271325">"Onemogočil skrbnik."</string>
<string name="allow_rotation_title" msgid="7222049633713050106">"Dovoli sukanje začetnega zaslona"</string>
<string name="allow_rotation_desc" msgid="8662546029078692509">"Ko se telefon zasuka"</string>
+ <!-- no translation found for landscape_mode_title (5138814555934843926) -->
+ <skip />
+ <!-- no translation found for landscape_mode_desc (7372569859592816793) -->
+ <skip />
<string name="notification_dots_title" msgid="9062440428204120317">"Obvestilne pike"</string>
<string name="notification_dots_desc_on" msgid="1679848116452218908">"Vklopljeno"</string>
<string name="notification_dots_desc_off" msgid="1760796511504341095">"Izklopljeno"</string>
@@ -142,7 +152,8 @@
<string name="app_installing_title" msgid="5864044122733792085">"<xliff:g id="NAME">%1$s</xliff:g> se namešča, dokončano: <xliff:g id="PROGRESS">%2$s</xliff:g>"</string>
<string name="app_downloading_title" msgid="8336702962104482644">"Prenašanje aplikacije <xliff:g id="NAME">%1$s</xliff:g>; preneseno <xliff:g id="PROGRESS">%2$s</xliff:g>"</string>
<string name="app_waiting_download_title" msgid="7053938513995617849">"Aplikacija <xliff:g id="NAME">%1$s</xliff:g> čaka na namestitev"</string>
- <string name="app_archived_title" msgid="7717956158562544081">"Aplikacija <xliff:g id="NAME">%1$s</xliff:g> je arhivirana. Dotaknite se za prenos in obnovitev."</string>
+ <string name="app_archived_title" msgid="4548283110222420708">"Aplikacija <xliff:g id="NAME">%1$s</xliff:g> je arhivirana."</string>
+ <string name="app_unarchiving_action" msgid="5736107006413929484">"prenos in obnovitev"</string>
<string name="dialog_update_title" msgid="114234265740994042">"Zahtevana je posodobitev aplikacije"</string>
<string name="dialog_update_message" msgid="4176784553982226114">"Aplikacija za to ikono ni posodobljena. Lahko jo ročno posodobite, da znova omogočite to bližnjico, ali pa odstranite ikono."</string>
<string name="dialog_update" msgid="2178028071796141234">"Posodobi"</string>
@@ -187,6 +198,8 @@
<string name="work_apps_paused_edu_accept" msgid="6377476824357318532">"V redu"</string>
<string name="work_apps_pause_btn_text" msgid="4669288269140620646">"Začasno zaustavi delovne aplikacije"</string>
<string name="work_apps_enable_btn_text" msgid="1736198302467317371">"Znova aktiviraj"</string>
+ <!-- no translation found for work_scheduler_button_content_description (917340740986764967) -->
+ <skip />
<string name="developer_options_filter_hint" msgid="5896817443635989056">"Filtriranje"</string>
<string name="remote_action_failed" msgid="1383965239183576790">"Ni uspelo: <xliff:g id="WHAT">%1$s</xliff:g>"</string>
<string name="private_space_label" msgid="2359721649407947001">"Zasebni prostor"</string>
diff --git a/res/values-sq/strings.xml b/res/values-sq/strings.xml
index 5be991a..1e5420a 100644
--- a/res/values-sq/strings.xml
+++ b/res/values-sq/strings.xml
@@ -69,6 +69,12 @@
<string name="widget_category_note_taking" msgid="3469689394504266039">"Mbajtja e shënimeve"</string>
<string name="widget_add_button_label" msgid="2761267068711937179">"Shto"</string>
<string name="widget_add_button_content_description" msgid="1810530016360039643">"Shto miniaplikacionin <xliff:g id="WIDGET_NAME">%1$s</xliff:g>"</string>
+ <!-- no translation found for widgets_list_expand_button_label (7912016136574932622) -->
+ <skip />
+ <!-- no translation found for widgets_list_expand_button_content_description (4600513860973450888) -->
+ <skip />
+ <!-- no translation found for widgets_list_expanded (7374857868788557730) -->
+ <skip />
<string name="reconfigurable_widget_education_tip" msgid="6336962690888067057">"Trokit për të ndryshuar cilësimet e miniaplikacionit"</string>
<string name="widget_reconfigure_button_content_description" msgid="8811472721881205250">"Ndrysho cilësimet e miniaplikacionit"</string>
<string name="all_apps_search_bar_hint" msgid="1390553134053255246">"Kërko për aplikacione"</string>
@@ -124,6 +130,10 @@
<string name="msg_disabled_by_admin" msgid="6898038085516271325">"Çaktivizuar nga administratori"</string>
<string name="allow_rotation_title" msgid="7222049633713050106">"Lejo rrotullimin e ekranit bazë"</string>
<string name="allow_rotation_desc" msgid="8662546029078692509">"Kur telefoni rrotullohet"</string>
+ <!-- no translation found for landscape_mode_title (5138814555934843926) -->
+ <skip />
+ <!-- no translation found for landscape_mode_desc (7372569859592816793) -->
+ <skip />
<string name="notification_dots_title" msgid="9062440428204120317">"Pikat e njoftimeve"</string>
<string name="notification_dots_desc_on" msgid="1679848116452218908">"Aktiv"</string>
<string name="notification_dots_desc_off" msgid="1760796511504341095">"Joaktiv"</string>
@@ -142,7 +152,8 @@
<string name="app_installing_title" msgid="5864044122733792085">"<xliff:g id="NAME">%1$s</xliff:g> po instalohet, <xliff:g id="PROGRESS">%2$s</xliff:g> i përfunduar"</string>
<string name="app_downloading_title" msgid="8336702962104482644">"<xliff:g id="NAME">%1$s</xliff:g> po shkarkohet, <xliff:g id="PROGRESS">%2$s</xliff:g> të përfunduara"</string>
<string name="app_waiting_download_title" msgid="7053938513995617849">"<xliff:g id="NAME">%1$s</xliff:g> po pret të instalohet"</string>
- <string name="app_archived_title" msgid="7717956158562544081">"<xliff:g id="NAME">%1$s</xliff:g> është arkivuar. Trokit për ta shkarkuar dhe restauruar."</string>
+ <string name="app_archived_title" msgid="4548283110222420708">"<xliff:g id="NAME">%1$s</xliff:g> është arkivuar."</string>
+ <string name="app_unarchiving_action" msgid="5736107006413929484">"shkarko dhe restauro"</string>
<string name="dialog_update_title" msgid="114234265740994042">"Kërkohet përditësimi i aplikacionit"</string>
<string name="dialog_update_message" msgid="4176784553982226114">"Aplikacioni për këtë ikonë nuk është përditësuar. Mund ta përditësosh manualisht për të riaktivizuar këtë shkurtore ose hiq ikonën."</string>
<string name="dialog_update" msgid="2178028071796141234">"Përditëso"</string>
@@ -187,6 +198,8 @@
<string name="work_apps_paused_edu_accept" msgid="6377476824357318532">"E kuptova"</string>
<string name="work_apps_pause_btn_text" msgid="4669288269140620646">"Vendos në pauzë aplikacionet e punës"</string>
<string name="work_apps_enable_btn_text" msgid="1736198302467317371">"Hiq nga pauza"</string>
+ <!-- no translation found for work_scheduler_button_content_description (917340740986764967) -->
+ <skip />
<string name="developer_options_filter_hint" msgid="5896817443635989056">"Filtro"</string>
<string name="remote_action_failed" msgid="1383965239183576790">"Dështoi: <xliff:g id="WHAT">%1$s</xliff:g>"</string>
<string name="private_space_label" msgid="2359721649407947001">"Hapësira private"</string>
diff --git a/res/values-sr/strings.xml b/res/values-sr/strings.xml
index afaeb61..c5b7bd0 100644
--- a/res/values-sr/strings.xml
+++ b/res/values-sr/strings.xml
@@ -69,6 +69,12 @@
<string name="widget_category_note_taking" msgid="3469689394504266039">"Прављење бележака"</string>
<string name="widget_add_button_label" msgid="2761267068711937179">"Додај"</string>
<string name="widget_add_button_content_description" msgid="1810530016360039643">"Додајте виџет <xliff:g id="WIDGET_NAME">%1$s</xliff:g>"</string>
+ <!-- no translation found for widgets_list_expand_button_label (7912016136574932622) -->
+ <skip />
+ <!-- no translation found for widgets_list_expand_button_content_description (4600513860973450888) -->
+ <skip />
+ <!-- no translation found for widgets_list_expanded (7374857868788557730) -->
+ <skip />
<string name="reconfigurable_widget_education_tip" msgid="6336962690888067057">"Додирните да бисте променили подешавања виџета"</string>
<string name="widget_reconfigure_button_content_description" msgid="8811472721881205250">"Промените подешавања виџета"</string>
<string name="all_apps_search_bar_hint" msgid="1390553134053255246">"Претражите апликације"</string>
@@ -124,6 +130,10 @@
<string name="msg_disabled_by_admin" msgid="6898038085516271325">"Администратор је онемогућио"</string>
<string name="allow_rotation_title" msgid="7222049633713050106">"Дозволи ротацију почетног екрана"</string>
<string name="allow_rotation_desc" msgid="8662546029078692509">"Када се телефон ротира"</string>
+ <!-- no translation found for landscape_mode_title (5138814555934843926) -->
+ <skip />
+ <!-- no translation found for landscape_mode_desc (7372569859592816793) -->
+ <skip />
<string name="notification_dots_title" msgid="9062440428204120317">"Тачке за обавештења"</string>
<string name="notification_dots_desc_on" msgid="1679848116452218908">"Укључено"</string>
<string name="notification_dots_desc_off" msgid="1760796511504341095">"Искључено"</string>
@@ -142,7 +152,8 @@
<string name="app_installing_title" msgid="5864044122733792085">"<xliff:g id="NAME">%1$s</xliff:g> се инсталира, <xliff:g id="PROGRESS">%2$s</xliff:g> готово"</string>
<string name="app_downloading_title" msgid="8336702962104482644">"<xliff:g id="NAME">%1$s</xliff:g> се преузима, завршено је <xliff:g id="PROGRESS">%2$s</xliff:g>"</string>
<string name="app_waiting_download_title" msgid="7053938513995617849">"<xliff:g id="NAME">%1$s</xliff:g> чека на инсталирање"</string>
- <string name="app_archived_title" msgid="7717956158562544081">"Апликација <xliff:g id="NAME">%1$s</xliff:g> је архивирана. Додирните да бисте је преузели и вратили."</string>
+ <string name="app_archived_title" msgid="4548283110222420708">"Апликација <xliff:g id="NAME">%1$s</xliff:g> је архивирана."</string>
+ <string name="app_unarchiving_action" msgid="5736107006413929484">"преузмите и вратите"</string>
<string name="dialog_update_title" msgid="114234265740994042">"Треба да ажурирате апликацију"</string>
<string name="dialog_update_message" msgid="4176784553982226114">"Апликација за ову икону није ажурирана. Можете да је ручно ажурирате да бисте поново омогућили ову пречицу или уклоните икону."</string>
<string name="dialog_update" msgid="2178028071796141234">"Ажурирај"</string>
@@ -187,6 +198,8 @@
<string name="work_apps_paused_edu_accept" msgid="6377476824357318532">"Важи"</string>
<string name="work_apps_pause_btn_text" msgid="4669288269140620646">"Паузирај пословне апликације"</string>
<string name="work_apps_enable_btn_text" msgid="1736198302467317371">"Поново активирај"</string>
+ <!-- no translation found for work_scheduler_button_content_description (917340740986764967) -->
+ <skip />
<string name="developer_options_filter_hint" msgid="5896817443635989056">"Филтер"</string>
<string name="remote_action_failed" msgid="1383965239183576790">"Није успело: <xliff:g id="WHAT">%1$s</xliff:g>"</string>
<string name="private_space_label" msgid="2359721649407947001">"Приватни простор"</string>
diff --git a/res/values-sv/strings.xml b/res/values-sv/strings.xml
index 547f60e..9ebf366 100644
--- a/res/values-sv/strings.xml
+++ b/res/values-sv/strings.xml
@@ -69,6 +69,12 @@
<string name="widget_category_note_taking" msgid="3469689394504266039">"Anteckna"</string>
<string name="widget_add_button_label" msgid="2761267068711937179">"Lägg till"</string>
<string name="widget_add_button_content_description" msgid="1810530016360039643">"Lägg till widgeten <xliff:g id="WIDGET_NAME">%1$s</xliff:g>"</string>
+ <!-- no translation found for widgets_list_expand_button_label (7912016136574932622) -->
+ <skip />
+ <!-- no translation found for widgets_list_expand_button_content_description (4600513860973450888) -->
+ <skip />
+ <!-- no translation found for widgets_list_expanded (7374857868788557730) -->
+ <skip />
<string name="reconfigurable_widget_education_tip" msgid="6336962690888067057">"Tryck för att ändra inställningarna för widgeten"</string>
<string name="widget_reconfigure_button_content_description" msgid="8811472721881205250">"Ändra inställningarna för widgeten"</string>
<string name="all_apps_search_bar_hint" msgid="1390553134053255246">"Sök efter appar"</string>
@@ -124,6 +130,10 @@
<string name="msg_disabled_by_admin" msgid="6898038085516271325">"Inaktiverat av administratören"</string>
<string name="allow_rotation_title" msgid="7222049633713050106">"Tillåt rotering av startskärmen"</string>
<string name="allow_rotation_desc" msgid="8662546029078692509">"När telefonen vrids"</string>
+ <!-- no translation found for landscape_mode_title (5138814555934843926) -->
+ <skip />
+ <!-- no translation found for landscape_mode_desc (7372569859592816793) -->
+ <skip />
<string name="notification_dots_title" msgid="9062440428204120317">"Aviseringsprickar"</string>
<string name="notification_dots_desc_on" msgid="1679848116452218908">"På"</string>
<string name="notification_dots_desc_off" msgid="1760796511504341095">"Av"</string>
@@ -142,7 +152,8 @@
<string name="app_installing_title" msgid="5864044122733792085">"<xliff:g id="NAME">%1$s</xliff:g> installeras. <xliff:g id="PROGRESS">%2$s</xliff:g> har slutförts"</string>
<string name="app_downloading_title" msgid="8336702962104482644">"<xliff:g id="NAME">%1$s</xliff:g> laddas ned, <xliff:g id="PROGRESS">%2$s</xliff:g> klart"</string>
<string name="app_waiting_download_title" msgid="7053938513995617849">"<xliff:g id="NAME">%1$s</xliff:g> väntar på installation"</string>
- <string name="app_archived_title" msgid="7717956158562544081">"<xliff:g id="NAME">%1$s</xliff:g> har arkiverats. Tryck för att ladda ner och återställa."</string>
+ <string name="app_archived_title" msgid="4548283110222420708">"<xliff:g id="NAME">%1$s</xliff:g> har arkiverats."</string>
+ <string name="app_unarchiving_action" msgid="5736107006413929484">"ladda ned och återställ"</string>
<string name="dialog_update_title" msgid="114234265740994042">"Du måste uppdatera appen"</string>
<string name="dialog_update_message" msgid="4176784553982226114">"Appen för den här ikonen har inte uppdaterats. Du kan uppdatera den manuellt för att återaktivera genvägen eller ta bort ikonen."</string>
<string name="dialog_update" msgid="2178028071796141234">"Uppdatera"</string>
@@ -187,6 +198,8 @@
<string name="work_apps_paused_edu_accept" msgid="6377476824357318532">"OK"</string>
<string name="work_apps_pause_btn_text" msgid="4669288269140620646">"Pausa jobbappar"</string>
<string name="work_apps_enable_btn_text" msgid="1736198302467317371">"Återuppta"</string>
+ <!-- no translation found for work_scheduler_button_content_description (917340740986764967) -->
+ <skip />
<string name="developer_options_filter_hint" msgid="5896817443635989056">"Filter"</string>
<string name="remote_action_failed" msgid="1383965239183576790">"Misslyckades: <xliff:g id="WHAT">%1$s</xliff:g>"</string>
<string name="private_space_label" msgid="2359721649407947001">"Privat rum"</string>
diff --git a/res/values-sw/strings.xml b/res/values-sw/strings.xml
index 71f8d8b..a7725f3 100644
--- a/res/values-sw/strings.xml
+++ b/res/values-sw/strings.xml
@@ -69,6 +69,12 @@
<string name="widget_category_note_taking" msgid="3469689394504266039">"Kuandika madokezo"</string>
<string name="widget_add_button_label" msgid="2761267068711937179">"Weka"</string>
<string name="widget_add_button_content_description" msgid="1810530016360039643">"Weka wijeti ya <xliff:g id="WIDGET_NAME">%1$s</xliff:g>"</string>
+ <!-- no translation found for widgets_list_expand_button_label (7912016136574932622) -->
+ <skip />
+ <!-- no translation found for widgets_list_expand_button_content_description (4600513860973450888) -->
+ <skip />
+ <!-- no translation found for widgets_list_expanded (7374857868788557730) -->
+ <skip />
<string name="reconfigurable_widget_education_tip" msgid="6336962690888067057">"Gusa ili ubadilishe mipangilio ya wijeti"</string>
<string name="widget_reconfigure_button_content_description" msgid="8811472721881205250">"Badilisha mipangilio ya wijeti"</string>
<string name="all_apps_search_bar_hint" msgid="1390553134053255246">"Tafuta programu"</string>
@@ -124,6 +130,10 @@
<string name="msg_disabled_by_admin" msgid="6898038085516271325">"Imezimwa na msimamizi wako"</string>
<string name="allow_rotation_title" msgid="7222049633713050106">"Ruhusu kipengele cha kuzungusha skrini ya kwanza"</string>
<string name="allow_rotation_desc" msgid="8662546029078692509">"Simu inapozungushwa"</string>
+ <!-- no translation found for landscape_mode_title (5138814555934843926) -->
+ <skip />
+ <!-- no translation found for landscape_mode_desc (7372569859592816793) -->
+ <skip />
<string name="notification_dots_title" msgid="9062440428204120317">"Vitone vya arifa"</string>
<string name="notification_dots_desc_on" msgid="1679848116452218908">"Imewashwa"</string>
<string name="notification_dots_desc_off" msgid="1760796511504341095">"Imezimwa"</string>
@@ -142,7 +152,8 @@
<string name="app_installing_title" msgid="5864044122733792085">"Inasakinisha <xliff:g id="NAME">%1$s</xliff:g>, imekamilika <xliff:g id="PROGRESS">%2$s</xliff:g>"</string>
<string name="app_downloading_title" msgid="8336702962104482644">"<xliff:g id="NAME">%1$s</xliff:g> inapakuliwa, <xliff:g id="PROGRESS">%2$s</xliff:g> imekamilika"</string>
<string name="app_waiting_download_title" msgid="7053938513995617849">"<xliff:g id="NAME">%1$s</xliff:g> inasubiri kusakinisha"</string>
- <string name="app_archived_title" msgid="7717956158562544081">"<xliff:g id="NAME">%1$s</xliff:g> imewekwa kwenye kumbukumbu. Gusa ili upakue na urejeshe."</string>
+ <string name="app_archived_title" msgid="4548283110222420708">"<xliff:g id="NAME">%1$s</xliff:g> imewekwa kwenye kumbukumbu."</string>
+ <string name="app_unarchiving_action" msgid="5736107006413929484">"pakua na urejeshe"</string>
<string name="dialog_update_title" msgid="114234265740994042">"Unahitaji kusasisha programu"</string>
<string name="dialog_update_message" msgid="4176784553982226114">"Programu ya aikoni hii haijasasishwa. Unaweza kusasisha mwenyewe ili uruhusu upya njia hii ya mkato au uondoe aikoni."</string>
<string name="dialog_update" msgid="2178028071796141234">"Sasisha"</string>
@@ -187,6 +198,8 @@
<string name="work_apps_paused_edu_accept" msgid="6377476824357318532">"Nimeelewa"</string>
<string name="work_apps_pause_btn_text" msgid="4669288269140620646">"Simamisha programu za kazini"</string>
<string name="work_apps_enable_btn_text" msgid="1736198302467317371">"Acha kusimamisha"</string>
+ <!-- no translation found for work_scheduler_button_content_description (917340740986764967) -->
+ <skip />
<string name="developer_options_filter_hint" msgid="5896817443635989056">"Kichujio"</string>
<string name="remote_action_failed" msgid="1383965239183576790">"Hitilafu: <xliff:g id="WHAT">%1$s</xliff:g>"</string>
<string name="private_space_label" msgid="2359721649407947001">"Nafasi ya faragha"</string>
diff --git a/res/values-ta/strings.xml b/res/values-ta/strings.xml
index e87e2eb..295367d 100644
--- a/res/values-ta/strings.xml
+++ b/res/values-ta/strings.xml
@@ -69,6 +69,12 @@
<string name="widget_category_note_taking" msgid="3469689394504266039">"குறிப்பெடுத்தல்"</string>
<string name="widget_add_button_label" msgid="2761267068711937179">"சேர்"</string>
<string name="widget_add_button_content_description" msgid="1810530016360039643">"<xliff:g id="WIDGET_NAME">%1$s</xliff:g> விட்ஜெட்டைச் சேர்க்கும்"</string>
+ <!-- no translation found for widgets_list_expand_button_label (7912016136574932622) -->
+ <skip />
+ <!-- no translation found for widgets_list_expand_button_content_description (4600513860973450888) -->
+ <skip />
+ <!-- no translation found for widgets_list_expanded (7374857868788557730) -->
+ <skip />
<string name="reconfigurable_widget_education_tip" msgid="6336962690888067057">"விட்ஜெட் அமைப்புகளை மாற்றத் தட்டவும்"</string>
<string name="widget_reconfigure_button_content_description" msgid="8811472721881205250">"விட்ஜெட் அமைப்புகளை மாற்றும்"</string>
<string name="all_apps_search_bar_hint" msgid="1390553134053255246">"ஆப்ஸில் தேடுக"</string>
@@ -124,6 +130,10 @@
<string name="msg_disabled_by_admin" msgid="6898038085516271325">"உங்கள் நிர்வாகி முடக்கியுள்ளார்"</string>
<string name="allow_rotation_title" msgid="7222049633713050106">"முகப்புத் திரை சுழற்சியை அனுமதித்தல்"</string>
<string name="allow_rotation_desc" msgid="8662546029078692509">"மொபைலைச் சுழற்றும் போது"</string>
+ <!-- no translation found for landscape_mode_title (5138814555934843926) -->
+ <skip />
+ <!-- no translation found for landscape_mode_desc (7372569859592816793) -->
+ <skip />
<string name="notification_dots_title" msgid="9062440428204120317">"அறிவிப்புப் புள்ளிகள்"</string>
<string name="notification_dots_desc_on" msgid="1679848116452218908">"ஆன்"</string>
<string name="notification_dots_desc_off" msgid="1760796511504341095">"ஆஃப்"</string>
@@ -142,7 +152,8 @@
<string name="app_installing_title" msgid="5864044122733792085">"<xliff:g id="NAME">%1$s</xliff:g> நிறுவப்படுகிறது, <xliff:g id="PROGRESS">%2$s</xliff:g> முடிந்தது"</string>
<string name="app_downloading_title" msgid="8336702962104482644">"<xliff:g id="NAME">%1$s</xliff:g>ஐப் பதிவிறக்குகிறது, <xliff:g id="PROGRESS">%2$s</xliff:g> முடிந்தது"</string>
<string name="app_waiting_download_title" msgid="7053938513995617849">"<xliff:g id="NAME">%1$s</xliff:g>ஐ நிறுவுவதற்காகக் காத்திருக்கிறது"</string>
- <string name="app_archived_title" msgid="7717956158562544081">"<xliff:g id="NAME">%1$s</xliff:g> காப்பிடப்பட்டுள்ளது. அதைப் பதிவிறக்கி மீட்டெடுக்க தட்டுங்கள்."</string>
+ <string name="app_archived_title" msgid="4548283110222420708">"<xliff:g id="NAME">%1$s</xliff:g> காப்பிடப்பட்டுள்ளது."</string>
+ <string name="app_unarchiving_action" msgid="5736107006413929484">"பதிவிறக்கி மீட்டெடுக்கும்"</string>
<string name="dialog_update_title" msgid="114234265740994042">"ஆப்ஸைப் புதுப்பியுங்கள்"</string>
<string name="dialog_update_message" msgid="4176784553982226114">"இந்த ஐகானுக்கான ஆப்ஸ் புதுப்பிக்கப்படவில்லை. இந்த ஷார்ட்கட்டை மீண்டும் இயக்கவோ ஐகானை அகற்றவோ நீங்களாகவே புதுப்பிக்கலாம்."</string>
<string name="dialog_update" msgid="2178028071796141234">"புதுப்பி"</string>
@@ -187,6 +198,8 @@
<string name="work_apps_paused_edu_accept" msgid="6377476824357318532">"சரி"</string>
<string name="work_apps_pause_btn_text" msgid="4669288269140620646">"பணி ஆப்ஸை இடைநிறுத்து"</string>
<string name="work_apps_enable_btn_text" msgid="1736198302467317371">"மீண்டும் இயக்கு"</string>
+ <!-- no translation found for work_scheduler_button_content_description (917340740986764967) -->
+ <skip />
<string name="developer_options_filter_hint" msgid="5896817443635989056">"வடிப்பான்"</string>
<string name="remote_action_failed" msgid="1383965239183576790">"தோல்வி: <xliff:g id="WHAT">%1$s</xliff:g>"</string>
<string name="private_space_label" msgid="2359721649407947001">"தனிப்பட்ட சேமிப்பிடம்"</string>
diff --git a/res/values-te/strings.xml b/res/values-te/strings.xml
index 75dc7f0..5859665 100644
--- a/res/values-te/strings.xml
+++ b/res/values-te/strings.xml
@@ -69,6 +69,12 @@
<string name="widget_category_note_taking" msgid="3469689394504266039">"నోట్-టేకింగ్"</string>
<string name="widget_add_button_label" msgid="2761267068711937179">"జోడించండి"</string>
<string name="widget_add_button_content_description" msgid="1810530016360039643">"<xliff:g id="WIDGET_NAME">%1$s</xliff:g> విడ్జెట్ను జోడించండి"</string>
+ <!-- no translation found for widgets_list_expand_button_label (7912016136574932622) -->
+ <skip />
+ <!-- no translation found for widgets_list_expand_button_content_description (4600513860973450888) -->
+ <skip />
+ <!-- no translation found for widgets_list_expanded (7374857868788557730) -->
+ <skip />
<string name="reconfigurable_widget_education_tip" msgid="6336962690888067057">"విడ్జెట్ సెట్టింగ్లను మార్చడానికి ట్యాప్ చేయండి"</string>
<string name="widget_reconfigure_button_content_description" msgid="8811472721881205250">"విడ్జెట్ సెట్టింగ్లను మార్చండి"</string>
<string name="all_apps_search_bar_hint" msgid="1390553134053255246">"యాప్ల కోసం సెర్చ్ చేయండి"</string>
@@ -124,6 +130,10 @@
<string name="msg_disabled_by_admin" msgid="6898038085516271325">"మీ నిర్వాహకులు నిలిపివేసారు"</string>
<string name="allow_rotation_title" msgid="7222049633713050106">"మొదటి స్క్రీన్ రొటేషన్ను అనుమతించండి"</string>
<string name="allow_rotation_desc" msgid="8662546029078692509">"ఫోన్ను తిప్పినప్పుడు"</string>
+ <!-- no translation found for landscape_mode_title (5138814555934843926) -->
+ <skip />
+ <!-- no translation found for landscape_mode_desc (7372569859592816793) -->
+ <skip />
<string name="notification_dots_title" msgid="9062440428204120317">"నోటిఫికేషన్ డాట్లు"</string>
<string name="notification_dots_desc_on" msgid="1679848116452218908">"ఆన్"</string>
<string name="notification_dots_desc_off" msgid="1760796511504341095">"ఆఫ్"</string>
@@ -142,7 +152,8 @@
<string name="app_installing_title" msgid="5864044122733792085">"<xliff:g id="NAME">%1$s</xliff:g>ను ఇన్స్టాల్ చేయడం, <xliff:g id="PROGRESS">%2$s</xliff:g> పూర్తయింది"</string>
<string name="app_downloading_title" msgid="8336702962104482644">"<xliff:g id="NAME">%1$s</xliff:g> డౌన్లోడ్ అవుతోంది, <xliff:g id="PROGRESS">%2$s</xliff:g> పూర్తయింది"</string>
<string name="app_waiting_download_title" msgid="7053938513995617849">"<xliff:g id="NAME">%1$s</xliff:g> ఇన్స్టాల్ కావడానికి వేచి ఉంది"</string>
- <string name="app_archived_title" msgid="7717956158562544081">"<xliff:g id="NAME">%1$s</xliff:g> ఆర్కైవ్ చేయబడింది. డౌన్లోడ్ చేయడానికి, రీస్టోర్ చేయడానికి ట్యాప్ చేయండి."</string>
+ <string name="app_archived_title" msgid="4548283110222420708">"<xliff:g id="NAME">%1$s</xliff:g> ఆర్కైవ్ చేయబడింది."</string>
+ <string name="app_unarchiving_action" msgid="5736107006413929484">"డౌన్లోడ్ చేసి, రీస్టోర్ చేయండి"</string>
<string name="dialog_update_title" msgid="114234265740994042">"యాప్ను అప్డేట్ చేయడం అవసరం"</string>
<string name="dialog_update_message" msgid="4176784553982226114">"ఈ చిహ్నం కోసం యాప్ అప్డేట్ చేయబడలేదు. మీరు ఈ షార్ట్కట్ను మళ్లీ ఎనేబుల్ చేయడానికి మాన్యువల్గా అప్డేట్ చేయవచ్చు లేదా చిహ్నాన్ని తీసివేయవచ్చు."</string>
<string name="dialog_update" msgid="2178028071796141234">"అప్డేట్ చేయండి"</string>
@@ -187,6 +198,8 @@
<string name="work_apps_paused_edu_accept" msgid="6377476824357318532">"అర్థమైంది"</string>
<string name="work_apps_pause_btn_text" msgid="4669288269140620646">"వర్క్ యాప్లను పాజ్ చేయండి"</string>
<string name="work_apps_enable_btn_text" msgid="1736198302467317371">"పాజ్ నుండి తీసివేయండి"</string>
+ <!-- no translation found for work_scheduler_button_content_description (917340740986764967) -->
+ <skip />
<string name="developer_options_filter_hint" msgid="5896817443635989056">"ఫిల్టర్ చేయి"</string>
<string name="remote_action_failed" msgid="1383965239183576790">"విఫలమైంది: <xliff:g id="WHAT">%1$s</xliff:g>"</string>
<string name="private_space_label" msgid="2359721649407947001">"ప్రైవేట్ స్పేస్"</string>
diff --git a/res/values-th/strings.xml b/res/values-th/strings.xml
index 50a0e52..fd2ba21 100644
--- a/res/values-th/strings.xml
+++ b/res/values-th/strings.xml
@@ -69,6 +69,12 @@
<string name="widget_category_note_taking" msgid="3469689394504266039">"การจดบันทึก"</string>
<string name="widget_add_button_label" msgid="2761267068711937179">"เพิ่ม"</string>
<string name="widget_add_button_content_description" msgid="1810530016360039643">"เพิ่มวิดเจ็ต <xliff:g id="WIDGET_NAME">%1$s</xliff:g>"</string>
+ <!-- no translation found for widgets_list_expand_button_label (7912016136574932622) -->
+ <skip />
+ <!-- no translation found for widgets_list_expand_button_content_description (4600513860973450888) -->
+ <skip />
+ <!-- no translation found for widgets_list_expanded (7374857868788557730) -->
+ <skip />
<string name="reconfigurable_widget_education_tip" msgid="6336962690888067057">"แตะเพื่อเปลี่ยนการตั้งค่าวิดเจ็ต"</string>
<string name="widget_reconfigure_button_content_description" msgid="8811472721881205250">"เปลี่ยนการตั้งค่าวิดเจ็ต"</string>
<string name="all_apps_search_bar_hint" msgid="1390553134053255246">"ค้นหาแอป"</string>
@@ -124,6 +130,10 @@
<string name="msg_disabled_by_admin" msgid="6898038085516271325">"ปิดใช้โดยผู้ดูแลระบบ"</string>
<string name="allow_rotation_title" msgid="7222049633713050106">"อนุญาตให้หมุนหน้าจอหลัก"</string>
<string name="allow_rotation_desc" msgid="8662546029078692509">"เมื่อหมุนโทรศัพท์"</string>
+ <!-- no translation found for landscape_mode_title (5138814555934843926) -->
+ <skip />
+ <!-- no translation found for landscape_mode_desc (7372569859592816793) -->
+ <skip />
<string name="notification_dots_title" msgid="9062440428204120317">"เครื่องหมายจุดแสดงการแจ้งเตือน"</string>
<string name="notification_dots_desc_on" msgid="1679848116452218908">"เปิด"</string>
<string name="notification_dots_desc_off" msgid="1760796511504341095">"ปิด"</string>
@@ -142,7 +152,8 @@
<string name="app_installing_title" msgid="5864044122733792085">"กำลังติดตั้ง <xliff:g id="NAME">%1$s</xliff:g> เสร็จแล้ว <xliff:g id="PROGRESS">%2$s</xliff:g>"</string>
<string name="app_downloading_title" msgid="8336702962104482644">"กำลังดาวน์โหลด <xliff:g id="NAME">%1$s</xliff:g> เสร็จแล้ว <xliff:g id="PROGRESS">%2$s</xliff:g>"</string>
<string name="app_waiting_download_title" msgid="7053938513995617849">"<xliff:g id="NAME">%1$s</xliff:g> กำลังรอติดตั้ง"</string>
- <string name="app_archived_title" msgid="7717956158562544081">"เก็บถาวร <xliff:g id="NAME">%1$s</xliff:g> แล้ว แตะเพื่อดาวน์โหลดและกู้คืน"</string>
+ <string name="app_archived_title" msgid="4548283110222420708">"เก็บถาวร <xliff:g id="NAME">%1$s</xliff:g> แล้ว"</string>
+ <string name="app_unarchiving_action" msgid="5736107006413929484">"ดาวน์โหลดและกู้คืน"</string>
<string name="dialog_update_title" msgid="114234265740994042">"ต้องอัปเดตแอป"</string>
<string name="dialog_update_message" msgid="4176784553982226114">"แอปสำหรับไอคอนนี้ยังไม่ได้อัปเดต คุณอัปเดตด้วยตนเองได้โดยเปิดใช้ทางลัดนี้อีกครั้งหรือนำไอคอนออก"</string>
<string name="dialog_update" msgid="2178028071796141234">"อัปเดต"</string>
@@ -187,6 +198,8 @@
<string name="work_apps_paused_edu_accept" msgid="6377476824357318532">"รับทราบ"</string>
<string name="work_apps_pause_btn_text" msgid="4669288269140620646">"หยุดแอปงานชั่วคราว"</string>
<string name="work_apps_enable_btn_text" msgid="1736198302467317371">"ยกเลิกการหยุดชั่วคราว"</string>
+ <!-- no translation found for work_scheduler_button_content_description (917340740986764967) -->
+ <skip />
<string name="developer_options_filter_hint" msgid="5896817443635989056">"ตัวกรอง"</string>
<string name="remote_action_failed" msgid="1383965239183576790">"ไม่สำเร็จ: <xliff:g id="WHAT">%1$s</xliff:g>"</string>
<string name="private_space_label" msgid="2359721649407947001">"พื้นที่ส่วนตัว"</string>
diff --git a/res/values-tl/strings.xml b/res/values-tl/strings.xml
index 86ad330..69f88e1 100644
--- a/res/values-tl/strings.xml
+++ b/res/values-tl/strings.xml
@@ -69,6 +69,12 @@
<string name="widget_category_note_taking" msgid="3469689394504266039">"Pagtatala"</string>
<string name="widget_add_button_label" msgid="2761267068711937179">"Idagdag"</string>
<string name="widget_add_button_content_description" msgid="1810530016360039643">"Idagdag ang widget na <xliff:g id="WIDGET_NAME">%1$s</xliff:g>"</string>
+ <!-- no translation found for widgets_list_expand_button_label (7912016136574932622) -->
+ <skip />
+ <!-- no translation found for widgets_list_expand_button_content_description (4600513860973450888) -->
+ <skip />
+ <!-- no translation found for widgets_list_expanded (7374857868788557730) -->
+ <skip />
<string name="reconfigurable_widget_education_tip" msgid="6336962690888067057">"I-tap para baguhin ang mga setting ng widget"</string>
<string name="widget_reconfigure_button_content_description" msgid="8811472721881205250">"Baguhin ang mga setting ng widget"</string>
<string name="all_apps_search_bar_hint" msgid="1390553134053255246">"Maghanap ng mga app"</string>
@@ -124,6 +130,10 @@
<string name="msg_disabled_by_admin" msgid="6898038085516271325">"Na-disable ng iyong admin"</string>
<string name="allow_rotation_title" msgid="7222049633713050106">"Payagan ang pag-rotate ng home screen"</string>
<string name="allow_rotation_desc" msgid="8662546029078692509">"Kailan maro-rotate ang telepono"</string>
+ <!-- no translation found for landscape_mode_title (5138814555934843926) -->
+ <skip />
+ <!-- no translation found for landscape_mode_desc (7372569859592816793) -->
+ <skip />
<string name="notification_dots_title" msgid="9062440428204120317">"Mga notification dot"</string>
<string name="notification_dots_desc_on" msgid="1679848116452218908">"Naka-on"</string>
<string name="notification_dots_desc_off" msgid="1760796511504341095">"Naka-off"</string>
@@ -142,7 +152,8 @@
<string name="app_installing_title" msgid="5864044122733792085">"Ini-install ang <xliff:g id="NAME">%1$s</xliff:g>, <xliff:g id="PROGRESS">%2$s</xliff:g> kumpleto"</string>
<string name="app_downloading_title" msgid="8336702962104482644">"Dina-download na ang <xliff:g id="NAME">%1$s</xliff:g>, tapos na ang <xliff:g id="PROGRESS">%2$s</xliff:g>"</string>
<string name="app_waiting_download_title" msgid="7053938513995617849">"Hinihintay nang mag-install ang <xliff:g id="NAME">%1$s</xliff:g>"</string>
- <string name="app_archived_title" msgid="7717956158562544081">"Naka-archive ang <xliff:g id="NAME">%1$s</xliff:g>. I-tap para i-download at i-restore."</string>
+ <string name="app_archived_title" msgid="4548283110222420708">"Naka-archive ang <xliff:g id="NAME">%1$s</xliff:g>."</string>
+ <string name="app_unarchiving_action" msgid="5736107006413929484">"i-download at i-restore"</string>
<string name="dialog_update_title" msgid="114234265740994042">"Kinakailangang i-update ang app"</string>
<string name="dialog_update_message" msgid="4176784553982226114">"Hindi updated ang app para sa icon na ito. Puwede kang manual na mag-update para ma-enable ulit ang shortcut na ito, o alisin ang icon."</string>
<string name="dialog_update" msgid="2178028071796141234">"I-update"</string>
@@ -187,6 +198,8 @@
<string name="work_apps_paused_edu_accept" msgid="6377476824357318532">"OK"</string>
<string name="work_apps_pause_btn_text" msgid="4669288269140620646">"I-pause ang mga app para sa trabaho"</string>
<string name="work_apps_enable_btn_text" msgid="1736198302467317371">"I-unpause"</string>
+ <!-- no translation found for work_scheduler_button_content_description (917340740986764967) -->
+ <skip />
<string name="developer_options_filter_hint" msgid="5896817443635989056">"Filter"</string>
<string name="remote_action_failed" msgid="1383965239183576790">"Hindi nagawa: <xliff:g id="WHAT">%1$s</xliff:g>"</string>
<string name="private_space_label" msgid="2359721649407947001">"Pribadong space"</string>
diff --git a/res/values-tr/strings.xml b/res/values-tr/strings.xml
index 9955bbf..e61b670 100644
--- a/res/values-tr/strings.xml
+++ b/res/values-tr/strings.xml
@@ -69,6 +69,12 @@
<string name="widget_category_note_taking" msgid="3469689394504266039">"Not alma"</string>
<string name="widget_add_button_label" msgid="2761267068711937179">"Ekle"</string>
<string name="widget_add_button_content_description" msgid="1810530016360039643">"<xliff:g id="WIDGET_NAME">%1$s</xliff:g> widget\'ı ekle"</string>
+ <!-- no translation found for widgets_list_expand_button_label (7912016136574932622) -->
+ <skip />
+ <!-- no translation found for widgets_list_expand_button_content_description (4600513860973450888) -->
+ <skip />
+ <!-- no translation found for widgets_list_expanded (7374857868788557730) -->
+ <skip />
<string name="reconfigurable_widget_education_tip" msgid="6336962690888067057">"Widget ayarlarını değiştirmek için dokunun"</string>
<string name="widget_reconfigure_button_content_description" msgid="8811472721881205250">"Widget ayarlarını değiştir"</string>
<string name="all_apps_search_bar_hint" msgid="1390553134053255246">"Uygulamalarda ara"</string>
@@ -124,6 +130,10 @@
<string name="msg_disabled_by_admin" msgid="6898038085516271325">"Yöneticiniz tarafından devre dışı bırakıldı"</string>
<string name="allow_rotation_title" msgid="7222049633713050106">"Ana ekranı döndürmeye izin ver"</string>
<string name="allow_rotation_desc" msgid="8662546029078692509">"Telefon döndürüldüğünde"</string>
+ <!-- no translation found for landscape_mode_title (5138814555934843926) -->
+ <skip />
+ <!-- no translation found for landscape_mode_desc (7372569859592816793) -->
+ <skip />
<string name="notification_dots_title" msgid="9062440428204120317">"Bildirim noktaları"</string>
<string name="notification_dots_desc_on" msgid="1679848116452218908">"Açık"</string>
<string name="notification_dots_desc_off" msgid="1760796511504341095">"Kapalı"</string>
@@ -142,7 +152,8 @@
<string name="app_installing_title" msgid="5864044122733792085">"<xliff:g id="NAME">%1$s</xliff:g> yükleniyor, <xliff:g id="PROGRESS">%2$s</xliff:g> tamamlandı"</string>
<string name="app_downloading_title" msgid="8336702962104482644">"<xliff:g id="NAME">%1$s</xliff:g> indiriliyor, <xliff:g id="PROGRESS">%2$s</xliff:g> tamamlandı"</string>
<string name="app_waiting_download_title" msgid="7053938513995617849">"<xliff:g id="NAME">%1$s</xliff:g> uygulaması yüklenmek için bekliyor"</string>
- <string name="app_archived_title" msgid="7717956158562544081">"<xliff:g id="NAME">%1$s</xliff:g> arşivlendi. İndirip geri yüklemek için dokunun."</string>
+ <string name="app_archived_title" msgid="4548283110222420708">"<xliff:g id="NAME">%1$s</xliff:g> arşivlendi."</string>
+ <string name="app_unarchiving_action" msgid="5736107006413929484">"indir ve geri yükle"</string>
<string name="dialog_update_title" msgid="114234265740994042">"Uygulama güncellemesi gerekli"</string>
<string name="dialog_update_message" msgid="4176784553982226114">"Bu simgenin uygulaması güncellenmemiş. Simgeyi kaldırabilir ya da uygulamayı manuel olarak güncelleyerek bu kısayolu yeniden etkinleştirebilirsiniz."</string>
<string name="dialog_update" msgid="2178028071796141234">"Güncelle"</string>
@@ -187,6 +198,8 @@
<string name="work_apps_paused_edu_accept" msgid="6377476824357318532">"Anladım"</string>
<string name="work_apps_pause_btn_text" msgid="4669288269140620646">"İş uygulamalarını duraklat"</string>
<string name="work_apps_enable_btn_text" msgid="1736198302467317371">"Devam ettir"</string>
+ <!-- no translation found for work_scheduler_button_content_description (917340740986764967) -->
+ <skip />
<string name="developer_options_filter_hint" msgid="5896817443635989056">"Filtre"</string>
<string name="remote_action_failed" msgid="1383965239183576790">"Başarısız: <xliff:g id="WHAT">%1$s</xliff:g>"</string>
<string name="private_space_label" msgid="2359721649407947001">"Gizli alan"</string>
diff --git a/res/values-uk/strings.xml b/res/values-uk/strings.xml
index e777262..fd293e3 100644
--- a/res/values-uk/strings.xml
+++ b/res/values-uk/strings.xml
@@ -69,6 +69,12 @@
<string name="widget_category_note_taking" msgid="3469689394504266039">"Створення нотаток"</string>
<string name="widget_add_button_label" msgid="2761267068711937179">"Додати"</string>
<string name="widget_add_button_content_description" msgid="1810530016360039643">"Додати віджет \"<xliff:g id="WIDGET_NAME">%1$s</xliff:g>\""</string>
+ <!-- no translation found for widgets_list_expand_button_label (7912016136574932622) -->
+ <skip />
+ <!-- no translation found for widgets_list_expand_button_content_description (4600513860973450888) -->
+ <skip />
+ <!-- no translation found for widgets_list_expanded (7374857868788557730) -->
+ <skip />
<string name="reconfigurable_widget_education_tip" msgid="6336962690888067057">"Натисніть, щоб змінити налаштування віджета"</string>
<string name="widget_reconfigure_button_content_description" msgid="8811472721881205250">"Змінити налаштування віджета"</string>
<string name="all_apps_search_bar_hint" msgid="1390553134053255246">"Пошук додатків"</string>
@@ -124,6 +130,10 @@
<string name="msg_disabled_by_admin" msgid="6898038085516271325">"Вимкнув адміністратор"</string>
<string name="allow_rotation_title" msgid="7222049633713050106">"Дозволити обертання головного екрана"</string>
<string name="allow_rotation_desc" msgid="8662546029078692509">"Коли телефон обертається"</string>
+ <!-- no translation found for landscape_mode_title (5138814555934843926) -->
+ <skip />
+ <!-- no translation found for landscape_mode_desc (7372569859592816793) -->
+ <skip />
<string name="notification_dots_title" msgid="9062440428204120317">"Значки сповіщень"</string>
<string name="notification_dots_desc_on" msgid="1679848116452218908">"Увімкнено"</string>
<string name="notification_dots_desc_off" msgid="1760796511504341095">"Вимкнено"</string>
@@ -142,7 +152,8 @@
<string name="app_installing_title" msgid="5864044122733792085">"<xliff:g id="NAME">%1$s</xliff:g> встановлюється, виконано <xliff:g id="PROGRESS">%2$s</xliff:g>"</string>
<string name="app_downloading_title" msgid="8336702962104482644">"<xliff:g id="NAME">%1$s</xliff:g> завантажується, <xliff:g id="PROGRESS">%2$s</xliff:g>"</string>
<string name="app_waiting_download_title" msgid="7053938513995617849">"<xliff:g id="NAME">%1$s</xliff:g> очікує на завантаження"</string>
- <string name="app_archived_title" msgid="7717956158562544081">"Додаток <xliff:g id="NAME">%1$s</xliff:g> заархівовано. Натисніть, щоб завантажити й відновити."</string>
+ <string name="app_archived_title" msgid="4548283110222420708">"Додаток <xliff:g id="NAME">%1$s</xliff:g> заархівовано."</string>
+ <string name="app_unarchiving_action" msgid="5736107006413929484">"завантажити й відновити"</string>
<string name="dialog_update_title" msgid="114234265740994042">"Потрібно оновити додаток"</string>
<string name="dialog_update_message" msgid="4176784553982226114">"Додаток для цього значка не оновлено. Ви можете оновити його вручну, щоб знову ввімкнути цю швидку команду, або можете вилучити значок."</string>
<string name="dialog_update" msgid="2178028071796141234">"Оновити"</string>
@@ -187,6 +198,8 @@
<string name="work_apps_paused_edu_accept" msgid="6377476824357318532">"Зрозуміло"</string>
<string name="work_apps_pause_btn_text" msgid="4669288269140620646">"Призупинити робочі додатки"</string>
<string name="work_apps_enable_btn_text" msgid="1736198302467317371">"Відновити"</string>
+ <!-- no translation found for work_scheduler_button_content_description (917340740986764967) -->
+ <skip />
<string name="developer_options_filter_hint" msgid="5896817443635989056">"Фільтр"</string>
<string name="remote_action_failed" msgid="1383965239183576790">"Не вдалося <xliff:g id="WHAT">%1$s</xliff:g>"</string>
<string name="private_space_label" msgid="2359721649407947001">"Приватний простір"</string>
diff --git a/res/values-ur/strings.xml b/res/values-ur/strings.xml
index 9fb85b2..911a2d5 100644
--- a/res/values-ur/strings.xml
+++ b/res/values-ur/strings.xml
@@ -69,6 +69,12 @@
<string name="widget_category_note_taking" msgid="3469689394504266039">"نوٹ لکھنا"</string>
<string name="widget_add_button_label" msgid="2761267068711937179">"شامل کریں"</string>
<string name="widget_add_button_content_description" msgid="1810530016360039643">"<xliff:g id="WIDGET_NAME">%1$s</xliff:g> ویجیٹ شامل کریں"</string>
+ <!-- no translation found for widgets_list_expand_button_label (7912016136574932622) -->
+ <skip />
+ <!-- no translation found for widgets_list_expand_button_content_description (4600513860973450888) -->
+ <skip />
+ <!-- no translation found for widgets_list_expanded (7374857868788557730) -->
+ <skip />
<string name="reconfigurable_widget_education_tip" msgid="6336962690888067057">"ویجیٹ ترتیبات تبدیل کرنے کے لیے تھپتھپائیں"</string>
<string name="widget_reconfigure_button_content_description" msgid="8811472721881205250">"ویجیٹ ترتیبات تبدیل کریں"</string>
<string name="all_apps_search_bar_hint" msgid="1390553134053255246">"ایپس تلاش کریں"</string>
@@ -124,6 +130,10 @@
<string name="msg_disabled_by_admin" msgid="6898038085516271325">"آپ کے منتظم کی طرف سے غیر فعال کر دیا گیا"</string>
<string name="allow_rotation_title" msgid="7222049633713050106">"ہوم اسکرین گھمانے کی اجازت دیں"</string>
<string name="allow_rotation_desc" msgid="8662546029078692509">"جب فون گھمایا جاتا ہے"</string>
+ <!-- no translation found for landscape_mode_title (5138814555934843926) -->
+ <skip />
+ <!-- no translation found for landscape_mode_desc (7372569859592816793) -->
+ <skip />
<string name="notification_dots_title" msgid="9062440428204120317">"اطلاعاتی ڈاٹس"</string>
<string name="notification_dots_desc_on" msgid="1679848116452218908">"آن ہے"</string>
<string name="notification_dots_desc_off" msgid="1760796511504341095">"آف ہے"</string>
@@ -142,7 +152,8 @@
<string name="app_installing_title" msgid="5864044122733792085">"<xliff:g id="NAME">%1$s</xliff:g> انسٹال کی جا رہی ہے، <xliff:g id="PROGRESS">%2$s</xliff:g> مکمل ہو گئی"</string>
<string name="app_downloading_title" msgid="8336702962104482644">"<xliff:g id="NAME">%1$s</xliff:g> ڈاؤن لوڈ ہو رہا ہے، <xliff:g id="PROGRESS">%2$s</xliff:g> مکمل ہو گیا"</string>
<string name="app_waiting_download_title" msgid="7053938513995617849">"<xliff:g id="NAME">%1$s</xliff:g> انسٹال ہونے کا انتظار کر رہی ہے"</string>
- <string name="app_archived_title" msgid="7717956158562544081">"<xliff:g id="NAME">%1$s</xliff:g> کو آرکائیو کر لیا گیا ہے۔ ڈاؤن لوڈ اور بحال کرنے کیلئے تھپتھپائیں۔"</string>
+ <string name="app_archived_title" msgid="4548283110222420708">"<xliff:g id="NAME">%1$s</xliff:g> کو آرکائیو کر لیا گیا ہے۔"</string>
+ <string name="app_unarchiving_action" msgid="5736107006413929484">"ڈاؤن لوڈ کریں اور بحال کریں"</string>
<string name="dialog_update_title" msgid="114234265740994042">"ایپ کی اپ ڈیٹ درکار ہے"</string>
<string name="dialog_update_message" msgid="4176784553982226114">"اس آئیکن کیلئے ایپ کو اپ ڈیٹ نہیں کیا گیا ہے۔ آپ اس شارٹ کٹ کو دوبارہ فعال کرنے کے لیے دستی طور پر اپ ڈیٹ کر سکتے ہیں، یا آئیکن کو ہٹا سکتے ہیں۔"</string>
<string name="dialog_update" msgid="2178028071796141234">"اپ ڈیٹ کریں"</string>
@@ -187,6 +198,8 @@
<string name="work_apps_paused_edu_accept" msgid="6377476824357318532">"سمجھ آ گئی"</string>
<string name="work_apps_pause_btn_text" msgid="4669288269140620646">"ورک ایپس موقوف کریں"</string>
<string name="work_apps_enable_btn_text" msgid="1736198302467317371">"چلائیں"</string>
+ <!-- no translation found for work_scheduler_button_content_description (917340740986764967) -->
+ <skip />
<string name="developer_options_filter_hint" msgid="5896817443635989056">"فلٹر"</string>
<string name="remote_action_failed" msgid="1383965239183576790">"ناکام ہو گيا: <xliff:g id="WHAT">%1$s</xliff:g>"</string>
<string name="private_space_label" msgid="2359721649407947001">"نجی اسپیس"</string>
diff --git a/res/values-uz/strings.xml b/res/values-uz/strings.xml
index 83cabc9..aacb35f 100644
--- a/res/values-uz/strings.xml
+++ b/res/values-uz/strings.xml
@@ -69,6 +69,12 @@
<string name="widget_category_note_taking" msgid="3469689394504266039">"Qayd olish"</string>
<string name="widget_add_button_label" msgid="2761267068711937179">"Chiqarish"</string>
<string name="widget_add_button_content_description" msgid="1810530016360039643">"<xliff:g id="WIDGET_NAME">%1$s</xliff:g> vidjetini chiqarish"</string>
+ <!-- no translation found for widgets_list_expand_button_label (7912016136574932622) -->
+ <skip />
+ <!-- no translation found for widgets_list_expand_button_content_description (4600513860973450888) -->
+ <skip />
+ <!-- no translation found for widgets_list_expanded (7374857868788557730) -->
+ <skip />
<string name="reconfigurable_widget_education_tip" msgid="6336962690888067057">"Vidjet sozlamalarini oʻzgartirish uchun bosing"</string>
<string name="widget_reconfigure_button_content_description" msgid="8811472721881205250">"Vidjet sozlamalarini oʻzgartirish"</string>
<string name="all_apps_search_bar_hint" msgid="1390553134053255246">"Ilovalarni qidirish"</string>
@@ -124,6 +130,10 @@
<string name="msg_disabled_by_admin" msgid="6898038085516271325">"Administrator tomonidan o‘chirilgan"</string>
<string name="allow_rotation_title" msgid="7222049633713050106">"Bosh ekranni burishga ruxsat"</string>
<string name="allow_rotation_desc" msgid="8662546029078692509">"Telefon burilganda"</string>
+ <!-- no translation found for landscape_mode_title (5138814555934843926) -->
+ <skip />
+ <!-- no translation found for landscape_mode_desc (7372569859592816793) -->
+ <skip />
<string name="notification_dots_title" msgid="9062440428204120317">"Bildirishnoma belgilari"</string>
<string name="notification_dots_desc_on" msgid="1679848116452218908">"Yoniq"</string>
<string name="notification_dots_desc_off" msgid="1760796511504341095">"Oʻchiq"</string>
@@ -142,7 +152,8 @@
<string name="app_installing_title" msgid="5864044122733792085">"<xliff:g id="NAME">%1$s</xliff:g> oʻrnatlmoqda, <xliff:g id="PROGRESS">%2$s</xliff:g> yakunlandi"</string>
<string name="app_downloading_title" msgid="8336702962104482644">"<xliff:g id="NAME">%1$s</xliff:g> yuklab olinmoqda, <xliff:g id="PROGRESS">%2$s</xliff:g> bajarildi"</string>
<string name="app_waiting_download_title" msgid="7053938513995617849">"<xliff:g id="NAME">%1$s</xliff:g> ilovasi o‘rnatilishi kutilmoqda"</string>
- <string name="app_archived_title" msgid="7717956158562544081">"<xliff:g id="NAME">%1$s</xliff:g> arxivlangan. Yuklab olish va tiklash uchun bosing."</string>
+ <string name="app_archived_title" msgid="4548283110222420708">"<xliff:g id="NAME">%1$s</xliff:g> arxivlangan."</string>
+ <string name="app_unarchiving_action" msgid="5736107006413929484">"yuklab olish va tiklash"</string>
<string name="dialog_update_title" msgid="114234265740994042">"Ilovani yangilash zarur"</string>
<string name="dialog_update_message" msgid="4176784553982226114">"Bu belgi uchun ilova yangilanmagan. Ushbu yorliqni qayta yoqish uchun oddiy usulda yangilashingiz yoki belgini olib tashlashingiz mumkin."</string>
<string name="dialog_update" msgid="2178028071796141234">"Yangilash"</string>
@@ -187,6 +198,8 @@
<string name="work_apps_paused_edu_accept" msgid="6377476824357318532">"OK"</string>
<string name="work_apps_pause_btn_text" msgid="4669288269140620646">"Ishga oid ilovalarni pauza qilish"</string>
<string name="work_apps_enable_btn_text" msgid="1736198302467317371">"Pauzadan chiqarish"</string>
+ <!-- no translation found for work_scheduler_button_content_description (917340740986764967) -->
+ <skip />
<string name="developer_options_filter_hint" msgid="5896817443635989056">"Saralash"</string>
<string name="remote_action_failed" msgid="1383965239183576790">"Xato: <xliff:g id="WHAT">%1$s</xliff:g>"</string>
<string name="private_space_label" msgid="2359721649407947001">"Shaxsiy xona"</string>
diff --git a/res/values-v31/colors.xml b/res/values-v31/colors.xml
index a5cdfc7..d74e308 100644
--- a/res/values-v31/colors.xml
+++ b/res/values-v31/colors.xml
@@ -104,11 +104,6 @@
<color name="widget_picker_add_button_text_color_light">
@android:color/system_accent1_0</color>
- <color name="work_fab_bg_color">
- @android:color/system_accent1_200</color>
- <color name="work_fab_icon_color">
- @android:color/system_accent1_900</color>
-
<color name="overview_foreground_scrim_color">@android:color/system_neutral1_1000</color>
<color name="material_color_on_surface">@android:color/system_neutral1_900</color>
diff --git a/res/values-vi/strings.xml b/res/values-vi/strings.xml
index d67f661..cea93da 100644
--- a/res/values-vi/strings.xml
+++ b/res/values-vi/strings.xml
@@ -69,6 +69,12 @@
<string name="widget_category_note_taking" msgid="3469689394504266039">"Ghi chú"</string>
<string name="widget_add_button_label" msgid="2761267068711937179">"Thêm"</string>
<string name="widget_add_button_content_description" msgid="1810530016360039643">"Thêm tiện ích <xliff:g id="WIDGET_NAME">%1$s</xliff:g>"</string>
+ <!-- no translation found for widgets_list_expand_button_label (7912016136574932622) -->
+ <skip />
+ <!-- no translation found for widgets_list_expand_button_content_description (4600513860973450888) -->
+ <skip />
+ <!-- no translation found for widgets_list_expanded (7374857868788557730) -->
+ <skip />
<string name="reconfigurable_widget_education_tip" msgid="6336962690888067057">"Nhấn để thay đổi chế độ cài đặt tiện ích"</string>
<string name="widget_reconfigure_button_content_description" msgid="8811472721881205250">"Thay đổi chế độ cài đặt tiện ích"</string>
<string name="all_apps_search_bar_hint" msgid="1390553134053255246">"Tìm kiếm ứng dụng"</string>
@@ -124,6 +130,10 @@
<string name="msg_disabled_by_admin" msgid="6898038085516271325">"Bị tắt bởi quản trị viên của bạn"</string>
<string name="allow_rotation_title" msgid="7222049633713050106">"Cho phép xoay màn hình chính"</string>
<string name="allow_rotation_desc" msgid="8662546029078692509">"Khi xoay điện thoại"</string>
+ <!-- no translation found for landscape_mode_title (5138814555934843926) -->
+ <skip />
+ <!-- no translation found for landscape_mode_desc (7372569859592816793) -->
+ <skip />
<string name="notification_dots_title" msgid="9062440428204120317">"Dấu chấm thông báo"</string>
<string name="notification_dots_desc_on" msgid="1679848116452218908">"Đang bật"</string>
<string name="notification_dots_desc_off" msgid="1760796511504341095">"Tắt"</string>
@@ -142,7 +152,8 @@
<string name="app_installing_title" msgid="5864044122733792085">"Đang cài đặt <xliff:g id="NAME">%1$s</xliff:g>, hoàn tất <xliff:g id="PROGRESS">%2$s</xliff:g>"</string>
<string name="app_downloading_title" msgid="8336702962104482644">"Đang tải xuống <xliff:g id="NAME">%1$s</xliff:g>, <xliff:g id="PROGRESS">%2$s</xliff:g> hoàn tất"</string>
<string name="app_waiting_download_title" msgid="7053938513995617849">"Đang chờ cài đặt <xliff:g id="NAME">%1$s</xliff:g>"</string>
- <string name="app_archived_title" msgid="7717956158562544081">"<xliff:g id="NAME">%1$s</xliff:g> đã được lưu trữ. Hãy nhấn để tải xuống và khôi phục."</string>
+ <string name="app_archived_title" msgid="4548283110222420708">"<xliff:g id="NAME">%1$s</xliff:g> đã được lưu trữ."</string>
+ <string name="app_unarchiving_action" msgid="5736107006413929484">"tải xuống và khôi phục"</string>
<string name="dialog_update_title" msgid="114234265740994042">"Cần cập nhật ứng dụng"</string>
<string name="dialog_update_message" msgid="4176784553982226114">"Ứng dụng cho biểu tượng này chưa được cập nhật. Bạn có thể cập nhật theo cách thủ công để bật lại phím tắt này hoặc xóa biểu tượng."</string>
<string name="dialog_update" msgid="2178028071796141234">"Cập nhật"</string>
@@ -187,6 +198,8 @@
<string name="work_apps_paused_edu_accept" msgid="6377476824357318532">"Tôi hiểu"</string>
<string name="work_apps_pause_btn_text" msgid="4669288269140620646">"Tạm dừng các ứng dụng công việc"</string>
<string name="work_apps_enable_btn_text" msgid="1736198302467317371">"Bỏ tạm dừng"</string>
+ <!-- no translation found for work_scheduler_button_content_description (917340740986764967) -->
+ <skip />
<string name="developer_options_filter_hint" msgid="5896817443635989056">"Bộ lọc"</string>
<string name="remote_action_failed" msgid="1383965239183576790">"Không thực hiện được thao tác: <xliff:g id="WHAT">%1$s</xliff:g>"</string>
<string name="private_space_label" msgid="2359721649407947001">"Không gian riêng tư"</string>
diff --git a/res/values-zh-rCN/strings.xml b/res/values-zh-rCN/strings.xml
index 1097e57..9efd6c3 100644
--- a/res/values-zh-rCN/strings.xml
+++ b/res/values-zh-rCN/strings.xml
@@ -69,6 +69,12 @@
<string name="widget_category_note_taking" msgid="3469689394504266039">"记事"</string>
<string name="widget_add_button_label" msgid="2761267068711937179">"添加"</string>
<string name="widget_add_button_content_description" msgid="1810530016360039643">"添加“<xliff:g id="WIDGET_NAME">%1$s</xliff:g>”微件"</string>
+ <!-- no translation found for widgets_list_expand_button_label (7912016136574932622) -->
+ <skip />
+ <!-- no translation found for widgets_list_expand_button_content_description (4600513860973450888) -->
+ <skip />
+ <!-- no translation found for widgets_list_expanded (7374857868788557730) -->
+ <skip />
<string name="reconfigurable_widget_education_tip" msgid="6336962690888067057">"点按即可更改微件设置"</string>
<string name="widget_reconfigure_button_content_description" msgid="8811472721881205250">"更改微件设置"</string>
<string name="all_apps_search_bar_hint" msgid="1390553134053255246">"搜索应用"</string>
@@ -124,6 +130,10 @@
<string name="msg_disabled_by_admin" msgid="6898038085516271325">"已被您的管理员停用"</string>
<string name="allow_rotation_title" msgid="7222049633713050106">"允许旋转主屏幕"</string>
<string name="allow_rotation_desc" msgid="8662546029078692509">"手机旋转时"</string>
+ <!-- no translation found for landscape_mode_title (5138814555934843926) -->
+ <skip />
+ <!-- no translation found for landscape_mode_desc (7372569859592816793) -->
+ <skip />
<string name="notification_dots_title" msgid="9062440428204120317">"通知圆点"</string>
<string name="notification_dots_desc_on" msgid="1679848116452218908">"已开启"</string>
<string name="notification_dots_desc_off" msgid="1760796511504341095">"已关闭"</string>
@@ -142,7 +152,8 @@
<string name="app_installing_title" msgid="5864044122733792085">"正在安装<xliff:g id="NAME">%1$s</xliff:g>,已完成 <xliff:g id="PROGRESS">%2$s</xliff:g>"</string>
<string name="app_downloading_title" msgid="8336702962104482644">"正在下载<xliff:g id="NAME">%1$s</xliff:g>,已完成 <xliff:g id="PROGRESS">%2$s</xliff:g>"</string>
<string name="app_waiting_download_title" msgid="7053938513995617849">"<xliff:g id="NAME">%1$s</xliff:g>正在等待安装"</string>
- <string name="app_archived_title" msgid="7717956158562544081">"已归档“<xliff:g id="NAME">%1$s</xliff:g>”。点按即可进行下载并恢复。"</string>
+ <string name="app_archived_title" msgid="4548283110222420708">"已归档“<xliff:g id="NAME">%1$s</xliff:g>”。"</string>
+ <string name="app_unarchiving_action" msgid="5736107006413929484">"下载并恢复"</string>
<string name="dialog_update_title" msgid="114234265740994042">"需要更新应用"</string>
<string name="dialog_update_message" msgid="4176784553982226114">"此图标对应的应用未更新。您可以手动更新以重新启用该快捷方式,或者移除此图标。"</string>
<string name="dialog_update" msgid="2178028071796141234">"更新"</string>
@@ -187,6 +198,8 @@
<string name="work_apps_paused_edu_accept" msgid="6377476824357318532">"知道了"</string>
<string name="work_apps_pause_btn_text" msgid="4669288269140620646">"暂停工作应用"</string>
<string name="work_apps_enable_btn_text" msgid="1736198302467317371">"取消暂停"</string>
+ <!-- no translation found for work_scheduler_button_content_description (917340740986764967) -->
+ <skip />
<string name="developer_options_filter_hint" msgid="5896817443635989056">"过滤器"</string>
<string name="remote_action_failed" msgid="1383965239183576790">"失败:<xliff:g id="WHAT">%1$s</xliff:g>"</string>
<string name="private_space_label" msgid="2359721649407947001">"私密空间"</string>
diff --git a/res/values-zh-rHK/strings.xml b/res/values-zh-rHK/strings.xml
index 6471a9a..c944240 100644
--- a/res/values-zh-rHK/strings.xml
+++ b/res/values-zh-rHK/strings.xml
@@ -69,6 +69,12 @@
<string name="widget_category_note_taking" msgid="3469689394504266039">"做筆記"</string>
<string name="widget_add_button_label" msgid="2761267068711937179">"新增"</string>
<string name="widget_add_button_content_description" msgid="1810530016360039643">"加<xliff:g id="WIDGET_NAME">%1$s</xliff:g>小工具"</string>
+ <!-- no translation found for widgets_list_expand_button_label (7912016136574932622) -->
+ <skip />
+ <!-- no translation found for widgets_list_expand_button_content_description (4600513860973450888) -->
+ <skip />
+ <!-- no translation found for widgets_list_expanded (7374857868788557730) -->
+ <skip />
<string name="reconfigurable_widget_education_tip" msgid="6336962690888067057">"輕按即可變更小工具設定"</string>
<string name="widget_reconfigure_button_content_description" msgid="8811472721881205250">"變更小工具設定"</string>
<string name="all_apps_search_bar_hint" msgid="1390553134053255246">"搜尋應用程式"</string>
@@ -124,6 +130,10 @@
<string name="msg_disabled_by_admin" msgid="6898038085516271325">"已由你的管理員停用"</string>
<string name="allow_rotation_title" msgid="7222049633713050106">"允許旋轉主畫面"</string>
<string name="allow_rotation_desc" msgid="8662546029078692509">"隨手機旋轉"</string>
+ <!-- no translation found for landscape_mode_title (5138814555934843926) -->
+ <skip />
+ <!-- no translation found for landscape_mode_desc (7372569859592816793) -->
+ <skip />
<string name="notification_dots_title" msgid="9062440428204120317">"通知圓點"</string>
<string name="notification_dots_desc_on" msgid="1679848116452218908">"開啟"</string>
<string name="notification_dots_desc_off" msgid="1760796511504341095">"關閉"</string>
@@ -142,7 +152,8 @@
<string name="app_installing_title" msgid="5864044122733792085">"正在安裝「<xliff:g id="NAME">%1$s</xliff:g>」(已完成 <xliff:g id="PROGRESS">%2$s</xliff:g>)"</string>
<string name="app_downloading_title" msgid="8336702962104482644">"正在下載 <xliff:g id="NAME">%1$s</xliff:g>,已完成 <xliff:g id="PROGRESS">%2$s</xliff:g>"</string>
<string name="app_waiting_download_title" msgid="7053938513995617849">"正在等待安裝 <xliff:g id="NAME">%1$s</xliff:g>"</string>
- <string name="app_archived_title" msgid="7717956158562544081">"「<xliff:g id="NAME">%1$s</xliff:g>」已封存。輕按即可下載並還原。"</string>
+ <string name="app_archived_title" msgid="4548283110222420708">"「<xliff:g id="NAME">%1$s</xliff:g>」已封存。"</string>
+ <string name="app_unarchiving_action" msgid="5736107006413929484">"下載及還原"</string>
<string name="dialog_update_title" msgid="114234265740994042">"必須更新應用程式"</string>
<string name="dialog_update_message" msgid="4176784553982226114">"你尚未更新這個圖示代表的應用程式。你可以手動更新以重新啟用此快速鍵,或者移除圖示。"</string>
<string name="dialog_update" msgid="2178028071796141234">"更新"</string>
@@ -187,6 +198,8 @@
<string name="work_apps_paused_edu_accept" msgid="6377476824357318532">"知道了"</string>
<string name="work_apps_pause_btn_text" msgid="4669288269140620646">"暫停工作應用程式"</string>
<string name="work_apps_enable_btn_text" msgid="1736198302467317371">"取消暫停"</string>
+ <!-- no translation found for work_scheduler_button_content_description (917340740986764967) -->
+ <skip />
<string name="developer_options_filter_hint" msgid="5896817443635989056">"篩選器"</string>
<string name="remote_action_failed" msgid="1383965239183576790">"操作失敗:<xliff:g id="WHAT">%1$s</xliff:g>"</string>
<string name="private_space_label" msgid="2359721649407947001">"私人空間"</string>
diff --git a/res/values-zh-rTW/strings.xml b/res/values-zh-rTW/strings.xml
index 0a9ffa2..476c0e5 100644
--- a/res/values-zh-rTW/strings.xml
+++ b/res/values-zh-rTW/strings.xml
@@ -69,6 +69,12 @@
<string name="widget_category_note_taking" msgid="3469689394504266039">"做筆記"</string>
<string name="widget_add_button_label" msgid="2761267068711937179">"新增"</string>
<string name="widget_add_button_content_description" msgid="1810530016360039643">"新增「<xliff:g id="WIDGET_NAME">%1$s</xliff:g>」小工具"</string>
+ <!-- no translation found for widgets_list_expand_button_label (7912016136574932622) -->
+ <skip />
+ <!-- no translation found for widgets_list_expand_button_content_description (4600513860973450888) -->
+ <skip />
+ <!-- no translation found for widgets_list_expanded (7374857868788557730) -->
+ <skip />
<string name="reconfigurable_widget_education_tip" msgid="6336962690888067057">"輕觸即可變更小工具設定"</string>
<string name="widget_reconfigure_button_content_description" msgid="8811472721881205250">"變更小工具設定"</string>
<string name="all_apps_search_bar_hint" msgid="1390553134053255246">"搜尋應用程式"</string>
@@ -124,6 +130,10 @@
<string name="msg_disabled_by_admin" msgid="6898038085516271325">"已由你的管理員停用"</string>
<string name="allow_rotation_title" msgid="7222049633713050106">"允許旋轉主畫面"</string>
<string name="allow_rotation_desc" msgid="8662546029078692509">"當手機旋轉時"</string>
+ <!-- no translation found for landscape_mode_title (5138814555934843926) -->
+ <skip />
+ <!-- no translation found for landscape_mode_desc (7372569859592816793) -->
+ <skip />
<string name="notification_dots_title" msgid="9062440428204120317">"通知圓點"</string>
<string name="notification_dots_desc_on" msgid="1679848116452218908">"開啟"</string>
<string name="notification_dots_desc_off" msgid="1760796511504341095">"關閉"</string>
@@ -142,7 +152,8 @@
<string name="app_installing_title" msgid="5864044122733792085">"正在安裝「<xliff:g id="NAME">%1$s</xliff:g>」(已完成 <xliff:g id="PROGRESS">%2$s</xliff:g>)"</string>
<string name="app_downloading_title" msgid="8336702962104482644">"正在下載「<xliff:g id="NAME">%1$s</xliff:g>」,已完成 <xliff:g id="PROGRESS">%2$s</xliff:g>"</string>
<string name="app_waiting_download_title" msgid="7053938513995617849">"正在等待安裝「<xliff:g id="NAME">%1$s</xliff:g>」"</string>
- <string name="app_archived_title" msgid="7717956158562544081">"「<xliff:g id="NAME">%1$s</xliff:g>」已封存。輕觸即可下載並還原。"</string>
+ <string name="app_archived_title" msgid="4548283110222420708">"「<xliff:g id="NAME">%1$s</xliff:g>」已封存。"</string>
+ <string name="app_unarchiving_action" msgid="5736107006413929484">"下載及還原"</string>
<string name="dialog_update_title" msgid="114234265740994042">"必須更新應用程式"</string>
<string name="dialog_update_message" msgid="4176784553982226114">"這個圖示代表的應用程式未更新。手動更新即可重新啟用這個捷徑,你也可以移除圖示。"</string>
<string name="dialog_update" msgid="2178028071796141234">"更新"</string>
@@ -187,6 +198,8 @@
<string name="work_apps_paused_edu_accept" msgid="6377476824357318532">"我知道了"</string>
<string name="work_apps_pause_btn_text" msgid="4669288269140620646">"暫停工作應用程式"</string>
<string name="work_apps_enable_btn_text" msgid="1736198302467317371">"取消暫停"</string>
+ <!-- no translation found for work_scheduler_button_content_description (917340740986764967) -->
+ <skip />
<string name="developer_options_filter_hint" msgid="5896817443635989056">"篩選器"</string>
<string name="remote_action_failed" msgid="1383965239183576790">"失敗:<xliff:g id="WHAT">%1$s</xliff:g>"</string>
<string name="private_space_label" msgid="2359721649407947001">"私人空間"</string>
diff --git a/res/values-zu/strings.xml b/res/values-zu/strings.xml
index 59c99c4..623454b 100644
--- a/res/values-zu/strings.xml
+++ b/res/values-zu/strings.xml
@@ -69,6 +69,12 @@
<string name="widget_category_note_taking" msgid="3469689394504266039">"Ukuthatha amanothi"</string>
<string name="widget_add_button_label" msgid="2761267068711937179">"Engeza"</string>
<string name="widget_add_button_content_description" msgid="1810530016360039643">"Engeza iwijethi ye-<xliff:g id="WIDGET_NAME">%1$s</xliff:g>"</string>
+ <!-- no translation found for widgets_list_expand_button_label (7912016136574932622) -->
+ <skip />
+ <!-- no translation found for widgets_list_expand_button_content_description (4600513860973450888) -->
+ <skip />
+ <!-- no translation found for widgets_list_expanded (7374857868788557730) -->
+ <skip />
<string name="reconfigurable_widget_education_tip" msgid="6336962690888067057">"Thepha ukuze ushintshe amasethingi ewijethi"</string>
<string name="widget_reconfigure_button_content_description" msgid="8811472721881205250">"Shintsha amasethingi ewijethi"</string>
<string name="all_apps_search_bar_hint" msgid="1390553134053255246">"Sesha izinhlelo zokusebenza"</string>
@@ -124,6 +130,10 @@
<string name="msg_disabled_by_admin" msgid="6898038085516271325">"Kukhutshazwe umlawuli wakho"</string>
<string name="allow_rotation_title" msgid="7222049633713050106">"Vumela ukuzungezisa kwesikrini sasekhaya"</string>
<string name="allow_rotation_desc" msgid="8662546029078692509">"Uma ifoni iphendukiswa"</string>
+ <!-- no translation found for landscape_mode_title (5138814555934843926) -->
+ <skip />
+ <!-- no translation found for landscape_mode_desc (7372569859592816793) -->
+ <skip />
<string name="notification_dots_title" msgid="9062440428204120317">"Amacashazi esaziso"</string>
<string name="notification_dots_desc_on" msgid="1679848116452218908">"Vuliwe"</string>
<string name="notification_dots_desc_off" msgid="1760796511504341095">"Valiwe"</string>
@@ -142,7 +152,8 @@
<string name="app_installing_title" msgid="5864044122733792085">"I-<xliff:g id="NAME">%1$s</xliff:g> iyafakwa, seyiqede <xliff:g id="PROGRESS">%2$s</xliff:g>"</string>
<string name="app_downloading_title" msgid="8336702962104482644">"I-<xliff:g id="NAME">%1$s</xliff:g> iyalandwa, <xliff:g id="PROGRESS">%2$s</xliff:g> kuqediwe"</string>
<string name="app_waiting_download_title" msgid="7053938513995617849">"<xliff:g id="NAME">%1$s</xliff:g> ilinde ukufakwa"</string>
- <string name="app_archived_title" msgid="7717956158562544081">"Okuthi <xliff:g id="NAME">%1$s</xliff:g> kufakwe kungobo yomlando. Thepha ukuze udawunilode futhi ubuyisele."</string>
+ <string name="app_archived_title" msgid="4548283110222420708">"Okuthi <xliff:g id="NAME">%1$s</xliff:g> kufakwe kungobo yomlando."</string>
+ <string name="app_unarchiving_action" msgid="5736107006413929484">"dawuniloda uphinde ubuyisele"</string>
<string name="dialog_update_title" msgid="114234265740994042">"Kudingeka isibuyekezo se-app"</string>
<string name="dialog_update_message" msgid="4176784553982226114">"I-app yalesi sithonjana ibuyekeziwe. Ungabuyekeza mathupha ukuze uphinde unike amandla lesi sinqamuleli, noma ususe isithonjana."</string>
<string name="dialog_update" msgid="2178028071796141234">"Vuselela"</string>
@@ -187,6 +198,8 @@
<string name="work_apps_paused_edu_accept" msgid="6377476824357318532">"Ngiyezwa"</string>
<string name="work_apps_pause_btn_text" msgid="4669288269140620646">"Misa ama-app omsebenzi"</string>
<string name="work_apps_enable_btn_text" msgid="1736198302467317371">"Susa ukumisa"</string>
+ <!-- no translation found for work_scheduler_button_content_description (917340740986764967) -->
+ <skip />
<string name="developer_options_filter_hint" msgid="5896817443635989056">"Hlunga"</string>
<string name="remote_action_failed" msgid="1383965239183576790">"Yehlulekile: <xliff:g id="WHAT">%1$s</xliff:g>"</string>
<string name="private_space_label" msgid="2359721649407947001">"Isikhala esiyimfihlo"</string>
diff --git a/res/values/attrs.xml b/res/values/attrs.xml
index 16ea0cd..77d789f 100644
--- a/res/values/attrs.xml
+++ b/res/values/attrs.xml
@@ -126,6 +126,8 @@
<attr name="widgetPickerCollapseHandleColor" format="color"/>
<attr name="widgetPickerAddButtonBackgroundColor" format="color"/>
<attr name="widgetPickerAddButtonTextColor" format="color"/>
+ <attr name="widgetPickerExpandButtonBackgroundColor" format="color"/>
+ <attr name="widgetPickerExpandButtonTextColor" format="color"/>
<attr name="widgetCellTitleColor" format="color" />
<attr name="widgetCellSubtitleColor" format="color" />
@@ -213,6 +215,8 @@
<attr name="minDeviceHeightPx" format="float"/>
<attr name="numRowsNew" format="integer"/>
<attr name="dbFile" />
+ <attr name="defaultLayoutId"/>
+ <attr name="demoModeLayoutId"/>
</declare-styleable>
<declare-styleable name="GridDisplayOption">
@@ -268,6 +272,9 @@
defaults to @dimen/taskbar_button_margin_default -->
<attr name="inlineNavButtonsEndSpacing" format="reference" />
+ <!-- Grid flips row and column count when rotating the device -->
+ <attr name="isDualGrid" format="boolean" />
+
<attr name="dbFile" format="string" />
<attr name="defaultLayoutId" format="reference" />
<attr name="demoModeLayoutId" format="reference" />
@@ -306,6 +313,9 @@
<!-- defaults to allAppsCellSpecsId, if not specified -->
<attr name="allAppsCellSpecsTwoPanelId" format="reference" />
+ <!-- defaults to false, if not specified -->
+ <attr name="isFixedLandscape" format="boolean" />
+
<!-- By default all categories are enabled -->
<attr name="deviceCategory" format="integer">
<!-- Enable on phone only -->
diff --git a/res/values/colors.xml b/res/values/colors.xml
index 1eca88d..4549b86 100644
--- a/res/values/colors.xml
+++ b/res/values/colors.xml
@@ -98,8 +98,6 @@
<color name="preload_icon_background_color_dark">#40484D</color>
<color name="work_turn_on_stroke">?android:attr/colorAccent</color>
- <color name="work_fab_bg_color">#A8C7FA</color>
- <color name="work_fab_icon_color">#041E49</color>
<color name="widget_picker_primary_surface_color_light">#EFEDED</color>
<color name="widget_picker_secondary_surface_color_light">#FAF9F8</color>
@@ -119,6 +117,12 @@
<color name="widget_picker_collapse_handle_color_light">#C4C7C5</color>
<color name="widget_picker_add_button_background_color_light">#0B57D0</color>
<color name="widget_picker_add_button_text_color_light">#0B57D0</color>
+ <color name="widget_picker_expand_button_background_color_light">
+ @color/widget_picker_secondary_surface_color_light
+ </color>
+ <color name="widget_picker_expand_button_text_color_light">
+ @color/widget_picker_header_app_title_color_light
+ </color>
<color name="widget_cell_title_color_light">@color/system_on_surface_light</color>
<color name="widget_cell_subtitle_color_light">@color/system_on_surface_variant_light</color>
@@ -140,6 +144,12 @@
<color name="widget_picker_collapse_handle_color_dark">#444746</color>
<color name="widget_picker_add_button_background_color_dark">#062E6F</color>
<color name="widget_picker_add_button_text_color_dark">#FFFFFF</color>
+ <color name="widget_picker_expand_button_background_color_dark">
+ @color/widget_picker_secondary_surface_color_dark
+ </color>
+ <color name="widget_picker_expand_button_text_color_dark">
+ @color/widget_picker_header_app_title_color_dark
+ </color>
<color name="widget_cell_title_color_dark">@color/system_on_surface_dark</color>
<color name="widget_cell_subtitle_color_dark">@color/system_on_surface_variant_dark</color>
diff --git a/res/values/config.xml b/res/values/config.xml
index b0b7aa2..f6f3c95 100644
--- a/res/values/config.xml
+++ b/res/values/config.xml
@@ -76,7 +76,6 @@
<string name="taskbar_view_callbacks_factory_class" translatable="false"></string>
<string name="launcher_restore_event_logger_class" translatable="false"></string>
<string name="taskbar_edu_tooltip_controller_class" translatable="false"></string>
- <string name="contextual_edu_manager_class" translatable="false"></string>
<!-- Used for determining category of a widget presented in widget recommendations. -->
<string name="widget_recommendation_category_provider_class" translatable="false"></string>
@@ -85,6 +84,9 @@
<string name="local_colors_extraction_class" translatable="false"></string>
<string name="search_session_manager_class" translatable="false"></string>
+ <!-- Filters for widgets displayed in the widget picker -->
+ <string name="widgets_filter_data_provider_class" translatable="false"></string>
+
<!-- Scalable Grid configuration -->
<!-- This is a float because it is converted to dp later in DeviceProfile -->
<dimen name="hotseat_bar_bottom_space_default">48</dimen>
diff --git a/res/values/dimens.xml b/res/values/dimens.xml
index 037687d..c69778a 100644
--- a/res/values/dimens.xml
+++ b/res/values/dimens.xml
@@ -166,6 +166,9 @@
<dimen name="work_fab_margin">16dp</dimen>
<dimen name="work_fab_margin_bottom">20dp</dimen>
<dimen name="work_mode_fab_background_horizontal_padding">16dp</dimen>
+ <dimen name="work_scheduler_background_padding">16dp</dimen>
+ <dimen name="work_scheduler_bottom_margin">8dp</dimen>
+ <dimen name="work_scheduler_size">56dp</dimen>
<dimen name="work_profile_footer_padding">20dp</dimen>
<dimen name="work_edu_card_margin">16dp</dimen>
<dimen name="work_edu_card_radius">16dp</dimen>
@@ -225,8 +228,18 @@
<!-- Bottom margin for the search and recommended widgets container with work profile -->
<dimen name="search_and_recommended_widgets_container_small_bottom_margin">10dp</dimen>
+ <dimen name="widget_header_focus_ring_width">3dp</dimen>
+ <dimen name="widget_focus_ring_corner_radius">28dp</dimen>
+ <dimen name="widget_header_background_border">5dp</dimen>
+
<dimen name="widget_list_top_bottom_corner_radius">28dp</dimen>
<dimen name="widget_list_content_corner_radius">4dp</dimen>
+ <!-- Button that expands the widget apps list in the widget picker. -->
+ <dimen name="widgets_list_expand_button_drawable_padding">8dp</dimen>
+ <dimen name="widgets_list_expand_button_start_padding">16dp</dimen>
+ <dimen name="widgets_list_expand_button_end_padding">24dp</dimen>
+ <dimen name="widgets_list_expand_button_vertical_padding">16dp</dimen>
+ <dimen name="widgets_list_expand_button_top_margin">14dp</dimen>
<dimen name="widget_list_header_view_vertical_padding">20dp</dimen>
<dimen name="widget_list_entry_spacing">2dp</dimen>
diff --git a/res/values/id.xml b/res/values/id.xml
index 28496b5..67692d8 100644
--- a/res/values/id.xml
+++ b/res/values/id.xml
@@ -19,6 +19,7 @@
<item type="id" name="view_type_widgets_space" />
<item type="id" name="view_type_widgets_list" />
<item type="id" name="view_type_widgets_header" />
+ <item type="id" name="view_type_widgets_list_expand" />
<!-- Accessibility actions -->
<item type="id" name="action_remove" />
diff --git a/res/values/strings.xml b/res/values/strings.xml
index d918698..123e2b8 100644
--- a/res/values/strings.xml
+++ b/res/values/strings.xml
@@ -157,6 +157,12 @@
<!-- Accessibility content description for the button that adds a widget to the home screen. The
placeholder text is the widget name. [CHAR_LIMIT=none] -->
<string name="widget_add_button_content_description">Add <xliff:g id="widget_name" example="Calendar month view">%1$s</xliff:g> widget</string>
+ <!-- Text on the button that enables users to expand the widgets list to see all widget apps besides the default ones displayed. [CHAR_LIMIT=15] -->
+ <string name="widgets_list_expand_button_label">Show all</string>
+ <!-- Accessibility content description for the button that enables users to expand the widgets list to see all widget apps besides the default ones displayed. [CHAR_LIMIT=none] -->
+ <string name="widgets_list_expand_button_content_description">Show all widgets</string>
+ <!-- Accessibility announcement to indicate to the users that widgets list is now expanded -->
+ <string name="widgets_list_expanded">Showing all widgets</string>
<!-- Text on an educational tip on widget informing users that they can change widget settings.
[CHAR_LIMIT=NONE] -->
@@ -311,6 +317,12 @@
<string name="allow_rotation_title">Allow home screen rotation</string>
<!-- Text explaining when the home screen will get rotated. [CHAR LIMIT=100] -->
<string name="allow_rotation_desc">When phone is rotated</string>
+
+ <!-- Title for Landscape Mode setting. [CHAR LIMIT=50] -->
+ <string name="landscape_mode_title">Landscape mode</string>
+ <!-- [CHAR LIMIT=100] -->
+ <string name="landscape_mode_desc">Set phone into landscape mode</string>
+
<!-- Title for Notification dots setting. Tapping this will link to the system Notifications settings screen where the user can turn off notification dots globally. [CHAR LIMIT=50] -->
<string name="notification_dots_title">Notification dots</string>
<!-- Text to indicate that the system notification dots setting is on [CHAR LIMIT=100] -->
@@ -466,6 +478,8 @@
<string name="work_profile_edu_accept">Got it</string>
<!-- Info icon unicode for alpha scroller when work edu card is present -->
<string name="work_profile_edu_section" translatable="false">\u24D8</string>
+ <!-- Intent for work profiler scheduler -->
+ <string name="work_profile_scheduler_intent" translatable="false"/>
<!--- heading shown when user opens work apps tab while work apps are paused -->
<string name="work_apps_paused_title">Work apps are paused</string>
@@ -484,6 +498,8 @@
<string name="work_apps_pause_btn_text">Pause work apps</string>
<!-- button string shown enable work profile -->
<string name="work_apps_enable_btn_text">Unpause</string>
+ <!-- Label for the work profile scheduler button in the work profile screen. [CHAR_LIMIT=40] -->
+ <string name="work_scheduler_button_content_description">Work apps schedule</string>
<!-- A hint shown in launcher settings develop options filter box -->
<string name="developer_options_filter_hint">Filter</string>
diff --git a/res/values/styles.xml b/res/values/styles.xml
index 728c523..6d3579b 100644
--- a/res/values/styles.xml
+++ b/res/values/styles.xml
@@ -275,6 +275,12 @@
@color/widget_picker_add_button_background_color_light</item>
<item name="widgetPickerAddButtonTextColor">
@color/widget_picker_add_button_text_color_light</item>
+ <item name="widgetPickerExpandButtonBackgroundColor">
+ @color/widget_picker_expand_button_background_color_light
+ </item>
+ <item name="widgetPickerExpandButtonTextColor">
+ @color/widget_picker_expand_button_text_color_light
+ </item>
<item name="widgetCellTitleColor">
@color/widget_cell_title_color_light</item>
<item name="widgetCellSubtitleColor">
@@ -316,6 +322,12 @@
@color/widget_picker_add_button_background_color_dark</item>
<item name="widgetPickerAddButtonTextColor">
@color/widget_picker_add_button_text_color_dark</item>
+ <item name="widgetPickerExpandButtonBackgroundColor">
+ @color/widget_picker_expand_button_background_color_dark
+ </item>
+ <item name="widgetPickerExpandButtonTextColor">
+ @color/widget_picker_expand_button_text_color_dark
+ </item>
<item name="widgetCellTitleColor">
@color/widget_cell_title_color_dark</item>
<item name="widgetCellSubtitleColor">
diff --git a/res/xml/backupscheme.xml b/res/xml/backupscheme.xml
index 27fddc8..34b80b1 100644
--- a/res/xml/backupscheme.xml
+++ b/res/xml/backupscheme.xml
@@ -2,6 +2,7 @@
<full-backup-content xmlns:android="http://schemas.android.com/apk/res/android">
<include domain="database" path="launcher.db" />
+ <include domain="database" path="launcher_5_by_8.db" />
<include domain="database" path="launcher_6_by_5.db" />
<include domain="database" path="launcher_5_by_6.db" />
<include domain="database" path="launcher_4_by_6.db" />
@@ -9,6 +10,7 @@
<include domain="database" path="launcher_4_by_4.db" />
<include domain="database" path="launcher_3_by_3.db" />
<include domain="database" path="launcher_2_by_2.db" />
+ <include domain="database" path="launcher_7_by_3.db" />
<include domain="sharedpref" path="com.android.launcher3.prefs.xml" />
<include domain="file" path="downgrade_schema.json" />
diff --git a/res/xml/default_workspace_5x8.xml b/res/xml/default_workspace_5x8.xml
new file mode 100644
index 0000000..b078cfd
--- /dev/null
+++ b/res/xml/default_workspace_5x8.xml
@@ -0,0 +1,76 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2021 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.
+-->
+
+<favorites xmlns:launcher="http://schemas.android.com/apk/res-auto/com.android.launcher3">
+
+ <!-- Hotseat (We use the screen as the position of the item in the hotseat) -->
+ <!-- Mail Calendar Gallery Store Internet Camera -->
+ <resolve
+ launcher:container="-101"
+ launcher:screen="0"
+ launcher:x="0"
+ launcher:y="0" >
+ <favorite launcher:uri="#Intent;action=android.intent.action.MAIN;category=android.intent.category.APP_EMAIL;end" />
+ <favorite launcher:uri="mailto:" />
+ </resolve>
+
+ <resolve
+ launcher:container="-101"
+ launcher:screen="1"
+ launcher:x="1"
+ launcher:y="0" >
+ <favorite launcher:uri="#Intent;action=android.intent.action.MAIN;category=android.intent.category.APP_CALENDAR;end" />
+ </resolve>
+
+ <resolve
+ launcher:container="-101"
+ launcher:screen="2"
+ launcher:x="2"
+ launcher:y="0" >
+ <favorite launcher:uri="#Intent;action=android.intent.action.MAIN;category=android.intent.category.APP_GALLERY;end" />
+ <favorite launcher:uri="#Intent;type=images/*;end" />
+ </resolve>
+
+ <resolve
+ launcher:container="-101"
+ launcher:screen="3"
+ launcher:x="3"
+ launcher:y="0" >
+ <favorite launcher:uri="#Intent;action=android.intent.action.MAIN;category=android.intent.category.APP_MARKET;end" />
+ <favorite launcher:uri="market://details?id=com.android.launcher" />
+ </resolve>
+
+ <resolve
+ launcher:container="-101"
+ launcher:screen="4"
+ launcher:x="4"
+ launcher:y="0" >
+ <favorite
+ launcher:uri="#Intent;action=android.intent.action.MAIN;category=android.intent.category.APP_BROWSER;end" />
+ <favorite launcher:uri="http://www.example.com/" />
+ </resolve>
+
+ <!-- Resolve camera intent if GoogleCamera is not available e.g. on emulator -->
+ <resolve
+ launcher:container="-101"
+ launcher:screen="5"
+ launcher:x="5"
+ launcher:y="0" >
+ <favorite launcher:uri="#Intent;action=android.media.action.STILL_IMAGE_CAMERA;end" />
+ <favorite launcher:uri="#Intent;action=android.intent.action.CAMERA_BUTTON;end" />
+ </resolve>
+
+</favorites>
diff --git a/res/xml/paddings_5x8.xml b/res/xml/paddings_5x8.xml
new file mode 100644
index 0000000..afa70c5
--- /dev/null
+++ b/res/xml/paddings_5x8.xml
@@ -0,0 +1,45 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+ ~ Copyright (C) 2024 The Android Open Source Project
+ ~
+ ~ Licensed under the Apache License, Version 2.0 (the "License");
+ ~ you may not use this file except in compliance with the License.
+ ~ You may obtain a copy of the License at
+ ~
+ ~ http://www.apache.org/licenses/LICENSE-2.0
+ ~
+ ~ Unless required by applicable law or agreed to in writing, software
+ ~ distributed under the License is distributed on an "AS IS" BASIS,
+ ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ ~ See the License for the specific language governing permissions and
+ ~ limitations under the License.
+ -->
+
+<device-paddings xmlns:launcher="http://schemas.android.com/apk/res-auto" >
+
+ <device-padding
+ launcher:maxEmptySpace="100dp">
+ <workspaceTopPadding
+ launcher:a="0.31"
+ launcher:b="0"/>
+ <workspaceBottomPadding
+ launcher:a="0.69"
+ launcher:b="0"/>
+ <hotseatBottomPadding
+ launcher:a="0"
+ launcher:b="0"/>
+ </device-padding>
+
+ <device-padding
+ launcher:maxEmptySpace="9999dp">
+ <workspaceTopPadding
+ launcher:a="0.48"
+ launcher:b="0"/>
+ <workspaceBottomPadding
+ launcher:a="0.52"
+ launcher:b="0"/>
+ <hotseatBottomPadding
+ launcher:a="0"
+ launcher:b="0"/>
+ </device-padding>
+</device-paddings>
\ No newline at end of file
diff --git a/src/com/android/launcher3/DeviceProfile.java b/src/com/android/launcher3/DeviceProfile.java
index 4305703..78535a1 100644
--- a/src/com/android/launcher3/DeviceProfile.java
+++ b/src/com/android/launcher3/DeviceProfile.java
@@ -617,7 +617,7 @@
|| inv.inlineQsb[INDEX_TWO_PANEL_LANDSCAPE]
: inv.inlineQsb[INDEX_DEFAULT] || inv.inlineQsb[INDEX_LANDSCAPE])
&& hotseatQsbHeight > 0;
- isQsbInline = mIsScalableGrid && inv.inlineQsb[mTypeIndex] && canQsbInline;
+ isQsbInline = isQsbInline(inv);
areNavButtonsInline = isTaskbarPresent && !isGestureMode;
numShownHotseatIcons =
@@ -827,7 +827,7 @@
hotseatBorderSpace = cellLayoutBorderSpacePx.y;
}
- if (isTablet) {
+ if (shouldShowAllAppsOnSheet()) {
allAppsPadding.top = mInsets.top;
allAppsShiftRange = heightPx;
} else {
@@ -850,6 +850,24 @@
mDotRendererAllApps = createDotRenderer(context, allAppsIconSizePx, dotRendererCache);
}
+ /**
+ * Takes care of the logic that determines if we show a the QSB inline or not.
+ */
+ private boolean isQsbInline(InvariantDeviceProfile inv) {
+ // For foldable (two panel), we inline the qsb if we have the screen open and we are in
+ // either Landscape or Portrait. This cal also be disabled in the device_profile.xml
+ boolean twoPanelCanInline = inv.inlineQsb[INDEX_TWO_PANEL_PORTRAIT]
+ || inv.inlineQsb[INDEX_TWO_PANEL_LANDSCAPE];
+
+ // In tablets we inline in both orientations but only if we have enough space in the QSB
+ boolean tabletInlineQsb = inv.inlineQsb[INDEX_DEFAULT] || inv.inlineQsb[INDEX_LANDSCAPE];
+ boolean canQsbInline = isTwoPanels ? twoPanelCanInline : tabletInlineQsb;
+ canQsbInline = canQsbInline && hotseatQsbHeight > 0;
+
+ return (mIsScalableGrid && inv.inlineQsb[mTypeIndex] && canQsbInline)
+ || inv.isFixedLandscapeMode;
+ }
+
private static DotRenderer createDotRenderer(
@NonNull Context context, int size, @NonNull SparseArray<DotRenderer> cache) {
DotRenderer renderer = cache.get(size);
@@ -1516,6 +1534,11 @@
}
}
+ /** Whether All Apps should be presented on a bottom sheet. */
+ public boolean shouldShowAllAppsOnSheet() {
+ return isTablet || Flags.allAppsSheetForHandheld();
+ }
+
private void setupAllAppsStyle(Context context) {
TypedArray allAppsStyle = context.obtainStyledAttributes(
inv.allAppsStyle != INVALID_RESOURCE_HANDLE ? inv.allAppsStyle
@@ -1898,7 +1921,7 @@
hotseatBarPadding.set(mHotseatBarWorkspaceSpacePx, paddingTop,
mInsets.right + mHotseatBarEdgePaddingPx, paddingBottom);
}
- } else if (isTaskbarPresent) {
+ } else if (isTaskbarPresent || inv.isFixedLandscapeMode) {
// Center the QSB vertically with hotseat
int hotseatBarBottomPadding = getHotseatBarBottomPadding();
int hotseatBarTopPadding =
@@ -1917,6 +1940,13 @@
}
startSpacing += getAdditionalQsbSpace();
+ if (inv.isFixedLandscapeMode) {
+ endSpacing += workspacePadding.right + cellLayoutPaddingPx.right
+ + mInsets.right;
+ startSpacing += workspacePadding.left + cellLayoutPaddingPx.left
+ + mInsets.left;
+ }
+
hotseatBarPadding.top = hotseatBarTopPadding;
hotseatBarPadding.bottom = hotseatBarBottomPadding;
boolean isRtl = Utilities.isRtl(context.getResources());
@@ -2512,7 +2542,8 @@
throw new IllegalArgumentException("Window bounds not set");
}
if (mTransposeLayoutWithOrientation == null) {
- mTransposeLayoutWithOrientation = !mInfo.isTablet(mWindowBounds);
+ mTransposeLayoutWithOrientation =
+ !(mInfo.isTablet(mWindowBounds) || mInv.isFixedLandscapeMode);
}
if (mIsGestureMode == null) {
mIsGestureMode = mInfo.getNavigationMode().hasGestures;
diff --git a/src/com/android/launcher3/Hotseat.java b/src/com/android/launcher3/Hotseat.java
index 27602af..6468f74 100644
--- a/src/com/android/launcher3/Hotseat.java
+++ b/src/com/android/launcher3/Hotseat.java
@@ -186,18 +186,20 @@
*/
public void adjustForBubbleBar(boolean isBubbleBarVisible) {
DeviceProfile dp = mActivity.getDeviceProfile();
+ float adjustedBorderSpace = dp.getHotseatAdjustedBorderSpaceForBubbleBar(getContext());
+ boolean adjustmentRequired = Float.compare(adjustedBorderSpace, 0f) != 0;
ShortcutAndWidgetContainer icons = getShortcutsAndWidgets();
- AnimatorSet animatorSet = new AnimatorSet();
-
// update the translation provider for future layout passes of hotseat icons.
- if (isBubbleBarVisible) {
+ if (adjustmentRequired && isBubbleBarVisible) {
icons.setTranslationProvider(
cellX -> dp.getHotseatAdjustedTranslation(getContext(), cellX));
} else {
icons.setTranslationProvider(null);
}
+ if (!adjustmentRequired) return;
+ AnimatorSet animatorSet = new AnimatorSet();
for (int i = 0; i < icons.getChildCount(); i++) {
View child = icons.getChildAt(i);
float tx = isBubbleBarVisible ? dp.getHotseatAdjustedTranslation(getContext(), i) : 0;
diff --git a/src/com/android/launcher3/InvariantDeviceProfile.java b/src/com/android/launcher3/InvariantDeviceProfile.java
index 7acba75..04e4b57 100644
--- a/src/com/android/launcher3/InvariantDeviceProfile.java
+++ b/src/com/android/launcher3/InvariantDeviceProfile.java
@@ -16,6 +16,7 @@
package com.android.launcher3;
+import static com.android.launcher3.LauncherPrefs.FIXED_LANDSCAPE_MODE;
import static com.android.launcher3.LauncherPrefs.GRID_NAME;
import static com.android.launcher3.Utilities.dpiFromPx;
import static com.android.launcher3.testing.shared.ResourceUtils.INVALID_RESOURCE_HANDLE;
@@ -52,7 +53,6 @@
import com.android.launcher3.config.FeatureFlags;
import com.android.launcher3.icons.DotRenderer;
-import com.android.launcher3.logging.FileLog;
import com.android.launcher3.model.DeviceGridState;
import com.android.launcher3.provider.RestoreDbTask;
import com.android.launcher3.testing.shared.ResourceUtils;
@@ -87,7 +87,8 @@
@Retention(RetentionPolicy.SOURCE)
@IntDef({TYPE_PHONE, TYPE_MULTI_DISPLAY, TYPE_TABLET})
- public @interface DeviceType {}
+ public @interface DeviceType {
+ }
public static final int TYPE_PHONE = 0;
public static final int TYPE_MULTI_DISPLAY = 1;
@@ -133,6 +134,7 @@
public int iconBitmapSize;
public int fillResIconDpi;
public @DeviceType int deviceType;
+ public Info displayInfo;
public PointF[] minCellSize;
@@ -210,6 +212,13 @@
@XmlRes
public int allAppsCellSpecsTwoPanelId = INVALID_RESOURCE_HANDLE;
+
+ /**
+ * Fixed landscape mode is the landscape on the phones.
+ */
+ public boolean isFixedLandscapeMode = false;
+ private LauncherPrefChangeListener mLandscapeModePreferenceListener;
+
public String dbFile;
public int defaultLayoutId;
public int demoModeLayoutId;
@@ -225,7 +234,8 @@
private final ArrayList<OnIDPChangeListener> mChangeListeners = new ArrayList<>();
@VisibleForTesting
- public InvariantDeviceProfile() { }
+ public InvariantDeviceProfile() {
+ }
@TargetApi(23)
private InvariantDeviceProfile(Context context) {
@@ -243,6 +253,18 @@
onConfigChanged(displayContext);
}
});
+ if (Flags.oneGridSpecs()) {
+ mLandscapeModePreferenceListener = (String s) -> {
+ boolean newFixedLandscapeValue = FIXED_LANDSCAPE_MODE.get(context);
+ if (isFixedLandscapeMode != newFixedLandscapeValue) {
+ setFixedLandscape(context, newFixedLandscapeValue);
+ }
+ };
+ LauncherPrefs.INSTANCE.get(context).addListener(
+ mLandscapeModePreferenceListener,
+ FIXED_LANDSCAPE_MODE
+ );
+ }
}
/**
@@ -268,8 +290,13 @@
@DeviceType int defaultDeviceType = defaultInfo.getDeviceType();
DisplayOption defaultDisplayOption = invDistWeightedInterpolate(
defaultInfo,
- getPredefinedDeviceProfiles(context, gridName, defaultDeviceType,
- /*allowDisabledGrid=*/false),
+ getPredefinedDeviceProfiles(
+ context,
+ gridName,
+ defaultInfo,
+ /*allowDisabledGrid=*/false,
+ isFixedLandscapeMode
+ ),
defaultDeviceType);
Context displayContext = context.createDisplayContext(display);
@@ -277,8 +304,13 @@
@DeviceType int deviceType = myInfo.getDeviceType();
DisplayOption myDisplayOption = invDistWeightedInterpolate(
myInfo,
- getPredefinedDeviceProfiles(context, gridName, deviceType,
- /*allowDisabledGrid=*/false),
+ getPredefinedDeviceProfiles(
+ context,
+ gridName,
+ myInfo,
+ /*allowDisabledGrid=*/false,
+ isFixedLandscapeMode
+ ),
deviceType);
DisplayOption result = new DisplayOption(defaultDisplayOption.grid)
@@ -295,40 +327,16 @@
System.arraycopy(defaultDisplayOption.borderSpaces, 0, result.borderSpaces, 0,
COUNT_SIZES);
- initGrid(context, myInfo, result, deviceType);
+ initGrid(context, myInfo, result);
}
@Override
public void close() {
DisplayController.INSTANCE.executeIfCreated(dc -> dc.setPriorityListener(null));
- }
-
- /**
- * Reinitialize the current grid after a restore, where some grids might now be disabled.
- */
- public void reinitializeAfterRestore(Context context) {
- String currentGridName = getCurrentGridName(context);
- String currentDbFile = dbFile;
- String newGridName = initGrid(context, currentGridName);
- String newDbFile = dbFile;
- FileLog.d(TAG, "Reinitializing grid after restore."
- + " currentGridName=" + currentGridName
- + ", currentDbFile=" + currentDbFile
- + ", newGridName=" + newGridName
- + ", newDbFile=" + newDbFile);
- if (!newDbFile.equals(currentDbFile)) {
- FileLog.d(TAG, "Restored grid is disabled : " + currentGridName
- + ", migrating to: " + newGridName
- + ", removing all other grid db files");
- for (String gridDbFile : LauncherFiles.GRID_DB_FILES) {
- if (gridDbFile.equals(currentDbFile)) {
- continue;
- }
- if (context.getDatabasePath(gridDbFile).delete()) {
- FileLog.d(TAG, "Removed old grid db file: " + gridDbFile);
- }
- }
- setCurrentGrid(context, newGridName);
+ if (mLandscapeModePreferenceListener != null) {
+ LauncherPrefs.INSTANCE.executeIfCreated(
+ lp -> lp.removeListener(mLandscapeModePreferenceListener, FIXED_LANDSCAPE_MODE)
+ );
}
}
@@ -337,12 +345,20 @@
}
private String initGrid(Context context, String gridName) {
- Info displayInfo = DisplayController.INSTANCE.get(context).getInfo();
- @DeviceType int deviceType = displayInfo.getDeviceType();
+ if (!Flags.oneGridSpecs() && (isFixedLandscapeMode || FIXED_LANDSCAPE_MODE.get(context))) {
+ LauncherPrefs.get(context).put(FIXED_LANDSCAPE_MODE, false);
+ isFixedLandscapeMode = false;
+ }
- List<DisplayOption> allOptions =
- getPredefinedDeviceProfiles(context, gridName, deviceType,
- RestoreDbTask.isPending(context));
+ Info displayInfo = DisplayController.INSTANCE.get(context).getInfo();
+
+ List<DisplayOption> allOptions = getPredefinedDeviceProfiles(
+ context,
+ gridName,
+ displayInfo,
+ RestoreDbTask.isPending(context),
+ FIXED_LANDSCAPE_MODE.get(context)
+ );
// Filter out options that don't have the same number of columns as the grid
DeviceGridState deviceGridState = new DeviceGridState(context);
@@ -351,9 +367,10 @@
DisplayOption displayOption =
invDistWeightedInterpolate(displayInfo, allOptionsFilteredByColCount.isEmpty()
- ? new ArrayList<>(allOptions)
- : new ArrayList<>(allOptionsFilteredByColCount), deviceType);
- initGrid(context, displayInfo, displayOption, deviceType);
+ ? new ArrayList<>(allOptions)
+ : new ArrayList<>(allOptionsFilteredByColCount),
+ displayInfo.getDeviceType());
+ initGrid(context, displayInfo, displayOption);
return displayOption.grid.name;
}
@@ -377,8 +394,7 @@
return new InvariantDeviceProfile().initGrid(context, null);
}
- private void initGrid(Context context, Info displayInfo, DisplayOption displayOption,
- @DeviceType int deviceType) {
+ private void initGrid(Context context, Info displayInfo, DisplayOption displayOption) {
DisplayMetrics metrics = context.getResources().getDisplayMetrics();
GridOption closestProfile = displayOption.grid;
numRows = closestProfile.numRows;
@@ -411,7 +427,8 @@
allAppsCellSpecsTwoPanelId = closestProfile.mAllAppsCellSpecsTwoPanelId;
numAllAppsRowsForCellHeightCalculation =
closestProfile.mNumAllAppsRowsForCellHeightCalculation;
- this.deviceType = deviceType;
+ this.deviceType = displayInfo.getDeviceType();
+ this.displayInfo = displayInfo;
inlineNavButtonsEndSpacing = closestProfile.inlineNavButtonsEndSpacing;
@@ -455,6 +472,9 @@
startAlignTaskbar = displayOption.startAlignTaskbar;
+ // Fixed Landscape mode
+ isFixedLandscapeMode = FIXED_LANDSCAPE_MODE.get(context) && Flags.oneGridSpecs();
+
// If the partner customization apk contains any grid overrides, apply them
// Supported overrides: numRows, numColumns, iconSize
applyPartnerDeviceProfileOverrides(context, metrics);
@@ -510,8 +530,12 @@
mChangeListeners.remove(listener);
}
- public void setCurrentGrid(Context context, String gridName) {
- LauncherPrefs.get(context).put(GRID_NAME, gridName);
+ /**
+ * Updates the current grid, this triggers a new IDP, reloads the database and triggers a grid
+ * migration.
+ */
+ public void setCurrentGrid(Context context, String newGridName) {
+ LauncherPrefs.get(context).put(GRID_NAME, newGridName);
MAIN_EXECUTOR.execute(() -> {
Trace.beginSection("InvariantDeviceProfile#setCurrentGrid");
onConfigChanged(context.getApplicationContext());
@@ -519,6 +543,24 @@
});
}
+ /**
+ * Updates the fixed landscape mode, this triggers a new IDP, reloads the database and triggers
+ * a grid migration.
+ */
+ public void setFixedLandscape(Context context, boolean isFixedLandscape) {
+ this.isFixedLandscapeMode = isFixedLandscape;
+ if (isFixedLandscape) {
+ // When in isFixedLandscape there should only be one default grid to choose from
+ MAIN_EXECUTOR.execute(() -> {
+ Trace.beginSection("InvariantDeviceProfile#setFixedLandscape");
+ onConfigChanged(context.getApplicationContext());
+ Trace.endSection();
+ });
+ } else {
+ setCurrentGrid(context, LauncherPrefs.get(context).get(GRID_NAME));
+ }
+ }
+
private Object[] toModelState() {
return new Object[]{
numColumns, numRows, numSearchContainerColumns, numDatabaseHotseatIcons,
@@ -540,8 +582,19 @@
}
}
- private List<DisplayOption> getPredefinedDeviceProfiles(Context context,
- String gridName, @DeviceType int deviceType, boolean allowDisabledGrid) {
+ private static boolean firstGridFilter(GridOption gridOption, int deviceType,
+ boolean allowDisabledGrid, boolean isFixedLandscapeMode) {
+ return (gridOption.isEnabled(deviceType) || allowDisabledGrid)
+ && gridOption.filterByFlag(deviceType, isFixedLandscapeMode);
+ }
+
+ private static List<DisplayOption> getPredefinedDeviceProfiles(
+ Context context,
+ String gridName,
+ Info displayInfo,
+ boolean allowDisabledGrid,
+ boolean isFixedLandscapeMode
+ ) {
ArrayList<DisplayOption> profiles = new ArrayList<>();
try (XmlResourceParser parser = context.getResources().getXml(R.xml.device_profiles)) {
@@ -551,10 +604,10 @@
parser.getDepth() > depth) && type != XmlPullParser.END_DOCUMENT) {
if ((type == XmlPullParser.START_TAG)
&& GridOption.TAG_NAME.equals(parser.getName())) {
-
- GridOption gridOption = new GridOption(context, Xml.asAttributeSet(parser));
- if ((gridOption.isEnabled(deviceType) || allowDisabledGrid)
- && (Flags.oneGridSpecs() == gridOption.isNewGridOption())) {
+ GridOption gridOption = new GridOption(
+ context, Xml.asAttributeSet(parser), displayInfo);
+ if (firstGridFilter(gridOption, displayInfo.getDeviceType(), allowDisabledGrid,
+ isFixedLandscapeMode)) {
final int displayDepth = parser.getDepth();
while (((type = parser.next()) != XmlPullParser.END_TAG
|| parser.getDepth() > displayDepth)
@@ -571,12 +624,11 @@
} catch (IOException | XmlPullParserException e) {
throw new RuntimeException(e);
}
-
ArrayList<DisplayOption> filteredProfiles = new ArrayList<>();
if (!TextUtils.isEmpty(gridName)) {
for (DisplayOption option : profiles) {
- if (gridName.equals(option.grid.name)
- && (option.grid.isEnabled(deviceType) || allowDisabledGrid)) {
+ if (gridName.equals(option.grid.name) && (option.grid.isEnabled(
+ displayInfo.getDeviceType()) || allowDisabledGrid)) {
filteredProfiles.add(option);
}
}
@@ -602,10 +654,10 @@
* Parses through the xml to find NumRows specs. Then calls findBestRowCount to get the correct
* row count for this GridOption.
*
- * @return the result of {@link #findBestRowCount(List, Context, int)}.
+ * @return the result of {@link #findBestRowCount(List, Info)}.
*/
public static NumRows getRowCount(ResourceHelper resourceHelper, Context context,
- int deviceType) {
+ Info displayInfo) {
ArrayList<NumRows> rowCounts = new ArrayList<>();
try (XmlResourceParser parser = resourceHelper.getXml()) {
@@ -622,21 +674,19 @@
throw new RuntimeException(e);
}
- return findBestRowCount(rowCounts, context, deviceType);
+ return findBestRowCount(rowCounts, displayInfo);
}
/**
* @return the biggest row count that fits the display dimensions spec using NumRows to
* determine that. If no best row count is found, return -1.
*/
- public static NumRows findBestRowCount(List<NumRows> list, Context context,
- @DeviceType int deviceType) {
- Info displayInfo = DisplayController.INSTANCE.get(context).getInfo();
+ public static NumRows findBestRowCount(List<NumRows> list, Info displayInfo) {
int minWidthPx = Integer.MAX_VALUE;
int minHeightPx = Integer.MAX_VALUE;
for (WindowBounds bounds : displayInfo.supportedBounds) {
boolean isTablet = displayInfo.isTablet(bounds);
- if (isTablet && deviceType == TYPE_MULTI_DISPLAY) {
+ if (isTablet && displayInfo.getDeviceType() == TYPE_MULTI_DISPLAY) {
// For split displays, take half width per page
minWidthPx = Math.min(minWidthPx, bounds.availableSize.x / 2);
minHeightPx = Math.min(minHeightPx, bounds.availableSize.y);
@@ -681,7 +731,6 @@
* supported. Ej. 4x4 -> normal, 5x4 -> practical, etc.
* (Note: the name of the grid can be different for the same grid size depending of
* the values of the InvariantDeviceProfile)
- *
*/
public String getGridNameFromSize(Context context, Point size) {
return parseAllGridOptions(context).stream()
@@ -707,19 +756,18 @@
* @return all the grid options that can be shown on the device
*/
public List<GridOption> parseAllGridOptions(Context context) {
- return parseAllDefinedGridOptions(context)
+ return parseAllDefinedGridOptions(context, displayInfo)
.stream()
.filter(go -> go.isEnabled(deviceType))
- .filter(go -> (Flags.oneGridSpecs() == go.isNewGridOption()))
+ .filter(go -> go.filterByFlag(deviceType, isFixedLandscapeMode))
.collect(Collectors.toList());
}
/**
* @return all the grid options that can be shown on the device
*/
- public static List<GridOption> parseAllDefinedGridOptions(Context context) {
+ public static List<GridOption> parseAllDefinedGridOptions(Context context, Info displayInfo) {
List<GridOption> result = new ArrayList<>();
-
try (XmlResourceParser parser = context.getResources().getXml(R.xml.device_profiles)) {
final int depth = parser.getDepth();
int type;
@@ -727,7 +775,7 @@
|| parser.getDepth() > depth) && type != XmlPullParser.END_DOCUMENT) {
if ((type == XmlPullParser.START_TAG)
&& GridOption.TAG_NAME.equals(parser.getName())) {
- result.add(new GridOption(context, Xml.asAttributeSet(parser)));
+ result.add(new GridOption(context, Xml.asAttributeSet(parser), displayInfo));
}
}
} catch (IOException | XmlPullParserException e) {
@@ -967,6 +1015,7 @@
private final int demoModeLayoutId;
private final boolean isScalable;
+ private final boolean mIsDualGrid;
private final int devicePaddingId;
private final int mWorkspaceSpecsId;
private final int mWorkspaceSpecsTwoPanelId;
@@ -981,8 +1030,9 @@
private final int mAllAppsCellSpecsId;
private final int mAllAppsCellSpecsTwoPanelId;
private final int mRowCountSpecsId;
+ private final boolean mIsFixedLandscape;
- public GridOption(Context context, AttributeSet attrs) {
+ public GridOption(Context context, AttributeSet attrs, Info displayInfo) {
TypedArray a = context.obtainStyledAttributes(
attrs, R.styleable.GridDisplayOption);
name = a.getString(R.styleable.GridDisplayOption_name);
@@ -991,23 +1041,26 @@
DEVICE_CATEGORY_ALL);
mRowCountSpecsId = a.getResourceId(
R.styleable.GridDisplayOption_rowCountSpecsId, INVALID_RESOURCE_HANDLE);
+ mIsDualGrid = a.getBoolean(R.styleable.GridDisplayOption_isDualGrid, false);
if (mRowCountSpecsId != INVALID_RESOURCE_HANDLE) {
ResourceHelper resourceHelper = new ResourceHelper(context, mRowCountSpecsId);
- NumRows numR = getRowCount(resourceHelper, context, deviceCategory);
+ NumRows numR = getRowCount(resourceHelper, context, displayInfo);
numRows = numR.mNumRowsNew;
dbFile = numR.mDbFile;
+ defaultLayoutId = numR.mDefaultLayoutId;
+ demoModeLayoutId = numR.mDemoModeLayoutId;
} else {
numRows = a.getInt(R.styleable.GridDisplayOption_numRows, 0);
dbFile = a.getString(R.styleable.GridDisplayOption_dbFile);
+ defaultLayoutId = a.getResourceId(
+ R.styleable.GridDisplayOption_defaultLayoutId, 0);
+ demoModeLayoutId = a.getResourceId(
+ R.styleable.GridDisplayOption_demoModeLayoutId, defaultLayoutId);
}
numColumns = a.getInt(R.styleable.GridDisplayOption_numColumns, 0);
numSearchContainerColumns = a.getInt(
R.styleable.GridDisplayOption_numSearchContainerColumns, numColumns);
- defaultLayoutId = a.getResourceId(
- R.styleable.GridDisplayOption_defaultLayoutId, 0);
- demoModeLayoutId = a.getResourceId(
- R.styleable.GridDisplayOption_demoModeLayoutId, defaultLayoutId);
allAppsStyle = a.getResourceId(R.styleable.GridDisplayOption_allAppsStyle,
R.style.AllAppsStyleDefault);
@@ -1121,6 +1174,8 @@
mNumAllAppsRowsForCellHeightCalculation = numRows;
}
+ mIsFixedLandscape = a.getBoolean(R.styleable.GridDisplayOption_isFixedLandscape, false);
+
int inlineForRotation = a.getInt(R.styleable.GridDisplayOption_inlineQsb,
DONT_INLINE_QSB);
inlineQsb[INDEX_DEFAULT] =
@@ -1154,6 +1209,18 @@
public boolean isNewGridOption() {
return mRowCountSpecsId != INVALID_RESOURCE_HANDLE;
}
+
+ public boolean filterByFlag(int deviceType, boolean isFixedLandscape) {
+ if (deviceType == TYPE_TABLET) {
+ return Flags.oneGridRotationHandling() == mIsDualGrid;
+ }
+
+ if (isFixedLandscape) {
+ return Flags.oneGridSpecs() && mIsFixedLandscape;
+ }
+
+ return ((Flags.oneGridSpecs() == isNewGridOption()) && !mIsFixedLandscape);
+ }
}
public static final class NumRows {
@@ -1161,6 +1228,9 @@
final float mMinDeviceWidthPx;
final float mMinDeviceHeightPx;
final String mDbFile;
+ final int mDefaultLayoutId;
+ final int mDemoModeLayoutId;
+
NumRows(Context context, AttributeSet attrs) {
TypedArray a = context.obtainStyledAttributes(attrs, R.styleable.NumRows);
@@ -1169,6 +1239,10 @@
mMinDeviceWidthPx = a.getFloat(R.styleable.NumRows_minDeviceWidthPx, 0);
mMinDeviceHeightPx = a.getFloat(R.styleable.NumRows_minDeviceHeightPx, 0);
mDbFile = a.getString(R.styleable.NumRows_dbFile);
+ mDefaultLayoutId = a.getResourceId(
+ R.styleable.NumRows_defaultLayoutId, 0);
+ mDemoModeLayoutId = a.getResourceId(
+ R.styleable.NumRows_demoModeLayoutId, mDefaultLayoutId);
a.recycle();
}
diff --git a/src/com/android/launcher3/Launcher.java b/src/com/android/launcher3/Launcher.java
index 983cf8d..6145077 100644
--- a/src/com/android/launcher3/Launcher.java
+++ b/src/com/android/launcher3/Launcher.java
@@ -279,6 +279,7 @@
import java.util.HashSet;
import java.util.List;
import java.util.Map;
+import java.util.Objects;
import java.util.Optional;
import java.util.function.Predicate;
import java.util.function.Supplier;
@@ -761,7 +762,6 @@
if (!initDeviceProfile(mDeviceProfile.inv) && !mForceConfigUpdate) {
return;
}
-
dispatchDeviceProfileChanged();
reapplyUi();
mDragLayer.recreateControllers();
@@ -777,6 +777,15 @@
}
}
+ private void updateFixedLandscape() {
+ if (!com.android.launcher3.Flags.oneGridSpecs()) {
+ return;
+ }
+ getRotationHelper().setFixedLandscape(
+ Objects.requireNonNull(mDeviceProfile.inv).isFixedLandscapeMode
+ );
+ }
+
public void onAssistantVisibilityChanged(float visibility) {
mHotseat.getQsb().setAlpha(1f - visibility);
}
@@ -805,6 +814,7 @@
mDeviceProfile.numShownHotseatIcons);
}
mModelWriter = mModel.getWriter(true, mCellPosMapper, this);
+ updateFixedLandscape();
return true;
}
@@ -2629,8 +2639,9 @@
* See {@code LauncherBindingDelegate}
*/
@Override
- public void bindAllWidgets(final List<WidgetsListBaseEntry> allWidgets) {
- mModelCallbacks.bindAllWidgets(allWidgets);
+ public void bindAllWidgets(@NonNull final List<WidgetsListBaseEntry> allWidgets,
+ @NonNull final List<WidgetsListBaseEntry> defaultWidgets) {
+ mModelCallbacks.bindAllWidgets(allWidgets, defaultWidgets);
}
@Override
diff --git a/src/com/android/launcher3/LauncherAppState.java b/src/com/android/launcher3/LauncherAppState.java
index b6da164..01d0a74 100644
--- a/src/com/android/launcher3/LauncherAppState.java
+++ b/src/com/android/launcher3/LauncherAppState.java
@@ -48,6 +48,7 @@
import com.android.launcher3.icons.LauncherIconProvider;
import com.android.launcher3.icons.LauncherIcons;
import com.android.launcher3.model.ModelLauncherCallbacks;
+import com.android.launcher3.model.WidgetsFilterDataProvider;
import com.android.launcher3.notification.NotificationListener;
import com.android.launcher3.pm.InstallSessionHelper;
import com.android.launcher3.pm.InstallSessionTracker;
@@ -197,7 +198,8 @@
mIconProvider = new LauncherIconProvider(context);
mIconCache = new IconCache(mContext, mInvariantDeviceProfile,
iconCacheFileName, mIconProvider);
- mModel = new LauncherModel(context, this, mIconCache, new AppFilter(mContext),
+ mModel = new LauncherModel(context, this, mIconCache,
+ WidgetsFilterDataProvider.Companion.newInstance(context), new AppFilter(mContext),
PackageManagerHelper.INSTANCE.get(context), iconCacheFileName != null);
mOnTerminateCallback.add(mIconCache::close);
mOnTerminateCallback.add(mModel::destroy);
diff --git a/src/com/android/launcher3/LauncherFiles.java b/src/com/android/launcher3/LauncherFiles.java
index 1148f79..df75470 100644
--- a/src/com/android/launcher3/LauncherFiles.java
+++ b/src/com/android/launcher3/LauncherFiles.java
@@ -16,6 +16,7 @@
private static final String XML = ".xml";
public static final String LAUNCHER_DB = "launcher.db";
+ public static final String LAUNCHER_5_BY_8_DB = "launcher_5_by_8.db";
public static final String LAUNCHER_6_BY_5_DB = "launcher_6_by_5.db";
public static final String LAUNCHER_4_BY_5_DB = "launcher_4_by_5.db";
public static final String LAUNCHER_4_BY_6_DB = "launcher_4_by_6.db";
@@ -23,6 +24,7 @@
public static final String LAUNCHER_4_BY_4_DB = "launcher_4_by_4.db";
public static final String LAUNCHER_3_BY_3_DB = "launcher_3_by_3.db";
public static final String LAUNCHER_2_BY_2_DB = "launcher_2_by_2.db";
+ public static final String LAUNCHER_7_BY_3_DB = "launcher_7_by_3.db";
public static final String BACKUP_DB = "backup.db";
public static final String SHARED_PREFERENCES_KEY = "com.android.launcher3.prefs";
public static final String MANAGED_USER_PREFERENCES_KEY =
@@ -35,13 +37,15 @@
public static final List<String> GRID_DB_FILES = Collections.unmodifiableList(Arrays.asList(
LAUNCHER_DB,
+ LAUNCHER_5_BY_8_DB,
LAUNCHER_6_BY_5_DB,
LAUNCHER_4_BY_5_DB,
LAUNCHER_4_BY_6_DB,
LAUNCHER_5_BY_6_DB,
LAUNCHER_4_BY_4_DB,
LAUNCHER_3_BY_3_DB,
- LAUNCHER_2_BY_2_DB));
+ LAUNCHER_2_BY_2_DB,
+ LAUNCHER_7_BY_3_DB));
public static final List<String> OTHER_FILES = Collections.unmodifiableList(Arrays.asList(
BACKUP_DB,
diff --git a/src/com/android/launcher3/LauncherModel.kt b/src/com/android/launcher3/LauncherModel.kt
index 85ecd58..b56df46 100644
--- a/src/com/android/launcher3/LauncherModel.kt
+++ b/src/com/android/launcher3/LauncherModel.kt
@@ -42,6 +42,7 @@
import com.android.launcher3.model.ReloadStringCacheTask
import com.android.launcher3.model.ShortcutsChangedTask
import com.android.launcher3.model.UserLockStateChangedTask
+import com.android.launcher3.model.WidgetsFilterDataProvider
import com.android.launcher3.model.data.ItemInfo
import com.android.launcher3.model.data.WorkspaceItemInfo
import com.android.launcher3.pm.UserCache
@@ -66,6 +67,7 @@
private val context: Context,
private val mApp: LauncherAppState,
private val iconCache: IconCache,
+ private val widgetsFilterDataProvider: WidgetsFilterDataProvider,
appFilter: AppFilter,
mPmHelper: PackageManagerHelper,
isPrimaryInstance: Boolean,
@@ -140,6 +142,11 @@
owner: BgDataModel.Callbacks?,
) = ModelWriter(mApp.context, this, mBgDataModel, verifyChanges, cellPosMapper, owner)
+ /** Returns the [WidgetsFilterDataProvider] that manages widget filters. */
+ fun getWidgetsFilterDataProvider(): WidgetsFilterDataProvider {
+ return widgetsFilterDataProvider
+ }
+
/** Called when the icon for an app changes, outside of package event */
@WorkerThread
fun onAppIconChanged(packageName: String, user: UserHandle) {
@@ -160,7 +167,10 @@
/** Called when the model is destroyed */
fun destroy() {
mModelDestroyed = true
- MODEL_EXECUTOR.execute(modelDelegate::destroy)
+ MODEL_EXECUTOR.execute {
+ modelDelegate.destroy()
+ widgetsFilterDataProvider.destroy()
+ }
}
fun onBroadcastIntent(intent: Intent) {
@@ -312,6 +322,7 @@
mBgDataModel,
this.modelDelegate,
launcherBinder,
+ widgetsFilterDataProvider,
)
// Always post the loader task, instead of running directly
@@ -417,6 +428,14 @@
}
}
+ /** Called when the widget filters are refreshed and available to bind to the model. */
+ fun onWidgetFiltersLoaded() {
+ enqueueModelUpdateTask { taskController, dataModel, _ ->
+ dataModel.widgetsModel.updateWidgetFilters(widgetsFilterDataProvider)
+ taskController.bindUpdatedWidgets(dataModel)
+ }
+ }
+
fun enqueueModelUpdateTask(task: ModelUpdateTask) {
if (mModelDestroyed) {
return
diff --git a/src/com/android/launcher3/LauncherPrefs.kt b/src/com/android/launcher3/LauncherPrefs.kt
index 5c03644..712c56c 100644
--- a/src/com/android/launcher3/LauncherPrefs.kt
+++ b/src/com/android/launcher3/LauncherPrefs.kt
@@ -26,6 +26,7 @@
import com.android.launcher3.pm.InstallSessionHelper
import com.android.launcher3.provider.RestoreDbTask
import com.android.launcher3.provider.RestoreDbTask.FIRST_LOAD_AFTER_RESTORE_KEY
+import com.android.launcher3.settings.SettingsActivity
import com.android.launcher3.states.RotationHelper
import com.android.launcher3.util.DisplayController
import com.android.launcher3.util.MainThreadInitializedObject
@@ -133,6 +134,7 @@
nonRestorableItem(FIRST_LOAD_AFTER_RESTORE_KEY, false, EncryptionType.ENCRYPTED)
@JvmField val APP_WIDGET_IDS = backedUpItem(RestoreDbTask.APPWIDGET_IDS, "")
@JvmField val OLD_APP_WIDGET_IDS = backedUpItem(RestoreDbTask.APPWIDGET_OLD_IDS, "")
+
@JvmField
val GRID_NAME =
ConstantItem(
@@ -148,6 +150,9 @@
RotationHelper.getAllowRotationDefaultValue(DisplayController.INSTANCE.get(it).info)
}
+ @JvmField
+ val FIXED_LANDSCAPE_MODE = backedUpItem(SettingsActivity.FIXED_LANDSCAPE_MODE, false)
+
// Preferences for widget configurations
@JvmField
val RECONFIGURABLE_WIDGET_EDUCATION_TIP_SEEN =
diff --git a/src/com/android/launcher3/LauncherState.java b/src/com/android/launcher3/LauncherState.java
index 102189b..7d5e481 100644
--- a/src/com/android/launcher3/LauncherState.java
+++ b/src/com/android/launcher3/LauncherState.java
@@ -375,8 +375,14 @@
}
public PageAlphaProvider getWorkspacePageAlphaProvider(Launcher launcher) {
- if ((this != NORMAL && this != HINT_STATE)
- || !launcher.getDeviceProfile().shouldFadeAdjacentWorkspaceScreens()) {
+ DeviceProfile dp = launcher.getDeviceProfile();
+ boolean shouldFadeAdjacentScreens = (this == NORMAL || this == HINT_STATE)
+ && dp.shouldFadeAdjacentWorkspaceScreens();
+ // Avoid showing adjacent screens behind handheld All Apps sheet.
+ if (Flags.allAppsSheetForHandheld() && dp.isPhone && this == ALL_APPS) {
+ shouldFadeAdjacentScreens = true;
+ }
+ if (!shouldFadeAdjacentScreens) {
return DEFAULT_ALPHA_PROVIDER;
}
final int centerPage = launcher.getWorkspace().getNextPage();
diff --git a/src/com/android/launcher3/ModelCallbacks.kt b/src/com/android/launcher3/ModelCallbacks.kt
index 496d517..5d32525 100644
--- a/src/com/android/launcher3/ModelCallbacks.kt
+++ b/src/com/android/launcher3/ModelCallbacks.kt
@@ -252,8 +252,11 @@
PopupContainerWithArrow.dismissInvalidPopup(launcher)
}
- override fun bindAllWidgets(allWidgets: List<WidgetsListBaseEntry>) {
- launcher.widgetPickerDataProvider.setWidgets(allWidgets, /* defaultWidgets= */ listOf())
+ override fun bindAllWidgets(
+ allWidgets: List<WidgetsListBaseEntry>,
+ defaultWidgets: List<WidgetsListBaseEntry>,
+ ) {
+ launcher.widgetPickerDataProvider.setWidgets(allWidgets, defaultWidgets)
}
/** Returns the ids of the workspaces to bind. */
diff --git a/src/com/android/launcher3/allapps/ActivityAllAppsContainerView.java b/src/com/android/launcher3/allapps/ActivityAllAppsContainerView.java
index 0dd2791..1b58987 100644
--- a/src/com/android/launcher3/allapps/ActivityAllAppsContainerView.java
+++ b/src/com/android/launcher3/allapps/ActivityAllAppsContainerView.java
@@ -47,7 +47,6 @@
import android.os.Process;
import android.os.UserManager;
import android.util.AttributeSet;
-import android.util.FloatProperty;
import android.util.Log;
import android.util.SparseArray;
import android.view.KeyEvent;
@@ -96,6 +95,7 @@
import com.android.launcher3.views.ScrimView;
import com.android.launcher3.views.SpringRelativeLayout;
import com.android.launcher3.workprofile.PersonalWorkSlidingTabStrip;
+import com.android.systemui.plugins.AllAppsRow;
import java.util.ArrayList;
import java.util.Arrays;
@@ -115,19 +115,6 @@
ScrimView.ScrimDrawingController {
- public static final FloatProperty<ActivityAllAppsContainerView<?>> BOTTOM_SHEET_ALPHA =
- new FloatProperty<>("bottomSheetAlpha") {
- @Override
- public Float get(ActivityAllAppsContainerView<?> containerView) {
- return containerView.mBottomSheetAlpha;
- }
-
- @Override
- public void setValue(ActivityAllAppsContainerView<?> containerView, float v) {
- containerView.setBottomSheetAlpha(v);
- }
- };
-
public static final float PULL_MULTIPLIER = .02f;
public static final float FLING_VELOCITY_MULTIPLIER = 1200f;
protected static final String BUNDLE_KEY_CURRENT_PAGE = "launcher.allapps.current_page";
@@ -166,6 +153,7 @@
private final RectF mTmpRectF = new RectF();
protected AllAppsPagedView mViewPager;
protected FloatingHeaderView mHeader;
+ protected final List<AllAppsRow> mAdditionalHeaderRows = new ArrayList<>();
protected View mBottomSheetBackground;
protected RecyclerViewFastScroller mFastScroller;
private ConstraintLayout mFastScrollLetterLayout;
@@ -191,8 +179,6 @@
private ScrimView mScrimView;
private int mHeaderColor;
private int mBottomSheetBackgroundColor;
- private float mBottomSheetAlpha = 1f;
- private boolean mForceBottomSheetVisible;
private int mTabsProtectionAlpha;
@Nullable private AllAppsTransitionController mAllAppsTransitionController;
@@ -278,6 +264,8 @@
getLayoutInflater().inflate(R.layout.all_apps_content, this);
mHeader = findViewById(R.id.all_apps_header);
+ mAdditionalHeaderRows.clear();
+ mAdditionalHeaderRows.addAll(getAdditionalHeaderRows());
mBottomSheetBackground = findViewById(R.id.bottom_sheet_background);
mBottomSheetHandleArea = findViewById(R.id.bottom_sheet_handle_area);
mSearchRecyclerView = findViewById(R.id.search_results_list_view);
@@ -304,6 +292,10 @@
mSearchUiManager = (SearchUiManager) mSearchContainer;
}
+ public List<AllAppsRow> getAdditionalHeaderRows() {
+ return List.of();
+ }
+
@Override
protected void onFinishInflate() {
super.onFinishInflate();
@@ -351,20 +343,6 @@
return mSearchUiManager;
}
- public View getBottomSheetBackground() {
- return mBottomSheetBackground;
- }
-
- /**
- * Temporarily force the bottom sheet to be visible on non-tablets.
- *
- * @param force {@code true} means bottom sheet will be visible on phones until {@code reset()}.
- */
- public void forceBottomSheetVisible(boolean force) {
- mForceBottomSheetVisible = force;
- updateBackgroundVisibility(mActivityContext.getDeviceProfile());
- }
-
public View getSearchView() {
return mSearchContainer;
}
@@ -496,7 +474,7 @@
if (mHeader != null && mHeader.getVisibility() == VISIBLE) {
mHeader.reset(animate);
}
- forceBottomSheetVisible(false);
+ updateBackgroundVisibility(mActivityContext.getDeviceProfile());
// Reset the base recycler view after transitioning home.
updateHeaderScroll(0);
if (exitSearch) {
@@ -726,7 +704,7 @@
post(() -> mAH.get(AdapterHolder.WORK).applyPadding());
} else {
- mWorkManager.detachWorkModeSwitch();
+ mWorkManager.detachWorkUtilityViews();
mViewPager = null;
}
@@ -744,6 +722,8 @@
}
void setupHeader() {
+ mAdditionalHeaderRows.forEach(row -> mHeader.onPluginDisconnected(row));
+
mHeader.setVisibility(View.VISIBLE);
boolean tabsHidden = !mUsingTabs;
mHeader.setup(
@@ -761,6 +741,7 @@
adapterHolder.mRecyclerView.scrollToTop();
}
});
+ mAdditionalHeaderRows.forEach(row -> mHeader.onPluginConnected(row, mActivityContext));
removeCustomRules(mHeader);
if (isSearchBarFloating()) {
@@ -1002,18 +983,13 @@
}
protected void updateBackgroundVisibility(DeviceProfile deviceProfile) {
- boolean visible = deviceProfile.isTablet || mForceBottomSheetVisible;
- mBottomSheetBackground.setVisibility(visible ? View.VISIBLE : View.GONE);
- // Note: For tablets, the opaque background and header protection are added in drawOnScrim.
+ mBottomSheetBackground.setVisibility(
+ deviceProfile.shouldShowAllAppsOnSheet() ? View.VISIBLE : View.GONE);
+ // Note: The opaque sheet background and header protection are added in drawOnScrim.
// For the taskbar entrypoint, the scrim is drawn by its abstract slide in view container,
// so its header protection is derived from this scrim instead.
}
- private void setBottomSheetAlpha(float alpha) {
- // Bottom sheet alpha is always 1 for tablets.
- mBottomSheetAlpha = mActivityContext.getDeviceProfile().isTablet ? 1f : alpha;
- }
-
@VisibleForTesting
public void onAppsUpdated() {
mHasWorkApps = Stream.of(mAllAppsStore.getApps())
@@ -1151,8 +1127,8 @@
applyAdapterSideAndBottomPaddings(grid);
MarginLayoutParams mlp = (MarginLayoutParams) getLayoutParams();
- // Ignore left/right insets on tablet because we are already centered in-screen.
- if (grid.isTablet) {
+ // Ignore left/right insets on bottom sheet because we are already centered in-screen.
+ if (grid.shouldShowAllAppsOnSheet()) {
mlp.leftMargin = mlp.rightMargin = 0;
} else {
mlp.leftMargin = insets.left;
@@ -1257,8 +1233,8 @@
/** Called in Launcher#bindStringCache() to update the UI when cache is updated. */
public void updateWorkUI() {
setDeviceManagementResources();
- if (mWorkManager.getWorkModeSwitch() != null) {
- mWorkManager.getWorkModeSwitch().updateStringFromCache();
+ if (mWorkManager.getWorkUtilityView() != null) {
+ mWorkManager.getWorkUtilityView().updateStringFromCache();
}
inflateWorkCardsIfNeeded();
}
@@ -1398,7 +1374,7 @@
// Draw full background panel for tablets.
if (hasBottomSheet) {
mHeaderPaint.setColor(mBottomSheetBackgroundColor);
- mHeaderPaint.setAlpha((int) (255 * mBottomSheetAlpha));
+ mHeaderPaint.setAlpha(255);
mTmpRectF.set(
leftWithScale,
@@ -1581,8 +1557,8 @@
void applyPadding() {
if (mRecyclerView != null) {
int bottomOffset = 0;
- if (isWork() && mWorkManager.getWorkModeSwitch() != null) {
- bottomOffset = mInsets.bottom + mWorkManager.getWorkModeSwitch().getHeight();
+ if (isWork() && mWorkManager.getWorkUtilityView() != null) {
+ bottomOffset = mInsets.bottom + mWorkManager.getWorkUtilityView().getHeight();
} else if (isMain() && mPrivateProfileManager != null) {
Optional<AdapterItem> privateSpaceHeaderItem = mAppsList.getAdapterItems()
.stream()
diff --git a/src/com/android/launcher3/allapps/AllAppsTransitionController.java b/src/com/android/launcher3/allapps/AllAppsTransitionController.java
index c6852e0..8554de5 100644
--- a/src/com/android/launcher3/allapps/AllAppsTransitionController.java
+++ b/src/com/android/launcher3/allapps/AllAppsTransitionController.java
@@ -16,7 +16,6 @@
package com.android.launcher3.allapps;
import static com.android.app.animation.Interpolators.DECELERATE_1_7;
-import static com.android.app.animation.Interpolators.INSTANT;
import static com.android.app.animation.Interpolators.LINEAR;
import static com.android.launcher3.LauncherAnimUtils.SCALE_PROPERTY;
import static com.android.launcher3.LauncherAnimUtils.VIEW_TRANSLATE_Y;
@@ -28,7 +27,6 @@
import static com.android.launcher3.UtilitiesKt.modifyAttributesOnViewTree;
import static com.android.launcher3.UtilitiesKt.restoreAttributesOnViewTree;
import static com.android.launcher3.anim.PropertySetter.NO_ANIM_PROPERTY_SETTER;
-import static com.android.launcher3.states.StateAnimationConfig.ANIM_ALL_APPS_BOTTOM_SHEET_FADE;
import static com.android.launcher3.states.StateAnimationConfig.ANIM_ALL_APPS_FADE;
import static com.android.launcher3.states.StateAnimationConfig.ANIM_VERTICAL_PROGRESS;
import static com.android.launcher3.util.SystemUiController.FLAG_DARK_NAV;
@@ -45,9 +43,9 @@
import androidx.annotation.FloatRange;
import androidx.annotation.Nullable;
-import com.android.app.animation.Interpolators;
import com.android.launcher3.DeviceProfile;
import com.android.launcher3.DeviceProfile.OnDeviceProfileChangeListener;
+import com.android.launcher3.Flags;
import com.android.launcher3.Launcher;
import com.android.launcher3.LauncherState;
import com.android.launcher3.R;
@@ -57,14 +55,16 @@
import com.android.launcher3.statemanager.StateManager.StateHandler;
import com.android.launcher3.states.StateAnimationConfig;
import com.android.launcher3.touch.AllAppsSwipeController;
+import com.android.launcher3.util.MSDLPlayerWrapper;
import com.android.launcher3.util.MultiPropertyFactory;
import com.android.launcher3.util.MultiPropertyFactory.MultiProperty;
import com.android.launcher3.util.MultiValueAlpha;
import com.android.launcher3.util.ScrollableLayoutManager;
import com.android.launcher3.util.Themes;
-import com.android.launcher3.util.VibratorWrapper;
import com.android.launcher3.views.ScrimView;
+import com.google.android.msdl.data.model.MSDLToken;
+
/**
* Handles AllApps view transition.
* 1) Slides all apps view using direct manipulation
@@ -106,7 +106,7 @@
@Override
public Float get(AllAppsTransitionController controller) {
- if (controller.mIsTablet) {
+ if (controller.mShouldShowAllAppsOnSheet) {
return controller.mAppsView.getActiveRecyclerView().getTranslationY();
} else {
return controller.getAppsViewPullbackTranslationY().getValue();
@@ -115,7 +115,7 @@
@Override
public void setValue(AllAppsTransitionController controller, float translation) {
- if (controller.mIsTablet) {
+ if (controller.mShouldShowAllAppsOnSheet) {
controller.mAppsView.getActiveRecyclerView().setTranslationY(translation);
controller.getAppsViewPullbackTranslationY().setValue(
ALL_APPS_PULL_BACK_TRANSLATION_DEFAULT);
@@ -134,7 +134,7 @@
@Override
public Float get(AllAppsTransitionController controller) {
- if (controller.mIsTablet) {
+ if (controller.mShouldShowAllAppsOnSheet) {
return controller.mAppsView.getActiveRecyclerView().getAlpha();
} else {
return controller.getAppsViewPullbackAlpha().getValue();
@@ -143,7 +143,7 @@
@Override
public void setValue(AllAppsTransitionController controller, float alpha) {
- if (controller.mIsTablet) {
+ if (controller.mShouldShowAllAppsOnSheet) {
controller.mAppsView.getActiveRecyclerView().setAlpha(alpha);
controller.getAppsViewPullbackAlpha().setValue(
ALL_APPS_PULL_BACK_ALPHA_DEFAULT);
@@ -168,6 +168,7 @@
@Nullable private Animator.AnimatorListener mAllAppsSearchBackAnimationListener;
private boolean mIsVerticalLayout;
+ private boolean mShouldShowAllAppsOnSheet;
// Animation in this class is controlled by a single variable {@link mProgress}.
// Visually, it represents top y coordinate of the all apps container if multiplied with
@@ -183,24 +184,22 @@
private MultiValueAlpha mAppsViewAlpha;
private MultiPropertyFactory<View> mAppsViewTranslationY;
- private boolean mIsTablet;
-
private boolean mHasScaleEffect;
- private final VibratorWrapper mVibratorWrapper;
+ private final MSDLPlayerWrapper mMSDLPlayerWrapper;
public AllAppsTransitionController(Launcher l) {
mLauncher = l;
DeviceProfile dp = mLauncher.getDeviceProfile();
mProgress = 1f;
mIsVerticalLayout = dp.isVerticalBarLayout();
- mIsTablet = dp.isTablet;
+ mShouldShowAllAppsOnSheet = dp.shouldShowAllAppsOnSheet();
mNavScrimFlag = Themes.getAttrBoolean(l, R.attr.isMainColorDark)
? FLAG_DARK_NAV : FLAG_LIGHT_NAV;
setShiftRange(dp.allAppsShiftRange);
mAllAppScale.value = 1;
mLauncher.addOnDeviceProfileChangeListener(this);
- mVibratorWrapper = VibratorWrapper.INSTANCE.get(mLauncher.getApplicationContext());
+ mMSDLPlayerWrapper = MSDLPlayerWrapper.INSTANCE.get(mLauncher.getApplicationContext());
}
public float getShiftRange() {
@@ -217,7 +216,7 @@
mLauncher.getWorkspace().getPageIndicator().setTranslationY(0);
}
- mIsTablet = dp.isTablet;
+ mShouldShowAllAppsOnSheet = dp.shouldShowAllAppsOnSheet();
}
/**
@@ -280,10 +279,9 @@
return;
}
- float deceleratedProgress = Interpolators.BACK_GESTURE.getInterpolation(backProgress);
float scaleProgress = ScrollableLayoutManager.PREDICTIVE_BACK_MIN_SCALE
+ (1 - ScrollableLayoutManager.PREDICTIVE_BACK_MIN_SCALE)
- * (1 - deceleratedProgress);
+ * (1 - backProgress);
mAllAppScale.updateValue(scaleProgress);
}
@@ -373,8 +371,16 @@
setAlphas(toState, config, builder);
// This controls both haptics for tapping on QSB and going to all apps.
if (ALL_APPS.equals(toState) && mLauncher.isInState(NORMAL)) {
- mLauncher.getAppsView().performHapticFeedback(HapticFeedbackConstants.VIRTUAL_KEY,
- HapticFeedbackConstants.FLAG_IGNORE_VIEW_SETTING);
+ if (Flags.msdlFeedback()) {
+ if (config.isUserControlled()) {
+ mMSDLPlayerWrapper.playToken(MSDLToken.SWIPE_THRESHOLD_INDICATOR);
+ } else {
+ mMSDLPlayerWrapper.playToken(MSDLToken.TAP_HIGH_EMPHASIS);
+ }
+ } else {
+ mLauncher.getAppsView().performHapticFeedback(HapticFeedbackConstants.VIRTUAL_KEY,
+ HapticFeedbackConstants.FLAG_IGNORE_VIEW_SETTING);
+ }
}
}
@@ -395,10 +401,6 @@
setter.setFloat(getAppsViewPullbackAlpha(), MultiPropertyFactory.MULTI_PROPERTY_VALUE,
hasAllAppsContent ? 1 : 0, allAppsFade);
- setter.setFloat(mLauncher.getAppsView(),
- ActivityAllAppsContainerView.BOTTOM_SHEET_ALPHA, hasAllAppsContent ? 1 : 0,
- config.getInterpolator(ANIM_ALL_APPS_BOTTOM_SHEET_FADE, INSTANT));
-
boolean shouldProtectHeader = !config.hasAnimationFlag(StateAnimationConfig.SKIP_SCRIM)
&& (ALL_APPS == state || mLauncher.getStateManager().getState() == ALL_APPS);
mScrimView.setDrawingController(shouldProtectHeader ? mAppsView : null);
diff --git a/src/com/android/launcher3/allapps/FloatingHeaderView.java b/src/com/android/launcher3/allapps/FloatingHeaderView.java
index ac06ab4..8193511 100644
--- a/src/com/android/launcher3/allapps/FloatingHeaderView.java
+++ b/src/com/android/launcher3/allapps/FloatingHeaderView.java
@@ -15,6 +15,8 @@
*/
package com.android.launcher3.allapps;
+import static com.android.launcher3.allapps.FloatingHeaderRow.NO_ROWS;
+
import android.animation.ValueAnimator;
import android.content.Context;
import android.graphics.Point;
@@ -109,11 +111,11 @@
// This is initialized once during inflation and stays constant after that. Fixed views
// cannot be added or removed dynamically.
- private FloatingHeaderRow[] mFixedRows = FloatingHeaderRow.NO_ROWS;
+ private FloatingHeaderRow[] mFixedRows = NO_ROWS;
// Array of all fixed rows and plugin rows. This is initialized every time a plugin is
// enabled or disabled, and represent the current set of all rows.
- private FloatingHeaderRow[] mAllRows = FloatingHeaderRow.NO_ROWS;
+ private FloatingHeaderRow[] mAllRows = NO_ROWS;
public FloatingHeaderView(@NonNull Context context) {
this(context, null);
@@ -180,6 +182,10 @@
@Override
public void onPluginConnected(AllAppsRow allAppsRowPlugin, Context context) {
+ if (mPluginRows.containsKey(allAppsRowPlugin)) {
+ // Plugin has already been connected
+ return;
+ }
PluginHeaderRow headerRow = new PluginHeaderRow(allAppsRowPlugin, this);
addView(headerRow.mView, indexOfChild(mTabLayout));
mPluginRows.put(allAppsRowPlugin, headerRow);
@@ -211,6 +217,9 @@
@Override
public void onPluginDisconnected(AllAppsRow plugin) {
PluginHeaderRow row = mPluginRows.get(plugin);
+ if (row == null) {
+ return;
+ }
removeView(row.mView);
mPluginRows.remove(plugin);
recreateAllRowsArray();
diff --git a/src/com/android/launcher3/allapps/WorkProfileManager.java b/src/com/android/launcher3/allapps/WorkProfileManager.java
index 96998a3..3d0c1d0 100644
--- a/src/com/android/launcher3/allapps/WorkProfileManager.java
+++ b/src/com/android/launcher3/allapps/WorkProfileManager.java
@@ -58,7 +58,7 @@
implements PersonalWorkSlidingTabStrip.OnActivePageChangedListener {
private static final String TAG = "WorkProfileManager";
private final ActivityAllAppsContainerView<?> mAllApps;
- private WorkModeSwitch mWorkModeSwitch;
+ private WorkUtilityView mWorkUtilityView;
private final Predicate<UserHandle> mWorkProfileMatcher;
public WorkProfileManager(
@@ -79,15 +79,15 @@
@Override
public void onActivePageChanged(int page) {
- updateWorkFAB(page);
+ updateWorkUtilityViews(page);
}
- private void updateWorkFAB(int page) {
- if (mWorkModeSwitch != null) {
+ private void updateWorkUtilityViews(int page) {
+ if (mWorkUtilityView != null) {
if (page == MAIN || page == SEARCH) {
- mWorkModeSwitch.animateVisibility(false);
+ mWorkUtilityView.animateVisibility(false);
} else if (page == WORK && getCurrentState() == STATE_ENABLED) {
- mWorkModeSwitch.animateVisibility(true);
+ mWorkUtilityView.animateVisibility(true);
}
}
}
@@ -104,10 +104,10 @@
}
boolean isEnabled = !mAllApps.getAppsStore().hasModelFlag(quietModeFlag);
updateCurrentState(isEnabled ? STATE_ENABLED : STATE_DISABLED);
- if (mWorkModeSwitch != null) {
+ if (mWorkUtilityView != null) {
// reset the position of the button and clear IME insets.
- mWorkModeSwitch.getImeInsets().setEmpty();
- mWorkModeSwitch.updateTranslationY();
+ mWorkUtilityView.getImeInsets().setEmpty();
+ mWorkUtilityView.updateTranslationY();
}
}
@@ -116,54 +116,54 @@
if (getAH() != null) {
getAH().mAppsList.updateAdapterItems();
}
- if (mWorkModeSwitch != null) {
- updateWorkFAB(mAllApps.getCurrentPage());
+ if (mWorkUtilityView != null) {
+ updateWorkUtilityViews(mAllApps.getCurrentPage());
}
if (getCurrentState() == STATE_ENABLED) {
- attachWorkModeSwitch();
+ attachWorkUtilityViews();
} else if (getCurrentState() == STATE_DISABLED) {
- detachWorkModeSwitch();
+ detachWorkUtilityViews();
}
}
/**
* Creates and attaches for profile toggle button to {@link ActivityAllAppsContainerView}
*/
- public boolean attachWorkModeSwitch() {
+ public boolean attachWorkUtilityViews() {
if (!mAllApps.getAppsStore().hasModelFlag(
FLAG_HAS_SHORTCUT_PERMISSION | FLAG_QUIET_MODE_CHANGE_PERMISSION)) {
Log.e(TAG, "unable to attach work mode switch; Missing required permissions");
return false;
}
- if (mWorkModeSwitch == null) {
- mWorkModeSwitch = (WorkModeSwitch) mAllApps.getLayoutInflater().inflate(
- R.layout.work_mode_fab, mAllApps, false);
+ if (mWorkUtilityView == null) {
+ mWorkUtilityView = (WorkUtilityView) mAllApps.getLayoutInflater().inflate(
+ R.layout.work_mode_utility_view, mAllApps, false);
}
- if (mWorkModeSwitch.getParent() == null) {
- mAllApps.addView(mWorkModeSwitch);
+ if (mWorkUtilityView.getParent() == null) {
+ mAllApps.addView(mWorkUtilityView);
}
if (mAllApps.getCurrentPage() != WORK) {
- mWorkModeSwitch.animateVisibility(false);
+ mWorkUtilityView.animateVisibility(false);
}
if (getAH() != null) {
getAH().applyPadding();
}
- mWorkModeSwitch.setOnClickListener(this::onWorkFabClicked);
+ mWorkUtilityView.setOnClickListener(this::onWorkFabClicked);
return true;
}
/**
* Removes work profile toggle button from {@link ActivityAllAppsContainerView}
*/
- public void detachWorkModeSwitch() {
- if (mWorkModeSwitch != null && mWorkModeSwitch.getParent() == mAllApps) {
- mAllApps.removeView(mWorkModeSwitch);
+ public void detachWorkUtilityViews() {
+ if (mWorkUtilityView != null && mWorkUtilityView.getParent() == mAllApps) {
+ mAllApps.removeView(mWorkUtilityView);
}
- mWorkModeSwitch = null;
+ mWorkUtilityView = null;
}
@Nullable
- public WorkModeSwitch getWorkModeSwitch() {
- return mWorkModeSwitch;
+ public WorkUtilityView getWorkUtilityView() {
+ return mWorkUtilityView;
}
private ActivityAllAppsContainerView.AdapterHolder getAH() {
@@ -199,7 +199,7 @@
}
private void onWorkFabClicked(View view) {
- if (getCurrentState() == STATE_ENABLED && mWorkModeSwitch.isEnabled()) {
+ if (getCurrentState() == STATE_ENABLED && mWorkUtilityView.isEnabled()) {
logEvents(LAUNCHER_TURN_OFF_WORK_APPS_TAP);
setWorkProfileEnabled(false);
}
@@ -216,7 +216,7 @@
}
@Override
public void onScrolled(@NonNull RecyclerView recyclerView, int dx, int dy) {
- WorkModeSwitch fab = getWorkModeSwitch();
+ WorkUtilityView fab = getWorkUtilityView();
if (fab == null){
return;
}
diff --git a/src/com/android/launcher3/allapps/WorkModeSwitch.java b/src/com/android/launcher3/allapps/WorkUtilityView.java
similarity index 65%
rename from src/com/android/launcher3/allapps/WorkModeSwitch.java
rename to src/com/android/launcher3/allapps/WorkUtilityView.java
index f1f72b2..4b58ab0 100644
--- a/src/com/android/launcher3/allapps/WorkModeSwitch.java
+++ b/src/com/android/launcher3/allapps/WorkUtilityView.java
@@ -21,11 +21,13 @@
import android.animation.ObjectAnimator;
import android.animation.ValueAnimator;
import android.content.Context;
+import android.content.Intent;
import android.graphics.Rect;
import android.text.TextUtils;
import android.util.AttributeSet;
import android.view.ViewGroup;
import android.view.WindowInsets;
+import android.widget.ImageButton;
import android.widget.ImageView;
import android.widget.LinearLayout;
import android.widget.TextView;
@@ -36,6 +38,7 @@
import com.android.app.animation.Interpolators;
import com.android.launcher3.DeviceProfile;
+import com.android.launcher3.Flags;
import com.android.launcher3.Insettable;
import com.android.launcher3.R;
import com.android.launcher3.Utilities;
@@ -43,10 +46,13 @@
import com.android.launcher3.anim.KeyboardInsetAnimationCallback;
import com.android.launcher3.model.StringCache;
import com.android.launcher3.views.ActivityContext;
+
+import java.util.ArrayList;
+
/**
- * Work profile toggle switch shown at the bottom of AllApps work tab
+ * Work profile utility ViewGroup that is shown at the bottom of AllApps work tab
*/
-public class WorkModeSwitch extends LinearLayout implements Insettable,
+public class WorkUtilityView extends LinearLayout implements Insettable,
KeyboardInsetAnimationCallback.KeyboardInsetListener {
private static final int TEXT_EXPAND_OPACITY_DURATION = 300;
@@ -54,10 +60,14 @@
private static final int EXPAND_COLLAPSE_DURATION = 300;
private static final int TEXT_ALPHA_EXPAND_DELAY = 80;
private static final int TEXT_ALPHA_COLLAPSE_DELAY = 0;
+ private static final int WORK_SCHEDULER_OPACITY_DURATION =
+ (int) (EXPAND_COLLAPSE_DURATION * 0.75f);
private static final int FLAG_FADE_ONGOING = 1 << 1;
private static final int FLAG_TRANSLATION_ONGOING = 1 << 2;
private static final int FLAG_IS_EXPAND = 1 << 3;
private static final int SCROLL_THRESHOLD_DP = 10;
+ private static final float WORK_SCHEDULER_SCALE_MIN = 0.25f;
+ private static final float WORK_SCHEDULER_SCALE_MAX = 1f;
private final Rect mInsets = new Rect();
private final Rect mImeInsets = new Rect();
@@ -67,22 +77,25 @@
private final int mTextMarginStart;
private final int mTextMarginEnd;
private final int mIconMarginStart;
+ private final String mWorkSchedulerIntentAction;
// Threshold when user scrolls up/down to determine when should button extend/collapse
private final int mScrollThreshold;
- private TextView mTextView;
- private ImageView mIcon;
private ValueAnimator mPauseFABAnim;
+ private TextView mPauseText;
+ private ImageView mWorkIcon;
+ private ImageButton mSchedulerButton;
- public WorkModeSwitch(@NonNull Context context) {
+ public WorkUtilityView(@NonNull Context context) {
this(context, null, 0);
}
- public WorkModeSwitch(@NonNull Context context, @NonNull AttributeSet attrs) {
+ public WorkUtilityView(@NonNull Context context, @NonNull AttributeSet attrs) {
this(context, attrs, 0);
}
- public WorkModeSwitch(@NonNull Context context, @NonNull AttributeSet attrs, int defStyleAttr) {
+ public WorkUtilityView(@NonNull Context context, @NonNull AttributeSet attrs,
+ int defStyleAttr) {
super(context, attrs, defStyleAttr);
mContext = context;
mScrollThreshold = Utilities.dpToPx(SCROLL_THRESHOLD_DP);
@@ -93,14 +106,17 @@
R.dimen.work_fab_text_end_margin);
mIconMarginStart = mContext.getResources().getDimensionPixelSize(
R.dimen.work_fab_icon_start_margin_expanded);
+ mWorkSchedulerIntentAction = mContext.getResources().getString(
+ R.string.work_profile_scheduler_intent);
}
@Override
protected void onFinishInflate() {
super.onFinishInflate();
- mTextView = findViewById(R.id.pause_text);
- mIcon = findViewById(R.id.work_icon);
+ mPauseText = findViewById(R.id.pause_text);
+ mWorkIcon = findViewById(R.id.work_icon);
+ mSchedulerButton = findViewById(R.id.work_scheduler);
setSelected(true);
KeyboardInsetAnimationCallback keyboardInsetAnimationCallback =
new KeyboardInsetAnimationCallback(this);
@@ -109,6 +125,12 @@
addFlag(FLAG_IS_EXPAND);
setInsets(mActivityContext.getDeviceProfile().getInsets());
updateStringFromCache();
+ mSchedulerButton.setVisibility(GONE);
+ if (shouldUseScheduler()) {
+ mSchedulerButton.setVisibility(VISIBLE);
+ mSchedulerButton.setOnClickListener(view ->
+ mContext.startActivity(new Intent(mWorkSchedulerIntentAction)));
+ }
}
@Override
@@ -166,8 +188,10 @@
WindowInsetsCompat.toWindowInsetsCompat(insets, this);
if (windowInsetsCompat.isVisible(WindowInsetsCompat.Type.ime())) {
setInsets(mImeInsets, windowInsetsCompat.getInsets(WindowInsetsCompat.Type.ime()));
+ shrink();
} else {
mImeInsets.setEmpty();
+ extend();
}
updateTranslationY();
return super.onApplyWindowInsets(insets);
@@ -183,15 +207,63 @@
super.setTranslationY(Math.min(translationY, -mInsets.bottom));
}
+ private ValueAnimator animateSchedulerScale(boolean isExpanding) {
+ float scaleFrom = isExpanding ? WORK_SCHEDULER_SCALE_MIN : WORK_SCHEDULER_SCALE_MAX;
+ float scaleTo = isExpanding ? WORK_SCHEDULER_SCALE_MAX : WORK_SCHEDULER_SCALE_MIN;
+ ValueAnimator schedulerScaleAnim = ObjectAnimator.ofFloat(scaleFrom, scaleTo);
+ schedulerScaleAnim.setDuration(EXPAND_COLLAPSE_DURATION);
+ schedulerScaleAnim.setInterpolator(Interpolators.STANDARD);
+ schedulerScaleAnim.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
+ @Override
+ public void onAnimationUpdate(ValueAnimator valueAnimator) {
+ float scale = (float) valueAnimator.getAnimatedValue();
+ mSchedulerButton.setScaleX(scale);
+ mSchedulerButton.setScaleY(scale);
+ }
+ });
+ schedulerScaleAnim.addListener(new AnimatorListenerAdapter() {
+ @Override
+ public void onAnimationStart(Animator animation) {
+ if (isExpanding) {
+ mSchedulerButton.setVisibility(VISIBLE);
+ }
+ }
- private void animatePillTransition(boolean isExpanding) {
+ @Override
+ public void onAnimationEnd(Animator animation) {
+ if (!isExpanding) {
+ mSchedulerButton.setVisibility(GONE);
+ }
+ }
+ });
+ return schedulerScaleAnim;
+ }
+
+ private ValueAnimator animateSchedulerAlpha(boolean isExpanding) {
+ float alphaFrom = isExpanding ? 0 : 1;
+ float alphaTo = isExpanding ? 1 : 0;
+ ValueAnimator schedulerAlphaAnim = ObjectAnimator.ofFloat(alphaFrom, alphaTo);
+ schedulerAlphaAnim.setDuration(WORK_SCHEDULER_OPACITY_DURATION);
+ schedulerAlphaAnim.setStartDelay(isExpanding ? 0 :
+ EXPAND_COLLAPSE_DURATION - WORK_SCHEDULER_OPACITY_DURATION);
+ schedulerAlphaAnim.setInterpolator(Interpolators.STANDARD);
+ schedulerAlphaAnim.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
+ @Override
+ public void onAnimationUpdate(ValueAnimator valueAnimator) {
+ mSchedulerButton.setAlpha((float) valueAnimator.getAnimatedValue());
+ }
+ });
+ return schedulerAlphaAnim;
+ }
+
+ private void animateWorkUtilityViews(boolean isExpanding) {
if (!shouldAnimate(isExpanding)) {
return;
}
AnimatorSet animatorSet = new AnimatedPropertySetter().buildAnim();
- mTextView.measure(0,0);
- int currentWidth = mTextView.getWidth();
- int fullWidth = mTextView.getMeasuredWidth();
+ mPauseText.measure(0,0);
+ int currentWidth = mPauseText.getWidth();
+ int fullWidth = mPauseText.getMeasuredWidth();
float from = isExpanding ? 0 : currentWidth;
float to = isExpanding ? fullWidth : 0;
mPauseFABAnim = ObjectAnimator.ofFloat(from, to);
@@ -203,15 +275,15 @@
float translation = (float) valueAnimator.getAnimatedValue();
float translationFraction = translation / fullWidth;
ViewGroup.MarginLayoutParams textViewLayoutParams =
- (ViewGroup.MarginLayoutParams) mTextView.getLayoutParams();
+ (ViewGroup.MarginLayoutParams) mPauseText.getLayoutParams();
textViewLayoutParams.width = (int) translation;
textViewLayoutParams.setMarginStart((int) (mTextMarginStart * translationFraction));
textViewLayoutParams.setMarginEnd((int) (mTextMarginEnd * translationFraction));
- mTextView.setLayoutParams(textViewLayoutParams);
+ mPauseText.setLayoutParams(textViewLayoutParams);
ViewGroup.MarginLayoutParams iconLayoutParams =
- (ViewGroup.MarginLayoutParams) mIcon.getLayoutParams();
+ (ViewGroup.MarginLayoutParams) mWorkIcon.getLayoutParams();
iconLayoutParams.setMarginStart((int) (mIconMarginStart * translationFraction));
- mIcon.setLayoutParams(iconLayoutParams);
+ mWorkIcon.setLayoutParams(iconLayoutParams);
}
});
mPauseFABAnim.addListener(new AnimatorListenerAdapter() {
@@ -220,21 +292,28 @@
if (isExpanding) {
addFlag(FLAG_IS_EXPAND);
} else {
- mTextView.setVisibility(GONE);
+ mPauseText.setVisibility(GONE);
removeFlag(FLAG_IS_EXPAND);
}
- mTextView.setHorizontallyScrolling(false);
- mTextView.setEllipsize(TextUtils.TruncateAt.END);
+ mPauseText.setHorizontallyScrolling(false);
+ mPauseText.setEllipsize(TextUtils.TruncateAt.END);
}
@Override
public void onAnimationStart(Animator animator) {
- mTextView.setHorizontallyScrolling(true);
- mTextView.setVisibility(VISIBLE);
- mTextView.setEllipsize(null);
+ mPauseText.setHorizontallyScrolling(true);
+ mPauseText.setVisibility(VISIBLE);
+ mPauseText.setEllipsize(null);
}
});
- animatorSet.playTogether(mPauseFABAnim, updatePauseTextAlpha(isExpanding));
+ ArrayList<Animator> animatorList = new ArrayList<>();
+ animatorList.add(mPauseFABAnim);
+ animatorList.add(updatePauseTextAlpha(isExpanding));
+ if (shouldUseScheduler()) {
+ animatorList.add(animateSchedulerScale(isExpanding));
+ animatorList.add(animateSchedulerAlpha(isExpanding));
+ }
+ animatorSet.playTogether(animatorList);
animatorSet.start();
}
@@ -250,7 +329,7 @@
alphaAnim.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
@Override
public void onAnimationUpdate(ValueAnimator valueAnimator) {
- mTextView.setAlpha((float) valueAnimator.getAnimatedValue());
+ mPauseText.setAlpha((float) valueAnimator.getAnimatedValue());
}
});
return alphaAnim;
@@ -287,11 +366,11 @@
}
public void extend() {
- animatePillTransition(true);
+ animateWorkUtilityViews(true);
}
- public void shrink(){
- animatePillTransition(false);
+ public void shrink() {
+ animateWorkUtilityViews(false);
}
/**
@@ -310,7 +389,11 @@
public void updateStringFromCache(){
StringCache cache = mActivityContext.getStringCache();
if (cache != null) {
- mTextView.setText(cache.workProfilePauseButton);
+ mPauseText.setText(cache.workProfilePauseButton);
}
}
+
+ private boolean shouldUseScheduler() {
+ return Flags.workSchedulerInWorkProfile() && !mWorkSchedulerIntentAction.isEmpty();
+ }
}
diff --git a/src/com/android/launcher3/contextualeducation/ContextualEduStatsManager.java b/src/com/android/launcher3/contextualeducation/ContextualEduStatsManager.java
index da13546..5664174 100644
--- a/src/com/android/launcher3/contextualeducation/ContextualEduStatsManager.java
+++ b/src/com/android/launcher3/contextualeducation/ContextualEduStatsManager.java
@@ -16,22 +16,25 @@
package com.android.launcher3.contextualeducation;
-import static com.android.launcher3.util.MainThreadInitializedObject.forOverride;
-
-import com.android.launcher3.R;
-import com.android.launcher3.util.MainThreadInitializedObject;
-import com.android.launcher3.util.ResourceBasedOverride;
-import com.android.launcher3.util.SafeCloseable;
+import com.android.launcher3.dagger.LauncherAppSingleton;
+import com.android.launcher3.dagger.LauncherBaseAppComponent;
+import com.android.launcher3.util.DaggerSingletonObject;
import com.android.systemui.contextualeducation.GestureType;
+import javax.inject.Inject;
+
/**
* A class to update contextual education data. It is a no-op implementation and could be
- * overridden by changing the resource value [R.string.contextual_edu_manager_class] to provide
- * a real implementation.
+ * overridden through dagger modules to provide a real implementation.
*/
-public class ContextualEduStatsManager implements ResourceBasedOverride, SafeCloseable {
- public static final MainThreadInitializedObject<ContextualEduStatsManager> INSTANCE =
- forOverride(ContextualEduStatsManager.class, R.string.contextual_edu_manager_class);
+@LauncherAppSingleton
+public class ContextualEduStatsManager {
+ public static final DaggerSingletonObject<ContextualEduStatsManager> INSTANCE =
+ new DaggerSingletonObject<>(LauncherBaseAppComponent::getContextualEduStatsManager);
+
+ @Inject
+ public ContextualEduStatsManager() { }
+
/**
* Updates contextual education stats when a gesture is triggered
@@ -40,8 +43,4 @@
*/
public void updateEduStats(boolean isTrackpadGesture, GestureType gestureType) {
}
-
- @Override
- public void close() {
- }
}
diff --git a/src/com/android/launcher3/dagger/LauncherBaseAppComponent.java b/src/com/android/launcher3/dagger/LauncherBaseAppComponent.java
index 0fa275e..fb486f7 100644
--- a/src/com/android/launcher3/dagger/LauncherBaseAppComponent.java
+++ b/src/com/android/launcher3/dagger/LauncherBaseAppComponent.java
@@ -18,14 +18,18 @@
import android.content.Context;
+import com.android.launcher3.contextualeducation.ContextualEduStatsManager;
import com.android.launcher3.graphics.IconShape;
+import com.android.launcher3.model.ItemInstallQueue;
import com.android.launcher3.pm.InstallSessionHelper;
import com.android.launcher3.util.ApiWrapper;
import com.android.launcher3.util.DaggerSingletonTracker;
+import com.android.launcher3.util.MSDLPlayerWrapper;
import com.android.launcher3.util.PackageManagerHelper;
import com.android.launcher3.util.PluginManagerWrapper;
import com.android.launcher3.util.ScreenOnTracker;
import com.android.launcher3.util.SettingsCache;
+import com.android.launcher3.util.VibratorWrapper;
import com.android.launcher3.util.window.RefreshRateTracker;
import com.android.launcher3.widget.custom.CustomWidgetManager;
@@ -42,14 +46,18 @@
public interface LauncherBaseAppComponent {
DaggerSingletonTracker getDaggerSingletonTracker();
ApiWrapper getApiWrapper();
+ ContextualEduStatsManager getContextualEduStatsManager();
CustomWidgetManager getCustomWidgetManager();
IconShape getIconShape();
InstallSessionHelper getInstallSessionHelper();
+ ItemInstallQueue getItemInstallQueue();
RefreshRateTracker getRefreshRateTracker();
ScreenOnTracker getScreenOnTracker();
SettingsCache getSettingsCache();
- PluginManagerWrapper getPluginManagerWrapper();
PackageManagerHelper getPackageManagerHelper();
+ PluginManagerWrapper getPluginManagerWrapper();
+ VibratorWrapper getVibratorWrapper();
+ MSDLPlayerWrapper getMSDLPlayerWrapper();
/** Builder for LauncherBaseAppComponent. */
interface Builder {
diff --git a/src/com/android/launcher3/graphics/PreviewSurfaceRenderer.java b/src/com/android/launcher3/graphics/PreviewSurfaceRenderer.java
index 1dd7d45..3000b25 100644
--- a/src/com/android/launcher3/graphics/PreviewSurfaceRenderer.java
+++ b/src/com/android/launcher3/graphics/PreviewSurfaceRenderer.java
@@ -16,6 +16,8 @@
package com.android.launcher3.graphics;
+import static android.content.res.Configuration.UI_MODE_NIGHT_NO;
+import static android.content.res.Configuration.UI_MODE_NIGHT_YES;
import static android.view.Display.DEFAULT_DISPLAY;
import static com.android.launcher3.LauncherSettings.Favorites.TABLE_NAME;
@@ -25,6 +27,7 @@
import android.app.WallpaperColors;
import android.appwidget.AppWidgetProviderInfo;
import android.content.Context;
+import android.content.res.Configuration;
import android.database.Cursor;
import android.hardware.display.DisplayManager;
import android.os.Bundle;
@@ -84,6 +87,7 @@
private static final String KEY_COLORS = "wallpaper_colors";
private static final String KEY_COLOR_RESOURCE_IDS = "color_resource_ids";
private static final String KEY_COLOR_VALUES = "color_values";
+ private static final String KEY_DARK_MODE = "use_dark_mode";
private Context mContext;
private final IBinder mHostToken;
@@ -95,6 +99,7 @@
private final Display mDisplay;
private final WallpaperColors mWallpaperColors;
private SparseIntArray mPreviewColorOverride;
+ @Nullable private Boolean mDarkMode;
private final RunnableList mLifeCycleTracker;
private final SurfaceControlViewHost mSurfaceControlViewHost;
@@ -235,6 +240,8 @@
}
private void updateColorOverrides(Bundle bundle) {
+ mDarkMode =
+ bundle.containsKey(KEY_DARK_MODE) ? bundle.getBoolean(KEY_DARK_MODE) : null;
int[] ids = bundle.getIntArray(KEY_COLOR_RESOURCE_IDS);
int[] colors = bundle.getIntArray(KEY_COLOR_VALUES);
if (ids != null && colors != null) {
@@ -253,6 +260,18 @@
*/
private Context getPreviewContext() {
Context context = mContext.createDisplayContext(mDisplay);
+ if (mDarkMode != null) {
+ Configuration configuration = new Configuration(
+ context.getResources().getConfiguration());
+ if (mDarkMode) {
+ configuration.uiMode &= ~UI_MODE_NIGHT_NO;
+ configuration.uiMode |= UI_MODE_NIGHT_YES;
+ } else {
+ configuration.uiMode &= ~UI_MODE_NIGHT_YES;
+ configuration.uiMode |= UI_MODE_NIGHT_NO;
+ }
+ context = context.createConfigurationContext(configuration);
+ }
if (Flags.newCustomizationPickerUi()) {
if (mPreviewColorOverride != null) {
LocalColorExtractor.newInstance(context)
@@ -305,7 +324,9 @@
bgModel,
LauncherAppState.getInstance(previewContext).getModel().getModelDelegate(),
new BaseLauncherBinder(LauncherAppState.getInstance(previewContext), bgModel,
- /* bgAllAppsList= */ null, new Callbacks[0])) {
+ /* bgAllAppsList= */ null, new Callbacks[0]),
+ LauncherAppState.getInstance(
+ previewContext).getModel().getWidgetsFilterDataProvider()) {
@Override
public void run() {
diff --git a/src/com/android/launcher3/icons/CacheableShortcutInfo.kt b/src/com/android/launcher3/icons/CacheableShortcutInfo.kt
index f8a5552..a78da23 100644
--- a/src/com/android/launcher3/icons/CacheableShortcutInfo.kt
+++ b/src/com/android/launcher3/icons/CacheableShortcutInfo.kt
@@ -121,7 +121,10 @@
item: CacheableShortcutInfo,
provider: IconProvider,
): String? =
- item.shortcutInfo.lastChangedTimestamp.toString() +
+ // Manifest shortcuts get updated on every reboot. Don't include their change timestamp as
+ // it gets covered by the app's version
+ (if (item.shortcutInfo.isDeclaredInManifest) ""
+ else item.shortcutInfo.lastChangedTimestamp.toString()) +
"-" +
provider.getStateForApp(getApplicationInfo(item))
}
diff --git a/src/com/android/launcher3/icons/MonochromeIconFactory.java b/src/com/android/launcher3/icons/MonochromeIconFactory.java
deleted file mode 100644
index 2854d51..0000000
--- a/src/com/android/launcher3/icons/MonochromeIconFactory.java
+++ /dev/null
@@ -1,172 +0,0 @@
-/*
- * Copyright (C) 2022 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.icons;
-
-import static android.graphics.Paint.FILTER_BITMAP_FLAG;
-
-import android.annotation.TargetApi;
-import android.graphics.Bitmap;
-import android.graphics.Bitmap.Config;
-import android.graphics.BlendMode;
-import android.graphics.Canvas;
-import android.graphics.Color;
-import android.graphics.ColorFilter;
-import android.graphics.ColorMatrix;
-import android.graphics.ColorMatrixColorFilter;
-import android.graphics.Paint;
-import android.graphics.PixelFormat;
-import android.graphics.Rect;
-import android.graphics.drawable.AdaptiveIconDrawable;
-import android.graphics.drawable.Drawable;
-import android.os.Build;
-
-import androidx.annotation.WorkerThread;
-
-import com.android.launcher3.icons.BaseIconFactory.ClippedMonoDrawable;
-
-import java.nio.ByteBuffer;
-
-/**
- * Utility class to generate monochrome icons version for a given drawable.
- */
-@TargetApi(Build.VERSION_CODES.TIRAMISU)
-public class MonochromeIconFactory extends Drawable {
-
- private final Bitmap mFlatBitmap;
- private final Canvas mFlatCanvas;
- private final Paint mCopyPaint;
-
- private final Bitmap mAlphaBitmap;
- private final Canvas mAlphaCanvas;
- private final byte[] mPixels;
-
- private final int mBitmapSize;
- private final int mEdgePixelLength;
-
- private final Paint mDrawPaint;
- private final Rect mSrcRect;
-
- MonochromeIconFactory(int iconBitmapSize) {
- float extraFactor = AdaptiveIconDrawable.getExtraInsetFraction();
- float viewPortScale = 1 / (1 + 2 * extraFactor);
- mBitmapSize = Math.round(iconBitmapSize * 2 * viewPortScale);
- mPixels = new byte[mBitmapSize * mBitmapSize];
- mEdgePixelLength = mBitmapSize * (mBitmapSize - iconBitmapSize) / 2;
-
- mFlatBitmap = Bitmap.createBitmap(mBitmapSize, mBitmapSize, Config.ARGB_8888);
- mFlatCanvas = new Canvas(mFlatBitmap);
-
- mAlphaBitmap = Bitmap.createBitmap(mBitmapSize, mBitmapSize, Config.ALPHA_8);
- mAlphaCanvas = new Canvas(mAlphaBitmap);
-
- mDrawPaint = new Paint(FILTER_BITMAP_FLAG);
- mDrawPaint.setColor(Color.WHITE);
- mSrcRect = new Rect(0, 0, mBitmapSize, mBitmapSize);
-
- mCopyPaint = new Paint(FILTER_BITMAP_FLAG);
- mCopyPaint.setBlendMode(BlendMode.SRC);
-
- // Crate a color matrix which converts the icon to grayscale and then uses the average
- // of RGB components as the alpha component.
- ColorMatrix satMatrix = new ColorMatrix();
- satMatrix.setSaturation(0);
- float[] vals = satMatrix.getArray();
- vals[15] = vals[16] = vals[17] = .3333f;
- vals[18] = vals[19] = 0;
- mCopyPaint.setColorFilter(new ColorMatrixColorFilter(vals));
- }
-
- private void drawDrawable(Drawable drawable) {
- if (drawable != null) {
- drawable.setBounds(0, 0, mBitmapSize, mBitmapSize);
- drawable.draw(mFlatCanvas);
- }
- }
-
- /**
- * Creates a monochrome version of the provided drawable
- */
- @WorkerThread
- public Drawable wrap(AdaptiveIconDrawable icon) {
- mFlatCanvas.drawColor(Color.BLACK);
- drawDrawable(icon.getBackground());
- drawDrawable(icon.getForeground());
- generateMono();
- return new ClippedMonoDrawable(this);
- }
-
- @WorkerThread
- private void generateMono() {
- mAlphaCanvas.drawBitmap(mFlatBitmap, 0, 0, mCopyPaint);
-
- // Scale the end points:
- ByteBuffer buffer = ByteBuffer.wrap(mPixels);
- buffer.rewind();
- mAlphaBitmap.copyPixelsToBuffer(buffer);
-
- int min = 0xFF;
- int max = 0;
- for (byte b : mPixels) {
- min = Math.min(min, b & 0xFF);
- max = Math.max(max, b & 0xFF);
- }
-
- if (min < max) {
- // rescale pixels to increase contrast
- float range = max - min;
-
- // In order to check if the colors should be flipped, we just take the average color
- // of top and bottom edge which should correspond to be background color. If the edge
- // colors have more opacity, we flip the colors;
- int sum = 0;
- for (int i = 0; i < mEdgePixelLength; i++) {
- sum += (mPixels[i] & 0xFF);
- sum += (mPixels[mPixels.length - 1 - i] & 0xFF);
- }
- float edgeAverage = sum / (mEdgePixelLength * 2f);
- float edgeMapped = (edgeAverage - min) / range;
- boolean flipColor = edgeMapped > .5f;
-
- for (int i = 0; i < mPixels.length; i++) {
- int p = mPixels[i] & 0xFF;
- int p2 = Math.round((p - min) * 0xFF / range);
- mPixels[i] = flipColor ? (byte) (255 - p2) : (byte) (p2);
- }
- buffer.rewind();
- mAlphaBitmap.copyPixelsFromBuffer(buffer);
- }
- }
-
- @Override
- public void draw(Canvas canvas) {
- canvas.drawBitmap(mAlphaBitmap, mSrcRect, getBounds(), mDrawPaint);
- }
-
- @Override
- public int getOpacity() {
- return PixelFormat.TRANSLUCENT;
- }
-
- @Override
- public void setAlpha(int i) {
- mDrawPaint.setAlpha(i);
- }
-
- @Override
- public void setColorFilter(ColorFilter colorFilter) {
- mDrawPaint.setColorFilter(colorFilter);
- }
-}
diff --git a/src/com/android/launcher3/logging/StatsLogManager.java b/src/com/android/launcher3/logging/StatsLogManager.java
index e5cd76a..2550ebb 100644
--- a/src/com/android/launcher3/logging/StatsLogManager.java
+++ b/src/com/android/launcher3/logging/StatsLogManager.java
@@ -175,6 +175,10 @@
@UiEvent(doc = "User searched for a widget in the widget picker.")
LAUNCHER_WIDGETSTRAY_SEARCHED(819),
+ @UiEvent(doc = "User clicked on view all button to expand the displayed list in the "
+ + "widget picker.")
+ LAUNCHER_WIDGETSTRAY_EXPAND_PRESS(1978),
+
@UiEvent(doc = "A dragged item is dropped on 'Remove' button in the target bar")
LAUNCHER_ITEM_DROPPED_ON_REMOVE(465),
diff --git a/src/com/android/launcher3/model/BaseLauncherBinder.java b/src/com/android/launcher3/model/BaseLauncherBinder.java
index b51f855..c251114 100644
--- a/src/com/android/launcher3/model/BaseLauncherBinder.java
+++ b/src/com/android/launcher3/model/BaseLauncherBinder.java
@@ -24,6 +24,8 @@
import static com.android.launcher3.util.Executors.MAIN_EXECUTOR;
import static com.android.launcher3.util.Executors.MODEL_EXECUTOR;
+import static java.util.Collections.emptyList;
+
import android.os.Process;
import android.os.Trace;
import android.util.Log;
@@ -43,6 +45,7 @@
import com.android.launcher3.model.data.AppInfo;
import com.android.launcher3.model.data.ItemInfo;
import com.android.launcher3.model.data.LauncherAppWidgetInfo;
+import com.android.launcher3.model.data.PackageItemInfo;
import com.android.launcher3.util.ComponentKey;
import com.android.launcher3.util.IntArray;
import com.android.launcher3.util.IntSet;
@@ -62,6 +65,7 @@
import java.util.Map;
import java.util.Objects;
import java.util.concurrent.Executor;
+import java.util.function.Predicate;
import java.util.stream.Collectors;
/**
@@ -162,9 +166,17 @@
if (!WIDGETS_ENABLED) {
return;
}
+ Map<PackageItemInfo, List<WidgetItem>>
+ widgetsByPackageItem = mBgDataModel.widgetsModel.getWidgetsByPackageItem();
List<WidgetsListBaseEntry> widgets = new WidgetsListBaseEntriesBuilder(mApp.getContext())
- .build(mBgDataModel.widgetsModel.getWidgetsByPackageItem());
- executeCallbacksTask(c -> c.bindAllWidgets(widgets), mUiExecutor);
+ .build(widgetsByPackageItem);
+ Predicate<WidgetItem> filter = mBgDataModel.widgetsModel.getDefaultWidgetsFilter();
+ List<WidgetsListBaseEntry> defaultWidgets =
+ filter != null ? new WidgetsListBaseEntriesBuilder(
+ mApp.getContext()).build(widgetsByPackageItem,
+ mBgDataModel.widgetsModel.getDefaultWidgetsFilter()) : emptyList();
+
+ executeCallbacksTask(c -> c.bindAllWidgets(widgets, defaultWidgets), mUiExecutor);
}
/**
diff --git a/src/com/android/launcher3/model/BgDataModel.java b/src/com/android/launcher3/model/BgDataModel.java
index 9a9fa5b..b9b1e98 100644
--- a/src/com/android/launcher3/model/BgDataModel.java
+++ b/src/com/android/launcher3/model/BgDataModel.java
@@ -537,7 +537,13 @@
default void bindWidgetsRestored(ArrayList<LauncherAppWidgetInfo> widgets) { }
default void bindRestoreItemsChange(HashSet<ItemInfo> updates) { }
default void bindWorkspaceComponentsRemoved(Predicate<ItemInfo> matcher) { }
- default void bindAllWidgets(List<WidgetsListBaseEntry> widgets) { }
+
+ /**
+ * Binds the app widgets to the providers that share widgets with the UI.
+ */
+ default void bindAllWidgets(@NonNull List<WidgetsListBaseEntry> widgets,
+ @NonNull List<WidgetsListBaseEntry> defaultWidgets) {
+ }
default void bindSmartspaceWidget() { }
/** Called when workspace has been bound. */
diff --git a/src/com/android/launcher3/model/GridSizeMigrationDBController.java b/src/com/android/launcher3/model/GridSizeMigrationDBController.java
index bad7577..617cac7 100644
--- a/src/com/android/launcher3/model/GridSizeMigrationDBController.java
+++ b/src/com/android/launcher3/model/GridSizeMigrationDBController.java
@@ -17,7 +17,6 @@
package com.android.launcher3.model;
import static com.android.launcher3.Flags.enableSmartspaceRemovalToggle;
-import static com.android.launcher3.LauncherPrefs.IS_FIRST_LOAD_AFTER_RESTORE;
import static com.android.launcher3.LauncherSettings.Favorites.TABLE_NAME;
import static com.android.launcher3.LauncherSettings.Favorites.TMP_TABLE;
import static com.android.launcher3.Utilities.SHOULD_SHOW_FIRST_PAGE_WIDGET;
@@ -38,7 +37,6 @@
import androidx.annotation.NonNull;
import androidx.annotation.VisibleForTesting;
-import com.android.launcher3.Flags;
import com.android.launcher3.InvariantDeviceProfile;
import com.android.launcher3.LauncherPrefs;
import com.android.launcher3.LauncherSettings;
@@ -86,6 +84,9 @@
if (needsToMigrate) {
Log.i(TAG, "Migration is needed. destDeviceState: " + destDeviceState
+ ", srcDeviceState: " + srcDeviceState);
+ } else {
+ Log.i(TAG, "Migration is not needed. destDeviceState: " + destDeviceState
+ + ", srcDeviceState: " + srcDeviceState);
}
return needsToMigrate;
}
@@ -116,23 +117,16 @@
@NonNull DeviceGridState srcDeviceState,
@NonNull DeviceGridState destDeviceState,
@NonNull DatabaseHelper target,
- @NonNull SQLiteDatabase source) {
-
- Log.i("b/360462379", "Going from " + srcDeviceState.getColumns() + "x"
- + srcDeviceState.getRows());
- Log.i("b/360462379", "Going to " + destDeviceState.getColumns() + "x"
- + destDeviceState.getRows());
+ @NonNull SQLiteDatabase source,
+ boolean isDestNewDb) {
if (!needsToMigrate(srcDeviceState, destDeviceState)) {
- Log.i("b/360462379", "Does not need to migrate.");
return true;
}
- if (LauncherPrefs.get(context).get(IS_FIRST_LOAD_AFTER_RESTORE)
- && Flags.enableGridMigrationFix()
+ if (isDestNewDb
&& srcDeviceState.getColumns().equals(destDeviceState.getColumns())
&& srcDeviceState.getRows() < destDeviceState.getRows()) {
- Log.i("b/360462379", "Grid migration fix entry point.");
// Only use this strategy when comparing the previous grid to the new grid and the
// columns are the same and the destination has more rows
copyTable(source, TABLE_NAME, target.getWritableDatabase(), TABLE_NAME, context);
diff --git a/src/com/android/launcher3/model/GridSizeMigrationLogic.kt b/src/com/android/launcher3/model/GridSizeMigrationLogic.kt
index 9470abf..c856d4b 100644
--- a/src/com/android/launcher3/model/GridSizeMigrationLogic.kt
+++ b/src/com/android/launcher3/model/GridSizeMigrationLogic.kt
@@ -46,6 +46,7 @@
destDeviceState: DeviceGridState,
target: DatabaseHelper,
source: SQLiteDatabase,
+ isDestNewDb: Boolean,
) {
if (!GridSizeMigrationDBController.needsToMigrate(srcDeviceState, destDeviceState)) {
return
@@ -57,7 +58,7 @@
// This is a special case where if the grid is the same amount of columns but a larger
// amount of rows we simply copy over the source grid to the destination grid, rather
// than undergoing the general grid migration.
- if (shouldMigrateToStrictlyTallerGrid(isFirstLoad, srcDeviceState, destDeviceState)) {
+ if (shouldMigrateToStrictlyTallerGrid(isDestNewDb, srcDeviceState, destDeviceState)) {
GridSizeMigrationDBController.copyCurrentGridToNewGrid(
context,
destDeviceState,
@@ -335,11 +336,11 @@
/** Only migrate the grid in this manner if the target grid is taller and not wider. */
private fun shouldMigrateToStrictlyTallerGrid(
- isFirstLoad: Boolean,
+ isDestNewDb: Boolean,
srcDeviceState: DeviceGridState,
destDeviceState: DeviceGridState,
): Boolean {
- return (isFirstLoad && Flags.enableGridMigrationFix()) &&
+ return isDestNewDb &&
srcDeviceState.columns == destDeviceState.columns &&
srcDeviceState.rows < destDeviceState.rows
}
diff --git a/src/com/android/launcher3/model/ItemInstallQueue.java b/src/com/android/launcher3/model/ItemInstallQueue.java
index 49f75eb..f9c6e96 100644
--- a/src/com/android/launcher3/model/ItemInstallQueue.java
+++ b/src/com/android/launcher3/model/ItemInstallQueue.java
@@ -45,16 +45,18 @@
import com.android.launcher3.Launcher;
import com.android.launcher3.LauncherAppState;
import com.android.launcher3.LauncherSettings.Favorites;
+import com.android.launcher3.dagger.ApplicationContext;
+import com.android.launcher3.dagger.LauncherAppSingleton;
+import com.android.launcher3.dagger.LauncherBaseAppComponent;
import com.android.launcher3.logging.FileLog;
import com.android.launcher3.model.data.ItemInfo;
import com.android.launcher3.model.data.LauncherAppWidgetInfo;
import com.android.launcher3.model.data.WorkspaceItemInfo;
import com.android.launcher3.shortcuts.ShortcutKey;
import com.android.launcher3.shortcuts.ShortcutRequest;
-import com.android.launcher3.util.MainThreadInitializedObject;
+import com.android.launcher3.util.DaggerSingletonObject;
import com.android.launcher3.util.PersistedItemArray;
import com.android.launcher3.util.Preconditions;
-import com.android.launcher3.util.SafeCloseable;
import com.android.launcher3.widget.LauncherAppWidgetProviderInfo;
import java.util.HashSet;
@@ -62,10 +64,13 @@
import java.util.stream.Collectors;
import java.util.stream.Stream;
+import javax.inject.Inject;
+
/**
* Class to maintain a queue of pending items to be added to the workspace.
*/
-public class ItemInstallQueue implements SafeCloseable {
+@LauncherAppSingleton
+public class ItemInstallQueue {
private static final String LOG = "ItemInstallQueue";
@@ -81,9 +86,8 @@
public static final int NEW_SHORTCUT_BOUNCE_DURATION = 450;
public static final int NEW_SHORTCUT_STAGGER_DELAY = 85;
- public static MainThreadInitializedObject<ItemInstallQueue> INSTANCE =
- new MainThreadInitializedObject<>(ItemInstallQueue::new);
-
+ public static DaggerSingletonObject<ItemInstallQueue> INSTANCE =
+ new DaggerSingletonObject<>(LauncherBaseAppComponent::getItemInstallQueue);
private final PersistedItemArray<PendingInstallShortcutInfo> mStorage =
new PersistedItemArray<>(APPS_PENDING_INSTALL);
private final Context mContext;
@@ -95,13 +99,11 @@
// Only accessed on worker thread
private List<PendingInstallShortcutInfo> mItems;
- private ItemInstallQueue(Context context) {
+ @Inject
+ public ItemInstallQueue(@ApplicationContext Context context) {
mContext = context;
}
- @Override
- public void close() {}
-
@WorkerThread
private void ensureQueueLoaded() {
Preconditions.assertWorkerThread();
diff --git a/src/com/android/launcher3/model/LoaderTask.java b/src/com/android/launcher3/model/LoaderTask.java
index 06d8b59..a830c96 100644
--- a/src/com/android/launcher3/model/LoaderTask.java
+++ b/src/com/android/launcher3/model/LoaderTask.java
@@ -20,6 +20,7 @@
import static com.android.launcher3.Flags.enableLauncherBrMetricsFixed;
import static com.android.launcher3.Flags.enableSmartspaceAsAWidget;
import static com.android.launcher3.Flags.enableSmartspaceRemovalToggle;
+import static com.android.launcher3.Flags.enableTieredWidgetsByDefaultInPicker;
import static com.android.launcher3.LauncherPrefs.IS_FIRST_LOAD_AFTER_RESTORE;
import static com.android.launcher3.LauncherPrefs.SHOULD_SHOW_SMARTSPACE;
import static com.android.launcher3.LauncherSettings.Favorites.TABLE_NAME;
@@ -142,6 +143,7 @@
private final UserManager mUserManager;
private final UserCache mUserCache;
private final PackageManagerHelper mPmHelper;
+ private final WidgetsFilterDataProvider mWidgetsFilterDataProvider;
private final InstallSessionHelper mSessionHelper;
private final IconCache mIconCache;
@@ -158,13 +160,16 @@
private String mDbName;
public LoaderTask(@NonNull LauncherAppState app, AllAppsList bgAllAppsList, BgDataModel bgModel,
- ModelDelegate modelDelegate, @NonNull BaseLauncherBinder launcherBinder) {
- this(app, bgAllAppsList, bgModel, modelDelegate, launcherBinder, new UserManagerState());
+ ModelDelegate modelDelegate, @NonNull BaseLauncherBinder launcherBinder,
+ @NonNull WidgetsFilterDataProvider widgetsFilterDataProvider) {
+ this(app, bgAllAppsList, bgModel, modelDelegate, launcherBinder, widgetsFilterDataProvider,
+ new UserManagerState());
}
@VisibleForTesting
LoaderTask(@NonNull LauncherAppState app, AllAppsList bgAllAppsList, BgDataModel bgModel,
ModelDelegate modelDelegate, @NonNull BaseLauncherBinder launcherBinder,
+ WidgetsFilterDataProvider widgetsFilterDataProvider,
UserManagerState userManagerState) {
mApp = app;
mBgAllAppsList = bgAllAppsList;
@@ -179,6 +184,7 @@
mIconCache = mApp.getIconCache();
mUserManagerState = userManagerState;
mInstallingPkgsCached = null;
+ mWidgetsFilterDataProvider = widgetsFilterDataProvider;
}
protected synchronized void waitForIdle() {
@@ -330,7 +336,15 @@
verifyNotStopped();
// fourth step
- List<CachedObject> allWidgetsList = mBgDataModel.widgetsModel.update(mApp, null);
+ WidgetsModel widgetsModel = mBgDataModel.widgetsModel;
+ if (enableTieredWidgetsByDefaultInPicker()) {
+ // Begin periodic refresh of filters
+ mWidgetsFilterDataProvider.initPeriodicDataRefresh(
+ mApp.getModel()::onWidgetFiltersLoaded);
+ // And, update model with currently cached data.
+ widgetsModel.updateWidgetFilters(mWidgetsFilterDataProvider);
+ }
+ List<CachedObject> allWidgetsList = widgetsModel.update(mApp, /*packageUser=*/null);
logASplit("load widgets");
verifyNotStopped();
diff --git a/src/com/android/launcher3/model/ModelDbController.java b/src/com/android/launcher3/model/ModelDbController.java
index 094798b..6ff8547 100644
--- a/src/com/android/launcher3/model/ModelDbController.java
+++ b/src/com/android/launcher3/model/ModelDbController.java
@@ -89,6 +89,7 @@
import java.io.File;
import java.io.InputStream;
import java.io.StringReader;
+import java.util.List;
/**
* Utility class which maintains an instance of Launcher database and provides utility methods
@@ -368,6 +369,13 @@
InvariantDeviceProfile idp = LauncherAppState.getIDP(mContext);
DatabaseHelper oldHelper = mOpenHelper;
+
+ // We save the existing db's before creating the destination db helper so we know what logic
+ // to run in grid migration based on if that grid already existed before migration or not.
+ List<String> existingDBs = LauncherFiles.GRID_DB_FILES.stream()
+ .filter(dbName -> mContext.getDatabasePath(dbName).exists())
+ .toList();
+
mOpenHelper = (mContext instanceof SandboxContext) ? oldHelper
: createDatabaseHelper(true, new DeviceGridState(idp).getDbFile());
try {
@@ -376,9 +384,11 @@
// This is the state we want to migrate to that is given by the idp
DeviceGridState destDeviceState = new DeviceGridState(idp);
+ boolean isDestNewDb = !existingDBs.contains(destDeviceState.getDbFile());
+
GridSizeMigrationLogic gridSizeMigrationLogic = new GridSizeMigrationLogic();
gridSizeMigrationLogic.migrateGrid(mContext, srcDeviceState, destDeviceState,
- mOpenHelper, oldHelper.getWritableDatabase());
+ mOpenHelper, oldHelper.getWritableDatabase(), isDestNewDb);
} catch (Exception e) {
resetLauncherDb(restoreEventLogger);
throw new Exception("Failed to migrate grid", e);
@@ -441,6 +451,13 @@
return false;
}
DatabaseHelper oldHelper = mOpenHelper;
+
+ // We save the existing db's before creating the destination db helper so we know what logic
+ // to run in grid migration based on if that grid already existed before migration or not.
+ List<String> existingDBs = LauncherFiles.GRID_DB_FILES.stream()
+ .filter(dbName -> mContext.getDatabasePath(dbName).exists())
+ .toList();
+
mOpenHelper = (mContext instanceof SandboxContext) ? oldHelper
: createDatabaseHelper(true /* forMigration */, targetDbName);
try {
@@ -448,8 +465,11 @@
DeviceGridState srcDeviceState = new DeviceGridState(mContext);
// This is the state we want to migrate to that is given by the idp
DeviceGridState destDeviceState = new DeviceGridState(idp);
+
+ boolean isDestNewDb = !existingDBs.contains(destDeviceState.getDbFile());
+
return GridSizeMigrationDBController.migrateGridIfNeeded(mContext, srcDeviceState,
- destDeviceState, mOpenHelper, oldHelper.getWritableDatabase());
+ destDeviceState, mOpenHelper, oldHelper.getWritableDatabase(), isDestNewDb);
} catch (Exception e) {
FileLog.e(TAG, "Failed to migrate grid", e);
return false;
diff --git a/src/com/android/launcher3/model/ModelTaskController.kt b/src/com/android/launcher3/model/ModelTaskController.kt
index cf2cadc..fc53343 100644
--- a/src/com/android/launcher3/model/ModelTaskController.kt
+++ b/src/com/android/launcher3/model/ModelTaskController.kt
@@ -35,7 +35,7 @@
val dataModel: BgDataModel,
val allAppsList: AllAppsList,
private val model: LauncherModel,
- private val uiExecutor: Executor
+ private val uiExecutor: Executor,
) {
/** Schedules a {@param task} to be executed on the current callbacks. */
@@ -79,10 +79,19 @@
}
fun bindUpdatedWidgets(dataModel: BgDataModel) {
- val widgets =
- WidgetsListBaseEntriesBuilder(app.context)
- .build(dataModel.widgetsModel.widgetsByPackageItem)
- scheduleCallbackTask { it.bindAllWidgets(widgets) }
+ val widgetsByPackageItem = dataModel.widgetsModel.widgetsByPackageItem
+ val allWidgets = WidgetsListBaseEntriesBuilder(app.context).build(widgetsByPackageItem)
+
+ val defaultWidgetsFilter = dataModel.widgetsModel.defaultWidgetsFilter
+ val defaultWidgets =
+ if (defaultWidgetsFilter != null) {
+ WidgetsListBaseEntriesBuilder(app.context)
+ .build(widgetsByPackageItem, defaultWidgetsFilter)
+ } else {
+ emptyList()
+ }
+
+ scheduleCallbackTask { it.bindAllWidgets(allWidgets, defaultWidgets) }
}
fun deleteAndBindComponentsRemoved(matcher: Predicate<ItemInfo?>, reason: String?) {
@@ -99,7 +108,7 @@
val packageUserKeyToUidMap =
apps.associateBy(
keySelector = { PackageUserKey(it.componentName!!.packageName, it.user) },
- valueTransform = { it.uid }
+ valueTransform = { it.uid },
)
scheduleCallbackTask { it.bindAllApplications(apps, flags, packageUserKeyToUidMap) }
}
diff --git a/src/com/android/launcher3/model/WidgetsFilterDataProvider.kt b/src/com/android/launcher3/model/WidgetsFilterDataProvider.kt
new file mode 100644
index 0000000..0571de3
--- /dev/null
+++ b/src/com/android/launcher3/model/WidgetsFilterDataProvider.kt
@@ -0,0 +1,70 @@
+/*
+ * 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.model
+
+import android.content.Context
+import androidx.annotation.WorkerThread
+import com.android.launcher3.R
+import com.android.launcher3.util.ResourceBasedOverride
+import java.util.function.Predicate
+
+/** Helper for the widgets model to load the filters that can be applied to available widgets. */
+open class WidgetsFilterDataProvider(val context: Context) : ResourceBasedOverride {
+ /**
+ * Start regular periodic refresh of widget filtering data starting now (if not started
+ * already).
+ */
+ @WorkerThread
+ open fun initPeriodicDataRefresh(callback: WidgetsFilterLoadedCallback? = null) {
+ // no-op
+ }
+
+ /**
+ * Returns a filter that should be applied to the widget predictions.
+ *
+ * @return null if no filter needs to be applied
+ */
+ @WorkerThread open fun getPredictedWidgetsFilter(): Predicate<WidgetItem>? = null
+
+ /**
+ * Returns a filter that should be applied to the widgets list to see which widgets can be shown
+ * by default.
+ *
+ * @return null if no separate "default" list is supported
+ */
+ @WorkerThread open fun getDefaultWidgetsFilter(): Predicate<WidgetItem>? = null
+
+ /** Called when filter data provider is no longer needed. */
+ open fun destroy() {}
+
+ companion object {
+ /** Returns a new instance of the [WidgetsFilterDataProvider] based on resource override. */
+ fun newInstance(context: Context?): WidgetsFilterDataProvider {
+ return ResourceBasedOverride.Overrides.getObject(
+ WidgetsFilterDataProvider::class.java,
+ context,
+ R.string.widgets_filter_data_provider_class,
+ )
+ }
+ }
+}
+
+/** Interface for the model callback to be invoked when filters are loaded. */
+interface WidgetsFilterLoadedCallback {
+ /** Method called back when widget filters are loaded */
+ fun onWidgetsFilterLoaded()
+}
diff --git a/src/com/android/launcher3/model/WidgetsModel.java b/src/com/android/launcher3/model/WidgetsModel.java
index b450f46..01d4996 100644
--- a/src/com/android/launcher3/model/WidgetsModel.java
+++ b/src/com/android/launcher3/model/WidgetsModel.java
@@ -18,6 +18,8 @@
import android.util.Log;
import android.util.Pair;
+import androidx.annotation.AnyThread;
+import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.collection.ArrayMap;
@@ -65,6 +67,8 @@
/* Map of widgets and shortcuts that are tracked per package. */
private final Map<PackageItemInfo, List<WidgetItem>> mWidgetsByPackageItem = new HashMap<>();
+ @Nullable private Predicate<WidgetItem> mDefaultWidgetsFilter = null;
+ @Nullable private Predicate<WidgetItem> mPredictedWidgetsFilter = null;
/**
* Returns all widgets keyed by their component key.
@@ -92,6 +96,37 @@
}
/**
+ * Returns widget filter that can be applied to {@link WidgetItem}s to check if they can be
+ * shown in the default widgets list.
+ * <p>Returns null if filtering isn't available</p>
+ */
+ @AnyThread
+ public @Nullable Predicate<WidgetItem> getDefaultWidgetsFilter() {
+ return mDefaultWidgetsFilter;
+ }
+
+ /**
+ * Returns widget filter that can be applied to {@link WidgetItem}s to check if they can be
+ * part of widget predictions.
+ * <p>Returns null if filter isn't available</p>
+ */
+ @AnyThread
+ public @Nullable Predicate<WidgetItem> getPredictedWidgetsFilter() {
+ return mPredictedWidgetsFilter;
+ }
+
+ /**
+ * Updates model with latest filter data in cache.
+ */
+ public void updateWidgetFilters(@NonNull WidgetsFilterDataProvider widgetsFilterDataProvider) {
+ if (!WIDGETS_ENABLED) {
+ return;
+ }
+ mDefaultWidgetsFilter = widgetsFilterDataProvider.getDefaultWidgetsFilter();
+ mPredictedWidgetsFilter = widgetsFilterDataProvider.getPredictedWidgetsFilter();
+ }
+
+ /**
* @param packageUser If null, all widgets and shortcuts are updated and returned, otherwise
* only widgets and shortcuts associated with the package/user are.
*/
@@ -299,7 +334,7 @@
if (pInfo == null) {
pInfo = new PackageItemInfo(key.mPackageName, key.mWidgetCategory, key.mUser);
pInfo.user = key.mUser;
- mMap.put(key, pInfo);
+ mMap.put(key, pInfo);
}
return pInfo;
}
diff --git a/src/com/android/launcher3/model/data/WorkspaceItemInfo.java b/src/com/android/launcher3/model/data/WorkspaceItemInfo.java
index f31bf1e..9af61f0 100644
--- a/src/com/android/launcher3/model/data/WorkspaceItemInfo.java
+++ b/src/com/android/launcher3/model/data/WorkspaceItemInfo.java
@@ -189,7 +189,13 @@
if (TextUtils.isEmpty(label)) {
label = shortcutInfo.getShortLabel();
}
- contentDescription = context.getPackageManager().getUserBadgedLabel(label, user);
+ try {
+ contentDescription = context.getPackageManager().getUserBadgedLabel(label, user);
+ } catch (SecurityException e) {
+ contentDescription = null;
+ Log.e(TAG, "Failed to get content description", e);
+ }
+
if (shortcutInfo.isEnabled()) {
runtimeStatusFlags &= ~FLAG_DISABLED_BY_PUBLISHER;
} else {
diff --git a/src/com/android/launcher3/provider/RestoreDbTask.java b/src/com/android/launcher3/provider/RestoreDbTask.java
index 59c27af..8db981f 100644
--- a/src/com/android/launcher3/provider/RestoreDbTask.java
+++ b/src/com/android/launcher3/provider/RestoreDbTask.java
@@ -51,7 +51,6 @@
import androidx.annotation.VisibleForTesting;
import androidx.annotation.WorkerThread;
-import com.android.launcher3.Flags;
import com.android.launcher3.InvariantDeviceProfile;
import com.android.launcher3.LauncherAppState;
import com.android.launcher3.LauncherFiles;
@@ -124,18 +123,14 @@
// executed again.
LauncherPrefs.get(context).removeSync(RESTORE_DEVICE);
- if (Flags.enableNarrowGridRestore()) {
- DeviceGridState deviceGridState = new DeviceGridState(context);
- String oldPhoneFileName = deviceGridState.getDbFile();
- List<String> previousDbs = existingDbs(context);
- removeOldDBs(context, oldPhoneFileName);
- // The idp before this contains data about the old phone, after this it becomes the idp
- // of the current phone.
- idp.reset(context);
- trySettingPreviousGridAsCurrent(context, idp, oldPhoneFileName, previousDbs);
- } else {
- idp.reinitializeAfterRestore(context);
- }
+ DeviceGridState deviceGridState = new DeviceGridState(context);
+ String oldPhoneFileName = deviceGridState.getDbFile();
+ List<String> previousDbs = existingDbs(context);
+ removeOldDBs(context, oldPhoneFileName);
+ // The idp before this contains data about the old phone, after this it becomes the idp
+ // of the current phone.
+ idp.reset(context);
+ trySettingPreviousGridAsCurrent(context, idp, oldPhoneFileName, previousDbs);
}
diff --git a/src/com/android/launcher3/settings/SettingsActivity.java b/src/com/android/launcher3/settings/SettingsActivity.java
index bd9298b..5851f62 100644
--- a/src/com/android/launcher3/settings/SettingsActivity.java
+++ b/src/com/android/launcher3/settings/SettingsActivity.java
@@ -26,6 +26,7 @@
import android.app.Activity;
import android.content.Intent;
+import android.content.pm.ActivityInfo;
import android.net.Uri;
import android.os.Bundle;
import android.provider.Settings;
@@ -66,6 +67,8 @@
@VisibleForTesting
static final String DEVELOPER_OPTIONS_KEY = "pref_developer_options";
+ public static final String FIXED_LANDSCAPE_MODE = "pref_fixed_landscape_mode";
+
private static final String NOTIFICATION_DOTS_PREFERENCE_KEY = "pref_icon_badging";
public static final String EXTRA_FRAGMENT_ARGS = ":settings:fragment_args";
@@ -236,7 +239,7 @@
/**
* Finds the parent preference screen for the given target key.
*
- * @param parent the parent preference screen
+ * @param parent the parent preference screen
* @param targetKey the key of the preference to find
* @return the parent preference screen that contains the target preference
*/
@@ -286,13 +289,14 @@
* will remove that preference from the list.
*/
protected boolean initPreference(Preference preference) {
+ DisplayController.Info info = DisplayController.INSTANCE.get(getContext()).getInfo();
switch (preference.getKey()) {
case NOTIFICATION_DOTS_PREFERENCE_KEY:
return BuildConfig.NOTIFICATION_DOTS_ENABLED;
-
case ALLOW_ROTATION_PREFERENCE_KEY:
- DisplayController.Info info =
- DisplayController.INSTANCE.get(getContext()).getInfo();
+ if (Flags.oneGridSpecs()) {
+ return false;
+ }
if (info.isTablet(info.realBounds)) {
// Launcher supports rotation by default. No need to show this setting.
return false;
@@ -300,14 +304,29 @@
// Initialize the UI once
preference.setDefaultValue(RotationHelper.getAllowRotationDefaultValue(info));
return true;
-
case DEVELOPER_OPTIONS_KEY:
if (IS_STUDIO_BUILD) {
preference.setOrder(0);
}
return mDeveloperOptionsEnabled;
+ case FIXED_LANDSCAPE_MODE:
+ if (!Flags.oneGridSpecs()) {
+ return false;
+ }
+ // When the setting changes rotate the screen accordingly to showcase the result
+ // of the setting
+ preference.setOnPreferenceChangeListener(
+ (pref, newValue) -> {
+ getActivity().setRequestedOrientation(
+ (boolean) newValue
+ ? ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE
+ : ActivityInfo.SCREEN_ORIENTATION_USER
+ );
+ return true;
+ }
+ );
+ return !info.isTablet(info.realBounds);
}
-
return true;
}
diff --git a/src/com/android/launcher3/states/RotationHelper.java b/src/com/android/launcher3/states/RotationHelper.java
index 4c9da5d..7d7ccd3 100644
--- a/src/com/android/launcher3/states/RotationHelper.java
+++ b/src/com/android/launcher3/states/RotationHelper.java
@@ -18,6 +18,7 @@
import static android.content.pm.ActivityInfo.SCREEN_ORIENTATION_LOCKED;
import static android.content.pm.ActivityInfo.SCREEN_ORIENTATION_NOSENSOR;
import static android.content.pm.ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED;
+import static android.content.pm.ActivityInfo.SCREEN_ORIENTATION_USER_LANDSCAPE;
import static android.util.DisplayMetrics.DENSITY_DEVICE_STABLE;
import static com.android.launcher3.LauncherPrefs.ALLOW_ROTATION;
@@ -63,6 +64,8 @@
public static final int REQUEST_ROTATE = 1;
public static final int REQUEST_LOCK = 2;
+ private boolean mIsFixedLandscape = false;
+
@NonNull
private final BaseActivity mActivity;
private final Handler mRequestOrientationHandler;
@@ -163,6 +166,18 @@
notifyChange();
}
+ public boolean isFixedLandscape() {
+ return mIsFixedLandscape;
+ }
+
+ /**
+ * If fixedLandscape is true then the Launcher become landscape until set false..
+ */
+ public void setFixedLandscape(boolean fixedLandscape) {
+ mIsFixedLandscape = fixedLandscape;
+ notifyChange();
+ }
+
// Used by tests only.
public void forceAllowRotationForTesting(boolean allowRotation) {
if (mDestroyed) return;
@@ -203,6 +218,8 @@
SCREEN_ORIENTATION_LOCKED : SCREEN_ORIENTATION_UNSPECIFIED;
} else if (mCurrentStateRequest == REQUEST_LOCK) {
activityFlags = SCREEN_ORIENTATION_LOCKED;
+ } else if (mIsFixedLandscape) {
+ activityFlags = SCREEN_ORIENTATION_USER_LANDSCAPE;
} else if (mIgnoreAutoRotateSettings || mCurrentStateRequest == REQUEST_ROTATE
|| mHomeRotationEnabled || mForceAllowRotationForTesting) {
activityFlags = SCREEN_ORIENTATION_UNSPECIFIED;
diff --git a/src/com/android/launcher3/states/StateAnimationConfig.java b/src/com/android/launcher3/states/StateAnimationConfig.java
index 0ca5afd..2ffbbf4 100644
--- a/src/com/android/launcher3/states/StateAnimationConfig.java
+++ b/src/com/android/launcher3/states/StateAnimationConfig.java
@@ -77,7 +77,6 @@
ANIM_WORKSPACE_PAGE_TRANSLATE_X,
ANIM_OVERVIEW_SPLIT_SELECT_FLOATING_TASK_TRANSLATE_OFFSCREEN,
ANIM_OVERVIEW_SPLIT_SELECT_INSTRUCTIONS_FADE,
- ANIM_ALL_APPS_BOTTOM_SHEET_FADE,
ANIM_ALL_APPS_KEYBOARD_FADE
})
@Retention(RetentionPolicy.SOURCE)
@@ -101,8 +100,7 @@
public static final int ANIM_WORKSPACE_PAGE_TRANSLATE_X = 15;
public static final int ANIM_OVERVIEW_SPLIT_SELECT_FLOATING_TASK_TRANSLATE_OFFSCREEN = 17;
public static final int ANIM_OVERVIEW_SPLIT_SELECT_INSTRUCTIONS_FADE = 18;
- public static final int ANIM_ALL_APPS_BOTTOM_SHEET_FADE = 19;
- public static final int ANIM_ALL_APPS_KEYBOARD_FADE = 20;
+ public static final int ANIM_ALL_APPS_KEYBOARD_FADE = 19;
private static final int ANIM_TYPES_COUNT = 21;
diff --git a/src/com/android/launcher3/touch/AllAppsSwipeController.java b/src/com/android/launcher3/touch/AllAppsSwipeController.java
index 9dcdf22..107bcc1 100644
--- a/src/com/android/launcher3/touch/AllAppsSwipeController.java
+++ b/src/com/android/launcher3/touch/AllAppsSwipeController.java
@@ -198,7 +198,7 @@
* Applies Animation config values for transition from all apps to home.
*/
public static void applyAllAppsToNormalConfig(Launcher launcher, StateAnimationConfig config) {
- if (launcher.getDeviceProfile().isTablet) {
+ if (launcher.getDeviceProfile().shouldShowAllAppsOnSheet()) {
config.setInterpolator(ANIM_SCRIM_FADE,
Interpolators.reverse(ALL_APPS_SCRIM_RESPONDER));
config.setInterpolator(ANIM_ALL_APPS_FADE, FINAL_FRAME);
@@ -240,7 +240,7 @@
*/
public static void applyNormalToAllAppsAnimConfig(
Launcher launcher, StateAnimationConfig config) {
- if (launcher.getDeviceProfile().isTablet) {
+ if (launcher.getDeviceProfile().shouldShowAllAppsOnSheet()) {
config.setInterpolator(ANIM_ALL_APPS_FADE, INSTANT);
config.setInterpolator(ANIM_SCRIM_FADE, ALL_APPS_SCRIM_RESPONDER);
if (!config.isUserControlled()) {
diff --git a/src/com/android/launcher3/util/MSDLPlayerWrapper.java b/src/com/android/launcher3/util/MSDLPlayerWrapper.java
new file mode 100644
index 0000000..1e53ac1
--- /dev/null
+++ b/src/com/android/launcher3/util/MSDLPlayerWrapper.java
@@ -0,0 +1,61 @@
+/*
+ * 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.UI_HELPER_EXECUTOR;
+
+import android.content.Context;
+import android.os.Vibrator;
+
+import com.android.launcher3.dagger.ApplicationContext;
+import com.android.launcher3.dagger.LauncherAppSingleton;
+import com.android.launcher3.dagger.LauncherBaseAppComponent;
+
+import com.google.android.msdl.data.model.MSDLToken;
+import com.google.android.msdl.domain.InteractionProperties;
+import com.google.android.msdl.domain.MSDLPlayer;
+
+import javax.inject.Inject;
+
+/**
+ * Wrapper around {@link com.google.android.msdl.domain.MSDLPlayer} to perform MSDL feedback.
+ */
+@LauncherAppSingleton
+public class MSDLPlayerWrapper {
+
+ public static final DaggerSingletonObject<MSDLPlayerWrapper> INSTANCE =
+ new DaggerSingletonObject<>(LauncherBaseAppComponent::getMSDLPlayerWrapper);
+
+ /** Internal player */
+ private final MSDLPlayer mMSDLPlayer;
+
+ @Inject
+ public MSDLPlayerWrapper(@ApplicationContext Context context) {
+ Vibrator vibrator = context.getSystemService(Vibrator.class);
+ mMSDLPlayer = MSDLPlayer.Companion.createPlayer(vibrator, UI_HELPER_EXECUTOR, null);
+ }
+
+ /** Perform MSDL feedback for a token with interaction properties */
+ public void playToken(MSDLToken token, InteractionProperties properties) {
+ mMSDLPlayer.playToken(token, properties);
+ }
+
+ /** Perform MSDL feedback for a token without properties */
+ public void playToken(MSDLToken token) {
+ mMSDLPlayer.playToken(token, null);
+ }
+}
diff --git a/src/com/android/launcher3/util/SettingsCache.java b/src/com/android/launcher3/util/SettingsCache.java
index 29d5032..8fe6e93 100644
--- a/src/com/android/launcher3/util/SettingsCache.java
+++ b/src/com/android/launcher3/util/SettingsCache.java
@@ -28,6 +28,8 @@
import android.os.Looper;
import android.provider.Settings;
+import androidx.annotation.UiThread;
+
import com.android.launcher3.dagger.ApplicationContext;
import com.android.launcher3.dagger.LauncherAppSingleton;
import com.android.launcher3.dagger.LauncherBaseAppComponent;
@@ -140,7 +142,9 @@
* Does not de-dupe if you add same listeners for the same key multiple times.
* Unregister once complete using {@link #unregister(Uri, OnChangeListener)}
*/
+ @UiThread
public void register(Uri uri, OnChangeListener changeListener) {
+ Preconditions.assertUIThread();
if (mListenerMap.containsKey(uri)) {
mListenerMap.get(uri).add(changeListener);
} else {
diff --git a/src/com/android/launcher3/util/VibratorWrapper.java b/src/com/android/launcher3/util/VibratorWrapper.java
index adb8f9d..39c9c42 100644
--- a/src/com/android/launcher3/util/VibratorWrapper.java
+++ b/src/com/android/launcher3/util/VibratorWrapper.java
@@ -19,6 +19,7 @@
import static android.os.VibrationEffect.createPredefined;
import static android.provider.Settings.System.HAPTIC_FEEDBACK_ENABLED;
+import static com.android.launcher3.util.Executors.MAIN_EXECUTOR;
import static com.android.launcher3.util.Executors.UI_HELPER_EXECUTOR;
import android.annotation.SuppressLint;
@@ -31,13 +32,20 @@
import androidx.annotation.VisibleForTesting;
+import com.android.launcher3.dagger.ApplicationContext;
+import com.android.launcher3.dagger.LauncherAppSingleton;
+import com.android.launcher3.dagger.LauncherBaseAppComponent;
+
+import javax.inject.Inject;
+
/**
* Wrapper around {@link Vibrator} to easily perform haptic feedback where necessary.
*/
-public class VibratorWrapper implements SafeCloseable {
+@LauncherAppSingleton
+public class VibratorWrapper {
- public static final MainThreadInitializedObject<VibratorWrapper> INSTANCE =
- new MainThreadInitializedObject<>(VibratorWrapper::new);
+ public static final DaggerSingletonObject<VibratorWrapper> INSTANCE =
+ new DaggerSingletonObject<>(LauncherBaseAppComponent::getVibratorWrapper);
public static final AudioAttributes VIBRATION_ATTRS = new AudioAttributes.Builder()
.setUsage(AudioAttributes.USAGE_ASSISTANCE_SONIFICATION)
@@ -59,38 +67,29 @@
private final Vibrator mVibrator;
private final boolean mHasVibrator;
- private final SettingsCache mSettingsCache;
-
@VisibleForTesting
final SettingsCache.OnChangeListener mHapticChangeListener =
isEnabled -> mIsHapticFeedbackEnabled = isEnabled;
private boolean mIsHapticFeedbackEnabled;
- private VibratorWrapper(Context context) {
- this(context.getSystemService(Vibrator.class), SettingsCache.INSTANCE.get(context));
- }
+ @Inject
+ public VibratorWrapper(@ApplicationContext Context context, SettingsCache settingsCache,
+ DaggerSingletonTracker tracker) {
- @VisibleForTesting
- VibratorWrapper(Vibrator vibrator, SettingsCache settingsCache) {
- mVibrator = vibrator;
+ mVibrator = context.getSystemService(Vibrator.class);
mHasVibrator = mVibrator.hasVibrator();
- mSettingsCache = settingsCache;
if (mHasVibrator) {
- mSettingsCache.register(HAPTIC_FEEDBACK_URI, mHapticChangeListener);
- mIsHapticFeedbackEnabled = mSettingsCache.getValue(HAPTIC_FEEDBACK_URI, 0);
+ MAIN_EXECUTOR.execute(
+ () -> settingsCache.register(HAPTIC_FEEDBACK_URI, mHapticChangeListener));
+ mIsHapticFeedbackEnabled = settingsCache.getValue(HAPTIC_FEEDBACK_URI, 0);
+ tracker.addCloseable(
+ () -> settingsCache.unregister(HAPTIC_FEEDBACK_URI, mHapticChangeListener));
} else {
mIsHapticFeedbackEnabled = false;
}
}
- @Override
- public void close() {
- if (mHasVibrator) {
- mSettingsCache.unregister(HAPTIC_FEEDBACK_URI, mHapticChangeListener);
- }
- }
-
/**
* This should be used to cancel a haptic in case where the haptic shouldn't be vibrating. For
* example, when no animation is happening but a vibrator happens to be vibrating still.
diff --git a/src/com/android/launcher3/views/AbstractSlideInView.java b/src/com/android/launcher3/views/AbstractSlideInView.java
index 85aad89..65d02d0 100644
--- a/src/com/android/launcher3/views/AbstractSlideInView.java
+++ b/src/com/android/launcher3/views/AbstractSlideInView.java
@@ -298,8 +298,7 @@
@RequiresApi(Build.VERSION_CODES.UPSIDE_DOWN_CAKE)
public void onBackProgressed(BackEvent backEvent) {
final float progress = backEvent.getProgress();
- float deceleratedProgress = Interpolators.BACK_GESTURE.getInterpolation(progress);
- mSwipeToDismissProgress.updateValue(deceleratedProgress);
+ mSwipeToDismissProgress.updateValue(progress);
}
/**
diff --git a/src/com/android/launcher3/widget/model/WidgetsListExpandActionEntry.java b/src/com/android/launcher3/widget/model/WidgetsListExpandActionEntry.java
new file mode 100644
index 0000000..8c84030
--- /dev/null
+++ b/src/com/android/launcher3/widget/model/WidgetsListExpandActionEntry.java
@@ -0,0 +1,38 @@
+/*
+ * 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.widget.model;
+
+import android.os.Process;
+
+import com.android.launcher3.model.data.PackageItemInfo;
+
+import java.util.Collections;
+
+/**
+ * Binds the section to be displayed at the bottom of the widgets list that enables user to expand
+ * and view all the widget apps including non-default. Bound when
+ * {@link WidgetsListExpandActionEntry} exists in the list on adapter.
+ */
+public class WidgetsListExpandActionEntry extends WidgetsListBaseEntry {
+
+ public WidgetsListExpandActionEntry() {
+ super(/*pkgItem=*/ new PackageItemInfo(/* packageName= */ "", Process.myUserHandle()),
+ /*titleSectionName=*/ "",
+ /*items=*/ Collections.EMPTY_LIST);
+ mPkgItem.title = "";
+ }
+}
diff --git a/src/com/android/launcher3/widget/picker/WidgetsFullSheet.java b/src/com/android/launcher3/widget/picker/WidgetsFullSheet.java
index 1860977..2f64ab1 100644
--- a/src/com/android/launcher3/widget/picker/WidgetsFullSheet.java
+++ b/src/com/android/launcher3/widget/picker/WidgetsFullSheet.java
@@ -16,12 +16,16 @@
package com.android.launcher3.widget.picker;
import static com.android.launcher3.Flags.enableCategorizedWidgetSuggestions;
+import static com.android.launcher3.Flags.enableTieredWidgetsByDefaultInPicker;
import static com.android.launcher3.Flags.enableUnfoldedTwoPanePicker;
import static com.android.launcher3.allapps.ActivityAllAppsContainerView.AdapterHolder.SEARCH;
+import static com.android.launcher3.logging.StatsLogManager.LauncherEvent.LAUNCHER_WIDGETSTRAY_EXPAND_PRESS;
import static com.android.launcher3.logging.StatsLogManager.LauncherEvent.LAUNCHER_WIDGETSTRAY_SEARCHED;
import static com.android.launcher3.testing.shared.TestProtocol.NORMAL_STATE_ORDINAL;
import static com.android.launcher3.views.RecyclerViewFastScroller.FastScrollerLocation.WIDGET_SCROLLER;
+import static java.util.Collections.emptyList;
+
import android.animation.Animator;
import android.content.Context;
import android.content.res.Resources;
@@ -68,6 +72,7 @@
import com.android.launcher3.widget.BaseWidgetSheet;
import com.android.launcher3.widget.WidgetCell;
import com.android.launcher3.widget.model.WidgetsListBaseEntry;
+import com.android.launcher3.widget.picker.model.data.WidgetPickerData;
import com.android.launcher3.widget.picker.search.SearchModeListener;
import com.android.launcher3.widget.picker.search.WidgetsSearchBar;
import com.android.launcher3.widget.picker.search.WidgetsSearchBar.WidgetsSearchDataProvider;
@@ -87,7 +92,8 @@
*/
public class WidgetsFullSheet extends BaseWidgetSheet
implements OnActivePageChangedListener,
- WidgetsRecyclerView.HeaderViewDimensionsProvider, SearchModeListener {
+ WidgetsRecyclerView.HeaderViewDimensionsProvider, SearchModeListener,
+ WidgetsListAdapter.ExpandButtonClickListener {
private static final long FADE_IN_DURATION = 150;
@@ -257,7 +263,13 @@
mSearchBar.initialize(new WidgetsSearchDataProvider() {
@Override
public List<WidgetsListBaseEntry> getWidgets() {
- return getWidgetsToDisplay();
+ if (enableTieredWidgetsByDefaultInPicker()) {
+ // search all
+ return mActivityContext.getWidgetPickerDataProvider().get().getAllWidgets();
+ } else {
+ // Can be removed when inlining enableTieredWidgetsByDefaultInPicker flag
+ return getWidgetsToDisplay();
+ }
}
}, /* searchModeListener= */ this);
}
@@ -482,6 +494,9 @@
/**
* Returns all displayable widgets.
*/
+ // Used by the two pane sheet to show 3-dot menu to toggle between default lists and all lists
+ // when enableTieredWidgetsByDefaultInPicker is OFF. This code path and the 3-dot menu can be
+ // safely deleted when it's alternative "enableTieredWidgetsByDefaultInPicker" flag is inlined.
protected List<WidgetsListBaseEntry> getWidgetsToDisplay() {
return mActivityContext.getWidgetPickerDataProvider().get().getAllWidgets();
}
@@ -491,16 +506,27 @@
if (mIsInSearchMode) {
return;
}
- List<WidgetsListBaseEntry> widgets = getWidgetsToDisplay();
+ List<WidgetsListBaseEntry> widgets;
+ List<WidgetsListBaseEntry> defaultWidgets = emptyList();
+
+ if (enableTieredWidgetsByDefaultInPicker()) {
+ WidgetPickerData dataProvider =
+ mActivityContext.getWidgetPickerDataProvider().get();
+ widgets = dataProvider.getAllWidgets();
+ defaultWidgets = dataProvider.getDefaultWidgets();
+ } else {
+ // This code path can be deleted once enableTieredWidgetsByDefaultInPicker is inlined.
+ widgets = getWidgetsToDisplay();
+ }
AdapterHolder primaryUserAdapterHolder = mAdapters.get(AdapterHolder.PRIMARY);
- primaryUserAdapterHolder.mWidgetsListAdapter.setWidgets(widgets);
+ primaryUserAdapterHolder.mWidgetsListAdapter.setWidgets(widgets, defaultWidgets);
if (mHasWorkProfile) {
mViewPager.setVisibility(VISIBLE);
mTabBar.setVisibility(VISIBLE);
AdapterHolder workUserAdapterHolder = mAdapters.get(AdapterHolder.WORK);
- workUserAdapterHolder.mWidgetsListAdapter.setWidgets(widgets);
+ workUserAdapterHolder.mWidgetsListAdapter.setWidgets(widgets, defaultWidgets);
onActivePageChanged(mViewPager.getCurrentPage());
} else {
onActivePageChanged(0);
@@ -518,6 +544,16 @@
}
@Override
+ public void onWidgetsListExpandButtonClick(View v) {
+ AdapterHolder currentAdapterHolder = mAdapters.get(getCurrentAdapterHolderType());
+ currentAdapterHolder.mWidgetsListAdapter.useExpandedList();
+ onWidgetsBound();
+ currentAdapterHolder.mWidgetsRecyclerView.announceForAccessibility(
+ mActivityContext.getString(R.string.widgets_list_expanded));
+ mActivityContext.getStatsLogManager().logger().log(LAUNCHER_WIDGETSTRAY_EXPAND_PRESS);
+ }
+
+ @Override
public void enterSearchMode(boolean shouldLog) {
if (mIsInSearchMode) return;
setViewVisibilityBasedOnSearch(/*isInSearchMode= */ true);
@@ -832,7 +868,7 @@
+ marginLayoutParams.topMargin;
}
- private int getCurrentAdapterHolderType() {
+ protected int getCurrentAdapterHolderType() {
if (mIsInSearchMode) {
return SEARCH;
} else if (mViewPager != null) {
@@ -861,6 +897,7 @@
WidgetsFullSheet sheet = show(BaseActivity.fromContext(getContext()), false);
sheet.restoreRecommendations(mRecommendedWidgets, mRecommendedWidgetsMap);
sheet.restoreHierarchyState(widgetsState);
+ sheet.restoreAdapterStates(mAdapters);
sheet.restorePreviousAdapterHolderType(getCurrentAdapterHolderType());
} else if (!isTwoPane()) {
reset();
@@ -876,6 +913,17 @@
mRecommendedWidgetsMap = recommendedWidgetsMap;
}
+ private void restoreAdapterStates(SparseArray<AdapterHolder> adapters) {
+ if (adapters.contains(AdapterHolder.WORK)) {
+ mAdapters.get(AdapterHolder.WORK).mWidgetsListAdapter.restoreState(
+ adapters.get(AdapterHolder.WORK).mWidgetsListAdapter);
+ }
+ mAdapters.get(AdapterHolder.PRIMARY).mWidgetsListAdapter.restoreState(
+ adapters.get(AdapterHolder.PRIMARY).mWidgetsListAdapter);
+ mAdapters.get(AdapterHolder.SEARCH).mWidgetsListAdapter.restoreState(
+ adapters.get(AdapterHolder.SEARCH).mWidgetsListAdapter);
+ }
+
/**
* Indicates if layout should be re-created on device profile change - so that a different
* layout can be displayed.
@@ -1045,6 +1093,7 @@
this::getEmptySpaceHeight,
/* iconClickListener= */ WidgetsFullSheet.this,
/* iconLongClickListener= */ WidgetsFullSheet.this,
+ /* expandButtonClickListener= */ WidgetsFullSheet.this,
isTwoPane());
mWidgetsListAdapter.setHasStableIds(true);
switch (mAdapterType) {
diff --git a/src/com/android/launcher3/widget/picker/WidgetsListAdapter.java b/src/com/android/launcher3/widget/picker/WidgetsListAdapter.java
index 3d3a669..3c67538 100644
--- a/src/com/android/launcher3/widget/picker/WidgetsListAdapter.java
+++ b/src/com/android/launcher3/widget/picker/WidgetsListAdapter.java
@@ -49,6 +49,7 @@
import com.android.launcher3.widget.model.WidgetListSpaceEntry;
import com.android.launcher3.widget.model.WidgetsListBaseEntry;
import com.android.launcher3.widget.model.WidgetsListContentEntry;
+import com.android.launcher3.widget.model.WidgetsListExpandActionEntry;
import com.android.launcher3.widget.model.WidgetsListHeaderEntry;
import com.android.launcher3.widget.util.WidgetSizes;
@@ -82,6 +83,7 @@
public static final int VIEW_TYPE_WIDGETS_SPACE = R.id.view_type_widgets_space;
public static final int VIEW_TYPE_WIDGETS_LIST = R.id.view_type_widgets_list;
public static final int VIEW_TYPE_WIDGETS_HEADER = R.id.view_type_widgets_header;
+ public static final int VIEW_TYPE_WIDGETS_EXPAND = R.id.view_type_widgets_list_expand;
private final Context mContext;
private final SparseArray<ViewHolderBinder> mViewHolderBinders = new SparseArray<>();
@@ -90,7 +92,9 @@
@Nullable private WidgetsTwoPaneSheet.HeaderChangeListener mHeaderChangeListener;
private final List<WidgetsListBaseEntry> mAllEntries = new ArrayList<>();
+ private final List<WidgetsListBaseEntry> mAllDefaultEntries = new ArrayList<>();
private ArrayList<WidgetsListBaseEntry> mVisibleEntries = new ArrayList<>();
+
@Nullable private PackageUserKey mWidgetsContentVisiblePackageUserKey = null;
private Predicate<WidgetsListBaseEntry> mHeaderAndSelectedContentFilter = entry ->
@@ -102,9 +106,12 @@
@Nullable private PackageUserKey mPendingClickHeader;
@Px private int mMaxHorizontalSpan;
+ private boolean mShowOnlyDefaultList = true;
+
public WidgetsListAdapter(Context context, LayoutInflater layoutInflater,
IntSupplier emptySpaceHeightProvider, OnClickListener iconClickListener,
OnLongClickListener iconLongClickListener,
+ ExpandButtonClickListener expandButtonClickListener,
boolean isTwoPane) {
mContext = context;
mMaxHorizontalSpan = WidgetSizes.getWidgetSizePx(
@@ -123,6 +130,16 @@
mViewHolderBinders.put(
VIEW_TYPE_WIDGETS_SPACE,
new WidgetsSpaceViewHolderBinder(emptySpaceHeightProvider));
+ mViewHolderBinders.put(VIEW_TYPE_WIDGETS_EXPAND,
+ new WidgetsListExpandActionViewHolderBinder(layoutInflater,
+ expandButtonClickListener::onWidgetsListExpandButtonClick));
+ }
+
+ /**
+ * Copies state info from another adapter.
+ */
+ public void restoreState(WidgetsListAdapter adapter) {
+ mShowOnlyDefaultList = adapter.mShowOnlyDefaultList;
}
public void setHeaderChangeListener(WidgetsTwoPaneSheet.HeaderChangeListener
@@ -168,10 +185,21 @@
}
/** Updates the widget list based on {@code tempEntries}. */
- public void setWidgets(List<WidgetsListBaseEntry> tempEntries) {
+ public void setWidgets(List<WidgetsListBaseEntry> tempEntries,
+ List<WidgetsListBaseEntry> tempDefaultEntries) {
mAllEntries.clear();
mAllEntries.add(new WidgetListSpaceEntry());
tempEntries.stream().sorted(mRowComparator).forEach(mAllEntries::add);
+
+ mAllDefaultEntries.clear();
+
+ if (mShowOnlyDefaultList && !tempDefaultEntries.isEmpty()) {
+ mAllDefaultEntries.add(new WidgetListSpaceEntry());
+ tempDefaultEntries.stream().sorted(mRowComparator).forEach(mAllDefaultEntries::add);
+ // Include view all action when default entries exist.
+ mAllDefaultEntries.add(new WidgetsListExpandActionEntry());
+ }
+
updateVisibleEntries();
}
@@ -179,7 +207,8 @@
public void setWidgetsOnSearch(List<WidgetsListBaseEntry> searchResults) {
// Forget the expanded package every time widget list is refreshed in search mode.
mWidgetsContentVisiblePackageUserKey = null;
- setWidgets(searchResults);
+ mShowOnlyDefaultList = false;
+ setWidgets(searchResults, /*tempDefaultEntries=*/ List.of());
}
private void updateVisibleEntries() {
@@ -190,10 +219,11 @@
OptionalInt topForPackageUserKey =
getOffsetForPosition(previousPositionForPackageUserKey);
- List<WidgetsListBaseEntry> newVisibleEntries = mAllEntries.stream()
+ List<WidgetsListBaseEntry> newVisibleEntries = getAllEntries().stream()
.filter(entry -> (((mFilter == null || mFilter.test(entry))
&& mHeaderAndSelectedContentFilter.test(entry))
- || entry instanceof WidgetListSpaceEntry)
+ || entry instanceof WidgetListSpaceEntry
+ || entry instanceof WidgetsListExpandActionEntry)
&& (mHeaderChangeListener == null
|| !(entry instanceof WidgetsListContentEntry)))
.map(entry -> {
@@ -227,6 +257,11 @@
}
}
+ private List<WidgetsListBaseEntry> getAllEntries() {
+ return (mShowOnlyDefaultList && !mAllDefaultEntries.isEmpty()) ? mAllDefaultEntries
+ : mAllEntries;
+ }
+
/** Returns whether {@code entry} matches {@code key}. */
private static boolean isHeaderForPackageUserKey(
@NonNull WidgetsListBaseEntry entry, @Nullable PackageUserKey key) {
@@ -262,7 +297,13 @@
// The first entry has an empty space, count from second entries.
int listPos = (pos > 1) ? POSITION_DEFAULT : POSITION_FIRST;
- if (pos == (getItemCount() - 1)) {
+ int lastIndex = getItemCount() - 1;
+ // Last index may be the view all entry
+ int actualLastItemIndex = (mVisibleEntries.get(
+ lastIndex) instanceof WidgetsListExpandActionEntry) ? getItemCount() - 2
+ : getItemCount() - 1;
+
+ if (pos == (actualLastItemIndex)) {
listPos |= POSITION_LAST;
}
viewHolderBinder.bindViewHolder(holder, mVisibleEntries.get(pos), listPos, payloads);
@@ -319,6 +360,8 @@
return VIEW_TYPE_WIDGETS_HEADER;
} else if (entry instanceof WidgetListSpaceEntry) {
return VIEW_TYPE_WIDGETS_SPACE;
+ } else if (entry instanceof WidgetsListExpandActionEntry) {
+ return VIEW_TYPE_WIDGETS_EXPAND;
}
throw new UnsupportedOperationException("ViewHolderBinder not found for " + entry);
}
@@ -412,6 +455,23 @@
updateVisibleEntries();
}
+ /**
+ * Returns the widget content {@link WidgetsListContentEntry} for a selected header.
+ */
+ public WidgetsListContentEntry getContentEntry(PackageUserKey selectedHeader) {
+ return getAllEntries().stream().filter(entry -> entry instanceof WidgetsListContentEntry)
+ .map(entry -> (WidgetsListContentEntry) entry)
+ .filter(entry -> PackageUserKey.fromPackageItemInfo(entry.mPkgItem).equals(
+ selectedHeader)).findFirst().orElse(null);
+ }
+
+ /**
+ * Sets adapter to use expanded list when updating widgets.
+ */
+ public void useExpandedList() {
+ mShowOnlyDefaultList = false;
+ }
+
/** Comparator for sorting WidgetListRowEntry based on package title. */
public static class WidgetListBaseRowEntryComparator implements
Comparator<WidgetsListBaseEntry> {
@@ -430,4 +490,10 @@
return 1;
}
}
+
+ /** Callback interface for the interaction with the expand button */
+ public interface ExpandButtonClickListener {
+ /** Called when user clicks the button at end of widget apps list to expand it. */
+ void onWidgetsListExpandButtonClick(View view);
+ }
}
diff --git a/src/com/android/launcher3/widget/picker/WidgetsListExpandActionViewHolderBinder.java b/src/com/android/launcher3/widget/picker/WidgetsListExpandActionViewHolderBinder.java
new file mode 100644
index 0000000..288c456
--- /dev/null
+++ b/src/com/android/launcher3/widget/picker/WidgetsListExpandActionViewHolderBinder.java
@@ -0,0 +1,60 @@
+/*
+ * 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.widget.picker;
+
+import android.view.LayoutInflater;
+import android.view.View;
+import android.view.ViewGroup;
+
+import androidx.annotation.NonNull;
+import androidx.recyclerview.widget.RecyclerView;
+
+import com.android.launcher3.R;
+import com.android.launcher3.recyclerview.ViewHolderBinder;
+import com.android.launcher3.widget.model.WidgetsListExpandActionEntry;
+
+import java.util.List;
+
+/**
+ * Creates and populates views for the {@link WidgetsListExpandActionEntry}.
+ */
+public class WidgetsListExpandActionViewHolderBinder implements
+ ViewHolderBinder<WidgetsListExpandActionEntry, RecyclerView.ViewHolder> {
+ @NonNull
+ View.OnClickListener mExpandListClickListener;
+ private final LayoutInflater mLayoutInflater;
+
+ public WidgetsListExpandActionViewHolderBinder(
+ @NonNull LayoutInflater layoutInflater,
+ @NonNull View.OnClickListener expandListClickListener) {
+ mLayoutInflater = layoutInflater;
+ mExpandListClickListener = expandListClickListener;
+ }
+
+ @Override
+ public RecyclerView.ViewHolder newViewHolder(ViewGroup parent) {
+ return new RecyclerView.ViewHolder(mLayoutInflater.inflate(
+ R.layout.widgets_list_expand_button, parent, false)) {
+ };
+ }
+
+ @Override
+ public void bindViewHolder(RecyclerView.ViewHolder viewHolder,
+ WidgetsListExpandActionEntry data, int position, List<Object> payloads) {
+ viewHolder.itemView.setOnClickListener(mExpandListClickListener);
+ }
+}
diff --git a/src/com/android/launcher3/widget/picker/WidgetsTwoPaneSheet.java b/src/com/android/launcher3/widget/picker/WidgetsTwoPaneSheet.java
index f4b99a0..f9bd5f1 100644
--- a/src/com/android/launcher3/widget/picker/WidgetsTwoPaneSheet.java
+++ b/src/com/android/launcher3/widget/picker/WidgetsTwoPaneSheet.java
@@ -16,6 +16,7 @@
package com.android.launcher3.widget.picker;
import static com.android.launcher3.Flags.enableCategorizedWidgetSuggestions;
+import static com.android.launcher3.Flags.enableTieredWidgetsByDefaultInPicker;
import static com.android.launcher3.Flags.enableUnfoldedTwoPanePicker;
import static com.android.launcher3.UtilitiesKt.CLIP_CHILDREN_FALSE_MODIFIER;
import static com.android.launcher3.UtilitiesKt.CLIP_TO_PADDING_FALSE_MODIFIER;
@@ -147,7 +148,9 @@
mHeaderDescription = mContent.findViewById(R.id.widget_picker_description);
mWidgetOptionsMenu = mContent.findViewById(R.id.widget_picker_widget_options_menu);
- setupWidgetOptionsMenu();
+ if (!enableTieredWidgetsByDefaultInPicker()) {
+ setupWidgetOptionsMenu();
+ }
mRightPane = mContent.findViewById(R.id.right_pane);
mRightPaneScrollView = mContent.findViewById(R.id.right_pane_scroll_view);
@@ -286,6 +289,9 @@
}
}
+ // Used by the two pane sheet to show 3-dot menu to toggle between default lists and all lists
+ // when enableTieredWidgetsByDefaultInPicker is OFF. This code path and the 3-dot menu can be
+ // safely deleted when it's alternative "enableTieredWidgetsByDefaultInPicker" flag is inlined.
@Override
protected List<WidgetsListBaseEntry> getWidgetsToDisplay() {
List<WidgetsListBaseEntry> allWidgets =
@@ -319,6 +325,15 @@
}
@Override
+ public void onWidgetsListExpandButtonClick(View v) {
+ super.onWidgetsListExpandButtonClick(v);
+ // Refresh right pane with updated data for the selected header.
+ if (mSelectedHeader != null && mSelectedHeader != mSuggestedWidgetsPackageUserKey) {
+ getHeaderChangeListener().onHeaderChanged(mSelectedHeader);
+ }
+ }
+
+ @Override
public void onRecommendedWidgetsBound() {
super.onRecommendedWidgetsBound();
@@ -511,11 +526,20 @@
&& !mOpenCloseAnimation.getAnimationPlayer().isRunning()
&& !getAccessibilityInitialFocusView().isAccessibilityFocused();
mSelectedHeader = selectedHeader;
- final boolean showDefaultWidgets = mWidgetOptionsMenuState != null
- && !mWidgetOptionsMenuState.showAllWidgets;
- WidgetsListContentEntry contentEntry = findContentEntryForPackageUser(
- mActivityContext.getWidgetPickerDataProvider().get(),
- selectedHeader, showDefaultWidgets);
+
+ WidgetsListContentEntry contentEntry;
+ if (enableTieredWidgetsByDefaultInPicker()) {
+ contentEntry = mAdapters.get(
+ getCurrentAdapterHolderType()).mWidgetsListAdapter.getContentEntry(
+ selectedHeader);
+ } else { // Can be deleted when inlining the "enableTieredWidgetsByDefaultInPicker"
+ // flag
+ final boolean showDefaultWidgets = mWidgetOptionsMenuState != null
+ && !mWidgetOptionsMenuState.showAllWidgets;
+ contentEntry = findContentEntryForPackageUser(
+ mActivityContext.getWidgetPickerDataProvider().get(),
+ selectedHeader, showDefaultWidgets);
+ }
if (contentEntry == null || mRightPane == null) {
return;
diff --git a/tests/multivalentTests/src/com/android/launcher3/AbstractDeviceProfileTest.kt b/tests/multivalentTests/src/com/android/launcher3/AbstractDeviceProfileTest.kt
index 55a028b..62c8426 100644
--- a/tests/multivalentTests/src/com/android/launcher3/AbstractDeviceProfileTest.kt
+++ b/tests/multivalentTests/src/com/android/launcher3/AbstractDeviceProfileTest.kt
@@ -307,6 +307,7 @@
whenever(launcherPrefs.get(LauncherPrefs.TASKBAR_PINNING)).thenReturn(false)
whenever(launcherPrefs.get(LauncherPrefs.TASKBAR_PINNING_IN_DESKTOP_MODE)).thenReturn(true)
+ whenever(launcherPrefs.get(LauncherPrefs.FIXED_LANDSCAPE_MODE)).thenReturn(false)
whenever(launcherPrefs.get(LauncherPrefs.HOTSEAT_COUNT)).thenReturn(-1)
whenever(launcherPrefs.get(LauncherPrefs.DEVICE_TYPE)).thenReturn(-1)
whenever(launcherPrefs.get(LauncherPrefs.WORKSPACE_SIZE)).thenReturn("")
diff --git a/tests/multivalentTests/src/com/android/launcher3/icons/IconCacheUpdateHandlerTest.kt b/tests/multivalentTests/src/com/android/launcher3/icons/IconCacheUpdateHandlerTest.kt
index ed9a080..bae74c8 100644
--- a/tests/multivalentTests/src/com/android/launcher3/icons/IconCacheUpdateHandlerTest.kt
+++ b/tests/multivalentTests/src/com/android/launcher3/icons/IconCacheUpdateHandlerTest.kt
@@ -19,6 +19,7 @@
import android.content.ComponentName
import android.content.pm.ApplicationInfo
import android.database.MatrixCursor
+import android.os.Handler
import android.os.Process.myUserHandle
import androidx.test.ext.junit.runners.AndroidJUnit4
import androidx.test.filters.SmallTest
@@ -34,9 +35,18 @@
import org.junit.Before
import org.junit.Test
import org.junit.runner.RunWith
+import org.mockito.ArgumentCaptor
+import org.mockito.Captor
import org.mockito.Mock
import org.mockito.MockitoAnnotations
+import org.mockito.kotlin.any
+import org.mockito.kotlin.anyOrNull
+import org.mockito.kotlin.doAnswer
import org.mockito.kotlin.doReturn
+import org.mockito.kotlin.eq
+import org.mockito.kotlin.never
+import org.mockito.kotlin.times
+import org.mockito.kotlin.verify
import org.mockito.kotlin.whenever
@SmallTest
@@ -45,14 +55,25 @@
@Mock private lateinit var iconProvider: IconProvider
@Mock private lateinit var baseIconCache: BaseIconCache
+ @Mock private lateinit var cacheDb: IconDB
+ @Mock private lateinit var workerHandler: Handler
- private var cursor: MatrixCursor? = null
- private var cachingLogic = CachedObjectCachingLogic
+ @Captor private lateinit var deleteCaptor: ArgumentCaptor<String>
+
+ private var cursor =
+ MatrixCursor(
+ arrayOf(IconDB.COLUMN_ROWID, IconDB.COLUMN_COMPONENT, IconDB.COLUMN_FRESHNESS_ID)
+ )
+
+ private lateinit var updateHandlerUnderTest: IconCacheUpdateHandler
@Before
fun setup() {
MockitoAnnotations.initMocks(this)
doReturn(iconProvider).whenever(baseIconCache).iconProvider
+ doReturn(cursor).whenever(cacheDb).query(any(), any(), any())
+
+ updateHandlerUnderTest = IconCacheUpdateHandler(baseIconCache, cacheDb, workerHandler)
}
@After
@@ -61,63 +82,136 @@
}
@Test
- fun `IconCacheUpdateHandler returns null if the component name is malformed`() {
- val updateHandlerUnderTest = IconCacheUpdateHandler(baseIconCache)
- val cn = ComponentName.unflattenFromString("com.android.fake/.FakeActivity")!!
+ fun `keeps correct icons irrespective of call order`() {
+ val obj1 = TestCachedObject(1).apply { addToCursor(cursor) }
+ val obj2 = TestCachedObject(2).apply { addToCursor(cursor) }
- val result =
- updateHandlerUnderTest.updateOrDeleteIcon(
- createCursor(1, cn.flattenToString() + "#", "freshId-old"),
- hashMapOf(cn to TestCachedObject(cn, "freshId")),
- setOf(),
- myUserHandle(),
- cachingLogic,
- )
- assertThat(result).isNull()
+ updateHandlerUnderTest.updateIcons(obj1)
+ updateHandlerUnderTest.updateIcons(obj2)
+ updateHandlerUnderTest.finish()
+
+ verify(cacheDb, never()).delete(any(), anyOrNull())
}
@Test
- fun `IconCacheUpdateHandler returns null if the freshId match`() {
- val updateHandlerUnderTest = IconCacheUpdateHandler(baseIconCache)
- val cn = ComponentName.unflattenFromString("com.android.fake/.FakeActivity")!!
+ fun `removes missing entries in single call`() {
+ TestCachedObject(1).addToCursor(cursor)
+ TestCachedObject(2).addToCursor(cursor)
+ TestCachedObject(3).addToCursor(cursor)
+ TestCachedObject(4).addToCursor(cursor)
+ TestCachedObject(5).addToCursor(cursor)
- val result =
- updateHandlerUnderTest.updateOrDeleteIcon(
- createCursor(1, cn.flattenToString(), "freshId"),
- hashMapOf(cn to TestCachedObject(cn, "freshId")),
- setOf(),
- myUserHandle(),
- cachingLogic,
- )
- assertThat(result).isNull()
+ updateHandlerUnderTest.updateIcons(TestCachedObject(1), TestCachedObject(4))
+ updateHandlerUnderTest.finish()
+
+ verifyItemsDeleted(2, 3, 5)
}
@Test
- fun `IconCacheUpdateHandler returns non-null if the freshId do not match`() {
- val updateHandlerUnderTest = IconCacheUpdateHandler(baseIconCache)
- val cn = ComponentName.unflattenFromString("com.android.fake/.FakeActivity")!!
- val testObj = TestCachedObject(cn, "freshId")
+ fun `removes missing entries in multiple calls`() {
+ TestCachedObject(1).addToCursor(cursor)
+ TestCachedObject(2).addToCursor(cursor)
+ TestCachedObject(3).addToCursor(cursor)
+ TestCachedObject(4).addToCursor(cursor)
+ TestCachedObject(5).addToCursor(cursor)
+ TestCachedObject(6).addToCursor(cursor)
- val result =
- updateHandlerUnderTest.updateOrDeleteIcon(
- createCursor(1, cn.flattenToString(), "freshId-old"),
- hashMapOf(cn to testObj),
- setOf(),
- myUserHandle(),
- cachingLogic,
- )
- assertThat(result).isEqualTo(testObj)
+ updateHandlerUnderTest.updateIcons(TestCachedObject(1), TestCachedObject(2))
+ updateHandlerUnderTest.updateIcons(TestCachedObject(4), TestCachedObject(5))
+ updateHandlerUnderTest.finish()
+
+ verifyItemsDeleted(3, 6)
}
- private fun createCursor(row: Long, component: String, appState: String) =
- MatrixCursor(
- arrayOf(IconDB.COLUMN_ROWID, IconDB.COLUMN_COMPONENT, IconDB.COLUMN_FRESHNESS_ID)
- )
- .apply { addRow(arrayOf(row, component, appState)) }
- .apply {
- cursor = this
- moveToNext()
+ @Test
+ fun `keeps valid app infos`() {
+ val appInfo = ApplicationInfo()
+ doReturn("app-fresh").whenever(iconProvider).getStateForApp(eq(appInfo))
+
+ TestCachedObject(1).addToCursor(cursor)
+ TestCachedObject(2).addToCursor(cursor)
+ cursor.addRow(arrayOf(33, TestCachedObject(1).getPackageKey(), "app-fresh"))
+
+ updateHandlerUnderTest.updateIcons(
+ TestCachedObject(1, appInfo = appInfo),
+ TestCachedObject(2),
+ )
+ updateHandlerUnderTest.finish()
+
+ verify(cacheDb, never()).delete(any(), anyOrNull())
+ }
+
+ @Test
+ fun `deletes stale app infos`() {
+ val appInfo1 = ApplicationInfo()
+ doReturn("app1-fresh").whenever(iconProvider).getStateForApp(eq(appInfo1))
+
+ val appInfo2 = ApplicationInfo()
+ doReturn("app2-fresh").whenever(iconProvider).getStateForApp(eq(appInfo2))
+
+ TestCachedObject(1).addToCursor(cursor)
+ TestCachedObject(2).addToCursor(cursor)
+ cursor.addRow(arrayOf(33, TestCachedObject(1).getPackageKey(), "app1-not-fresh"))
+ cursor.addRow(arrayOf(34, TestCachedObject(2).getPackageKey(), "app2-fresh"))
+
+ updateHandlerUnderTest.updateIcons(
+ TestCachedObject(1, appInfo = appInfo1),
+ TestCachedObject(2, appInfo = appInfo2),
+ )
+ updateHandlerUnderTest.finish()
+
+ verifyItemsDeleted(33)
+ }
+
+ @Test
+ fun `updates stale entries`() {
+ doAnswer { i ->
+ (i.arguments[0] as Runnable).run()
+ true
}
+ .whenever(workerHandler)
+ .postAtTime(any(), anyOrNull(), any())
+
+ TestCachedObject(1).addToCursor(cursor)
+ TestCachedObject(2).addToCursor(cursor)
+ TestCachedObject(3).addToCursor(cursor)
+
+ var updatedPackages = mutableSetOf<String>()
+ updateHandlerUnderTest.updateIcons(
+ listOf(
+ TestCachedObject(1, freshnessId = "not-fresh"),
+ TestCachedObject(2, freshnessId = "not-fresh"),
+ TestCachedObject(3),
+ ),
+ CachedObjectCachingLogic,
+ ) { apps, _ ->
+ updatedPackages.addAll(apps)
+ }
+ updateHandlerUnderTest.finish()
+
+ assertThat(updatedPackages)
+ .isEqualTo(
+ mutableSetOf(TestCachedObject(1).cn.packageName, TestCachedObject(2).cn.packageName)
+ )
+ }
+
+ private fun IconCacheUpdateHandler.updateIcons(vararg items: TestCachedObject) {
+ updateIcons(items.toList(), CachedObjectCachingLogic) { _, _ -> }
+ }
+
+ private fun verifyItemsDeleted(vararg rowIds: Long) {
+ verify(cacheDb, times(1)).delete(deleteCaptor.capture(), anyOrNull())
+ val actual =
+ deleteCaptor.value
+ .split('(')
+ ?.get(1)
+ ?.split(')')
+ ?.get(0)
+ ?.split(",")
+ ?.map { it.trim().toLong() }!!
+ .sorted()
+ assertThat(actual).isEqualTo(rowIds.toList().sorted())
+ }
}
/** Utility method to wait for the icon update handler to finish */
@@ -135,7 +229,13 @@
}
}
-class TestCachedObject(val cn: ComponentName, val freshnessId: String) : CachedObject {
+class TestCachedObject(
+ val rowId: Long,
+ val cn: ComponentName =
+ ComponentName.unflattenFromString("com.android.fake$rowId/.FakeActivity")!!,
+ val freshnessId: String = "fresh-$rowId",
+ val appInfo: ApplicationInfo? = null,
+) : CachedObject {
override fun getComponent() = cn
@@ -143,7 +243,13 @@
override fun getLabel(): CharSequence? = null
- override fun getApplicationInfo(): ApplicationInfo? = null
+ override fun getApplicationInfo(): ApplicationInfo? = appInfo
override fun getFreshnessIdentifier(iconProvider: IconProvider): String? = freshnessId
+
+ fun addToCursor(cursor: MatrixCursor) =
+ cursor.addRow(arrayOf(rowId, cn.flattenToString(), freshnessId))
+
+ fun getPackageKey() =
+ BaseIconCache.getPackageKey(cn.packageName, user).componentName.flattenToString()
}
diff --git a/tests/multivalentTests/src/com/android/launcher3/model/WidgetsModelTest.kt b/tests/multivalentTests/src/com/android/launcher3/model/WidgetsModelTest.kt
index ff545fe..ae4ff04 100644
--- a/tests/multivalentTests/src/com/android/launcher3/model/WidgetsModelTest.kt
+++ b/tests/multivalentTests/src/com/android/launcher3/model/WidgetsModelTest.kt
@@ -43,6 +43,7 @@
import com.google.common.truth.Truth.assertThat
import java.util.concurrent.CountDownLatch
import java.util.concurrent.TimeUnit
+import java.util.function.Predicate
import org.junit.Assert.fail
import org.junit.Before
import org.junit.Rule
@@ -64,6 +65,7 @@
@Mock private lateinit var appWidgetManager: AppWidgetManager
@Mock private lateinit var app: LauncherAppState
@Mock private lateinit var iconCacheMock: IconCache
+ @Mock private lateinit var widgetsFilterDataProvider: WidgetsFilterDataProvider
private lateinit var context: Context
private lateinit var idp: InvariantDeviceProfile
@@ -215,6 +217,27 @@
// No exception
}
+ @Test
+ fun updateWidgetFilters_setsFiltersCorrectly() {
+ val testDefaultWidgetFilter = Predicate<WidgetItem> { w -> w.widgetInfo != null }
+ whenever(widgetsFilterDataProvider.getDefaultWidgetsFilter())
+ .thenReturn(testDefaultWidgetFilter)
+ val testPredicatedWidgetFilter = Predicate<WidgetItem> { w -> w.widgetInfo != null }
+ whenever(widgetsFilterDataProvider.getPredictedWidgetsFilter())
+ .thenReturn(testPredicatedWidgetFilter)
+
+ underTest.updateWidgetFilters(widgetsFilterDataProvider)
+
+ assertThat(underTest.defaultWidgetsFilter).isEqualTo(testDefaultWidgetFilter)
+ assertThat(underTest.predictedWidgetsFilter).isEqualTo(testPredicatedWidgetFilter)
+ }
+
+ @Test
+ fun widgetFilters_nullInitially() {
+ assertThat(underTest.defaultWidgetsFilter).isNull()
+ assertThat(underTest.predictedWidgetsFilter).isNull()
+ }
+
private fun loadWidgets() {
val latch = CountDownLatch(1)
Executors.MODEL_EXECUTOR.execute {
diff --git a/tests/multivalentTests/src/com/android/launcher3/util/TestUtil.java b/tests/multivalentTests/src/com/android/launcher3/util/TestUtil.java
index ce682f1..eb25acf 100644
--- a/tests/multivalentTests/src/com/android/launcher3/util/TestUtil.java
+++ b/tests/multivalentTests/src/com/android/launcher3/util/TestUtil.java
@@ -29,7 +29,10 @@
import android.app.blob.BlobHandle;
import android.app.blob.BlobStoreManager;
import android.content.Context;
+import android.content.Intent;
+import android.content.pm.ActivityInfo;
import android.content.pm.LauncherApps;
+import android.content.pm.PackageManager;
import android.content.res.Resources;
import android.graphics.Point;
import android.os.AsyncTask;
@@ -231,6 +234,15 @@
.adoptShellPermissionIdentity(Manifest.permission.WRITE_SECURE_SETTINGS);
}
+ /**
+ * Returns the activity info corresponding to the system app for the provided category
+ */
+ public static ActivityInfo resolveSystemAppInfo(String category) {
+ return getInstrumentation().getTargetContext().getPackageManager().resolveActivity(
+ new Intent(Intent.ACTION_MAIN).addCategory(category),
+ PackageManager.MATCH_SYSTEM_ONLY).activityInfo;
+ }
+
/** Interface to indicate a runnable which can throw any exception. */
public interface UncheckedRunnable {
/** Method to run the task */
diff --git a/tests/multivalentTests/src/com/android/launcher3/util/VibratorWrapperTest.kt b/tests/multivalentTests/src/com/android/launcher3/util/VibratorWrapperTest.kt
index d321e41..0f212eb 100644
--- a/tests/multivalentTests/src/com/android/launcher3/util/VibratorWrapperTest.kt
+++ b/tests/multivalentTests/src/com/android/launcher3/util/VibratorWrapperTest.kt
@@ -21,8 +21,8 @@
import android.os.VibrationEffect.Composition.PRIMITIVE_LOW_TICK
import android.os.VibrationEffect.Composition.PRIMITIVE_TICK
import android.os.Vibrator
-import androidx.test.ext.junit.runners.AndroidJUnit4
import androidx.test.filters.SmallTest
+import com.android.launcher3.util.LauncherModelHelper.SandboxModelContext
import com.android.launcher3.util.VibratorWrapper.HAPTIC_FEEDBACK_URI
import com.android.launcher3.util.VibratorWrapper.OVERVIEW_HAPTIC
import com.android.launcher3.util.VibratorWrapper.VIBRATION_ATTRS
@@ -41,40 +41,36 @@
import org.mockito.kotlin.same
@SmallTest
-@RunWith(AndroidJUnit4::class)
+@RunWith(LauncherMultivalentJUnit::class)
class VibratorWrapperTest {
@Mock private lateinit var settingsCache: SettingsCache
- @Mock private lateinit var vibrator: Vibrator
+ private lateinit var vibrator: Vibrator
+ private val context: SandboxModelContext = SandboxModelContext()
@Captor private lateinit var vibrationEffectCaptor: ArgumentCaptor<VibrationEffect>
-
+ @Mock private lateinit var tracker: DaggerSingletonTracker
private lateinit var underTest: VibratorWrapper
@Before
fun setup() {
MockitoAnnotations.initMocks(this)
+ vibrator = context.spyService(Vibrator::class.java)
`when`(settingsCache.getValue(HAPTIC_FEEDBACK_URI, 0)).thenReturn(true)
`when`(vibrator.hasVibrator()).thenReturn(true)
`when`(vibrator.areAllPrimitivesSupported(PRIMITIVE_TICK)).thenReturn(true)
`when`(vibrator.areAllPrimitivesSupported(PRIMITIVE_LOW_TICK)).thenReturn(true)
`when`(vibrator.getPrimitiveDurations(PRIMITIVE_LOW_TICK)).thenReturn(intArrayOf(10))
- underTest = VibratorWrapper(vibrator, settingsCache)
+ underTest = VibratorWrapper(context, settingsCache, tracker)
}
@Test
fun init_register_onChangeListener() {
+ TestUtil.runOnExecutorSync(Executors.MAIN_EXECUTOR) {}
verify(settingsCache).register(HAPTIC_FEEDBACK_URI, underTest.mHapticChangeListener)
}
@Test
- fun close_unregister_onChangeListener() {
- underTest.close()
-
- verify(settingsCache).unregister(HAPTIC_FEEDBACK_URI, underTest.mHapticChangeListener)
- }
-
- @Test
fun vibrate() {
underTest.vibrate(OVERVIEW_HAPTIC)
@@ -117,7 +113,7 @@
@Test
fun haptic_feedback_disabled_no_vibrate() {
`when`(vibrator.hasVibrator()).thenReturn(false)
- underTest = VibratorWrapper(vibrator, settingsCache)
+ underTest = VibratorWrapper(context, settingsCache, tracker)
underTest.vibrate(OVERVIEW_HAPTIC)
diff --git a/tests/src/com/android/launcher3/LauncherIntentTest.java b/tests/src/com/android/launcher3/LauncherIntentTest.java
index aeeb42a..a3d9614 100644
--- a/tests/src/com/android/launcher3/LauncherIntentTest.java
+++ b/tests/src/com/android/launcher3/LauncherIntentTest.java
@@ -23,21 +23,27 @@
import android.platform.test.annotations.LargeTest;
import android.view.KeyEvent;
-import androidx.test.runner.AndroidJUnit4;
+import androidx.test.ext.junit.runners.AndroidJUnit4;
import com.android.launcher3.allapps.ActivityAllAppsContainerView;
import com.android.launcher3.allapps.SearchRecyclerView;
-import com.android.launcher3.ui.AbstractLauncherUiTest;
+import com.android.launcher3.util.BaseLauncherActivityTest;
+import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
@LargeTest
@RunWith(AndroidJUnit4.class)
-public class LauncherIntentTest extends AbstractLauncherUiTest<Launcher> {
+public class LauncherIntentTest extends BaseLauncherActivityTest<Launcher> {
public final Intent allAppsIntent = new Intent(Intent.ACTION_ALL_APPS);
+ @Before
+ public void setUp() {
+ loadLauncherSync();
+ }
+
@Test
public void testAllAppsIntent() {
// Try executing ALL_APPS intent
@@ -45,7 +51,6 @@
// A-Z view with Main adapter should be loaded
assertOnMainAdapterAToZView();
-
// Try Moving to search view now
moveToSearchView();
// Try executing ALL_APPS intent
@@ -63,12 +68,14 @@
// Search view should be in focus
waitForLauncherCondition("Search view is not in focus.",
launcher -> launcher.getAppsView().getSearchView().hasFocus());
- mLauncher.pressAndHoldKeyCode(KeyEvent.KEYCODE_C, 0);
+
+ injectKeyEvent(KeyEvent.KEYCODE_C, true);
// Upon key press, search recycler view should be loaded
waitForLauncherCondition("Search view not active.",
launcher -> launcher.getAppsView().getActiveRecyclerView()
instanceof SearchRecyclerView);
- mLauncher.unpressKeyCode(KeyEvent.KEYCODE_C, 0);
+
+ injectKeyEvent(KeyEvent.KEYCODE_C, false);
}
// Checks if main adapter view is selected, search bar is out of focus and scroller is at start.
diff --git a/tests/src/com/android/launcher3/allapps/KeyboardFocusTest.java b/tests/src/com/android/launcher3/allapps/KeyboardFocusTest.java
new file mode 100644
index 0000000..1e21ee5
--- /dev/null
+++ b/tests/src/com/android/launcher3/allapps/KeyboardFocusTest.java
@@ -0,0 +1,94 @@
+/*
+ * Copyright (C) 2023 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.allapps;
+
+import android.view.KeyEvent;
+
+import androidx.test.ext.junit.runners.AndroidJUnit4;
+import androidx.test.filters.SmallTest;
+
+import com.android.launcher3.Launcher;
+import com.android.launcher3.LauncherState;
+import com.android.launcher3.util.BaseLauncherActivityTest;
+import com.android.launcher3.util.rule.ScreenRecordRule.ScreenRecord;
+import com.android.launcher3.views.ActivityContext;
+
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
+@SmallTest
+@RunWith(AndroidJUnit4.class)
+public class KeyboardFocusTest extends BaseLauncherActivityTest<Launcher> {
+
+ @Test
+ public void testAllAppsFocusApp() {
+ loadLauncherSync();
+ goToState(LauncherState.ALL_APPS);
+ freezeAllApps();
+
+ injectKeyEvent(KeyEvent.KEYCODE_DPAD_DOWN, true);
+ injectKeyEvent(KeyEvent.KEYCODE_DPAD_DOWN, false);
+ waitForLauncherCondition("No focused child", launcher ->
+ launcher.getAppsView().getActiveRecyclerView().getApps().getFocusedChild()
+ != null);
+ }
+
+ @Test
+ public void testAllAppsExitSearchAndFocusApp() {
+ loadLauncherSync();
+ goToState(LauncherState.ALL_APPS);
+ freezeAllApps();
+
+ executeOnLauncher(launcher -> launcher.getAppsView().getSearchView().requestFocus());
+ waitForLauncherCondition("Search view does not have focus.",
+ launcher -> launcher.getAppsView().getSearchView().hasFocus());
+
+ injectKeyEvent(KeyEvent.KEYCODE_DPAD_DOWN, true);
+ injectKeyEvent(KeyEvent.KEYCODE_DPAD_DOWN, false);
+ waitForLauncherCondition("No focused child", launcher ->
+ launcher.getAppsView().getActiveRecyclerView().getApps().getFocusedChild()
+ != null);
+ }
+
+ @Test
+ @ScreenRecord //b/378167329
+ public void testAllAppsExitSearchAndFocusSearchResults() {
+ loadLauncherSync();
+ goToState(LauncherState.ALL_APPS);
+ freezeAllApps();
+
+ executeOnLauncher(launcher -> launcher.getAppsView().getSearchView().requestFocus());
+ waitForLauncherCondition("Search view does not have focus.",
+ launcher -> launcher.getAppsView().getSearchView().hasFocus());
+
+ injectKeyEvent(KeyEvent.KEYCODE_C, true);
+ waitForLauncherCondition("Search view not active.",
+ launcher -> launcher.getAppsView().getActiveRecyclerView()
+ instanceof SearchRecyclerView);
+ injectKeyEvent(KeyEvent.KEYCODE_C, false);
+
+ executeOnLauncher(launcher -> launcher.getAppsView().getSearchUiManager().getEditText()
+ .hideKeyboard(/* clearFocus= */ false));
+ waitForLauncherCondition("Keyboard still visible.",
+ ActivityContext::isSoftwareKeyboardHidden);
+
+ injectKeyEvent(KeyEvent.KEYCODE_DPAD_DOWN, true);
+ injectKeyEvent(KeyEvent.KEYCODE_DPAD_DOWN, false);
+ waitForLauncherCondition("No focused child", launcher ->
+ launcher.getAppsView().getActiveRecyclerView().getApps().getFocusedChild()
+ != null);
+ }
+}
diff --git a/tests/src/com/android/launcher3/allapps/TaplKeyboardFocusTest.java b/tests/src/com/android/launcher3/allapps/TaplKeyboardFocusTest.java
deleted file mode 100644
index 4e627a9..0000000
--- a/tests/src/com/android/launcher3/allapps/TaplKeyboardFocusTest.java
+++ /dev/null
@@ -1,108 +0,0 @@
-/*
- * Copyright (C) 2023 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.allapps;
-
-import static com.android.launcher3.util.rule.TestStabilityRule.LOCAL;
-import static com.android.launcher3.util.rule.TestStabilityRule.PLATFORM_POSTSUBMIT;
-
-import static org.junit.Assert.assertNotNull;
-import static org.junit.Assert.assertTrue;
-
-import android.view.KeyEvent;
-
-import androidx.test.ext.junit.runners.AndroidJUnit4;
-import androidx.test.filters.SmallTest;
-
-import com.android.launcher3.Launcher;
-import com.android.launcher3.LauncherState;
-import com.android.launcher3.tapl.HomeAllApps;
-import com.android.launcher3.ui.AbstractLauncherUiTest;
-import com.android.launcher3.util.rule.TestStabilityRule;
-import com.android.launcher3.views.ActivityContext;
-
-import org.junit.Test;
-import org.junit.runner.RunWith;
-
-@SmallTest
-@RunWith(AndroidJUnit4.class)
-public class TaplKeyboardFocusTest extends AbstractLauncherUiTest<Launcher> {
-
- @Test
- public void testAllAppsFocusApp() {
- final HomeAllApps allApps = mLauncher.goHome().switchToAllApps();
- assertTrue("Launcher internal state is not All Apps",
- isInState(() -> LauncherState.ALL_APPS));
- allApps.freeze();
- try {
- mLauncher.pressAndHoldKeyCode(KeyEvent.KEYCODE_DPAD_DOWN, 0);
- executeOnLauncher(launcher -> assertNotNull("No focused child.",
- launcher.getAppsView().getActiveRecyclerView().getApps().getFocusedChild()));
- } finally {
- allApps.unfreeze();
- }
- }
-
- @Test
- public void testAllAppsExitSearchAndFocusApp() {
- final HomeAllApps allApps = mLauncher.goHome().switchToAllApps();
- assertTrue("Launcher internal state is not All Apps",
- isInState(() -> LauncherState.ALL_APPS));
- allApps.freeze();
- try {
- executeOnLauncher(launcher -> launcher.getAppsView().getSearchView().requestFocus());
- waitForLauncherCondition("Search view does not have focus.",
- launcher -> launcher.getAppsView().getSearchView().hasFocus());
-
- mLauncher.pressAndHoldKeyCode(KeyEvent.KEYCODE_DPAD_DOWN, 0);
- executeOnLauncher(launcher -> assertNotNull("No focused child.",
- launcher.getAppsView().getActiveRecyclerView().getApps().getFocusedChild()));
- } finally {
- allApps.unfreeze();
- }
- }
-
- @Test
- public void testAllAppsExitSearchAndFocusSearchResults() {
- final HomeAllApps allApps = mLauncher.goHome().switchToAllApps();
- assertTrue("Launcher internal state is not All Apps",
- isInState(() -> LauncherState.ALL_APPS));
- allApps.freeze();
- try {
- executeOnLauncher(launcher -> launcher.getAppsView().getSearchView().requestFocus());
- waitForLauncherCondition("Search view does not have focus.",
- launcher -> launcher.getAppsView().getSearchView().hasFocus());
-
- mLauncher.pressAndHoldKeyCode(KeyEvent.KEYCODE_C, 0);
- waitForLauncherCondition("Search view not active.",
- launcher -> launcher.getAppsView().getActiveRecyclerView()
- instanceof SearchRecyclerView);
- mLauncher.unpressKeyCode(KeyEvent.KEYCODE_C, 0);
-
- executeOnLauncher(launcher -> launcher.getAppsView().getSearchUiManager().getEditText()
- .hideKeyboard(/* clearFocus= */ false));
- waitForLauncherCondition("Keyboard still visible.",
- ActivityContext::isSoftwareKeyboardHidden);
-
- mLauncher.pressAndHoldKeyCode(KeyEvent.KEYCODE_DPAD_DOWN, 0);
- mLauncher.unpressKeyCode(KeyEvent.KEYCODE_DPAD_DOWN, 0);
- waitForLauncherCondition("No focused child", launcher ->
- launcher.getAppsView().getActiveRecyclerView().getApps().getFocusedChild()
- != null);
- } finally {
- allApps.unfreeze();
- }
- }
-}
diff --git a/tests/src/com/android/launcher3/compat/TaplPromiseIconUiTest.java b/tests/src/com/android/launcher3/compat/PromiseIconUiTest.java
similarity index 73%
rename from tests/src/com/android/launcher3/compat/TaplPromiseIconUiTest.java
rename to tests/src/com/android/launcher3/compat/PromiseIconUiTest.java
index 1500538..34b292c 100644
--- a/tests/src/com/android/launcher3/compat/TaplPromiseIconUiTest.java
+++ b/tests/src/com/android/launcher3/compat/PromiseIconUiTest.java
@@ -1,18 +1,19 @@
/*
* 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
+ * 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
+ * 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.
+ * 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.compat;
import static com.android.launcher3.Flags.FLAG_ENABLE_SUPPORT_FOR_ARCHIVING;
@@ -27,32 +28,31 @@
import android.platform.test.flag.junit.DeviceFlagsValueProvider;
import android.text.TextUtils;
+import androidx.test.ext.junit.runners.AndroidJUnit4;
import androidx.test.filters.LargeTest;
-import androidx.test.runner.AndroidJUnit4;
import com.android.launcher3.Launcher;
import com.android.launcher3.LauncherState;
-import com.android.launcher3.tapl.AllApps;
-import com.android.launcher3.ui.AbstractLauncherUiTest;
+import com.android.launcher3.util.BaseLauncherActivityTest;
import com.android.launcher3.util.LauncherBindableItemsContainer.ItemOperator;
import com.android.launcher3.util.TestUtil;
-import com.android.launcher3.util.rule.ViewCaptureRule;
import org.junit.After;
+import org.junit.Before;
import org.junit.Rule;
import org.junit.Test;
import org.junit.runner.RunWith;
import java.io.IOException;
+import java.util.Arrays;
import java.util.UUID;
-
/**
* Test to verify promise icon flow.
*/
@LargeTest
@RunWith(AndroidJUnit4.class)
-public class TaplPromiseIconUiTest extends AbstractLauncherUiTest<Launcher> {
+public class PromiseIconUiTest extends BaseLauncherActivityTest<Launcher> {
@Rule
public final CheckFlagsRule mCheckFlagsRule =
@@ -64,19 +64,17 @@
private int mSessionId = -1;
- @Override
+ @Before
public void setUp() throws Exception {
- super.setUp();
- mDevice.pressHome();
- waitForLauncherCondition("Launcher didn't start", launcher -> launcher != null);
- waitForState("Launcher internal state didn't switch to Home", () -> LauncherState.NORMAL);
+ loadLauncherSync();
+ goToState(LauncherState.NORMAL);
mSessionId = -1;
}
@After
public void tearDown() throws IOException {
if (mSessionId > -1) {
- mTargetContext.getPackageManager().getPackageInstaller().abandonSession(mSessionId);
+ targetContext().getPackageManager().getPackageInstaller().abandonSession(mSessionId);
}
TestUtil.uninstallDummyApp();
}
@@ -90,7 +88,7 @@
params.setAppLabel(label);
params.setAppIcon(icon);
params.setInstallReason(PackageManager.INSTALL_REASON_USER);
- return mTargetContext.getPackageManager().getPackageInstaller().createSession(params);
+ return targetContext().getPackageManager().getPackageInstaller().createSession(params);
}
@Test
@@ -108,7 +106,7 @@
launcher.getWorkspace().getFirstMatch(findPromiseApp) != null);
// Remove session
- mTargetContext.getPackageManager().getPackageInstaller().abandonSession(mSessionId);
+ targetContext().getPackageManager().getPackageInstaller().abandonSession(mSessionId);
mSessionId = -1;
// Verify promise icon is removed
@@ -117,7 +115,6 @@
}
@Test
- @ViewCaptureRule.MayProduceNoFrames
public void testPromiseIcon_notAddedFromIneligibleSession() throws Throwable {
final String appLabel = "Test Promise App " + UUID.randomUUID().toString();
final ItemOperator findPromiseApp = (info, view) ->
@@ -138,7 +135,8 @@
@RequiresFlagsEnabled(FLAG_ENABLE_SUPPORT_FOR_ARCHIVING)
public void testPromiseIcon_addedArchivedApp() throws Throwable {
installDummyAppAndWaitForUIUpdate();
- assertThat(mDevice.executeShellCommand(String.format("pm archive %s", DUMMY_PACKAGE)))
+ assertThat(executeShellCommand(
+ String.format("pm archive %s", DUMMY_PACKAGE)))
.isEqualTo("Success\n");
// Create and add test session
@@ -148,28 +146,19 @@
// Verify promise icon is added to all apps view. The icon may not be added to the
// workspace even if there might be no icon present for archived app. But icon will
// always be in all apps view. In case an icon is not added, an exception would be thrown.
- final AllApps allApps = mLauncher.getWorkspace().switchToAllApps();
+ goToState(LauncherState.ALL_APPS);
// Wait for the promise icon to be added.
waitForLauncherCondition(
DUMMY_PACKAGE + " app was not found on all apps after being archived",
- launcher -> {
- try {
- allApps.getAppIcon(DUMMY_LABEL);
- } catch (Throwable t) {
- return false;
- }
- return true;
- });
-
- // Remove session
- mTargetContext.getPackageManager().getPackageInstaller().abandonSession(mSessionId);
- mSessionId = -1;
+ launcher -> Arrays.stream(launcher.getAppsView().getAppsStore().getApps())
+ .filter(info -> DUMMY_LABEL.equals(info.title.toString()))
+ .findAny()
+ .isPresent());
}
private void installDummyAppAndWaitForUIUpdate() throws IOException {
TestUtil.installDummyApp();
- mLauncher.waitForModelQueueCleared();
- mLauncher.waitForLauncherInitialized();
+ loadLauncherSync();
}
}
diff --git a/tests/src/com/android/launcher3/dragging/TaplUninstallRemoveTest.java b/tests/src/com/android/launcher3/dragging/TaplUninstallRemoveTest.java
index 44b8ff8..1816030 100644
--- a/tests/src/com/android/launcher3/dragging/TaplUninstallRemoveTest.java
+++ b/tests/src/com/android/launcher3/dragging/TaplUninstallRemoveTest.java
@@ -69,8 +69,7 @@
private void verifyAppUninstalledFromAllApps(Workspace workspace, String appName) {
final HomeAllApps allApps = workspace.switchToAllApps();
Wait.atMost(appName + " app was found on all apps after being uninstalled",
- () -> allApps.tryGetAppIcon(appName) == null,
- DEFAULT_UI_TIMEOUT, mLauncher);
+ () -> allApps.tryGetAppIcon(appName) == null, mLauncher);
}
private void installDummyAppAndWaitForUIUpdate() throws IOException {
diff --git a/tests/src/com/android/launcher3/model/GridMigrationTest.kt b/tests/src/com/android/launcher3/model/GridMigrationTest.kt
index 666ec16..379e98d 100644
--- a/tests/src/com/android/launcher3/model/GridMigrationTest.kt
+++ b/tests/src/com/android/launcher3/model/GridMigrationTest.kt
@@ -101,6 +101,7 @@
dst.gridState,
dst.dbHelper,
src.dbHelper.readableDatabase,
+ false,
)
} else {
GridSizeMigrationDBController.migrateGridIfNeeded(
@@ -109,6 +110,7 @@
dst.gridState,
dst.dbHelper,
src.dbHelper.readableDatabase,
+ false,
)
}
}
diff --git a/tests/src/com/android/launcher3/model/LoaderTaskTest.kt b/tests/src/com/android/launcher3/model/LoaderTaskTest.kt
index ef7242f..882061f 100644
--- a/tests/src/com/android/launcher3/model/LoaderTaskTest.kt
+++ b/tests/src/com/android/launcher3/model/LoaderTaskTest.kt
@@ -28,6 +28,7 @@
import com.android.launcher3.util.UserIconInfo
import com.google.common.truth.Truth
import java.util.concurrent.CountDownLatch
+import java.util.function.Predicate
import junit.framework.Assert.assertEquals
import org.junit.After
import org.junit.Before
@@ -76,6 +77,7 @@
@Mock private lateinit var modelDelegate: ModelDelegate
@Mock private lateinit var launcherBinder: BaseLauncherBinder
private lateinit var launcherModel: LauncherModel
+ @Mock private lateinit var widgetsFilterDataProvider: WidgetsFilterDataProvider
@Mock private lateinit var transaction: LoaderTransaction
@Mock private lateinit var iconCache: IconCache
@Mock private lateinit var idleLock: LooperIdleLock
@@ -89,6 +91,7 @@
@Before
fun setup() {
MockitoAnnotations.initMocks(this)
+ setFlagsRule.enableFlags(Flags.FLAG_ENABLE_TIERED_WIDGETS_BY_DEFAULT_IN_PICKER)
launcherModel = mock(LauncherModel::class.java)
mockitoSession =
ExtendedMockito.mockitoSession()
@@ -118,6 +121,7 @@
`when`(launcherBinder.newIdleLock(any())).thenReturn(idleLock)
`when`(idleLock.awaitLocked(1000)).thenReturn(false)
`when`(iconCache.updateHandler).thenReturn(iconCacheUpdateHandler)
+ `when`(widgetsFilterDataProvider.getDefaultWidgetsFilter()).thenReturn(Predicate { true })
context.putObject(UserCache.INSTANCE, userCache)
TestUtil.grantWriteSecurePermission()
@@ -136,17 +140,32 @@
val mockUserHandles = arrayListOf<UserHandle>(MAIN_HANDLE)
`when`(userCache.userProfiles).thenReturn(mockUserHandles)
`when`(userCache.getUserInfo(MAIN_HANDLE)).thenReturn(UserIconInfo(MAIN_HANDLE, 1))
- LoaderTask(app, bgAllAppsList, this, modelDelegate, launcherBinder)
+ LoaderTask(
+ app,
+ bgAllAppsList,
+ this,
+ modelDelegate,
+ launcherBinder,
+ widgetsFilterDataProvider,
+ )
.runSyncOnBackgroundThread()
Truth.assertThat(workspaceItems.size).isAtLeast(25)
Truth.assertThat(appWidgets.size).isAtLeast(7)
Truth.assertThat(collections.size()).isAtLeast(8)
Truth.assertThat(itemsIdMap.size()).isAtLeast(40)
+ Truth.assertThat(widgetsModel.defaultWidgetsFilter).isNotNull()
}
@Test
fun bindsLoadedDataCorrectly() {
- LoaderTask(app, bgAllAppsList, BgDataModel(), modelDelegate, launcherBinder)
+ LoaderTask(
+ app,
+ bgAllAppsList,
+ BgDataModel(),
+ modelDelegate,
+ launcherBinder,
+ widgetsFilterDataProvider,
+ )
.runSyncOnBackgroundThread()
verify(launcherBinder).bindWorkspace(true, false)
@@ -155,6 +174,7 @@
verify(launcherBinder).bindAllApps()
verify(iconCacheUpdateHandler, times(4)).updateIcons(any(), any<CachingLogic<Any>>(), any())
verify(launcherBinder).bindDeepShortcuts()
+ verify(widgetsFilterDataProvider).initPeriodicDataRefresh(any())
verify(launcherBinder).bindWidgets()
verify(modelDelegate).loadAndBindOtherItems(anyOrNull())
verify(iconCacheUpdateHandler).finish()
@@ -172,7 +192,15 @@
`when`(userManagerState?.isUserQuiet(MAIN_HANDLE)).thenReturn(true)
`when`(userCache.getUserInfo(MAIN_HANDLE)).thenReturn(UserIconInfo(MAIN_HANDLE, 1))
- LoaderTask(app, bgAllAppsList, this, modelDelegate, launcherBinder, userManagerState)
+ LoaderTask(
+ app,
+ bgAllAppsList,
+ this,
+ modelDelegate,
+ launcherBinder,
+ widgetsFilterDataProvider,
+ userManagerState,
+ )
.runSyncOnBackgroundThread()
verify(bgAllAppsList)
@@ -193,7 +221,15 @@
`when`(userManagerState?.isUserQuiet(MAIN_HANDLE)).thenReturn(true)
`when`(userCache.getUserInfo(MAIN_HANDLE)).thenReturn(UserIconInfo(MAIN_HANDLE, 3))
- LoaderTask(app, bgAllAppsList, this, modelDelegate, launcherBinder, userManagerState)
+ LoaderTask(
+ app,
+ bgAllAppsList,
+ this,
+ modelDelegate,
+ launcherBinder,
+ widgetsFilterDataProvider,
+ userManagerState,
+ )
.runSyncOnBackgroundThread()
verify(bgAllAppsList)
@@ -232,7 +268,14 @@
RestoreDbTask.setPending(spyContext)
// When
- LoaderTask(app, bgAllAppsList, BgDataModel(), modelDelegate, launcherBinder)
+ LoaderTask(
+ app,
+ bgAllAppsList,
+ BgDataModel(),
+ modelDelegate,
+ launcherBinder,
+ widgetsFilterDataProvider,
+ )
.runSyncOnBackgroundThread()
// Then
@@ -301,7 +344,14 @@
RestoreDbTask.setPending(spyContext)
// When
- LoaderTask(app, bgAllAppsList, BgDataModel(), modelDelegate, launcherBinder)
+ LoaderTask(
+ app,
+ bgAllAppsList,
+ BgDataModel(),
+ modelDelegate,
+ launcherBinder,
+ widgetsFilterDataProvider,
+ )
.runSyncOnBackgroundThread()
// Then
@@ -369,7 +419,14 @@
Settings.Secure.putInt(spyContext.contentResolver, "launcher_broadcast_installed_apps", 1)
// When
- LoaderTask(app, bgAllAppsList, BgDataModel(), modelDelegate, launcherBinder)
+ LoaderTask(
+ app,
+ bgAllAppsList,
+ BgDataModel(),
+ modelDelegate,
+ launcherBinder,
+ widgetsFilterDataProvider,
+ )
.runSyncOnBackgroundThread()
// Then
@@ -404,7 +461,14 @@
RestoreDbTask.setPending(spyContext)
// When
- LoaderTask(app, bgAllAppsList, BgDataModel(), modelDelegate, launcherBinder)
+ LoaderTask(
+ app,
+ bgAllAppsList,
+ BgDataModel(),
+ modelDelegate,
+ launcherBinder,
+ widgetsFilterDataProvider,
+ )
.runSyncOnBackgroundThread()
// Then
diff --git a/tests/src/com/android/launcher3/ui/AbstractLauncherUiTest.java b/tests/src/com/android/launcher3/ui/AbstractLauncherUiTest.java
index 206647a..a273648 100644
--- a/tests/src/com/android/launcher3/ui/AbstractLauncherUiTest.java
+++ b/tests/src/com/android/launcher3/ui/AbstractLauncherUiTest.java
@@ -21,6 +21,7 @@
import static com.android.launcher3.testing.shared.TestProtocol.ICON_MISSING;
import static com.android.launcher3.util.Executors.MAIN_EXECUTOR;
+import static com.android.launcher3.util.TestUtil.resolveSystemAppInfo;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertTrue;
@@ -31,9 +32,6 @@
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
-import android.content.pm.ActivityInfo;
-import android.content.pm.LauncherActivityInfo;
-import android.content.pm.LauncherApps;
import android.content.pm.PackageInfo;
import android.content.pm.PackageManager;
import android.graphics.Point;
@@ -97,10 +95,8 @@
*/
public abstract class AbstractLauncherUiTest<LAUNCHER_TYPE extends Launcher> {
- public static final long DEFAULT_ACTIVITY_TIMEOUT = TimeUnit.SECONDS.toMillis(10);
public static final long DEFAULT_BROADCAST_TIMEOUT_SECS = 10;
- public static final long DEFAULT_UI_TIMEOUT = TestUtil.DEFAULT_UI_TIMEOUT;
private static final String TAG = "AbstractLauncherUiTest";
private static final long BYTES_PER_MEGABYTE = 1 << 20;
@@ -151,7 +147,7 @@
launcher.forceGc();
return MAIN_EXECUTOR.submit(
() -> launcher.noLeakedActivities(requireOneActiveActivity)).get();
- }, DEFAULT_UI_TIMEOUT, launcher);
+ }, launcher);
}
public static String getAppPackageName() {
@@ -443,7 +439,7 @@
*/
protected <T> T getOnUiThread(final Callable<T> callback) {
try {
- return mMainThreadExecutor.submit(callback).get(DEFAULT_UI_TIMEOUT,
+ return mMainThreadExecutor.submit(callback).get(TestUtil.DEFAULT_UI_TIMEOUT,
TimeUnit.MILLISECONDS);
} catch (TimeoutException e) {
Log.e(TAG, "Timeout in getOnUiThread, sending SIGABRT", e);
@@ -498,13 +494,7 @@
// flakiness.
protected void waitForLauncherCondition(String
message, Function<LAUNCHER_TYPE, Boolean> condition) {
- waitForLauncherCondition(message, condition, DEFAULT_ACTIVITY_TIMEOUT);
- }
-
- // Cannot be used in TaplTests after injecting any gesture using Tapl because this can hide
- // flakiness.
- protected <O> O getOnceNotNull(String message, Function<LAUNCHER_TYPE, O> f) {
- return getOnceNotNull(message, f, DEFAULT_ACTIVITY_TIMEOUT);
+ waitForLauncherCondition(message, condition, TestUtil.DEFAULT_UI_TIMEOUT);
}
// Cannot be used in TaplTests after injecting any gesture using Tapl because this can hide
@@ -513,12 +503,12 @@
String message, Function<LAUNCHER_TYPE, Boolean> condition, long timeout) {
verifyKeyguardInvisible();
if (!TestHelpers.isInLauncherProcess()) return;
- Wait.atMost(message, () -> getFromLauncher(condition), timeout, mLauncher);
+ Wait.atMost(message, () -> getFromLauncher(condition), mLauncher, timeout);
}
// Cannot be used in TaplTests after injecting any gesture using Tapl because this can hide
// flakiness.
- protected <T> T getOnceNotNull(String message, Function<LAUNCHER_TYPE, T> f, long timeout) {
+ protected <T> T getOnceNotNull(String message, Function<LAUNCHER_TYPE, T> f) {
if (!TestHelpers.isInLauncherProcess()) return null;
final Object[] output = new Object[1];
@@ -526,7 +516,7 @@
final Object fromLauncher = getFromLauncher(f);
output[0] = fromLauncher;
return fromLauncher != null;
- }, timeout, mLauncher);
+ }, mLauncher);
return (T) output[0];
}
@@ -540,12 +530,7 @@
Wait.atMost(message, () -> {
testThreadAction.run();
return getFromLauncher(condition);
- }, timeout, mLauncher);
- }
-
- protected LauncherActivityInfo getSettingsApp() {
- return mTargetContext.getSystemService(LauncherApps.class)
- .getActivityList("com.android.settings", Process.myUserHandle()).get(0);
+ }, mLauncher, timeout);
}
/**
@@ -633,20 +618,13 @@
}
getInstrumentation().getTargetContext().startActivity(intent);
assertTrue("App didn't start: " + selector,
- TestHelpers.wait(Until.hasObject(selector), DEFAULT_UI_TIMEOUT));
+ TestHelpers.wait(Until.hasObject(selector), TestUtil.DEFAULT_UI_TIMEOUT));
// Wait for the Launcher to stop.
final LauncherInstrumentation launcherInstrumentation = new LauncherInstrumentation();
Wait.atMost("Launcher activity didn't stop",
() -> !launcherInstrumentation.isLauncherActivityStarted(),
- DEFAULT_ACTIVITY_TIMEOUT, launcherInstrumentation);
- }
-
- public static ActivityInfo resolveSystemAppInfo(String category) {
- return getInstrumentation().getContext().getPackageManager().resolveActivity(
- new Intent(Intent.ACTION_MAIN).addCategory(category),
- PackageManager.MATCH_SYSTEM_ONLY).
- activityInfo;
+ launcherInstrumentation);
}
@@ -662,8 +640,7 @@
launcher.finish();
}
});
- waitForLauncherCondition(
- "Launcher still active", launcher -> launcher == null, DEFAULT_UI_TIMEOUT);
+ waitForLauncherCondition("Launcher still active", launcher -> launcher == null);
}
protected boolean isInLaunchedApp(LAUNCHER_TYPE launcher) {
diff --git a/tests/src/com/android/launcher3/ui/TaplWorkProfileTest.java b/tests/src/com/android/launcher3/ui/TaplWorkProfileTest.java
index a45e3bb..33ffd1d 100644
--- a/tests/src/com/android/launcher3/ui/TaplWorkProfileTest.java
+++ b/tests/src/com/android/launcher3/ui/TaplWorkProfileTest.java
@@ -158,16 +158,16 @@
waitForLauncherCondition("work profile initial state check failed", launcher ->
- manager.getWorkModeSwitch() != null
+ manager.getWorkUtilityView() != null
&& manager.getCurrentState() == WorkProfileManager.STATE_ENABLED
- && manager.getWorkModeSwitch().isEnabled(),
+ && manager.getWorkUtilityView().isEnabled(),
LauncherInstrumentation.WAIT_TIME_MS);
//start work profile toggle OFF test
executeOnLauncher(l -> {
// Ensure updates are not deferred so notification happens when apps pause.
l.getAppsView().getAppsStore().disableDeferUpdates(DEFER_UPDATES_TEST);
- l.getAppsView().getWorkManager().getWorkModeSwitch().performClick();
+ l.getAppsView().getWorkManager().getWorkUtilityView().performClick();
});
waitForLauncherCondition("Work profile toggle OFF failed", launcher -> {
diff --git a/tests/src/com/android/launcher3/ui/widget/TaplAddConfigWidgetTest.java b/tests/src/com/android/launcher3/ui/widget/TaplAddConfigWidgetTest.java
index 7ff4f22..7845222 100644
--- a/tests/src/com/android/launcher3/ui/widget/TaplAddConfigWidgetTest.java
+++ b/tests/src/com/android/launcher3/ui/widget/TaplAddConfigWidgetTest.java
@@ -103,12 +103,12 @@
setResultAndWaitForAnimation(acceptConfig);
if (acceptConfig) {
- Wait.atMost("", new WidgetSearchCondition(), DEFAULT_ACTIVITY_TIMEOUT, mLauncher);
+ Wait.atMost("", new WidgetSearchCondition(), mLauncher);
assertNotNull(mAppWidgetManager.getAppWidgetInfo(mWidgetId));
} else {
// Verify that the widget id is deleted.
Wait.atMost("", () -> mAppWidgetManager.getAppWidgetInfo(mWidgetId) == null,
- DEFAULT_ACTIVITY_TIMEOUT, mLauncher);
+ mLauncher);
}
}
diff --git a/tests/src/com/android/launcher3/ui/widget/TaplAddWidgetTest.java b/tests/src/com/android/launcher3/ui/widget/TaplAddWidgetTest.java
index 9a2147a..460ffc4 100644
--- a/tests/src/com/android/launcher3/ui/widget/TaplAddWidgetTest.java
+++ b/tests/src/com/android/launcher3/ui/widget/TaplAddWidgetTest.java
@@ -29,6 +29,7 @@
import com.android.launcher3.ui.AbstractLauncherUiTest;
import com.android.launcher3.ui.PortraitLandscapeRunner.PortraitLandscape;
import com.android.launcher3.ui.TestViewHelpers;
+import com.android.launcher3.util.TestUtil;
import com.android.launcher3.util.rule.ShellCommandRule;
import com.android.launcher3.widget.LauncherAppWidgetProviderInfo;
@@ -68,7 +69,7 @@
resizeFrame.dismiss();
final Widget widget = mLauncher.getWorkspace().tryGetWidget(widgetInfo.label,
- DEFAULT_UI_TIMEOUT);
+ TestUtil.DEFAULT_UI_TIMEOUT);
assertNotNull("Widget not found on the workspace", widget);
widget.launch(getAppPackageName());
mLauncher.disableDebugTracing(); // b/289161193
diff --git a/tests/src/com/android/launcher3/ui/widget/TaplBindWidgetTest.java b/tests/src/com/android/launcher3/ui/widget/TaplBindWidgetTest.java
index d40d3bc..4cdbd96 100644
--- a/tests/src/com/android/launcher3/ui/widget/TaplBindWidgetTest.java
+++ b/tests/src/com/android/launcher3/ui/widget/TaplBindWidgetTest.java
@@ -53,6 +53,7 @@
import com.android.launcher3.tapl.Workspace;
import com.android.launcher3.ui.AbstractLauncherUiTest;
import com.android.launcher3.ui.TestViewHelpers;
+import com.android.launcher3.util.TestUtil;
import com.android.launcher3.util.rule.ShellCommandRule;
import com.android.launcher3.widget.LauncherAppWidgetProviderInfo;
import com.android.launcher3.widget.WidgetManagerHelper;
@@ -233,13 +234,15 @@
}
private void verifyWidgetPresent(LauncherAppWidgetProviderInfo info) {
- final Widget widget = mLauncher.getWorkspace().tryGetWidget(info.label, DEFAULT_UI_TIMEOUT);
+ final Widget widget = mLauncher.getWorkspace().tryGetWidget(info.label,
+ TestUtil.DEFAULT_UI_TIMEOUT);
assertTrue("Widget is not present",
widget != null);
}
private void verifyPendingWidgetPresent() {
- final Widget widget = mLauncher.getWorkspace().tryGetPendingWidget(DEFAULT_UI_TIMEOUT);
+ final Widget widget = mLauncher.getWorkspace().tryGetPendingWidget(
+ TestUtil.DEFAULT_UI_TIMEOUT);
assertTrue("Pending widget is not present",
widget != null);
}
diff --git a/tests/src/com/android/launcher3/ui/widget/TaplRequestPinItemTest.java b/tests/src/com/android/launcher3/ui/widget/TaplRequestPinItemTest.java
index 35c7cab..fe3b2ee 100644
--- a/tests/src/com/android/launcher3/ui/widget/TaplRequestPinItemTest.java
+++ b/tests/src/com/android/launcher3/ui/widget/TaplRequestPinItemTest.java
@@ -169,8 +169,7 @@
// Go back to home
mLauncher.goHome();
- Wait.atMost("", new ItemSearchCondition(itemMatcher), DEFAULT_ACTIVITY_TIMEOUT,
- mLauncher);
+ Wait.atMost("", new ItemSearchCondition(itemMatcher), mLauncher);
}
/**
diff --git a/tests/src/com/android/launcher3/util/BaseLauncherActivityTest.kt b/tests/src/com/android/launcher3/util/BaseLauncherActivityTest.kt
new file mode 100644
index 0000000..bacce40
--- /dev/null
+++ b/tests/src/com/android/launcher3/util/BaseLauncherActivityTest.kt
@@ -0,0 +1,146 @@
+/*
+ * 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 android.content.Context
+import android.content.Intent
+import android.os.SystemClock
+import android.view.InputDevice
+import android.view.KeyCharacterMap
+import android.view.KeyEvent
+import android.view.MotionEvent
+import androidx.lifecycle.Lifecycle.State.RESUMED
+import androidx.test.core.app.ActivityScenario
+import androidx.test.core.app.ActivityScenario.ActivityAction
+import androidx.test.platform.app.InstrumentationRegistry.getInstrumentation
+import androidx.test.uiautomator.UiDevice
+import com.android.launcher3.Launcher
+import com.android.launcher3.LauncherAppState
+import com.android.launcher3.LauncherState
+import com.android.launcher3.allapps.AllAppsStore.DEFER_UPDATES_TEST
+import com.android.launcher3.tapl.TestHelpers
+import com.android.launcher3.util.ModelTestExtensions.loadModelSync
+import com.android.launcher3.util.Wait.atMost
+import java.util.function.Function
+import java.util.function.Supplier
+import org.junit.After
+
+/**
+ * Base class for tests which use Launcher activity with some utility methods.
+ *
+ * This should instead be a rule, but is kept as a base class for easier migration from TAPL
+ */
+open class BaseLauncherActivityTest<LAUNCHER_TYPE : Launcher> {
+
+ private var currentScenario: ActivityScenario<LAUNCHER_TYPE>? = null
+
+ val scenario: ActivityScenario<LAUNCHER_TYPE>
+ get() =
+ currentScenario
+ ?: ActivityScenario.launch<LAUNCHER_TYPE>(
+ TestHelpers.getHomeIntentInPackage(targetContext()),
+ null,
+ )
+ .also { currentScenario = it }
+
+ @After
+ fun closeCurrentActivity() {
+ currentScenario?.close()
+ currentScenario = null
+ }
+
+ protected fun loadLauncherSync() {
+ LauncherAppState.getInstance(targetContext()).model.loadModelSync()
+ scenario.moveToState(RESUMED)
+ }
+
+ protected fun targetContext(): Context = getInstrumentation().targetContext
+
+ protected fun goToState(state: LauncherState) = executeOnLauncher {
+ it.stateManager.goToState(state, 0)
+ }
+
+ protected fun executeOnLauncher(f: ActivityAction<LAUNCHER_TYPE>) = scenario.onActivity(f)
+
+ protected fun <T> getFromLauncher(f: Function<in LAUNCHER_TYPE, out T?>): T? {
+ var result: T? = null
+ executeOnLauncher { result = f.apply(it) }
+ return result
+ }
+
+ protected fun isInState(state: Supplier<LauncherState>): Boolean =
+ getFromLauncher { it.stateManager.state == state.get() }!!
+
+ protected fun waitForState(message: String, state: Supplier<LauncherState>) =
+ waitForLauncherCondition(message) { it.stateManager.currentStableState === state.get() }
+
+ protected fun waitForLauncherCondition(
+ message: String,
+ condition: Function<LAUNCHER_TYPE, Boolean>,
+ ) = atMost(message, { getFromLauncher(condition)!! })
+
+ protected fun <T> getOnceNotNull(message: String, f: Function<LAUNCHER_TYPE, T?>): T? {
+ var output: T? = null
+ atMost(
+ message,
+ {
+ val fromLauncher = getFromLauncher<T>(f)
+ output = fromLauncher
+ fromLauncher != null
+ },
+ )
+ return output
+ }
+
+ protected fun getAllAppsScroll(launcher: LAUNCHER_TYPE) =
+ launcher.appsView.activeRecyclerView.computeVerticalScrollOffset()
+
+ @JvmOverloads
+ protected fun injectKeyEvent(keyCode: Int, actionDown: Boolean, metaState: Int = 0) {
+ val eventTime = SystemClock.uptimeMillis()
+ val event =
+ KeyEvent.obtain(
+ eventTime,
+ eventTime,
+ if (actionDown) KeyEvent.ACTION_DOWN else MotionEvent.ACTION_UP,
+ keyCode,
+ /* repeat= */ 0,
+ metaState,
+ KeyCharacterMap.VIRTUAL_KEYBOARD,
+ /* scancode= */ 0,
+ /* flags= */ 0,
+ InputDevice.SOURCE_KEYBOARD,
+ /* characters =*/ null,
+ )
+ executeOnLauncher { it.dispatchKeyEvent(event) }
+ event.recycle()
+ }
+
+ fun startAppFast(packageName: String) {
+ val intent = targetContext().packageManager.getLaunchIntentForPackage(packageName)!!
+ intent.addCategory(Intent.CATEGORY_LAUNCHER)
+ intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK or Intent.FLAG_ACTIVITY_CLEAR_TASK)
+ targetContext().startActivity(intent)
+ UiDevice.getInstance(getInstrumentation()).waitForIdle()
+ }
+
+ fun freezeAllApps() = executeOnLauncher {
+ it.appsView.appsStore.enableDeferUpdates(DEFER_UPDATES_TEST)
+ }
+
+ fun executeShellCommand(cmd: String) =
+ UiDevice.getInstance(getInstrumentation()).executeShellCommand(cmd)
+}
diff --git a/tests/src/com/android/launcher3/util/Wait.java b/tests/src/com/android/launcher3/util/Wait.java
deleted file mode 100644
index 50bc32e..0000000
--- a/tests/src/com/android/launcher3/util/Wait.java
+++ /dev/null
@@ -1,66 +0,0 @@
-package com.android.launcher3.util;
-
-import android.os.SystemClock;
-import android.util.Log;
-
-import com.android.launcher3.tapl.LauncherInstrumentation;
-
-import org.junit.Assert;
-
-import java.util.function.Supplier;
-
-/**
- * A utility class for waiting for a condition to be true.
- */
-public class Wait {
-
- private static final long DEFAULT_SLEEP_MS = 200;
-
- public static void atMost(String message, Condition condition, long timeout,
- LauncherInstrumentation launcher) {
- atMost(() -> message, condition, timeout, DEFAULT_SLEEP_MS, launcher);
- }
-
- public static void atMost(Supplier<String> message, Condition condition, long timeout,
- LauncherInstrumentation launcher) {
- atMost(message, condition, timeout, DEFAULT_SLEEP_MS, launcher);
- }
-
- public static void atMost(Supplier<String> message, Condition condition, long timeout,
- long sleepMillis,
- LauncherInstrumentation launcher) {
- final long startTime = SystemClock.uptimeMillis();
- long endTime = startTime + timeout;
- Log.d("Wait", "atMost: " + startTime + " - " + endTime);
- while (SystemClock.uptimeMillis() < endTime) {
- try {
- if (condition.isTrue()) {
- return;
- }
- } catch (Throwable t) {
- throw new RuntimeException(t);
- }
- SystemClock.sleep(sleepMillis);
- }
-
- // Check once more before returning false.
- try {
- if (condition.isTrue()) {
- return;
- }
- } catch (Throwable t) {
- throw new RuntimeException(t);
- }
- Log.d("Wait", "atMost: timed out: " + SystemClock.uptimeMillis());
- launcher.checkForAnomaly(false, false);
- Assert.fail(message.get());
- }
-
- /**
- * Interface representing a generic condition
- */
- public interface Condition {
-
- boolean isTrue() throws Throwable;
- }
-}
diff --git a/tests/src/com/android/launcher3/util/Wait.kt b/tests/src/com/android/launcher3/util/Wait.kt
new file mode 100644
index 0000000..1e5af54
--- /dev/null
+++ b/tests/src/com/android/launcher3/util/Wait.kt
@@ -0,0 +1,79 @@
+/*
+ * 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 android.os.SystemClock
+import android.util.Log
+import com.android.launcher3.tapl.LauncherInstrumentation
+import java.util.function.Supplier
+import org.junit.Assert
+
+/** A utility class for waiting for a condition to be true. */
+object Wait {
+ private const val DEFAULT_SLEEP_MS: Long = 200
+
+ @JvmStatic
+ @JvmOverloads
+ fun atMost(
+ message: String,
+ condition: Condition,
+ launcherInstrumentation: LauncherInstrumentation? = null,
+ timeout: Long = TestUtil.DEFAULT_UI_TIMEOUT,
+ ) {
+ atMost({ message }, condition, launcherInstrumentation, timeout)
+ }
+
+ @JvmStatic
+ @JvmOverloads
+ fun atMost(
+ message: Supplier<String>,
+ condition: Condition,
+ launcherInstrumentation: LauncherInstrumentation? = null,
+ timeout: Long = TestUtil.DEFAULT_UI_TIMEOUT,
+ ) {
+ val startTime = SystemClock.uptimeMillis()
+ val endTime = startTime + timeout
+ Log.d("Wait", "atMost: $startTime - $endTime")
+ while (SystemClock.uptimeMillis() < endTime) {
+ try {
+ if (condition.isTrue()) {
+ return
+ }
+ } catch (t: Throwable) {
+ throw RuntimeException(t)
+ }
+ SystemClock.sleep(DEFAULT_SLEEP_MS)
+ }
+
+ // Check once more before returning false.
+ try {
+ if (condition.isTrue()) {
+ return
+ }
+ } catch (t: Throwable) {
+ throw RuntimeException(t)
+ }
+ Log.d("Wait", "atMost: timed out: " + SystemClock.uptimeMillis())
+ launcherInstrumentation?.checkForAnomaly(false, false)
+ Assert.fail(message.get())
+ }
+
+ /** Interface representing a generic condition */
+ fun interface Condition {
+
+ @Throws(Throwable::class) fun isTrue(): Boolean
+ }
+}
diff --git a/tests/tapl/com/android/launcher3/tapl/Background.java b/tests/tapl/com/android/launcher3/tapl/Background.java
index e1bd686..512db39 100644
--- a/tests/tapl/com/android/launcher3/tapl/Background.java
+++ b/tests/tapl/com/android/launcher3/tapl/Background.java
@@ -29,6 +29,7 @@
import com.android.launcher3.tapl.LauncherInstrumentation.NavigationModel;
import com.android.launcher3.tapl.LauncherInstrumentation.TrackpadGestureType;
+import com.android.launcher3.tapl.OverviewTask.TaskViewType;
import com.android.launcher3.testing.shared.TestProtocol;
import java.util.List;
@@ -121,12 +122,31 @@
if (mLauncher.isTablet()) {
List<UiObject2> tasks = mLauncher.getDevice().findObjects(
TASK_SELECTOR);
+
final int centerX = mLauncher.getDevice().getDisplayWidth() / 2;
- mLauncher.assertTrue(
- "Task(s) found to the right of the swiped task",
- tasks.stream().allMatch(t ->
- t.getVisibleBounds().right < centerX
- || t.getVisibleBounds().centerX() == centerX));
+ UiObject2 centerTask = tasks.stream()
+ .filter(t -> t.getVisibleCenter().x == centerX)
+ .findFirst()
+ .orElse(null);
+
+ if (centerTask != null) {
+ mLauncher.assertTrue(
+ "Task(s) found to the right of the swiped task",
+ tasks.stream()
+ .filter(t -> t != centerTask
+ && OverviewTask.getType(t)
+ != TaskViewType.DESKTOP)
+ .allMatch(t -> t.getVisibleBounds().right
+ < centerTask.getVisibleBounds().left));
+ mLauncher.assertTrue(
+ "DesktopTask(s) found to the left of the swiped task",
+ tasks.stream()
+ .filter(t -> t != centerTask
+ && OverviewTask.getType(t)
+ == TaskViewType.DESKTOP)
+ .allMatch(t -> t.getVisibleBounds().left
+ > centerTask.getVisibleBounds().right));
+ }
}
}
diff --git a/tests/tapl/com/android/launcher3/tapl/BaseOverview.java b/tests/tapl/com/android/launcher3/tapl/BaseOverview.java
index 1002ca4..b15afc1 100644
--- a/tests/tapl/com/android/launcher3/tapl/BaseOverview.java
+++ b/tests/tapl/com/android/launcher3/tapl/BaseOverview.java
@@ -536,6 +536,10 @@
int focusedTaskHeight = focusTaskSize.height();
for (UiObject2 task : taskViews) {
OverviewTask overviewTask = new OverviewTask(mLauncher, task, this);
+ // Desktop tasks can't be focused tasks, but are the same size.
+ if (overviewTask.isDesktop()) {
+ continue;
+ }
if (overviewTask.getVisibleHeight() == focusedTaskHeight) {
return overviewTask;
}
diff --git a/tests/tapl/com/android/launcher3/tapl/OverviewTask.java b/tests/tapl/com/android/launcher3/tapl/OverviewTask.java
index 5fd4dac..8512d73 100644
--- a/tests/tapl/com/android/launcher3/tapl/OverviewTask.java
+++ b/tests/tapl/com/android/launcher3/tapl/OverviewTask.java
@@ -57,7 +57,7 @@
mLauncher.assertNotNull("task must not be null", task);
mTask = task;
mOverview = overview;
- mType = getType();
+ mType = getType(task);
verifyActiveContainer();
}
@@ -304,8 +304,12 @@
return containsContentDescription(expected, DEFAULT);
}
- private TaskViewType getType() {
- String resourceName = mTask.getResourceName();
+ /**
+ * Returns the TaskView type of the task. It will return whether the task is a single TaskView,
+ * a GroupedTaskView or a DesktopTaskView.
+ */
+ static TaskViewType getType(UiObject2 task) {
+ String resourceName = task.getResourceName();
if (resourceName.endsWith("task_view_grouped")) {
return TaskViewType.GROUPED;
} else if (resourceName.endsWith("task_view_desktop")) {
@@ -345,7 +349,7 @@
}
}
- private enum TaskViewType {
+ enum TaskViewType {
SINGLE,
GROUPED,
DESKTOP