Merge "Use ItemInfo with correct position when adding to Workspace via Accessibility." into main
diff --git a/AndroidManifest-common.xml b/AndroidManifest-common.xml
index a31ee80..edbea88 100644
--- a/AndroidManifest-common.xml
+++ b/AndroidManifest-common.xml
@@ -52,18 +52,18 @@
name in the permissions. eq com.mypackage.permission.READ_SETTINGS
-->
<permission
- android:name="${packageName}.permission.READ_SETTINGS"
+ android:name="${applicationId}.permission.READ_SETTINGS"
android:protectionLevel="signatureOrSystem"
android:label="@string/permlab_read_settings"
android:description="@string/permdesc_read_settings"/>
<permission
- android:name="${packageName}.permission.WRITE_SETTINGS"
+ android:name="${applicationId}.permission.WRITE_SETTINGS"
android:protectionLevel="signatureOrSystem"
android:label="@string/permlab_write_settings"
android:description="@string/permdesc_write_settings"/>
- <uses-permission android:name="${packageName}.permission.READ_SETTINGS" />
- <uses-permission android:name="${packageName}.permission.WRITE_SETTINGS" />
+ <uses-permission android:name="${applicationId}.permission.READ_SETTINGS" />
+ <uses-permission android:name="${applicationId}.permission.WRITE_SETTINGS" />
<application
android:backupAgent="com.android.launcher3.LauncherBackupAgent"
@@ -126,10 +126,10 @@
-->
<provider
android:name="com.android.launcher3.LauncherProvider"
- android:authorities="${packageName}.settings"
+ android:authorities="${applicationId}.settings"
android:exported="true"
- android:writePermission="${packageName}.permission.WRITE_SETTINGS"
- android:readPermission="${packageName}.permission.READ_SETTINGS" />
+ android:writePermission="${applicationId}.permission.WRITE_SETTINGS"
+ android:readPermission="${applicationId}.permission.READ_SETTINGS" />
<!--
The content provider for exposing various launcher grid options.
@@ -137,7 +137,7 @@
-->
<provider
android:name="com.android.launcher3.graphics.GridCustomizationsProvider"
- android:authorities="${packageName}.grid_control"
+ android:authorities="${applicationId}.grid_control"
android:exported="true" />
<!--
@@ -157,7 +157,7 @@
<provider
android:name="com.android.launcher3.testing.TestInformationProvider"
- android:authorities="${packageName}.TestInfo"
+ android:authorities="${applicationId}.TestInfo"
android:readPermission="android.permission.WRITE_SECURE_SETTINGS"
android:writePermission="android.permission.WRITE_SECURE_SETTINGS"
android:exported="true"
diff --git a/aconfig/launcher.aconfig b/aconfig/launcher.aconfig
index 8274bd6..6b07bb6 100644
--- a/aconfig/launcher.aconfig
+++ b/aconfig/launcher.aconfig
@@ -229,3 +229,13 @@
description: "Enables an add button in the widget picker"
bug: "323886237"
}
+
+flag {
+ name: "enable_handle_delayed_gesture_callbacks"
+ namespace: "launcher"
+ description: "Enables additional handling for delayed mid-gesture callbacks"
+ bug: "285636175"
+ metadata {
+ purpose: PURPOSE_BUGFIX
+ }
+}
diff --git a/go/quickstep/res/values-ne/strings.xml b/go/quickstep/res/values-ne/strings.xml
index cee6603..e66f063 100644
--- a/go/quickstep/res/values-ne/strings.xml
+++ b/go/quickstep/res/values-ne/strings.xml
@@ -8,7 +8,7 @@
<string name="dialog_acknowledge" msgid="2804025517675853172">"बुझेँ"</string>
<string name="dialog_cancel" msgid="6464336969134856366">"रद्द गर्नुहोस्"</string>
<string name="dialog_settings" msgid="6564397136021186148">"सेटिङ"</string>
- <string name="niu_actions_confirmation_title" msgid="3863451714863526143">"स्क्रिनमा देखिने पाठ अनुवाद गर्नुहोस् वा पढेर सुनाइयोस्"</string>
+ <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="assistant_not_selected_title" msgid="5017072974603345228">"तपाईं यो सुविधा चलाउन चाहनुहुन्छ भने कुनै सहायक छनौट गर्नुहोस्"</string>
<string name="assistant_not_selected_text" msgid="3244613673884359276">"तपाईं आफ्नो स्क्रिनमा देखिने पाठ सुन्न वा अनुवाद गर्न चाहनुहुन्छ भने सेटिङमा गई कुनै डिजिटल सहायक एप छनौट गर्नुहोस्"</string>
diff --git a/quickstep/AndroidManifest.xml b/quickstep/AndroidManifest.xml
index e75812a..bf198b6 100644
--- a/quickstep/AndroidManifest.xml
+++ b/quickstep/AndroidManifest.xml
@@ -50,7 +50,7 @@
<uses-permission android:name="android.permission.ACCESS_HIDDEN_PROFILES_FULL" />
<!-- Permission required to start a WidgetPickerActivity. -->
- <permission android:name="${packageName}.permission.START_WIDGET_PICKER_ACTIVITY"
+ <permission android:name="${applicationId}.permission.START_WIDGET_PICKER_ACTIVITY"
android:protectionLevel="signature|privileged" />
<application android:backupAgent="com.android.launcher3.LauncherBackupAgent"
@@ -83,11 +83,12 @@
android:configChanges="keyboard|keyboardHidden|mcc|mnc|navigation|orientation|screenSize|screenLayout|smallestScreenSize"
android:resizeableActivity="true"
android:resumeWhilePausing="true"
+ android:enableOnBackInvokedCallback="false"
android:taskAffinity=""/>
<!-- Content provider to settings search. The autority should be same as the packageName -->
<provider android:name="com.android.quickstep.LauncherSearchIndexablesProvider"
- android:authorities="${packageName}"
+ android:authorities="${applicationId}"
android:grantUriPermissions="true"
android:multiprocess="true"
android:permission="android.permission.READ_SEARCH_INDEXABLES"
@@ -99,7 +100,7 @@
<!-- FileProvider used for sharing images. -->
<provider android:name="androidx.core.content.FileProvider"
- android:authorities="${packageName}.overview.fileprovider"
+ android:authorities="${applicationId}.overview.fileprovider"
android:exported="false"
android:grantUriPermissions="true">
<meta-data android:name="android.support.FILE_PROVIDER_PATHS"
diff --git a/quickstep/res/values-be/strings.xml b/quickstep/res/values-be/strings.xml
index 344a3e6..6b20866 100644
--- a/quickstep/res/values-be/strings.xml
+++ b/quickstep/res/values-be/strings.xml
@@ -118,10 +118,8 @@
<string name="taskbar_edu_features" msgid="3320337287472848162">"Выкарыстоўвайце магчымасці панэлі задач"</string>
<string name="taskbar_edu_pinning_title" msgid="210102174154211712">"Замацуйце панэль задач унізе экрана"</string>
<string name="taskbar_edu_pinning_standalone" msgid="2636919474366410467">"Для гэтага націсніце на раздзяляльнік і ўтрымлівайце яго"</string>
- <!-- no translation found for taskbar_edu_circle_to_search_title (4322780398403949508) -->
- <skip />
- <!-- no translation found for taskbar_edu_circle_to_search_disclosure (5841648785867787221) -->
- <skip />
+ <string name="taskbar_edu_circle_to_search_title" msgid="4322780398403949508">"Каб выканаць пошук па тым, што адлюстравана на экране, націсніце і ўтрымлівайце клавішу дзеяння"</string>
+ <string name="taskbar_edu_circle_to_search_disclosure" msgid="5841648785867787221">"Гэты прадукт выконвае пошук па змесціве выбранай часткі экрана. Дзейнічаюць <xliff:g id="BEGIN_TOS_LINK"><a href="%2$s"></xliff:g>Умовы выкарыстання<xliff:g id="END_TOS_LINK"></a></xliff:g> і <xliff:g id="BEGIN_PRIVACY_LINK"><a href="%1$s"></xliff:g>Палітыка прыватнасці<xliff:g id="END_PRIVACY_LINK"></a></xliff:g> Google."</string>
<string name="taskbar_edu_close" msgid="887022990168191073">"Закрыць"</string>
<string name="taskbar_edu_done" msgid="6880178093977704569">"Гатова"</string>
<string name="taskbar_button_home" msgid="2151398979630664652">"Галоўны экран"</string>
diff --git a/quickstep/res/values-bg/strings.xml b/quickstep/res/values-bg/strings.xml
index 6ae8931..8631d8b 100644
--- a/quickstep/res/values-bg/strings.xml
+++ b/quickstep/res/values-bg/strings.xml
@@ -118,10 +118,8 @@
<string name="taskbar_edu_features" msgid="3320337287472848162">"Правете повече неща с лентата на задачите"</string>
<string name="taskbar_edu_pinning_title" msgid="210102174154211712">"Лентата на задачите да се показва винаги"</string>
<string name="taskbar_edu_pinning_standalone" msgid="2636919474366410467">"За да фиксирате лентата на задачите най-долу на екрана, докоснете и задръжте разделителя"</string>
- <!-- no translation found for taskbar_edu_circle_to_search_title (4322780398403949508) -->
- <skip />
- <!-- no translation found for taskbar_edu_circle_to_search_disclosure (5841648785867787221) -->
- <skip />
+ <string name="taskbar_edu_circle_to_search_title" msgid="4322780398403949508">"Докоснете и задръжте клавиша за действия, за да извършите търсене със съдържанието на екрана"</string>
+ <string name="taskbar_edu_circle_to_search_disclosure" msgid="5841648785867787221">"Този продукт използва избраната част на екрана ви, за да търси. Прилагат се <xliff:g id="BEGIN_PRIVACY_LINK"><a href="%1$s"></xliff:g>Декларацията за поверителност<xliff:g id="END_PRIVACY_LINK"></a></xliff:g> и <xliff:g id="BEGIN_TOS_LINK"><a href="%2$s"></xliff:g>Общите условия<xliff:g id="END_TOS_LINK"></a></xliff:g> на Google."</string>
<string name="taskbar_edu_close" msgid="887022990168191073">"Затваряне"</string>
<string name="taskbar_edu_done" msgid="6880178093977704569">"Готово"</string>
<string name="taskbar_button_home" msgid="2151398979630664652">"Начало"</string>
diff --git a/quickstep/res/values-bn/strings.xml b/quickstep/res/values-bn/strings.xml
index dec05ff..948d07d 100644
--- a/quickstep/res/values-bn/strings.xml
+++ b/quickstep/res/values-bn/strings.xml
@@ -118,10 +118,8 @@
<string name="taskbar_edu_features" msgid="3320337287472848162">"\'টাস্কবার\' ফিচারের সাহায্যে আরও অনেক কিছু করুন"</string>
<string name="taskbar_edu_pinning_title" msgid="210102174154211712">"টাস্কবার সবসময় দেখানো"</string>
<string name="taskbar_edu_pinning_standalone" msgid="2636919474366410467">"স্ক্রিনের নিচে টাস্কবার সবসময় দেখাতে ডিভাইডার টাচ করে ধরে থাকুন"</string>
- <!-- no translation found for taskbar_edu_circle_to_search_title (4322780398403949508) -->
- <skip />
- <!-- no translation found for taskbar_edu_circle_to_search_disclosure (5841648785867787221) -->
- <skip />
+ <string name="taskbar_edu_circle_to_search_title" msgid="4322780398403949508">"আপনার স্ক্রিনে দেখতে পাওয়া কন্টেন্ট সার্চ করতে অ্যাকশন কী স্পর্শ করে ধরে রাখুন"</string>
+ <string name="taskbar_edu_circle_to_search_disclosure" msgid="5841648785867787221">"সার্চ করার জন্য এই প্রোডাক্ট স্ক্রিনের বেছে নেওয়া অংশটুকু ব্যবহার করে। Google-এর <xliff:g id="BEGIN_PRIVACY_LINK"><a href="%1$s"></xliff:g>গোপনীয়তা নীতি<xliff:g id="END_PRIVACY_LINK"></a></xliff:g> এবং <xliff:g id="BEGIN_TOS_LINK"><a href="%2$s"></xliff:g>পরিষেবার শর্তাবলী<xliff:g id="END_TOS_LINK"></a></xliff:g> প্রযোজ্য।"</string>
<string name="taskbar_edu_close" msgid="887022990168191073">"বন্ধ করুন"</string>
<string name="taskbar_edu_done" msgid="6880178093977704569">"হয়ে গেছে"</string>
<string name="taskbar_button_home" msgid="2151398979630664652">"হোম"</string>
diff --git a/quickstep/res/values-bs/strings.xml b/quickstep/res/values-bs/strings.xml
index 83e4935..15da445 100644
--- a/quickstep/res/values-bs/strings.xml
+++ b/quickstep/res/values-bs/strings.xml
@@ -118,8 +118,8 @@
<string name="taskbar_edu_features" msgid="3320337287472848162">"Uradite više pomoću trake zadataka"</string>
<string name="taskbar_edu_pinning_title" msgid="210102174154211712">"Stalni prikaz trake zadataka"</string>
<string name="taskbar_edu_pinning_standalone" msgid="2636919474366410467">"Da se traka zadataka uvijek prikazuje na dnu ekrana, dodirnite i zadržite razdjelnik"</string>
- <string name="taskbar_edu_circle_to_search_title" msgid="4322780398403949508">"Dodirnite i zadržite tipku za radnju da biste pretražili što se nalazi na zaslonu"</string>
- <string name="taskbar_edu_circle_to_search_disclosure" msgid="5841648785867787221">"Ovaj proizvod upotrebljava odabrani dio zaslona za pretraživanje. Primjenjuju se Googleova <xliff:g id="BEGIN_PRIVACY_LINK"><a href="%1$s"></xliff:g>pravila o privatnosti<xliff:g id="END_PRIVACY_LINK"></a></xliff:g> i <xliff:g id="BEGIN_TOS_LINK"><a href="%2$s"></xliff:g>uvjeti pružanja usluge<xliff:g id="END_TOS_LINK"></a></xliff:g>."</string>
+ <string name="taskbar_edu_circle_to_search_title" msgid="4322780398403949508">"Dodirnite i zadržite tipku radnji da pretražite sadržaj na ekranu"</string>
+ <string name="taskbar_edu_circle_to_search_disclosure" msgid="5841648785867787221">"Ovaj proizvod koristi odabrani dio ekrana za pretraživanje. Primjenjuju se Googleova <xliff:g id="BEGIN_PRIVACY_LINK"><a href="%1$s"></xliff:g>Pravila privatnosti<xliff:g id="END_PRIVACY_LINK"></a></xliff:g> i <xliff:g id="BEGIN_TOS_LINK"><a href="%2$s"></xliff:g>Uslovi korištenja usluge<xliff:g id="END_TOS_LINK"></a></xliff:g>."</string>
<string name="taskbar_edu_close" msgid="887022990168191073">"Zatvori"</string>
<string name="taskbar_edu_done" msgid="6880178093977704569">"Gotovo"</string>
<string name="taskbar_button_home" msgid="2151398979630664652">"Dom"</string>
diff --git a/quickstep/res/values-ca/strings.xml b/quickstep/res/values-ca/strings.xml
index d4c7d91..a13e943 100644
--- a/quickstep/res/values-ca/strings.xml
+++ b/quickstep/res/values-ca/strings.xml
@@ -118,10 +118,8 @@
<string name="taskbar_edu_features" msgid="3320337287472848162">"Treu més partit de la Barra de tasques"</string>
<string name="taskbar_edu_pinning_title" msgid="210102174154211712">"Mostra sempre la Barra de tasques"</string>
<string name="taskbar_edu_pinning_standalone" msgid="2636919474366410467">"Perquè es mostri sempre la Barra de tasques a la part inferior de la pantalla, mantén premut el separador"</string>
- <!-- no translation found for taskbar_edu_circle_to_search_title (4322780398403949508) -->
- <skip />
- <!-- no translation found for taskbar_edu_circle_to_search_disclosure (5841648785867787221) -->
- <skip />
+ <string name="taskbar_edu_circle_to_search_title" msgid="4322780398403949508">"Mantén premuda la tecla d\'acció per cercar què es mostra a la pantalla"</string>
+ <string name="taskbar_edu_circle_to_search_disclosure" msgid="5841648785867787221">"Aquest producte utilitza la part seleccionada de la pantalla per fer cerques. S\'apliquen la <xliff:g id="BEGIN_PRIVACY_LINK"><a href="%1$s"></xliff:g>política de privadesa<xliff:g id="END_PRIVACY_LINK"></a></xliff:g> i les <xliff:g id="BEGIN_TOS_LINK"><a href="%2$s"></xliff:g>condicions del servei de Google<xliff:g id="END_TOS_LINK"></a></xliff:g>."</string>
<string name="taskbar_edu_close" msgid="887022990168191073">"Tanca"</string>
<string name="taskbar_edu_done" msgid="6880178093977704569">"Fet"</string>
<string name="taskbar_button_home" msgid="2151398979630664652">"Inici"</string>
diff --git a/quickstep/res/values-cs/strings.xml b/quickstep/res/values-cs/strings.xml
index 743fc2b..eedcd45 100644
--- a/quickstep/res/values-cs/strings.xml
+++ b/quickstep/res/values-cs/strings.xml
@@ -118,10 +118,8 @@
<string name="taskbar_edu_features" msgid="3320337287472848162">"Více možností s panelem aplikací"</string>
<string name="taskbar_edu_pinning_title" msgid="210102174154211712">"Stálé zobrazení panelu aplikací"</string>
<string name="taskbar_edu_pinning_standalone" msgid="2636919474366410467">"Pokud chcete, aby se panel aplikací vždy zobrazoval ve spodní části obrazovky, podržte oddělovač."</string>
- <!-- no translation found for taskbar_edu_circle_to_search_title (4322780398403949508) -->
- <skip />
- <!-- no translation found for taskbar_edu_circle_to_search_disclosure (5841648785867787221) -->
- <skip />
+ <string name="taskbar_edu_circle_to_search_title" msgid="4322780398403949508">"Podržením akční klávesy můžete vyhledat obsah na obrazovce"</string>
+ <string name="taskbar_edu_circle_to_search_disclosure" msgid="5841648785867787221">"Tato služba používá k vyhledávání vybranou část obrazovky. Platí <xliff:g id="BEGIN_PRIVACY_LINK"><a href="%1$s"></xliff:g>zásady ochrany soukromí<xliff:g id="END_PRIVACY_LINK"></a></xliff:g> a <xliff:g id="BEGIN_TOS_LINK"><a href="%2$s"></xliff:g>smluvní podmínky<xliff:g id="END_TOS_LINK"></a></xliff:g> společnosti Google."</string>
<string name="taskbar_edu_close" msgid="887022990168191073">"Zavřít"</string>
<string name="taskbar_edu_done" msgid="6880178093977704569">"Hotovo"</string>
<string name="taskbar_button_home" msgid="2151398979630664652">"Domů"</string>
diff --git a/quickstep/res/values-da/strings.xml b/quickstep/res/values-da/strings.xml
index cfe55cf..a1ca3c5 100644
--- a/quickstep/res/values-da/strings.xml
+++ b/quickstep/res/values-da/strings.xml
@@ -118,10 +118,8 @@
<string name="taskbar_edu_features" msgid="3320337287472848162">"Få mere fra hånden med proceslinjen"</string>
<string name="taskbar_edu_pinning_title" msgid="210102174154211712">"Vis altid proceslinjen"</string>
<string name="taskbar_edu_pinning_standalone" msgid="2636919474366410467">"Hvis du vil have, at proceslinjen altid vises nederst på din skærm, skal du holde fingeren på skillelinjen"</string>
- <!-- no translation found for taskbar_edu_circle_to_search_title (4322780398403949508) -->
- <skip />
- <!-- no translation found for taskbar_edu_circle_to_search_disclosure (5841648785867787221) -->
- <skip />
+ <string name="taskbar_edu_circle_to_search_title" msgid="4322780398403949508">"Hold fingeren på handlingstasten for at søge efter det, der vises på din skærm"</string>
+ <string name="taskbar_edu_circle_to_search_disclosure" msgid="5841648785867787221">"Dette produkt bruger den valgte del af din skærm til at søge. Googles <xliff:g id="BEGIN_PRIVACY_LINK"><a href="%1$s"></xliff:g>privatlivspolitik<xliff:g id="END_PRIVACY_LINK"></a></xliff:g> og <xliff:g id="BEGIN_TOS_LINK"><a href="%2$s"></xliff:g>servicevilkår<xliff:g id="END_TOS_LINK"></a></xliff:g> er gældende."</string>
<string name="taskbar_edu_close" msgid="887022990168191073">"Luk"</string>
<string name="taskbar_edu_done" msgid="6880178093977704569">"Luk"</string>
<string name="taskbar_button_home" msgid="2151398979630664652">"Hjem"</string>
diff --git a/quickstep/res/values-de/strings.xml b/quickstep/res/values-de/strings.xml
index 1d012bb..73c3f04 100644
--- a/quickstep/res/values-de/strings.xml
+++ b/quickstep/res/values-de/strings.xml
@@ -118,10 +118,8 @@
<string name="taskbar_edu_features" msgid="3320337287472848162">"Mehr Möglichkeiten mit der Taskleiste"</string>
<string name="taskbar_edu_pinning_title" msgid="210102174154211712">"Taskleiste immer anzeigen"</string>
<string name="taskbar_edu_pinning_standalone" msgid="2636919474366410467">"Damit die Taskleiste immer unten angezeigt wird, halte den Teiler gedrückt"</string>
- <!-- no translation found for taskbar_edu_circle_to_search_title (4322780398403949508) -->
- <skip />
- <!-- no translation found for taskbar_edu_circle_to_search_disclosure (5841648785867787221) -->
- <skip />
+ <string name="taskbar_edu_circle_to_search_title" msgid="4322780398403949508">"Aktionstaste gedrückt halten, um auf dem Bildschirm zu suchen"</string>
+ <string name="taskbar_edu_circle_to_search_disclosure" msgid="5841648785867787221">"Dieses Produkt verwendet den ausgewählten Teil deines Bildschirms für die Suche. Es gelten die <xliff:g id="BEGIN_PRIVACY_LINK"><a href="%1$s"></xliff:g>Datenschutzerklärung<xliff:g id="END_PRIVACY_LINK"></a></xliff:g> und die <xliff:g id="BEGIN_TOS_LINK"><a href="%2$s"></xliff:g>Nutzungsbedingungen<xliff:g id="END_TOS_LINK"></a></xliff:g> von Google."</string>
<string name="taskbar_edu_close" msgid="887022990168191073">"Schließen"</string>
<string name="taskbar_edu_done" msgid="6880178093977704569">"Fertig"</string>
<string name="taskbar_button_home" msgid="2151398979630664652">"Startbildschirm"</string>
diff --git a/quickstep/res/values-el/strings.xml b/quickstep/res/values-el/strings.xml
index ae3bef8..30c4dc8 100644
--- a/quickstep/res/values-el/strings.xml
+++ b/quickstep/res/values-el/strings.xml
@@ -118,10 +118,8 @@
<string name="taskbar_edu_features" msgid="3320337287472848162">"Κάντε περισσότερα με τη Γραμμή εργαλείων"</string>
<string name="taskbar_edu_pinning_title" msgid="210102174154211712">"Να εμφανίζεται πάντα η Γραμμή εργαλείων"</string>
<string name="taskbar_edu_pinning_standalone" msgid="2636919474366410467">"Για να εμφανίζεται πάντα η Γραμμή εργαλείων στο κάτω μέρος της οθόνης, αγγίξτε παρατεταμένα το διαχωριστικό"</string>
- <!-- no translation found for taskbar_edu_circle_to_search_title (4322780398403949508) -->
- <skip />
- <!-- no translation found for taskbar_edu_circle_to_search_disclosure (5841648785867787221) -->
- <skip />
+ <string name="taskbar_edu_circle_to_search_title" msgid="4322780398403949508">"Αγγίξτε παρατεταμένα το πλήκτρο ενέργειας για να αναζητήσετε το περιεχόμενο της οθόνης"</string>
+ <string name="taskbar_edu_circle_to_search_disclosure" msgid="5841648785867787221">"Αυτό το προϊόν χρησιμοποιεί το επιλεγμένο τμήμα της οθόνης σας για αναζήτηση. Ισχύουν η <xliff:g id="BEGIN_PRIVACY_LINK"><a href="%1$s"></xliff:g>Πολιτική απορρήτου<xliff:g id="END_PRIVACY_LINK"></a></xliff:g> και οι <xliff:g id="BEGIN_TOS_LINK"><a href="%2$s"></xliff:g>Όροι Παροχής Υπηρεσιών<xliff:g id="END_TOS_LINK"></a></xliff:g> της Google."</string>
<string name="taskbar_edu_close" msgid="887022990168191073">"Κλείσιμο"</string>
<string name="taskbar_edu_done" msgid="6880178093977704569">"Τέλος"</string>
<string name="taskbar_button_home" msgid="2151398979630664652">"Αρχική σελίδα"</string>
diff --git a/quickstep/res/values-en-rAU/strings.xml b/quickstep/res/values-en-rAU/strings.xml
index fea224b..8050284 100644
--- a/quickstep/res/values-en-rAU/strings.xml
+++ b/quickstep/res/values-en-rAU/strings.xml
@@ -118,10 +118,8 @@
<string name="taskbar_edu_features" msgid="3320337287472848162">"Do more with the Taskbar"</string>
<string name="taskbar_edu_pinning_title" msgid="210102174154211712">"Always show the Taskbar"</string>
<string name="taskbar_edu_pinning_standalone" msgid="2636919474366410467">"To always show the Taskbar on the bottom of your screen, touch and hold the divider"</string>
- <!-- no translation found for taskbar_edu_circle_to_search_title (4322780398403949508) -->
- <skip />
- <!-- no translation found for taskbar_edu_circle_to_search_disclosure (5841648785867787221) -->
- <skip />
+ <string name="taskbar_edu_circle_to_search_title" msgid="4322780398403949508">"Touch and hold the action key to search what\'s on your screen"</string>
+ <string name="taskbar_edu_circle_to_search_disclosure" msgid="5841648785867787221">"This product uses the selected part of your screen to search. Google\'s <xliff:g id="BEGIN_PRIVACY_LINK"><a href="%1$s"></xliff:g>Privacy Policy<xliff:g id="END_PRIVACY_LINK"></a></xliff:g> and <xliff:g id="BEGIN_TOS_LINK"><a href="%2$s"></xliff:g>Terms of Service<xliff:g id="END_TOS_LINK"></a></xliff:g> apply."</string>
<string name="taskbar_edu_close" msgid="887022990168191073">"Close"</string>
<string name="taskbar_edu_done" msgid="6880178093977704569">"Done"</string>
<string name="taskbar_button_home" msgid="2151398979630664652">"Home"</string>
diff --git a/quickstep/res/values-en-rCA/strings.xml b/quickstep/res/values-en-rCA/strings.xml
index 37f4bce..4daaa90 100644
--- a/quickstep/res/values-en-rCA/strings.xml
+++ b/quickstep/res/values-en-rCA/strings.xml
@@ -21,8 +21,7 @@
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
<string name="recent_task_option_pin" msgid="7929860679018978258">"Pin"</string>
<string name="recent_task_option_freeform" msgid="48863056265284071">"Freeform"</string>
- <!-- no translation found for recent_task_option_desktop (8280879717125435668) -->
- <skip />
+ <string name="recent_task_option_desktop" msgid="8280879717125435668">"Desktop"</string>
<string name="recents_empty_message" msgid="7040467240571714191">"No recent items"</string>
<string name="accessibility_app_usage_settings" msgid="6312864233673544149">"App usage settings"</string>
<string name="recents_clear_all" msgid="5328176793634888831">"Clear all"</string>
diff --git a/quickstep/res/values-en-rGB/strings.xml b/quickstep/res/values-en-rGB/strings.xml
index fea224b..8050284 100644
--- a/quickstep/res/values-en-rGB/strings.xml
+++ b/quickstep/res/values-en-rGB/strings.xml
@@ -118,10 +118,8 @@
<string name="taskbar_edu_features" msgid="3320337287472848162">"Do more with the Taskbar"</string>
<string name="taskbar_edu_pinning_title" msgid="210102174154211712">"Always show the Taskbar"</string>
<string name="taskbar_edu_pinning_standalone" msgid="2636919474366410467">"To always show the Taskbar on the bottom of your screen, touch and hold the divider"</string>
- <!-- no translation found for taskbar_edu_circle_to_search_title (4322780398403949508) -->
- <skip />
- <!-- no translation found for taskbar_edu_circle_to_search_disclosure (5841648785867787221) -->
- <skip />
+ <string name="taskbar_edu_circle_to_search_title" msgid="4322780398403949508">"Touch and hold the action key to search what\'s on your screen"</string>
+ <string name="taskbar_edu_circle_to_search_disclosure" msgid="5841648785867787221">"This product uses the selected part of your screen to search. Google\'s <xliff:g id="BEGIN_PRIVACY_LINK"><a href="%1$s"></xliff:g>Privacy Policy<xliff:g id="END_PRIVACY_LINK"></a></xliff:g> and <xliff:g id="BEGIN_TOS_LINK"><a href="%2$s"></xliff:g>Terms of Service<xliff:g id="END_TOS_LINK"></a></xliff:g> apply."</string>
<string name="taskbar_edu_close" msgid="887022990168191073">"Close"</string>
<string name="taskbar_edu_done" msgid="6880178093977704569">"Done"</string>
<string name="taskbar_button_home" msgid="2151398979630664652">"Home"</string>
diff --git a/quickstep/res/values-en-rIN/strings.xml b/quickstep/res/values-en-rIN/strings.xml
index fea224b..8050284 100644
--- a/quickstep/res/values-en-rIN/strings.xml
+++ b/quickstep/res/values-en-rIN/strings.xml
@@ -118,10 +118,8 @@
<string name="taskbar_edu_features" msgid="3320337287472848162">"Do more with the Taskbar"</string>
<string name="taskbar_edu_pinning_title" msgid="210102174154211712">"Always show the Taskbar"</string>
<string name="taskbar_edu_pinning_standalone" msgid="2636919474366410467">"To always show the Taskbar on the bottom of your screen, touch and hold the divider"</string>
- <!-- no translation found for taskbar_edu_circle_to_search_title (4322780398403949508) -->
- <skip />
- <!-- no translation found for taskbar_edu_circle_to_search_disclosure (5841648785867787221) -->
- <skip />
+ <string name="taskbar_edu_circle_to_search_title" msgid="4322780398403949508">"Touch and hold the action key to search what\'s on your screen"</string>
+ <string name="taskbar_edu_circle_to_search_disclosure" msgid="5841648785867787221">"This product uses the selected part of your screen to search. Google\'s <xliff:g id="BEGIN_PRIVACY_LINK"><a href="%1$s"></xliff:g>Privacy Policy<xliff:g id="END_PRIVACY_LINK"></a></xliff:g> and <xliff:g id="BEGIN_TOS_LINK"><a href="%2$s"></xliff:g>Terms of Service<xliff:g id="END_TOS_LINK"></a></xliff:g> apply."</string>
<string name="taskbar_edu_close" msgid="887022990168191073">"Close"</string>
<string name="taskbar_edu_done" msgid="6880178093977704569">"Done"</string>
<string name="taskbar_button_home" msgid="2151398979630664652">"Home"</string>
diff --git a/quickstep/res/values-en-rXC/strings.xml b/quickstep/res/values-en-rXC/strings.xml
index c64c495..19e6aa0 100644
--- a/quickstep/res/values-en-rXC/strings.xml
+++ b/quickstep/res/values-en-rXC/strings.xml
@@ -21,8 +21,7 @@
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
<string name="recent_task_option_pin" msgid="7929860679018978258">"Pin"</string>
<string name="recent_task_option_freeform" msgid="48863056265284071">"Freeform"</string>
- <!-- no translation found for recent_task_option_desktop (8280879717125435668) -->
- <skip />
+ <string name="recent_task_option_desktop" msgid="8280879717125435668">"Desktop"</string>
<string name="recents_empty_message" msgid="7040467240571714191">"No recent items"</string>
<string name="accessibility_app_usage_settings" msgid="6312864233673544149">"App usage settings"</string>
<string name="recents_clear_all" msgid="5328176793634888831">"Clear all"</string>
diff --git a/quickstep/res/values-es-rUS/strings.xml b/quickstep/res/values-es-rUS/strings.xml
index 244c23f..aa568f3 100644
--- a/quickstep/res/values-es-rUS/strings.xml
+++ b/quickstep/res/values-es-rUS/strings.xml
@@ -118,10 +118,8 @@
<string name="taskbar_edu_features" msgid="3320337287472848162">"Aprovecha mejor la Barra de tareas"</string>
<string name="taskbar_edu_pinning_title" msgid="210102174154211712">"Mostrar siempre la Barra de tareas"</string>
<string name="taskbar_edu_pinning_standalone" msgid="2636919474366410467">"Mantén presionado el divisor para mostrar siempre la Barra de tareas en la parte inferior de la pantalla"</string>
- <!-- no translation found for taskbar_edu_circle_to_search_title (4322780398403949508) -->
- <skip />
- <!-- no translation found for taskbar_edu_circle_to_search_disclosure (5841648785867787221) -->
- <skip />
+ <string name="taskbar_edu_circle_to_search_title" msgid="4322780398403949508">"Mantén presionada la tecla de acción para buscar qué hay en la pantalla"</string>
+ <string name="taskbar_edu_circle_to_search_disclosure" msgid="5841648785867787221">"Este producto usa la parte seleccionada de la pantalla para buscar. Se aplican la <xliff:g id="BEGIN_PRIVACY_LINK"><a href="%1$s"></xliff:g>Política de Privacidad<xliff:g id="END_PRIVACY_LINK"></a></xliff:g> y las <xliff:g id="BEGIN_TOS_LINK"><a href="%2$s"></xliff:g>Condiciones del Servicio<xliff:g id="END_TOS_LINK"></a></xliff:g> de Google."</string>
<string name="taskbar_edu_close" msgid="887022990168191073">"Cerrar"</string>
<string name="taskbar_edu_done" msgid="6880178093977704569">"Listo"</string>
<string name="taskbar_button_home" msgid="2151398979630664652">"Botón de inicio"</string>
diff --git a/quickstep/res/values-es/strings.xml b/quickstep/res/values-es/strings.xml
index 1bab3ac..27eceb8 100644
--- a/quickstep/res/values-es/strings.xml
+++ b/quickstep/res/values-es/strings.xml
@@ -118,10 +118,8 @@
<string name="taskbar_edu_features" msgid="3320337287472848162">"Sácale más partido a la barra de tareas"</string>
<string name="taskbar_edu_pinning_title" msgid="210102174154211712">"Mostrar siempre la barra de tareas"</string>
<string name="taskbar_edu_pinning_standalone" msgid="2636919474366410467">"Para mostrar siempre la barra de tareas en la parte inferior, mantén pulsada la línea divisoria"</string>
- <!-- no translation found for taskbar_edu_circle_to_search_title (4322780398403949508) -->
- <skip />
- <!-- no translation found for taskbar_edu_circle_to_search_disclosure (5841648785867787221) -->
- <skip />
+ <string name="taskbar_edu_circle_to_search_title" msgid="4322780398403949508">"Mantén pulsada la tecla de acción para buscar lo que ves en pantalla"</string>
+ <string name="taskbar_edu_circle_to_search_disclosure" msgid="5841648785867787221">"El producto usa la parte seleccionada de tu pantalla para hacer búsquedas. Se aplican la <xliff:g id="BEGIN_PRIVACY_LINK"><a href="%1$s"></xliff:g>Política de Privacidad<xliff:g id="END_PRIVACY_LINK"></a></xliff:g> y los <xliff:g id="BEGIN_TOS_LINK"><a href="%2$s"></xliff:g>Términos del Servicio<xliff:g id="END_TOS_LINK"></a></xliff:g> de Google."</string>
<string name="taskbar_edu_close" msgid="887022990168191073">"Cerrar"</string>
<string name="taskbar_edu_done" msgid="6880178093977704569">"Hecho"</string>
<string name="taskbar_button_home" msgid="2151398979630664652">"Inicio"</string>
diff --git a/quickstep/res/values-et/strings.xml b/quickstep/res/values-et/strings.xml
index 0a587d1..bffce79 100644
--- a/quickstep/res/values-et/strings.xml
+++ b/quickstep/res/values-et/strings.xml
@@ -118,10 +118,8 @@
<string name="taskbar_edu_features" msgid="3320337287472848162">"Tehke tegumiriba abil enamat"</string>
<string name="taskbar_edu_pinning_title" msgid="210102174154211712">"Alati kuvatud tegumiriba"</string>
<string name="taskbar_edu_pinning_standalone" msgid="2636919474366410467">"Puudutage pikalt jaoturit, et tegumiriba oleks ekraani allosas alati kuvatud"</string>
- <!-- no translation found for taskbar_edu_circle_to_search_title (4322780398403949508) -->
- <skip />
- <!-- no translation found for taskbar_edu_circle_to_search_disclosure (5841648785867787221) -->
- <skip />
+ <string name="taskbar_edu_circle_to_search_title" msgid="4322780398403949508">"Puudutage pikalt toiminguklahvi, et ekraanil kuvatut otsida"</string>
+ <string name="taskbar_edu_circle_to_search_disclosure" msgid="5841648785867787221">"See toode kasutab otsingu jaoks ekraani valitud osa. Kehtivad Google\'i <xliff:g id="BEGIN_PRIVACY_LINK"><a href="%1$s"></xliff:g>privaatsuseeskirjad<xliff:g id="END_PRIVACY_LINK"></a></xliff:g> ja <xliff:g id="BEGIN_TOS_LINK"><a href="%2$s"></xliff:g>teenusetingimused<xliff:g id="END_TOS_LINK"></a></xliff:g>."</string>
<string name="taskbar_edu_close" msgid="887022990168191073">"Sule"</string>
<string name="taskbar_edu_done" msgid="6880178093977704569">"Valmis"</string>
<string name="taskbar_button_home" msgid="2151398979630664652">"Avaleht"</string>
diff --git a/quickstep/res/values-eu/strings.xml b/quickstep/res/values-eu/strings.xml
index e10a085..39fc489 100644
--- a/quickstep/res/values-eu/strings.xml
+++ b/quickstep/res/values-eu/strings.xml
@@ -118,10 +118,8 @@
<string name="taskbar_edu_features" msgid="3320337287472848162">"Egin gauza gehiago zereginen barrarekin"</string>
<string name="taskbar_edu_pinning_title" msgid="210102174154211712">"Erakutsi beti zereginen barra"</string>
<string name="taskbar_edu_pinning_standalone" msgid="2636919474366410467">"Pantailaren behealdeko zereginen barra beti erakusteko, eduki sakatuta zatitzailea"</string>
- <!-- no translation found for taskbar_edu_circle_to_search_title (4322780398403949508) -->
- <skip />
- <!-- no translation found for taskbar_edu_circle_to_search_disclosure (5841648785867787221) -->
- <skip />
+ <string name="taskbar_edu_circle_to_search_title" msgid="4322780398403949508">"Eduki sakatuta ekintza-tekla pantailan dagoena bilatzeko"</string>
+ <string name="taskbar_edu_circle_to_search_disclosure" msgid="5841648785867787221">"Produktu honek pantailan hautatutako zatia erabiltzen du bilaketa egiteko. Google-ren <xliff:g id="BEGIN_PRIVACY_LINK"><a href="%1$s"></xliff:g>Pribatutasun-gidalerroak<xliff:g id="END_PRIVACY_LINK"></a></xliff:g> eta <xliff:g id="BEGIN_TOS_LINK"><a href="%2$s"></xliff:g>Zerbitzu-baldintzak<xliff:g id="END_TOS_LINK"></a></xliff:g> aplikatzen dira."</string>
<string name="taskbar_edu_close" msgid="887022990168191073">"Itxi"</string>
<string name="taskbar_edu_done" msgid="6880178093977704569">"Eginda"</string>
<string name="taskbar_button_home" msgid="2151398979630664652">"Hasiera"</string>
diff --git a/quickstep/res/values-fi/strings.xml b/quickstep/res/values-fi/strings.xml
index d4a0d83..40c4fc2 100644
--- a/quickstep/res/values-fi/strings.xml
+++ b/quickstep/res/values-fi/strings.xml
@@ -118,10 +118,8 @@
<string name="taskbar_edu_features" msgid="3320337287472848162">"Vinkkejä tehtäväpalkin tehokkaampaan käyttöön"</string>
<string name="taskbar_edu_pinning_title" msgid="210102174154211712">"Näytä tehtäväpalkki aina"</string>
<string name="taskbar_edu_pinning_standalone" msgid="2636919474366410467">"Jos haluat tehtäväpalkin näkyvän aina näytön alaosassa, kosketa jakajaa pitkään"</string>
- <!-- no translation found for taskbar_edu_circle_to_search_title (4322780398403949508) -->
- <skip />
- <!-- no translation found for taskbar_edu_circle_to_search_disclosure (5841648785867787221) -->
- <skip />
+ <string name="taskbar_edu_circle_to_search_title" msgid="4322780398403949508">"Kosketa toimintonäppäintä pitkään, niin voit tehdä haun näytöltäsi"</string>
+ <string name="taskbar_edu_circle_to_search_disclosure" msgid="5841648785867787221">"Tämä tuote käyttää hakuun näytön valittua osaa. Tähän sovelletaan Googlen <xliff:g id="BEGIN_PRIVACY_LINK"><a href="%1$s"></xliff:g>tietosuojakäytäntöä<xliff:g id="END_PRIVACY_LINK"></a></xliff:g> ja <xliff:g id="BEGIN_TOS_LINK"><a href="%2$s"></xliff:g>käyttöehtoja<xliff:g id="END_TOS_LINK"></a></xliff:g>."</string>
<string name="taskbar_edu_close" msgid="887022990168191073">"Sulje"</string>
<string name="taskbar_edu_done" msgid="6880178093977704569">"Valmis"</string>
<string name="taskbar_button_home" msgid="2151398979630664652">"Etusivu"</string>
diff --git a/quickstep/res/values-fr-rCA/strings.xml b/quickstep/res/values-fr-rCA/strings.xml
index 444bb83..33536b7 100644
--- a/quickstep/res/values-fr-rCA/strings.xml
+++ b/quickstep/res/values-fr-rCA/strings.xml
@@ -118,10 +118,8 @@
<string name="taskbar_edu_features" msgid="3320337287472848162">"Faites-en plus avec la barre des tâches"</string>
<string name="taskbar_edu_pinning_title" msgid="210102174154211712">"Toujours afficher la Barre des tâches"</string>
<string name="taskbar_edu_pinning_standalone" msgid="2636919474366410467">"Pour toujours afficher la Barre des tâches en bas de l\'écran, maintenez le doigt sur le séparateur"</string>
- <!-- no translation found for taskbar_edu_circle_to_search_title (4322780398403949508) -->
- <skip />
- <!-- no translation found for taskbar_edu_circle_to_search_disclosure (5841648785867787221) -->
- <skip />
+ <string name="taskbar_edu_circle_to_search_title" msgid="4322780398403949508">"Maintenez le doigt sur la touche d\'action pour rechercher ce qui se trouve sur votre écran"</string>
+ <string name="taskbar_edu_circle_to_search_disclosure" msgid="5841648785867787221">"Ce produit utilise la partie sélectionnée de votre écran pour effectuer une recherche. La <xliff:g id="BEGIN_PRIVACY_LINK"><a href="%1$s"></xliff:g>politique de confidentialité<xliff:g id="END_PRIVACY_LINK"></a></xliff:g> et les <xliff:g id="BEGIN_TOS_LINK"><a href="%2$s"></xliff:g>conditions d\'utilisation<xliff:g id="END_TOS_LINK"></a></xliff:g> de Google s\'appliquent."</string>
<string name="taskbar_edu_close" msgid="887022990168191073">"Fermer"</string>
<string name="taskbar_edu_done" msgid="6880178093977704569">"OK"</string>
<string name="taskbar_button_home" msgid="2151398979630664652">"Accueil"</string>
diff --git a/quickstep/res/values-fr/strings.xml b/quickstep/res/values-fr/strings.xml
index 0d70416..bf89f83 100644
--- a/quickstep/res/values-fr/strings.xml
+++ b/quickstep/res/values-fr/strings.xml
@@ -118,10 +118,8 @@
<string name="taskbar_edu_features" msgid="3320337287472848162">"Faites-en plus avec la barre des tâches"</string>
<string name="taskbar_edu_pinning_title" msgid="210102174154211712">"Toujours afficher la barre des tâches"</string>
<string name="taskbar_edu_pinning_standalone" msgid="2636919474366410467">"Pour toujours afficher la barre des tâches en bas de votre écran, appuyez sur le séparateur de manière prolongée."</string>
- <!-- no translation found for taskbar_edu_circle_to_search_title (4322780398403949508) -->
- <skip />
- <!-- no translation found for taskbar_edu_circle_to_search_disclosure (5841648785867787221) -->
- <skip />
+ <string name="taskbar_edu_circle_to_search_title" msgid="4322780398403949508">"Appuyez de manière prolongée sur la touche d\'action pour rechercher ce qui se trouve à l\'écran"</string>
+ <string name="taskbar_edu_circle_to_search_disclosure" msgid="5841648785867787221">"Ce produit utilise la zone sélectionnée de l\'écran pour rechercher. Les <xliff:g id="BEGIN_PRIVACY_LINK"><a href="%1$s"></xliff:g>Règles de confidentialité<xliff:g id="END_PRIVACY_LINK"></a></xliff:g> et les <xliff:g id="BEGIN_TOS_LINK"><a href="%2$s"></xliff:g>Conditions d\'utilisation<xliff:g id="END_TOS_LINK"></a></xliff:g> de Google s\'appliquent."</string>
<string name="taskbar_edu_close" msgid="887022990168191073">"Fermer"</string>
<string name="taskbar_edu_done" msgid="6880178093977704569">"OK"</string>
<string name="taskbar_button_home" msgid="2151398979630664652">"Accueil"</string>
diff --git a/quickstep/res/values-gl/strings.xml b/quickstep/res/values-gl/strings.xml
index eadd73d..0be8958 100644
--- a/quickstep/res/values-gl/strings.xml
+++ b/quickstep/res/values-gl/strings.xml
@@ -118,10 +118,8 @@
<string name="taskbar_edu_features" msgid="3320337287472848162">"Tira máis proveito da barra de tarefas"</string>
<string name="taskbar_edu_pinning_title" msgid="210102174154211712">"Mostrar sempre a barra de tarefas"</string>
<string name="taskbar_edu_pinning_standalone" msgid="2636919474366410467">"Para fixar a barra de tarefas na parte inferior, mantén premida a liña divisoria"</string>
- <!-- no translation found for taskbar_edu_circle_to_search_title (4322780398403949508) -->
- <skip />
- <!-- no translation found for taskbar_edu_circle_to_search_disclosure (5841648785867787221) -->
- <skip />
+ <string name="taskbar_edu_circle_to_search_title" msgid="4322780398403949508">"Mantén premida a tecla de acción para buscar o que hai na pantalla"</string>
+ <string name="taskbar_edu_circle_to_search_disclosure" msgid="5841648785867787221">"Este produto utiliza a parte seleccionada da pantalla para facer buscas. Aplícanse as <xliff:g id="BEGIN_TOS_LINK"><a href="%2$s"></xliff:g>Condicións de servizo<xliff:g id="END_TOS_LINK"></a></xliff:g> e a <xliff:g id="BEGIN_PRIVACY_LINK"><a href="%1$s"></xliff:g>Política de privacidade<xliff:g id="END_PRIVACY_LINK"></a></xliff:g> de Google."</string>
<string name="taskbar_edu_close" msgid="887022990168191073">"Pechar"</string>
<string name="taskbar_edu_done" msgid="6880178093977704569">"Listo"</string>
<string name="taskbar_button_home" msgid="2151398979630664652">"Inicio"</string>
diff --git a/quickstep/res/values-hu/strings.xml b/quickstep/res/values-hu/strings.xml
index e69bc53..fe629dd 100644
--- a/quickstep/res/values-hu/strings.xml
+++ b/quickstep/res/values-hu/strings.xml
@@ -118,10 +118,8 @@
<string name="taskbar_edu_features" msgid="3320337287472848162">"Jobban kihasználhatja a Feladatsávot"</string>
<string name="taskbar_edu_pinning_title" msgid="210102174154211712">"Mindig jelenjen meg a Feladatsáv"</string>
<string name="taskbar_edu_pinning_standalone" msgid="2636919474366410467">"Ahhoz, hogy a Feladatsáv mindig megjelenjen a képernyő alján, érintse meg és tartsa lenyomva az elválasztót"</string>
- <!-- no translation found for taskbar_edu_circle_to_search_title (4322780398403949508) -->
- <skip />
- <!-- no translation found for taskbar_edu_circle_to_search_disclosure (5841648785867787221) -->
- <skip />
+ <string name="taskbar_edu_circle_to_search_title" msgid="4322780398403949508">"A műveletbillentyűt lenyomva tartva kereshet a képernyőn található tartalmak között"</string>
+ <string name="taskbar_edu_circle_to_search_disclosure" msgid="5841648785867787221">"Ez a termék a képernyő kiválasztott részét használja a kereséshez. A Google <xliff:g id="BEGIN_PRIVACY_LINK"><a href="%1$s"></xliff:g>Adatvédelmi irányelvei<xliff:g id="END_PRIVACY_LINK"></a></xliff:g> és <xliff:g id="BEGIN_TOS_LINK"><a href="%2$s"></xliff:g>Általános Szerződési Feltételei<xliff:g id="END_TOS_LINK"></a></xliff:g> érvényesek."</string>
<string name="taskbar_edu_close" msgid="887022990168191073">"Bezárás"</string>
<string name="taskbar_edu_done" msgid="6880178093977704569">"Kész"</string>
<string name="taskbar_button_home" msgid="2151398979630664652">"Kezdőlap"</string>
diff --git a/quickstep/res/values-hy/strings.xml b/quickstep/res/values-hy/strings.xml
index 1889a4e..e0646aa 100644
--- a/quickstep/res/values-hy/strings.xml
+++ b/quickstep/res/values-hy/strings.xml
@@ -118,10 +118,8 @@
<string name="taskbar_edu_features" msgid="3320337287472848162">"Օգտվեք հավելվածների վահանակի բոլոր հնարավորություններից"</string>
<string name="taskbar_edu_pinning_title" msgid="210102174154211712">"Ամրացրեք հավելվածների վահանակը"</string>
<string name="taskbar_edu_pinning_standalone" msgid="2636919474366410467">"Հավելվածների վահանակն էկրանի ներքևում ամրացնելու համար հպեք և պահեք բաժանիչը"</string>
- <!-- no translation found for taskbar_edu_circle_to_search_title (4322780398403949508) -->
- <skip />
- <!-- no translation found for taskbar_edu_circle_to_search_disclosure (5841648785867787221) -->
- <skip />
+ <string name="taskbar_edu_circle_to_search_title" msgid="4322780398403949508">"Սեղմած պահեք գործողության ստեղնը՝ էկրանին բովանդակություն որոնելու համար"</string>
+ <string name="taskbar_edu_circle_to_search_disclosure" msgid="5841648785867787221">"Այս պրոդուկտն օգտագործում է էկրանի ընտրված հատվածը որոնման համար։ Կիրառվում են Google-ի <xliff:g id="BEGIN_PRIVACY_LINK"><a href="%1$s"></xliff:g>գաղտնիության քաղաքականությունը<xliff:g id="END_PRIVACY_LINK"></a></xliff:g> և <xliff:g id="BEGIN_TOS_LINK"><a href="%2$s"></xliff:g>օգտագործման պայմանները<xliff:g id="END_TOS_LINK"></a></xliff:g>։"</string>
<string name="taskbar_edu_close" msgid="887022990168191073">"Փակել"</string>
<string name="taskbar_edu_done" msgid="6880178093977704569">"Պատրաստ է"</string>
<string name="taskbar_button_home" msgid="2151398979630664652">"Սկիզբ"</string>
diff --git a/quickstep/res/values-it/strings.xml b/quickstep/res/values-it/strings.xml
index aeeb6a2..f66761f 100644
--- a/quickstep/res/values-it/strings.xml
+++ b/quickstep/res/values-it/strings.xml
@@ -118,10 +118,8 @@
<string name="taskbar_edu_features" msgid="3320337287472848162">"Fai di più con la barra delle app"</string>
<string name="taskbar_edu_pinning_title" msgid="210102174154211712">"Mostra sempre la barra delle app"</string>
<string name="taskbar_edu_pinning_standalone" msgid="2636919474366410467">"Per mostrare sempre la barra delle app in basso, tocca e tieni premuto il divisore"</string>
- <!-- no translation found for taskbar_edu_circle_to_search_title (4322780398403949508) -->
- <skip />
- <!-- no translation found for taskbar_edu_circle_to_search_disclosure (5841648785867787221) -->
- <skip />
+ <string name="taskbar_edu_circle_to_search_title" msgid="4322780398403949508">"Tocca e tieni premuto il tasto azione per cercare gli elementi sullo schermo"</string>
+ <string name="taskbar_edu_circle_to_search_disclosure" msgid="5841648785867787221">"Il prodotto usa la parte selezionata dello schermo per cercare. Si applicano le <xliff:g id="BEGIN_PRIVACY_LINK"><a href="%1$s"></xliff:g>Norme sulla privacy<xliff:g id="END_PRIVACY_LINK"></a></xliff:g> e i <xliff:g id="BEGIN_TOS_LINK"><a href="%2$s"></xliff:g>Termini di servizio<xliff:g id="END_TOS_LINK"></a></xliff:g> di Google."</string>
<string name="taskbar_edu_close" msgid="887022990168191073">"Chiudi"</string>
<string name="taskbar_edu_done" msgid="6880178093977704569">"Fine"</string>
<string name="taskbar_button_home" msgid="2151398979630664652">"Home"</string>
diff --git a/quickstep/res/values-iw/strings.xml b/quickstep/res/values-iw/strings.xml
index 3899f67..a424bcd 100644
--- a/quickstep/res/values-iw/strings.xml
+++ b/quickstep/res/values-iw/strings.xml
@@ -118,10 +118,8 @@
<string name="taskbar_edu_features" msgid="3320337287472848162">"פעולות נוספות שאפשר לעשות עם סרגל האפליקציות"</string>
<string name="taskbar_edu_pinning_title" msgid="210102174154211712">"תמיד להציג את סרגל האפליקציות"</string>
<string name="taskbar_edu_pinning_standalone" msgid="2636919474366410467">"כדי להציג תמיד את סרגל האפליקציות בתחתית המסך, יש ללחוץ לחיצה ארוכה על המחיצה"</string>
- <!-- no translation found for taskbar_edu_circle_to_search_title (4322780398403949508) -->
- <skip />
- <!-- no translation found for taskbar_edu_circle_to_search_disclosure (5841648785867787221) -->
- <skip />
+ <string name="taskbar_edu_circle_to_search_title" msgid="4322780398403949508">"כדי לחפש במסך, צריך ללחוץ לחיצה ארוכה על מקש הפעולה"</string>
+ <string name="taskbar_edu_circle_to_search_disclosure" msgid="5841648785867787221">"המוצר הזה משתמש בחלק שבחרת במסך לצורך חיפוש, בכפוף ל<xliff:g id="BEGIN_PRIVACY_LINK"><a href="%1$s"></xliff:g>מדיניות הפרטיות<xliff:g id="END_PRIVACY_LINK"></a></xliff:g> ו<xliff:g id="BEGIN_TOS_LINK"><a href="%2$s"></xliff:g>התנאים וההגבלות<xliff:g id="END_TOS_LINK"></a></xliff:g> של Google."</string>
<string name="taskbar_edu_close" msgid="887022990168191073">"סגירה"</string>
<string name="taskbar_edu_done" msgid="6880178093977704569">"סיום"</string>
<string name="taskbar_button_home" msgid="2151398979630664652">"בית"</string>
diff --git a/quickstep/res/values-ja/strings.xml b/quickstep/res/values-ja/strings.xml
index 8125ea4..b0b1190 100644
--- a/quickstep/res/values-ja/strings.xml
+++ b/quickstep/res/values-ja/strings.xml
@@ -118,10 +118,8 @@
<string name="taskbar_edu_features" msgid="3320337287472848162">"タスクバーの各種機能"</string>
<string name="taskbar_edu_pinning_title" msgid="210102174154211712">"タスクバーを常に表示"</string>
<string name="taskbar_edu_pinning_standalone" msgid="2636919474366410467">"タスクバーを画面下部に常に表示するには分割線を長押しします"</string>
- <!-- no translation found for taskbar_edu_circle_to_search_title (4322780398403949508) -->
- <skip />
- <!-- no translation found for taskbar_edu_circle_to_search_disclosure (5841648785867787221) -->
- <skip />
+ <string name="taskbar_edu_circle_to_search_title" msgid="4322780398403949508">"画面上の内容を検索するには、アクションキーを長押ししてください"</string>
+ <string name="taskbar_edu_circle_to_search_disclosure" msgid="5841648785867787221">"このサービスは、検索する際に画面上で選択された箇所を使用します。Google の<xliff:g id="BEGIN_PRIVACY_LINK"><a href="%1$s"></xliff:g>プライバシー ポリシー<xliff:g id="END_PRIVACY_LINK"></a></xliff:g>と<xliff:g id="BEGIN_TOS_LINK"><a href="%2$s"></xliff:g>利用規約<xliff:g id="END_TOS_LINK"></a></xliff:g>が適用されます。"</string>
<string name="taskbar_edu_close" msgid="887022990168191073">"閉じる"</string>
<string name="taskbar_edu_done" msgid="6880178093977704569">"完了"</string>
<string name="taskbar_button_home" msgid="2151398979630664652">"ホーム"</string>
diff --git a/quickstep/res/values-ka/strings.xml b/quickstep/res/values-ka/strings.xml
index 14c0773..b4eb026 100644
--- a/quickstep/res/values-ka/strings.xml
+++ b/quickstep/res/values-ka/strings.xml
@@ -118,10 +118,8 @@
<string name="taskbar_edu_features" msgid="3320337287472848162">"გააკეთეთ მეტი ამოცანათა ზოლის მეშვეობით"</string>
<string name="taskbar_edu_pinning_title" msgid="210102174154211712">"ამოცანათა ზოლის მუდმივად ჩვენება"</string>
<string name="taskbar_edu_pinning_standalone" msgid="2636919474366410467">"თქვენი ეკრანის ქვედა ნაწილში ამოცანათა ზოლის მუდმივად საჩვენებლად, ხანგრძლივად შეეხეთ გამყოფს"</string>
- <!-- no translation found for taskbar_edu_circle_to_search_title (4322780398403949508) -->
- <skip />
- <!-- no translation found for taskbar_edu_circle_to_search_disclosure (5841648785867787221) -->
- <skip />
+ <string name="taskbar_edu_circle_to_search_title" msgid="4322780398403949508">"შეეხეთ და გეჭიროთ მოქმედების კლავიში, რათა მოძებნოთ ის, რაც თქვენს ეკრანზეა"</string>
+ <string name="taskbar_edu_circle_to_search_disclosure" msgid="5841648785867787221">"ეს პროდუქტი ძიებისთვის იყენებს თქვენი ეკრანის არჩეულ ნაწილს. მოქმედებს Google-ის <xliff:g id="BEGIN_PRIVACY_LINK"><a href="%1$s"></xliff:g>კონფიდენციალურობის დებულება<xliff:g id="END_PRIVACY_LINK"></a></xliff:g> და <xliff:g id="BEGIN_TOS_LINK"><a href="%2$s"></xliff:g>მომსახურებს პირობები<xliff:g id="END_TOS_LINK"></a></xliff:g>."</string>
<string name="taskbar_edu_close" msgid="887022990168191073">"დახურვა"</string>
<string name="taskbar_edu_done" msgid="6880178093977704569">"მზადაა"</string>
<string name="taskbar_button_home" msgid="2151398979630664652">"მთავარი"</string>
diff --git a/quickstep/res/values-kk/strings.xml b/quickstep/res/values-kk/strings.xml
index 9964105..a8bbdf5 100644
--- a/quickstep/res/values-kk/strings.xml
+++ b/quickstep/res/values-kk/strings.xml
@@ -118,10 +118,8 @@
<string name="taskbar_edu_features" msgid="3320337287472848162">"Тапсырмалар жолағында мүмкіндік көп"</string>
<string name="taskbar_edu_pinning_title" msgid="210102174154211712">"Тапсырмалар жолағын әрдайым көрсету"</string>
<string name="taskbar_edu_pinning_standalone" msgid="2636919474366410467">"Экранның төменгі жағында тапсырмалар жолағы әрдайым көрсетілуі үшін, бөлгішті басып тұрыңыз."</string>
- <!-- no translation found for taskbar_edu_circle_to_search_title (4322780398403949508) -->
- <skip />
- <!-- no translation found for taskbar_edu_circle_to_search_disclosure (5841648785867787221) -->
- <skip />
+ <string name="taskbar_edu_circle_to_search_title" msgid="4322780398403949508">"Экраннан іздеу үшін әрекет пернесін басып тұрыңыз."</string>
+ <string name="taskbar_edu_circle_to_search_disclosure" msgid="5841648785867787221">"Бұл өнім іздеу үшін экранның таңдалған бөлігін пайдаланады. Google <xliff:g id="BEGIN_PRIVACY_LINK"><a href="%1$s"></xliff:g>Құпиялық саясаты<xliff:g id="END_PRIVACY_LINK"></a></xliff:g> мен <xliff:g id="BEGIN_TOS_LINK"><a href="%2$s"></xliff:g>Қызмет көрсету шарттары<xliff:g id="END_TOS_LINK"></a></xliff:g> қолданылады."</string>
<string name="taskbar_edu_close" msgid="887022990168191073">"Жабу"</string>
<string name="taskbar_edu_done" msgid="6880178093977704569">"Дайын"</string>
<string name="taskbar_button_home" msgid="2151398979630664652">"Негізгі экран"</string>
diff --git a/quickstep/res/values-kn/strings.xml b/quickstep/res/values-kn/strings.xml
index 688098c..c7c6389 100644
--- a/quickstep/res/values-kn/strings.xml
+++ b/quickstep/res/values-kn/strings.xml
@@ -118,10 +118,8 @@
<string name="taskbar_edu_features" msgid="3320337287472848162">"ಟಾಸ್ಕ್ಬಾರ್ ಮೂಲಕ ಹೆಚ್ಚಿನದನ್ನು ಮಾಡಿ"</string>
<string name="taskbar_edu_pinning_title" msgid="210102174154211712">"ಯಾವಾಗಲೂ ಟಾಸ್ಕ್ಬಾರ್ ಅನ್ನು ತೋರಿಸಿ"</string>
<string name="taskbar_edu_pinning_standalone" msgid="2636919474366410467">"ಯಾವಾಗಲೂ ನಿಮ್ಮ ಸ್ಕ್ರೀನ್ನ ಕೆಳಭಾಗದಲ್ಲಿ ಟಾಸ್ಕ್ ಬಾರ್ ಅನ್ನು ತೋರಿಸಲು, ಡಿವೈಡರ್ ಅನ್ನು ಸ್ಪರ್ಶಿಸಿ ಹಿಡಿದಿಟ್ಟುಕೊಳ್ಳಿ"</string>
- <!-- no translation found for taskbar_edu_circle_to_search_title (4322780398403949508) -->
- <skip />
- <!-- no translation found for taskbar_edu_circle_to_search_disclosure (5841648785867787221) -->
- <skip />
+ <string name="taskbar_edu_circle_to_search_title" msgid="4322780398403949508">"ನಿಮ್ಮ ಸ್ಕ್ರೀನ್ನ ಮೇಲೆ ಏನಿದೆ ಎಂಬುದನ್ನು ಹುಡುಕಲು ಆ್ಯಕ್ಷನ್ ಕೀಯನ್ನು ಸ್ಪರ್ಶಿಸಿ ಮತ್ತು ಒತ್ತಿ ಹಿಡಿದುಕೊಳ್ಳಿ"</string>
+ <string name="taskbar_edu_circle_to_search_disclosure" msgid="5841648785867787221">"ಈ ಉತ್ಪನ್ನವು ಹುಡುಕಲು ನಿಮ್ಮ ಸ್ಕ್ರೀನ್ನ ಆಯ್ದ ಭಾಗವನ್ನು ಬಳಸುತ್ತದೆ. Google ನ <xliff:g id="BEGIN_PRIVACY_LINK"><a href="%1$s"></xliff:g>ಗೌಪ್ಯತೆ ನೀತಿ<xliff:g id="END_PRIVACY_LINK"></a></xliff:g> ಮತ್ತು <xliff:g id="BEGIN_TOS_LINK"><a href="%2$s"></xliff:g>ಸೇವಾ ನಿಯಮಗಳು<xliff:g id="END_TOS_LINK"></a></xliff:g> ಅನ್ವಯಿಸುತ್ತವೆ."</string>
<string name="taskbar_edu_close" msgid="887022990168191073">"ಮುಚ್ಚಿರಿ"</string>
<string name="taskbar_edu_done" msgid="6880178093977704569">"ಆಯಿತು"</string>
<string name="taskbar_button_home" msgid="2151398979630664652">"ಮುಖಪುಟ"</string>
diff --git a/quickstep/res/values-ko/strings.xml b/quickstep/res/values-ko/strings.xml
index b8a131a..0fba87d 100644
--- a/quickstep/res/values-ko/strings.xml
+++ b/quickstep/res/values-ko/strings.xml
@@ -118,10 +118,8 @@
<string name="taskbar_edu_features" msgid="3320337287472848162">"태스크 바 최대한 활용하기"</string>
<string name="taskbar_edu_pinning_title" msgid="210102174154211712">"태스크 바 항상 표시"</string>
<string name="taskbar_edu_pinning_standalone" msgid="2636919474366410467">"화면 하단에 태스크 바를 항상 표시하려면 구분선을 길게 터치하세요."</string>
- <!-- no translation found for taskbar_edu_circle_to_search_title (4322780398403949508) -->
- <skip />
- <!-- no translation found for taskbar_edu_circle_to_search_disclosure (5841648785867787221) -->
- <skip />
+ <string name="taskbar_edu_circle_to_search_title" msgid="4322780398403949508">"화면 내용을 검색하려면 작업 키 길게 터치"</string>
+ <string name="taskbar_edu_circle_to_search_disclosure" msgid="5841648785867787221">"이 제품은 사용자가 화면에서 선택한 부분을 사용하여 검색하며, Google <xliff:g id="BEGIN_PRIVACY_LINK"><a href="%1$s"></xliff:g>개인정보처리방침<xliff:g id="END_PRIVACY_LINK"></a></xliff:g> 및 <xliff:g id="BEGIN_TOS_LINK"><a href="%2$s"></xliff:g>서비스 약관<xliff:g id="END_TOS_LINK"></a></xliff:g>이 적용됩니다."</string>
<string name="taskbar_edu_close" msgid="887022990168191073">"닫기"</string>
<string name="taskbar_edu_done" msgid="6880178093977704569">"완료"</string>
<string name="taskbar_button_home" msgid="2151398979630664652">"홈"</string>
diff --git a/quickstep/res/values-lt/strings.xml b/quickstep/res/values-lt/strings.xml
index e2f1af9..c8a031f 100644
--- a/quickstep/res/values-lt/strings.xml
+++ b/quickstep/res/values-lt/strings.xml
@@ -118,10 +118,8 @@
<string name="taskbar_edu_features" msgid="3320337287472848162">"Atlikite daugiau naudodami Užduočių juostą"</string>
<string name="taskbar_edu_pinning_title" msgid="210102174154211712">"Visada rodyti užduočių juostą"</string>
<string name="taskbar_edu_pinning_standalone" msgid="2636919474366410467">"Jei norite, kad užduočių juosta visada būtų rodoma ekrano apačioje, palieskite ir palaikykite daliklį"</string>
- <!-- no translation found for taskbar_edu_circle_to_search_title (4322780398403949508) -->
- <skip />
- <!-- no translation found for taskbar_edu_circle_to_search_disclosure (5841648785867787221) -->
- <skip />
+ <string name="taskbar_edu_circle_to_search_title" msgid="4322780398403949508">"Ekrane rodomo turinio paieška palietus ir laikant veiksmų klavišą"</string>
+ <string name="taskbar_edu_circle_to_search_disclosure" msgid="5841648785867787221">"Šis produktas paieškai naudoja pasirinktą ekrano dalį. Taikomos „Google“ <xliff:g id="BEGIN_PRIVACY_LINK"><a href="%1$s"></xliff:g>privatumo politikos<xliff:g id="END_PRIVACY_LINK"></a></xliff:g> ir <xliff:g id="BEGIN_TOS_LINK"><a href="%2$s"></xliff:g>paslaugų teikimo sąlygos<xliff:g id="END_TOS_LINK"></a></xliff:g>."</string>
<string name="taskbar_edu_close" msgid="887022990168191073">"Uždaryti"</string>
<string name="taskbar_edu_done" msgid="6880178093977704569">"Atlikta"</string>
<string name="taskbar_button_home" msgid="2151398979630664652">"Pagrindinis"</string>
diff --git a/quickstep/res/values-lv/strings.xml b/quickstep/res/values-lv/strings.xml
index 6881a09..276120b 100644
--- a/quickstep/res/values-lv/strings.xml
+++ b/quickstep/res/values-lv/strings.xml
@@ -118,10 +118,8 @@
<string name="taskbar_edu_features" msgid="3320337287472848162">"Plašākas iespējas, izmantojot uzdevumu joslu"</string>
<string name="taskbar_edu_pinning_title" msgid="210102174154211712">"Vienmēr rādīt uzdevumu joslu"</string>
<string name="taskbar_edu_pinning_standalone" msgid="2636919474366410467">"Lai uzdevumu joslu rādītu apakšdaļā, pieskarieties atdalītājam un turiet"</string>
- <!-- no translation found for taskbar_edu_circle_to_search_title (4322780398403949508) -->
- <skip />
- <!-- no translation found for taskbar_edu_circle_to_search_disclosure (5841648785867787221) -->
- <skip />
+ <string name="taskbar_edu_circle_to_search_title" msgid="4322780398403949508">"Pieskarieties darbību taustiņam un turiet to, lai meklētu ekrānā redzamo saturu"</string>
+ <string name="taskbar_edu_circle_to_search_disclosure" msgid="5841648785867787221">"Šis produkts meklēšanai izmanto atlasīto ekrāna daļu. Ir spēkā Google <xliff:g id="BEGIN_PRIVACY_LINK"><a href="%1$s"></xliff:g>konfidencialitātes politika<xliff:g id="END_PRIVACY_LINK"></a></xliff:g> un <xliff:g id="BEGIN_TOS_LINK"><a href="%2$s"></xliff:g>pakalpojumu sniegšanas noteikumi<xliff:g id="END_TOS_LINK"></a></xliff:g>."</string>
<string name="taskbar_edu_close" msgid="887022990168191073">"Aizvērt"</string>
<string name="taskbar_edu_done" msgid="6880178093977704569">"Gatavs"</string>
<string name="taskbar_button_home" msgid="2151398979630664652">"Sākums"</string>
diff --git a/quickstep/res/values-mk/strings.xml b/quickstep/res/values-mk/strings.xml
index 6408a4d..539448d 100644
--- a/quickstep/res/values-mk/strings.xml
+++ b/quickstep/res/values-mk/strings.xml
@@ -118,10 +118,8 @@
<string name="taskbar_edu_features" msgid="3320337287472848162">"Правете сешто со „Лентата со задачи“"</string>
<string name="taskbar_edu_pinning_title" msgid="210102174154211712">"Како секогаш да се прикажува „Лентата со задачи“"</string>
<string name="taskbar_edu_pinning_standalone" msgid="2636919474366410467">"Допрете и задржете го разделникот за да може „Лентата со задачи“ секогаш да се прикажува на дното на екранот"</string>
- <!-- no translation found for taskbar_edu_circle_to_search_title (4322780398403949508) -->
- <skip />
- <!-- no translation found for taskbar_edu_circle_to_search_disclosure (5841648785867787221) -->
- <skip />
+ <string name="taskbar_edu_circle_to_search_title" msgid="4322780398403949508">"Допрете и задржете го копчето за дејство за да пребарувате на екранот"</string>
+ <string name="taskbar_edu_circle_to_search_disclosure" msgid="5841648785867787221">"Производов го користи избраниот дел од екранот за пребарување. Важат <xliff:g id="BEGIN_PRIVACY_LINK"><a href="%1$s"></xliff:g>Политиката за приватност<xliff:g id="END_PRIVACY_LINK"></a></xliff:g> и <xliff:g id="BEGIN_TOS_LINK"><a href="%2$s"></xliff:g>Условите за користење<xliff:g id="END_TOS_LINK"></a></xliff:g> на Google."</string>
<string name="taskbar_edu_close" msgid="887022990168191073">"Затвори"</string>
<string name="taskbar_edu_done" msgid="6880178093977704569">"Готово"</string>
<string name="taskbar_button_home" msgid="2151398979630664652">"Дома"</string>
diff --git a/quickstep/res/values-mn/strings.xml b/quickstep/res/values-mn/strings.xml
index bc6a43b..c021d21 100644
--- a/quickstep/res/values-mn/strings.xml
+++ b/quickstep/res/values-mn/strings.xml
@@ -118,10 +118,8 @@
<string name="taskbar_edu_features" msgid="3320337287472848162">"Ажлын хэсгийн тусламжтай илүү ихийг хийгээрэй"</string>
<string name="taskbar_edu_pinning_title" msgid="210102174154211712">"Ажлын хэсгийг үргэлж харуулах"</string>
<string name="taskbar_edu_pinning_standalone" msgid="2636919474366410467">"Дэлгэцийнхээ доод талд Ажлын хэсгийг үргэлж харуулахын тулд хуваагч дээр хүрээд удаан дарна уу"</string>
- <!-- no translation found for taskbar_edu_circle_to_search_title (4322780398403949508) -->
- <skip />
- <!-- no translation found for taskbar_edu_circle_to_search_disclosure (5841648785867787221) -->
- <skip />
+ <string name="taskbar_edu_circle_to_search_title" msgid="4322780398403949508">"Дэлгэц дээрээ байгаа зүйлийг хайхын тулд тусгай товчлуурыг удаан дарна уу"</string>
+ <string name="taskbar_edu_circle_to_search_disclosure" msgid="5841648785867787221">"Энэ бүтээгдэхүүн хайхын тулд таны дэлгэцийн сонгосон хэсгийг ашигладаг. Google-н <xliff:g id="BEGIN_PRIVACY_LINK"><a href="%1$s"></xliff:g>нууцлалын бодлого<xliff:g id="END_PRIVACY_LINK"></a></xliff:g> болон <xliff:g id="BEGIN_TOS_LINK"><a href="%2$s"></xliff:g>үйлчилгээний нөхцөл<xliff:g id="END_TOS_LINK"></a></xliff:g> хэрэгжинэ."</string>
<string name="taskbar_edu_close" msgid="887022990168191073">"Хаах"</string>
<string name="taskbar_edu_done" msgid="6880178093977704569">"Дууссан"</string>
<string name="taskbar_button_home" msgid="2151398979630664652">"Гэр"</string>
diff --git a/quickstep/res/values-mr/strings.xml b/quickstep/res/values-mr/strings.xml
index b0c6aca..fa09e2b 100644
--- a/quickstep/res/values-mr/strings.xml
+++ b/quickstep/res/values-mr/strings.xml
@@ -118,10 +118,8 @@
<string name="taskbar_edu_features" msgid="3320337287472848162">"टास्कबार चा पुरेपूर वापर करा"</string>
<string name="taskbar_edu_pinning_title" msgid="210102174154211712">"टास्कबार नेहमी दाखवा"</string>
<string name="taskbar_edu_pinning_standalone" msgid="2636919474366410467">"टास्कबार नेहमी तुमच्या स्क्रीनच्या तळाशी दाखवण्यासाठी, विभाजकाला स्पर्श करून धरून ठेवा"</string>
- <!-- no translation found for taskbar_edu_circle_to_search_title (4322780398403949508) -->
- <skip />
- <!-- no translation found for taskbar_edu_circle_to_search_disclosure (5841648785867787221) -->
- <skip />
+ <string name="taskbar_edu_circle_to_search_title" msgid="4322780398403949508">"तुमच्या स्क्रीनवर काय आहे हे शोधण्यासाठी अॅक्शन की स्पर्श करून धरून ठेवा"</string>
+ <string name="taskbar_edu_circle_to_search_disclosure" msgid="5841648785867787221">"शोधण्यासाठी हे उत्पादन तुमच्या स्क्रीनचा निवडलेला भाग वापरते. Google चे <xliff:g id="BEGIN_PRIVACY_LINK"><a href="%1$s"></xliff:g>गोपनीयता धोरण<xliff:g id="END_PRIVACY_LINK"></a></xliff:g> आणि <xliff:g id="BEGIN_TOS_LINK"><a href="%2$s"></xliff:g>सेवा अटी<xliff:g id="END_TOS_LINK"></a></xliff:g> लागू होतात."</string>
<string name="taskbar_edu_close" msgid="887022990168191073">"बंद करा"</string>
<string name="taskbar_edu_done" msgid="6880178093977704569">"पूर्ण झाले"</string>
<string name="taskbar_button_home" msgid="2151398979630664652">"होम"</string>
diff --git a/quickstep/res/values-my/strings.xml b/quickstep/res/values-my/strings.xml
index d7c98d3..66c4e5f 100644
--- a/quickstep/res/values-my/strings.xml
+++ b/quickstep/res/values-my/strings.xml
@@ -118,10 +118,8 @@
<string name="taskbar_edu_features" msgid="3320337287472848162">"Taskbar ဖြင့် ပိုမိုလုပ်ဆောင်နိုင်ခြင်း"</string>
<string name="taskbar_edu_pinning_title" msgid="210102174154211712">"Taskbar ကို အမြဲပြပါ"</string>
<string name="taskbar_edu_pinning_standalone" msgid="2636919474366410467">"Taskbar ကို စခရင်အောက်ခြေတွင် အမြဲပြရန် ခွဲခြားမျဉ်းကို တို့ထိ၍ ဖိထားပါ"</string>
- <!-- no translation found for taskbar_edu_circle_to_search_title (4322780398403949508) -->
- <skip />
- <!-- no translation found for taskbar_edu_circle_to_search_disclosure (5841648785867787221) -->
- <skip />
+ <string name="taskbar_edu_circle_to_search_title" msgid="4322780398403949508">"သင့်စခရင်ပေါ်ရှိအရာကို ရှာရန် လုပ်ဆောင်ချက်ကီးကို ထိ၍ဖိထားပါ"</string>
+ <string name="taskbar_edu_circle_to_search_disclosure" msgid="5841648785867787221">"ဤကုန်ပစ္စည်းသည် သင့်စခရင်၌ ရွေးထားသောအပိုင်းကိုသုံး၍ ရှာဖွေသည်။ Google ၏ <xliff:g id="BEGIN_PRIVACY_LINK"><a href="%1$s"></xliff:g>ကိုယ်ရေးအချက်အလက်လုံခြုံမှုဆိုင်ရာ မူဝါဒ<xliff:g id="END_PRIVACY_LINK"></a></xliff:g> နှင့် <xliff:g id="BEGIN_TOS_LINK"><a href="%2$s"></xliff:g>ဝန်ဆောင်မှုစည်းမျဉ်းများ<xliff:g id="END_TOS_LINK"></a></xliff:g> အကျုံးဝင်သည်။"</string>
<string name="taskbar_edu_close" msgid="887022990168191073">"ပိတ်ရန်"</string>
<string name="taskbar_edu_done" msgid="6880178093977704569">"ပြီးပြီ"</string>
<string name="taskbar_button_home" msgid="2151398979630664652">"ပင်မစာမျက်နှာ"</string>
diff --git a/quickstep/res/values-nb/strings.xml b/quickstep/res/values-nb/strings.xml
index 550bacc..6f9f38c 100644
--- a/quickstep/res/values-nb/strings.xml
+++ b/quickstep/res/values-nb/strings.xml
@@ -118,10 +118,8 @@
<string name="taskbar_edu_features" msgid="3320337287472848162">"Gjør mer med oppgavelinjen"</string>
<string name="taskbar_edu_pinning_title" msgid="210102174154211712">"Vis alltid oppgavelinjen"</string>
<string name="taskbar_edu_pinning_standalone" msgid="2636919474366410467">"For å alltid vise oppgavelinjen nederst på skjermen, trykk og hold på skillelinjen"</string>
- <!-- no translation found for taskbar_edu_circle_to_search_title (4322780398403949508) -->
- <skip />
- <!-- no translation found for taskbar_edu_circle_to_search_disclosure (5841648785867787221) -->
- <skip />
+ <string name="taskbar_edu_circle_to_search_title" msgid="4322780398403949508">"Trykk og hold på handlingstasten for å søke etter det som er på skjermen"</string>
+ <string name="taskbar_edu_circle_to_search_disclosure" msgid="5841648785867787221">"Dette produktet bruker den merkede delen av skjermen til å søke. Dette er underlagt Googles <xliff:g id="BEGIN_PRIVACY_LINK"><a href="%1$s"></xliff:g>personvernregler<xliff:g id="END_PRIVACY_LINK"></a></xliff:g> og <xliff:g id="BEGIN_TOS_LINK"><a href="%2$s"></xliff:g>vilkår for bruk<xliff:g id="END_TOS_LINK"></a></xliff:g>."</string>
<string name="taskbar_edu_close" msgid="887022990168191073">"Lukk"</string>
<string name="taskbar_edu_done" msgid="6880178093977704569">"Ferdig"</string>
<string name="taskbar_button_home" msgid="2151398979630664652">"Hjem"</string>
diff --git a/quickstep/res/values-nl/strings.xml b/quickstep/res/values-nl/strings.xml
index 3032ade..c288868 100644
--- a/quickstep/res/values-nl/strings.xml
+++ b/quickstep/res/values-nl/strings.xml
@@ -118,10 +118,8 @@
<string name="taskbar_edu_features" msgid="3320337287472848162">"Doe meer met de taakbalk"</string>
<string name="taskbar_edu_pinning_title" msgid="210102174154211712">"De taakbalk altijd tonen"</string>
<string name="taskbar_edu_pinning_standalone" msgid="2636919474366410467">"Houd de scheidingslijn ingedrukt als je de taakbalk altijd onderaan je scherm wilt tonen"</string>
- <!-- no translation found for taskbar_edu_circle_to_search_title (4322780398403949508) -->
- <skip />
- <!-- no translation found for taskbar_edu_circle_to_search_disclosure (5841648785867787221) -->
- <skip />
+ <string name="taskbar_edu_circle_to_search_title" msgid="4322780398403949508">"Houd je vinger op de actietoets om te zoeken naar wat er op je scherm staat"</string>
+ <string name="taskbar_edu_circle_to_search_disclosure" msgid="5841648785867787221">"Dit product gebruikt het geselecteerde gedeelte van je scherm om te zoeken. Het <xliff:g id="BEGIN_PRIVACY_LINK"><a href="%1$s"></xliff:g>Privacybeleid<xliff:g id="END_PRIVACY_LINK"></a></xliff:g> en de <xliff:g id="BEGIN_TOS_LINK"><a href="%2$s"></xliff:g>Servicevoorwaarden<xliff:g id="END_TOS_LINK"></a></xliff:g> van Google zijn van toepassing."</string>
<string name="taskbar_edu_close" msgid="887022990168191073">"Sluiten"</string>
<string name="taskbar_edu_done" msgid="6880178093977704569">"Klaar"</string>
<string name="taskbar_button_home" msgid="2151398979630664652">"Home"</string>
diff --git a/quickstep/res/values-pa/strings.xml b/quickstep/res/values-pa/strings.xml
index 38d2dac..5c85461 100644
--- a/quickstep/res/values-pa/strings.xml
+++ b/quickstep/res/values-pa/strings.xml
@@ -118,10 +118,8 @@
<string name="taskbar_edu_features" msgid="3320337287472848162">"ਟਾਸਕਬਾਰ ਦਾ ਹੋਰ ਲਾਹਾ ਲਓ"</string>
<string name="taskbar_edu_pinning_title" msgid="210102174154211712">"ਹਮੇਸ਼ਾਂ ਟਾਸਕਬਾਰ ਦਿਖਾਉਣਾ"</string>
<string name="taskbar_edu_pinning_standalone" msgid="2636919474366410467">"ਆਪਣੀ ਸਕ੍ਰੀਨ ਦੇ ਹੇਠਾਂ ਹਮੇਸ਼ਾਂ ਟਾਸਕਬਾਰ ਦਿਖਾਉਣ ਲਈ, ਵਿਭਾਜਕ ਨੂੰ ਸਪਰਸ਼ ਕਰ ਕੇ ਰੱਖੋ"</string>
- <!-- no translation found for taskbar_edu_circle_to_search_title (4322780398403949508) -->
- <skip />
- <!-- no translation found for taskbar_edu_circle_to_search_disclosure (5841648785867787221) -->
- <skip />
+ <string name="taskbar_edu_circle_to_search_title" msgid="4322780398403949508">"ਤੁਹਾਡੀ ਸਕ੍ਰੀਨ \'ਤੇ ਮੌਜੂਦ ਸਮੱਗਰੀ ਨੂੰ ਖੋਜਣ ਲਈ, ਕਾਰਵਾਈ ਕੁੰਜੀ ਨੂੰ ਸਪਰਸ਼ ਕਰ ਕੇ ਰੱਖੋ"</string>
+ <string name="taskbar_edu_circle_to_search_disclosure" msgid="5841648785867787221">"ਇਹ ਉਤਪਾਦ ਖੋਜ ਕਰਨ ਲਈ ਤੁਹਾਡੀ ਸਕ੍ਰੀਨ ਦੇ ਚੁਣੇ ਹੋਏ ਹਿੱਸੇ ਦੀ ਵਰਤੋਂ ਕਰਦਾ ਹੈ। Google ਦੀ <xliff:g id="BEGIN_PRIVACY_LINK"><a href="%1$s"></xliff:g>ਪਰਦੇਦਾਰੀ ਨੀਤੀ<xliff:g id="END_PRIVACY_LINK"></a></xliff:g> ਅਤੇ <xliff:g id="BEGIN_TOS_LINK"><a href="%2$s"></xliff:g>ਸੇਵਾ ਦੇ ਨਿਯਮ<xliff:g id="END_TOS_LINK"></a></xliff:g> ਲਾਗੂ ਹੁੰਦੇ ਹਨ।"</string>
<string name="taskbar_edu_close" msgid="887022990168191073">"ਬੰਦ ਕਰੋ"</string>
<string name="taskbar_edu_done" msgid="6880178093977704569">"ਸਮਝ ਲਿਆ"</string>
<string name="taskbar_button_home" msgid="2151398979630664652">"ਘਰ"</string>
diff --git a/quickstep/res/values-pl/strings.xml b/quickstep/res/values-pl/strings.xml
index 9a55b94..11f46bc 100644
--- a/quickstep/res/values-pl/strings.xml
+++ b/quickstep/res/values-pl/strings.xml
@@ -21,8 +21,7 @@
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
<string name="recent_task_option_pin" msgid="7929860679018978258">"Przypnij"</string>
<string name="recent_task_option_freeform" msgid="48863056265284071">"Tryb dowolny"</string>
- <!-- no translation found for recent_task_option_desktop (8280879717125435668) -->
- <skip />
+ <string name="recent_task_option_desktop" msgid="8280879717125435668">"Pulpit"</string>
<string name="recents_empty_message" msgid="7040467240571714191">"Brak ostatnich elementów"</string>
<string name="accessibility_app_usage_settings" msgid="6312864233673544149">"Ustawienia użycia aplikacji"</string>
<string name="recents_clear_all" msgid="5328176793634888831">"Wyczyść wszystko"</string>
diff --git a/quickstep/res/values-pt/strings.xml b/quickstep/res/values-pt/strings.xml
index 532a598..9ea746c 100644
--- a/quickstep/res/values-pt/strings.xml
+++ b/quickstep/res/values-pt/strings.xml
@@ -118,10 +118,8 @@
<string name="taskbar_edu_features" msgid="3320337287472848162">"Aproveite ainda mais a Barra de tarefas"</string>
<string name="taskbar_edu_pinning_title" msgid="210102174154211712">"Sempre mostrar a Barra de tarefas"</string>
<string name="taskbar_edu_pinning_standalone" msgid="2636919474366410467">"Toque e pressione o divisor para sempre mostrar a Barra de tarefas na parte de baixo da tela"</string>
- <!-- no translation found for taskbar_edu_circle_to_search_title (4322780398403949508) -->
- <skip />
- <!-- no translation found for taskbar_edu_circle_to_search_disclosure (5841648785867787221) -->
- <skip />
+ <string name="taskbar_edu_circle_to_search_title" msgid="4322780398403949508">"Toque e pressione a tecla de ação para pesquisar o que está na tela"</string>
+ <string name="taskbar_edu_circle_to_search_disclosure" msgid="5841648785867787221">"O produto usa a parte selecionada da tela para pesquisar. O uso desses dados está sujeito à <xliff:g id="BEGIN_PRIVACY_LINK"><a href="%1$s"></xliff:g>Política de Privacidade<xliff:g id="END_PRIVACY_LINK"></a></xliff:g> e aos <xliff:g id="BEGIN_TOS_LINK"><a href="%2$s"></xliff:g>Termos de Serviço<xliff:g id="END_TOS_LINK"></a></xliff:g> do Google."</string>
<string name="taskbar_edu_close" msgid="887022990168191073">"Fechar"</string>
<string name="taskbar_edu_done" msgid="6880178093977704569">"Concluído"</string>
<string name="taskbar_button_home" msgid="2151398979630664652">"Início"</string>
diff --git a/quickstep/res/values-ro/strings.xml b/quickstep/res/values-ro/strings.xml
index ed7dfd8..e45e45a 100644
--- a/quickstep/res/values-ro/strings.xml
+++ b/quickstep/res/values-ro/strings.xml
@@ -118,10 +118,8 @@
<string name="taskbar_edu_features" msgid="3320337287472848162">"Fă mai multe din Bara de activități"</string>
<string name="taskbar_edu_pinning_title" msgid="210102174154211712">"Afișează întotdeauna Bara de activități"</string>
<string name="taskbar_edu_pinning_standalone" msgid="2636919474366410467">"Pentru a afișa mereu Bara de activități în partea de jos a ecranului, atinge lung separatorul"</string>
- <!-- no translation found for taskbar_edu_circle_to_search_title (4322780398403949508) -->
- <skip />
- <!-- no translation found for taskbar_edu_circle_to_search_disclosure (5841648785867787221) -->
- <skip />
+ <string name="taskbar_edu_circle_to_search_title" msgid="4322780398403949508">"Atinge lung tasta de acțiuni ca să cauți pe ecran"</string>
+ <string name="taskbar_edu_circle_to_search_disclosure" msgid="5841648785867787221">"Acest produs folosește partea selectată a ecranului pentru a căuta. Se aplică <xliff:g id="BEGIN_PRIVACY_LINK"><a href="%1$s"></xliff:g>Politica de confidențialitate<xliff:g id="END_PRIVACY_LINK"></a></xliff:g> și <xliff:g id="BEGIN_TOS_LINK"><a href="%2$s"></xliff:g>Termenii și condițiile<xliff:g id="END_TOS_LINK"></a></xliff:g> Google."</string>
<string name="taskbar_edu_close" msgid="887022990168191073">"Închide"</string>
<string name="taskbar_edu_done" msgid="6880178093977704569">"Gata"</string>
<string name="taskbar_button_home" msgid="2151398979630664652">"Ecran de pornire"</string>
diff --git a/quickstep/res/values-si/strings.xml b/quickstep/res/values-si/strings.xml
index 1335e0e..65dde9d 100644
--- a/quickstep/res/values-si/strings.xml
+++ b/quickstep/res/values-si/strings.xml
@@ -118,10 +118,8 @@
<string name="taskbar_edu_features" msgid="3320337287472848162">"කාර්ය තීරුව සමග තවත් කරන්න"</string>
<string name="taskbar_edu_pinning_title" msgid="210102174154211712">"සෑම විටම කාර්ය තීරුව පෙන්වන්න"</string>
<string name="taskbar_edu_pinning_standalone" msgid="2636919474366410467">"සෑම විටම ඔබේ තිරයේ පතුලේ ඇති කාර්ය තීරුව පෙන්වීමට, බෙදුම්කරු ස්පර්ශ කර අල්ලාගෙන සිටින්න"</string>
- <!-- no translation found for taskbar_edu_circle_to_search_title (4322780398403949508) -->
- <skip />
- <!-- no translation found for taskbar_edu_circle_to_search_disclosure (5841648785867787221) -->
- <skip />
+ <string name="taskbar_edu_circle_to_search_title" msgid="4322780398403949508">"ඔබේ තිරයෙහි ඇති දේ සෙවීමට ක්රියා යතුර ස්පර්ශ කර සිටින්න"</string>
+ <string name="taskbar_edu_circle_to_search_disclosure" msgid="5841648785867787221">"මෙම නිෂ්පාදනය සෙවීමට ඔබේ තිරයෙහි තෝරන ලද කොටස භාවිතා කරයි. Google හි <xliff:g id="BEGIN_PRIVACY_LINK"><a href="%1$s"></xliff:g>පෞද්ගලිකත්ව ප්රතිපත්තිය<xliff:g id="END_PRIVACY_LINK"></a></xliff:g> සහ <xliff:g id="BEGIN_TOS_LINK"><a href="%2$s"></xliff:g>සේවා නියමයන්<xliff:g id="END_TOS_LINK"></a></xliff:g> අදාළ වේ."</string>
<string name="taskbar_edu_close" msgid="887022990168191073">"වසන්න"</string>
<string name="taskbar_edu_done" msgid="6880178093977704569">"නිමයි"</string>
<string name="taskbar_button_home" msgid="2151398979630664652">"මුල් පිටුව"</string>
diff --git a/quickstep/res/values-sq/strings.xml b/quickstep/res/values-sq/strings.xml
index 1cc11d2..7ae201f 100644
--- a/quickstep/res/values-sq/strings.xml
+++ b/quickstep/res/values-sq/strings.xml
@@ -118,10 +118,8 @@
<string name="taskbar_edu_features" msgid="3320337287472848162">"Bëj më shumë me \"Shiritin e detyrave\""</string>
<string name="taskbar_edu_pinning_title" msgid="210102174154211712">"Shfaq gjithmonë \"Shiritin e detyrave\""</string>
<string name="taskbar_edu_pinning_standalone" msgid="2636919474366410467">"Prek e mbaj ndarësin dhe shfaq gjithmonë \"Shiritin e detyrave\" në fund të ekranit"</string>
- <!-- no translation found for taskbar_edu_circle_to_search_title (4322780398403949508) -->
- <skip />
- <!-- no translation found for taskbar_edu_circle_to_search_disclosure (5841648785867787221) -->
- <skip />
+ <string name="taskbar_edu_circle_to_search_title" msgid="4322780398403949508">"Prek dhe mbaj shtypur tastin e veprimit për të kërkuar për gjërat në ekran"</string>
+ <string name="taskbar_edu_circle_to_search_disclosure" msgid="5841648785867787221">"Ky produkt përdor pjesën e zgjedhur të ekranit tënd për të kërkuar. Zbatohen <xliff:g id="BEGIN_PRIVACY_LINK"><a href="%1$s"></xliff:g>Politika e privatësisë<xliff:g id="END_PRIVACY_LINK"></a></xliff:g> dhe <xliff:g id="BEGIN_TOS_LINK"><a href="%2$s"></xliff:g>Kushtet e shërbimit<xliff:g id="END_TOS_LINK"></a></xliff:g> të Google."</string>
<string name="taskbar_edu_close" msgid="887022990168191073">"Mbyll"</string>
<string name="taskbar_edu_done" msgid="6880178093977704569">"U krye"</string>
<string name="taskbar_button_home" msgid="2151398979630664652">"Faqja kryesore"</string>
diff --git a/quickstep/res/values-sv/strings.xml b/quickstep/res/values-sv/strings.xml
index d994ef5..808cfe9 100644
--- a/quickstep/res/values-sv/strings.xml
+++ b/quickstep/res/values-sv/strings.xml
@@ -118,10 +118,8 @@
<string name="taskbar_edu_features" msgid="3320337287472848162">"Gör mer med aktivitetsfältet"</string>
<string name="taskbar_edu_pinning_title" msgid="210102174154211712">"Visa alltid aktivitetsfältet"</string>
<string name="taskbar_edu_pinning_standalone" msgid="2636919474366410467">"Tryck länge på avgränsaren för att alltid visa aktivitetsfältet längst ned på skärmen"</string>
- <!-- no translation found for taskbar_edu_circle_to_search_title (4322780398403949508) -->
- <skip />
- <!-- no translation found for taskbar_edu_circle_to_search_disclosure (5841648785867787221) -->
- <skip />
+ <string name="taskbar_edu_circle_to_search_title" msgid="4322780398403949508">"Tryck länge på åtgärdstangenten för att söka efter det som finns på skärmen"</string>
+ <string name="taskbar_edu_circle_to_search_disclosure" msgid="5841648785867787221">"Den här produkten använder den valda delen av skärmen för att söka. Googles <xliff:g id="BEGIN_PRIVACY_LINK"><a href="%1$s"></xliff:g>integritetspolicy<xliff:g id="END_PRIVACY_LINK"></a></xliff:g> och <xliff:g id="BEGIN_TOS_LINK"><a href="%2$s"></xliff:g>användarvillkor<xliff:g id="END_TOS_LINK"></a></xliff:g> gäller."</string>
<string name="taskbar_edu_close" msgid="887022990168191073">"Stäng"</string>
<string name="taskbar_edu_done" msgid="6880178093977704569">"Klar"</string>
<string name="taskbar_button_home" msgid="2151398979630664652">"Startsida"</string>
diff --git a/quickstep/res/values-ta/strings.xml b/quickstep/res/values-ta/strings.xml
index 2f458f4..c5cbfcd 100644
--- a/quickstep/res/values-ta/strings.xml
+++ b/quickstep/res/values-ta/strings.xml
@@ -118,10 +118,8 @@
<string name="taskbar_edu_features" msgid="3320337287472848162">"செயல் பட்டி மூலம் மேலும் பலவற்றைச் செய்யுங்கள்"</string>
<string name="taskbar_edu_pinning_title" msgid="210102174154211712">"செயல் பட்டியை எப்போதும் காட்டுதல்"</string>
<string name="taskbar_edu_pinning_standalone" msgid="2636919474366410467">"திரையின் கீழ்ப்பகுதியில் செயல் பட்டியை எப்போதும் காட்டுவதற்கு, பிரிப்பானைத் தொட்டுப் பிடித்திருக்கவும்"</string>
- <!-- no translation found for taskbar_edu_circle_to_search_title (4322780398403949508) -->
- <skip />
- <!-- no translation found for taskbar_edu_circle_to_search_disclosure (5841648785867787221) -->
- <skip />
+ <string name="taskbar_edu_circle_to_search_title" msgid="4322780398403949508">"உங்கள் திரையில் உள்ளவற்றைத் தேடுவதற்கு ஆக்ஷன் பட்டனைத் தொட்டுப் பிடியுங்கள்"</string>
+ <string name="taskbar_edu_circle_to_search_disclosure" msgid="5841648785867787221">"தேடுவதற்கு உங்கள் திரையின் தேர்ந்தெடுக்கப்பட்ட பகுதியை இந்தத் தயாரிப்பு பயன்படுத்துகிறது. Googleளின் <xliff:g id="BEGIN_PRIVACY_LINK"><a href="%1$s"></xliff:g>தனியுரிமைக் கொள்கையும்<xliff:g id="END_PRIVACY_LINK"></a></xliff:g> <xliff:g id="BEGIN_TOS_LINK"><a href="%2$s"></xliff:g>சேவை விதிமுறைகளும்<xliff:g id="END_TOS_LINK"></a></xliff:g> பொருந்தும்."</string>
<string name="taskbar_edu_close" msgid="887022990168191073">"மூடுக"</string>
<string name="taskbar_edu_done" msgid="6880178093977704569">"முடிந்தது"</string>
<string name="taskbar_button_home" msgid="2151398979630664652">"முகப்பு"</string>
diff --git a/quickstep/res/values-tr/strings.xml b/quickstep/res/values-tr/strings.xml
index a10d0e3..79f8ad1 100644
--- a/quickstep/res/values-tr/strings.xml
+++ b/quickstep/res/values-tr/strings.xml
@@ -118,10 +118,8 @@
<string name="taskbar_edu_features" msgid="3320337287472848162">"Görev çubuğuyla daha fazla şey yapın"</string>
<string name="taskbar_edu_pinning_title" msgid="210102174154211712">"Görev çubuğunu sabitleyin"</string>
<string name="taskbar_edu_pinning_standalone" msgid="2636919474366410467">"Ayırıcıya dokunup basılı tuttuğunuzda görev çubuğu ekranın alt kısmına sabitlenir"</string>
- <!-- no translation found for taskbar_edu_circle_to_search_title (4322780398403949508) -->
- <skip />
- <!-- no translation found for taskbar_edu_circle_to_search_disclosure (5841648785867787221) -->
- <skip />
+ <string name="taskbar_edu_circle_to_search_title" msgid="4322780398403949508">"Ekranınızda bulunan içerikleri aramak için eylem tuşuna dokunup basılı tutun"</string>
+ <string name="taskbar_edu_circle_to_search_disclosure" msgid="5841648785867787221">"Bu ürün, ekranınızın seçilen bölümünü kullanarak arama yapar. Google\'ın <xliff:g id="BEGIN_PRIVACY_LINK"><a href="%1$s"></xliff:g>Gizlilik Politikası<xliff:g id="END_PRIVACY_LINK"></a></xliff:g> ve <xliff:g id="BEGIN_TOS_LINK"><a href="%2$s"></xliff:g>Hizmet Şartları<xliff:g id="END_TOS_LINK"></a></xliff:g> geçerlidir."</string>
<string name="taskbar_edu_close" msgid="887022990168191073">"Kapat"</string>
<string name="taskbar_edu_done" msgid="6880178093977704569">"Bitti"</string>
<string name="taskbar_button_home" msgid="2151398979630664652">"Ana ekran"</string>
diff --git a/quickstep/res/values-uk/strings.xml b/quickstep/res/values-uk/strings.xml
index 5e19342..c1ef51d 100644
--- a/quickstep/res/values-uk/strings.xml
+++ b/quickstep/res/values-uk/strings.xml
@@ -118,10 +118,8 @@
<string name="taskbar_edu_features" msgid="3320337287472848162">"Більше можливостей завдяки панелі завдань"</string>
<string name="taskbar_edu_pinning_title" msgid="210102174154211712">"Завжди показувати панель завдань"</string>
<string name="taskbar_edu_pinning_standalone" msgid="2636919474366410467">"Щоб завжди показувати панель завдань унизу екрана, натисніть і втримуйте роздільник"</string>
- <!-- no translation found for taskbar_edu_circle_to_search_title (4322780398403949508) -->
- <skip />
- <!-- no translation found for taskbar_edu_circle_to_search_disclosure (5841648785867787221) -->
- <skip />
+ <string name="taskbar_edu_circle_to_search_title" msgid="4322780398403949508">"Для пошуку інформації, що відображається на екрані, натисніть і втримуйте клавішу дії"</string>
+ <string name="taskbar_edu_circle_to_search_disclosure" msgid="5841648785867787221">"Цей продукт використовує для пошуку вибрану частину екрана. Застосовуються <xliff:g id="BEGIN_PRIVACY_LINK"><a href="%1$s"></xliff:g>Політика конфіденційності<xliff:g id="END_PRIVACY_LINK"></a></xliff:g> та <xliff:g id="BEGIN_TOS_LINK"><a href="%2$s"></xliff:g>Загальні положення й умови<xliff:g id="END_TOS_LINK"></a></xliff:g> Google."</string>
<string name="taskbar_edu_close" msgid="887022990168191073">"Закрити"</string>
<string name="taskbar_edu_done" msgid="6880178093977704569">"Готово"</string>
<string name="taskbar_button_home" msgid="2151398979630664652">"Головний екран"</string>
diff --git a/quickstep/res/values-uz/strings.xml b/quickstep/res/values-uz/strings.xml
index efbb6a3..e543225 100644
--- a/quickstep/res/values-uz/strings.xml
+++ b/quickstep/res/values-uz/strings.xml
@@ -118,10 +118,8 @@
<string name="taskbar_edu_features" msgid="3320337287472848162">"Vazifalar panelidan maksimal darajada foydalaning"</string>
<string name="taskbar_edu_pinning_title" msgid="210102174154211712">"Vazifalar paneli doim chiqarilsin"</string>
<string name="taskbar_edu_pinning_standalone" msgid="2636919474366410467">"Vazifalar panelini ekranning pastki qismida doim chiqib turishi uchun ajratkichni bosib turing"</string>
- <!-- no translation found for taskbar_edu_circle_to_search_title (4322780398403949508) -->
- <skip />
- <!-- no translation found for taskbar_edu_circle_to_search_disclosure (5841648785867787221) -->
- <skip />
+ <string name="taskbar_edu_circle_to_search_title" msgid="4322780398403949508">"Ekrandagi element haqida maʼlumotni topish uchun amal tugmasini bosib turing"</string>
+ <string name="taskbar_edu_circle_to_search_disclosure" msgid="5841648785867787221">"Bu mahsulot qidirish uchun ekranning tanlangan qismidan foydalanadi. Google <xliff:g id="BEGIN_PRIVACY_LINK"><a href="%1$s"></xliff:g>maxfiylik siyosati<xliff:g id="END_PRIVACY_LINK"></a></xliff:g> va <xliff:g id="BEGIN_TOS_LINK"><a href="%2$s"></xliff:g>xizmat shartlari<xliff:g id="END_TOS_LINK"></a></xliff:g> tatbiq qilinadi."</string>
<string name="taskbar_edu_close" msgid="887022990168191073">"Yopish"</string>
<string name="taskbar_edu_done" msgid="6880178093977704569">"Tayyor"</string>
<string name="taskbar_button_home" msgid="2151398979630664652">"Bosh ekran"</string>
diff --git a/quickstep/res/values-vi/strings.xml b/quickstep/res/values-vi/strings.xml
index 8d35279..136e1d2 100644
--- a/quickstep/res/values-vi/strings.xml
+++ b/quickstep/res/values-vi/strings.xml
@@ -118,10 +118,8 @@
<string name="taskbar_edu_features" msgid="3320337287472848162">"Làm nhiều việc hơn qua Thanh tác vụ"</string>
<string name="taskbar_edu_pinning_title" msgid="210102174154211712">"Luôn hiện Taskbar"</string>
<string name="taskbar_edu_pinning_standalone" msgid="2636919474366410467">"Để luôn hiện Taskbar ở cuối màn hình, hãy nhấn và giữ đường phân chia"</string>
- <!-- no translation found for taskbar_edu_circle_to_search_title (4322780398403949508) -->
- <skip />
- <!-- no translation found for taskbar_edu_circle_to_search_disclosure (5841648785867787221) -->
- <skip />
+ <string name="taskbar_edu_circle_to_search_title" msgid="4322780398403949508">"Hãy chạm và giữ phím hành động để tìm xem trên màn hình của bạn có gì"</string>
+ <string name="taskbar_edu_circle_to_search_disclosure" msgid="5841648785867787221">"Sản phẩm này dùng phần được chọn trên màn hình để tìm kiếm. Có áp dụng <xliff:g id="BEGIN_PRIVACY_LINK"><a href="%1$s"></xliff:g>Chính sách quyền riêng tư<xliff:g id="END_PRIVACY_LINK"></a></xliff:g> và <xliff:g id="BEGIN_TOS_LINK"><a href="%2$s"></xliff:g>Điều khoản dịch vụ<xliff:g id="END_TOS_LINK"></a></xliff:g> của Google."</string>
<string name="taskbar_edu_close" msgid="887022990168191073">"Đóng"</string>
<string name="taskbar_edu_done" msgid="6880178093977704569">"Xong"</string>
<string name="taskbar_button_home" msgid="2151398979630664652">"Màn hình chính"</string>
diff --git a/quickstep/res/values-zh-rCN/strings.xml b/quickstep/res/values-zh-rCN/strings.xml
index b567c66..b90d6bf 100644
--- a/quickstep/res/values-zh-rCN/strings.xml
+++ b/quickstep/res/values-zh-rCN/strings.xml
@@ -118,10 +118,8 @@
<string name="taskbar_edu_features" msgid="3320337287472848162">"体验任务栏的更多功能"</string>
<string name="taskbar_edu_pinning_title" msgid="210102174154211712">"始终显示任务栏"</string>
<string name="taskbar_edu_pinning_standalone" msgid="2636919474366410467">"若要始终在屏幕底部显示任务栏,请轻触并按住分隔线"</string>
- <!-- no translation found for taskbar_edu_circle_to_search_title (4322780398403949508) -->
- <skip />
- <!-- no translation found for taskbar_edu_circle_to_search_disclosure (5841648785867787221) -->
- <skip />
+ <string name="taskbar_edu_circle_to_search_title" msgid="4322780398403949508">"轻触并按住操作键,即可根据屏幕上的内容进行搜索"</string>
+ <string name="taskbar_edu_circle_to_search_disclosure" msgid="5841648785867787221">"此产品会根据您在屏幕上选取的部分进行搜索。Google 的<xliff:g id="BEGIN_PRIVACY_LINK"><a href="%1$s"></xliff:g>《隐私权政策》<xliff:g id="END_PRIVACY_LINK"></a></xliff:g>和<xliff:g id="BEGIN_TOS_LINK"><a href="%2$s"></xliff:g>《服务条款》<xliff:g id="END_TOS_LINK"></a></xliff:g>在此适用。"</string>
<string name="taskbar_edu_close" msgid="887022990168191073">"关闭"</string>
<string name="taskbar_edu_done" msgid="6880178093977704569">"完成"</string>
<string name="taskbar_button_home" msgid="2151398979630664652">"主屏幕"</string>
diff --git a/quickstep/res/values-zh-rHK/strings.xml b/quickstep/res/values-zh-rHK/strings.xml
index b314def..c006c59 100644
--- a/quickstep/res/values-zh-rHK/strings.xml
+++ b/quickstep/res/values-zh-rHK/strings.xml
@@ -118,10 +118,8 @@
<string name="taskbar_edu_features" msgid="3320337287472848162">"工作列助你事半功倍"</string>
<string name="taskbar_edu_pinning_title" msgid="210102174154211712">"一律顯示工作列"</string>
<string name="taskbar_edu_pinning_standalone" msgid="2636919474366410467">"如要持續在畫面底部顯示工作列,請按住分隔線"</string>
- <!-- no translation found for taskbar_edu_circle_to_search_title (4322780398403949508) -->
- <skip />
- <!-- no translation found for taskbar_edu_circle_to_search_disclosure (5841648785867787221) -->
- <skip />
+ <string name="taskbar_edu_circle_to_search_title" msgid="4322780398403949508">"按住快捷操作鍵即可搜尋畫面上的內容"</string>
+ <string name="taskbar_edu_circle_to_search_disclosure" msgid="5841648785867787221">"此產品使用螢幕的特定部分進行搜尋。須受 Google 的《<xliff:g id="BEGIN_PRIVACY_LINK"><a href="%1$s"></xliff:g>私隱權政策<xliff:g id="END_PRIVACY_LINK"></a></xliff:g>》和《<xliff:g id="BEGIN_TOS_LINK"><a href="%2$s"></xliff:g>服務條款<xliff:g id="END_TOS_LINK"></a></xliff:g>》約束。"</string>
<string name="taskbar_edu_close" msgid="887022990168191073">"關閉"</string>
<string name="taskbar_edu_done" msgid="6880178093977704569">"完成"</string>
<string name="taskbar_button_home" msgid="2151398979630664652">"住宅"</string>
diff --git a/quickstep/res/values-zh-rTW/strings.xml b/quickstep/res/values-zh-rTW/strings.xml
index 0864c55..e793df6 100644
--- a/quickstep/res/values-zh-rTW/strings.xml
+++ b/quickstep/res/values-zh-rTW/strings.xml
@@ -118,10 +118,8 @@
<string name="taskbar_edu_features" msgid="3320337287472848162">"充分發揮工作列的功用"</string>
<string name="taskbar_edu_pinning_title" msgid="210102174154211712">"一律顯示工作列"</string>
<string name="taskbar_edu_pinning_standalone" msgid="2636919474366410467">"如要一律在畫面底部顯示工作列,請按住分隔線"</string>
- <!-- no translation found for taskbar_edu_circle_to_search_title (4322780398403949508) -->
- <skip />
- <!-- no translation found for taskbar_edu_circle_to_search_disclosure (5841648785867787221) -->
- <skip />
+ <string name="taskbar_edu_circle_to_search_title" msgid="4322780398403949508">"按住快捷操作鍵即可搜尋畫面上的內容"</string>
+ <string name="taskbar_edu_circle_to_search_disclosure" msgid="5841648785867787221">"這項產品會搜尋你在畫面上選取的內容 (適用 Google 的《<xliff:g id="BEGIN_PRIVACY_LINK"><a href="%1$s"></xliff:g>隱私權政策<xliff:g id="END_PRIVACY_LINK"></a></xliff:g>》和《<xliff:g id="BEGIN_TOS_LINK"><a href="%2$s"></xliff:g>服務條款<xliff:g id="END_TOS_LINK"></a></xliff:g>》)。"</string>
<string name="taskbar_edu_close" msgid="887022990168191073">"關閉"</string>
<string name="taskbar_edu_done" msgid="6880178093977704569">"完成"</string>
<string name="taskbar_button_home" msgid="2151398979630664652">"主畫面"</string>
diff --git a/quickstep/res/values-zu/strings.xml b/quickstep/res/values-zu/strings.xml
index e1c1f3a..5723214 100644
--- a/quickstep/res/values-zu/strings.xml
+++ b/quickstep/res/values-zu/strings.xml
@@ -118,10 +118,8 @@
<string name="taskbar_edu_features" msgid="3320337287472848162">"Yenza okwengeziwe nge-Taskbar"</string>
<string name="taskbar_edu_pinning_title" msgid="210102174154211712">"Bonisa njalo i-Taskbar"</string>
<string name="taskbar_edu_pinning_standalone" msgid="2636919474366410467">"Ukuze ubonise njalo i-Taskbar phansi kwesikrini sakho, thinta bese ubamba isihlukanisi"</string>
- <!-- no translation found for taskbar_edu_circle_to_search_title (4322780398403949508) -->
- <skip />
- <!-- no translation found for taskbar_edu_circle_to_search_disclosure (5841648785867787221) -->
- <skip />
+ <string name="taskbar_edu_circle_to_search_title" msgid="4322780398403949508">"Thinta uphinde ubambe inkinobho yokufinyelela ukuze useshe lokho okukusikrini sakho"</string>
+ <string name="taskbar_edu_circle_to_search_disclosure" msgid="5841648785867787221">"Lo mkhiqizo usebenzisa ingxenye ekhethiwe yesikrini sakho ukusesha. <xliff:g id="BEGIN_PRIVACY_LINK"><a href="%1$s"></xliff:g>Inqubomgomo Yobumfihlo<xliff:g id="END_PRIVACY_LINK"></a></xliff:g> ye-Google kanye <xliff:g id="BEGIN_TOS_LINK"><a href="%2$s"></xliff:g>Nemigomo Yesevisi<xliff:g id="END_TOS_LINK"></a></xliff:g> iyasebenza."</string>
<string name="taskbar_edu_close" msgid="887022990168191073">"Vala"</string>
<string name="taskbar_edu_done" msgid="6880178093977704569">"Kwenziwe"</string>
<string name="taskbar_button_home" msgid="2151398979630664652">"Ikhaya"</string>
diff --git a/quickstep/res/values/dimens.xml b/quickstep/res/values/dimens.xml
index 69e07f2..dc28614 100644
--- a/quickstep/res/values/dimens.xml
+++ b/quickstep/res/values/dimens.xml
@@ -427,11 +427,14 @@
<dimen name="bubblebar_drag_elevation">2dp</dimen>
<dimen name="bubblebar_hotseat_adjustment_threshold">90dp</dimen>
- <dimen name="bubblebar_icon_size">50dp</dimen>
+ <dimen name="bubblebar_icon_size_small">32dp</dimen>
+ <dimen name="bubblebar_icon_size">36dp</dimen>
<dimen name="bubblebar_badge_size">24dp</dimen>
<dimen name="bubblebar_icon_overlap">12dp</dimen>
- <dimen name="bubblebar_overflow_inset">24dp</dimen>
- <dimen name="bubblebar_icon_spacing">3dp</dimen>
+ <dimen name="bubblebar_overflow_inset">16dp</dimen>
+ <dimen name="bubblebar_icon_spacing">6dp</dimen>
+ <dimen name="bubblebar_icon_spacing_large">8dp</dimen>
+ <dimen name="bubblebar_expanded_icon_spacing">12dp</dimen>
<dimen name="bubblebar_icon_elevation">1dp</dimen>
<!-- Bubble bar dismiss view -->
diff --git a/quickstep/src/com/android/launcher3/model/QuickstepModelDelegate.java b/quickstep/src/com/android/launcher3/model/QuickstepModelDelegate.java
index bc35125..fb14f9e 100644
--- a/quickstep/src/com/android/launcher3/model/QuickstepModelDelegate.java
+++ b/quickstep/src/com/android/launcher3/model/QuickstepModelDelegate.java
@@ -70,6 +70,7 @@
import com.android.launcher3.model.data.WorkspaceItemInfo;
import com.android.launcher3.pm.UserCache;
import com.android.launcher3.shortcuts.ShortcutKey;
+import com.android.launcher3.util.ApiWrapper;
import com.android.launcher3.util.Executors;
import com.android.launcher3.util.IntSparseArrayMap;
import com.android.launcher3.util.PersistedItemArray;
@@ -557,6 +558,7 @@
AppInfo info = new AppInfo(
lai,
UserCache.INSTANCE.get(mAppState.getContext()).getUserInfo(user),
+ ApiWrapper.INSTANCE.get(mAppState.getContext()),
mUMS.isUserQuiet(user));
info.container = mContainer;
mAppState.getIconCache().getTitleAndIcon(info, lai, false);
diff --git a/quickstep/src/com/android/launcher3/statehandlers/DesktopVisibilityController.java b/quickstep/src/com/android/launcher3/statehandlers/DesktopVisibilityController.java
index c0dacf1..74376c8 100644
--- a/quickstep/src/com/android/launcher3/statehandlers/DesktopVisibilityController.java
+++ b/quickstep/src/com/android/launcher3/statehandlers/DesktopVisibilityController.java
@@ -19,6 +19,7 @@
import static com.android.launcher3.LauncherState.BACKGROUND_APP;
import static com.android.launcher3.util.Executors.MAIN_EXECUTOR;
+import static com.android.window.flags.Flags.enableDesktopWindowingWallpaperActivity;
import android.os.Debug;
import android.os.SystemProperties;
@@ -141,7 +142,8 @@
final boolean isVisible = visibleTasksCount > 0;
mVisibleDesktopTasksCount = visibleTasksCount;
- if (wasVisible != isVisible) {
+ if (!enableDesktopWindowingWallpaperActivity() && wasVisible != isVisible) {
+ // TODO: b/333533253 - Remove after flag rollout
if (mVisibleDesktopTasksCount > 0) {
setLauncherViewsVisibility(View.INVISIBLE);
if (!mInOverviewState) {
@@ -178,6 +180,10 @@
}
if (overviewStateEnabled != mInOverviewState) {
mInOverviewState = overviewStateEnabled;
+ if (enableDesktopWindowingWallpaperActivity()) {
+ return;
+ }
+ // TODO: b/333533253 - Clean up after flag rollout
if (mInOverviewState) {
setLauncherViewsVisibility(View.VISIBLE);
markLauncherResumed();
@@ -190,6 +196,9 @@
}
}
+ /**
+ * TODO: b/333533253 - Remove after flag rollout
+ */
private void setBackgroundStateEnabled(boolean backgroundStateEnabled) {
if (DEBUG) {
Log.d(TAG, "setBackgroundStateEnabled: enabled=" + backgroundStateEnabled
@@ -210,6 +219,8 @@
/**
* Whether recents gesture is currently in progress.
+ *
+ * TODO: b/333533253 - Remove after flag rollout
*/
public boolean isRecentsGestureInProgress() {
return mGestureInProgress;
@@ -217,6 +228,8 @@
/**
* Notify controller that recents gesture has started.
+ *
+ * TODO: b/333533253 - Remove after flag rollout
*/
public void setRecentsGestureStart() {
if (DEBUG) {
@@ -228,6 +241,8 @@
/**
* Notify controller that recents gesture finished with the given
* {@link com.android.quickstep.GestureState.GestureEndTarget}
+ *
+ * TODO: b/333533253 - Remove after flag rollout
*/
public void setRecentsGestureEnd(@Nullable GestureState.GestureEndTarget endTarget) {
if (DEBUG) {
@@ -241,6 +256,9 @@
}
}
+ /**
+ * TODO: b/333533253 - Remove after flag rollout
+ */
private void setRecentsGestureInProgress(boolean gestureInProgress) {
if (gestureInProgress != mGestureInProgress) {
mGestureInProgress = gestureInProgress;
@@ -256,7 +274,13 @@
}
}
+ /**
+ * TODO: b/333533253 - Remove after flag rollout
+ */
private void setLauncherViewsVisibility(int visibility) {
+ if (enableDesktopWindowingWallpaperActivity()) {
+ return;
+ }
if (DEBUG) {
Log.d(TAG, "setLauncherViewsVisibility: visibility=" + visibility + " "
+ Debug.getCaller());
@@ -275,7 +299,13 @@
}
}
+ /**
+ * TODO: b/333533253 - Remove after flag rollout
+ */
private void markLauncherPaused() {
+ if (enableDesktopWindowingWallpaperActivity()) {
+ return;
+ }
if (DEBUG) {
Log.d(TAG, "markLauncherPaused " + Debug.getCaller());
}
@@ -286,7 +316,13 @@
}
}
+ /**
+ * TODO: b/333533253 - Remove after flag rollout
+ */
private void markLauncherResumed() {
+ if (enableDesktopWindowingWallpaperActivity()) {
+ return;
+ }
if (DEBUG) {
Log.d(TAG, "markLauncherResumed " + Debug.getCaller());
}
diff --git a/quickstep/src/com/android/launcher3/taskbar/KeyboardQuickSwitchView.java b/quickstep/src/com/android/launcher3/taskbar/KeyboardQuickSwitchView.java
index 2d9e236..a5383f5 100644
--- a/quickstep/src/com/android/launcher3/taskbar/KeyboardQuickSwitchView.java
+++ b/quickstep/src/com/android/launcher3/taskbar/KeyboardQuickSwitchView.java
@@ -362,8 +362,9 @@
OPEN_OUTLINE_INTERPOLATOR));
}
});
- animateFocusMove(-1, currentFocusIndexOverride == -1
- ? Math.min(mContent.getChildCount(), 1) : currentFocusIndexOverride);
+ animateFocusMove(-1, Math.min(
+ mContent.getChildCount() - 1,
+ currentFocusIndexOverride == -1 ? 1 : currentFocusIndexOverride));
displayedContent.setVisibility(VISIBLE);
setVisibility(VISIBLE);
requestFocus();
diff --git a/quickstep/src/com/android/launcher3/taskbar/LauncherTaskbarUIController.java b/quickstep/src/com/android/launcher3/taskbar/LauncherTaskbarUIController.java
index 81f2c0f..489102f 100644
--- a/quickstep/src/com/android/launcher3/taskbar/LauncherTaskbarUIController.java
+++ b/quickstep/src/com/android/launcher3/taskbar/LauncherTaskbarUIController.java
@@ -21,6 +21,7 @@
import static com.android.launcher3.taskbar.TaskbarEduTooltipControllerKt.TOOLTIP_STEP_FEATURES;
import static com.android.launcher3.taskbar.TaskbarLauncherStateController.FLAG_VISIBLE;
import static com.android.quickstep.TaskAnimationManager.ENABLE_SHELL_TRANSITIONS;
+import static com.android.window.flags.Flags.enableDesktopWindowingWallpaperActivity;
import android.animation.Animator;
import android.animation.AnimatorSet;
@@ -218,9 +219,10 @@
DesktopVisibilityController desktopController =
LauncherActivityInterface.INSTANCE.getDesktopVisibilityController();
- final boolean onDesktop =
- desktopController != null && desktopController.areDesktopTasksVisible();
- if (onDesktop) {
+ if (!enableDesktopWindowingWallpaperActivity()
+ && desktopController != null
+ && desktopController.areDesktopTasksVisible()) {
+ // TODO: b/333533253 - Remove after flag rollout
isVisible = false;
}
diff --git a/quickstep/src/com/android/launcher3/taskbar/TaskbarLauncherStateController.java b/quickstep/src/com/android/launcher3/taskbar/TaskbarLauncherStateController.java
index 17dcace..ee21eac 100644
--- a/quickstep/src/com/android/launcher3/taskbar/TaskbarLauncherStateController.java
+++ b/quickstep/src/com/android/launcher3/taskbar/TaskbarLauncherStateController.java
@@ -837,6 +837,7 @@
appendFlag(result, flags, FLAG_LAUNCHER_WAS_ACTIVE_WHILE_AWAKE,
"was_active_while_awake");
appendFlag(result, flags, FLAG_DEVICE_LOCKED, "device_locked");
+ appendFlag(result, flags, FLAG_TASKBAR_HIDDEN, "taskbar_hidden");
return result.toString();
}
diff --git a/quickstep/src/com/android/launcher3/taskbar/TaskbarStashController.java b/quickstep/src/com/android/launcher3/taskbar/TaskbarStashController.java
index 15be8e7..41c0586 100644
--- a/quickstep/src/com/android/launcher3/taskbar/TaskbarStashController.java
+++ b/quickstep/src/com/android/launcher3/taskbar/TaskbarStashController.java
@@ -1165,6 +1165,7 @@
appendFlag(sj, flags, FLAG_STASHED_IN_APP_AUTO, "FLAG_STASHED_IN_APP_AUTO");
appendFlag(sj, flags, FLAG_STASHED_SYSUI, "FLAG_STASHED_SYSUI");
appendFlag(sj, flags, FLAG_STASHED_DEVICE_LOCKED, "FLAG_STASHED_DEVICE_LOCKED");
+ appendFlag(sj, flags, FLAG_IN_OVERVIEW, "FLAG_IN_OVERVIEW");
return sj.toString();
}
diff --git a/quickstep/src/com/android/launcher3/taskbar/allapps/TaskbarAllAppsSlideInView.java b/quickstep/src/com/android/launcher3/taskbar/allapps/TaskbarAllAppsSlideInView.java
index 6ceec3e..8e05686 100644
--- a/quickstep/src/com/android/launcher3/taskbar/allapps/TaskbarAllAppsSlideInView.java
+++ b/quickstep/src/com/android/launcher3/taskbar/allapps/TaskbarAllAppsSlideInView.java
@@ -207,13 +207,6 @@
}
@Override
- protected void onUserSwipeToDismissProgressChanged() {
- super.onUserSwipeToDismissProgressChanged();
- mAppsView.setClipChildren(!mIsDismissInProgress);
- mAppsView.getAppsRecyclerViewContainer().setClipChildren(!mIsDismissInProgress);
- }
-
- @Override
protected void onLayout(boolean changed, int l, int t, int r, int b) {
super.onLayout(changed, l, t, r, b);
setTranslationShift(mTranslationShift);
@@ -259,12 +252,28 @@
return getPopupContainer().isEventOverView(mAppsView.getVisibleContainerView(), ev);
}
+ /**
+ * In taskbar all apps search mode, we should scale down content inside all apps, rather
+ * than the whole all apps bottom sheet, to indicate we will navigate back within the all apps.
+ */
+ @Override
+ public boolean shouldAnimateContentViewInBackSwipe() {
+ return mAllAppsCallbacks.canHandleSearchBackInvoked();
+ }
+
+ @Override
+ protected void onUserSwipeToDismissProgressChanged() {
+ super.onUserSwipeToDismissProgressChanged();
+ mAppsView.setClipChildren(!mIsDismissInProgress);
+ mAppsView.getAppsRecyclerViewContainer().setClipChildren(!mIsDismissInProgress);
+ }
+
@Override
public void onBackInvoked() {
if (mAllAppsCallbacks.handleSearchBackInvoked()) {
// We need to scale back taskbar all apps if we navigate back within search inside all
// apps
- animateSwipeToDismissProgressToStart();
+ post(this::animateSwipeToDismissProgressToStart);
} else {
super.onBackInvoked();
}
diff --git a/quickstep/src/com/android/launcher3/taskbar/allapps/TaskbarAllAppsViewController.java b/quickstep/src/com/android/launcher3/taskbar/allapps/TaskbarAllAppsViewController.java
index ba4fa45..52f7176 100644
--- a/quickstep/src/com/android/launcher3/taskbar/allapps/TaskbarAllAppsViewController.java
+++ b/quickstep/src/com/android/launcher3/taskbar/allapps/TaskbarAllAppsViewController.java
@@ -143,6 +143,11 @@
}
}
+ /** Check if search session can handle back. This check doesn't perform any action. */
+ boolean canHandleSearchBackInvoked() {
+ return mSearchSessionController.canHandleBackInvoked();
+ }
+
/** Invoked on back press, returning {@code true} if the search session handled it. */
boolean handleSearchBackInvoked() {
return mSearchSessionController.handleBackInvoked();
diff --git a/quickstep/src/com/android/launcher3/taskbar/allapps/TaskbarSearchSessionController.kt b/quickstep/src/com/android/launcher3/taskbar/allapps/TaskbarSearchSessionController.kt
index 3d15fbd..4d0b376 100644
--- a/quickstep/src/com/android/launcher3/taskbar/allapps/TaskbarSearchSessionController.kt
+++ b/quickstep/src/com/android/launcher3/taskbar/allapps/TaskbarSearchSessionController.kt
@@ -49,6 +49,8 @@
/** Creates a [PreDragCondition] for [view], if it is a search result that requires one. */
open fun createPreDragConditionForSearch(view: View): PreDragCondition? = null
+ open fun canHandleBackInvoked(): Boolean = false
+
open fun handleBackInvoked(): Boolean = false
open fun onAllAppsAnimationPending(
diff --git a/quickstep/src/com/android/launcher3/taskbar/bubbles/BubbleBarBackground.kt b/quickstep/src/com/android/launcher3/taskbar/bubbles/BubbleBarBackground.kt
index 8eeb055..9799349 100644
--- a/quickstep/src/com/android/launcher3/taskbar/bubbles/BubbleBarBackground.kt
+++ b/quickstep/src/com/android/launcher3/taskbar/bubbles/BubbleBarBackground.kt
@@ -31,7 +31,7 @@
import com.android.wm.shell.common.TriangleShape
/** Drawable for the background of the bubble bar. */
-class BubbleBarBackground(context: Context, private val backgroundHeight: Float) : Drawable() {
+class BubbleBarBackground(context: Context, private var backgroundHeight: Float) : Drawable() {
private val DARK_THEME_SHADOW_ALPHA = 51f
private val LIGHT_THEME_SHADOW_ALPHA = 25f
@@ -171,4 +171,8 @@
fun setArrowAlpha(alpha: Int) {
arrowDrawable.paint.alpha = alpha
}
+
+ fun setHeight(newHeight: Float) {
+ backgroundHeight = newHeight
+ }
}
diff --git a/quickstep/src/com/android/launcher3/taskbar/bubbles/BubbleBarController.java b/quickstep/src/com/android/launcher3/taskbar/bubbles/BubbleBarController.java
index a2c1b07..981c9f9 100644
--- a/quickstep/src/com/android/launcher3/taskbar/bubbles/BubbleBarController.java
+++ b/quickstep/src/com/android/launcher3/taskbar/bubbles/BubbleBarController.java
@@ -313,8 +313,11 @@
|| (!update.expandedChanged && !mBubbleBarViewController.isExpanded());
final boolean isExpanding = update.expandedChanged && update.expanded;
// don't animate bubbles if this is the initial state because we may be unfolding or
- // enabling gesture nav
- final boolean suppressAnimation = update.initialState;
+ // enabling gesture nav. also suppress animation if the bubble bar is hidden for sysui e.g.
+ // the shade is open, or we're locked.
+ final boolean suppressAnimation =
+ update.initialState || mBubbleBarViewController.isHiddenForSysui();
+
BubbleBarItem previouslySelectedBubble = mSelectedBubble;
BubbleBarBubble bubbleToSelect = null;
if (!update.removedBubbles.isEmpty()) {
diff --git a/quickstep/src/com/android/launcher3/taskbar/bubbles/BubbleBarView.java b/quickstep/src/com/android/launcher3/taskbar/bubbles/BubbleBarView.java
index 711ba62..1003c3f 100644
--- a/quickstep/src/com/android/launcher3/taskbar/bubbles/BubbleBarView.java
+++ b/quickstep/src/com/android/launcher3/taskbar/bubbles/BubbleBarView.java
@@ -106,10 +106,12 @@
private final Rect mBubbleBarBounds = new Rect();
// The amount the bubbles overlap when they are stacked in the bubble bar
private final float mIconOverlapAmount;
- // The spacing between the bubbles when they are expanded in the bubble bar
- private final float mIconSpacing;
+ // The spacing between the bubbles when bubble bar is expanded
+ private final float mExpandedBarIconsSpacing;
+ // The spacing between the bubbles and the borders of the bubble bar
+ private float mBubbleBarPadding;
// The size of a bubble in the bar
- private final float mIconSize;
+ private float mIconSize;
// The elevation of the bubbles within the bar
private final float mBubbleElevation;
private final float mDragElevation;
@@ -169,16 +171,17 @@
setAlpha(0);
setVisibility(INVISIBLE);
mIconOverlapAmount = getResources().getDimensionPixelSize(R.dimen.bubblebar_icon_overlap);
- mIconSpacing = getResources().getDimensionPixelSize(R.dimen.bubblebar_icon_spacing);
+ mBubbleBarPadding = getResources().getDimensionPixelSize(R.dimen.bubblebar_icon_spacing);
mIconSize = getResources().getDimensionPixelSize(R.dimen.bubblebar_icon_size);
+ mExpandedBarIconsSpacing = getResources().getDimensionPixelSize(
+ R.dimen.bubblebar_expanded_icon_spacing);
mBubbleElevation = getResources().getDimensionPixelSize(R.dimen.bubblebar_icon_elevation);
mDragElevation = getResources().getDimensionPixelSize(R.dimen.bubblebar_drag_elevation);
mPointerSize = getResources().getDimensionPixelSize(R.dimen.bubblebar_pointer_size);
setClipToPadding(false);
- mBubbleBarBackground = new BubbleBarBackground(context,
- getResources().getDimensionPixelSize(R.dimen.bubblebar_size));
+ mBubbleBarBackground = new BubbleBarBackground(context, getBubbleBarHeight());
setBackgroundDrawable(mBubbleBarBackground);
mWidthAnimator.setDuration(WIDTH_ANIMATION_DURATION_MS);
@@ -219,6 +222,29 @@
});
}
+ /**
+ * Sets new icon size and spacing between icons and bubble bar borders.
+ *
+ * @param newIconSize new icon size
+ * @param spacing spacing between icons and bubble bar borders.
+ */
+ // TODO(b/335575529): animate bubble bar icons size change
+ public void setIconSizeAndPadding(float newIconSize, float spacing) {
+ // TODO(b/335457839): handle new bubble animation during the size change
+ mBubbleBarPadding = spacing;
+ mIconSize = newIconSize;
+ int childCount = getChildCount();
+ for (int i = 0; i < childCount; i++) {
+ View childView = getChildAt(i);
+ FrameLayout.LayoutParams params = (LayoutParams) childView.getLayoutParams();
+ params.height = (int) mIconSize;
+ params.width = (int) mIconSize;
+ childView.setLayoutParams(params);
+ }
+ mBubbleBarBackground.setHeight(getBubbleBarHeight());
+ updateLayoutParams();
+ }
+
@Override
protected void onLayout(boolean changed, int left, int top, int right, int bottom) {
super.onLayout(changed, left, top, right, bottom);
@@ -516,6 +542,13 @@
setLayoutParams(lp);
}
+ private void updateLayoutParams() {
+ LayoutParams lp = (FrameLayout.LayoutParams) getLayoutParams();
+ lp.height = getBubbleBarHeight();
+ lp.width = (int) (mIsBarExpanded ? expandedWidth() : collapsedWidth());
+ setLayoutParams(lp);
+ }
+
/** @return the horizontal margin between the bubble bar and the edge of the screen. */
int getHorizontalMargin() {
LayoutParams lp = (FrameLayout.LayoutParams) getLayoutParams();
@@ -551,12 +584,12 @@
final float collapsedX;
if (onLeft) {
// If bar is on the left, bubbles are ordered right to left
- expandedX = (bubbleCount - i - 1) * (mIconSize + mIconSpacing);
+ expandedX = (bubbleCount - i - 1) * (mIconSize + mExpandedBarIconsSpacing);
// Shift the first bubble only if there are more bubbles in addition to overflow
collapsedX = i == 0 && bubbleCount > 2 ? mIconOverlapAmount : 0;
} else {
// Bubbles ordered left to right, don't move the first bubble
- expandedX = i * (mIconSize + mIconSpacing);
+ expandedX = i * (mIconSize + mExpandedBarIconsSpacing);
collapsedX = i == 0 ? 0 : mIconOverlapAmount;
}
@@ -599,14 +632,14 @@
final float interpolatedWidth =
widthState * (expandedWidth - collapsedWidth) + collapsedWidth;
final float arrowPosition;
+
+ float interpolatedShift = (expandedArrowPosition - collapsedArrowPosition) * widthState;
if (onLeft) {
- float interpolatedShift = (expandedArrowPosition - collapsedArrowPosition) * widthState;
arrowPosition = collapsedArrowPosition + interpolatedShift;
} else {
if (mIsBarExpanded) {
- // when the bar is expanding, the selected bubble is always the first, so the arrow
- // always shifts with the interpolated width.
- arrowPosition = currentWidth - interpolatedWidth + collapsedArrowPosition;
+ arrowPosition = currentWidth - interpolatedWidth + collapsedArrowPosition
+ + interpolatedShift;
} else {
final float targetPosition = currentWidth - collapsedWidth + collapsedArrowPosition;
arrowPosition =
@@ -709,7 +742,8 @@
} else {
bubblePosition = index;
}
- return getPaddingStart() + bubblePosition * (mIconSize + mIconSpacing) + mIconSize / 2f;
+ return getPaddingStart() + bubblePosition * (mIconSize + mExpandedBarIconsSpacing)
+ + mIconSize / 2f;
}
private float arrowPositionForSelectedWhenCollapsed() {
@@ -770,7 +804,9 @@
public float expandedWidth() {
final int childCount = getChildCount();
final int horizontalPadding = getPaddingStart() + getPaddingEnd();
- return childCount * (mIconSize + mIconSpacing) + horizontalPadding;
+ // spaces amount is less than child count by 1, or 0 if no child views
+ int spacesCount = Math.max(childCount - 1, 0);
+ return childCount * mIconSize + spacesCount * mExpandedBarIconsSpacing + horizontalPadding;
}
private float collapsedWidth() {
@@ -783,6 +819,10 @@
: mIconSize + horizontalPadding;
}
+ private int getBubbleBarHeight() {
+ return (int) (mIconSize + mBubbleBarPadding * 2 + mPointerSize);
+ }
+
/**
* Returns whether the given MotionEvent, *in screen coordinates*, is within bubble bar
* touch bounds.
diff --git a/quickstep/src/com/android/launcher3/taskbar/bubbles/BubbleBarViewController.java b/quickstep/src/com/android/launcher3/taskbar/bubbles/BubbleBarViewController.java
index aa1b4df..a1a2898 100644
--- a/quickstep/src/com/android/launcher3/taskbar/bubbles/BubbleBarViewController.java
+++ b/quickstep/src/com/android/launcher3/taskbar/bubbles/BubbleBarViewController.java
@@ -18,9 +18,12 @@
import static android.view.View.INVISIBLE;
import static android.view.View.VISIBLE;
+import android.content.res.Resources;
import android.graphics.Point;
import android.graphics.Rect;
+import android.util.DisplayMetrics;
import android.util.Log;
+import android.util.TypedValue;
import android.view.Gravity;
import android.view.MotionEvent;
import android.view.View;
@@ -52,12 +55,13 @@
public class BubbleBarViewController {
private static final String TAG = BubbleBarViewController.class.getSimpleName();
-
+ private static final float APP_ICON_SMALL_DP = 44f;
+ private static final float APP_ICON_MEDIUM_DP = 48f;
+ private static final float APP_ICON_LARGE_DP = 52f;
private final SystemUiProxy mSystemUiProxy;
private final TaskbarActivityContext mActivity;
private final BubbleBarView mBarView;
- private final int mIconSize;
- private final int mPointerSize;
+ private int mIconSize;
// Initialized in init.
private BubbleStashController mBubbleStashController;
@@ -96,9 +100,8 @@
mSystemUiProxy = SystemUiProxy.INSTANCE.get(mActivity);
mBubbleBarAlpha = new MultiValueAlpha(mBarView, 1 /* num alpha channels */);
mBubbleBarAlpha.setUpdateVisibility(true);
- mIconSize = activity.getResources().getDimensionPixelSize(R.dimen.bubblebar_icon_size);
- mPointerSize = activity.getResources().getDimensionPixelSize(
- R.dimen.bubblebar_pointer_size);
+ mIconSize = activity.getResources().getDimensionPixelSize(
+ R.dimen.bubblebar_icon_size);
}
public void init(TaskbarControllers controllers, BubbleControllers bubbleControllers) {
@@ -108,12 +111,8 @@
mTaskbarStashController = controllers.taskbarStashController;
mTaskbarInsetsController = controllers.taskbarInsetsController;
- mActivity.addOnDeviceProfileChangeListener(dp ->
- mBarView.getLayoutParams().height =
- mActivity.getDeviceProfile().taskbarHeight + mPointerSize
- );
- mBarView.getLayoutParams().height =
- mActivity.getDeviceProfile().taskbarHeight + mPointerSize;
+ mActivity.addOnDeviceProfileChangeListener(dp -> setBubbleBarIconSize(dp.taskbarIconSize));
+ setBubbleBarIconSize(mActivity.getDeviceProfile().taskbarIconSize);
mBubbleBarScale.updateValue(1f);
mBubbleClickListener = v -> onBubbleClicked(v);
mBubbleBarClickListener = v -> onBubbleBarClicked();
@@ -260,12 +259,44 @@
}
}
+ private void setBubbleBarIconSize(int newIconSize) {
+ if (newIconSize == mIconSize) {
+ return;
+ }
+ Resources res = mActivity.getResources();
+ DisplayMetrics dm = res.getDisplayMetrics();
+ float smallIconSize = TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP,
+ APP_ICON_SMALL_DP, dm);
+ float mediumIconSize = TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP,
+ APP_ICON_MEDIUM_DP, dm);
+ float largeIconSize = TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP,
+ APP_ICON_LARGE_DP, dm);
+ float smallMediumThreshold = (smallIconSize + mediumIconSize) / 2f;
+ float mediumLargeThreshold = (mediumIconSize + largeIconSize) / 2f;
+ mIconSize = newIconSize <= smallMediumThreshold
+ ? res.getDimensionPixelSize(R.dimen.bubblebar_icon_size_small) :
+ res.getDimensionPixelSize(R.dimen.bubblebar_icon_size);
+ float bubbleBarPadding = newIconSize >= mediumLargeThreshold
+ ? res.getDimensionPixelSize(R.dimen.bubblebar_icon_spacing_large) :
+ res.getDimensionPixelSize(R.dimen.bubblebar_icon_spacing);
+
+ mBarView.setIconSizeAndPadding(mIconSize, bubbleBarPadding);
+ mBarView.setPadding((int) bubbleBarPadding, mBarView.getPaddingTop(),
+ (int) bubbleBarPadding,
+ mBarView.getPaddingBottom());
+ }
+
/** Sets a callback that updates the selected bubble after the bubble bar collapses. */
public void setUpdateSelectedBubbleAfterCollapse(
Consumer<String> updateSelectedBubbleAfterCollapse) {
mBarView.setUpdateSelectedBubbleAfterCollapse(updateSelectedBubbleAfterCollapse);
}
+ /** Returns whether the bubble bar should be hidden because of the current sysui state. */
+ boolean isHiddenForSysui() {
+ return mHiddenForSysui;
+ }
+
/**
* Sets whether the bubble bar should be hidden due to SysUI state (e.g. on lockscreen).
*/
diff --git a/quickstep/src/com/android/launcher3/taskbar/bubbles/BubbleStashController.java b/quickstep/src/com/android/launcher3/taskbar/bubbles/BubbleStashController.java
index 61a2e22..76d86de 100644
--- a/quickstep/src/com/android/launcher3/taskbar/bubbles/BubbleStashController.java
+++ b/quickstep/src/com/android/launcher3/taskbar/bubbles/BubbleStashController.java
@@ -23,6 +23,7 @@
import android.annotation.Nullable;
import android.view.InsetsController;
import android.view.MotionEvent;
+import android.view.View;
import com.android.launcher3.anim.AnimatedFloat;
import com.android.launcher3.taskbar.StashedHandleViewController;
@@ -32,6 +33,7 @@
import com.android.launcher3.taskbar.TaskbarStashController;
import com.android.launcher3.util.MultiPropertyFactory;
import com.android.wm.shell.common.bubbles.BubbleBarLocation;
+import com.android.wm.shell.shared.animation.PhysicsAnimator;
/**
* Coordinates between controllers such as BubbleBarView and BubbleHandleViewController to
@@ -51,15 +53,6 @@
*/
private static final float STASHED_BAR_SCALE = 0.5f;
- /** The duration of hiding and showing the stashed handle as part of a new bubble animation. */
- private static final long NEW_BUBBLE_HANDLE_ANIMATION_DURATION_MS = 200;
-
- /** The translation Y value the handle animates to when hiding it for a new bubble. */
- private static final int NEW_BUBBLE_HIDE_HANDLE_ANIMATION_TRANSLATION_Y = -20;
-
- /** The alpha value the handle animates to when hiding it for a new bubble. */
- public static final float NEW_BUBBLE_HIDE_HANDLE_ANIMATION_ALPHA = 0.5f;
-
protected final TaskbarActivityContext mActivity;
// Initialized in init.
@@ -73,7 +66,6 @@
private AnimatedFloat mIconScaleForStash;
private AnimatedFloat mIconTranslationYForStash;
private MultiPropertyFactory.MultiProperty mBubbleStashedHandleAlpha;
- private AnimatedFloat mBubbleStashedHandleTranslationY;
private boolean mRequestedStashState;
private boolean mRequestedExpandedState;
@@ -105,7 +97,6 @@
mBubbleStashedHandleAlpha = mHandleViewController.getStashedHandleAlpha().get(
StashedHandleViewController.ALPHA_INDEX_STASHED);
- mBubbleStashedHandleTranslationY = mHandleViewController.getStashedHandleTranslationY();
mStashedHeight = mHandleViewController.getStashedHeight();
mUnstashedHeight = mHandleViewController.getUnstashedHeight();
@@ -379,29 +370,8 @@
return mHandleViewController.getStashedHandleCenterX();
}
- /** Returns the animation for hiding the handle before a new bubble animates in. */
- public AnimatorSet buildHideHandleAnimationForNewBubble() {
- AnimatorSet animatorSet = new AnimatorSet();
- animatorSet.playTogether(
- mBubbleStashedHandleTranslationY.animateToValue(
- NEW_BUBBLE_HIDE_HANDLE_ANIMATION_TRANSLATION_Y),
- mBubbleStashedHandleAlpha.animateToValue(NEW_BUBBLE_HIDE_HANDLE_ANIMATION_ALPHA));
- animatorSet.setDuration(NEW_BUBBLE_HANDLE_ANIMATION_DURATION_MS);
- return animatorSet;
- }
-
- /** Sets the alpha value of the stashed handle. */
- public void setStashAlpha(float alpha) {
- mBubbleStashedHandleAlpha.setValue(alpha);
- }
-
- /** Returns the animation for showing the handle after a new bubble animated in. */
- public AnimatorSet buildShowHandleAnimationForNewBubble() {
- AnimatorSet animatorSet = new AnimatorSet();
- animatorSet.playTogether(
- mBubbleStashedHandleTranslationY.animateToValue(0),
- mBubbleStashedHandleAlpha.animateToValue(1));
- animatorSet.setDuration(NEW_BUBBLE_HANDLE_ANIMATION_DURATION_MS);
- return animatorSet;
+ /** Returns the [PhysicsAnimator] for the stashed handle view. */
+ public PhysicsAnimator<View> getStashedHandlePhysicsAnimator() {
+ return mHandleViewController.getPhysicsAnimator();
}
}
diff --git a/quickstep/src/com/android/launcher3/taskbar/bubbles/BubbleStashedHandleViewController.java b/quickstep/src/com/android/launcher3/taskbar/bubbles/BubbleStashedHandleViewController.java
index 2a5912a..6f1a093 100644
--- a/quickstep/src/com/android/launcher3/taskbar/bubbles/BubbleStashedHandleViewController.java
+++ b/quickstep/src/com/android/launcher3/taskbar/bubbles/BubbleStashedHandleViewController.java
@@ -29,7 +29,6 @@
import android.view.ViewOutlineProvider;
import com.android.launcher3.R;
-import com.android.launcher3.anim.AnimatedFloat;
import com.android.launcher3.anim.RevealOutlineAnimation;
import com.android.launcher3.anim.RoundedRectRevealOutlineProvider;
import com.android.launcher3.taskbar.StashedHandleView;
@@ -40,6 +39,7 @@
import com.android.launcher3.util.MultiValueAlpha;
import com.android.systemui.shared.navigationbar.RegionSamplingHelper;
import com.android.wm.shell.common.bubbles.BubbleBarLocation;
+import com.android.wm.shell.shared.animation.PhysicsAnimator;
/**
* Handles properties/data collection, then passes the results to our stashed handle View to render.
@@ -59,12 +59,6 @@
private int mStashedHandleWidth;
private int mStashedHandleHeight;
- private final AnimatedFloat mStashedHandleTranslationY =
- new AnimatedFloat(this::updateTranslationY);
-
- // Modified when swipe up is happening on the stashed handle or task bar.
- private float mSwipeUpTranslationY;
-
// The bounds we want to clip to in the settled state when showing the stashed handle.
private final Rect mStashedHandleBounds = new Rect();
@@ -129,6 +123,11 @@
updateBounds(mBarViewController.getBubbleBarLocation()));
}
+ /** Returns the [PhysicsAnimator] for the stashed handle view. */
+ public PhysicsAnimator<View> getPhysicsAnimator() {
+ return PhysicsAnimator.getInstance(mStashedHandleView);
+ }
+
private void updateBounds(BubbleBarLocation bubbleBarLocation) {
// As more bubbles get added, the icon bounds become larger. To ensure a consistent
// handle bar position, we pin it to the edge of the screen.
@@ -238,21 +237,11 @@
}
}
- /** Returns an animator for translation Y. */
- public AnimatedFloat getStashedHandleTranslationY() {
- return mStashedHandleTranslationY;
- }
-
/**
* Sets the translation of the stashed handle during the swipe up gesture.
*/
public void setTranslationYForSwipe(float transY) {
- mSwipeUpTranslationY = transY;
- updateTranslationY();
- }
-
- private void updateTranslationY() {
- mStashedHandleView.setTranslationY(mStashedHandleTranslationY.value + mSwipeUpTranslationY);
+ mStashedHandleView.setTranslationY(transY);
}
/**
diff --git a/quickstep/src/com/android/launcher3/taskbar/bubbles/OWNERS b/quickstep/src/com/android/launcher3/taskbar/bubbles/OWNERS
index edabae2..3f947a0 100644
--- a/quickstep/src/com/android/launcher3/taskbar/bubbles/OWNERS
+++ b/quickstep/src/com/android/launcher3/taskbar/bubbles/OWNERS
@@ -1,3 +1,5 @@
atsjenk@google.com
liranb@google.com
madym@google.com
+mpodolian@google.com
+
diff --git a/quickstep/src/com/android/launcher3/taskbar/bubbles/animation/BubbleBarViewAnimator.kt b/quickstep/src/com/android/launcher3/taskbar/bubbles/animation/BubbleBarViewAnimator.kt
index 1db5103..2d8983f 100644
--- a/quickstep/src/com/android/launcher3/taskbar/bubbles/animation/BubbleBarViewAnimator.kt
+++ b/quickstep/src/com/android/launcher3/taskbar/bubbles/animation/BubbleBarViewAnimator.kt
@@ -18,16 +18,12 @@
import android.view.View
import android.view.View.VISIBLE
-import androidx.core.animation.AnimatorSet
-import androidx.core.animation.ObjectAnimator
-import androidx.core.animation.doOnEnd
import androidx.dynamicanimation.animation.DynamicAnimation
import androidx.dynamicanimation.animation.SpringForce
import com.android.launcher3.taskbar.bubbles.BubbleBarBubble
import com.android.launcher3.taskbar.bubbles.BubbleBarView
import com.android.launcher3.taskbar.bubbles.BubbleStashController
import com.android.launcher3.taskbar.bubbles.BubbleView
-import com.android.systemui.util.doOnEnd
import com.android.wm.shell.shared.animation.PhysicsAnimator
/** Handles animations for bubble bar bubbles. */
@@ -43,17 +39,19 @@
/** The time to show the flyout. */
const val FLYOUT_DELAY_MS: Long = 2500
/** The translation Y the new bubble will animate to. */
- const val BUBBLE_ANIMATION_FINAL_TRANSLATION_Y = -50f
+ const val BUBBLE_ANIMATION_BUBBLE_TRANSLATION_Y = -50f
/** The initial translation Y value the new bubble is set to before the animation starts. */
// TODO(liranb): get rid of this and calculate this based on the y-distance between the
// bubble and the stash handle.
- const val BUBBLE_ANIMATION_INITIAL_TRANSLATION_Y = 50f
+ const val BUBBLE_ANIMATION_TRANSLATION_Y_OFFSET = 50f
/** The initial scale Y value that the new bubble is set to before the animation starts. */
const val BUBBLE_ANIMATION_INITIAL_SCALE_Y = 0.3f
- /** The initial alpha value that the new bubble is set to before the animation starts. */
- const val BUBBLE_ANIMATION_INITIAL_ALPHA = 0.5f
- /** The duration of the hide bubble animation. */
- const val HIDE_BUBBLE_ANIMATION_DURATION_MS = 250L
+ /**
+ * The distance the stashed handle will travel as it gets hidden as part of the new bubble
+ * animation.
+ */
+ // TODO(liranb): calculate this based on the position of the views
+ const val BUBBLE_ANIMATION_STASH_HANDLE_TRANSLATION_Y = -20f
}
/** An interface for scheduling jobs. */
@@ -91,7 +89,7 @@
if (animator.isRunning()) animator.cancel()
// the animation of a new bubble is divided into 2 parts. The first part shows the bubble
// and the second part hides it after a delay.
- val showAnimation = buildShowAnimation(bubbleView, b.key, animator)
+ val showAnimation = buildShowAnimation(bubbleView, b.key)
val hideAnimation = buildHideAnimation(bubbleView)
scheduler.post(showAnimation)
scheduler.postDelayed(FLYOUT_DELAY_MS, hideAnimation)
@@ -100,71 +98,139 @@
/**
* Returns a lambda that starts the animation that shows the new bubble.
*
- * The animation is divided into 2 parts. First the stash handle starts animating up and fades
- * out. When it ends the bubble starts fading in. The bubble and stashed handle are aligned to
- * give the impression of the stash handle morphing into the bubble.
+ * Visually, the animation is divided into 2 parts. The stash handle starts animating up and
+ * fading out and then the bubble starts animating up and fading in.
+ *
+ * To make the transition from the handle to the bubble smooth, the positions and movement of
+ * the 2 views must be synchronized. To do that we use a single spring path along the Y axis,
+ * starting from the handle's position to the eventual bubble's position. The path is split into
+ * 3 parts.
+ * 1. In the first part, we only animate the handle.
+ * 1. In the second part the handle is fully hidden, and the bubble is animating in.
+ * 1. The third part is the overshoot of the spring animation, where we make the bubble fully
+ * visible which helps avoiding further updates when we re-enter the second part.
*/
private fun buildShowAnimation(
bubbleView: BubbleView,
key: String,
- bubbleAnimator: PhysicsAnimator<BubbleView>
): () -> Unit = {
+ bubbleBarView.prepareForAnimatingBubbleWhileStashed(key)
// calculate the initial translation x the bubble should have in order to align it with the
// stash handle.
val initialTranslationX =
bubbleStashController.stashedHandleCenterX - bubbleView.centerXOnScreen
- bubbleBarView.prepareForAnimatingBubbleWhileStashed(key)
- bubbleAnimator.setDefaultSpringConfig(springConfig)
- bubbleAnimator
- .spring(DynamicAnimation.ALPHA, 1f)
- .spring(DynamicAnimation.TRANSLATION_Y, BUBBLE_ANIMATION_FINAL_TRANSLATION_Y)
- .spring(DynamicAnimation.SCALE_Y, 1f)
// prepare the bubble for the animation
bubbleView.alpha = 0f
bubbleView.translationX = initialTranslationX
- bubbleView.translationY = BUBBLE_ANIMATION_INITIAL_TRANSLATION_Y
bubbleView.scaleY = BUBBLE_ANIMATION_INITIAL_SCALE_Y
bubbleView.visibility = VISIBLE
- // start the stashed handle animation. when it ends, start the bubble animation.
- val stashedHandleAnimation = bubbleStashController.buildHideHandleAnimationForNewBubble()
- stashedHandleAnimation.doOnEnd {
- bubbleView.alpha = BUBBLE_ANIMATION_INITIAL_ALPHA
- bubbleAnimator.start()
- bubbleStashController.setStashAlpha(0f)
+
+ // this is the total distance that both the stashed handle and the bubble will be traveling
+ val totalTranslationY =
+ BUBBLE_ANIMATION_BUBBLE_TRANSLATION_Y + BUBBLE_ANIMATION_STASH_HANDLE_TRANSLATION_Y
+ val animator = bubbleStashController.stashedHandlePhysicsAnimator
+ animator.setDefaultSpringConfig(springConfig)
+ animator.spring(DynamicAnimation.TRANSLATION_Y, totalTranslationY)
+ animator.addUpdateListener { target, values ->
+ val ty = values[DynamicAnimation.TRANSLATION_Y]?.value ?: return@addUpdateListener
+ when {
+ ty >= BUBBLE_ANIMATION_STASH_HANDLE_TRANSLATION_Y -> {
+ // we're in the first leg of the animation. only animate the handle. the bubble
+ // remains hidden during this part of the animation
+
+ // map the path [0, BUBBLE_ANIMATION_STASH_HANDLE_TRANSLATION_Y] to [0,1]
+ val fraction = ty / BUBBLE_ANIMATION_STASH_HANDLE_TRANSLATION_Y
+ target.alpha = 1 - fraction / 2
+ }
+ ty >= totalTranslationY -> {
+ // this is the second leg of the animation. the handle should be completely
+ // hidden and the bubble should start animating in.
+ // it's possible that we're re-entering this leg because this is a spring
+ // animation, so only set the alpha and scale for the bubble if we didn't
+ // already fully animate in.
+ target.alpha = 0f
+ bubbleView.translationY = ty + BUBBLE_ANIMATION_TRANSLATION_Y_OFFSET
+ if (bubbleView.alpha != 1f) {
+ // map the path
+ // [BUBBLE_ANIMATION_STASH_HANDLE_TRANSLATION_Y, totalTranslationY]
+ // to [0, 1]
+ val fraction =
+ (ty - BUBBLE_ANIMATION_STASH_HANDLE_TRANSLATION_Y) /
+ BUBBLE_ANIMATION_BUBBLE_TRANSLATION_Y
+ bubbleView.alpha = fraction
+ bubbleView.scaleY =
+ BUBBLE_ANIMATION_INITIAL_SCALE_Y +
+ (1 - BUBBLE_ANIMATION_INITIAL_SCALE_Y) * fraction
+ }
+ }
+ else -> {
+ // we're past the target animated value, set the alpha and scale for the bubble
+ // so that it's fully visible and no longer changing, but keep moving it along
+ // the animation path
+ bubbleView.alpha = 1f
+ bubbleView.scaleY = 1f
+ bubbleView.translationY = ty + BUBBLE_ANIMATION_TRANSLATION_Y_OFFSET
+ }
+ }
}
- stashedHandleAnimation.start()
+ animator.start()
}
/**
* Returns a lambda that starts the animation that hides the new bubble.
*
- * Similarly to the show animation, this is divided into 2 parts. We first animate the bubble
- * out, and then animate the stash handle in. At the end of the animation we reset the values of
- * the bubble.
+ * Similarly to the show animation, this is visually divided into 2 parts. We first animate the
+ * bubble out, and then animate the stash handle in. At the end of the animation we reset the
+ * values of the bubble.
+ *
+ * This is a spring animation that goes along the same path of the show animation in the
+ * opposite order, and is split into 3 parts:
+ * 1. In the first part the bubble animates out.
+ * 1. In the second part the bubble is fully hidden and the handle animates in.
+ * 1. The third part is the overshoot. The handle is made fully visible.
*/
private fun buildHideAnimation(bubbleView: BubbleView): () -> Unit = {
- val stashAnimation = bubbleStashController.buildShowHandleAnimationForNewBubble()
- val alphaAnimator =
- ObjectAnimator.ofFloat(bubbleView, View.ALPHA, BUBBLE_ANIMATION_INITIAL_ALPHA)
- val translationYAnimator =
- ObjectAnimator.ofFloat(
- bubbleView,
- View.TRANSLATION_Y,
- BUBBLE_ANIMATION_INITIAL_TRANSLATION_Y
- )
- val scaleYAnimator =
- ObjectAnimator.ofFloat(bubbleView, View.SCALE_Y, BUBBLE_ANIMATION_INITIAL_SCALE_Y)
- val hideBubbleAnimation = AnimatorSet()
- hideBubbleAnimation.playTogether(alphaAnimator, translationYAnimator, scaleYAnimator)
- hideBubbleAnimation.duration = HIDE_BUBBLE_ANIMATION_DURATION_MS
- hideBubbleAnimation.doOnEnd {
- // the bubble is now hidden, start the stash handle animation and reset bubble
- // properties
- bubbleStashController.setStashAlpha(
- BubbleStashController.NEW_BUBBLE_HIDE_HANDLE_ANIMATION_ALPHA
- )
+ // this is the total distance that both the stashed handle and the bubble will be traveling
+ val totalTranslationY =
+ BUBBLE_ANIMATION_BUBBLE_TRANSLATION_Y + BUBBLE_ANIMATION_STASH_HANDLE_TRANSLATION_Y
+ val animator = bubbleStashController.stashedHandlePhysicsAnimator
+ animator.setDefaultSpringConfig(springConfig)
+ animator.spring(DynamicAnimation.TRANSLATION_Y, 0f)
+ animator.addUpdateListener { target, values ->
+ val ty = values[DynamicAnimation.TRANSLATION_Y]?.value ?: return@addUpdateListener
+ when {
+ ty <= BUBBLE_ANIMATION_STASH_HANDLE_TRANSLATION_Y -> {
+ // this is the first leg of the animation. only animate the bubble. the handle
+ // is hidden during this part
+ bubbleView.translationY = ty + BUBBLE_ANIMATION_TRANSLATION_Y_OFFSET
+ // map the path
+ // [totalTranslationY, BUBBLE_ANIMATION_STASH_HANDLE_TRANSLATION_Y]
+ // to [0, 1]
+ val fraction = (totalTranslationY - ty) / BUBBLE_ANIMATION_BUBBLE_TRANSLATION_Y
+ bubbleView.alpha = 1 - fraction / 2
+ bubbleView.scaleY = 1 - (1 - BUBBLE_ANIMATION_INITIAL_SCALE_Y) * fraction
+ }
+ ty <= 0 -> {
+ // this is the second part of the animation. make the bubble invisible and
+ // start fading in the handle, but don't update the alpha if it's already fully
+ // visible
+ bubbleView.alpha = 0f
+ if (target.alpha != 1f) {
+ // map the path [BUBBLE_ANIMATION_STASH_HANDLE_TRANSLATION_Y, 0] to [0, 1]
+ val fraction =
+ (BUBBLE_ANIMATION_STASH_HANDLE_TRANSLATION_Y - ty) /
+ BUBBLE_ANIMATION_STASH_HANDLE_TRANSLATION_Y
+ target.alpha = fraction
+ }
+ }
+ else -> {
+ // we reached the target value. set the alpha of the handle to 1
+ target.alpha = 1f
+ }
+ }
+ }
+ animator.addEndListener { _, _, _, _, _, _, _ ->
bubbleView.alpha = 0f
- stashAnimation.start()
bubbleView.translationY = 0f
bubbleView.scaleY = 1f
if (bubbleStashController.isStashed) {
@@ -172,7 +238,7 @@
}
bubbleBarView.onAnimatingBubbleCompleted()
}
- hideBubbleAnimation.start()
+ animator.start()
}
}
diff --git a/quickstep/src/com/android/launcher3/uioverrides/QuickstepLauncher.java b/quickstep/src/com/android/launcher3/uioverrides/QuickstepLauncher.java
index 6c05bfe..4acddee 100644
--- a/quickstep/src/com/android/launcher3/uioverrides/QuickstepLauncher.java
+++ b/quickstep/src/com/android/launcher3/uioverrides/QuickstepLauncher.java
@@ -64,6 +64,7 @@
import static com.android.quickstep.util.SplitAnimationTimings.TABLET_HOME_TO_SPLIT;
import static com.android.systemui.shared.system.ActivityManagerWrapper.CLOSE_SYSTEM_WINDOWS_REASON_HOME_KEY;
import static com.android.window.flags.Flags.enableDesktopWindowingMode;
+import static com.android.window.flags.Flags.enableDesktopWindowingWallpaperActivity;
import static com.android.wm.shell.common.split.SplitScreenConstants.SNAP_TO_50_50;
import android.animation.Animator;
@@ -87,6 +88,7 @@
import android.util.AttributeSet;
import android.view.Display;
import android.view.HapticFeedbackConstants;
+import android.view.KeyEvent;
import android.view.View;
import android.widget.AnalogClock;
import android.widget.TextClock;
@@ -840,6 +842,28 @@
}
@Override
+ public boolean dispatchKeyEvent(KeyEvent event) {
+ return tryHandleBackKey(event) || super.dispatchKeyEvent(event);
+ }
+
+ // TODO (b/267248420) Once the recents input consumer has been removed, there is no need to
+ // handle the back key specially.
+ private boolean tryHandleBackKey(KeyEvent event) {
+ // Unlike normal activity, recents can receive input event from InputConsumer, so the input
+ // event won't go through ViewRootImpl#InputStage#onProcess.
+ // So when receive back key, try to do the same check thing in
+ // ViewRootImpl#NativePreImeInputStage#onProcess
+ if (!Utilities.ATLEAST_U || !enablePredictiveBackGesture()
+ || event.getKeyCode() != KeyEvent.KEYCODE_BACK
+ || event.getAction() != KeyEvent.ACTION_UP || event.isCanceled()) {
+ return false;
+ }
+
+ getOnBackAnimationCallback().onBackInvoked();
+ return true;
+ }
+
+ @Override
protected void registerBackDispatcher() {
if (!enablePredictiveBackGesture()) {
super.registerBackDispatcher();
@@ -942,12 +966,12 @@
@Override
public void setResumed() {
- if (mDesktopVisibilityController != null
+ if (!enableDesktopWindowingWallpaperActivity()
+ && mDesktopVisibilityController != null
&& mDesktopVisibilityController.areDesktopTasksVisible()
&& !mDesktopVisibilityController.isRecentsGestureInProgress()) {
// Return early to skip setting activity to appear as resumed
- // TODO(b/255649902): shouldn't be needed when we have a separate launcher state
- // for desktop that we can use to control other parts of launcher
+ // TODO: b/333533253 - Remove after flag rollout
return;
}
super.setResumed();
@@ -1186,6 +1210,7 @@
switch (info.container) {
case Favorites.CONTAINER_DESKTOP:
case Favorites.CONTAINER_HOTSEAT:
+ case Favorites.CONTAINER_PRIVATESPACE:
// Fall through and continue it's on the workspace (we don't support swiping back
// to other containers like all apps or the hotseat predictions (which can change)
break;
diff --git a/quickstep/src/com/android/launcher3/uioverrides/flags/DevOptionsUiHelper.kt b/quickstep/src/com/android/launcher3/uioverrides/flags/DevOptionsUiHelper.kt
index e94fa61..3881e9a 100644
--- a/quickstep/src/com/android/launcher3/uioverrides/flags/DevOptionsUiHelper.kt
+++ b/quickstep/src/com/android/launcher3/uioverrides/flags/DevOptionsUiHelper.kt
@@ -16,32 +16,98 @@
package com.android.launcher3.uioverrides.flags
+import android.content.Context
import android.content.Intent
import android.content.pm.PackageManager
import android.net.Uri
-import android.os.Handler
import android.provider.DeviceConfig
import android.provider.Settings.ACTION_APPLICATION_DETAILS_SETTINGS
import android.text.Html
+import android.util.AttributeSet
import android.view.inputmethod.EditorInfo
+import android.widget.TextView
+import android.widget.Toast
+import androidx.core.widget.doAfterTextChanged
import androidx.preference.Preference
+import androidx.preference.PreferenceCategory
import androidx.preference.PreferenceGroup
import androidx.preference.PreferenceViewHolder
import androidx.preference.SwitchPreference
import com.android.launcher3.ExtendedEditText
+import com.android.launcher3.LauncherPrefs
import com.android.launcher3.R
+import com.android.launcher3.secondarydisplay.SecondaryDisplayLauncher
import com.android.launcher3.uioverrides.plugins.PluginManagerWrapperImpl
+import com.android.launcher3.util.OnboardingPrefs.ALL_APPS_VISITED_COUNT
+import com.android.launcher3.util.OnboardingPrefs.HOME_BOUNCE_COUNT
+import com.android.launcher3.util.OnboardingPrefs.HOME_BOUNCE_SEEN
+import com.android.launcher3.util.OnboardingPrefs.HOTSEAT_DISCOVERY_TIP_COUNT
+import com.android.launcher3.util.OnboardingPrefs.HOTSEAT_LONGPRESS_TIP_SEEN
+import com.android.launcher3.util.OnboardingPrefs.TASKBAR_EDU_TOOLTIP_STEP
import com.android.launcher3.util.PluginManagerWrapper
import com.android.quickstep.util.DeviceConfigHelper
import com.android.quickstep.util.DeviceConfigHelper.Companion.NAMESPACE_LAUNCHER
import com.android.quickstep.util.DeviceConfigHelper.DebugInfo
import com.android.systemui.shared.plugins.PluginEnabler
+import com.android.systemui.shared.plugins.PluginPrefs
+import java.util.Locale
/** Helper class to generate UI for Device Config */
-class DevOptionsUiHelper {
+class DevOptionsUiHelper(c: Context, attr: AttributeSet?) : PreferenceGroup(c, attr) {
+
+ init {
+ layoutResource = R.layout.developer_options_top_bar
+ isPersistent = false
+ }
+
+ override fun onBindViewHolder(holder: PreferenceViewHolder) {
+ super.onBindViewHolder(holder)
+
+ // Initialize search
+ (holder.findViewById(R.id.filter_box) as TextView?)?.doAfterTextChanged {
+ val query: String = it.toString().lowercase(Locale.getDefault()).replace("_", " ")
+ filterPreferences(query, this)
+ }
+ }
+
+ private fun filterPreferences(query: String, pg: PreferenceGroup) {
+ val count = pg.preferenceCount
+ var visible = false
+ for (i in 0 until count) {
+ val preference = pg.getPreference(i)
+ if (preference is PreferenceGroup) {
+ filterPreferences(query, preference)
+ } else {
+ val title =
+ preference.title.toString().lowercase(Locale.getDefault()).replace("_", " ")
+ preference.isVisible = query.isEmpty() || title.contains(query)
+ }
+ visible = visible or preference.isVisible
+ }
+ pg.isVisible = visible
+ }
+
+ override fun onAttached() {
+ super.onAttached()
+
+ removeAll()
+ inflateServerFlags(newCategory("Server flags", "Long press to reset"))
+ if (PluginPrefs.hasPlugins(context)) {
+ inflatePluginPrefs(newCategory("Plugins"))
+ }
+ addIntentTargets()
+ addOnboardingPrefsCategory()
+ }
+
+ private fun newCategory(titleText: String, subTitleText: String? = null) =
+ PreferenceCategory(context).apply {
+ title = titleText
+ summary = subTitleText
+ this@DevOptionsUiHelper.addPreference(this)
+ }
/** Inflates preferences for all server flags in the provider PreferenceGroup */
- fun inflateServerFlags(parent: PreferenceGroup) {
+ private fun inflateServerFlags(parent: PreferenceGroup) {
val prefs = DeviceConfigHelper.prefs
// Sort the keys in the order of modified first followed by natural order
val allProps =
@@ -59,25 +125,21 @@
if (it.isInt) return@forEach
val info = it as DebugInfo<Boolean>
- val preference =
- object : SwitchPreference(parent.context) {
- override fun onBindViewHolder(holder: PreferenceViewHolder) {
- super.onBindViewHolder(holder)
- holder.itemView.setOnLongClickListener {
- prefs.edit().remove(key).apply()
- setChecked(info.getBoolValue())
- summary = info.getSummary()
- true
- }
- }
+ val preference = CustomSwitchPref { holder, pref ->
+ holder.itemView.setOnLongClickListener {
+ prefs.edit().remove(pref.key).apply()
+ pref.setChecked(info.getBoolValue())
+ summary = info.getSummary()
+ true
}
+ }
preference.key = info.key
preference.isPersistent = false
preference.title = info.key
preference.summary = info.getSummary()
preference.setChecked(prefs.getBoolean(info.key, info.getBoolValue()))
preference.setOnPreferenceChangeListener { _, newVal ->
- DeviceConfigHelper.prefs.edit().putBoolean(info.key, newVal as Boolean).apply()
+ prefs.edit().putBoolean(info.key, newVal as Boolean).apply()
preference.summary = info.getSummary()
true
}
@@ -89,36 +151,29 @@
if (!it.isInt) return@forEach
val info = it as DebugInfo<Int>
- val preference =
- object : Preference(parent.context) {
- override fun onBindViewHolder(holder: PreferenceViewHolder) {
- super.onBindViewHolder(holder)
- val textView = holder.findViewById(R.id.pref_edit_text) as ExtendedEditText
- textView.setText(info.getIntValueAsString())
- textView.setOnEditorActionListener { _, actionId, _ ->
- if (actionId == EditorInfo.IME_ACTION_DONE) {
- DeviceConfigHelper.prefs
- .edit()
- .putInt(key, textView.text.toString().toInt())
- .apply()
- Handler().post { summary = info.getSummary() }
- true
- }
- false
- }
- textView.setOnBackKeyListener {
- textView.setText(info.getIntValueAsString())
- true
- }
-
- holder.itemView.setOnLongClickListener {
- prefs.edit().remove(key).apply()
- textView.setText(info.getIntValueAsString())
- summary = info.getSummary()
- true
- }
+ val preference = CustomPref { holder, pref ->
+ val textView = holder.findViewById(R.id.pref_edit_text) as ExtendedEditText
+ textView.setText(info.getIntValueAsString())
+ textView.setOnEditorActionListener { _, actionId, _ ->
+ if (actionId == EditorInfo.IME_ACTION_DONE) {
+ prefs.edit().putInt(pref.key, textView.text.toString().toInt()).apply()
+ pref.summary = info.getSummary()
+ true
}
+ false
}
+ textView.setOnBackKeyListener {
+ textView.setText(info.getIntValueAsString())
+ true
+ }
+
+ holder.itemView.setOnLongClickListener {
+ prefs.edit().remove(pref.key).apply()
+ textView.setText(info.getIntValueAsString())
+ pref.summary = info.getSummary()
+ true
+ }
+ }
preference.key = info.key
preference.isPersistent = false
preference.title = info.key
@@ -158,8 +213,7 @@
* corresponding plugins on the device. When a plugin-group is enabled/disabled we also need to
* notify the pluginManager manually since the broadcast-mechanism only works in sysui process
*/
- fun inflatePluginPrefs(parent: PreferenceGroup) {
- val context = parent.context
+ private fun inflatePluginPrefs(parent: PreferenceGroup) {
val manager = PluginManagerWrapper.INSTANCE[context] as PluginManagerWrapperImpl
val pm = context.packageManager
@@ -185,15 +239,12 @@
val pluginInfo = infoList[0]!!
val pluginUri = Uri.fromParts("package", pluginInfo.serviceInfo.packageName, null)
- object : SwitchPreference(context) {
- override fun onBindViewHolder(holder: PreferenceViewHolder) {
- super.onBindViewHolder(holder)
- holder.itemView.setOnLongClickListener {
- context.startActivity(
- Intent(ACTION_APPLICATION_DETAILS_SETTINGS, pluginUri)
- )
- true
- }
+ CustomSwitchPref { holder, _ ->
+ holder.itemView.setOnLongClickListener {
+ context.startActivity(
+ Intent(ACTION_APPLICATION_DETAILS_SETTINGS, pluginUri)
+ )
+ true
}
}
.apply {
@@ -232,6 +283,113 @@
}
}
+ private fun addIntentTargets() {
+ val launchSandboxIntent =
+ Intent("com.android.quickstep.action.GESTURE_SANDBOX")
+ .setPackage(context.packageName)
+ .addFlags(Intent.FLAG_ACTIVITY_NEW_TASK)
+ newCategory("Gesture Navigation Sandbox").apply {
+ addPreference(
+ Preference(context).apply {
+ title = "Launch Gesture Tutorial Steps menu"
+ intent = Intent(launchSandboxIntent).putExtra("use_tutorial_menu", true)
+ }
+ )
+ addPreference(
+ Preference(context).apply {
+ title = "Launch Back Tutorial"
+ intent =
+ Intent(launchSandboxIntent)
+ .putExtra("use_tutorial_menu", false)
+ .putExtra("tutorial_steps", arrayOf("BACK_NAVIGATION"))
+ }
+ )
+ addPreference(
+ Preference(context).apply {
+ title = "Launch Home Tutorial"
+ intent =
+ Intent(launchSandboxIntent)
+ .putExtra("use_tutorial_menu", false)
+ .putExtra("tutorial_steps", arrayOf("HOME_NAVIGATION"))
+ }
+ )
+ addPreference(
+ Preference(context).apply {
+ title = "Launch Overview Tutorial"
+ intent =
+ Intent(launchSandboxIntent)
+ .putExtra("use_tutorial_menu", false)
+ .putExtra("tutorial_steps", arrayOf("OVERVIEW_NAVIGATION"))
+ }
+ )
+ }
+
+ newCategory("Other activity targets").apply {
+ addPreference(
+ Preference(context).apply {
+ title = "Launch Secondary Display"
+ intent =
+ Intent(context, SecondaryDisplayLauncher::class.java)
+ .addFlags(Intent.FLAG_ACTIVITY_NEW_TASK)
+ }
+ )
+ }
+ }
+
+ private fun addOnboardingPrefsCategory() {
+ newCategory("Onboarding Flows").apply {
+ summary = "Reset these if you want to see the education again."
+ addOnboardPref(
+ "All Apps Bounce",
+ HOME_BOUNCE_SEEN.sharedPrefKey,
+ HOME_BOUNCE_COUNT.sharedPrefKey
+ )
+ addOnboardPref(
+ "Hybrid Hotseat Education",
+ HOTSEAT_DISCOVERY_TIP_COUNT.sharedPrefKey,
+ HOTSEAT_LONGPRESS_TIP_SEEN.sharedPrefKey
+ )
+ addOnboardPref("Taskbar Education", TASKBAR_EDU_TOOLTIP_STEP.sharedPrefKey)
+ addOnboardPref("All Apps Visited Count", ALL_APPS_VISITED_COUNT.sharedPrefKey)
+ }
+ }
+
+ private fun PreferenceCategory.addOnboardPref(title: String, vararg keys: String) =
+ this.addPreference(
+ Preference(context).also {
+ it.title = title
+ it.summary = "Tap to reset"
+ setOnPreferenceClickListener { _ ->
+ LauncherPrefs.getPrefs(context)
+ .edit()
+ .apply { keys.forEach { key -> remove(key) } }
+ .apply()
+ Toast.makeText(context, "Reset $title", Toast.LENGTH_SHORT).show()
+ true
+ }
+ }
+ )
+
+ private inner class CustomSwitchPref(
+ private val bindCallback: (holder: PreferenceViewHolder, pref: SwitchPreference) -> Unit
+ ) : SwitchPreference(context) {
+
+ override fun onBindViewHolder(holder: PreferenceViewHolder) {
+ super.onBindViewHolder(holder)
+ bindCallback.invoke(holder, this)
+ }
+ }
+
+ private inner class CustomPref(
+ private val bindCallback: (holder: PreferenceViewHolder, pref: Preference) -> Unit
+ ) : Preference(context) {
+
+ override fun onBindViewHolder(holder: PreferenceViewHolder) {
+ super.onBindViewHolder(holder)
+ bindCallback.invoke(holder, this)
+ }
+ }
+
companion object {
const val TAG = "DeviceConfigUIHelper"
diff --git a/quickstep/src/com/android/launcher3/uioverrides/flags/DeveloperOptionsUI.java b/quickstep/src/com/android/launcher3/uioverrides/flags/DeveloperOptionsUI.java
deleted file mode 100644
index ca8da08..0000000
--- a/quickstep/src/com/android/launcher3/uioverrides/flags/DeveloperOptionsUI.java
+++ /dev/null
@@ -1,240 +0,0 @@
-/*
- * Copyright (C) 2018 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.uioverrides.flags;
-
-import static com.android.launcher3.settings.SettingsActivity.EXTRA_FRAGMENT_HIGHLIGHT_KEY;
-import static com.android.launcher3.util.OnboardingPrefs.ALL_APPS_VISITED_COUNT;
-import static com.android.launcher3.util.OnboardingPrefs.HOME_BOUNCE_COUNT;
-import static com.android.launcher3.util.OnboardingPrefs.HOME_BOUNCE_SEEN;
-import static com.android.launcher3.util.OnboardingPrefs.HOTSEAT_DISCOVERY_TIP_COUNT;
-import static com.android.launcher3.util.OnboardingPrefs.HOTSEAT_LONGPRESS_TIP_SEEN;
-import static com.android.launcher3.util.OnboardingPrefs.TASKBAR_EDU_TOOLTIP_STEP;
-
-import android.content.Context;
-import android.content.Intent;
-import android.content.SharedPreferences;
-import android.text.Editable;
-import android.text.TextWatcher;
-import android.view.LayoutInflater;
-import android.view.View;
-import android.view.ViewGroup;
-import android.widget.EditText;
-import android.widget.Toast;
-
-import androidx.preference.Preference;
-import androidx.preference.PreferenceCategory;
-import androidx.preference.PreferenceFragmentCompat;
-import androidx.preference.PreferenceGroup;
-import androidx.preference.PreferenceScreen;
-
-import com.android.launcher3.LauncherPrefs;
-import com.android.launcher3.R;
-import com.android.launcher3.config.FeatureFlags;
-import com.android.launcher3.secondarydisplay.SecondaryDisplayLauncher;
-import com.android.systemui.shared.plugins.PluginPrefs;
-
-/**
- * Dev-build only UI allowing developers to toggle flag settings and plugins.
- * See {@link FeatureFlags}.
- */
-public class DeveloperOptionsUI {
-
- private final PreferenceFragmentCompat mFragment;
- private final PreferenceScreen mPreferenceScreen;
-
- public DeveloperOptionsUI(PreferenceFragmentCompat fragment, PreferenceCategory flags) {
- mFragment = fragment;
- mPreferenceScreen = fragment.getPreferenceScreen();
- flags.getParent().removePreference(flags);
-
- // Add search bar
- View listView = mFragment.getListView();
- ViewGroup parent = (ViewGroup) listView.getParent();
- View topBar = LayoutInflater.from(parent.getContext())
- .inflate(R.layout.developer_options_top_bar, parent, false);
- parent.addView(topBar, parent.indexOfChild(listView));
- initSearch(topBar.findViewById(R.id.filter_box));
-
- DevOptionsUiHelper uiHelper = new DevOptionsUiHelper();
- uiHelper.inflateServerFlags(newCategory("Server flags"));
- if (PluginPrefs.hasPlugins(getContext())) {
- uiHelper.inflatePluginPrefs(newCategory("Plugins"));
- }
-
- maybeAddSandboxCategory();
- addOnboardingPrefsCatergory();
- }
-
- private void filterPreferences(String query, PreferenceGroup pg) {
- int count = pg.getPreferenceCount();
- int hidden = 0;
- for (int i = 0; i < count; i++) {
- Preference preference = pg.getPreference(i);
- if (preference instanceof PreferenceGroup) {
- filterPreferences(query, (PreferenceGroup) preference);
- } else {
- String title = preference.getTitle().toString().toLowerCase().replace("_", " ");
- if (query.isEmpty() || title.contains(query)) {
- preference.setVisible(true);
- } else {
- preference.setVisible(false);
- hidden++;
- }
- }
- }
- pg.setVisible(hidden != count);
- }
-
- private void initSearch(EditText filterBox) {
- filterBox.addTextChangedListener(new TextWatcher() {
- @Override
- public void beforeTextChanged(CharSequence charSequence, int i, int i1, int i2) { }
-
- @Override
- public void onTextChanged(CharSequence charSequence, int i, int i1, int i2) { }
-
- @Override
- public void afterTextChanged(Editable editable) {
- String query = editable.toString().toLowerCase().replace("_", " ");
- filterPreferences(query, mPreferenceScreen);
- }
- });
-
- if (mFragment.getArguments() != null) {
- String filter = mFragment.getArguments().getString(EXTRA_FRAGMENT_HIGHLIGHT_KEY);
- // Normally EXTRA_FRAGMENT_ARG_KEY is used to highlight the preference with the given
- // key. This is a slight variation where we instead filter by the human-readable titles.
- if (filter != null) {
- filterBox.setText(filter);
- }
- }
- }
-
- private PreferenceCategory newCategory(String title) {
- PreferenceCategory category = new PreferenceCategory(getContext());
- category.setOrder(Preference.DEFAULT_ORDER);
- category.setTitle(title);
- mPreferenceScreen.addPreference(category);
- return category;
- }
-
- private Context getContext() {
- return mFragment.requireContext();
- }
-
- private void maybeAddSandboxCategory() {
- Context context = getContext();
- if (context == null) {
- return;
- }
- Intent launchSandboxIntent =
- new Intent("com.android.quickstep.action.GESTURE_SANDBOX")
- .setPackage(context.getPackageName())
- .addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
- if (launchSandboxIntent.resolveActivity(context.getPackageManager()) == null) {
- return;
- }
- PreferenceCategory sandboxCategory = newCategory("Gesture Navigation Sandbox");
- sandboxCategory.setSummary("Learn and practice navigation gestures");
- Preference launchTutorialStepMenuPreference = new Preference(context);
- launchTutorialStepMenuPreference.setKey("launchTutorialStepMenu");
- launchTutorialStepMenuPreference.setTitle("Launch Gesture Tutorial Steps menu");
- launchTutorialStepMenuPreference.setSummary("Select a gesture tutorial step.");
- launchTutorialStepMenuPreference.setIntent(
- new Intent(launchSandboxIntent).putExtra("use_tutorial_menu", true));
-
- sandboxCategory.addPreference(launchTutorialStepMenuPreference);
- Preference launchOnboardingTutorialPreference = new Preference(context);
- launchOnboardingTutorialPreference.setKey("launchOnboardingTutorial");
- launchOnboardingTutorialPreference.setTitle("Launch Onboarding Tutorial");
- launchOnboardingTutorialPreference.setSummary("Learn the basic navigation gestures.");
- launchTutorialStepMenuPreference.setIntent(new Intent(launchSandboxIntent)
- .putExtra("use_tutorial_menu", false)
- .putExtra("tutorial_steps",
- new String[] {
- "HOME_NAVIGATION",
- "BACK_NAVIGATION",
- "OVERVIEW_NAVIGATION"}));
-
- sandboxCategory.addPreference(launchOnboardingTutorialPreference);
- Preference launchBackTutorialPreference = new Preference(context);
- launchBackTutorialPreference.setKey("launchBackTutorial");
- launchBackTutorialPreference.setTitle("Launch Back Tutorial");
- launchBackTutorialPreference.setSummary("Learn how to use the Back gesture");
- launchBackTutorialPreference.setIntent(new Intent(launchSandboxIntent)
- .putExtra("use_tutorial_menu", false)
- .putExtra("tutorial_steps", new String[] {"BACK_NAVIGATION"}));
-
- sandboxCategory.addPreference(launchBackTutorialPreference);
- Preference launchHomeTutorialPreference = new Preference(context);
- launchHomeTutorialPreference.setKey("launchHomeTutorial");
- launchHomeTutorialPreference.setTitle("Launch Home Tutorial");
- launchHomeTutorialPreference.setSummary("Learn how to use the Home gesture");
- launchHomeTutorialPreference.setIntent(new Intent(launchSandboxIntent)
- .putExtra("use_tutorial_menu", false)
- .putExtra("tutorial_steps", new String[] {"HOME_NAVIGATION"}));
-
- sandboxCategory.addPreference(launchHomeTutorialPreference);
- Preference launchOverviewTutorialPreference = new Preference(context);
- launchOverviewTutorialPreference.setKey("launchOverviewTutorial");
- launchOverviewTutorialPreference.setTitle("Launch Overview Tutorial");
- launchOverviewTutorialPreference.setSummary("Learn how to use the Overview gesture");
- launchOverviewTutorialPreference.setIntent(new Intent(launchSandboxIntent)
- .putExtra("use_tutorial_menu", false)
- .putExtra("tutorial_steps", new String[] {"OVERVIEW_NAVIGATION"}));
-
- sandboxCategory.addPreference(launchOverviewTutorialPreference);
- Preference launchSecondaryDisplayPreference = new Preference(context);
- launchSecondaryDisplayPreference.setKey("launchSecondaryDisplay");
- launchSecondaryDisplayPreference.setTitle("Launch Secondary Display");
- launchSecondaryDisplayPreference.setSummary("Launch secondary display activity");
- launchSecondaryDisplayPreference.setIntent(
- new Intent(context, SecondaryDisplayLauncher.class));
-
- }
-
- private void addOnboardingPrefsCatergory() {
- PreferenceCategory onboardingCategory = newCategory("Onboarding Flows");
- onboardingCategory.setSummary("Reset these if you want to see the education again.");
-
- onboardingCategory.addPreference(createOnboardPref("All Apps Bounce",
- HOME_BOUNCE_SEEN.getSharedPrefKey(), HOME_BOUNCE_COUNT.getSharedPrefKey()));
- onboardingCategory.addPreference(createOnboardPref("Hybrid Hotseat Education",
- HOTSEAT_DISCOVERY_TIP_COUNT.getSharedPrefKey(),
- HOTSEAT_LONGPRESS_TIP_SEEN.getSharedPrefKey()));
- onboardingCategory.addPreference(createOnboardPref("Taskbar Education",
- TASKBAR_EDU_TOOLTIP_STEP.getSharedPrefKey()));
- onboardingCategory.addPreference(createOnboardPref("All Apps Visited Count",
- ALL_APPS_VISITED_COUNT.getSharedPrefKey()));
- }
-
- private Preference createOnboardPref(String title, String... keys) {
- Preference onboardingPref = new Preference(getContext());
- onboardingPref.setTitle(title);
- onboardingPref.setSummary("Tap to reset");
- onboardingPref.setOnPreferenceClickListener(preference -> {
- SharedPreferences.Editor sharedPrefsEdit = LauncherPrefs.getPrefs(getContext())
- .edit();
- for (String key : keys) {
- sharedPrefsEdit.remove(key);
- }
- sharedPrefsEdit.apply();
- Toast.makeText(getContext(), "Reset " + title, Toast.LENGTH_SHORT).show();
- return true;
- });
- return onboardingPref;
- }
-}
diff --git a/quickstep/src/com/android/launcher3/uioverrides/touchcontrollers/NavBarToHomeTouchController.java b/quickstep/src/com/android/launcher3/uioverrides/touchcontrollers/NavBarToHomeTouchController.java
index 615e3e3..3ed2d0b 100644
--- a/quickstep/src/com/android/launcher3/uioverrides/touchcontrollers/NavBarToHomeTouchController.java
+++ b/quickstep/src/com/android/launcher3/uioverrides/touchcontrollers/NavBarToHomeTouchController.java
@@ -19,7 +19,7 @@
import static com.android.launcher3.AbstractFloatingView.TYPE_ALL;
import static com.android.launcher3.AbstractFloatingView.TYPE_ALL_APPS_EDU;
import static com.android.launcher3.LauncherAnimUtils.SUCCESS_TRANSITION_PROGRESS;
-import static com.android.launcher3.LauncherAnimUtils.newCancelListener;
+import static com.android.launcher3.LauncherAnimUtils.newSingleUseCancelListener;
import static com.android.launcher3.LauncherState.ALL_APPS;
import static com.android.launcher3.LauncherState.NORMAL;
import static com.android.launcher3.MotionEventsUtils.isTrackpadMotionEvent;
@@ -47,7 +47,6 @@
import com.android.launcher3.config.FeatureFlags;
import com.android.launcher3.statemanager.StateManager;
import com.android.launcher3.touch.SingleAxisSwipeDetector;
-import com.android.launcher3.uioverrides.QuickstepLauncher;
import com.android.launcher3.util.DisplayController;
import com.android.launcher3.util.TouchController;
import com.android.quickstep.TaskUtils;
@@ -166,7 +165,7 @@
topView.addHintCloseAnim(mPullbackDistance, PULLBACK_INTERPOLATOR, builder);
}
mCurrentAnimation = builder.createPlaybackController();
- mCurrentAnimation.getTarget().addListener(newCancelListener(this::clearState));
+ mCurrentAnimation.getTarget().addListener(newSingleUseCancelListener(this::clearState));
}
private void clearState() {
diff --git a/quickstep/src/com/android/launcher3/uioverrides/touchcontrollers/NoButtonNavbarToOverviewTouchController.java b/quickstep/src/com/android/launcher3/uioverrides/touchcontrollers/NoButtonNavbarToOverviewTouchController.java
index 26e994f..42be52f 100644
--- a/quickstep/src/com/android/launcher3/uioverrides/touchcontrollers/NoButtonNavbarToOverviewTouchController.java
+++ b/quickstep/src/com/android/launcher3/uioverrides/touchcontrollers/NoButtonNavbarToOverviewTouchController.java
@@ -18,7 +18,7 @@
import static com.android.app.animation.Interpolators.ACCELERATE_DECELERATE;
import static com.android.launcher3.LauncherAnimUtils.VIEW_BACKGROUND_COLOR;
-import static com.android.launcher3.LauncherAnimUtils.newCancelListener;
+import static com.android.launcher3.LauncherAnimUtils.newSingleUseCancelListener;
import static com.android.launcher3.LauncherState.ALL_APPS;
import static com.android.launcher3.LauncherState.HINT_STATE;
import static com.android.launcher3.LauncherState.NORMAL;
@@ -226,7 +226,7 @@
return;
}
mNormalToHintOverviewScrimAnimator = null;
- mCurrentAnimation.getTarget().addListener(newCancelListener(() ->
+ mCurrentAnimation.getTarget().addListener(newSingleUseCancelListener(() ->
mLauncher.getStateManager().goToState(OVERVIEW, true, forSuccessCallback(() -> {
mOverviewResistYAnim = AnimatorControllerWithResistance
.createRecentsResistanceFromOverviewAnim(mLauncher, null)
diff --git a/quickstep/src/com/android/launcher3/uioverrides/touchcontrollers/NoButtonQuickSwitchTouchController.java b/quickstep/src/com/android/launcher3/uioverrides/touchcontrollers/NoButtonQuickSwitchTouchController.java
index 5a19ed4..527a776 100644
--- a/quickstep/src/com/android/launcher3/uioverrides/touchcontrollers/NoButtonQuickSwitchTouchController.java
+++ b/quickstep/src/com/android/launcher3/uioverrides/touchcontrollers/NoButtonQuickSwitchTouchController.java
@@ -109,7 +109,7 @@
private final float mMotionPauseMinDisplacement;
private final RecentsView mRecentsView;
protected final AnimatorListener mClearStateOnCancelListener =
- newCancelListener(this::clearState);
+ newCancelListener(this::clearState, /* isSingleUse = */ false);
private boolean mNoIntercept;
private LauncherState mStartState;
diff --git a/quickstep/src/com/android/quickstep/AbsSwipeUpHandler.java b/quickstep/src/com/android/quickstep/AbsSwipeUpHandler.java
index 2fedb6f..9e1addf 100644
--- a/quickstep/src/com/android/quickstep/AbsSwipeUpHandler.java
+++ b/quickstep/src/com/android/quickstep/AbsSwipeUpHandler.java
@@ -1254,10 +1254,12 @@
return LAST_TASK;
}
- if (((mRecentsView.getNextPageTaskView() != null
- && mRecentsView.getNextPageTaskView().isDesktopTask())
- || (mRecentsView.getCurrentPageTaskView() != null
- && mRecentsView.getCurrentPageTaskView().isDesktopTask()))
+ TaskView nextPageTaskView = mRecentsView != null
+ ? mRecentsView.getNextPageTaskView() : null;
+ TaskView currentPageTaskView = mRecentsView != null
+ ? mRecentsView.getCurrentPageTaskView() : null;
+ if (((nextPageTaskView != null && nextPageTaskView.isDesktopTask())
+ || (currentPageTaskView != null && currentPageTaskView.isDesktopTask()))
&& endTarget == NEW_TASK) {
// TODO(b/268075592): add support for quickswitch to/from desktop
return LAST_TASK;
diff --git a/quickstep/src/com/android/quickstep/BootAwarePreloader.kt b/quickstep/src/com/android/quickstep/BootAwarePreloader.kt
deleted file mode 100644
index 2fc4d04..0000000
--- a/quickstep/src/com/android/quickstep/BootAwarePreloader.kt
+++ /dev/null
@@ -1,52 +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.quickstep
-
-import android.content.Context
-import android.util.Log
-import com.android.launcher3.LauncherAppState
-import com.android.launcher3.LauncherPrefs
-import com.android.launcher3.moveStartupDataToDeviceProtectedStorageIsEnabled
-import com.android.launcher3.util.LockedUserState
-
-/**
- * Loads expensive objects in memory before the user is unlocked. This decreases experienced latency
- * when starting the launcher for the first time after a reboot.
- */
-object BootAwarePreloader {
- private const val TAG = "BootAwarePreloader"
-
- @JvmStatic
- fun start(context: Context) {
- val lp = LauncherPrefs.get(context)
- when {
- LockedUserState.get(context).isUserUnlocked ||
- !moveStartupDataToDeviceProtectedStorageIsEnabled -> {
- /* No-Op */
- }
- lp.isStartupDataMigrated -> {
- Log.d(TAG, "preloading start up data")
- LauncherAppState.INSTANCE.get(context)
- }
- else -> {
- Log.d(TAG, "queuing start up data migration to boot aware prefs")
- LockedUserState.get(context).runOnUserUnlocked {
- lp.migrateStartupDataToDeviceProtectedStorage()
- }
- }
- }
- }
-}
diff --git a/quickstep/src/com/android/quickstep/DesktopModeStatus.java b/quickstep/src/com/android/quickstep/DesktopModeStatus.java
new file mode 100644
index 0000000..b1aae16
--- /dev/null
+++ b/quickstep/src/com/android/quickstep/DesktopModeStatus.java
@@ -0,0 +1,58 @@
+/*
+ * 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;
+
+import android.content.Context;
+import android.os.SystemProperties;
+
+import com.android.internal.annotations.VisibleForTesting;
+import com.android.window.flags.Flags;
+
+// TODO(b/335401172): Explore unifying logic across core and shell
+public class DesktopModeStatus {
+
+ /**
+ * Flag to indicate whether to restrict desktop mode to supported devices.
+ */
+ private static final boolean ENFORCE_DEVICE_RESTRICTIONS = SystemProperties.getBoolean(
+ "persist.wm.debug.desktop_mode_enforce_device_restrictions", true);
+
+ /**
+ * Return {@code true} if desktop mode should be restricted to supported devices.
+ */
+ @VisibleForTesting
+ public static boolean enforceDeviceRestrictions() {
+ return ENFORCE_DEVICE_RESTRICTIONS;
+ }
+
+ /**
+ * Return {@code true} if the current device supports desktop mode.
+ */
+ @VisibleForTesting
+ public static boolean isDesktopModeSupported(Context context) {
+ return context.getResources().getBoolean(
+ com.android.internal.R.bool.config_isDesktopModeSupported);
+ }
+
+ /**
+ * Return {@code true} if desktop mode can be entered on the current device.
+ */
+ public static boolean canEnterDesktopMode(Context context) {
+ return Flags.enableDesktopWindowingMode()
+ && (!enforceDeviceRestrictions() || isDesktopModeSupported(context));
+ }
+}
diff --git a/quickstep/src/com/android/quickstep/DesktopSystemShortcut.kt b/quickstep/src/com/android/quickstep/DesktopSystemShortcut.kt
index aa0f728..f26d594 100644
--- a/quickstep/src/com/android/quickstep/DesktopSystemShortcut.kt
+++ b/quickstep/src/com/android/quickstep/DesktopSystemShortcut.kt
@@ -24,7 +24,6 @@
import com.android.quickstep.views.RecentsView
import com.android.quickstep.views.RecentsViewContainer
import com.android.quickstep.views.TaskView.TaskIdAttributeContainer
-import com.android.window.flags.Flags
/** A menu item, "Desktop", that allows the user to bring the current app into Desktop Windowing. */
class DesktopSystemShortcut(
@@ -52,7 +51,7 @@
}
companion object {
- /** Creates a factory for creating Desktop system shorcuts. */
+ /** Creates a factory for creating Desktop system shortcuts. */
@JvmOverloads
fun createFactory(
abstractFloatingViewHelper: AbstractFloatingViewHelper = AbstractFloatingViewHelper()
@@ -62,7 +61,7 @@
container: RecentsViewContainer,
taskContainer: TaskIdAttributeContainer
): List<DesktopSystemShortcut>? {
- return if (!Flags.enableDesktopWindowingMode()) null
+ return if (!DesktopModeStatus.canEnterDesktopMode(container.asContext())) null
else if (!taskContainer.task.isDockable) null
else
listOf(
diff --git a/quickstep/src/com/android/quickstep/DeviceConfigWrapper.kt b/quickstep/src/com/android/quickstep/DeviceConfigWrapper.kt
index 1cc54d8..f68f793 100644
--- a/quickstep/src/com/android/quickstep/DeviceConfigWrapper.kt
+++ b/quickstep/src/com/android/quickstep/DeviceConfigWrapper.kt
@@ -33,7 +33,7 @@
val customLphThresholds =
propReader.get(
"CUSTOM_LPH_THRESHOLDS",
- false,
+ true,
"Server side control to customize LPH timeout and touch slop"
)
diff --git a/quickstep/src/com/android/quickstep/GestureState.java b/quickstep/src/com/android/quickstep/GestureState.java
index 6b33c0a..c8a91df 100644
--- a/quickstep/src/com/android/quickstep/GestureState.java
+++ b/quickstep/src/com/android/quickstep/GestureState.java
@@ -30,6 +30,7 @@
import static com.android.quickstep.util.ActiveGestureErrorDetector.GestureEvent.SET_END_TARGET_NEW_TASK;
import android.content.Intent;
+import android.os.SystemClock;
import android.view.MotionEvent;
import android.view.RemoteAnimationTarget;
@@ -182,7 +183,7 @@
private HashMap<Integer, ThumbnailData> mRecentsAnimationCanceledSnapshots;
/** The time when the swipe up gesture is triggered. */
- private long mSwipeUpStartTimeMs;
+ private final long mSwipeUpStartTimeMs = SystemClock.uptimeMillis();
private boolean mHandlingAtomicEvent;
@@ -508,21 +509,18 @@
return null;
}
- void setSwipeUpStartTimeMs(long uptimeMs) {
- mSwipeUpStartTimeMs = uptimeMs;
- }
-
long getSwipeUpStartTimeMs() {
return mSwipeUpStartTimeMs;
}
- public void dump(PrintWriter pw) {
- pw.println("GestureState:");
- pw.println(" gestureID=" + mGestureId);
- pw.println(" runningTask=" + mRunningTask);
- pw.println(" endTarget=" + mEndTarget);
- pw.println(" lastAppearedTaskTargetId=" + Arrays.toString(mLastAppearedTaskTargets));
- pw.println(" lastStartedTaskId=" + Arrays.toString(mLastStartedTaskId));
- pw.println(" isRecentsAnimationRunning=" + isRecentsAnimationRunning());
+ public void dump(String prefix, PrintWriter pw) {
+ pw.println(prefix + "GestureState:");
+ pw.println(prefix + "\tgestureID=" + mGestureId);
+ pw.println(prefix + "\trunningTask=" + mRunningTask);
+ pw.println(prefix + "\tendTarget=" + mEndTarget);
+ pw.println(prefix + "\tlastAppearedTaskTargetId="
+ + Arrays.toString(mLastAppearedTaskTargets));
+ pw.println(prefix + "\tlastStartedTaskId=" + Arrays.toString(mLastStartedTaskId));
+ pw.println(prefix + "\tisRecentsAnimationRunning=" + isRecentsAnimationRunning());
}
}
diff --git a/quickstep/src/com/android/quickstep/LauncherSwipeHandlerV2.java b/quickstep/src/com/android/quickstep/LauncherSwipeHandlerV2.java
index 6647057..af02ccf 100644
--- a/quickstep/src/com/android/quickstep/LauncherSwipeHandlerV2.java
+++ b/quickstep/src/com/android/quickstep/LauncherSwipeHandlerV2.java
@@ -88,8 +88,11 @@
final View workspaceView = findWorkspaceView(launchCookies,
mRecentsView.getRunningTaskView());
- boolean canUseWorkspaceView = workspaceView != null && workspaceView.isAttachedToWindow()
- && workspaceView.getHeight() > 0;
+ boolean canUseWorkspaceView = workspaceView != null
+ && workspaceView.isAttachedToWindow()
+ && workspaceView.getHeight() > 0
+ && (mContainer.getDesktopVisibilityController() == null
+ || !mContainer.getDesktopVisibilityController().areDesktopTasksVisible());
mContainer.getRootView().setForceHideBackArrow(true);
if (!TaskAnimationManager.ENABLE_SHELL_TRANSITIONS) {
@@ -119,6 +122,10 @@
float windowAlphaThreshold = 1f - SHAPE_PROGRESS_DURATION;
return new FloatingViewHomeAnimationFactory(floatingIconView) {
+ @Nullable
+ private RectF mTargetRect;
+ @Nullable
+ private RectFSpringAnim mSiblingAnimation;
@Nullable
@Override
@@ -135,15 +142,36 @@
@NonNull
@Override
public RectF getWindowTargetRect() {
- return iconLocation;
+ if (enableScalingRevealHomeAnimation()) {
+ if (mTargetRect == null) {
+ mTargetRect = new RectF(iconLocation);
+ }
+ return mTargetRect;
+ } else {
+ return iconLocation;
+ }
+ }
+
+ @Override
+ public void playAtomicAnimation(float velocity) {
+ if (enableScalingRevealHomeAnimation()) {
+ if (mContainer != null) {
+ new ScalingWorkspaceRevealAnim(
+ mContainer, mSiblingAnimation, getWindowTargetRect()).start();
+ }
+ } else {
+ super.playAtomicAnimation(velocity);
+ }
}
@Override
public void setAnimation(RectFSpringAnim anim) {
super.setAnimation(anim);
- anim.addAnimatorListener(floatingIconView);
- floatingIconView.setOnTargetChangeListener(anim::onTargetPositionChanged);
- floatingIconView.setFastFinishRunnable(anim::end);
+ mSiblingAnimation = anim;
+ mSiblingAnimation.addAnimatorListener(floatingIconView);
+ floatingIconView.setOnTargetChangeListener(
+ mSiblingAnimation::onTargetPositionChanged);
+ floatingIconView.setFastFinishRunnable(mSiblingAnimation::end);
}
@Override
@@ -298,15 +326,9 @@
@Override
public void playAtomicAnimation(float velocity) {
- if (enableScalingRevealHomeAnimation()) {
- if (mContainer != null) {
- new ScalingWorkspaceRevealAnim(mContainer).start();
- }
- } else {
- new StaggeredWorkspaceAnim(mContainer, velocity, true /* animateOverviewScrim */,
- getViewIgnoredInWorkspaceRevealAnimation())
- .start();
- }
+ new StaggeredWorkspaceAnim(mContainer, velocity, true /* animateOverviewScrim */,
+ getViewIgnoredInWorkspaceRevealAnimation())
+ .start();
}
}
}
diff --git a/quickstep/src/com/android/quickstep/RecentsAnimationCallbacks.java b/quickstep/src/com/android/quickstep/RecentsAnimationCallbacks.java
index 5d26ec0..da7a98f 100644
--- a/quickstep/src/com/android/quickstep/RecentsAnimationCallbacks.java
+++ b/quickstep/src/com/android/quickstep/RecentsAnimationCallbacks.java
@@ -39,6 +39,7 @@
import com.android.systemui.shared.recents.model.ThumbnailData;
import com.android.systemui.shared.system.RecentsAnimationControllerCompat;
+import java.io.PrintWriter;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashMap;
@@ -219,6 +220,13 @@
}
}
+ public void dump(String prefix, PrintWriter pw) {
+ pw.println(prefix + "RecentsAnimationCallbacks:");
+
+ pw.println(prefix + "\tmAllowMinimizeSplitScreen=" + mAllowMinimizeSplitScreen);
+ pw.println(prefix + "\tmCancelled=" + mCancelled);
+ }
+
/**
* Listener for the recents animation callbacks.
*/
diff --git a/quickstep/src/com/android/quickstep/RecentsAnimationController.java b/quickstep/src/com/android/quickstep/RecentsAnimationController.java
index 06a442b..1b05e28 100644
--- a/quickstep/src/com/android/quickstep/RecentsAnimationController.java
+++ b/quickstep/src/com/android/quickstep/RecentsAnimationController.java
@@ -41,6 +41,7 @@
import com.android.systemui.shared.system.InteractionJankMonitorWrapper;
import com.android.systemui.shared.system.RecentsAnimationControllerCompat;
+import java.io.PrintWriter;
import java.util.function.Consumer;
/**
@@ -267,4 +268,14 @@
public boolean getFinishTargetIsLauncher() {
return mFinishTargetIsLauncher;
}
+
+ public void dump(String prefix, PrintWriter pw) {
+ pw.println(prefix + "RecentsAnimationController:");
+
+ pw.println(prefix + "\tmAllowMinimizeSplitScreen=" + mAllowMinimizeSplitScreen);
+ pw.println(prefix + "\tmUseLauncherSysBarFlags=" + mUseLauncherSysBarFlags);
+ pw.println(prefix + "\tmSplitScreenMinimized=" + mSplitScreenMinimized);
+ pw.println(prefix + "\tmFinishRequested=" + mFinishRequested);
+ pw.println(prefix + "\tmFinishTargetIsLauncher=" + mFinishTargetIsLauncher);
+ }
}
diff --git a/quickstep/src/com/android/quickstep/RecentsAnimationTargets.java b/quickstep/src/com/android/quickstep/RecentsAnimationTargets.java
index f936882..82bb453 100644
--- a/quickstep/src/com/android/quickstep/RecentsAnimationTargets.java
+++ b/quickstep/src/com/android/quickstep/RecentsAnimationTargets.java
@@ -25,6 +25,8 @@
import android.os.Bundle;
import android.view.RemoteAnimationTarget;
+import java.io.PrintWriter;
+
/**
* Extension of {@link RemoteAnimationTargets} with additional information about swipe
* up animation
@@ -63,4 +65,14 @@
}
return false;
}
+
+ @Override
+ public void dump(String prefix, PrintWriter pw) {
+ super.dump(prefix, pw);
+ prefix += '\t';
+ pw.println(prefix + "RecentsAnimationTargets:");
+
+ pw.println(prefix + "\thomeContentInsets=" + homeContentInsets);
+ pw.println(prefix + "\tminimizedHomeBounds=" + minimizedHomeBounds);
+ }
}
diff --git a/quickstep/src/com/android/quickstep/RemoteAnimationTargets.java b/quickstep/src/com/android/quickstep/RemoteAnimationTargets.java
index e0c7403..57edd82 100644
--- a/quickstep/src/com/android/quickstep/RemoteAnimationTargets.java
+++ b/quickstep/src/com/android/quickstep/RemoteAnimationTargets.java
@@ -22,6 +22,7 @@
import android.os.Bundle;
import android.view.RemoteAnimationTarget;
+import java.io.PrintWriter;
import java.util.ArrayList;
import java.util.concurrent.CopyOnWriteArrayList;
@@ -149,6 +150,14 @@
}
}
+ public void dump(String prefix, PrintWriter pw) {
+ pw.println(prefix + "RemoteAnimationTargets:");
+
+ pw.println(prefix + "\ttargetMode=" + targetMode);
+ pw.println(prefix + "\thasRecents=" + hasRecents);
+ pw.println(prefix + "\tmReleased=" + mReleased);
+ }
+
/**
* Interface for intercepting surface release method
*/
diff --git a/quickstep/src/com/android/quickstep/RemoteTargetGluer.java b/quickstep/src/com/android/quickstep/RemoteTargetGluer.java
index 7f2aded..3dec381 100644
--- a/quickstep/src/com/android/quickstep/RemoteTargetGluer.java
+++ b/quickstep/src/com/android/quickstep/RemoteTargetGluer.java
@@ -222,8 +222,10 @@
for (int i = 0; i < mRemoteTargetHandles.length; i++) {
RemoteAnimationTarget primaryTaskTarget = targets.apps[i];
+ List<RemoteAnimationTarget> excludeTargets = Arrays.stream(targets.apps)
+ .filter(target -> target.taskId != primaryTaskTarget.taskId).toList();
mRemoteTargetHandles[i].mTransformParams.setTargetSet(
- createRemoteAnimationTargetsForTaskId(targets, primaryTaskTarget.taskId));
+ createRemoteAnimationTargetsForTarget(targets, excludeTargets));
mRemoteTargetHandles[i].mTaskViewSimulator.setPreview(primaryTaskTarget, null);
}
return mRemoteTargetHandles;
@@ -290,33 +292,6 @@
}
/**
- * Ensures that we only animate one specific app target. Includes ancillary targets such as
- * home/recents
- *
- * @param targets remote animation targets to filter
- * @param taskId id for a task that we want this remote animation to apply to
- * @return {@link RemoteAnimationTargets} where app target only includes the app that has the
- * {@code taskId} that was passed in
- */
- private RemoteAnimationTargets createRemoteAnimationTargetsForTaskId(
- RemoteAnimationTargets targets, int taskId) {
- RemoteAnimationTarget[] targetApp = null;
- for (RemoteAnimationTarget targetCompat : targets.unfilteredApps) {
- if (targetCompat.taskId == taskId) {
- targetApp = new RemoteAnimationTarget[]{targetCompat};
- break;
- }
- }
-
- if (targetApp == null) {
- targetApp = new RemoteAnimationTarget[0];
- }
-
- return new RemoteAnimationTargets(targetApp, targets.wallpapers, targets.nonApps,
- targets.targetMode);
- }
-
- /**
* The object returned by this is may be modified in
* {@link #assignTargetsForSplitScreen(RemoteAnimationTargets)}, specifically the length of the
* array may be shortened based on the number of RemoteAnimationTargets present.
diff --git a/quickstep/src/com/android/quickstep/TaskAnimationManager.java b/quickstep/src/com/android/quickstep/TaskAnimationManager.java
index 3b1ed46..dec8a12 100644
--- a/quickstep/src/com/android/quickstep/TaskAnimationManager.java
+++ b/quickstep/src/com/android/quickstep/TaskAnimationManager.java
@@ -17,6 +17,7 @@
import static android.app.WindowConfiguration.ACTIVITY_TYPE_HOME;
+import static com.android.launcher3.Flags.enableHandleDelayedGestureCallbacks;
import static com.android.launcher3.util.Executors.MAIN_EXECUTOR;
import static com.android.launcher3.util.Executors.UI_HELPER_EXECUTOR;
import static com.android.launcher3.util.NavigationMode.NO_BUTTON;
@@ -49,6 +50,7 @@
import com.android.systemui.shared.system.TaskStackChangeListener;
import com.android.systemui.shared.system.TaskStackChangeListeners;
+import java.io.PrintWriter;
import java.util.HashMap;
public class TaskAnimationManager implements RecentsAnimationCallbacks.RecentsAnimationListener {
@@ -67,6 +69,7 @@
private Context mCtx;
private boolean mRecentsAnimationStartPending = false;
+ private boolean mShouldIgnoreMotionEvents = false;
private final TaskStackChangeListener mLiveTileRestartListener = new TaskStackChangeListener() {
@Override
@@ -103,8 +106,16 @@
.startRecentsActivity(intent, 0, null, null, null));
}
- public boolean isRecentsAnimationStartPending() {
- return mRecentsAnimationStartPending;
+ boolean shouldIgnoreMotionEvents() {
+ return mShouldIgnoreMotionEvents;
+ }
+
+ void notifyNewGestureStart() {
+ // If mRecentsAnimationStartPending is true at the beginning of a gesture, block all motion
+ // events for this new gesture so that this new gesture does not interfere with the
+ // previously-requested recents animation. Otherwise, clean up mShouldIgnoreMotionEvents.
+ // NOTE: this can lead to misleading logs
+ mShouldIgnoreMotionEvents = mRecentsAnimationStartPending;
}
/**
@@ -145,7 +156,12 @@
@Override
public void onRecentsAnimationStart(RecentsAnimationController controller,
RecentsAnimationTargets targets) {
- mRecentsAnimationStartPending = false;
+ if (enableHandleDelayedGestureCallbacks() && mRecentsAnimationStartPending) {
+ ActiveGestureLog.INSTANCE.addLog(new ActiveGestureLog.CompoundString(
+ "TaskAnimationManager.startRecentsAnimation(onRecentsAnimationStart): ")
+ .append("Setting mRecentsAnimationStartPending = false"));
+ mRecentsAnimationStartPending = false;
+ }
if (mCallbacks == null) {
// It's possible for the recents animation to have finished and be cleaned up
// by the time we process the start callback, and in that case, just we can skip
@@ -186,13 +202,25 @@
@Override
public void onRecentsAnimationCanceled(HashMap<Integer, ThumbnailData> thumbnailDatas) {
- mRecentsAnimationStartPending = false;
+ if (enableHandleDelayedGestureCallbacks() && mRecentsAnimationStartPending) {
+ ActiveGestureLog.INSTANCE.addLog(new ActiveGestureLog.CompoundString(
+ "TaskAnimationManager.startRecentsAnimation")
+ .append("(onRecentsAnimationCanceled): ")
+ .append("Setting mRecentsAnimationStartPending = false"));
+ mRecentsAnimationStartPending = false;
+ }
cleanUpRecentsAnimation(newCallbacks);
}
@Override
public void onRecentsAnimationFinished(RecentsAnimationController controller) {
- mRecentsAnimationStartPending = false;
+ if (enableHandleDelayedGestureCallbacks() && mRecentsAnimationStartPending) {
+ ActiveGestureLog.INSTANCE.addLog(new ActiveGestureLog.CompoundString(
+ "TaskAnimationManager.startRecentsAnimation")
+ .append("(onRecentsAnimationFinished): ")
+ .append("Setting mRecentsAnimationStartPending = false"));
+ mRecentsAnimationStartPending = false;
+ }
cleanUpRecentsAnimation(newCallbacks);
}
@@ -303,13 +331,29 @@
options.setSourceInfo(ActivityOptions.SourceInfo.TYPE_RECENTS_ANIMATION, eventTime);
mRecentsAnimationStartPending = SystemUiProxy.INSTANCE.getNoCreate()
.startRecentsActivity(intent, options, mCallbacks);
+ if (enableHandleDelayedGestureCallbacks()) {
+ ActiveGestureLog.INSTANCE.addLog(new ActiveGestureLog.CompoundString(
+ "TaskAnimationManager.startRecentsAnimation(shell transition path): ")
+ .append("Setting mRecentsAnimationStartPending = ")
+ .append(mRecentsAnimationStartPending));
+ }
} else {
UI_HELPER_EXECUTOR.execute(
() -> ActivityManagerWrapper.getInstance().startRecentsActivity(
intent,
eventTime,
mCallbacks,
- result -> mRecentsAnimationStartPending = result,
+ result -> {
+ if (enableHandleDelayedGestureCallbacks()) {
+ ActiveGestureLog.INSTANCE.addLog(
+ new ActiveGestureLog.CompoundString(
+ "TaskAnimationManager.startRecentsAnimation")
+ .append("(legacy path): Setting ")
+ .append("mRecentsAnimationStartPending = ")
+ .append(result));
+ }
+ mRecentsAnimationStartPending = result;
+ },
MAIN_EXECUTOR.getHandler()));
}
gestureState.setState(STATE_RECENTS_ANIMATION_INITIALIZED);
@@ -439,7 +483,24 @@
return mCallbacks;
}
- public void dump() {
- // TODO
+ public void dump(String prefix, PrintWriter pw) {
+ pw.println(prefix + "TaskAnimationManager:");
+
+ if (enableHandleDelayedGestureCallbacks()) {
+ pw.println(prefix + "\tmRecentsAnimationStartPending=" + mRecentsAnimationStartPending);
+ pw.println(prefix + "\tmShouldIgnoreUpcomingGestures=" + mShouldIgnoreMotionEvents);
+ }
+ if (mController != null) {
+ mController.dump(prefix + '\t', pw);
+ }
+ if (mCallbacks != null) {
+ mCallbacks.dump(prefix + '\t', pw);
+ }
+ if (mTargets != null) {
+ mTargets.dump(prefix + '\t', pw);
+ }
+ if (mLastGestureState != null) {
+ mLastGestureState.dump(prefix + '\t', pw);
+ }
}
}
diff --git a/quickstep/src/com/android/quickstep/TouchInteractionService.java b/quickstep/src/com/android/quickstep/TouchInteractionService.java
index 6635ee4..a842b51 100644
--- a/quickstep/src/com/android/quickstep/TouchInteractionService.java
+++ b/quickstep/src/com/android/quickstep/TouchInteractionService.java
@@ -24,6 +24,7 @@
import static android.view.MotionEvent.ACTION_UP;
import static com.android.launcher3.Flags.enableCursorHoverStates;
+import static com.android.launcher3.Flags.enableHandleDelayedGestureCallbacks;
import static com.android.launcher3.Flags.useActivityOverlay;
import static com.android.launcher3.Launcher.INTENT_ACTION_ALL_APPS_TOGGLE;
import static com.android.launcher3.LauncherPrefs.backedUpItem;
@@ -41,6 +42,7 @@
import static com.android.quickstep.util.ActiveGestureErrorDetector.GestureEvent.MOTION_DOWN;
import static com.android.quickstep.util.ActiveGestureErrorDetector.GestureEvent.MOTION_MOVE;
import static com.android.quickstep.util.ActiveGestureErrorDetector.GestureEvent.MOTION_UP;
+import static com.android.quickstep.util.ActiveGestureErrorDetector.GestureEvent.RECENTS_ANIMATION_START_PENDING;
import static com.android.systemui.shared.system.ActivityManagerWrapper.CLOSE_SYSTEM_WINDOWS_REASON_RECENTS;
import static com.android.systemui.shared.system.QuickStepContract.KEY_EXTRA_SYSUI_PROXY;
import static com.android.systemui.shared.system.QuickStepContract.KEY_EXTRA_UNFOLD_ANIMATION_FORWARDER;
@@ -501,7 +503,6 @@
mTaskbarManager = new TaskbarManager(this, mAllAppsActionManager);
mRotationTouchHelper = mDeviceState.getRotationTouchHelper();
mInputConsumer = InputConsumerController.getRecentsAnimationInputConsumer();
- BootAwarePreloader.start(this);
// Call runOnUserUnlocked() before any other callbacks to ensure everything is initialized.
LockedUserState.get(this).runOnUserUnlocked(this::onUserUnlocked);
@@ -716,16 +717,22 @@
boolean isHoverActionWithoutConsumer = enableCursorHoverStates()
&& isHoverActionWithoutConsumer(event);
- // TODO(b/285636175): Uncomment this once WM can properly guarantee all animation callbacks
-// if (mTaskAnimationManager.isRecentsAnimationStartPending()
-// && (action == ACTION_DOWN || isHoverActionWithoutConsumer)) {
-// ActiveGestureLog.INSTANCE.addLog(
-// new CompoundString("TIS.onInputEvent: ")
-// .append("Cannot process input event: a recents animation has been ")
-// .append("requested, but hasn't started."),
-// RECENTS_ANIMATION_START_PENDING);
-// return;
-// }
+ if (enableHandleDelayedGestureCallbacks()) {
+ if (action == ACTION_DOWN || isHoverActionWithoutConsumer) {
+ mTaskAnimationManager.notifyNewGestureStart();
+ }
+ if (mTaskAnimationManager.shouldIgnoreMotionEvents()) {
+ if (action == ACTION_DOWN || isHoverActionWithoutConsumer) {
+ ActiveGestureLog.INSTANCE.addLog(
+ new CompoundString("TIS.onMotionEvent: A new gesture has been ")
+ .append("started, but a previously-requested recents ")
+ .append("animation hasn't started. Ignoring all following ")
+ .append("motion events."),
+ RECENTS_ANIMATION_START_PENDING);
+ }
+ return;
+ }
+ }
SafeCloseable traceToken = TraceHelper.INSTANCE.allowIpcs("TIS.onInputEvent");
@@ -751,7 +758,6 @@
GestureState prevGestureState = new GestureState(mGestureState);
GestureState newGestureState = createGestureState(mGestureState,
getTrackpadGestureType(event));
- newGestureState.setSwipeUpStartTimeMs(SystemClock.uptimeMillis());
mConsumer.onConsumerAboutToBeSwitched();
mGestureState = newGestureState;
mConsumer = newConsumer(prevGestureState, mGestureState, event);
@@ -1431,28 +1437,31 @@
mOverviewCommandHelper.dump(pw);
}
if (mGestureState != null) {
- mGestureState.dump(pw);
+ mGestureState.dump("", pw);
}
pw.println("Input state:");
- pw.println(" mInputMonitorCompat=" + mInputMonitorCompat);
- pw.println(" mInputEventReceiver=" + mInputEventReceiver);
+ pw.println("\tmInputMonitorCompat=" + mInputMonitorCompat);
+ pw.println("\tmInputEventReceiver=" + mInputEventReceiver);
DisplayController.INSTANCE.get(this).dump(pw);
pw.println("TouchState:");
BaseDraggingActivity createdOverviewActivity = mOverviewComponentObserver == null ? null
: mOverviewComponentObserver.getActivityInterface().getCreatedContainer();
boolean resumed = mOverviewComponentObserver != null
&& mOverviewComponentObserver.getActivityInterface().isResumed();
- pw.println(" createdOverviewActivity=" + createdOverviewActivity);
- pw.println(" resumed=" + resumed);
- pw.println(" mConsumer=" + mConsumer.getName());
+ pw.println("\tcreatedOverviewActivity=" + createdOverviewActivity);
+ pw.println("\tresumed=" + resumed);
+ pw.println("\tmConsumer=" + mConsumer.getName());
ActiveGestureLog.INSTANCE.dump("", pw);
RecentsModel.INSTANCE.get(this).dump("", pw);
+ if (mTaskAnimationManager != null) {
+ mTaskAnimationManager.dump("", pw);
+ }
if (createdOverviewActivity != null) {
createdOverviewActivity.getDeviceProfile().dump(this, "", pw);
}
mTaskbarManager.dumpLogs("", pw);
pw.println("AssistStateManager:");
- AssistStateManager.INSTANCE.get(this).dump(" ", pw);
+ AssistStateManager.INSTANCE.get(this).dump("\t", pw);
SystemUiProxy.INSTANCE.get(this).dump(pw);
DeviceConfigWrapper.get().dump(" ", pw);
}
diff --git a/quickstep/src/com/android/quickstep/util/ActiveGestureErrorDetector.java b/quickstep/src/com/android/quickstep/util/ActiveGestureErrorDetector.java
index e3772bd..cfa6b98 100644
--- a/quickstep/src/com/android/quickstep/util/ActiveGestureErrorDetector.java
+++ b/quickstep/src/com/android/quickstep/util/ActiveGestureErrorDetector.java
@@ -277,7 +277,8 @@
errorDetected |= printErrorIfTrue(
true,
prefix,
- /* errorMessage= */ "new gesture attempted while a requested recents"
+ /* errorMessage= */ (eventEntry.getDuplicateCount() + 1)
+ + " gesture(s) attempted while a requested recents"
+ " animation is still pending.",
writer);
break;
diff --git a/quickstep/src/com/android/quickstep/util/ActiveGestureLog.java b/quickstep/src/com/android/quickstep/util/ActiveGestureLog.java
index 1e05a69..c54862a 100644
--- a/quickstep/src/com/android/quickstep/util/ActiveGestureLog.java
+++ b/quickstep/src/com/android/quickstep/util/ActiveGestureLog.java
@@ -216,6 +216,10 @@
return gestureEvent;
}
+ public int getDuplicateCount() {
+ return duplicateCount;
+ }
+
private void update(
@NonNull CompoundString compoundString,
ActiveGestureErrorDetector.GestureEvent gestureEvent) {
diff --git a/quickstep/src/com/android/quickstep/util/AppPairsController.java b/quickstep/src/com/android/quickstep/util/AppPairsController.java
index 3f06571..2b4d280 100644
--- a/quickstep/src/com/android/quickstep/util/AppPairsController.java
+++ b/quickstep/src/com/android/quickstep/util/AppPairsController.java
@@ -265,9 +265,7 @@
}
if (ai != null) {
- wii.status = ai.resizeMode == ActivityInfo.RESIZE_MODE_UNRESIZEABLE
- ? wii.status | WorkspaceItemInfo.FLAG_NON_RESIZEABLE
- : wii.status & ~WorkspaceItemInfo.FLAG_NON_RESIZEABLE;
+ wii.setNonResizeable(ai.resizeMode == ActivityInfo.RESIZE_MODE_UNRESIZEABLE);
}
}
diff --git a/quickstep/src/com/android/quickstep/util/AssistStateManager.java b/quickstep/src/com/android/quickstep/util/AssistStateManager.java
index a3904bc..4a35c3b 100644
--- a/quickstep/src/com/android/quickstep/util/AssistStateManager.java
+++ b/quickstep/src/com/android/quickstep/util/AssistStateManager.java
@@ -20,12 +20,13 @@
import com.android.launcher3.R;
import com.android.launcher3.util.MainThreadInitializedObject;
import com.android.launcher3.util.ResourceBasedOverride;
+import com.android.launcher3.util.SafeCloseable;
import java.io.PrintWriter;
import java.util.Optional;
/** Class to manage Assistant states. */
-public class AssistStateManager implements ResourceBasedOverride {
+public class AssistStateManager implements ResourceBasedOverride, SafeCloseable {
public static final MainThreadInitializedObject<AssistStateManager> INSTANCE =
forOverride(AssistStateManager.class, R.string.assist_state_manager_class);
@@ -42,6 +43,11 @@
return false;
}
+ /** Whether search supports showing on the lockscreen. */
+ public boolean supportsShowWhenLocked() {
+ return false;
+ }
+
/** Whether CsHelper CtS invocation path is available. */
public Optional<Boolean> isCsHelperAvailable() {
return Optional.empty();
@@ -91,4 +97,7 @@
/** Dump states. */
public void dump(String prefix, PrintWriter writer) {}
+
+ @Override
+ public void close() {}
}
diff --git a/quickstep/src/com/android/quickstep/util/RectFSpringAnim.java b/quickstep/src/com/android/quickstep/util/RectFSpringAnim.java
index c39056d..5505bb3 100644
--- a/quickstep/src/com/android/quickstep/util/RectFSpringAnim.java
+++ b/quickstep/src/com/android/quickstep/util/RectFSpringAnim.java
@@ -171,8 +171,13 @@
public void onTargetPositionChanged() {
if (enableScalingRevealHomeAnimation()) {
+ if (isEnded()) {
+ return;
+ }
+
if (mRectXSpring != null) {
mRectXSpring.animateToFinalPosition(mTargetRect.centerX());
+ mRectXAnimEnded = false;
}
if (mRectYSpring != null) {
@@ -187,6 +192,7 @@
mRectYSpring.animateToFinalPosition(mTargetRect.centerY());
break;
}
+ mRectYAnimEnded = false;
}
} else {
if (mRectXAnim != null && mRectXAnim.getTargetPosition() != mTargetRect.centerX()) {
@@ -297,6 +303,7 @@
.setStiffness(stiffnessZ)
.setDampingRatio(dampingZ))
.setStartVelocity(velocityPxPerMs.y * minVisibleChange)
+ .setMaxValue(1f)
.setMinimumVisibleChange(minVisibleChange)
.addEndListener((animation, canceled, value, velocity) -> {
mRectScaleAnimEnded = true;
diff --git a/quickstep/src/com/android/quickstep/util/ScalingWorkspaceRevealAnim.kt b/quickstep/src/com/android/quickstep/util/ScalingWorkspaceRevealAnim.kt
index 48c2407..1bf77f1 100644
--- a/quickstep/src/com/android/quickstep/util/ScalingWorkspaceRevealAnim.kt
+++ b/quickstep/src/com/android/quickstep/util/ScalingWorkspaceRevealAnim.kt
@@ -16,7 +16,10 @@
package com.android.quickstep.util
+import android.graphics.Matrix
+import android.graphics.RectF
import android.view.View
+import androidx.core.graphics.transform
import com.android.app.animation.Interpolators
import com.android.app.animation.Interpolators.EMPHASIZED
import com.android.app.animation.Interpolators.LINEAR
@@ -38,7 +41,11 @@
* Creates an animation where the workspace and hotseat fade in while revealing from the center of
* the screen outwards radially. This is used in conjunction with the swipe up to home animation.
*/
-class ScalingWorkspaceRevealAnim(launcher: QuickstepLauncher) {
+class ScalingWorkspaceRevealAnim(
+ launcher: QuickstepLauncher,
+ siblingAnimation: RectFSpringAnim?,
+ windowTargetRect: RectF?
+) {
companion object {
private const val FADE_DURATION_MS = 200L
private const val SCALE_DURATION_MS = 1000L
@@ -52,11 +59,11 @@
init {
// Make sure the starting state is right for the animation.
- val config = StateAnimationConfig()
- config.animFlags = SKIP_OVERVIEW.or(SKIP_DEPTH_CONTROLLER).or(SKIP_SCRIM)
- config.duration = 0
+ val setupConfig = StateAnimationConfig()
+ setupConfig.animFlags = SKIP_OVERVIEW.or(SKIP_DEPTH_CONTROLLER).or(SKIP_SCRIM)
+ setupConfig.duration = 0
launcher.stateManager
- .createAtomicAnimation(LauncherState.BACKGROUND_APP, LauncherState.NORMAL, config)
+ .createAtomicAnimation(LauncherState.BACKGROUND_APP, LauncherState.NORMAL, setupConfig)
.start()
launcher
.getOverviewPanel<RecentsView<QuickstepLauncher, LauncherState>>()
@@ -64,7 +71,7 @@
launcher.workspace.stateTransitionAnimation.setScrim(
PropertySetter.NO_ANIM_PROPERTY_SETTER,
LauncherState.BACKGROUND_APP,
- config
+ setupConfig
)
val workspace = launcher.workspace
@@ -103,11 +110,55 @@
Interpolators.clampToProgress(LINEAR, 0f, fadeClamp)
)
+ val transitionConfig = StateAnimationConfig()
+
// Match the Wallpaper animation to the rest of the content.
val depthController = (launcher as? QuickstepLauncher)?.depthController
- val depthConfig = StateAnimationConfig()
- depthConfig.setInterpolator(StateAnimationConfig.ANIM_DEPTH, EMPHASIZED)
- depthController?.setStateWithAnimation(LauncherState.NORMAL, depthConfig, animation)
+ transitionConfig.setInterpolator(StateAnimationConfig.ANIM_DEPTH, EMPHASIZED)
+ depthController?.setStateWithAnimation(LauncherState.NORMAL, transitionConfig, animation)
+
+ // Make sure that the contrast scrim animates correctly if needed.
+ transitionConfig.setInterpolator(StateAnimationConfig.ANIM_SCRIM_FADE, EMPHASIZED)
+ launcher.workspace.stateTransitionAnimation.setScrim(
+ animation,
+ LauncherState.NORMAL,
+ transitionConfig
+ )
+
+ // To avoid awkward jumps in icon position, we want the sibling animation to always be
+ // targeting the current position. Since we can't easily access this, instead we calculate
+ // it using the animation of the whole of home.
+ // We start by caching the final target position, as this is the base for the transforms.
+ val originalTarget = RectF(windowTargetRect)
+ animation.addOnFrameListener {
+ val transformed = RectF(originalTarget)
+
+ // First we scale down using the same pivot as the workspace scale, so we find the
+ // correct position AND size.
+ transformed.transform(
+ Matrix().apply {
+ setScale(workspace.scaleX, workspace.scaleY, workspace.pivotX, workspace.pivotY)
+ }
+ )
+ // Then we scale back up around the center of the current position. This is because the
+ // icon animation behaves poorly if it is given a target that is smaller than the size
+ // of the icon.
+ transformed.transform(
+ Matrix().apply {
+ setScale(
+ 1 / workspace.scaleX,
+ 1 / workspace.scaleY,
+ transformed.centerX(),
+ transformed.centerY()
+ )
+ }
+ )
+
+ if (transformed != windowTargetRect) {
+ windowTargetRect?.set(transformed)
+ siblingAnimation?.onTargetPositionChanged()
+ }
+ }
// Needed to avoid text artefacts during the scale animation.
workspace.setLayerType(View.LAYER_TYPE_HARDWARE, null)
diff --git a/quickstep/src/com/android/quickstep/util/SwipePipToHomeAnimator.java b/quickstep/src/com/android/quickstep/util/SwipePipToHomeAnimator.java
index 6c89be1..f823aff 100644
--- a/quickstep/src/com/android/quickstep/util/SwipePipToHomeAnimator.java
+++ b/quickstep/src/com/android/quickstep/util/SwipePipToHomeAnimator.java
@@ -112,7 +112,7 @@
@NonNull ActivityInfo activityInfo,
int appIconSizePx,
@NonNull SurfaceControl leash,
- @Nullable Rect sourceRectHint,
+ @NonNull Rect sourceRectHint,
@NonNull Rect appBounds,
@NonNull Matrix homeToWindowPositionMap,
@NonNull RectF startBounds,
@@ -135,22 +135,25 @@
mDestinationBoundsTransformed.set(destinationBoundsTransformed);
mSurfaceTransactionHelper = new PipSurfaceTransactionHelper(cornerRadius, shadowRadius);
- if (sourceRectHint != null && (sourceRectHint.width() < destinationBounds.width()
- || sourceRectHint.height() < destinationBounds.height())) {
+ String reasonForCreateOverlay = null; // For debugging purpose.
+ if (sourceRectHint.isEmpty()) {
+ reasonForCreateOverlay = "Source rect hint is empty";
+ } else if (sourceRectHint.width() < destinationBounds.width()
+ || sourceRectHint.height() < destinationBounds.height()) {
// This is a situation in which the source hint rect on at least one axis is smaller
// than the destination bounds, which presents a problem because we would have to scale
// up that axis to fit the bounds. So instead, just fallback to the non-source hint
// animation in this case.
- sourceRectHint = null;
- }
-
- if (sourceRectHint != null && !appBounds.contains(sourceRectHint)) {
+ reasonForCreateOverlay = "Source rect hint is too small " + sourceRectHint;
+ sourceRectHint.setEmpty();
+ } else if (!appBounds.contains(sourceRectHint)) {
// This is a situation in which the source hint rect is outside the app bounds, so it is
// not a valid rectangle to use for cropping app surface
- sourceRectHint = null;
+ sourceRectHint.setEmpty();
+ reasonForCreateOverlay = "Source rect hint exceeds display bounds " + sourceRectHint;
}
- if (sourceRectHint == null) {
+ if (sourceRectHint.isEmpty()) {
mSourceRectHint.setEmpty();
mSourceHintRectInsets = null;
@@ -162,6 +165,7 @@
new IconProvider(context).getIcon(mActivityInfo), appIconSizePx);
final SurfaceControl.Transaction tx = new SurfaceControl.Transaction();
mPipContentOverlay.attach(tx, mLeash);
+ Log.d(TAG, getContentOverlay() + " is created: " + reasonForCreateOverlay);
} else {
mSourceRectHint.set(sourceRectHint);
mSourceHintRectInsets = new Rect(sourceRectHint.left - appBounds.left,
diff --git a/quickstep/src/com/android/quickstep/views/LauncherRecentsView.java b/quickstep/src/com/android/quickstep/views/LauncherRecentsView.java
index 06c2aa3..8d1907f 100644
--- a/quickstep/src/com/android/quickstep/views/LauncherRecentsView.java
+++ b/quickstep/src/com/android/quickstep/views/LauncherRecentsView.java
@@ -26,6 +26,7 @@
import static com.android.launcher3.LauncherState.OVERVIEW_SPLIT_SELECT;
import static com.android.launcher3.LauncherState.SPRING_LOADED;
import static com.android.launcher3.logging.StatsLogManager.LauncherEvent.LAUNCHER_SPLIT_SELECTION_EXIT_HOME;
+import static com.android.window.flags.Flags.enableDesktopWindowingWallpaperActivity;
import android.annotation.TargetApi;
import android.content.Context;
@@ -260,7 +261,8 @@
super.onGestureAnimationStart(runningTasks, rotationTouchHelper);
DesktopVisibilityController desktopVisibilityController =
mContainer.getDesktopVisibilityController();
- if (desktopVisibilityController != null) {
+ if (!enableDesktopWindowingWallpaperActivity() && desktopVisibilityController != null) {
+ // TODO: b/333533253 - Remove after flag rollout
desktopVisibilityController.setRecentsGestureStart();
}
}
@@ -282,7 +284,8 @@
}
}
super.onGestureAnimationEnd();
- if (desktopVisibilityController != null) {
+ if (!enableDesktopWindowingWallpaperActivity() && desktopVisibilityController != null) {
+ // TODO: b/333533253 - Remove after flag rollout
desktopVisibilityController.setRecentsGestureEnd(endTarget);
}
if (showDesktopApps) {
diff --git a/quickstep/src/com/android/quickstep/views/RecentsView.java b/quickstep/src/com/android/quickstep/views/RecentsView.java
index 791ef04..ae6f703 100644
--- a/quickstep/src/com/android/quickstep/views/RecentsView.java
+++ b/quickstep/src/com/android/quickstep/views/RecentsView.java
@@ -68,7 +68,6 @@
import static com.android.quickstep.views.OverviewActionsView.HIDDEN_NO_TASKS;
import static com.android.quickstep.views.OverviewActionsView.HIDDEN_SPLIT_SCREEN;
import static com.android.quickstep.views.OverviewActionsView.HIDDEN_SPLIT_SELECT_ACTIVE;
-import static com.android.window.flags.Flags.enableDesktopWindowingMode;
import android.animation.Animator;
import android.animation.AnimatorListenerAdapter;
@@ -167,6 +166,7 @@
import com.android.launcher3.util.VibratorWrapper;
import com.android.launcher3.util.ViewPool;
import com.android.quickstep.BaseContainerInterface;
+import com.android.quickstep.DesktopModeStatus;
import com.android.quickstep.GestureState;
import com.android.quickstep.OverviewCommandHelper;
import com.android.quickstep.RecentsAnimationController;
@@ -2817,7 +2817,7 @@
}
private boolean hasDesktopTask(Task[] runningTasks) {
- if (!enableDesktopWindowingMode()) {
+ if (!DesktopModeStatus.canEnterDesktopMode(mContext)) {
return false;
}
for (Task task : runningTasks) {
@@ -6229,7 +6229,7 @@
*/
public void moveTaskToDesktop(TaskIdAttributeContainer taskContainer,
Runnable successCallback) {
- if (!enableDesktopWindowingMode()) {
+ if (!DesktopModeStatus.canEnterDesktopMode(mContext)) {
return;
}
switchToScreenshot(() -> finishRecentsAnimation(/* toRecents= */true, /* shouldPip= */false,
diff --git a/quickstep/tests/multivalentTests/src/com/android/launcher3/taskbar/bubbles/animation/BubbleBarViewAnimatorTest.kt b/quickstep/tests/multivalentTests/src/com/android/launcher3/taskbar/bubbles/animation/BubbleBarViewAnimatorTest.kt
index b478efa..d90e048 100644
--- a/quickstep/tests/multivalentTests/src/com/android/launcher3/taskbar/bubbles/animation/BubbleBarViewAnimatorTest.kt
+++ b/quickstep/tests/multivalentTests/src/com/android/launcher3/taskbar/bubbles/animation/BubbleBarViewAnimatorTest.kt
@@ -16,19 +16,15 @@
package com.android.launcher3.taskbar.bubbles.animation
-import android.animation.Animator
-import android.animation.AnimatorListenerAdapter
-import android.animation.AnimatorSet
import android.content.Context
import android.graphics.Color
import android.graphics.Path
import android.graphics.drawable.ColorDrawable
import android.view.LayoutInflater
+import android.view.View
import android.view.View.INVISIBLE
import android.view.View.VISIBLE
import android.widget.FrameLayout
-import androidx.core.animation.AnimatorTestRule
-import androidx.core.animation.doOnEnd
import androidx.core.graphics.drawable.toBitmap
import androidx.dynamicanimation.animation.DynamicAnimation
import androidx.test.core.app.ApplicationProvider
@@ -42,16 +38,13 @@
import com.android.launcher3.taskbar.bubbles.BubbleStashController
import com.android.launcher3.taskbar.bubbles.BubbleView
import com.android.wm.shell.common.bubbles.BubbleInfo
+import com.android.wm.shell.shared.animation.PhysicsAnimator
import com.android.wm.shell.shared.animation.PhysicsAnimatorTestUtils
import com.google.common.truth.Truth.assertThat
-import java.util.concurrent.Semaphore
-import java.util.concurrent.TimeUnit
import org.junit.Before
-import org.junit.ClassRule
import org.junit.Test
import org.junit.runner.RunWith
import org.mockito.kotlin.mock
-import org.mockito.kotlin.verify
import org.mockito.kotlin.whenever
@SmallTest
@@ -61,10 +54,6 @@
private val context = ApplicationProvider.getApplicationContext<Context>()
private val animatorScheduler = TestBubbleBarViewAnimatorScheduler()
- companion object {
- @JvmField @ClassRule val animatorTestRule = AnimatorTestRule()
- }
-
@Before
fun setUp() {
PhysicsAnimatorTestUtils.prepareForTest()
@@ -99,14 +88,9 @@
val bubbleStashController = mock<BubbleStashController>()
whenever(bubbleStashController.isStashed).thenReturn(true)
- val semaphore = Semaphore(0)
- val hideHandleAnimator = AnimatorSet()
- hideHandleAnimator.duration = 0
- whenever(bubbleStashController.buildHideHandleAnimationForNewBubble())
- .thenReturn(hideHandleAnimator)
- // add an end listener to the hide handle animation. we add it when the animation starts
- // to ensure that it gets called after all other end listeners.
- hideHandleAnimator.doOnStart { hideHandleAnimator.doOnEnd { semaphore.release() } }
+ val handle = View(context)
+ val handleAnimator = PhysicsAnimator.getInstance(handle)
+ whenever(bubbleStashController.stashedHandlePhysicsAnimator).thenReturn(handleAnimator)
val animator =
BubbleBarViewAnimator(bubbleBarView, bubbleStashController, animatorScheduler)
@@ -115,44 +99,26 @@
animator.animateBubbleInForStashed(bubble)
}
- // wait for the stash handle animation to complete
- assertThat(semaphore.tryAcquire(5, TimeUnit.SECONDS)).isTrue()
- // stash handle animation finished. verify that the stash handle is now hidden
- verify(bubbleStashController).setStashAlpha(0f)
-
+ // let the animation start and wait for it to complete
InstrumentationRegistry.getInstrumentation().waitForIdleSync()
+ PhysicsAnimatorTestUtils.blockUntilAnimationsEnd(DynamicAnimation.TRANSLATION_Y)
+ assertThat(handle.alpha).isEqualTo(0)
+ assertThat(handle.translationY).isEqualTo(-70)
assertThat(overflowView.visibility).isEqualTo(INVISIBLE)
assertThat(bubbleBarView.visibility).isEqualTo(VISIBLE)
assertThat(bubbleView.visibility).isEqualTo(VISIBLE)
-
- // wait for the show bubble animation to complete
- PhysicsAnimatorTestUtils.blockUntilAnimationsEnd(
- DynamicAnimation.ALPHA,
- DynamicAnimation.TRANSLATION_Y,
- DynamicAnimation.SCALE_Y,
- )
-
assertThat(bubbleView.alpha).isEqualTo(1)
- assertThat(bubbleView.translationY).isEqualTo(-50)
+ assertThat(bubbleView.translationY).isEqualTo(-20)
assertThat(bubbleView.scaleY).isEqualTo(1)
- val showHandleAnimator = AnimatorSet()
- showHandleAnimator.duration = 0
- whenever(bubbleStashController.buildShowHandleAnimationForNewBubble())
- .thenReturn(showHandleAnimator)
- var showHandleAnimationStarted = false
- showHandleAnimator.doOnStart { showHandleAnimationStarted = true }
-
// execute the hide bubble animation
assertThat(animatorScheduler.delayedBlock).isNotNull()
InstrumentationRegistry.getInstrumentation().runOnMainSync(animatorScheduler.delayedBlock!!)
- // finish the hide bubble animation
- InstrumentationRegistry.getInstrumentation().runOnMainSync {
- animatorTestRule.advanceTimeBy(250)
- }
- assertThat(showHandleAnimationStarted).isTrue()
+ // let the animation start and wait for it to complete
+ InstrumentationRegistry.getInstrumentation().waitForIdleSync()
+ PhysicsAnimatorTestUtils.blockUntilAnimationsEnd(DynamicAnimation.TRANSLATION_Y)
assertThat(bubbleView.alpha).isEqualTo(1)
assertThat(bubbleView.visibility).isEqualTo(VISIBLE)
@@ -160,16 +126,8 @@
assertThat(bubbleBarView.alpha).isEqualTo(0)
assertThat(overflowView.alpha).isEqualTo(1)
assertThat(overflowView.visibility).isEqualTo(VISIBLE)
- }
-
- private fun AnimatorSet.doOnStart(onStart: () -> Unit) {
- addListener(
- object : AnimatorListenerAdapter() {
- override fun onAnimationStart(animator: Animator) {
- onStart()
- }
- }
- )
+ assertThat(handle.alpha).isEqualTo(1)
+ assertThat(handle.translationY).isEqualTo(0)
}
private class TestBubbleBarViewAnimatorScheduler : BubbleBarViewAnimator.Scheduler {
diff --git a/quickstep/tests/src/com/android/launcher3/taskbar/bubbles/OWNERS b/quickstep/tests/src/com/android/launcher3/taskbar/bubbles/OWNERS
new file mode 100644
index 0000000..3f947a0
--- /dev/null
+++ b/quickstep/tests/src/com/android/launcher3/taskbar/bubbles/OWNERS
@@ -0,0 +1,5 @@
+atsjenk@google.com
+liranb@google.com
+madym@google.com
+mpodolian@google.com
+
diff --git a/quickstep/tests/src/com/android/quickstep/DesktopSystemShortcutTest.kt b/quickstep/tests/src/com/android/quickstep/DesktopSystemShortcutTest.kt
index 7dabbca..0f9d96c 100644
--- a/quickstep/tests/src/com/android/quickstep/DesktopSystemShortcutTest.kt
+++ b/quickstep/tests/src/com/android/quickstep/DesktopSystemShortcutTest.kt
@@ -16,12 +16,14 @@
package com.android.quickstep
+import com.android.dx.mockito.inline.extended.ExtendedMockito.doReturn
+import com.android.dx.mockito.inline.extended.ExtendedMockito.mockitoSession
+import com.android.dx.mockito.inline.extended.StaticMockitoSession
import android.content.ComponentName
import android.content.Intent
import android.platform.test.flag.junit.SetFlagsRule
import com.android.launcher3.AbstractFloatingView
import com.android.launcher3.AbstractFloatingViewHelper
-import com.android.launcher3.Launcher
import com.android.launcher3.logging.StatsLogManager
import com.android.launcher3.logging.StatsLogManager.LauncherEvent
import com.android.launcher3.model.data.WorkspaceItemInfo
@@ -33,8 +35,11 @@
import com.android.systemui.shared.recents.model.Task.TaskKey
import com.android.window.flags.Flags
import com.google.common.truth.Truth.assertThat
+import org.junit.After
+import org.junit.Before
import org.junit.Rule
import org.junit.Test
+import org.mockito.quality.Strictness
import org.mockito.kotlin.any
import org.mockito.kotlin.eq
import org.mockito.kotlin.mock
@@ -56,8 +61,23 @@
private val factory: TaskShortcutFactory =
DesktopSystemShortcut.createFactory(abstractFloatingViewHelper)
+ private lateinit var mockitoSession: StaticMockitoSession
+
+ @Before
+ fun setUp(){
+ mockitoSession = mockitoSession().strictness(Strictness.LENIENT)
+ .spyStatic(DesktopModeStatus::class.java).startMocking()
+ doReturn(true).`when` { DesktopModeStatus.enforceDeviceRestrictions() }
+ doReturn(true).`when` { DesktopModeStatus.isDesktopModeSupported(any()) }
+ }
+
+ @After
+ fun tearDown(){
+ mockitoSession.finishMocking()
+ }
+
@Test
- fun createDesktopTaskShortcutFactory_featureOff() {
+ fun createDesktopTaskShortcutFactory_desktopModeDisabled() {
setFlagsRule.disableFlags(Flags.FLAG_ENABLE_DESKTOP_WINDOWING_MODE)
val task =
@@ -77,6 +97,49 @@
}
@Test
+ fun createDesktopTaskShortcutFactory_desktopModeEnabled_DeviceNotSupported() {
+ setFlagsRule.enableFlags(Flags.FLAG_ENABLE_DESKTOP_WINDOWING_MODE)
+ doReturn(false).`when` { DesktopModeStatus.isDesktopModeSupported(any()) }
+
+ val task =
+ Task(TaskKey(1, 0, Intent(), ComponentName("", ""), 0, 2000)).apply {
+ isDockable = true
+ }
+ val taskContainer =
+ taskView.TaskIdAttributeContainer(
+ task,
+ null,
+ null,
+ SplitConfigurationOptions.STAGE_POSITION_UNDEFINED
+ )
+
+ val shortcuts = factory.getShortcuts(launcher, taskContainer)
+ assertThat(shortcuts).isNull()
+ }
+
+ @Test
+ fun createDesktopTaskShortcutFactory_desktopModeEnabled_DeviceNotSupported_OverrideEnabled() {
+ setFlagsRule.enableFlags(Flags.FLAG_ENABLE_DESKTOP_WINDOWING_MODE)
+ doReturn(false).`when` { DesktopModeStatus.isDesktopModeSupported(any()) }
+ doReturn(false).`when` { DesktopModeStatus.enforceDeviceRestrictions() }
+
+ val task =
+ Task(TaskKey(1, 0, Intent(), ComponentName("", ""), 0, 2000)).apply {
+ isDockable = true
+ }
+ val taskContainer =
+ taskView.TaskIdAttributeContainer(
+ task,
+ null,
+ null,
+ SplitConfigurationOptions.STAGE_POSITION_UNDEFINED
+ )
+
+ val shortcuts = factory.getShortcuts(launcher, taskContainer)
+ assertThat(shortcuts).isNotNull()
+ }
+
+ @Test
fun createDesktopTaskShortcutFactory_undockable() {
setFlagsRule.enableFlags(Flags.FLAG_ENABLE_DESKTOP_WINDOWING_MODE)
diff --git a/quickstep/tests/src/com/android/quickstep/HotseatWidthCalculationTest.kt b/quickstep/tests/src/com/android/quickstep/HotseatWidthCalculationTest.kt
index b1ba4c6..a388510 100644
--- a/quickstep/tests/src/com/android/quickstep/HotseatWidthCalculationTest.kt
+++ b/quickstep/tests/src/com/android/quickstep/HotseatWidthCalculationTest.kt
@@ -42,6 +42,8 @@
assertThat(dp.hotseatBarEndOffset).isEqualTo(510)
assertThat(dp.numShownHotseatIcons).isEqualTo(6)
assertThat(dp.hotseatBorderSpace).isEqualTo(70)
+ assertThat(dp.hotseatColumnSpan).isEqualTo(6)
+ assertThat(dp.hotseatWidthPx).isEqualTo(1445)
assertThat(dp.getHotseatLayoutPadding(context).left).isEqualTo(150)
assertThat(dp.getHotseatLayoutPadding(context).right).isEqualTo(580)
@@ -64,6 +66,8 @@
assertThat(dp.hotseatBarEndOffset).isEqualTo(510)
assertThat(dp.numShownHotseatIcons).isEqualTo(4)
assertThat(dp.hotseatBorderSpace).isEqualTo(40)
+ assertThat(dp.hotseatColumnSpan).isEqualTo(6)
+ assertThat(dp.hotseatWidthPx).isEqualTo(1080)
assertThat(dp.getHotseatLayoutPadding(context).left).isEqualTo(150)
assertThat(dp.getHotseatLayoutPadding(context).right).isEqualTo(550)
@@ -85,6 +89,8 @@
assertThat(dp.hotseatBarEndOffset).isEqualTo(705)
assertThat(dp.numShownHotseatIcons).isEqualTo(6)
assertThat(dp.hotseatBorderSpace).isEqualTo(54)
+ assertThat(dp.hotseatColumnSpan).isEqualTo(6)
+ assertThat(dp.hotseatWidthPx).isEqualTo(1468)
assertThat(dp.getHotseatLayoutPadding(context).left).isEqualTo(231)
assertThat(dp.getHotseatLayoutPadding(context).right).isEqualTo(759)
@@ -100,22 +106,21 @@
@Test
fun nav_buttons_dont_interfere_with_required_hotseat_width() {
initializeVarsForTablet(isGestureMode = false, isLandscape = true)
- inv?.apply {
- hotseatColumnSpan = IntArray(4) { 4 }
- inlineQsb = BooleanArray(4) { false }
- }
+ inv?.apply { inlineQsb = BooleanArray(4) { false } }
val dp = newDP()
dp.isTaskbarPresentInApps = true
assertThat(dp.hotseatBarEndOffset).isEqualTo(660)
assertThat(dp.numShownHotseatIcons).isEqualTo(6)
assertThat(dp.hotseatBorderSpace).isEqualTo(100)
+ assertThat(dp.hotseatColumnSpan).isEqualTo(6)
+ assertThat(dp.hotseatWidthPx).isEqualTo(1975)
assertThat(dp.getHotseatLayoutPadding(context).left).isEqualTo(300)
assertThat(dp.getHotseatLayoutPadding(context).right).isEqualTo(1040)
assertThat(dp.isQsbInline).isFalse()
- assertThat(dp.hotseatQsbWidth).isEqualTo(1223)
+ assertThat(dp.hotseatQsbWidth).isEqualTo(1965)
}
/** This is a case when after setting the hotseat, the QSB width needs to be changed to fit */
@@ -128,13 +133,15 @@
assertThat(dp.hotseatBarEndOffset).isEqualTo(660)
assertThat(dp.numShownHotseatIcons).isEqualTo(6)
- assertThat(dp.hotseatBorderSpace).isEqualTo(36)
+ assertThat(dp.hotseatBorderSpace).isEqualTo(34)
+ assertThat(dp.hotseatColumnSpan).isEqualTo(4)
+ assertThat(dp.hotseatWidthPx).isEqualTo(1179)
- assertThat(dp.getHotseatLayoutPadding(context).left).isEqualTo(864)
- assertThat(dp.getHotseatLayoutPadding(context).right).isEqualTo(696)
+ assertThat(dp.getHotseatLayoutPadding(context).left).isEqualTo(876)
+ assertThat(dp.getHotseatLayoutPadding(context).right).isEqualTo(694)
assertThat(dp.isQsbInline).isTrue()
- assertThat(dp.hotseatQsbWidth).isEqualTo(528)
+ assertThat(dp.hotseatQsbWidth).isEqualTo(542)
}
/**
@@ -151,6 +158,8 @@
assertThat(dp.hotseatBarEndOffset).isEqualTo(660)
assertThat(dp.numShownHotseatIcons).isEqualTo(5)
assertThat(dp.hotseatBorderSpace).isEqualTo(36)
+ assertThat(dp.hotseatColumnSpan).isEqualTo(4)
+ assertThat(dp.hotseatWidthPx).isEqualTo(1095)
assertThat(dp.getHotseatLayoutPadding(context).left).isEqualTo(816)
assertThat(dp.getHotseatLayoutPadding(context).right).isEqualTo(700)
@@ -158,4 +167,23 @@
assertThat(dp.isQsbInline).isTrue()
assertThat(dp.hotseatQsbWidth).isEqualTo(480)
}
+
+ @Test
+ fun increase_span_when_space_between_icons_is_less_than_minimum() {
+ initializeVarsForTwoPanel(isGestureMode = false, isLandscape = false, rows = 5, cols = 5)
+ val dp = newDP()
+ dp.isTaskbarPresentInApps = true
+
+ assertThat(dp.hotseatBarEndOffset).isEqualTo(600)
+ assertThat(dp.numShownHotseatIcons).isEqualTo(6)
+ assertThat(dp.hotseatBorderSpace).isEqualTo(48)
+ assertThat(dp.hotseatColumnSpan).isEqualTo(8)
+ assertThat(dp.hotseatWidthPx).isEqualTo(1383)
+
+ assertThat(dp.getHotseatLayoutPadding(context).left).isEqualTo(126)
+ assertThat(dp.getHotseatLayoutPadding(context).right).isEqualTo(652)
+
+ assertThat(dp.isQsbInline).isFalse()
+ assertThat(dp.hotseatQsbWidth).isEqualTo(1372)
+ }
}
diff --git a/quickstep/tests/src/com/android/quickstep/TaplTestsKeyboardQuickSwitch.java b/quickstep/tests/src/com/android/quickstep/TaplTestsKeyboardQuickSwitch.java
index 7c2d41d..43ebb17 100644
--- a/quickstep/tests/src/com/android/quickstep/TaplTestsKeyboardQuickSwitch.java
+++ b/quickstep/tests/src/com/android/quickstep/TaplTestsKeyboardQuickSwitch.java
@@ -149,6 +149,13 @@
runTest(TestSurface.WIDGETS, TestCase.LAUNCH_OVERVIEW);
}
+ @Test
+ public void testLaunchSingleRecentTask() {
+ mLauncher.getLaunchedAppState().switchToOverview().dismissAllTasks();
+ startAppFast(CALCULATOR_APP_PACKAGE);
+ mLauncher.goHome().showQuickSwitchView().launchFocusedAppTask(CALCULATOR_APP_PACKAGE);
+ }
+
private void runTest(@NonNull TestSurface testSurface, @NonNull TestCase testCase) {
for (int i = 0; i < testCase.mNumAdditionalRunningTasks; i++) {
startTestActivity(3 + i);
diff --git a/quickstep/tests/src/com/android/quickstep/TaplTestsTransientTaskbar.java b/quickstep/tests/src/com/android/quickstep/TaplTestsTransientTaskbar.java
index d04e389..4b20d60 100644
--- a/quickstep/tests/src/com/android/quickstep/TaplTestsTransientTaskbar.java
+++ b/quickstep/tests/src/com/android/quickstep/TaplTestsTransientTaskbar.java
@@ -17,8 +17,6 @@
import static com.android.launcher3.Flags.enableCursorHoverStates;
import static com.android.launcher3.util.TestConstants.AppNames.TEST_APP_NAME;
-import static com.android.launcher3.util.rule.TestStabilityRule.LOCAL;
-import static com.android.launcher3.util.rule.TestStabilityRule.PLATFORM_POSTSUBMIT;
import static com.android.quickstep.TaskbarModeSwitchRule.Mode.TRANSIENT;
import static org.junit.Assume.assumeTrue;
@@ -26,9 +24,6 @@
import androidx.test.filters.LargeTest;
import androidx.test.runner.AndroidJUnit4;
-import com.android.launcher3.ui.PortraitLandscapeRunner.PortraitLandscape;
-import com.android.launcher3.util.rule.ScreenRecordRule.ScreenRecord;
-import com.android.launcher3.util.rule.TestStabilityRule;
import com.android.quickstep.TaskbarModeSwitchRule.TaskbarModeSwitch;
import org.junit.Test;
@@ -72,9 +67,6 @@
@Test
@TaskbarModeSwitch(mode = TRANSIENT)
- @PortraitLandscape
- @ScreenRecord // b/317798731
- @TestStabilityRule.Stability(flavors = LOCAL | PLATFORM_POSTSUBMIT) // b/321083190
public void testSwipeToStashAndUnstash() {
getTaskbar().swipeDownToStash();
mLauncher.getLaunchedAppState().swipeUpToUnstashTaskbar();
diff --git a/res/drawable/ic_private_profile_app_scroller_badge.xml b/res/drawable/ic_private_profile_app_scroller_badge.xml
new file mode 100644
index 0000000..b52a277
--- /dev/null
+++ b/res/drawable/ic_private_profile_app_scroller_badge.xml
@@ -0,0 +1,28 @@
+<!--
+ ~ 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" xmlns:aapt="http://schemas.android.com/aapt"
+ android:viewportWidth="32"
+ android:viewportHeight="32"
+ android:width="32dp"
+ android:height="32dp">
+ <path
+ android:pathData="M16.0007 2.66602L5.33398 6.66602V14.786C5.33398 21.5194 9.88065 27.7993 16.0007 29.3327C22.1207 27.7993 26.6673 21.5194 26.6673 14.786V6.66602L16.0007 2.66602ZM20.0007 19.9993V22.666H17.334V23.9993H14.6673V17.1193C12.7473 16.546 11.334 14.786 11.334 12.666C11.334 10.0927 13.4273 7.99935 16.0007 7.99935C18.574 7.99935 20.6673 10.0927 20.6673 12.666C20.6673 14.7727 19.254 16.546 17.334 17.1193V19.9993H20.0007Z"
+ android:fillType="evenOdd"
+ android:fillColor="@android:color/white" />
+ <path
+ android:pathData="M16 14.666C17.1046 14.666 18 13.7706 18 12.666C18 11.5614 17.1046 10.666 16 10.666C14.8954 10.666 14 11.5614 14 12.666C14 13.7706 14.8954 14.666 16 14.666Z"
+ android:fillColor="@android:color/white" />
+</vector>
diff --git a/res/drawable/work_mode_fab_background.xml b/res/drawable/work_mode_fab_background.xml
index 478b887..6be33e8 100644
--- a/res/drawable/work_mode_fab_background.xml
+++ b/res/drawable/work_mode_fab_background.xml
@@ -19,9 +19,6 @@
<shape android:shape="rectangle">
<corners android:radius="@dimen/work_fab_radius" />
<solid android:color="@color/work_fab_bg_color" />
- <padding
- android:left="@dimen/work_profile_footer_padding"
- android:right="@dimen/work_profile_footer_padding" />
</shape>
</item>
</ripple>
diff --git a/res/layout/private_space_header.xml b/res/layout/private_space_header.xml
index 185207b..65f1004 100644
--- a/res/layout/private_space_header.xml
+++ b/res/layout/private_space_header.xml
@@ -24,6 +24,7 @@
android:background="@drawable/bg_ps_header"
android:clipToOutline="true"
android:gravity="center_vertical"
+ android:textDirection="locale"
android:orientation="horizontal">
<LinearLayout
diff --git a/res/layout/work_mode_fab.xml b/res/layout/work_mode_fab.xml
index 276d73e..b3484c9 100644
--- a/res/layout/work_mode_fab.xml
+++ b/res/layout/work_mode_fab.xml
@@ -24,12 +24,15 @@
android:background="@drawable/work_mode_fab_background"
android:forceHasOverlappingRendering="false"
android:contentDescription="@string/work_apps_pause_btn_text"
+ android:paddingStart="@dimen/work_mode_fab_background_start_padding"
+ android:paddingEnd="@dimen/work_mode_fab_background_end_padding"
android:animateLayoutChanges="true">
<ImageView
android:id="@+id/work_icon"
android:layout_width="@dimen/work_fab_icon_size"
android:layout_height="@dimen/work_fab_icon_size"
android:importantForAccessibility="no"
+ android:layout_marginEnd="@dimen/work_fab_icon_end_margin"
android:src="@drawable/ic_corp_off"
android:tint="@color/work_fab_icon_color"
android:scaleType="center"/>
@@ -43,7 +46,7 @@
android:includeFontPadding="false"
android:textDirection="locale"
android:text="@string/work_apps_pause_btn_text"
- android:layout_marginStart="@dimen/work_fab_text_start_margin"
+ android:layout_marginEnd="@dimen/work_fab_text_end_margin"
android:ellipsize="end"
android:maxLines="1"
style="@style/TextHeadline"/>
diff --git a/res/values-ar/strings.xml b/res/values-ar/strings.xml
index 6963bb7..07343d7 100644
--- a/res/values-ar/strings.xml
+++ b/res/values-ar/strings.xml
@@ -175,7 +175,7 @@
<string name="accessibility_close" msgid="2277148124685870734">"إغلاق"</string>
<string name="all_apps_personal_tab" msgid="4190252696685155002">"شخصية"</string>
<string name="all_apps_work_tab" msgid="4884822796154055118">"للعمل"</string>
- <string name="work_profile_toggle_label" msgid="3081029915775481146">"الملف الشخصي للعمل"</string>
+ <string name="work_profile_toggle_label" msgid="3081029915775481146">"ملف العمل"</string>
<string name="work_profile_edu_work_apps" msgid="7895468576497746520">"تحمل تطبيقات العمل مميّزة بشارة ومرئية لمشرف تكنولوجيا المعلومات."</string>
<string name="work_profile_edu_accept" msgid="6069788082535149071">"حسنًا"</string>
<string name="work_apps_paused_title" msgid="3040901117349444598">"تطبيقات العمل متوقفة مؤقتًا"</string>
diff --git a/res/values-be/strings.xml b/res/values-be/strings.xml
index b6e30de..d4c18f0 100644
--- a/res/values-be/strings.xml
+++ b/res/values-be/strings.xml
@@ -33,8 +33,7 @@
<string name="app_pair_default_title" msgid="4045241727446873529">"<xliff:g id="APP1">%1$s</xliff:g> | <xliff:g id="APP2">%2$s</xliff:g>"</string>
<string name="app_pair_unlaunchable_at_screen_size" msgid="3446551575502685376">"Дадзенае спалучэнне праграм не падтрымліваецца на гэтай прыладзе"</string>
<string name="app_pair_needs_unfold" msgid="4588897528143807002">"Каб выкарыстоўваць гэта спалучэнне праграм, раскладзіце прыладу"</string>
- <!-- no translation found for app_pair_not_available (3556767440808032031) -->
- <skip />
+ <string name="app_pair_not_available" msgid="3556767440808032031">"Спалучэнне праграм недаступнае"</string>
<string name="long_press_widget_to_add" msgid="3587712543577675817">"Націсніце і ўтрымлівайце віджэт для перамяшчэння."</string>
<string name="long_accessible_way_to_add" msgid="2733588281439571974">"Дакраніцеся двойчы і ўтрымлівайце, каб перамясціць віджэт або выкарыстоўваць спецыяльныя дзеянні."</string>
<string name="widget_dims_format" msgid="2370757736025621599">"%1$d × %2$d"</string>
diff --git a/res/values-bg/strings.xml b/res/values-bg/strings.xml
index b9b6b60..0b92509 100644
--- a/res/values-bg/strings.xml
+++ b/res/values-bg/strings.xml
@@ -33,8 +33,7 @@
<string name="app_pair_default_title" msgid="4045241727446873529">"<xliff:g id="APP1">%1$s</xliff:g> | <xliff:g id="APP2">%2$s</xliff:g>"</string>
<string name="app_pair_unlaunchable_at_screen_size" msgid="3446551575502685376">"Тази двойка приложения не се поддържа на устройството"</string>
<string name="app_pair_needs_unfold" msgid="4588897528143807002">"Отворете устройството, за да използвате тази двойка приложения"</string>
- <!-- no translation found for app_pair_not_available (3556767440808032031) -->
- <skip />
+ <string name="app_pair_not_available" msgid="3556767440808032031">"Двойката приложения не е налице"</string>
<string name="long_press_widget_to_add" msgid="3587712543577675817">"Докоснете и задръжте за преместване на приспособление"</string>
<string name="long_accessible_way_to_add" msgid="2733588281439571974">"Докоснете двукратно и задръжте за преместване на приспособление или използвайте персонал. действия."</string>
<string name="widget_dims_format" msgid="2370757736025621599">"%1$d × %2$d"</string>
diff --git a/res/values-bn/strings.xml b/res/values-bn/strings.xml
index 64b0ba2..54238cf 100644
--- a/res/values-bn/strings.xml
+++ b/res/values-bn/strings.xml
@@ -33,8 +33,7 @@
<string name="app_pair_default_title" msgid="4045241727446873529">"<xliff:g id="APP1">%1$s</xliff:g> | <xliff:g id="APP2">%2$s</xliff:g>"</string>
<string name="app_pair_unlaunchable_at_screen_size" msgid="3446551575502685376">"এই ডিভাইসে এই অ্যাপ পেয়ারটি কাজ করে না"</string>
<string name="app_pair_needs_unfold" msgid="4588897528143807002">"এই অ্যাপ পেয়ার ব্যবহার করতে ডিভাইস আনফোল্ড করুন"</string>
- <!-- no translation found for app_pair_not_available (3556767440808032031) -->
- <skip />
+ <string name="app_pair_not_available" msgid="3556767440808032031">"অ্যাপ পেয়ার উপলভ্য নেই"</string>
<string name="long_press_widget_to_add" msgid="3587712543577675817">"কোনও উইজেট সরাতে সেটি টাচ করে ধরে রাখুন।"</string>
<string name="long_accessible_way_to_add" msgid="2733588281439571974">"একটি উইজেট সরাতে বা কাস্টম অ্যাকশন ব্যবহার করতে ডবল ট্যাপ করে ধরে রাখুন।"</string>
<string name="widget_dims_format" msgid="2370757736025621599">"%1$d × %2$d"</string>
diff --git a/res/values-ca/strings.xml b/res/values-ca/strings.xml
index 5d54f2e..c411783 100644
--- a/res/values-ca/strings.xml
+++ b/res/values-ca/strings.xml
@@ -33,8 +33,7 @@
<string name="app_pair_default_title" msgid="4045241727446873529">"<xliff:g id="APP1">%1$s</xliff:g> | <xliff:g id="APP2">%2$s</xliff:g>"</string>
<string name="app_pair_unlaunchable_at_screen_size" msgid="3446551575502685376">"Aquesta parella d\'aplicacions no s\'admet en aquest dispositiu"</string>
<string name="app_pair_needs_unfold" msgid="4588897528143807002">"Desplega el dispositiu per utilitzar aquesta parella d\'aplicacions"</string>
- <!-- no translation found for app_pair_not_available (3556767440808032031) -->
- <skip />
+ <string name="app_pair_not_available" msgid="3556767440808032031">"La parella d\'aplicacions no està disponible"</string>
<string name="long_press_widget_to_add" msgid="3587712543577675817">"Fes doble toc i mantén premut per moure un widget."</string>
<string name="long_accessible_way_to_add" msgid="2733588281439571974">"Fes doble toc i mantén premut per moure un widget o per utilitzar accions personalitzades."</string>
<string name="widget_dims_format" msgid="2370757736025621599">"%1$d × %2$d"</string>
diff --git a/res/values-cs/strings.xml b/res/values-cs/strings.xml
index 5d93636..4cf1e8f 100644
--- a/res/values-cs/strings.xml
+++ b/res/values-cs/strings.xml
@@ -33,8 +33,7 @@
<string name="app_pair_default_title" msgid="4045241727446873529">"<xliff:g id="APP1">%1$s</xliff:g> | <xliff:g id="APP2">%2$s</xliff:g>"</string>
<string name="app_pair_unlaunchable_at_screen_size" msgid="3446551575502685376">"Tento pár aplikací není na tomto zařízení podporován"</string>
<string name="app_pair_needs_unfold" msgid="4588897528143807002">"Pokud chcete použít tento pár aplikací, rozložte zařízení"</string>
- <!-- no translation found for app_pair_not_available (3556767440808032031) -->
- <skip />
+ <string name="app_pair_not_available" msgid="3556767440808032031">"Dvojice aplikací není k dispozici"</string>
<string name="long_press_widget_to_add" msgid="3587712543577675817">"Widget přesunete klepnutím a podržením."</string>
<string name="long_accessible_way_to_add" msgid="2733588281439571974">"Dvojitým klepnutím a podržením přesunete widget, případně použijte vlastní akce."</string>
<string name="widget_dims_format" msgid="2370757736025621599">"%1$d × %2$d"</string>
diff --git a/res/values-da/strings.xml b/res/values-da/strings.xml
index 3260fb5..6502e63 100644
--- a/res/values-da/strings.xml
+++ b/res/values-da/strings.xml
@@ -33,8 +33,7 @@
<string name="app_pair_default_title" msgid="4045241727446873529">"<xliff:g id="APP1">%1$s</xliff:g> | <xliff:g id="APP2">%2$s</xliff:g>"</string>
<string name="app_pair_unlaunchable_at_screen_size" msgid="3446551575502685376">"Denne appsammenknytning understøttes ikke på enheden"</string>
<string name="app_pair_needs_unfold" msgid="4588897528143807002">"Fold enheden ud for at bruge denne appsammenknytning"</string>
- <!-- no translation found for app_pair_not_available (3556767440808032031) -->
- <skip />
+ <string name="app_pair_not_available" msgid="3556767440808032031">"Appsammenknytning er ikke tilgængelig"</string>
<string name="long_press_widget_to_add" msgid="3587712543577675817">"Hold en widget nede for at flytte den."</string>
<string name="long_accessible_way_to_add" msgid="2733588281439571974">"Tryk to gange, og hold en widget nede for at flytte den eller bruge tilpassede handlinger."</string>
<string name="widget_dims_format" msgid="2370757736025621599">"%1$d × %2$d"</string>
diff --git a/res/values-de/strings.xml b/res/values-de/strings.xml
index 78e20b6..80941c7 100644
--- a/res/values-de/strings.xml
+++ b/res/values-de/strings.xml
@@ -33,8 +33,7 @@
<string name="app_pair_default_title" msgid="4045241727446873529">"<xliff:g id="APP1">%1$s</xliff:g> | <xliff:g id="APP2">%2$s</xliff:g>"</string>
<string name="app_pair_unlaunchable_at_screen_size" msgid="3446551575502685376">"Dieses App-Paar wird auf diesem Gerät nicht unterstützt"</string>
<string name="app_pair_needs_unfold" msgid="4588897528143807002">"Gerät aufklappen, um dieses App-Paar zu verwenden"</string>
- <!-- no translation found for app_pair_not_available (3556767440808032031) -->
- <skip />
+ <string name="app_pair_not_available" msgid="3556767440808032031">"App-Paar nicht verfügbar"</string>
<string name="long_press_widget_to_add" msgid="3587712543577675817">"Zum Verschieben des Widgets berühren und halten"</string>
<string name="long_accessible_way_to_add" msgid="2733588281439571974">"Doppeltippen und halten, um ein Widget zu bewegen oder benutzerdefinierte Aktionen zu nutzen."</string>
<string name="widget_dims_format" msgid="2370757736025621599">"%1$d × %2$d"</string>
diff --git a/res/values-el/strings.xml b/res/values-el/strings.xml
index f2d8a15..a4f8692 100644
--- a/res/values-el/strings.xml
+++ b/res/values-el/strings.xml
@@ -33,8 +33,7 @@
<string name="app_pair_default_title" msgid="4045241727446873529">"<xliff:g id="APP1">%1$s</xliff:g> | <xliff:g id="APP2">%2$s</xliff:g>"</string>
<string name="app_pair_unlaunchable_at_screen_size" msgid="3446551575502685376">"Αυτό το ζεύγος εφαρμογών δεν υποστηρίζεται σε αυτή τη συσκευή"</string>
<string name="app_pair_needs_unfold" msgid="4588897528143807002">"Ξεδιπλώστε τη συσκευή για να χρησιμοποιήσετε αυτό το ζεύγος εφαρμογών"</string>
- <!-- no translation found for app_pair_not_available (3556767440808032031) -->
- <skip />
+ <string name="app_pair_not_available" msgid="3556767440808032031">"Το ζεύγος εφαρμογών δεν είναι διαθέσιμο"</string>
<string name="long_press_widget_to_add" msgid="3587712543577675817">"Πατήστε παρατετ. για μετακίνηση γραφ. στοιχείου."</string>
<string name="long_accessible_way_to_add" msgid="2733588281439571974">"Πατήστε δύο φορές παρατεταμένα για μετακίνηση γραφικού στοιχείου ή χρήση προσαρμοσμένων ενεργειών."</string>
<string name="widget_dims_format" msgid="2370757736025621599">"%1$d × %2$d"</string>
diff --git a/res/values-en-rAU/strings.xml b/res/values-en-rAU/strings.xml
index 7061889..8deac65 100644
--- a/res/values-en-rAU/strings.xml
+++ b/res/values-en-rAU/strings.xml
@@ -33,8 +33,7 @@
<string name="app_pair_default_title" msgid="4045241727446873529">"<xliff:g id="APP1">%1$s</xliff:g> | <xliff:g id="APP2">%2$s</xliff:g>"</string>
<string name="app_pair_unlaunchable_at_screen_size" msgid="3446551575502685376">"This app pair isn\'t supported on this device"</string>
<string name="app_pair_needs_unfold" msgid="4588897528143807002">"Unfold device to use this app pair"</string>
- <!-- no translation found for app_pair_not_available (3556767440808032031) -->
- <skip />
+ <string name="app_pair_not_available" msgid="3556767440808032031">"App pair isn\'t available"</string>
<string name="long_press_widget_to_add" msgid="3587712543577675817">"Touch and hold to move a widget."</string>
<string name="long_accessible_way_to_add" msgid="2733588281439571974">"Double-tap & hold to move a widget or use custom actions."</string>
<string name="widget_dims_format" msgid="2370757736025621599">"%1$d × %2$d"</string>
diff --git a/res/values-en-rGB/strings.xml b/res/values-en-rGB/strings.xml
index 7061889..8deac65 100644
--- a/res/values-en-rGB/strings.xml
+++ b/res/values-en-rGB/strings.xml
@@ -33,8 +33,7 @@
<string name="app_pair_default_title" msgid="4045241727446873529">"<xliff:g id="APP1">%1$s</xliff:g> | <xliff:g id="APP2">%2$s</xliff:g>"</string>
<string name="app_pair_unlaunchable_at_screen_size" msgid="3446551575502685376">"This app pair isn\'t supported on this device"</string>
<string name="app_pair_needs_unfold" msgid="4588897528143807002">"Unfold device to use this app pair"</string>
- <!-- no translation found for app_pair_not_available (3556767440808032031) -->
- <skip />
+ <string name="app_pair_not_available" msgid="3556767440808032031">"App pair isn\'t available"</string>
<string name="long_press_widget_to_add" msgid="3587712543577675817">"Touch and hold to move a widget."</string>
<string name="long_accessible_way_to_add" msgid="2733588281439571974">"Double-tap & hold to move a widget or use custom actions."</string>
<string name="widget_dims_format" msgid="2370757736025621599">"%1$d × %2$d"</string>
diff --git a/res/values-en-rIN/strings.xml b/res/values-en-rIN/strings.xml
index 7061889..8deac65 100644
--- a/res/values-en-rIN/strings.xml
+++ b/res/values-en-rIN/strings.xml
@@ -33,8 +33,7 @@
<string name="app_pair_default_title" msgid="4045241727446873529">"<xliff:g id="APP1">%1$s</xliff:g> | <xliff:g id="APP2">%2$s</xliff:g>"</string>
<string name="app_pair_unlaunchable_at_screen_size" msgid="3446551575502685376">"This app pair isn\'t supported on this device"</string>
<string name="app_pair_needs_unfold" msgid="4588897528143807002">"Unfold device to use this app pair"</string>
- <!-- no translation found for app_pair_not_available (3556767440808032031) -->
- <skip />
+ <string name="app_pair_not_available" msgid="3556767440808032031">"App pair isn\'t available"</string>
<string name="long_press_widget_to_add" msgid="3587712543577675817">"Touch and hold to move a widget."</string>
<string name="long_accessible_way_to_add" msgid="2733588281439571974">"Double-tap & hold to move a widget or use custom actions."</string>
<string name="widget_dims_format" msgid="2370757736025621599">"%1$d × %2$d"</string>
diff --git a/res/values-es-rUS/strings.xml b/res/values-es-rUS/strings.xml
index 012609e..86b0de7 100644
--- a/res/values-es-rUS/strings.xml
+++ b/res/values-es-rUS/strings.xml
@@ -33,8 +33,7 @@
<string name="app_pair_default_title" msgid="4045241727446873529">"<xliff:g id="APP1">%1$s</xliff:g> | <xliff:g id="APP2">%2$s</xliff:g>"</string>
<string name="app_pair_unlaunchable_at_screen_size" msgid="3446551575502685376">"No se admite esta vinculación de apps en este dispositivo"</string>
<string name="app_pair_needs_unfold" msgid="4588897528143807002">"Abre el dispositivo para usar esta vinculación de apps"</string>
- <!-- no translation found for app_pair_not_available (3556767440808032031) -->
- <skip />
+ <string name="app_pair_not_available" msgid="3556767440808032031">"La vinculación de apps no está disponible"</string>
<string name="long_press_widget_to_add" msgid="3587712543577675817">"Mantén presionado para mover un widget."</string>
<string name="long_accessible_way_to_add" msgid="2733588281439571974">"Presiona dos veces y mantén presionado para mover un widget o usar acciones personalizadas."</string>
<string name="widget_dims_format" msgid="2370757736025621599">"%1$d × %2$d"</string>
diff --git a/res/values-es/strings.xml b/res/values-es/strings.xml
index 0b0cb41..971bf81 100644
--- a/res/values-es/strings.xml
+++ b/res/values-es/strings.xml
@@ -29,12 +29,11 @@
<string name="home_screen" msgid="5629429142036709174">"Inicio"</string>
<string name="recent_task_option_split_screen" msgid="6690461455618725183">"Pantalla dividida"</string>
<string name="split_app_info_accessibility" msgid="5475288491241414932">"Información de la aplicación %1$s"</string>
- <string name="save_app_pair" msgid="5647523853662686243">"Guardar aplicaciones emparejadas"</string>
+ <string name="save_app_pair" msgid="5647523853662686243">"Guardar apps emparejadas"</string>
<string name="app_pair_default_title" msgid="4045241727446873529">"<xliff:g id="APP1">%1$s</xliff:g> | <xliff:g id="APP2">%2$s</xliff:g>"</string>
<string name="app_pair_unlaunchable_at_screen_size" msgid="3446551575502685376">"El dispositivo no admite esta aplicación emparejada"</string>
<string name="app_pair_needs_unfold" msgid="4588897528143807002">"Despliega el dispositivo para usar esta aplicación emparejada"</string>
- <!-- no translation found for app_pair_not_available (3556767440808032031) -->
- <skip />
+ <string name="app_pair_not_available" msgid="3556767440808032031">"La aplicación emparejada no está disponible"</string>
<string name="long_press_widget_to_add" msgid="3587712543577675817">"Mantén pulsado un widget para moverlo"</string>
<string name="long_accessible_way_to_add" msgid="2733588281439571974">"Toca dos veces y mantén pulsado un widget para moverlo o usar acciones personalizadas."</string>
<string name="widget_dims_format" msgid="2370757736025621599">"%1$d × %2$d"</string>
diff --git a/res/values-et/strings.xml b/res/values-et/strings.xml
index 212b672..46c530e 100644
--- a/res/values-et/strings.xml
+++ b/res/values-et/strings.xml
@@ -33,8 +33,7 @@
<string name="app_pair_default_title" msgid="4045241727446873529">"<xliff:g id="APP1">%1$s</xliff:g> | <xliff:g id="APP2">%2$s</xliff:g>"</string>
<string name="app_pair_unlaunchable_at_screen_size" msgid="3446551575502685376">"See rakendusepaar ei ole selles seadmes toetatud"</string>
<string name="app_pair_needs_unfold" msgid="4588897528143807002">"Selle rakendusepaari kasutamiseks voltige seade lahti"</string>
- <!-- no translation found for app_pair_not_available (3556767440808032031) -->
- <skip />
+ <string name="app_pair_not_available" msgid="3556767440808032031">"Rakendusepaar ei ole saadaval"</string>
<string name="long_press_widget_to_add" msgid="3587712543577675817">"Vidina teisaldamiseks puudutage ja hoidke all."</string>
<string name="long_accessible_way_to_add" msgid="2733588281439571974">"Vidina teisaldamiseks või kohandatud toimingute kasutamiseks topeltpuudutage ja hoidke all."</string>
<string name="widget_dims_format" msgid="2370757736025621599">"%1$d × %2$d"</string>
@@ -45,7 +44,7 @@
<string name="add_to_home_screen" msgid="9168649446635919791">"Lisa avakuvale"</string>
<string name="added_to_home_screen_accessibility_text" msgid="4451545765448884415">"Vidin <xliff:g id="WIDGET_NAME">%1$s</xliff:g> lisati avakuvale"</string>
<string name="suggested_widgets_header_title" msgid="1844314680798145222">"Soovitused"</string>
- <string name="productivity_widget_recommendation_category_label" msgid="3811812719618323750">"Alustalad"</string>
+ <string name="productivity_widget_recommendation_category_label" msgid="3811812719618323750">"Põhiasjad"</string>
<string name="news_widget_recommendation_category_label" msgid="6756167867113741310">"Uudised ja ajakirjad"</string>
<string name="social_and_entertainment_widget_recommendation_category_label" msgid="2923840997302308191">"Teie lõõgastumiskoht"</string>
<string name="entertainment_widget_recommendation_category_label" msgid="3973107268630717874">"Meelelahutus"</string>
diff --git a/res/values-eu/strings.xml b/res/values-eu/strings.xml
index 8ffbea6..acf67f2 100644
--- a/res/values-eu/strings.xml
+++ b/res/values-eu/strings.xml
@@ -26,15 +26,14 @@
<string name="safemode_shortcut_error" msgid="9160126848219158407">"Deskargatutako aplikazioa modu seguruan desgaitu da"</string>
<string name="safemode_widget_error" msgid="4863470563535682004">"Widgetak desgaitu egin dira modu seguruan"</string>
<string name="shortcut_not_available" msgid="2536503539825726397">"Lasterbideak ez daude erabilgarri"</string>
- <string name="home_screen" msgid="5629429142036709174">"Hasierako pantaila"</string>
+ <string name="home_screen" msgid="5629429142036709174">"Orri nagusia"</string>
<string name="recent_task_option_split_screen" msgid="6690461455618725183">"Pantaila zatitzea"</string>
<string name="split_app_info_accessibility" msgid="5475288491241414932">"%1$s aplikazioari buruzko informazioa"</string>
<string name="save_app_pair" msgid="5647523853662686243">"Gorde aplikazio parea"</string>
<string name="app_pair_default_title" msgid="4045241727446873529">"<xliff:g id="APP1">%1$s</xliff:g> | <xliff:g id="APP2">%2$s</xliff:g>"</string>
<string name="app_pair_unlaunchable_at_screen_size" msgid="3446551575502685376">"Aplikazio pare hori ez da onartzen gailu honetan"</string>
<string name="app_pair_needs_unfold" msgid="4588897528143807002">"Zabaldu gailua aplikazio pare hau erabiltzeko"</string>
- <!-- no translation found for app_pair_not_available (3556767440808032031) -->
- <skip />
+ <string name="app_pair_not_available" msgid="3556767440808032031">"Aplikazio parea ez dago erabilgarri"</string>
<string name="long_press_widget_to_add" msgid="3587712543577675817">"Eduki sakatuta widget bat mugitzeko."</string>
<string name="long_accessible_way_to_add" msgid="2733588281439571974">"Sakatu birritan eta eduki sakatuta widget bat mugitzeko edo ekintza pertsonalizatuak erabiltzeko."</string>
<string name="widget_dims_format" msgid="2370757736025621599">"%1$d × %2$d"</string>
diff --git a/res/values-fi/strings.xml b/res/values-fi/strings.xml
index e55c32f..9cb07fb 100644
--- a/res/values-fi/strings.xml
+++ b/res/values-fi/strings.xml
@@ -33,8 +33,7 @@
<string name="app_pair_default_title" msgid="4045241727446873529">"<xliff:g id="APP1">%1$s</xliff:g> | <xliff:g id="APP2">%2$s</xliff:g>"</string>
<string name="app_pair_unlaunchable_at_screen_size" msgid="3446551575502685376">"Sovellusparia ei tueta tällä laitteella"</string>
<string name="app_pair_needs_unfold" msgid="4588897528143807002">"Avaa taitettu laite, niin voit käyttää sovellusparia"</string>
- <!-- no translation found for app_pair_not_available (3556767440808032031) -->
- <skip />
+ <string name="app_pair_not_available" msgid="3556767440808032031">"Sovelluspari ei ole saatavilla"</string>
<string name="long_press_widget_to_add" msgid="3587712543577675817">"Kosketa pitkään, niin voit siirtää widgetiä."</string>
<string name="long_accessible_way_to_add" msgid="2733588281439571974">"Kaksoisnapauta ja paina pitkään, niin voit siirtää widgetiä tai käyttää muokattuja toimintoja."</string>
<string name="widget_dims_format" msgid="2370757736025621599">"%1$d × %2$d"</string>
@@ -49,7 +48,7 @@
<string name="news_widget_recommendation_category_label" msgid="6756167867113741310">"Uutiset ja aikakauslehdet"</string>
<string name="social_and_entertainment_widget_recommendation_category_label" msgid="2923840997302308191">"Ota rennosti"</string>
<string name="entertainment_widget_recommendation_category_label" msgid="3973107268630717874">"Viihde"</string>
- <string name="social_widget_recommendation_category_label" msgid="689147679536384717">"Some"</string>
+ <string name="social_widget_recommendation_category_label" msgid="689147679536384717">"Sosiaalinen"</string>
<string name="fitness_widget_recommendation_category_label" msgid="2756483898236585324">"Terveys ja kuntoilu"</string>
<string name="weather_widget_recommendation_category_label" msgid="3059715991930798039">"Sää"</string>
<string name="others_widget_recommendation_category_label" msgid="5555987036267226245">"Sinulle ehdotetut"</string>
diff --git a/res/values-fr-rCA/strings.xml b/res/values-fr-rCA/strings.xml
index 7578aea..0254d5e 100644
--- a/res/values-fr-rCA/strings.xml
+++ b/res/values-fr-rCA/strings.xml
@@ -33,8 +33,7 @@
<string name="app_pair_default_title" msgid="4045241727446873529">"<xliff:g id="APP1">%1$s</xliff:g> | <xliff:g id="APP2">%2$s</xliff:g>"</string>
<string name="app_pair_unlaunchable_at_screen_size" msgid="3446551575502685376">"Cette paire d\'applications n\'est pas prise en charge sur cet appareil"</string>
<string name="app_pair_needs_unfold" msgid="4588897528143807002">"Déplier l\'appareil pour utiliser cette paire d\'applications"</string>
- <!-- no translation found for app_pair_not_available (3556767440808032031) -->
- <skip />
+ <string name="app_pair_not_available" msgid="3556767440808032031">"La Paire d\'applications n\'est pas offerte"</string>
<string name="long_press_widget_to_add" msgid="3587712543577675817">"Maintenez le doigt sur un widget pour le déplacer."</string>
<string name="long_accessible_way_to_add" msgid="2733588281439571974">"Touchez 2x un widget et maintenez le doigt dessus pour le déplacer ou utiliser des actions personnalisées."</string>
<string name="widget_dims_format" msgid="2370757736025621599">"%1$d × %2$d"</string>
diff --git a/res/values-fr/strings.xml b/res/values-fr/strings.xml
index 435d3d3..1329a16 100644
--- a/res/values-fr/strings.xml
+++ b/res/values-fr/strings.xml
@@ -33,8 +33,7 @@
<string name="app_pair_default_title" msgid="4045241727446873529">"<xliff:g id="APP1">%1$s</xliff:g> | <xliff:g id="APP2">%2$s</xliff:g>"</string>
<string name="app_pair_unlaunchable_at_screen_size" msgid="3446551575502685376">"Cette paire d\'applications n\'est pas prise en charge sur cet appareil"</string>
<string name="app_pair_needs_unfold" msgid="4588897528143807002">"Dépliez l\'appareil pour utiliser cette paire d\'applications"</string>
- <!-- no translation found for app_pair_not_available (3556767440808032031) -->
- <skip />
+ <string name="app_pair_not_available" msgid="3556767440808032031">"La paire d\'applications n\'est pas disponible"</string>
<string name="long_press_widget_to_add" msgid="3587712543577675817">"Appuyez de manière prolongée sur un widget pour le déplacer."</string>
<string name="long_accessible_way_to_add" msgid="2733588281439571974">"Appuyez deux fois et maintenez la pression pour déplacer widget ou utiliser actions personnalisées."</string>
<string name="widget_dims_format" msgid="2370757736025621599">"%1$d x %2$d"</string>
diff --git a/res/values-gl/strings.xml b/res/values-gl/strings.xml
index 180a786..4466c6d 100644
--- a/res/values-gl/strings.xml
+++ b/res/values-gl/strings.xml
@@ -33,8 +33,7 @@
<string name="app_pair_default_title" msgid="4045241727446873529">"<xliff:g id="APP1">%1$s</xliff:g> | <xliff:g id="APP2">%2$s</xliff:g>"</string>
<string name="app_pair_unlaunchable_at_screen_size" msgid="3446551575502685376">"O dispositivo non admite este emparellamento de aplicacións"</string>
<string name="app_pair_needs_unfold" msgid="4588897528143807002">"Desprega o dispositivo para usar este emparellamento de aplicacións"</string>
- <!-- no translation found for app_pair_not_available (3556767440808032031) -->
- <skip />
+ <string name="app_pair_not_available" msgid="3556767440808032031">"Non está dispoñible o emparellamento de aplicacións"</string>
<string name="long_press_widget_to_add" msgid="3587712543577675817">"Mantén premido un widget para movelo."</string>
<string name="long_accessible_way_to_add" msgid="2733588281439571974">"Toca dúas veces un widget e manteno premido para movelo ou utiliza accións personalizadas."</string>
<string name="widget_dims_format" msgid="2370757736025621599">"%1$d × %2$d"</string>
@@ -125,7 +124,7 @@
<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>
<string name="notification_dots_title" msgid="9062440428204120317">"Puntos de notificacións"</string>
- <string name="notification_dots_desc_on" msgid="1679848116452218908">"Activados"</string>
+ <string name="notification_dots_desc_on" msgid="1679848116452218908">"Opción activada"</string>
<string name="notification_dots_desc_off" msgid="1760796511504341095">"Desactivados"</string>
<string name="title_missing_notification_access" msgid="7503287056163941064">"Necesítase acceso ás notificacións"</string>
<string name="msg_missing_notification_access" msgid="281113995110910548">"Para que se mostren os puntos de notificacións, activa as notificacións da aplicación <xliff:g id="NAME">%1$s</xliff:g>"</string>
diff --git a/res/values-hu/strings.xml b/res/values-hu/strings.xml
index 69031fe..72d23fa 100644
--- a/res/values-hu/strings.xml
+++ b/res/values-hu/strings.xml
@@ -33,8 +33,7 @@
<string name="app_pair_default_title" msgid="4045241727446873529">"<xliff:g id="APP1">%1$s</xliff:g> | <xliff:g id="APP2">%2$s</xliff:g>"</string>
<string name="app_pair_unlaunchable_at_screen_size" msgid="3446551575502685376">"Ezt az alkalmazáspárt nem támogatja az eszköz"</string>
<string name="app_pair_needs_unfold" msgid="4588897528143807002">"Hajtsa ki az eszközt az alkalmazáspár használatához"</string>
- <!-- no translation found for app_pair_not_available (3556767440808032031) -->
- <skip />
+ <string name="app_pair_not_available" msgid="3556767440808032031">"Az alkalmazáspár nem áll rendelkezésre"</string>
<string name="long_press_widget_to_add" msgid="3587712543577675817">"Tartsa lenyomva a modult az áthelyezéshez."</string>
<string name="long_accessible_way_to_add" msgid="2733588281439571974">"Modul áthelyezéséhez koppintson duplán, tartsa nyomva az ujját, vagy használjon egyéni műveleteket."</string>
<string name="widget_dims_format" msgid="2370757736025621599">"%1$d × %2$d"</string>
@@ -45,7 +44,7 @@
<string name="add_to_home_screen" msgid="9168649446635919791">"Hozzáadás a kezdőképernyőhöz"</string>
<string name="added_to_home_screen_accessibility_text" msgid="4451545765448884415">"<xliff:g id="WIDGET_NAME">%1$s</xliff:g> modul hozzáadva a kezdőképernyőhöz"</string>
<string name="suggested_widgets_header_title" msgid="1844314680798145222">"Javaslatok"</string>
- <string name="productivity_widget_recommendation_category_label" msgid="3811812719618323750">"Kihagyhatatlanok"</string>
+ <string name="productivity_widget_recommendation_category_label" msgid="3811812719618323750">"Legfontosabbak"</string>
<string name="news_widget_recommendation_category_label" msgid="6756167867113741310">"Hírlapok és folyóiratok"</string>
<string name="social_and_entertainment_widget_recommendation_category_label" msgid="2923840997302308191">"Az Ön relaxáló zónája"</string>
<string name="entertainment_widget_recommendation_category_label" msgid="3973107268630717874">"Szórakozás"</string>
diff --git a/res/values-hy/strings.xml b/res/values-hy/strings.xml
index 8d78f1c..0f65295 100644
--- a/res/values-hy/strings.xml
+++ b/res/values-hy/strings.xml
@@ -33,8 +33,7 @@
<string name="app_pair_default_title" msgid="4045241727446873529">"<xliff:g id="APP1">%1$s</xliff:g> | <xliff:g id="APP2">%2$s</xliff:g>"</string>
<string name="app_pair_unlaunchable_at_screen_size" msgid="3446551575502685376">"Հավելվածների զույգը չի աջակցվում այս սարքում"</string>
<string name="app_pair_needs_unfold" msgid="4588897528143807002">"Բացեք սարքը՝ այս հավելվածների զույգն օգտագործելու համար"</string>
- <!-- no translation found for app_pair_not_available (3556767440808032031) -->
- <skip />
+ <string name="app_pair_not_available" msgid="3556767440808032031">"Հավելվածների զույգը հասանելի չէ"</string>
<string name="long_press_widget_to_add" msgid="3587712543577675817">"Հպեք և պահեք՝ վիջեթ տեղափոխելու համար։"</string>
<string name="long_accessible_way_to_add" msgid="2733588281439571974">"Կրկնակի հպեք և պահեք՝ վիջեթ տեղափոխելու համար, կամ օգտվեք հատուկ գործողություններից։"</string>
<string name="widget_dims_format" msgid="2370757736025621599">"%1$d × %2$d"</string>
diff --git a/res/values-in/strings.xml b/res/values-in/strings.xml
index 092995c..c678e41 100644
--- a/res/values-in/strings.xml
+++ b/res/values-in/strings.xml
@@ -44,14 +44,14 @@
<string name="add_to_home_screen" msgid="9168649446635919791">"Tambahkan ke layar utama"</string>
<string name="added_to_home_screen_accessibility_text" msgid="4451545765448884415">"Widget <xliff:g id="WIDGET_NAME">%1$s</xliff:g> ditambahkan ke layar utama"</string>
<string name="suggested_widgets_header_title" msgid="1844314680798145222">"Saran"</string>
- <string name="productivity_widget_recommendation_category_label" msgid="3811812719618323750">"Wajib Coba"</string>
+ <string name="productivity_widget_recommendation_category_label" msgid="3811812719618323750">"Penting"</string>
<string name="news_widget_recommendation_category_label" msgid="6756167867113741310">"Berita & majalah"</string>
<string name="social_and_entertainment_widget_recommendation_category_label" msgid="2923840997302308191">"Zona Nyaman Anda"</string>
<string name="entertainment_widget_recommendation_category_label" msgid="3973107268630717874">"Hiburan"</string>
<string name="social_widget_recommendation_category_label" msgid="689147679536384717">"Sosial"</string>
<string name="fitness_widget_recommendation_category_label" msgid="2756483898236585324">"Kesehatan & kebugaran"</string>
<string name="weather_widget_recommendation_category_label" msgid="3059715991930798039">"Cuaca"</string>
- <string name="others_widget_recommendation_category_label" msgid="5555987036267226245">"Saran untuk Anda"</string>
+ <string name="others_widget_recommendation_category_label" msgid="5555987036267226245">"Disarankan untuk Anda"</string>
<string name="widget_picker_right_pane_accessibility_title" msgid="1673313931455067502">"Widget <xliff:g id="SELECTED_HEADER">%1$s</xliff:g> di bagian kanan, penelusuran dan opsi di bagian kiri"</string>
<string name="widgets_count" msgid="6467746476364652096">"{count,plural, =1{# widget}other{# widget}}"</string>
<string name="shortcuts_count" msgid="8471715556199592381">"{count,plural, =1{# pintasan}other{# pintasan}}"</string>
diff --git a/res/values-it/strings.xml b/res/values-it/strings.xml
index 8cffb25..c32fec0 100644
--- a/res/values-it/strings.xml
+++ b/res/values-it/strings.xml
@@ -33,8 +33,7 @@
<string name="app_pair_default_title" msgid="4045241727446873529">"<xliff:g id="APP1">%1$s</xliff:g> | <xliff:g id="APP2">%2$s</xliff:g>"</string>
<string name="app_pair_unlaunchable_at_screen_size" msgid="3446551575502685376">"Questa coppia di app non è supportata su questo dispositivo"</string>
<string name="app_pair_needs_unfold" msgid="4588897528143807002">"Apri il dispositivo per usare questa coppia di app"</string>
- <!-- no translation found for app_pair_not_available (3556767440808032031) -->
- <skip />
+ <string name="app_pair_not_available" msgid="3556767440808032031">"La coppia di app non è disponibile"</string>
<string name="long_press_widget_to_add" msgid="3587712543577675817">"Tocca e tieni premuto per spostare un widget."</string>
<string name="long_accessible_way_to_add" msgid="2733588281439571974">"Tocca due volte e tieni premuto per spostare un widget o per usare le azioni personalizzate."</string>
<string name="widget_dims_format" msgid="2370757736025621599">"%1$d × %2$d"</string>
diff --git a/res/values-iw/strings.xml b/res/values-iw/strings.xml
index 0d67af5..88dce21 100644
--- a/res/values-iw/strings.xml
+++ b/res/values-iw/strings.xml
@@ -33,8 +33,7 @@
<string name="app_pair_default_title" msgid="4045241727446873529">"<xliff:g id="APP1">%1$s</xliff:g> | <xliff:g id="APP2">%2$s</xliff:g>"</string>
<string name="app_pair_unlaunchable_at_screen_size" msgid="3446551575502685376">"צמד האפליקציות הזה לא נתמך במכשיר הזה"</string>
<string name="app_pair_needs_unfold" msgid="4588897528143807002">"צריך לפתוח את המכשיר כדי להשתמש בצמד האפליקציות הזה"</string>
- <!-- no translation found for app_pair_not_available (3556767440808032031) -->
- <skip />
+ <string name="app_pair_not_available" msgid="3556767440808032031">"צמד האפליקציות לא זמין"</string>
<string name="long_press_widget_to_add" msgid="3587712543577675817">"להעברת ווידג\'ט למקום אחר לוחצים עליו לחיצה ארוכה."</string>
<string name="long_accessible_way_to_add" msgid="2733588281439571974">"כדי להעביר ווידג\'ט למקום אחר או להשתמש בפעולות מותאמות אישית, יש ללחוץ פעמיים ולא להרפות."</string>
<string name="widget_dims_format" msgid="2370757736025621599">"%1$d × %2$d"</string>
diff --git a/res/values-ja/strings.xml b/res/values-ja/strings.xml
index 50f5ddf..d028e4e 100644
--- a/res/values-ja/strings.xml
+++ b/res/values-ja/strings.xml
@@ -33,8 +33,7 @@
<string name="app_pair_default_title" msgid="4045241727446873529">"<xliff:g id="APP1">%1$s</xliff:g> | <xliff:g id="APP2">%2$s</xliff:g>"</string>
<string name="app_pair_unlaunchable_at_screen_size" msgid="3446551575502685376">"このデバイスは、このアプリのペア設定に対応していません"</string>
<string name="app_pair_needs_unfold" msgid="4588897528143807002">"このアプリのペア設定を使用するには、デバイスを開いてください"</string>
- <!-- no translation found for app_pair_not_available (3556767440808032031) -->
- <skip />
+ <string name="app_pair_not_available" msgid="3556767440808032031">"アプリのペア設定は利用できません"</string>
<string name="long_press_widget_to_add" msgid="3587712543577675817">"長押ししてウィジェットを移動させます。"</string>
<string name="long_accessible_way_to_add" msgid="2733588281439571974">"ウィジェットをダブルタップして長押ししながら移動するか、カスタム操作を使用してください。"</string>
<string name="widget_dims_format" msgid="2370757736025621599">"%1$dx%2$d"</string>
diff --git a/res/values-ka/strings.xml b/res/values-ka/strings.xml
index a3c3d87..e3b5627 100644
--- a/res/values-ka/strings.xml
+++ b/res/values-ka/strings.xml
@@ -33,8 +33,7 @@
<string name="app_pair_default_title" msgid="4045241727446873529">"<xliff:g id="APP1">%1$s</xliff:g> | <xliff:g id="APP2">%2$s</xliff:g>"</string>
<string name="app_pair_unlaunchable_at_screen_size" msgid="3446551575502685376">"ამ მოწყობილობაზე აღნიშნული აპთა წყვილი არ არის მხარდაჭერილი"</string>
<string name="app_pair_needs_unfold" msgid="4588897528143807002">"გაშალეთ მოწყობილობა ამ აპთა წყვილის გამოსაყენებლად"</string>
- <!-- no translation found for app_pair_not_available (3556767440808032031) -->
- <skip />
+ <string name="app_pair_not_available" msgid="3556767440808032031">"აპთა წყვილი მიუწვდომელია"</string>
<string name="long_press_widget_to_add" msgid="3587712543577675817">"შეხებით აირჩიეთ და გეჭიროთ ვიჯეტის გადასაადგილებლად."</string>
<string name="long_accessible_way_to_add" msgid="2733588281439571974">"ორმაგი შეხებით აირჩიეთ და გეჭიროთ ვიჯეტის გადასაადგილებლად ან მორგებული მოქმედებების გამოსაყენებლად."</string>
<string name="widget_dims_format" msgid="2370757736025621599">"%1$d × %2$d"</string>
diff --git a/res/values-kk/strings.xml b/res/values-kk/strings.xml
index ff030e8..0a1e4aa 100644
--- a/res/values-kk/strings.xml
+++ b/res/values-kk/strings.xml
@@ -33,8 +33,7 @@
<string name="app_pair_default_title" msgid="4045241727446873529">"<xliff:g id="APP1">%1$s</xliff:g> | <xliff:g id="APP2">%2$s</xliff:g>"</string>
<string name="app_pair_unlaunchable_at_screen_size" msgid="3446551575502685376">"Бұл құрылғы қолданбаларды жұптау функциясын қолдамайды."</string>
<string name="app_pair_needs_unfold" msgid="4588897528143807002">"Қолданбаларды жұптау функциясын пайдалану үшін құрылғыны ашыңыз."</string>
- <!-- no translation found for app_pair_not_available (3556767440808032031) -->
- <skip />
+ <string name="app_pair_not_available" msgid="3556767440808032031">"Қолданбаларды жұптау функциясы қолжетімді емес."</string>
<string name="long_press_widget_to_add" msgid="3587712543577675817">"Виджетті жылжыту үшін басып тұрыңыз."</string>
<string name="long_accessible_way_to_add" msgid="2733588281439571974">"Виджетті жылжыту үшін екі рет түртіңіз де, ұстап тұрыңыз немесе арнаулы әрекеттерді пайдаланыңыз."</string>
<string name="widget_dims_format" msgid="2370757736025621599">"%1$d × %2$d"</string>
diff --git a/res/values-kn/strings.xml b/res/values-kn/strings.xml
index 62864cb..b2f307b 100644
--- a/res/values-kn/strings.xml
+++ b/res/values-kn/strings.xml
@@ -33,8 +33,7 @@
<string name="app_pair_default_title" msgid="4045241727446873529">"<xliff:g id="APP1">%1$s</xliff:g> | <xliff:g id="APP2">%2$s</xliff:g>"</string>
<string name="app_pair_unlaunchable_at_screen_size" msgid="3446551575502685376">"ಈ ಆ್ಯಪ್ ಜೋಡಿಯು ಈ ಸಾಧನದಲ್ಲಿ ಬೆಂಬಲಿತವಾಗಿಲ್ಲ"</string>
<string name="app_pair_needs_unfold" msgid="4588897528143807002">"ಈ ಆ್ಯಪ್ ಜೋಡಿಯನ್ನು ಬಳಸಲು ಸಾಧನವನ್ನು ಅನ್ಫೋಲ್ಡ್ ಮಾಡಿ"</string>
- <!-- no translation found for app_pair_not_available (3556767440808032031) -->
- <skip />
+ <string name="app_pair_not_available" msgid="3556767440808032031">"ಆ್ಯಪ್ ಜೋಡಿ ಲಭ್ಯವಿಲ್ಲ"</string>
<string name="long_press_widget_to_add" msgid="3587712543577675817">"ವಿಜೆಟ್ ಸರಿಸಲು ಸ್ಪರ್ಶಿಸಿ ಮತ್ತು ಹಿಡಿದುಕೊಳ್ಳಿ."</string>
<string name="long_accessible_way_to_add" msgid="2733588281439571974">"ವಿಜೆಟ್ ಸರಿಸಲು ಅಥವಾ ಕಸ್ಟಮ್ ಕ್ರಿಯೆಗಳನ್ನು ಬಳಸಲು ಡಬಲ್-ಟ್ಯಾಪ್ ಮಾಡಿ ಮತ್ತು ಹಿಡಿದುಕೊಳ್ಳಿ."</string>
<string name="widget_dims_format" msgid="2370757736025621599">"%1$d × %2$d"</string>
diff --git a/res/values-ko/strings.xml b/res/values-ko/strings.xml
index f97acf1..42b12ab 100644
--- a/res/values-ko/strings.xml
+++ b/res/values-ko/strings.xml
@@ -33,8 +33,7 @@
<string name="app_pair_default_title" msgid="4045241727446873529">"<xliff:g id="APP1">%1$s</xliff:g> | <xliff:g id="APP2">%2$s</xliff:g>"</string>
<string name="app_pair_unlaunchable_at_screen_size" msgid="3446551575502685376">"이 앱 페어링은 이 기기에서 지원되지 않습니다"</string>
<string name="app_pair_needs_unfold" msgid="4588897528143807002">"이 앱 페어링을 사용하려면 기기를 펼치세요"</string>
- <!-- no translation found for app_pair_not_available (3556767440808032031) -->
- <skip />
+ <string name="app_pair_not_available" msgid="3556767440808032031">"앱 페어링을 사용할 수 없습니다."</string>
<string name="long_press_widget_to_add" msgid="3587712543577675817">"길게 터치하여 위젯을 이동하세요."</string>
<string name="long_accessible_way_to_add" msgid="2733588281439571974">"두 번 탭한 다음 길게 터치하여 위젯을 이동하거나 맞춤 작업을 사용하세요."</string>
<string name="widget_dims_format" msgid="2370757736025621599">"%1$d×%2$d"</string>
diff --git a/res/values-lt/strings.xml b/res/values-lt/strings.xml
index 1dcb559..fda9e95 100644
--- a/res/values-lt/strings.xml
+++ b/res/values-lt/strings.xml
@@ -33,8 +33,7 @@
<string name="app_pair_default_title" msgid="4045241727446873529">"<xliff:g id="APP1">%1$s</xliff:g> | <xliff:g id="APP2">%2$s</xliff:g>"</string>
<string name="app_pair_unlaunchable_at_screen_size" msgid="3446551575502685376">"Ši programų pora šiame įrenginyje nepalaikoma"</string>
<string name="app_pair_needs_unfold" msgid="4588897528143807002">"Atlenkite įrenginį, kad galėtumėte naudoti šią programų porą."</string>
- <!-- no translation found for app_pair_not_available (3556767440808032031) -->
- <skip />
+ <string name="app_pair_not_available" msgid="3556767440808032031">"Programų pora nepasiekiama"</string>
<string name="long_press_widget_to_add" msgid="3587712543577675817">"Dukart pal. ir palaik., kad perkeltumėte valdiklį."</string>
<string name="long_accessible_way_to_add" msgid="2733588281439571974">"Dukart palieskite ir palaikykite, kad perkeltumėte valdiklį ar naudotumėte tinkintus veiksmus."</string>
<string name="widget_dims_format" msgid="2370757736025621599">"%1$d × %2$d"</string>
diff --git a/res/values-lv/strings.xml b/res/values-lv/strings.xml
index e2b1031..c9c4dfa 100644
--- a/res/values-lv/strings.xml
+++ b/res/values-lv/strings.xml
@@ -33,8 +33,7 @@
<string name="app_pair_default_title" msgid="4045241727446873529">"<xliff:g id="APP1">%1$s</xliff:g> | <xliff:g id="APP2">%2$s</xliff:g>"</string>
<string name="app_pair_unlaunchable_at_screen_size" msgid="3446551575502685376">"Šis lietotņu pāris netiek atbalstīts šajā ierīcē"</string>
<string name="app_pair_needs_unfold" msgid="4588897528143807002">"Atveriet ierīci, lai izmantotu šo lietotņu pāri"</string>
- <!-- no translation found for app_pair_not_available (3556767440808032031) -->
- <skip />
+ <string name="app_pair_not_available" msgid="3556767440808032031">"Lietotņu pāris nav pieejams"</string>
<string name="long_press_widget_to_add" msgid="3587712543577675817">"Lai pārvietotu logrīku, pieskarieties un turiet."</string>
<string name="long_accessible_way_to_add" msgid="2733588281439571974">"Lai pārvietotu logrīku, uz tā veiciet dubultskārienu un turiet. Varat arī veikt pielāgotas darbības."</string>
<string name="widget_dims_format" msgid="2370757736025621599">"%1$d × %2$d"</string>
diff --git a/res/values-mk/strings.xml b/res/values-mk/strings.xml
index 0accd7f..a429c7a 100644
--- a/res/values-mk/strings.xml
+++ b/res/values-mk/strings.xml
@@ -33,8 +33,7 @@
<string name="app_pair_default_title" msgid="4045241727446873529">"<xliff:g id="APP1">%1$s</xliff:g> | <xliff:g id="APP2">%2$s</xliff:g>"</string>
<string name="app_pair_unlaunchable_at_screen_size" msgid="3446551575502685376">"Паров апликации не е поддржан на уредов"</string>
<string name="app_pair_needs_unfold" msgid="4588897528143807002">"Отворете го уредот за да го користите паров апликации"</string>
- <!-- no translation found for app_pair_not_available (3556767440808032031) -->
- <skip />
+ <string name="app_pair_not_available" msgid="3556767440808032031">"Парот апликации не е достапен"</string>
<string name="long_press_widget_to_add" msgid="3587712543577675817">"Допрете и задржете за да преместите виџет."</string>
<string name="long_accessible_way_to_add" msgid="2733588281439571974">"Допрете двапати и задржете за да преместите виџет или користете приспособени дејства."</string>
<string name="widget_dims_format" msgid="2370757736025621599">"%1$d × %2$d"</string>
@@ -191,10 +190,10 @@
<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_lock_unlock_button" msgid="7605602332253423755">"Заклучување/отклучување на „Приватен простор“"</string>
- <string name="ps_container_lock_title" msgid="2640257399982364682">"Брава"</string>
+ <string name="ps_container_lock_title" msgid="2640257399982364682">"Заклучи"</string>
<string name="ps_container_transition" msgid="8667331812048014412">"Префрлање на „Приватен простор“"</string>
<string name="ps_add_button_label" msgid="8611055839242385935">"Инсталирајте апликации"</string>
<string name="ps_add_button_content_description" msgid="3254274107740952556">"Инсталирање апликации во „Приватен простор“"</string>
diff --git a/res/values-mn/strings.xml b/res/values-mn/strings.xml
index cc4af0e..ffc6509 100644
--- a/res/values-mn/strings.xml
+++ b/res/values-mn/strings.xml
@@ -33,8 +33,7 @@
<string name="app_pair_default_title" msgid="4045241727446873529">"<xliff:g id="APP1">%1$s</xliff:g> | <xliff:g id="APP2">%2$s</xliff:g>"</string>
<string name="app_pair_unlaunchable_at_screen_size" msgid="3446551575502685376">"Энэ апп хослуулалтыг уг төхөөрөмж дээр дэмждэггүй"</string>
<string name="app_pair_needs_unfold" msgid="4588897528143807002">"Энэ апп хослуулалтыг ашиглахын тулд төхөөрөмжийг дэлгэнэ үү"</string>
- <!-- no translation found for app_pair_not_available (3556767440808032031) -->
- <skip />
+ <string name="app_pair_not_available" msgid="3556767440808032031">"Апп хослуулалт боломжгүй байна"</string>
<string name="long_press_widget_to_add" msgid="3587712543577675817">"Виджетийг зөөх бол хүрээд, удаан дарна уу."</string>
<string name="long_accessible_way_to_add" msgid="2733588281439571974">"Виджетийг зөөх эсвэл захиалгат үйлдлийг ашиглахын тулд хоёр товшоод, удаан дарна уу."</string>
<string name="widget_dims_format" msgid="2370757736025621599">"%1$d × %2$d"</string>
diff --git a/res/values-mr/strings.xml b/res/values-mr/strings.xml
index 5eec969..c8af44e 100644
--- a/res/values-mr/strings.xml
+++ b/res/values-mr/strings.xml
@@ -33,8 +33,7 @@
<string name="app_pair_default_title" msgid="4045241727446873529">"<xliff:g id="APP1">%1$s</xliff:g> | <xliff:g id="APP2">%2$s</xliff:g>"</string>
<string name="app_pair_unlaunchable_at_screen_size" msgid="3446551575502685376">"या ॲपची जोडीला या डिव्हाइसवर सपोर्ट नाही"</string>
<string name="app_pair_needs_unfold" msgid="4588897528143807002">"ही ॲपची जोडी वापरण्यासाठी डिव्हाइस अनफोल्ड करा"</string>
- <!-- no translation found for app_pair_not_available (3556767440808032031) -->
- <skip />
+ <string name="app_pair_not_available" msgid="3556767440808032031">"ॲपची जोडी उपलब्ध नाही"</string>
<string name="long_press_widget_to_add" msgid="3587712543577675817">"विजेट हलवण्यासाठी स्पर्श करा आणि धरून ठेवा."</string>
<string name="long_accessible_way_to_add" msgid="2733588281439571974">"विजेट हलवण्यासाठी किंवा कस्टम कृती वापरण्यासाठी दोनदा टॅप करा आणि धरून ठेवा."</string>
<string name="widget_dims_format" msgid="2370757736025621599">"%1$d × %2$d"</string>
diff --git a/res/values-my/strings.xml b/res/values-my/strings.xml
index 6a06d0d..aca6d7d 100644
--- a/res/values-my/strings.xml
+++ b/res/values-my/strings.xml
@@ -33,8 +33,7 @@
<string name="app_pair_default_title" msgid="4045241727446873529">"<xliff:g id="APP1">%1$s</xliff:g> | <xliff:g id="APP2">%2$s</xliff:g>"</string>
<string name="app_pair_unlaunchable_at_screen_size" msgid="3446551575502685376">"ဤအက်ပ်တွဲချိတ်ခြင်းကို ဤစက်တွင် ပံ့ပိုးမထားပါ"</string>
<string name="app_pair_needs_unfold" msgid="4588897528143807002">"ဤအက်ပ်တွဲချိတ်ခြင်းကို သုံးရန် စက်ကိုဖြန့်ပါ"</string>
- <!-- no translation found for app_pair_not_available (3556767440808032031) -->
- <skip />
+ <string name="app_pair_not_available" msgid="3556767440808032031">"အက်ပ်တွဲချိတ်ခြင်းကို မရနိုင်ပါ"</string>
<string name="long_press_widget_to_add" msgid="3587712543577675817">"ဝိဂျက်ကို ရွှေ့ရန် တို့ပြီး ဖိထားပါ။"</string>
<string name="long_accessible_way_to_add" msgid="2733588281439571974">"ဝိဂျက်ကို ရွှေ့ရန် (သို့) စိတ်ကြိုက်လုပ်ဆောင်ချက်များကို သုံးရန် နှစ်ချက်တို့ပြီး ဖိထားပါ။"</string>
<string name="widget_dims_format" msgid="2370757736025621599">"%1$d × %2$d"</string>
@@ -46,7 +45,7 @@
<string name="added_to_home_screen_accessibility_text" msgid="4451545765448884415">"<xliff:g id="WIDGET_NAME">%1$s</xliff:g> ဝိဂျက်ကို ပင်မစာမျက်နှာတွင် ထည့်လိုက်ပြီ"</string>
<string name="suggested_widgets_header_title" msgid="1844314680798145222">"အကြံပြုချက်"</string>
<string name="productivity_widget_recommendation_category_label" msgid="3811812719618323750">"မရှိမဖြစ်များ"</string>
- <string name="news_widget_recommendation_category_label" msgid="6756167867113741310">"သတင်းနှင့် မဂ္ဂဇင်းများ"</string>
+ <string name="news_widget_recommendation_category_label" msgid="6756167867113741310">"သတင်းနှင့် မဂ္ဂဇင်း"</string>
<string name="social_and_entertainment_widget_recommendation_category_label" msgid="2923840997302308191">"သင်အနားယူသောနေရာ"</string>
<string name="entertainment_widget_recommendation_category_label" msgid="3973107268630717874">"ဖျော်ဖြေရေး"</string>
<string name="social_widget_recommendation_category_label" msgid="689147679536384717">"လူမှုရေး"</string>
diff --git a/res/values-nb/strings.xml b/res/values-nb/strings.xml
index 5a19b9b..3f82cb3 100644
--- a/res/values-nb/strings.xml
+++ b/res/values-nb/strings.xml
@@ -33,8 +33,7 @@
<string name="app_pair_default_title" msgid="4045241727446873529">"<xliff:g id="APP1">%1$s</xliff:g> | <xliff:g id="APP2">%2$s</xliff:g>"</string>
<string name="app_pair_unlaunchable_at_screen_size" msgid="3446551575502685376">"Denne apptilkoblingen støttes ikke på denne enheten"</string>
<string name="app_pair_needs_unfold" msgid="4588897528143807002">"Åpne enheten for å bruke denne apptilkoblingen"</string>
- <!-- no translation found for app_pair_not_available (3556767440808032031) -->
- <skip />
+ <string name="app_pair_not_available" msgid="3556767440808032031">"Apptilkoblingen er ikke tilgjengelig"</string>
<string name="long_press_widget_to_add" msgid="3587712543577675817">"Trykk og hold for å flytte en modul."</string>
<string name="long_accessible_way_to_add" msgid="2733588281439571974">"Dobbelttrykk og hold inne for å flytte en modul eller bruke tilpassede handlinger."</string>
<string name="widget_dims_format" msgid="2370757736025621599">"%1$d × %2$d"</string>
@@ -45,7 +44,7 @@
<string name="add_to_home_screen" msgid="9168649446635919791">"Legg til på startskjermen"</string>
<string name="added_to_home_screen_accessibility_text" msgid="4451545765448884415">"<xliff:g id="WIDGET_NAME">%1$s</xliff:g>-modulen er lagt til på startskjermen"</string>
<string name="suggested_widgets_header_title" msgid="1844314680798145222">"Forslag"</string>
- <string name="productivity_widget_recommendation_category_label" msgid="3811812719618323750">"Uunnværlige spill"</string>
+ <string name="productivity_widget_recommendation_category_label" msgid="3811812719618323750">"Anbefalt"</string>
<string name="news_widget_recommendation_category_label" msgid="6756167867113741310">"Nyheter og tidsskrifter"</string>
<string name="social_and_entertainment_widget_recommendation_category_label" msgid="2923840997302308191">"Avslappingssonen din"</string>
<string name="entertainment_widget_recommendation_category_label" msgid="3973107268630717874">"Underholdning"</string>
diff --git a/res/values-nl/strings.xml b/res/values-nl/strings.xml
index d64e6c3..3da759f 100644
--- a/res/values-nl/strings.xml
+++ b/res/values-nl/strings.xml
@@ -33,8 +33,7 @@
<string name="app_pair_default_title" msgid="4045241727446873529">"<xliff:g id="APP1">%1$s</xliff:g> | <xliff:g id="APP2">%2$s</xliff:g>"</string>
<string name="app_pair_unlaunchable_at_screen_size" msgid="3446551575502685376">"Dit app-paar wordt niet ondersteund op dit apparaat"</string>
<string name="app_pair_needs_unfold" msgid="4588897528143807002">"Vouw het apparaat open om dit app-paar te gebruiken"</string>
- <!-- no translation found for app_pair_not_available (3556767440808032031) -->
- <skip />
+ <string name="app_pair_not_available" msgid="3556767440808032031">"App-paar is niet beschikbaar"</string>
<string name="long_press_widget_to_add" msgid="3587712543577675817">"Tik en houd vast om een widget te verplaatsen."</string>
<string name="long_accessible_way_to_add" msgid="2733588281439571974">"Dubbeltik en houd vast om een widget te verplaatsen of aangepaste acties te gebruiken."</string>
<string name="widget_dims_format" msgid="2370757736025621599">"%1$d × %2$d"</string>
diff --git a/res/values-pa/strings.xml b/res/values-pa/strings.xml
index 17f16f1..fa01494 100644
--- a/res/values-pa/strings.xml
+++ b/res/values-pa/strings.xml
@@ -33,8 +33,7 @@
<string name="app_pair_default_title" msgid="4045241727446873529">"<xliff:g id="APP1">%1$s</xliff:g> | <xliff:g id="APP2">%2$s</xliff:g>"</string>
<string name="app_pair_unlaunchable_at_screen_size" msgid="3446551575502685376">"ਇਸ ਐਪ ਜੋੜਾਬੱਧ ਦਾ ਇਸ ਡੀਵਾਈਸ \'ਤੇ ਸਮਰਥਨ ਨਹੀਂ ਕੀਤਾ ਜਾਂਦਾ"</string>
<string name="app_pair_needs_unfold" msgid="4588897528143807002">"ਇਸ ਐਪ ਜੋੜਾਬੱਧ ਨੂੰ ਵਰਤਣ ਲਈ ਡੀਵਾਈਸ ਨੂੰ ਅਣਫੋਲਡ ਕਰੋ"</string>
- <!-- no translation found for app_pair_not_available (3556767440808032031) -->
- <skip />
+ <string name="app_pair_not_available" msgid="3556767440808032031">"ਐਪ ਜੋੜਾਬੱਧ ਉਪਲਬਧ ਨਹੀਂ ਹੈ"</string>
<string name="long_press_widget_to_add" msgid="3587712543577675817">"ਕਿਸੇ ਵਿਜੇਟ ਨੂੰ ਲਿਜਾਉਣ ਲਈ ਸਪਰਸ਼ ਕਰਕੇ ਰੱਖੋ।"</string>
<string name="long_accessible_way_to_add" msgid="2733588281439571974">"ਵਿਜੇਟ ਲਿਜਾਉਣ ਲਈ ਜਾਂ ਵਿਉਂਂਤੀਆਂ ਕਾਰਵਾਈਆਂ ਵਰਤਣ ਲਈ ਦੋ ਵਾਰ ਟੈਪ ਕਰਕੇ ਦਬਾ ਕੇ ਰੱਖੋ।"</string>
<string name="widget_dims_format" msgid="2370757736025621599">"%1$d × %2$d"</string>
diff --git a/res/values-pt/strings.xml b/res/values-pt/strings.xml
index 0391efe..c0e4457 100644
--- a/res/values-pt/strings.xml
+++ b/res/values-pt/strings.xml
@@ -33,8 +33,7 @@
<string name="app_pair_default_title" msgid="4045241727446873529">"<xliff:g id="APP1">%1$s</xliff:g> | <xliff:g id="APP2">%2$s</xliff:g>"</string>
<string name="app_pair_unlaunchable_at_screen_size" msgid="3446551575502685376">"Este Par de apps não está disponível no dispositivo"</string>
<string name="app_pair_needs_unfold" msgid="4588897528143807002">"Abra o dispositivo para usar este Par de apps"</string>
- <!-- no translation found for app_pair_not_available (3556767440808032031) -->
- <skip />
+ <string name="app_pair_not_available" msgid="3556767440808032031">"O Par de apps não está disponível"</string>
<string name="long_press_widget_to_add" msgid="3587712543577675817">"Toque e pressione para mover um widget."</string>
<string name="long_accessible_way_to_add" msgid="2733588281439571974">"Toque duas vezes e mantenha a tela pressionada para mover um widget ou usar ações personalizadas."</string>
<string name="widget_dims_format" msgid="2370757736025621599">"%1$d × %2$d"</string>
diff --git a/res/values-ro/strings.xml b/res/values-ro/strings.xml
index 07f3cf4..0cfaad4 100644
--- a/res/values-ro/strings.xml
+++ b/res/values-ro/strings.xml
@@ -33,8 +33,7 @@
<string name="app_pair_default_title" msgid="4045241727446873529">"<xliff:g id="APP1">%1$s</xliff:g> | <xliff:g id="APP2">%2$s</xliff:g>"</string>
<string name="app_pair_unlaunchable_at_screen_size" msgid="3446551575502685376">"Perechea de aplicații nu este acceptată pe acest dispozitiv"</string>
<string name="app_pair_needs_unfold" msgid="4588897528143807002">"Deschide dispozitivul ca să folosești această pereche de aplicații"</string>
- <!-- no translation found for app_pair_not_available (3556767440808032031) -->
- <skip />
+ <string name="app_pair_not_available" msgid="3556767440808032031">"Perechea de aplicații nu este disponibilă"</string>
<string name="long_press_widget_to_add" msgid="3587712543577675817">"Atinge și ține apăsat pentru a muta un widget."</string>
<string name="long_accessible_way_to_add" msgid="2733588281439571974">"Atinge de două ori și ține apăsat pentru a muta un widget sau folosește acțiuni personalizate."</string>
<string name="widget_dims_format" msgid="2370757736025621599">"%1$d × %2$d"</string>
diff --git a/res/values-si/strings.xml b/res/values-si/strings.xml
index 25cc880..89594c5 100644
--- a/res/values-si/strings.xml
+++ b/res/values-si/strings.xml
@@ -33,8 +33,7 @@
<string name="app_pair_default_title" msgid="4045241727446873529">"<xliff:g id="APP1">%1$s</xliff:g> | <xliff:g id="APP2">%2$s</xliff:g>"</string>
<string name="app_pair_unlaunchable_at_screen_size" msgid="3446551575502685376">"මෙම යෙදුම් යුගලය මෙම උපාංගයෙහි සහාය නොදක්වයි"</string>
<string name="app_pair_needs_unfold" msgid="4588897528143807002">"මෙම යෙදුම් යුගලය භාවිතා කිරීමට උපාංගය දිගහරින්න"</string>
- <!-- no translation found for app_pair_not_available (3556767440808032031) -->
- <skip />
+ <string name="app_pair_not_available" msgid="3556767440808032031">"යෙදුම් යුගලයක් නොමැත"</string>
<string name="long_press_widget_to_add" msgid="3587712543577675817">"විජට් එකක් ගෙන යාමට ස්පර්ශ කර අල්ලා ගෙන සිටින්න."</string>
<string name="long_accessible_way_to_add" msgid="2733588281439571974">"විජට් එකක් ගෙන යාමට හෝ අභිරුචි ක්රියා භාවිත කිරීමට දෙවරක් තට්ටු කර අල්ලා ගෙන සිටින්න."</string>
<string name="widget_dims_format" msgid="2370757736025621599">"%1$d × %2$d"</string>
diff --git a/res/values-sl/strings.xml b/res/values-sl/strings.xml
index 8693ea2..7184d7e 100644
--- a/res/values-sl/strings.xml
+++ b/res/values-sl/strings.xml
@@ -44,7 +44,7 @@
<string name="add_to_home_screen" msgid="9168649446635919791">"Dodaj na začetni zaslon"</string>
<string name="added_to_home_screen_accessibility_text" msgid="4451545765448884415">"Pripomoček »<xliff:g id="WIDGET_NAME">%1$s</xliff:g>« je dodan na začetni zaslon."</string>
<string name="suggested_widgets_header_title" msgid="1844314680798145222">"Predlogi"</string>
- <string name="productivity_widget_recommendation_category_label" msgid="3811812719618323750">"Nepogrešljivo"</string>
+ <string name="productivity_widget_recommendation_category_label" msgid="3811812719618323750">"Osnove"</string>
<string name="news_widget_recommendation_category_label" msgid="6756167867113741310">"Novice in revije"</string>
<string name="social_and_entertainment_widget_recommendation_category_label" msgid="2923840997302308191">"Vaš kotiček za sprostitev"</string>
<string name="entertainment_widget_recommendation_category_label" msgid="3973107268630717874">"Razvedrilo"</string>
diff --git a/res/values-sq/strings.xml b/res/values-sq/strings.xml
index 7643c4a..29b3416 100644
--- a/res/values-sq/strings.xml
+++ b/res/values-sq/strings.xml
@@ -33,8 +33,7 @@
<string name="app_pair_default_title" msgid="4045241727446873529">"<xliff:g id="APP1">%1$s</xliff:g> | <xliff:g id="APP2">%2$s</xliff:g>"</string>
<string name="app_pair_unlaunchable_at_screen_size" msgid="3446551575502685376">"Ky çift aplikacionesh nuk mbështetet në këtë pajisje"</string>
<string name="app_pair_needs_unfold" msgid="4588897528143807002">"Shpalose pajisjen për të përdorur këtë çift aplikacionesh"</string>
- <!-- no translation found for app_pair_not_available (3556767440808032031) -->
- <skip />
+ <string name="app_pair_not_available" msgid="3556767440808032031">"Çifti i aplikacioneve nuk ofrohet"</string>
<string name="long_press_widget_to_add" msgid="3587712543577675817">"Prek dhe mbaj shtypur një miniaplikacion për ta zhvendosur."</string>
<string name="long_accessible_way_to_add" msgid="2733588281439571974">"Trokit dy herë dhe mbaje shtypur një miniapliikacion për ta zhvendosur atë ose për të përdorur veprimet e personalizuara."</string>
<string name="widget_dims_format" msgid="2370757736025621599">"%1$d × %2$d"</string>
diff --git a/res/values-sv/strings.xml b/res/values-sv/strings.xml
index fd34dee..07672c7 100644
--- a/res/values-sv/strings.xml
+++ b/res/values-sv/strings.xml
@@ -33,8 +33,7 @@
<string name="app_pair_default_title" msgid="4045241727446873529">"<xliff:g id="APP1">%1$s</xliff:g> | <xliff:g id="APP2">%2$s</xliff:g>"</string>
<string name="app_pair_unlaunchable_at_screen_size" msgid="3446551575502685376">"De här apparna som ska användas tillsammans stöds inte på den här enheten"</string>
<string name="app_pair_needs_unfold" msgid="4588897528143807002">"Vik upp enheten för att använda de här apparna som ska användas tillsammans"</string>
- <!-- no translation found for app_pair_not_available (3556767440808032031) -->
- <skip />
+ <string name="app_pair_not_available" msgid="3556767440808032031">"App-paret är inte tillgängligt"</string>
<string name="long_press_widget_to_add" msgid="3587712543577675817">"Tryck länge för att flytta en widget."</string>
<string name="long_accessible_way_to_add" msgid="2733588281439571974">"Tryck snabbt två gånger och håll kvar för att flytta en widget eller använda anpassade åtgärder."</string>
<string name="widget_dims_format" msgid="2370757736025621599">"%1$d × %2$d"</string>
diff --git a/res/values-sw600dp/dimens.xml b/res/values-sw600dp/dimens.xml
index cc1f09e..eda9b2d 100644
--- a/res/values-sw600dp/dimens.xml
+++ b/res/values-sw600dp/dimens.xml
@@ -40,6 +40,7 @@
<!-- Hotseat -->
<dimen name="dynamic_grid_hotseat_side_padding">0dp</dimen>
<dimen name="spring_loaded_hotseat_top_margin">65dp</dimen>
+ <dimen name="min_hotseat_icon_space">17dp</dimen>
<!-- Dragging -->
<dimen name="drop_target_top_margin">64dp</dimen>
diff --git a/res/values-ta/strings.xml b/res/values-ta/strings.xml
index 6baa6b1..68f3633 100644
--- a/res/values-ta/strings.xml
+++ b/res/values-ta/strings.xml
@@ -33,8 +33,7 @@
<string name="app_pair_default_title" msgid="4045241727446873529">"<xliff:g id="APP1">%1$s</xliff:g> | <xliff:g id="APP2">%2$s</xliff:g>"</string>
<string name="app_pair_unlaunchable_at_screen_size" msgid="3446551575502685376">"இந்தச் சாதனத்தில் இந்த ஆப்ஸ் ஜோடி ஆதரிக்கப்படவில்லை"</string>
<string name="app_pair_needs_unfold" msgid="4588897528143807002">"இந்த ஆப்ஸ் ஜோடியைப் பயன்படுத்த சாதனத்தை விரியுங்கள்"</string>
- <!-- no translation found for app_pair_not_available (3556767440808032031) -->
- <skip />
+ <string name="app_pair_not_available" msgid="3556767440808032031">"ஆப்ஸ் ஜோடி கிடைக்கவில்லை"</string>
<string name="long_press_widget_to_add" msgid="3587712543577675817">"விட்ஜெட்டை நகர்த்தத் தொட்டுப் பிடிக்கவும்."</string>
<string name="long_accessible_way_to_add" msgid="2733588281439571974">"விட்ஜெட்டை நகர்த்த இருமுறை தட்டிப் பிடிக்கவும் அல்லது பிரத்தியேகச் செயல்களைப் பயன்படுத்தவும்."</string>
<string name="widget_dims_format" msgid="2370757736025621599">"%1$d × %2$d"</string>
diff --git a/res/values-tr/strings.xml b/res/values-tr/strings.xml
index b4743d6..5a88489 100644
--- a/res/values-tr/strings.xml
+++ b/res/values-tr/strings.xml
@@ -33,8 +33,7 @@
<string name="app_pair_default_title" msgid="4045241727446873529">"<xliff:g id="APP1">%1$s</xliff:g> | <xliff:g id="APP2">%2$s</xliff:g>"</string>
<string name="app_pair_unlaunchable_at_screen_size" msgid="3446551575502685376">"Bu uygulama çifti bu cihazda desteklenmiyor"</string>
<string name="app_pair_needs_unfold" msgid="4588897528143807002">"Bu uygulama çiftini kullanmak için katlanmış durumda olan cihazı açın"</string>
- <!-- no translation found for app_pair_not_available (3556767440808032031) -->
- <skip />
+ <string name="app_pair_not_available" msgid="3556767440808032031">"Uygulama çifti kullanılamıyor"</string>
<string name="long_press_widget_to_add" msgid="3587712543577675817">"Widget\'ı taşımak için dokunup basılı tutun."</string>
<string name="long_accessible_way_to_add" msgid="2733588281439571974">"Widget\'ı taşımak veya özel işlemleri kullanmak için iki kez dokunup basılı tutun."</string>
<string name="widget_dims_format" msgid="2370757736025621599">"%1$d × %2$d"</string>
diff --git a/res/values-uk/strings.xml b/res/values-uk/strings.xml
index d09e51b..8f5cce4 100644
--- a/res/values-uk/strings.xml
+++ b/res/values-uk/strings.xml
@@ -33,8 +33,7 @@
<string name="app_pair_default_title" msgid="4045241727446873529">"<xliff:g id="APP1">%1$s</xliff:g> | <xliff:g id="APP2">%2$s</xliff:g>"</string>
<string name="app_pair_unlaunchable_at_screen_size" msgid="3446551575502685376">"Ці два додатки не можна одночасно використовувати на цьому пристрої"</string>
<string name="app_pair_needs_unfold" msgid="4588897528143807002">"Розкладіть пристрій, щоб одночасно використовувати ці два додатки"</string>
- <!-- no translation found for app_pair_not_available (3556767440808032031) -->
- <skip />
+ <string name="app_pair_not_available" msgid="3556767440808032031">"Одночасне використання двох додатків недоступне"</string>
<string name="long_press_widget_to_add" msgid="3587712543577675817">"Натисніть і втримуйте, щоб перемістити віджет."</string>
<string name="long_accessible_way_to_add" msgid="2733588281439571974">"Двічі натисніть і втримуйте віджет, щоб перемістити його або виконати інші дії."</string>
<string name="widget_dims_format" msgid="2370757736025621599">"%1$d × %2$d"</string>
diff --git a/res/values-uz/strings.xml b/res/values-uz/strings.xml
index 795a495..c9b0610 100644
--- a/res/values-uz/strings.xml
+++ b/res/values-uz/strings.xml
@@ -33,8 +33,7 @@
<string name="app_pair_default_title" msgid="4045241727446873529">"<xliff:g id="APP1">%1$s</xliff:g> | <xliff:g id="APP2">%2$s</xliff:g>"</string>
<string name="app_pair_unlaunchable_at_screen_size" msgid="3446551575502685376">"Bu ilova jufti ushbu qurilmada ishlamaydi"</string>
<string name="app_pair_needs_unfold" msgid="4588897528143807002">"Bu ilova juftidan foydalanish uchun qurilmani oching"</string>
- <!-- no translation found for app_pair_not_available (3556767440808032031) -->
- <skip />
+ <string name="app_pair_not_available" msgid="3556767440808032031">"Ikkita ilovadan bir vaqtda foydalanish mumkin emas"</string>
<string name="long_press_widget_to_add" msgid="3587712543577675817">"Vidjetni bosib turgan holatda suring."</string>
<string name="long_accessible_way_to_add" msgid="2733588281439571974">"Ikki marta bosib va bosib turgan holatda vidjetni tanlang yoki maxsus amaldan foydalaning."</string>
<string name="widget_dims_format" msgid="2370757736025621599">"%1$d × %2$d"</string>
diff --git a/res/values-vi/strings.xml b/res/values-vi/strings.xml
index 99bf064..448d2a2 100644
--- a/res/values-vi/strings.xml
+++ b/res/values-vi/strings.xml
@@ -33,8 +33,7 @@
<string name="app_pair_default_title" msgid="4045241727446873529">"<xliff:g id="APP1">%1$s</xliff:g> | <xliff:g id="APP2">%2$s</xliff:g>"</string>
<string name="app_pair_unlaunchable_at_screen_size" msgid="3446551575502685376">"Cặp ứng dụng này không hoạt động được trên thiết bị này"</string>
<string name="app_pair_needs_unfold" msgid="4588897528143807002">"Hãy mở thiết bị để dùng cặp ứng dụng này"</string>
- <!-- no translation found for app_pair_not_available (3556767440808032031) -->
- <skip />
+ <string name="app_pair_not_available" msgid="3556767440808032031">"Hiện không có cặp ứng dụng này"</string>
<string name="long_press_widget_to_add" msgid="3587712543577675817">"Chạm và giữ để di chuyển một tiện ích."</string>
<string name="long_accessible_way_to_add" msgid="2733588281439571974">"Nhấn đúp và giữ để di chuyển một tiện ích hoặc sử dụng các thao tác tùy chỉnh."</string>
<string name="widget_dims_format" msgid="2370757736025621599">"%1$d × %2$d"</string>
diff --git a/res/values-zh-rCN/strings.xml b/res/values-zh-rCN/strings.xml
index 2b4abe1..d675db3 100644
--- a/res/values-zh-rCN/strings.xml
+++ b/res/values-zh-rCN/strings.xml
@@ -33,8 +33,7 @@
<string name="app_pair_default_title" msgid="4045241727446873529">"<xliff:g id="APP1">%1$s</xliff:g> | <xliff:g id="APP2">%2$s</xliff:g>"</string>
<string name="app_pair_unlaunchable_at_screen_size" msgid="3446551575502685376">"在该设备上无法使用此应用对"</string>
<string name="app_pair_needs_unfold" msgid="4588897528143807002">"展开设备即可使用此应用组合"</string>
- <!-- no translation found for app_pair_not_available (3556767440808032031) -->
- <skip />
+ <string name="app_pair_not_available" msgid="3556767440808032031">"应用对不可用"</string>
<string name="long_press_widget_to_add" msgid="3587712543577675817">"轻触并按住即可移动微件。"</string>
<string name="long_accessible_way_to_add" msgid="2733588281439571974">"点按两次并按住微件即可移动该微件或使用自定义操作。"</string>
<string name="widget_dims_format" msgid="2370757736025621599">"%1$d × %2$d"</string>
diff --git a/res/values-zh-rHK/strings.xml b/res/values-zh-rHK/strings.xml
index a48ca7e..e9c968a 100644
--- a/res/values-zh-rHK/strings.xml
+++ b/res/values-zh-rHK/strings.xml
@@ -33,8 +33,7 @@
<string name="app_pair_default_title" msgid="4045241727446873529">"<xliff:g id="APP1">%1$s</xliff:g> | <xliff:g id="APP2">%2$s</xliff:g>"</string>
<string name="app_pair_unlaunchable_at_screen_size" msgid="3446551575502685376">"此裝置不支援此應用程式配對"</string>
<string name="app_pair_needs_unfold" msgid="4588897528143807002">"打開裝置即可使用此應用程式配對"</string>
- <!-- no translation found for app_pair_not_available (3556767440808032031) -->
- <skip />
+ <string name="app_pair_not_available" msgid="3556767440808032031">"應用程式配對無法使用"</string>
<string name="long_press_widget_to_add" msgid="3587712543577675817">"輕觸並按住即可移動小工具。"</string>
<string name="long_accessible_way_to_add" msgid="2733588281439571974">"㩒兩下之後㩒住,就可以郁小工具或者用自訂操作。"</string>
<string name="widget_dims_format" msgid="2370757736025621599">"%1$d × %2$d"</string>
diff --git a/res/values-zh-rTW/strings.xml b/res/values-zh-rTW/strings.xml
index 66e504c..e891ee2 100644
--- a/res/values-zh-rTW/strings.xml
+++ b/res/values-zh-rTW/strings.xml
@@ -33,8 +33,7 @@
<string name="app_pair_default_title" msgid="4045241727446873529">"<xliff:g id="APP1">%1$s</xliff:g> | <xliff:g id="APP2">%2$s</xliff:g>"</string>
<string name="app_pair_unlaunchable_at_screen_size" msgid="3446551575502685376">"這部裝置不支援這組應用程式配對"</string>
<string name="app_pair_needs_unfold" msgid="4588897528143807002">"展開裝置即可使用這組應用程式配對"</string>
- <!-- no translation found for app_pair_not_available (3556767440808032031) -->
- <skip />
+ <string name="app_pair_not_available" msgid="3556767440808032031">"這個應用程式配對無法使用"</string>
<string name="long_press_widget_to_add" msgid="3587712543577675817">"按住即可移動小工具。"</string>
<string name="long_accessible_way_to_add" msgid="2733588281439571974">"輕觸兩下並按住即可移動小工具或使用自訂操作。"</string>
<string name="widget_dims_format" msgid="2370757736025621599">"%1$d × %2$d"</string>
diff --git a/res/values-zu/strings.xml b/res/values-zu/strings.xml
index 9a90e1e..7a0871a 100644
--- a/res/values-zu/strings.xml
+++ b/res/values-zu/strings.xml
@@ -33,8 +33,7 @@
<string name="app_pair_default_title" msgid="4045241727446873529">"<xliff:g id="APP1">%1$s</xliff:g> | <xliff:g id="APP2">%2$s</xliff:g>"</string>
<string name="app_pair_unlaunchable_at_screen_size" msgid="3446551575502685376">"Lokhu kubhanqwa kwe-app akusekelwa kule divayisi"</string>
<string name="app_pair_needs_unfold" msgid="4588897528143807002">"Vula idivayisi ukuze usebenzise lokhu kubhanqwa kwe-app"</string>
- <!-- no translation found for app_pair_not_available (3556767440808032031) -->
- <skip />
+ <string name="app_pair_not_available" msgid="3556767440808032031">"Ukubhangqwa kwe-app akutholakali"</string>
<string name="long_press_widget_to_add" msgid="3587712543577675817">"Thinta uphinde ubambe ukuze uhambise iwijethi."</string>
<string name="long_accessible_way_to_add" msgid="2733588281439571974">"Thepha kabili uphinde ubambe ukuze uhambise iwijethi noma usebenzise izindlela ezingokwezifiso."</string>
<string name="widget_dims_format" msgid="2370757736025621599">"%1$d × %2$d"</string>
diff --git a/res/values/attrs.xml b/res/values/attrs.xml
index b3a25c0..f23c790 100644
--- a/res/values/attrs.xml
+++ b/res/values/attrs.xml
@@ -204,17 +204,6 @@
defaults to 2 * numHotseatIcons -->
<attr name="numExtendedHotseatIcons" format="integer" />
- <!-- alignment of hotseat to the grid.
- Not applicable for 3 button mode when taskbar is enabled -->
- <!-- defaults to numColumns, if not specified -->
- <attr name="hotseatColumnSpan" format="integer" />
- <!-- defaults to numColumns, if not specified -->
- <attr name="hotseatColumnSpanLandscape" format="integer" />
- <!-- defaults to numColumns, if not specified -->
- <attr name="hotseatColumnSpanTwoPanelLandscape" format="integer" />
- <!-- defaults to numColumns, if not specified -->
- <attr name="hotseatColumnSpanTwoPanelPortrait" format="integer" />
-
<!-- Spacing to have at the end of the nav buttons in large screen 3 button nav,
defaults to @dimen/taskbar_button_margin_default -->
<attr name="inlineNavButtonsEndSpacing" format="reference" />
diff --git a/res/values/dimens.xml b/res/values/dimens.xml
index a056e81..1e5a957 100644
--- a/res/values/dimens.xml
+++ b/res/values/dimens.xml
@@ -147,13 +147,15 @@
<dimen name="work_fab_height">56dp</dimen>
<dimen name="work_fab_radius">16dp</dimen>
<dimen name="work_fab_icon_size">24dp</dimen>
- <dimen name="work_fab_text_start_margin">8dp</dimen>
+ <dimen name="work_fab_icon_end_margin">12dp</dimen>
+ <dimen name="work_fab_text_end_margin">16dp</dimen>
<dimen name="work_card_padding_horizontal">10dp</dimen>
<dimen name="work_fab_width">214dp</dimen>
<dimen name="work_card_button_height">52dp</dimen>
<dimen name="work_fab_margin">16dp</dimen>
<dimen name="work_fab_margin_bottom">20dp</dimen>
- <dimen name="work_mode_fab_padding">16dp</dimen>
+ <dimen name="work_mode_fab_background_start_padding">16dp</dimen>
+ <dimen name="work_mode_fab_background_end_padding">4dp</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>
@@ -183,6 +185,7 @@
<dimen name="widget_cell_add_button_height">48dp</dimen>
<dimen name="widget_cell_add_button_start_padding">8dp</dimen>
<dimen name="widget_cell_add_button_end_padding">16dp</dimen>
+ <dimen name="widget_cell_add_button_scroll_padding">24dp</dimen>
<dimen name="widget_tabs_button_horizontal_padding">4dp</dimen>
<dimen name="widget_tabs_horizontal_padding">16dp</dimen>
diff --git a/res/xml/device_profiles.xml b/res/xml/device_profiles.xml
index c9a44a1..1d0dbff 100644
--- a/res/xml/device_profiles.xml
+++ b/res/xml/device_profiles.xml
@@ -168,7 +168,6 @@
launcher:numFolderRows="3"
launcher:numFolderColumns="3"
launcher:numHotseatIcons="6"
- launcher:hotseatColumnSpanLandscape="4"
launcher:numAllAppsColumns="6"
launcher:isScalable="true"
launcher:inlineNavButtonsEndSpacing="@dimen/taskbar_button_margin_6_5"
diff --git a/src/com/android/launcher3/DeviceProfile.java b/src/com/android/launcher3/DeviceProfile.java
index 6cb33a8..a667c96 100644
--- a/src/com/android/launcher3/DeviceProfile.java
+++ b/src/com/android/launcher3/DeviceProfile.java
@@ -47,6 +47,7 @@
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
+import androidx.annotation.VisibleForTesting;
import androidx.core.content.res.ResourcesCompat;
import com.android.launcher3.CellLayout.ContainerType;
@@ -212,6 +213,8 @@
// Hotseat
public int numShownHotseatIcons;
public int hotseatCellHeightPx;
+ private int mHotseatColumnSpan;
+ private int mHotseatWidthPx; // not used in vertical bar layout
public final boolean areNavButtonsInline;
// In portrait: size = height, in landscape: size = width
public int hotseatBarSizePx;
@@ -551,6 +554,7 @@
areNavButtonsInline = isTaskbarPresent && !isGestureMode;
numShownHotseatIcons =
isTwoPanels ? inv.numDatabaseHotseatIcons : inv.numShownHotseatIcons;
+ mHotseatColumnSpan = inv.numColumns;
numShownAllAppsColumns =
isTwoPanels ? inv.numDatabaseAllAppsColumns : inv.numAllAppsColumns;
@@ -818,8 +822,7 @@
- hotseatBorderSpace * numShownHotseatIcons
- iconExtraSpacePx;
} else {
- int columns = inv.hotseatColumnSpan[mTypeIndex];
- return getIconToIconWidthForColumns(columns) - iconExtraSpacePx;
+ return getIconToIconWidthForColumns(mHotseatColumnSpan) - iconExtraSpacePx;
}
}
@@ -890,10 +893,31 @@
public void recalculateHotseatWidthAndBorderSpace() {
if (!mIsScalableGrid) return;
- int columns = inv.hotseatColumnSpan[mTypeIndex];
- float hotseatWidthPx = getIconToIconWidthForColumns(columns);
- hotseatBorderSpace = calculateHotseatBorderSpace(hotseatWidthPx, /* numExtraBorder= */ 0);
+ updateHotseatWidthAndBorderSpace(inv.numColumns);
+ int numWorkspaceColumns = getPanelCount() * inv.numColumns;
+ if (isTwoPanels) {
+ updateHotseatWidthAndBorderSpace(inv.numDatabaseHotseatIcons);
+ // If hotseat doesn't fit with current width, increase column span to fit by multiple
+ // of 2.
+ while (hotseatBorderSpace < mMinHotseatIconSpacePx
+ && mHotseatColumnSpan < numWorkspaceColumns) {
+ updateHotseatWidthAndBorderSpace(mHotseatColumnSpan + 2);
+ }
+ }
+ if (isQsbInline) {
+ // If QSB is inline, reduce column span until it fits.
+ int maxHotseatWidthAllowedPx = getIconToIconWidthForColumns(numWorkspaceColumns);
+ int minHotseatWidthRequiredPx =
+ mMinHotseatQsbWidthPx + hotseatBorderSpace + mHotseatWidthPx;
+ while (minHotseatWidthRequiredPx > maxHotseatWidthAllowedPx
+ && mHotseatColumnSpan > 1) {
+ updateHotseatWidthAndBorderSpace(mHotseatColumnSpan - 1);
+ minHotseatWidthRequiredPx =
+ mMinHotseatQsbWidthPx + hotseatBorderSpace + mHotseatWidthPx;
+ }
+ }
hotseatQsbWidth = calculateQsbWidth(hotseatBorderSpace);
+
// Spaces should be correct when the nav buttons are not inline
if (!areNavButtonsInline) {
return;
@@ -935,6 +959,12 @@
} while (hotseatBorderSpace < mMinHotseatIconSpacePx && numShownHotseatIcons > 1);
}
+ private void updateHotseatWidthAndBorderSpace(int columns) {
+ mHotseatColumnSpan = columns;
+ mHotseatWidthPx = getIconToIconWidthForColumns(mHotseatColumnSpan);
+ hotseatBorderSpace = calculateHotseatBorderSpace(mHotseatWidthPx, /* numExtraBorder= */ 0);
+ }
+
private Point getCellLayoutBorderSpace(InvariantDeviceProfile idp) {
return getCellLayoutBorderSpace(idp, 1f);
}
@@ -958,6 +988,16 @@
return mInfo;
}
+ @VisibleForTesting
+ public int getHotseatColumnSpan() {
+ return mHotseatColumnSpan;
+ }
+
+ @VisibleForTesting
+ public int getHotseatWidthPx() {
+ return mHotseatWidthPx;
+ }
+
public Builder toBuilder(Context context) {
WindowBounds bounds = new WindowBounds(
widthPx, heightPx, availableWidthPx, availableHeightPx, rotationHint);
@@ -2120,7 +2160,8 @@
writer.println(prefix + pxToDpStr("allAppsLeftRightMargin", allAppsLeftRightMargin));
writer.println(prefix + pxToDpStr("hotseatBarSizePx", hotseatBarSizePx));
- writer.println(prefix + "\tinv.hotseatColumnSpan: " + inv.hotseatColumnSpan[mTypeIndex]);
+ writer.println(prefix + "\tmHotseatColumnSpan: " + mHotseatColumnSpan);
+ writer.println(prefix + pxToDpStr("mHotseatWidthPx", mHotseatWidthPx));
writer.println(prefix + pxToDpStr("hotseatCellHeightPx", hotseatCellHeightPx));
writer.println(prefix + pxToDpStr("hotseatBarBottomSpacePx", hotseatBarBottomSpacePx));
writer.println(prefix + pxToDpStr("mHotseatBarEdgePaddingPx",
diff --git a/src/com/android/launcher3/FastScrollRecyclerView.java b/src/com/android/launcher3/FastScrollRecyclerView.java
index 51c7a05..eff748a 100644
--- a/src/com/android/launcher3/FastScrollRecyclerView.java
+++ b/src/com/android/launcher3/FastScrollRecyclerView.java
@@ -155,7 +155,7 @@
* Maps the touch (from 0..1) to the adapter position that should be visible.
* <p>Override in each subclass of this base class.
*/
- public abstract String scrollToPositionAtProgress(float touchFraction);
+ public abstract CharSequence scrollToPositionAtProgress(float touchFraction);
/**
* Updates the bounds for the scrollbar.
@@ -193,14 +193,4 @@
}
scrollToPosition(0);
}
-
- /**
- * Scrolls this recycler view to the bottom with easing and duration.
- */
- public void scrollToBottomWithMotion(int duration) {
- if (mScrollbar != null) {
- mScrollbar.reattachThumbToScroll();
- }
- smoothScrollBy(0, getAvailableScrollHeight(), Interpolators.EMPHASIZED, duration);
- }
}
diff --git a/src/com/android/launcher3/InvariantDeviceProfile.java b/src/com/android/launcher3/InvariantDeviceProfile.java
index bc36336..98cb84e 100644
--- a/src/com/android/launcher3/InvariantDeviceProfile.java
+++ b/src/com/android/launcher3/InvariantDeviceProfile.java
@@ -163,7 +163,6 @@
*/
public int numDatabaseHotseatIcons;
- public int[] hotseatColumnSpan;
public float[] hotseatBarBottomSpace;
public float[] hotseatQsbSpace;
@@ -263,7 +262,7 @@
// Get the display info based on default display and interpolate it to existing display
Info defaultInfo = DisplayController.INSTANCE.get(context).getInfo();
- @DeviceType int defaultDeviceType = getDeviceType(defaultInfo);
+ @DeviceType int defaultDeviceType = defaultInfo.getDeviceType();
DisplayOption defaultDisplayOption = invDistWeightedInterpolate(
defaultInfo,
getPredefinedDeviceProfiles(context, gridName, defaultDeviceType,
@@ -272,7 +271,7 @@
Context displayContext = context.createDisplayContext(display);
Info myInfo = new Info(displayContext);
- @DeviceType int deviceType = getDeviceType(myInfo);
+ @DeviceType int deviceType = myInfo.getDeviceType();
DisplayOption myDisplayOption = invDistWeightedInterpolate(
myInfo,
getPredefinedDeviceProfiles(context, gridName, deviceType,
@@ -325,30 +324,13 @@
}
}
- private static @DeviceType int getDeviceType(Info displayInfo) {
- int flagPhone = 1 << 0;
- int flagTablet = 1 << 1;
-
- int type = displayInfo.supportedBounds.stream()
- .mapToInt(bounds -> displayInfo.isTablet(bounds) ? flagTablet : flagPhone)
- .reduce(0, (a, b) -> a | b);
- if (type == (flagPhone | flagTablet)) {
- // device has profiles supporting both phone and table modes
- return TYPE_MULTI_DISPLAY;
- } else if (type == flagTablet) {
- return TYPE_TABLET;
- } else {
- return TYPE_PHONE;
- }
- }
-
public static String getCurrentGridName(Context context) {
return LauncherPrefs.get(context).get(GRID_NAME);
}
private String initGrid(Context context, String gridName) {
Info displayInfo = DisplayController.INSTANCE.get(context).getInfo();
- @DeviceType int deviceType = getDeviceType(displayInfo);
+ @DeviceType int deviceType = displayInfo.getDeviceType();
ArrayList<DisplayOption> allOptions =
getPredefinedDeviceProfiles(context, gridName, deviceType,
@@ -429,7 +411,6 @@
numShownHotseatIcons = closestProfile.numHotseatIcons;
numDatabaseHotseatIcons = deviceType == TYPE_MULTI_DISPLAY
? closestProfile.numDatabaseHotseatIcons : closestProfile.numHotseatIcons;
- hotseatColumnSpan = closestProfile.hotseatColumnSpan;
hotseatBarBottomSpace = displayOption.hotseatBarBottomSpace;
hotseatQsbSpace = displayOption.hotseatQsbSpace;
@@ -879,8 +860,6 @@
private final int numHotseatIcons;
private final int numDatabaseHotseatIcons;
- private final int[] hotseatColumnSpan = new int[COUNT_SIZES];
-
private final boolean[] inlineQsb = new boolean[COUNT_SIZES];
private @DimenRes int inlineNavButtonsEndSpacing;
@@ -931,17 +910,6 @@
numDatabaseHotseatIcons = a.getInt(
R.styleable.GridDisplayOption_numExtendedHotseatIcons, 2 * numHotseatIcons);
- hotseatColumnSpan[INDEX_DEFAULT] = a.getInt(
- R.styleable.GridDisplayOption_hotseatColumnSpan, numColumns);
- hotseatColumnSpan[INDEX_LANDSCAPE] = a.getInt(
- R.styleable.GridDisplayOption_hotseatColumnSpanLandscape, numColumns);
- hotseatColumnSpan[INDEX_TWO_PANEL_LANDSCAPE] = a.getInt(
- R.styleable.GridDisplayOption_hotseatColumnSpanTwoPanelLandscape,
- numColumns);
- hotseatColumnSpan[INDEX_TWO_PANEL_PORTRAIT] = a.getInt(
- R.styleable.GridDisplayOption_hotseatColumnSpanTwoPanelPortrait,
- numColumns);
-
inlineNavButtonsEndSpacing =
a.getResourceId(R.styleable.GridDisplayOption_inlineNavButtonsEndSpacing,
R.dimen.taskbar_button_margin_default);
diff --git a/src/com/android/launcher3/Launcher.java b/src/com/android/launcher3/Launcher.java
index c91d4d0..dc7c349 100644
--- a/src/com/android/launcher3/Launcher.java
+++ b/src/com/android/launcher3/Launcher.java
@@ -2508,7 +2508,13 @@
final int itemCount = container.getChildCount();
for (int itemIdx = 0; itemIdx < itemCount; itemIdx++) {
View item = container.getChildAt(itemIdx);
- if (op.test((ItemInfo) item.getTag())) {
+ if (item instanceof ViewGroup viewGroup) {
+ View view = mapOverViewGroup(viewGroup, op);
+ if (view != null) {
+ return view;
+ }
+ }
+ if (item.getTag() instanceof ItemInfo itemInfo && op.test(itemInfo)) {
return item;
}
}
diff --git a/src/com/android/launcher3/LauncherAnimUtils.java b/src/com/android/launcher3/LauncherAnimUtils.java
index c20f323..6a9d170 100644
--- a/src/com/android/launcher3/LauncherAnimUtils.java
+++ b/src/com/android/launcher3/LauncherAnimUtils.java
@@ -220,17 +220,28 @@
/**
* Utility method to create an {@link AnimatorListener} which executes a callback on animation
- * cancel.
+ * cancel. Once the cancel has been dispatched, this listener will no longer be called.
*/
- public static AnimatorListener newCancelListener(Runnable callback) {
- return new AnimatorListenerAdapter() {
+ public static AnimatorListener newSingleUseCancelListener(Runnable callback) {
+ return newCancelListener(callback, true);
+ }
+ /**
+ * Utility method to create an {@link AnimatorListener} which executes a callback on animation
+ * cancel.
+ *
+ * @param isSingleUse {@code true} means the callback will be called at most once
+ */
+ public static AnimatorListener newCancelListener(Runnable callback, boolean isSingleUse) {
+ return new AnimatorListenerAdapter() {
boolean mDispatched = false;
@Override
public void onAnimationCancel(Animator animation) {
if (!mDispatched) {
- mDispatched = true;
+ if (isSingleUse) {
+ mDispatched = true;
+ }
callback.run();
}
}
diff --git a/src/com/android/launcher3/LauncherPrefs.kt b/src/com/android/launcher3/LauncherPrefs.kt
index 875c407..80a8cea 100644
--- a/src/com/android/launcher3/LauncherPrefs.kt
+++ b/src/com/android/launcher3/LauncherPrefs.kt
@@ -19,7 +19,6 @@
import android.content.Context.MODE_PRIVATE
import android.content.SharedPreferences
import android.content.SharedPreferences.OnSharedPreferenceChangeListener
-import android.util.Log
import androidx.annotation.VisibleForTesting
import com.android.launcher3.BuildConfig.WIDGET_ON_FIRST_SCREEN
import com.android.launcher3.LauncherFiles.DEVICE_PREFERENCES_KEY
@@ -37,8 +36,6 @@
* Use same context for shared preferences, so that we use a single cached instance
*
* TODO(b/262721340): Replace all direct SharedPreference refs with LauncherPrefs / Item methods.
- * TODO(b/274501660): Fix ReorderWidgets#simpleReorder test before enabling
- * isBootAwareStartupDataEnabled
*/
class LauncherPrefs(private val encryptedContext: Context) {
private val deviceProtectedStorageContext =
@@ -51,22 +48,8 @@
private val Item.encryptedPrefs
get() = encryptedContext.getSharedPreferences(sharedPrefFile, MODE_PRIVATE)
- // This call to `SharedPreferences` needs to be explicit rather than using `get` since doing so
- // would result in a circular dependency between `isStartupDataMigrated` and `choosePreferences`
- val isStartupDataMigrated: Boolean
- get() =
- bootAwarePrefs.getBoolean(
- IS_STARTUP_DATA_MIGRATED.sharedPrefKey,
- IS_STARTUP_DATA_MIGRATED.defaultValue
- )
-
private fun chooseSharedPreferences(item: Item): SharedPreferences =
- if (
- (moveStartupDataToDeviceProtectedStorageIsEnabled &&
- item.encryptionType == EncryptionType.MOVE_TO_DEVICE_PROTECTED &&
- isStartupDataMigrated) || item.encryptionType == EncryptionType.DEVICE_PROTECTED
- )
- bootAwarePrefs
+ if (item.encryptionType == EncryptionType.DEVICE_PROTECTED) bootAwarePrefs
else item.encryptedPrefs
/** Wrapper around `getInner` for a `ContextualItem` */
@@ -146,11 +129,7 @@
.toMutableMap()
val bootAwareUpdates =
- updates.filter {
- (it.first.encryptionType == EncryptionType.MOVE_TO_DEVICE_PROTECTED &&
- moveStartupDataToDeviceProtectedStorageIsEnabled) ||
- it.first.encryptionType == EncryptionType.DEVICE_PROTECTED
- }
+ updates.filter { it.first.encryptionType == EncryptionType.DEVICE_PROTECTED }
if (bootAwareUpdates.isNotEmpty()) {
updatesPerPrefFile[bootAwarePrefs] = bootAwareUpdates
}
@@ -251,12 +230,7 @@
.groupBy { it.encryptedPrefs }
.toMutableMap()
- val bootAwareUpdates =
- items.filter {
- (it.encryptionType == EncryptionType.MOVE_TO_DEVICE_PROTECTED &&
- moveStartupDataToDeviceProtectedStorageIsEnabled) ||
- it.encryptionType == EncryptionType.DEVICE_PROTECTED
- }
+ val bootAwareUpdates = items.filter { it.encryptionType == EncryptionType.DEVICE_PROTECTED }
if (bootAwareUpdates.isNotEmpty()) {
itemsPerFile[bootAwarePrefs] = bootAwareUpdates
}
@@ -268,24 +242,7 @@
}
}
- fun migrateStartupDataToDeviceProtectedStorage() {
- if (!moveStartupDataToDeviceProtectedStorageIsEnabled) return
-
- Log.d(
- TAG,
- "Migrating data to unencrypted shared preferences to enable preloading " +
- "while the user is locked the next time the device reboots."
- )
-
- with(bootAwarePrefs.edit()) {
- ITEMS_TO_MOVE_TO_DEVICE_PROTECTED_STORAGE.forEach { putValue(it, get(it)) }
- putBoolean(IS_STARTUP_DATA_MIGRATED.sharedPrefKey, true)
- apply()
- }
- }
-
companion object {
- private const val TAG = "LauncherPrefs"
@VisibleForTesting const val BOOT_AWARE_PREFS_KEY = "boot_aware_prefs"
@JvmField var INSTANCE = MainThreadInitializedObject { LauncherPrefs(it) }
@@ -295,30 +252,20 @@
const val TASKBAR_PINNING_KEY = "TASKBAR_PINNING_KEY"
const val SHOULD_SHOW_SMARTSPACE_KEY = "SHOULD_SHOW_SMARTSPACE_KEY"
@JvmField
- val ICON_STATE =
- nonRestorableItem("pref_icon_shape_path", "", EncryptionType.MOVE_TO_DEVICE_PROTECTED)
+ val ICON_STATE = nonRestorableItem("pref_icon_shape_path", "", EncryptionType.ENCRYPTED)
@JvmField
val ENABLE_TWOLINE_ALLAPPS_TOGGLE = backedUpItem("pref_enable_two_line_toggle", false)
@JvmField
- val THEMED_ICONS =
- backedUpItem(Themes.KEY_THEMED_ICONS, false, EncryptionType.MOVE_TO_DEVICE_PROTECTED)
+ val THEMED_ICONS = backedUpItem(Themes.KEY_THEMED_ICONS, false, EncryptionType.ENCRYPTED)
@JvmField val PROMISE_ICON_IDS = backedUpItem(InstallSessionHelper.PROMISE_ICON_IDS, "")
@JvmField val WORK_EDU_STEP = backedUpItem("showed_work_profile_edu", 0)
@JvmField
val WORKSPACE_SIZE =
- backedUpItem(
- DeviceGridState.KEY_WORKSPACE_SIZE,
- "",
- EncryptionType.MOVE_TO_DEVICE_PROTECTED
- )
+ backedUpItem(DeviceGridState.KEY_WORKSPACE_SIZE, "", EncryptionType.ENCRYPTED)
@JvmField
val HOTSEAT_COUNT =
- backedUpItem(
- DeviceGridState.KEY_HOTSEAT_COUNT,
- -1,
- EncryptionType.MOVE_TO_DEVICE_PROTECTED
- )
+ backedUpItem(DeviceGridState.KEY_HOTSEAT_COUNT, -1, EncryptionType.ENCRYPTED)
@JvmField
val TASKBAR_PINNING =
backedUpItem(TASKBAR_PINNING_KEY, false, EncryptionType.DEVICE_PROTECTED)
@@ -328,11 +275,10 @@
backedUpItem(
DeviceGridState.KEY_DEVICE_TYPE,
InvariantDeviceProfile.TYPE_PHONE,
- EncryptionType.MOVE_TO_DEVICE_PROTECTED
+ EncryptionType.ENCRYPTED
)
@JvmField
- val DB_FILE =
- backedUpItem(DeviceGridState.KEY_DB_FILE, "", EncryptionType.MOVE_TO_DEVICE_PROTECTED)
+ val DB_FILE = backedUpItem(DeviceGridState.KEY_DB_FILE, "", EncryptionType.ENCRYPTED)
@JvmField
val SHOULD_SHOW_SMARTSPACE =
backedUpItem(
@@ -345,15 +291,11 @@
backedUpItem(
RestoreDbTask.RESTORED_DEVICE_TYPE,
InvariantDeviceProfile.TYPE_PHONE,
- EncryptionType.MOVE_TO_DEVICE_PROTECTED
+ EncryptionType.ENCRYPTED
)
@JvmField
val IS_FIRST_LOAD_AFTER_RESTORE =
- nonRestorableItem(
- FIRST_LOAD_AFTER_RESTORE_KEY,
- false,
- EncryptionType.MOVE_TO_DEVICE_PROTECTED
- )
+ 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
@@ -362,7 +304,7 @@
"idp_grid_name",
isBackedUp = true,
defaultValue = null,
- encryptionType = EncryptionType.MOVE_TO_DEVICE_PROTECTED,
+ encryptionType = EncryptionType.ENCRYPTED,
type = String::class.java
)
@JvmField
@@ -370,14 +312,6 @@
backedUpItem(RotationHelper.ALLOW_ROTATION_PREFERENCE_KEY, Boolean::class.java) {
RotationHelper.getAllowRotationDefaultValue(DisplayController.INSTANCE.get(it).info)
}
- @JvmField
- val IS_STARTUP_DATA_MIGRATED =
- ConstantItem(
- "is_startup_data_boot_aware",
- isBackedUp = false,
- defaultValue = false,
- encryptionType = EncryptionType.DEVICE_PROTECTED
- )
// Preferences for widget configurations
@JvmField
@@ -442,12 +376,6 @@
}
}
-// It is a var because the unit tests are setting this to true so they can run.
-var moveStartupDataToDeviceProtectedStorageIsEnabled: Boolean =
- com.android.launcher3.config.FeatureFlags.MOVE_STARTUP_DATA_TO_DEVICE_PROTECTED_STORAGE.get()
-
-private val ITEMS_TO_MOVE_TO_DEVICE_PROTECTED_STORAGE: MutableSet<ConstantItem<*>> = mutableSetOf()
-
abstract class Item {
abstract val sharedPrefKey: String
abstract val isBackedUp: Boolean
@@ -467,14 +395,6 @@
// The default value can be null. If so, the type needs to be explicitly stated, or else NPE
override val type: Class<out T> = defaultValue!!::class.java
) : Item() {
- init {
- if (
- encryptionType == EncryptionType.MOVE_TO_DEVICE_PROTECTED &&
- moveStartupDataToDeviceProtectedStorageIsEnabled
- ) {
- ITEMS_TO_MOVE_TO_DEVICE_PROTECTED_STORAGE.add(this)
- }
- }
fun get(c: Context): T = LauncherPrefs.get(c).get(this)
}
@@ -501,5 +421,4 @@
enum class EncryptionType {
ENCRYPTED,
DEVICE_PROTECTED,
- MOVE_TO_DEVICE_PROTECTED
}
diff --git a/src/com/android/launcher3/LauncherSettings.java b/src/com/android/launcher3/LauncherSettings.java
index 84b8ba1..87ac193 100644
--- a/src/com/android/launcher3/LauncherSettings.java
+++ b/src/com/android/launcher3/LauncherSettings.java
@@ -183,6 +183,7 @@
public static final int CONTAINER_SHORTCUTS = -107;
public static final int CONTAINER_SETTINGS = -108;
public static final int CONTAINER_TASKSWITCHER = -109;
+ public static final int CONTAINER_PRIVATESPACE = -110;
// Represents any of the extended containers implemented in non-AOSP variants.
public static final int EXTENDED_CONTAINERS = -200;
diff --git a/src/com/android/launcher3/allapps/AllAppsRecyclerView.java b/src/com/android/launcher3/allapps/AllAppsRecyclerView.java
index 36a44cc..ba34f59 100644
--- a/src/com/android/launcher3/allapps/AllAppsRecyclerView.java
+++ b/src/com/android/launcher3/allapps/AllAppsRecyclerView.java
@@ -180,7 +180,7 @@
* Maps the touch (from 0..1) to the adapter position that should be visible.
*/
@Override
- public String scrollToPositionAtProgress(float touchFraction) {
+ public CharSequence scrollToPositionAtProgress(float touchFraction) {
int rowCount = mApps.getNumAppRows();
if (rowCount == 0) {
return "";
diff --git a/src/com/android/launcher3/allapps/AlphabeticalAppsList.java b/src/com/android/launcher3/allapps/AlphabeticalAppsList.java
index 4d4b8d2..60df7c5 100644
--- a/src/com/android/launcher3/allapps/AlphabeticalAppsList.java
+++ b/src/com/android/launcher3/allapps/AlphabeticalAppsList.java
@@ -22,6 +22,10 @@
import static com.android.launcher3.logging.StatsLogManager.LauncherEvent.LAUNCHER_PRIVATE_SPACE_USER_INSTALLED_APPS_COUNT;
import android.content.Context;
+import android.graphics.drawable.Drawable;
+import android.text.Spannable;
+import android.text.SpannableString;
+import android.text.style.ImageSpan;
import androidx.annotation.Nullable;
import androidx.annotation.VisibleForTesting;
@@ -65,11 +69,11 @@
*/
public static class FastScrollSectionInfo {
// The section name
- public final String sectionName;
+ public final CharSequence sectionName;
// The item position
public final int position;
- public FastScrollSectionInfo(String sectionName, int position) {
+ public FastScrollSectionInfo(CharSequence sectionName, int position) {
this.sectionName = sectionName;
this.position = position;
}
@@ -93,6 +97,7 @@
// The of ordered component names as a result of a search query
private final ArrayList<AdapterItem> mSearchResults = new ArrayList<>();
+ private final SpannableString mPrivateProfileAppScrollerBadge;
private BaseAllAppsAdapter<T> mAdapter;
private AppInfoComparator mAppNameComparator;
private int mNumAppsPerRowAllApps;
@@ -110,6 +115,10 @@
if (mAllAppsStore != null) {
mAllAppsStore.addUpdateListener(this);
}
+ mPrivateProfileAppScrollerBadge = new SpannableString(" ");
+ mPrivateProfileAppScrollerBadge.setSpan(new ImageSpan(context,
+ R.drawable.ic_private_profile_app_scroller_badge, ImageSpan.ALIGN_CENTER),
+ 0, 1, Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);
}
/** Set the number of apps per row when device profile changes. */
@@ -383,6 +392,7 @@
private int addAppsWithSections(List<AppInfo> appList, int startPosition) {
String lastSectionName = null;
boolean hasPrivateApps = false;
+ int position = startPosition;
if (mPrivateProviderManager != null) {
hasPrivateApps = appList.stream().
allMatch(mPrivateProviderManager.getItemInfoMatcher());
@@ -403,11 +413,12 @@
// Create a new section if the section names do not match
if (!sectionName.equals(lastSectionName)) {
lastSectionName = sectionName;
- mFastScrollerSections.add(new FastScrollSectionInfo(sectionName, startPosition));
+ mFastScrollerSections.add(new FastScrollSectionInfo(hasPrivateApps ?
+ mPrivateProfileAppScrollerBadge : sectionName, position));
}
- startPosition++;
+ position++;
}
- return startPosition;
+ return position;
}
/**
diff --git a/src/com/android/launcher3/allapps/BaseAllAppsAdapter.java b/src/com/android/launcher3/allapps/BaseAllAppsAdapter.java
index 3ba1eed..a21d7be 100644
--- a/src/com/android/launcher3/allapps/BaseAllAppsAdapter.java
+++ b/src/com/android/launcher3/allapps/BaseAllAppsAdapter.java
@@ -15,6 +15,8 @@
*/
package com.android.launcher3.allapps;
+import static android.view.View.GONE;
+
import static com.android.launcher3.allapps.SectionDecorationInfo.ROUND_BOTTOM_LEFT;
import static com.android.launcher3.allapps.SectionDecorationInfo.ROUND_BOTTOM_RIGHT;
import static com.android.launcher3.allapps.SectionDecorationInfo.ROUND_NOTHING;
@@ -42,6 +44,7 @@
import com.android.launcher3.R;
import com.android.launcher3.allapps.search.SearchAdapterProvider;
import com.android.launcher3.model.data.AppInfo;
+import com.android.launcher3.model.data.ItemInfo;
import com.android.launcher3.views.ActivityContext;
/**
@@ -263,15 +266,25 @@
icon.applyFromApplicationInfo(adapterItem.itemInfo);
icon.setOnFocusChangeListener(mIconFocusListener);
PrivateProfileManager privateProfileManager = mApps.getPrivateProfileManager();
- // Set the alpha of the private space icon to 0 upon expanding the header so the
- // alpha can animate -> 1.
- if (icon.getAlpha() == 0 || icon.getAlpha() == 1) {
- icon.setAlpha(privateProfileManager != null
- && privateProfileManager.isPrivateSpaceItem(adapterItem)
- && privateProfileManager.getAnimationScrolling()
- && privateProfileManager.getAnimate()
- && privateProfileManager.getCurrentState() == STATE_ENABLED
- ? 0 : 1);
+ if (privateProfileManager != null) {
+ // Set the alpha of the private space icon to 0 upon expanding the header so the
+ // alpha can animate -> 1.
+ boolean isPrivateSpaceItem =
+ privateProfileManager.isPrivateSpaceItem(adapterItem);
+ if (icon.getAlpha() == 0 || icon.getAlpha() == 1) {
+ icon.setAlpha(isPrivateSpaceItem
+ && privateProfileManager.getAnimationScrolling()
+ && privateProfileManager.getAnimate()
+ && privateProfileManager.getCurrentState() == STATE_ENABLED
+ ? 0 : 1);
+ }
+ // Views can still be bounded before the app list is updated hence showing icons
+ // after collapsing.
+ if (privateProfileManager.getCurrentState() == STATE_DISABLED
+ && isPrivateSpaceItem) {
+ adapterItem.decorationInfo = null;
+ icon.setVisibility(GONE);
+ }
}
break;
}
@@ -298,7 +311,8 @@
break;
case VIEW_TYPE_PRIVATE_SPACE_SYS_APPS_DIVIDER:
adapterItem = mApps.getAdapterItems().get(position);
- adapterItem.decorationInfo = new SectionDecorationInfo(mActivityContext,
+ adapterItem.decorationInfo = mApps.getPrivateProfileManager().getCurrentState()
+ == STATE_DISABLED ? null : new SectionDecorationInfo(mActivityContext,
ROUND_NOTHING, true /* decorateTogether */);
break;
case VIEW_TYPE_ALL_APPS_DIVIDER:
diff --git a/src/com/android/launcher3/allapps/PrivateAppsSectionDecorator.java b/src/com/android/launcher3/allapps/PrivateAppsSectionDecorator.java
index 18175b6..339e443 100644
--- a/src/com/android/launcher3/allapps/PrivateAppsSectionDecorator.java
+++ b/src/com/android/launcher3/allapps/PrivateAppsSectionDecorator.java
@@ -43,6 +43,9 @@
for (int i = 0; i < parent.getChildCount(); i++) {
View view = parent.getChildAt(i);
int position = parent.getChildAdapterPosition(view);
+ if (position < 0 || position >= mAppsList.getAdapterItems().size()) {
+ continue;
+ }
BaseAllAppsAdapter.AdapterItem adapterItem = mAppsList.getAdapterItems().get(position);
SectionDecorationInfo info = adapterItem.decorationInfo;
if (info == null) {
diff --git a/src/com/android/launcher3/allapps/PrivateProfileManager.java b/src/com/android/launcher3/allapps/PrivateProfileManager.java
index fc186e8..38fe138 100644
--- a/src/com/android/launcher3/allapps/PrivateProfileManager.java
+++ b/src/com/android/launcher3/allapps/PrivateProfileManager.java
@@ -21,6 +21,7 @@
import static android.view.View.VISIBLE;
import static com.android.launcher3.LauncherAnimUtils.VIEW_ALPHA;
+import static com.android.launcher3.LauncherSettings.Favorites.CONTAINER_PRIVATESPACE;
import static com.android.launcher3.allapps.ActivityAllAppsContainerView.AdapterHolder.MAIN;
import static com.android.launcher3.allapps.BaseAllAppsAdapter.VIEW_TYPE_ICON;
import static com.android.launcher3.allapps.BaseAllAppsAdapter.VIEW_TYPE_PRIVATE_SPACE_HEADER;
@@ -198,6 +199,7 @@
* when animation is not running.
*/
public void reset() {
+ getMainRecyclerView().setChildAttachedConsumer(null);
int previousState = getCurrentState();
boolean isEnabled = !mAllApps.getAppsStore()
.hasModelFlag(FLAG_PRIVATE_PROFILE_QUIET_MODE_ENABLED);
@@ -214,11 +216,27 @@
resetPrivateSpaceDecorator(updatedState);
}
- /** Opens the Private Space Settings Page. */
- public void openPrivateSpaceSettings() {
+ /**
+ * Opens the Private Space Settings Page.
+ *
+ * @param view the view that was clicked to open the settings page and which will be the same
+ * view to animate back. Otherwise if there is no view, simply start the activity.
+ */
+ public void openPrivateSpaceSettings(View view) {
if (mPrivateSpaceSettingsAvailable) {
- mAllApps.getContext().startActivity(
- ApiWrapper.INSTANCE.get(mAllApps.getContext()).getPrivateSpaceSettingsIntent());
+ Context context = mAllApps.getContext();
+ Intent intent = ApiWrapper.INSTANCE.get(context).getPrivateSpaceSettingsIntent();
+ if (view == null) {
+ context.startActivity(intent);
+ return;
+ }
+ ActivityContext activityContext = ActivityContext.lookupContext(context);
+ AppInfo itemInfo = new AppInfo();
+ itemInfo.id = CONTAINER_PRIVATESPACE;
+ itemInfo.componentName = intent.getComponent();
+ itemInfo.container = CONTAINER_PRIVATESPACE;
+ view.setTag(itemInfo);
+ activityContext.startActivitySafely(view, intent, itemInfo);
}
}
@@ -421,7 +439,7 @@
settingsButton.setOnClickListener(
view -> {
logEvents(LAUNCHER_PRIVATE_SPACE_SETTINGS_TAP);
- openPrivateSpaceSettings();
+ openPrivateSpaceSettings(view);
});
} else {
settingsButton.setVisibility(GONE);
@@ -589,6 +607,9 @@
* here.
*/
private void updatePrivateStateAnimator(boolean expand) {
+ if (!Flags.enablePrivateSpace() || !Flags.privateSpaceAnimation()) {
+ return;
+ }
if (mPSHeader == null) {
mOnPSHeaderAdded = () -> updatePrivateStateAnimator(expand);
setAnimationRunning(false);
@@ -615,12 +636,13 @@
});
animatorSet.addListener(forEndCallback(() -> {
setAnimationRunning(false);
+ getMainRecyclerView().setChildAttachedConsumer(child -> child.setAlpha(1));
if (!expand) {
// Call onAppsUpdated() because it may be canceled when this animation occurs.
mAllApps.getPersonalAppList().onAppsUpdated();
if (isPrivateSpaceHidden()) {
// TODO (b/325455879): Figure out if we can avoid this.
- mAllApps.getActiveRecyclerView().getAdapter().notifyDataSetChanged();
+ getMainRecyclerView().getAdapter().notifyDataSetChanged();
}
}
}));
@@ -724,6 +746,10 @@
allAppsRecyclerView.addOnScrollListener(mOnIdleScrollListener);
}
+ AllAppsRecyclerView getMainRecyclerView() {
+ return mAllApps.mAH.get(ActivityAllAppsContainerView.AdapterHolder.MAIN).mRecyclerView;
+ }
+
boolean getAnimate() {
return mAnimate;
}
@@ -737,6 +763,7 @@
}
boolean isPrivateSpaceItem(BaseAllAppsAdapter.AdapterItem item) {
- return item.decorationInfo != null;
+ return getItemInfoMatcher().test(item.itemInfo) || item.decorationInfo != null
+ || (item.itemInfo instanceof PrivateSpaceInstallAppButtonInfo);
}
}
diff --git a/src/com/android/launcher3/allapps/WorkModeSwitch.java b/src/com/android/launcher3/allapps/WorkModeSwitch.java
index eb7d429..6049574 100644
--- a/src/com/android/launcher3/allapps/WorkModeSwitch.java
+++ b/src/com/android/launcher3/allapps/WorkModeSwitch.java
@@ -15,14 +15,10 @@
*/
package com.android.launcher3.allapps;
-import static com.android.launcher3.workprofile.PersonalWorkSlidingTabStrip.getTabWidth;
-
import android.content.Context;
import android.graphics.Rect;
import android.util.AttributeSet;
-import android.view.View;
import android.view.WindowInsets;
-import android.widget.ImageView;
import android.widget.LinearLayout;
import android.widget.TextView;
@@ -35,7 +31,6 @@
import com.android.launcher3.R;
import com.android.launcher3.Utilities;
import com.android.launcher3.anim.KeyboardInsetAnimationCallback;
-import com.android.launcher3.logging.StatsLogManager;
import com.android.launcher3.model.StringCache;
import com.android.launcher3.views.ActivityContext;
/**
@@ -53,12 +48,11 @@
private final Rect mImeInsets = new Rect();
private int mFlags;
private final ActivityContext mActivityContext;
+ private final Context mContext;
// Threshold when user scrolls up/down to determine when should button extend/collapse
private final int mScrollThreshold;
- private ImageView mIcon;
private TextView mTextView;
- private final StatsLogManager mStatsLogManager;
public WorkModeSwitch(@NonNull Context context) {
@@ -71,16 +65,15 @@
public WorkModeSwitch(@NonNull Context context, @NonNull AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
+ mContext = context;
mScrollThreshold = Utilities.dpToPx(SCROLL_THRESHOLD_DP);
mActivityContext = ActivityContext.lookupContext(getContext());
- mStatsLogManager = mActivityContext.getStatsLogManager();
}
@Override
protected void onFinishInflate() {
super.onFinishInflate();
- mIcon = findViewById(R.id.work_icon);
mTextView = findViewById(R.id.pause_text);
setSelected(true);
KeyboardInsetAnimationCallback keyboardInsetAnimationCallback =
@@ -114,13 +107,8 @@
@Override
protected void onLayout(boolean changed, int left, int top, int right, int bottom) {
super.onLayout(changed, left, top, right, bottom);
- View parent = (View) getParent();
boolean isRtl = Utilities.isRtl(getResources());
- Rect allAppsPadding = mActivityContext.getDeviceProfile().allAppsPadding;
- int size = parent.getWidth() - parent.getPaddingLeft() - parent.getPaddingRight()
- - (allAppsPadding.left + allAppsPadding.right);
- int tabWidth = getTabWidth(getContext(), size);
- int shift = (size - tabWidth) / 2 + (isRtl ? allAppsPadding.left : allAppsPadding.right);
+ int shift = mActivityContext.getDeviceProfile().getAllAppsIconStartMargin(mContext);
setTranslationX(isRtl ? shift : -shift);
}
diff --git a/src/com/android/launcher3/allapps/search/AllAppsSearchBarController.java b/src/com/android/launcher3/allapps/search/AllAppsSearchBarController.java
index ec45415..19c3ebe 100644
--- a/src/com/android/launcher3/allapps/search/AllAppsSearchBarController.java
+++ b/src/com/android/launcher3/allapps/search/AllAppsSearchBarController.java
@@ -31,7 +31,6 @@
import com.android.launcher3.ExtendedEditText;
import com.android.launcher3.Utilities;
import com.android.launcher3.allapps.BaseAllAppsAdapter.AdapterItem;
-import com.android.launcher3.config.FeatureFlags;
import com.android.launcher3.search.SearchAlgorithm;
import com.android.launcher3.search.SearchCallback;
import com.android.launcher3.views.ActivityContext;
@@ -144,7 +143,7 @@
@Override
public void onFocusChange(View view, boolean hasFocus) {
- if (!hasFocus && !FeatureFlags.ENABLE_DEVICE_SEARCH.get()) {
+ if (!hasFocus) {
mInput.hideKeyboard();
}
}
diff --git a/src/com/android/launcher3/config/FeatureFlags.java b/src/com/android/launcher3/config/FeatureFlags.java
index 830e552..3badc64 100644
--- a/src/com/android/launcher3/config/FeatureFlags.java
+++ b/src/com/android/launcher3/config/FeatureFlags.java
@@ -80,13 +80,6 @@
public static final BooleanFlag ENABLE_DISMISS_PREDICTION_UNDO = getDebugFlag(270394476,
"ENABLE_DISMISS_PREDICTION_UNDO", DISABLED,
"Show an 'Undo' snackbar when users dismiss a predicted hotseat item");
-
- public static final BooleanFlag MOVE_STARTUP_DATA_TO_DEVICE_PROTECTED_STORAGE = getDebugFlag(
- 251502424, "ENABLE_BOOT_AWARE_STARTUP_DATA", DISABLED,
- "Marks LauncherPref data as (and allows it to) available while the device is"
- + " locked. Enabling this causes a 1-time movement of certain SharedPreferences"
- + " data. Improves startup latency.");
-
public static final BooleanFlag CONTINUOUS_VIEW_TREE_CAPTURE = getDebugFlag(270395171,
"CONTINUOUS_VIEW_TREE_CAPTURE", ENABLED, "Capture View tree every frame");
diff --git a/src/com/android/launcher3/model/AllAppsList.java b/src/com/android/launcher3/model/AllAppsList.java
index 8c5ea79..a1a05f4 100644
--- a/src/com/android/launcher3/model/AllAppsList.java
+++ b/src/com/android/launcher3/model/AllAppsList.java
@@ -18,7 +18,6 @@
import static com.android.launcher3.model.data.AppInfo.COMPONENT_KEY_COMPARATOR;
import static com.android.launcher3.model.data.AppInfo.EMPTY_ARRAY;
-import static com.android.launcher3.model.data.ItemInfoWithIcon.FLAG_ARCHIVED;
import android.content.ComponentName;
import android.content.Context;
@@ -33,14 +32,14 @@
import androidx.annotation.Nullable;
import com.android.launcher3.AppFilter;
-import com.android.launcher3.Flags;
-import com.android.launcher3.Utilities;
import com.android.launcher3.compat.AlphabeticIndexCompat;
import com.android.launcher3.icons.IconCache;
import com.android.launcher3.model.BgDataModel.Callbacks;
import com.android.launcher3.model.data.AppInfo;
import com.android.launcher3.model.data.ItemInfo;
import com.android.launcher3.pm.PackageInstallInfo;
+import com.android.launcher3.pm.UserCache;
+import com.android.launcher3.util.ApiWrapper;
import com.android.launcher3.util.FlagOp;
import com.android.launcher3.util.PackageManagerHelper;
import com.android.launcher3.util.SafeCloseable;
@@ -300,6 +299,8 @@
*/
public List<LauncherActivityInfo> updatePackage(
Context context, String packageName, UserHandle user) {
+ final ApiWrapper apiWrapper = ApiWrapper.INSTANCE.get(context);
+ final UserCache userCache = UserCache.getInstance(context);
final List<LauncherActivityInfo> matches = context.getSystemService(LauncherApps.class)
.getActivityList(packageName, user);
if (matches.size() > 0) {
@@ -327,19 +328,9 @@
mIconCache.getTitleAndIcon(applicationInfo, info, false /* useLowResIcon */);
applicationInfo.sectionName = mIndex.computeSectionName(applicationInfo.title);
- applicationInfo.setProgressLevel(
- PackageManagerHelper.getLoadingProgress(info),
- PackageInstallInfo.STATUS_INSTALLED_DOWNLOADING);
applicationInfo.intent = launchIntent;
- if (Flags.enableSupportForArchiving()) {
- // In case an app is archived, the respective item flag corresponding to
- // archiving should also be applied during package updates
- if (info.getActivityInfo().isArchived) {
- applicationInfo.runtimeStatusFlags |= FLAG_ARCHIVED;
- } else {
- applicationInfo.runtimeStatusFlags &= (~FLAG_ARCHIVED);
- }
- }
+ AppInfo.updateRuntimeFlagsForActivityTarget(applicationInfo, info,
+ userCache.getUserInfo(user), apiWrapper);
mDataChanged = true;
}
}
diff --git a/src/com/android/launcher3/model/LoaderCursor.java b/src/com/android/launcher3/model/LoaderCursor.java
index 2f678a8..b17684c 100644
--- a/src/com/android/launcher3/model/LoaderCursor.java
+++ b/src/com/android/launcher3/model/LoaderCursor.java
@@ -52,6 +52,7 @@
import com.android.launcher3.model.data.WorkspaceItemInfo;
import com.android.launcher3.pm.UserCache;
import com.android.launcher3.shortcuts.ShortcutKey;
+import com.android.launcher3.util.ApiWrapper;
import com.android.launcher3.util.ContentWriter;
import com.android.launcher3.util.GridOccupancy;
import com.android.launcher3.util.IntArray;
@@ -366,7 +367,8 @@
}
if (mActivityInfo != null) {
- AppInfo.updateRuntimeFlagsForActivityTarget(info, mActivityInfo, userIconInfo);
+ AppInfo.updateRuntimeFlagsForActivityTarget(info, mActivityInfo, userIconInfo,
+ ApiWrapper.INSTANCE.get(mContext));
}
// from the db
diff --git a/src/com/android/launcher3/model/LoaderTask.java b/src/com/android/launcher3/model/LoaderTask.java
index ac4c087..a742c75 100644
--- a/src/com/android/launcher3/model/LoaderTask.java
+++ b/src/com/android/launcher3/model/LoaderTask.java
@@ -89,6 +89,7 @@
import com.android.launcher3.shortcuts.ShortcutKey;
import com.android.launcher3.shortcuts.ShortcutRequest;
import com.android.launcher3.shortcuts.ShortcutRequest.QueryResult;
+import com.android.launcher3.util.ApiWrapper;
import com.android.launcher3.util.ComponentKey;
import com.android.launcher3.util.IOUtils;
import com.android.launcher3.util.IntArray;
@@ -443,7 +444,7 @@
List<IconRequestInfo<WorkspaceItemInfo>> iconRequestInfos = new ArrayList<>();
WorkspaceItemProcessor itemProcessor = new WorkspaceItemProcessor(c, memoryLogger,
- mUserManagerState, mLauncherApps, mPendingPackages,
+ mUserCache, mUserManagerState, mLauncherApps, mPendingPackages,
mShortcutKeyToPinnedShortcuts, mApp, mBgDataModel,
mWidgetProvidersMap, installingPkgs, isSdCardReady,
widgetInflater, pmHelper, iconRequestInfos, unlockedUsers,
@@ -694,7 +695,8 @@
// Create the ApplicationInfos
for (int i = 0; i < apps.size(); i++) {
LauncherActivityInfo app = apps.get(i);
- AppInfo appInfo = new AppInfo(app, mUserCache.getUserInfo(user), quietMode);
+ AppInfo appInfo = new AppInfo(app, mUserCache.getUserInfo(user),
+ ApiWrapper.INSTANCE.get(mApp.getContext()), quietMode);
if (Flags.enableSupportForArchiving() && app.getApplicationInfo().isArchived) {
// For archived apps, include progress info in case there is a pending
// install session post restart of device.
diff --git a/src/com/android/launcher3/model/PackageUpdatedTask.java b/src/com/android/launcher3/model/PackageUpdatedTask.java
index 1923065..6432d33 100644
--- a/src/com/android/launcher3/model/PackageUpdatedTask.java
+++ b/src/com/android/launcher3/model/PackageUpdatedTask.java
@@ -286,10 +286,8 @@
}
if (si.itemType == Favorites.ITEM_TYPE_APPLICATION) {
if (activities != null && !activities.isEmpty()) {
- si.status = ApiWrapper.INSTANCE.get(context)
- .isNonResizeableActivity(activities.get(0))
- ? si.status | WorkspaceItemInfo.FLAG_NON_RESIZEABLE
- : si.status & ~WorkspaceItemInfo.FLAG_NON_RESIZEABLE;
+ si.setNonResizeable(ApiWrapper.INSTANCE.get(context)
+ .isNonResizeableActivity(activities.get(0)));
}
iconCache.getTitleAndIcon(si, si.usingLowResIcon());
infoUpdated = true;
diff --git a/src/com/android/launcher3/model/WorkspaceItemProcessor.kt b/src/com/android/launcher3/model/WorkspaceItemProcessor.kt
index ee45c0f..cea4380 100644
--- a/src/com/android/launcher3/model/WorkspaceItemProcessor.kt
+++ b/src/com/android/launcher3/model/WorkspaceItemProcessor.kt
@@ -34,6 +34,7 @@
import com.android.launcher3.backuprestore.LauncherRestoreEventLogger.RestoreError
import com.android.launcher3.config.FeatureFlags
import com.android.launcher3.logging.FileLog
+import com.android.launcher3.model.data.AppInfo
import com.android.launcher3.model.data.AppPairInfo
import com.android.launcher3.model.data.FolderInfo
import com.android.launcher3.model.data.IconRequestInfo
@@ -41,6 +42,7 @@
import com.android.launcher3.model.data.LauncherAppWidgetInfo
import com.android.launcher3.model.data.WorkspaceItemInfo
import com.android.launcher3.pm.PackageInstallInfo
+import com.android.launcher3.pm.UserCache
import com.android.launcher3.shortcuts.ShortcutKey
import com.android.launcher3.util.ApiWrapper
import com.android.launcher3.util.ComponentKey
@@ -60,6 +62,7 @@
class WorkspaceItemProcessor(
private val c: LoaderCursor,
private val memoryLogger: LoaderMemoryLogger?,
+ private val userCache: UserCache,
private val userManagerState: UserManagerState,
private val launcherApps: LauncherApps,
private val pendingPackages: MutableSet<PackageUserKey>,
@@ -181,6 +184,9 @@
}
}
}
+ if (intent.`package` == null) {
+ intent.`package` = targetPkg
+ }
// else if cn == null => can't infer much, leave it
// else if !validPkg => could be restored icon or missing sd-card
when {
@@ -326,12 +332,11 @@
}
val activityInfo = c.launcherActivityInfo
if (activityInfo != null) {
- if (ApiWrapper.INSTANCE.get(app.context).isNonResizeableActivity(activityInfo)) {
- info.status = info.status or WorkspaceItemInfo.FLAG_NON_RESIZEABLE
- }
- info.setProgressLevel(
- PackageManagerHelper.getLoadingProgress(activityInfo),
- PackageInstallInfo.STATUS_INSTALLED_DOWNLOADING
+ AppInfo.updateRuntimeFlagsForActivityTarget(
+ info,
+ activityInfo,
+ userCache.getUserInfo(c.user),
+ ApiWrapper.INSTANCE[app.context]
)
}
if (
diff --git a/src/com/android/launcher3/model/data/AppInfo.java b/src/com/android/launcher3/model/data/AppInfo.java
index 93ba619..18aa6e7 100644
--- a/src/com/android/launcher3/model/data/AppInfo.java
+++ b/src/com/android/launcher3/model/data/AppInfo.java
@@ -35,6 +35,7 @@
import com.android.launcher3.Utilities;
import com.android.launcher3.pm.PackageInstallInfo;
import com.android.launcher3.pm.UserCache;
+import com.android.launcher3.util.ApiWrapper;
import com.android.launcher3.util.PackageManagerHelper;
import com.android.launcher3.util.UserIconInfo;
@@ -89,10 +90,12 @@
*/
public AppInfo(Context context, LauncherActivityInfo info, UserHandle user) {
this(info, UserCache.INSTANCE.get(context).getUserInfo(user),
+ ApiWrapper.INSTANCE.get(context),
context.getSystemService(UserManager.class).isQuietModeEnabled(user));
}
- public AppInfo(LauncherActivityInfo info, UserIconInfo userIconInfo, boolean quietModeEnabled) {
+ public AppInfo(LauncherActivityInfo info, UserIconInfo userIconInfo,
+ ApiWrapper apiWrapper, boolean quietModeEnabled) {
this.componentName = info.getComponentName();
this.container = CONTAINER_ALL_APPS;
this.user = userIconInfo.user;
@@ -102,7 +105,7 @@
runtimeStatusFlags |= FLAG_DISABLED_QUIET_USER;
}
uid = info.getApplicationInfo().uid;
- updateRuntimeFlagsForActivityTarget(this, info, userIconInfo);
+ updateRuntimeFlagsForActivityTarget(this, info, userIconInfo, apiWrapper);
}
public AppInfo(AppInfo info) {
@@ -175,14 +178,27 @@
return componentName;
}
- public static void updateRuntimeFlagsForActivityTarget(
- ItemInfoWithIcon info, LauncherActivityInfo lai, UserIconInfo userIconInfo) {
+ /**
+ * Updates the runtime status flags for the given info based on the state of the specified
+ * activity.
+ */
+ public static boolean updateRuntimeFlagsForActivityTarget(
+ ItemInfoWithIcon info, LauncherActivityInfo lai, UserIconInfo userIconInfo,
+ ApiWrapper apiWrapper) {
+ final int oldProgressLevel = info.getProgressLevel();
+ final int oldRuntimeStatusFlags = info.runtimeStatusFlags;
ApplicationInfo appInfo = lai.getApplicationInfo();
if (PackageManagerHelper.isAppSuspended(appInfo)) {
info.runtimeStatusFlags |= FLAG_DISABLED_SUSPENDED;
+ } else {
+ info.runtimeStatusFlags &= ~FLAG_DISABLED_SUSPENDED;
}
- if (Flags.enableSupportForArchiving() && lai.getActivityInfo().isArchived) {
- info.runtimeStatusFlags |= FLAG_ARCHIVED;
+ if (Flags.enableSupportForArchiving()) {
+ if (lai.getActivityInfo().isArchived) {
+ info.runtimeStatusFlags |= FLAG_ARCHIVED;
+ } else {
+ info.runtimeStatusFlags &= ~FLAG_ARCHIVED;
+ }
}
info.runtimeStatusFlags |= (appInfo.flags & ApplicationInfo.FLAG_SYSTEM) == 0
? FLAG_SYSTEM_NO : FLAG_SYSTEM_YES;
@@ -190,6 +206,8 @@
if (Flags.privateSpaceRestrictAccessibilityDrag()) {
if (userIconInfo.isPrivate()) {
info.runtimeStatusFlags |= FLAG_NOT_PINNABLE;
+ } else {
+ info.runtimeStatusFlags &= ~FLAG_NOT_PINNABLE;
}
}
@@ -197,6 +215,9 @@
info.setProgressLevel(
PackageManagerHelper.getLoadingProgress(lai),
PackageInstallInfo.STATUS_INSTALLED_DOWNLOADING);
+ info.setNonResizeable(apiWrapper.isNonResizeableActivity(lai));
+ return (oldProgressLevel != info.getProgressLevel())
+ || (oldRuntimeStatusFlags != info.runtimeStatusFlags);
}
@Override
diff --git a/src/com/android/launcher3/model/data/AppPairInfo.kt b/src/com/android/launcher3/model/data/AppPairInfo.kt
index 3dbd45b..2eb6154 100644
--- a/src/com/android/launcher3/model/data/AppPairInfo.kt
+++ b/src/com/android/launcher3/model/data/AppPairInfo.kt
@@ -73,8 +73,8 @@
val isTablet =
(ActivityContext.lookupContext(context) as ActivityContext).getDeviceProfile().isTablet
return Pair(
- isTablet || !getFirstApp().hasStatusFlag(WorkspaceItemInfo.FLAG_NON_RESIZEABLE),
- isTablet || !getSecondApp().hasStatusFlag(WorkspaceItemInfo.FLAG_NON_RESIZEABLE)
+ isTablet || !getFirstApp().isNonResizeable(),
+ isTablet || !getSecondApp().isNonResizeable()
)
}
diff --git a/src/com/android/launcher3/model/data/ItemInfoWithIcon.java b/src/com/android/launcher3/model/data/ItemInfoWithIcon.java
index 3a74ff2..d4c25cb 100644
--- a/src/com/android/launcher3/model/data/ItemInfoWithIcon.java
+++ b/src/com/android/launcher3/model/data/ItemInfoWithIcon.java
@@ -122,6 +122,11 @@
public static final int FLAG_ARCHIVED = 1 << 14;
/**
+ * Flag indicating whether the package related to the item & user does not support resizing.
+ */
+ public static final int FLAG_NOT_RESIZEABLE = 1 << 15;
+
+ /**
* Status associated with the system state of the underlying item. This is calculated every
* time a new info is created and not persisted on the disk.
*/
@@ -246,6 +251,24 @@
}
}
+ /**
+ * Sets whether this app info is non-resizeable.
+ */
+ public void setNonResizeable(boolean nonResizeable) {
+ if (nonResizeable) {
+ runtimeStatusFlags |= FLAG_NOT_RESIZEABLE;
+ } else {
+ runtimeStatusFlags &= ~FLAG_NOT_RESIZEABLE;
+ }
+ }
+
+ /**
+ * Returns whether this app info is resizeable.
+ */
+ public boolean isNonResizeable() {
+ return (runtimeStatusFlags & FLAG_NOT_RESIZEABLE) != 0;
+ }
+
/** Creates an intent to that launches the app store at this app's page. */
@Nullable
public Intent getMarketIntent(Context context) {
diff --git a/src/com/android/launcher3/model/data/WorkspaceItemInfo.java b/src/com/android/launcher3/model/data/WorkspaceItemInfo.java
index 5ae7003..2c533ac 100644
--- a/src/com/android/launcher3/model/data/WorkspaceItemInfo.java
+++ b/src/com/android/launcher3/model/data/WorkspaceItemInfo.java
@@ -75,12 +75,6 @@
public static final int FLAG_START_FOR_RESULT = 1 << 4;
/**
- * The app is flagged non-resizeable, meaning that it does not support multi-window on small
- * screens.
- */
- public static final int FLAG_NON_RESIZEABLE = 1 << 5;
-
- /**
* The intent used to start the application.
*/
@NonNull
diff --git a/src/com/android/launcher3/settings/SettingsActivity.java b/src/com/android/launcher3/settings/SettingsActivity.java
index c10d85e..52ce4e8 100644
--- a/src/com/android/launcher3/settings/SettingsActivity.java
+++ b/src/com/android/launcher3/settings/SettingsActivity.java
@@ -41,7 +41,6 @@
import androidx.fragment.app.FragmentActivity;
import androidx.fragment.app.FragmentManager;
import androidx.preference.Preference;
-import androidx.preference.PreferenceCategory;
import androidx.preference.PreferenceFragmentCompat;
import androidx.preference.PreferenceFragmentCompat.OnPreferenceStartFragmentCallback;
import androidx.preference.PreferenceFragmentCompat.OnPreferenceStartScreenCallback;
@@ -53,9 +52,7 @@
import com.android.launcher3.LauncherFiles;
import com.android.launcher3.R;
import com.android.launcher3.states.RotationHelper;
-import com.android.launcher3.uioverrides.flags.DeveloperOptionsUI;
import com.android.launcher3.util.DisplayController;
-import com.android.launcher3.util.Executors;
import com.android.launcher3.util.SettingsCache;
/**
@@ -255,12 +252,6 @@
preference.setOrder(0);
}
return mDeveloperOptionsEnabled;
- case "pref_developer_flags":
- if (mDeveloperOptionsEnabled && preference instanceof PreferenceCategory pc) {
- Executors.MAIN_EXECUTOR.post(() -> new DeveloperOptionsUI(this, pc));
- return true;
- }
- return false;
}
return true;
diff --git a/src/com/android/launcher3/touch/AbstractStateChangeTouchController.java b/src/com/android/launcher3/touch/AbstractStateChangeTouchController.java
index 9aed4eb..50f98f2 100644
--- a/src/com/android/launcher3/touch/AbstractStateChangeTouchController.java
+++ b/src/com/android/launcher3/touch/AbstractStateChangeTouchController.java
@@ -57,7 +57,7 @@
protected final SingleAxisSwipeDetector.Direction mSwipeDirection;
protected final AnimatorListener mClearStateOnCancelListener =
- newCancelListener(this::clearState);
+ newCancelListener(this::clearState, /* isSingleUse = */ false);
private final FlingBlockCheck mFlingBlockCheck = new FlingBlockCheck();
protected int mStartContainerType;
diff --git a/src/com/android/launcher3/util/DisplayController.java b/src/com/android/launcher3/util/DisplayController.java
index ff95212..8806e27 100644
--- a/src/com/android/launcher3/util/DisplayController.java
+++ b/src/com/android/launcher3/util/DisplayController.java
@@ -19,6 +19,9 @@
import static android.view.Display.DEFAULT_DISPLAY;
import static android.view.WindowManager.LayoutParams.TYPE_APPLICATION;
+import static com.android.launcher3.InvariantDeviceProfile.TYPE_MULTI_DISPLAY;
+import static com.android.launcher3.InvariantDeviceProfile.TYPE_PHONE;
+import static com.android.launcher3.InvariantDeviceProfile.TYPE_TABLET;
import static com.android.launcher3.LauncherPrefs.TASKBAR_PINNING;
import static com.android.launcher3.LauncherPrefs.TASKBAR_PINNING_KEY;
import static com.android.launcher3.Utilities.dpiFromPx;
@@ -47,6 +50,7 @@
import androidx.annotation.UiThread;
import androidx.annotation.VisibleForTesting;
+import com.android.launcher3.InvariantDeviceProfile.DeviceType;
import com.android.launcher3.LauncherPrefs;
import com.android.launcher3.Utilities;
import com.android.launcher3.logging.FileLog;
@@ -466,6 +470,23 @@
public int getDensityDpi() {
return densityDpi;
}
+
+ public @DeviceType int getDeviceType() {
+ int flagPhone = 1 << 0;
+ int flagTablet = 1 << 1;
+
+ int type = supportedBounds.stream()
+ .mapToInt(bounds -> isTablet(bounds) ? flagTablet : flagPhone)
+ .reduce(0, (a, b) -> a | b);
+ if (type == (flagPhone | flagTablet)) {
+ // device has profiles supporting both phone and tablet modes
+ return TYPE_MULTI_DISPLAY;
+ } else if (type == flagTablet) {
+ return TYPE_TABLET;
+ } else {
+ return TYPE_PHONE;
+ }
+ }
}
/**
diff --git a/src/com/android/launcher3/views/AbstractSlideInView.java b/src/com/android/launcher3/views/AbstractSlideInView.java
index 9f6e8f8..5ce455a 100644
--- a/src/com/android/launcher3/views/AbstractSlideInView.java
+++ b/src/com/android/launcher3/views/AbstractSlideInView.java
@@ -25,6 +25,8 @@
import static com.android.launcher3.allapps.AllAppsTransitionController.REVERT_SWIPE_ALL_APPS_TO_HOME_ANIMATION_DURATION_MS;
import static com.android.launcher3.util.ScrollableLayoutManager.PREDICTIVE_BACK_MIN_SCALE;
+import android.animation.Animator;
+import android.animation.ObjectAnimator;
import android.animation.ValueAnimator;
import android.content.Context;
import android.graphics.Canvas;
@@ -135,6 +137,7 @@
protected final AnimatedFloat mSwipeToDismissProgress =
new AnimatedFloat(this::onUserSwipeToDismissProgressChanged, 0f);
protected boolean mIsDismissInProgress;
+ private View mViewToAnimateInSwipeToDismiss = this;
private @Nullable Drawable mContentBackground;
private @Nullable View mContentBackgroundParentView;
@@ -286,18 +289,37 @@
@Override
@RequiresApi(Build.VERSION_CODES.UPSIDE_DOWN_CAKE)
+ public void onBackStarted(BackEvent backEvent) {
+ super.onBackStarted(backEvent);
+ mViewToAnimateInSwipeToDismiss = shouldAnimateContentViewInBackSwipe() ? mContent : this;
+ }
+
+ @Override
+ @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);
}
+ /**
+ * During predictive back swipe, the default behavior is to scale {@link AbstractSlideInView}
+ * during back swipe. This method allow subclass to scale {@link #mContent}, typically to exit
+ * search mode.
+ *
+ * <p>Note that this method can be expensive, and should only be called from
+ * {@link #onBackStarted(BackEvent)}, not from {@link #onBackProgressed(BackEvent)}.
+ */
+ protected boolean shouldAnimateContentViewInBackSwipe() {
+ return false;
+ }
+
protected void onUserSwipeToDismissProgressChanged() {
float progress = mSwipeToDismissProgress.value;
mIsDismissInProgress = progress > 0f;
float scale = PREDICTIVE_BACK_MIN_SCALE + (1 - PREDICTIVE_BACK_MIN_SCALE) * (1f - progress);
- SCALE_PROPERTY.set(this, scale);
+ SCALE_PROPERTY.set(mViewToAnimateInSwipeToDismiss, scale);
setClipChildren(!mIsDismissInProgress);
setClipToPadding(!mIsDismissInProgress);
mContent.setClipChildren(!mIsDismissInProgress);
@@ -312,9 +334,32 @@
}
protected void animateSwipeToDismissProgressToStart() {
- mSwipeToDismissProgress.animateToValue(0f)
- .setDuration(REVERT_SWIPE_ALL_APPS_TO_HOME_ANIMATION_DURATION_MS)
- .start();
+ ObjectAnimator objectAnimator = mSwipeToDismissProgress.animateToValue(0f)
+ .setDuration(REVERT_SWIPE_ALL_APPS_TO_HOME_ANIMATION_DURATION_MS);
+
+ // If we are animating a different view, we should reset the animating view back to
+ // AbstractSlideInView as it is the default view to animate.
+ if (this != mViewToAnimateInSwipeToDismiss) {
+ objectAnimator.addListener(new Animator.AnimatorListener() {
+ @Override
+ public void onAnimationCancel(Animator animator) {
+ mViewToAnimateInSwipeToDismiss = AbstractSlideInView.this;
+ }
+
+ @Override
+ public void onAnimationEnd(Animator animator) {
+ mViewToAnimateInSwipeToDismiss = AbstractSlideInView.this;
+ }
+
+ @Override
+ public void onAnimationRepeat(Animator animator) {}
+
+ @Override
+ public void onAnimationStart(Animator animator) {}
+ });
+ }
+
+ objectAnimator.start();
}
@Override
diff --git a/src/com/android/launcher3/views/FloatingIconView.java b/src/com/android/launcher3/views/FloatingIconView.java
index f76b53b..f560311 100644
--- a/src/com/android/launcher3/views/FloatingIconView.java
+++ b/src/com/android/launcher3/views/FloatingIconView.java
@@ -55,6 +55,7 @@
import com.android.launcher3.graphics.PreloadIconDrawable;
import com.android.launcher3.icons.FastBitmapDrawable;
import com.android.launcher3.icons.LauncherIcons;
+import com.android.launcher3.model.data.AppInfo;
import com.android.launcher3.model.data.ItemInfo;
import com.android.launcher3.model.data.ItemInfoWithIcon;
import com.android.launcher3.popup.SystemShortcut;
@@ -282,6 +283,8 @@
} else if (btvIcon instanceof PreloadIconDrawable) {
// Force the progress bar to display.
drawable = btvIcon;
+ } else if (originalView instanceof ImageView) {
+ drawable = ((ImageView) originalView).getDrawable();
} else {
int width = (int) pos.width();
int height = (int) pos.height();
diff --git a/src/com/android/launcher3/views/RecyclerViewFastScroller.java b/src/com/android/launcher3/views/RecyclerViewFastScroller.java
index 8408cc7..df8f635 100644
--- a/src/com/android/launcher3/views/RecyclerViewFastScroller.java
+++ b/src/com/android/launcher3/views/RecyclerViewFastScroller.java
@@ -30,6 +30,7 @@
import android.graphics.Point;
import android.graphics.Rect;
import android.graphics.RectF;
+import android.text.TextUtils;
import android.util.AttributeSet;
import android.util.Log;
import android.util.Property;
@@ -121,7 +122,7 @@
// Fast scroller popup
private TextView mPopupView;
private boolean mPopupVisible;
- private String mPopupSectionName;
+ private CharSequence mPopupSectionName;
private Insets mSystemGestureInsets;
protected FastScrollRecyclerView mRv;
@@ -307,13 +308,13 @@
// Update the fastscroller section name at this touch position
int bottom = mRv.getScrollbarTrackHeight() - mThumbHeight;
float boundedY = (float) Math.max(0, Math.min(bottom, y - mTouchOffsetY));
- String sectionName = mRv.scrollToPositionAtProgress(boundedY / bottom);
+ CharSequence sectionName = mRv.scrollToPositionAtProgress(boundedY / bottom);
if (!sectionName.equals(mPopupSectionName)) {
mPopupSectionName = sectionName;
mPopupView.setText(sectionName);
performHapticFeedback(CLOCK_TICK);
}
- animatePopupVisibility(!sectionName.isEmpty());
+ animatePopupVisibility(!TextUtils.isEmpty(sectionName));
mLastTouchY = boundedY;
setThumbOffsetY((int) mLastTouchY);
}
diff --git a/src/com/android/launcher3/views/StickyHeaderLayout.java b/src/com/android/launcher3/views/StickyHeaderLayout.java
index d6481a9..090251f 100644
--- a/src/com/android/launcher3/views/StickyHeaderLayout.java
+++ b/src/com/android/launcher3/views/StickyHeaderLayout.java
@@ -36,6 +36,9 @@
import com.android.launcher3.R;
+import java.util.ArrayList;
+import java.util.List;
+
/**
* A {@link LinearLayout} container which allows scrolling parts of its content based on the
* scroll of a different view. Views which are marked as sticky are not scrolled, giving the
@@ -242,6 +245,22 @@
return p instanceof MyLayoutParams;
}
+ /**
+ * Return a list of all the children that have the sticky layout param set.
+ */
+ public List<View> getStickyChildren() {
+ List<View> stickyChildren = new ArrayList<>();
+ int count = getChildCount();
+ for (int i = 0; i < count; i++) {
+ View v = getChildAt(i);
+ MyLayoutParams lp = (MyLayoutParams) v.getLayoutParams();
+ if (lp.sticky) {
+ stickyChildren.add(v);
+ }
+ }
+ return stickyChildren;
+ }
+
private static class MyLayoutParams extends LayoutParams {
public final boolean sticky;
diff --git a/src/com/android/launcher3/widget/BaseWidgetSheet.java b/src/com/android/launcher3/widget/BaseWidgetSheet.java
index c17ae09..e5b5daa 100644
--- a/src/com/android/launcher3/widget/BaseWidgetSheet.java
+++ b/src/com/android/launcher3/widget/BaseWidgetSheet.java
@@ -16,8 +16,6 @@
package com.android.launcher3.widget;
import static com.android.app.animation.Interpolators.EMPHASIZED;
-import static com.android.launcher3.Flags.enableCategorizedWidgetSuggestions;
-import static com.android.launcher3.Flags.enableUnfoldedTwoPanePicker;
import static com.android.launcher3.Flags.enableWidgetTapToAdd;
import static com.android.launcher3.LauncherPrefs.WIDGETS_EDUCATION_TIP_SEEN;
import static com.android.launcher3.logging.StatsLogManager.LauncherEvent.LAUNCHER_WIDGET_ADD_BUTTON_TAP;
@@ -27,6 +25,7 @@
import android.graphics.Paint;
import android.graphics.Rect;
import android.util.AttributeSet;
+import android.util.Log;
import android.view.View;
import android.view.View.OnClickListener;
import android.view.View.OnLongClickListener;
@@ -141,6 +140,7 @@
}
if (enableWidgetTapToAdd()) {
+ scrollToWidgetCell(wc);
if (mWidgetCellWithAddButton != null) {
// If there is a add button currently showing, hide it.
mWidgetCellWithAddButton.hideAddButton(/* animate= */ true);
@@ -187,6 +187,52 @@
handleClose(true);
}
+ /**
+ * Scroll to show the widget cell. If both the bottom and top of the cell are clipped, this will
+ * prioritize showing the bottom of the cell (where the add button is).
+ */
+ private void scrollToWidgetCell(@NonNull WidgetCell wc) {
+ final int headerTopClip = getHeaderTopClip(wc);
+ final Rect visibleRect = new Rect();
+ final boolean isPartiallyVisible = wc.getLocalVisibleRect(visibleRect);
+ int scrollByY = 0;
+ if (isPartiallyVisible) {
+ final int scrollPadding = getResources()
+ .getDimensionPixelSize(R.dimen.widget_cell_add_button_scroll_padding);
+ final int topClip = visibleRect.top + headerTopClip;
+ final int bottomClip = wc.getHeight() - visibleRect.bottom;
+ if (bottomClip != 0) {
+ scrollByY = bottomClip + scrollPadding;
+ } else if (topClip != 0) {
+ scrollByY = -topClip - scrollPadding;
+ }
+ }
+
+ if (isPartiallyVisible && scrollByY == 0) {
+ // Widget is fully visible.
+ return;
+ } else if (!isPartiallyVisible) {
+ Log.e("BaseWidgetSheet", "click on invisible WidgetCell should not be possible");
+ return;
+ }
+
+ scrollCellContainerByY(wc, scrollByY);
+ }
+
+ /**
+ * Find the nearest scrollable container of the given WidgetCell, and scroll by the given
+ * amount.
+ */
+ protected abstract void scrollCellContainerByY(WidgetCell wc, int scrollByY);
+
+
+ /**
+ * Return the top clip of any sticky headers over the given cell.
+ */
+ protected int getHeaderTopClip(@NonNull WidgetCell cell) {
+ return 0;
+ }
+
@Override
public boolean onLongClick(View v) {
TestLogging.recordEvent(TestProtocol.SEQUENCE_MAIN, "Widgets.onLongClick");
@@ -272,19 +318,8 @@
MeasureSpec.getSize(heightMeasureSpec));
}
- private int getTabletHorizontalMargin(DeviceProfile deviceProfile) {
- // All bottom-sheets showing widgets will be full-width across all devices.
- if (enableCategorizedWidgetSuggestions()) {
- return 0;
- }
- if (deviceProfile.isLandscape && !deviceProfile.isTwoPanels) {
- return getResources().getDimensionPixelSize(
- R.dimen.widget_picker_landscape_tablet_left_right_margin);
- }
- if (deviceProfile.isTwoPanels && enableUnfoldedTwoPanePicker()) {
- return getResources().getDimensionPixelSize(
- R.dimen.widget_picker_two_panels_left_right_margin);
- }
+ /** Returns the horizontal margins to be applied to the widget sheet. **/
+ protected int getTabletHorizontalMargin(DeviceProfile deviceProfile) {
return deviceProfile.allAppsLeftRightMargin;
}
diff --git a/src/com/android/launcher3/widget/WidgetsBottomSheet.java b/src/com/android/launcher3/widget/WidgetsBottomSheet.java
index f1b80e4..97aa67d 100644
--- a/src/com/android/launcher3/widget/WidgetsBottomSheet.java
+++ b/src/com/android/launcher3/widget/WidgetsBottomSheet.java
@@ -28,6 +28,7 @@
import android.view.MotionEvent;
import android.view.View;
import android.view.ViewGroup;
+import android.view.ViewParent;
import android.view.animation.Interpolator;
import android.widget.ScrollView;
import android.widget.TableLayout;
@@ -282,4 +283,16 @@
float distanceToMove, Interpolator interpolator, PendingAnimation target) {
target.addAnimatedFloat(mSwipeToDismissProgress, 0f, 1f, interpolator);
}
+
+ @Override
+ protected void scrollCellContainerByY(WidgetCell wc, int scrollByY) {
+ for (ViewParent parent = wc.getParent(); parent != null; parent = parent.getParent()) {
+ if (parent instanceof ScrollView scrollView) {
+ scrollView.smoothScrollBy(0, scrollByY);
+ return;
+ } else if (parent == this) {
+ return;
+ }
+ }
+ }
}
diff --git a/src/com/android/launcher3/widget/picker/WidgetsFullSheet.java b/src/com/android/launcher3/widget/picker/WidgetsFullSheet.java
index c3067a5..28eeb10 100644
--- a/src/com/android/launcher3/widget/picker/WidgetsFullSheet.java
+++ b/src/com/android/launcher3/widget/picker/WidgetsFullSheet.java
@@ -38,6 +38,7 @@
import android.view.MotionEvent;
import android.view.View;
import android.view.ViewGroup;
+import android.view.ViewParent;
import android.view.WindowInsets;
import android.view.WindowInsetsController;
import android.view.animation.AnimationUtils;
@@ -46,6 +47,7 @@
import android.widget.LinearLayout;
import android.widget.TextView;
+import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.annotation.Px;
import androidx.annotation.VisibleForTesting;
@@ -69,6 +71,7 @@
import com.android.launcher3.views.StickyHeaderLayout;
import com.android.launcher3.views.WidgetsEduView;
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.search.SearchModeListener;
import com.android.launcher3.widget.picker.search.WidgetsSearchBar;
@@ -899,11 +902,23 @@
return isFoldUnFold || useDifferentLayoutOnOrientationChange;
}
+ /**
+ * In widget search mode, we should scale down content inside widget bottom sheet, rather
+ * than the whole bottom sheet, to indicate we will navigate back within the widget
+ * bottom sheet.
+ */
+ @Override
+ public boolean shouldAnimateContentViewInBackSwipe() {
+ return mIsInSearchMode;
+ }
+
@Override
public void onBackInvoked() {
if (mIsInSearchMode) {
mSearchBar.reset();
- animateSwipeToDismissProgressToStart();
+ // Posting animation to next frame will let widget sheet finish updating UI first, and
+ // make animation smoother.
+ post(this::animateSwipeToDismissProgressToStart);
} else {
super.onBackInvoked();
}
@@ -991,6 +1006,60 @@
mAdapters.get(AdapterHolder.PRIMARY).mWidgetsRecyclerView.scrollToTop();
}
+ @Override
+ protected int getHeaderTopClip(@NonNull WidgetCell cell) {
+ StickyHeaderLayout header = findViewById(R.id.search_and_recommendations_container);
+ if (header == null) {
+ return 0;
+ }
+ Rect cellRect = new Rect();
+ boolean cellIsPartiallyVisible = cell.getGlobalVisibleRect(cellRect);
+ if (cellIsPartiallyVisible) {
+ Rect occludingRect = new Rect();
+ for (View headerChild : header.getStickyChildren()) {
+ Rect childRect = new Rect();
+ boolean childVisible = headerChild.getGlobalVisibleRect(childRect);
+ if (childVisible && childRect.intersect(cellRect)) {
+ occludingRect.union(childRect);
+ }
+ }
+ if (!occludingRect.isEmpty() && cellRect.top < occludingRect.bottom) {
+ return occludingRect.bottom - cellRect.top;
+ }
+ }
+ return 0;
+ }
+
+ @Override
+ protected void scrollCellContainerByY(WidgetCell wc, int scrollByY) {
+ for (ViewParent parent = wc.getParent(); parent != null; parent = parent.getParent()) {
+ if (parent instanceof WidgetsRecyclerView recyclerView) {
+ // Scrollable container for main widget list.
+ recyclerView.smoothScrollBy(0, scrollByY);
+ return;
+ } else if (parent instanceof StickyHeaderLayout header) {
+ // Scrollable container for recommendations. We still scroll on the recycler (even
+ // though the recommendations are not in the recycler view) because the
+ // StickyHeaderLayout scroll is connected to the currently visible recycler view.
+ WidgetsRecyclerView recyclerView = findVisibleRecyclerView();
+ if (recyclerView != null) {
+ recyclerView.smoothScrollBy(0, scrollByY);
+ }
+ return;
+ } else if (parent == this) {
+ return;
+ }
+ }
+ }
+
+ @Nullable
+ private WidgetsRecyclerView findVisibleRecyclerView() {
+ if (mViewPager != null) {
+ return (WidgetsRecyclerView) mViewPager.getPageAt(mViewPager.getCurrentPage());
+ }
+ return findViewById(R.id.primary_widgets_list_view);
+ }
+
/** A holder class for holding adapters & their corresponding recycler view. */
final class AdapterHolder {
static final int PRIMARY = 0;
diff --git a/src/com/android/launcher3/widget/picker/WidgetsRecyclerView.java b/src/com/android/launcher3/widget/picker/WidgetsRecyclerView.java
index 698e764..a47818f 100644
--- a/src/com/android/launcher3/widget/picker/WidgetsRecyclerView.java
+++ b/src/com/android/launcher3/widget/picker/WidgetsRecyclerView.java
@@ -73,7 +73,7 @@
* Maps the touch (from 0..1) to the adapter position that should be visible.
*/
@Override
- public String scrollToPositionAtProgress(float touchFraction) {
+ public CharSequence scrollToPositionAtProgress(float touchFraction) {
// Skip early if widgets are not bound.
if (isModelNotReady()) {
return "";
diff --git a/src/com/android/launcher3/widget/picker/WidgetsTwoPaneSheet.java b/src/com/android/launcher3/widget/picker/WidgetsTwoPaneSheet.java
index 14985bf..41d5f76 100644
--- a/src/com/android/launcher3/widget/picker/WidgetsTwoPaneSheet.java
+++ b/src/com/android/launcher3/widget/picker/WidgetsTwoPaneSheet.java
@@ -39,11 +39,13 @@
import androidx.annotation.NonNull;
import androidx.annotation.Px;
+import com.android.launcher3.DeviceProfile;
import com.android.launcher3.R;
import com.android.launcher3.Utilities;
import com.android.launcher3.model.data.PackageItemInfo;
import com.android.launcher3.recyclerview.ViewHolderBinder;
import com.android.launcher3.util.PackageUserKey;
+import com.android.launcher3.widget.WidgetCell;
import com.android.launcher3.widget.model.WidgetsListBaseEntry;
import com.android.launcher3.widget.model.WidgetsListContentEntry;
import com.android.launcher3.widget.model.WidgetsListHeaderEntry;
@@ -154,6 +156,26 @@
}
@Override
+ protected int getTabletHorizontalMargin(DeviceProfile deviceProfile) {
+ if (enableCategorizedWidgetSuggestions()) {
+ // two pane picker is full width for fold as well as tablet.
+ return getResources().getDimensionPixelSize(
+ R.dimen.widget_picker_two_panels_left_right_margin);
+ }
+ if (deviceProfile.isTwoPanels && enableUnfoldedTwoPanePicker()) {
+ // enableUnfoldedTwoPanePicker made two pane picker full-width for fold only.
+ return getResources().getDimensionPixelSize(
+ R.dimen.widget_picker_two_panels_left_right_margin);
+ }
+ if (deviceProfile.isLandscape && !deviceProfile.isTwoPanels) {
+ // non-fold tablet landscape margins (ag/22163531)
+ return getResources().getDimensionPixelSize(
+ R.dimen.widget_picker_landscape_tablet_left_right_margin);
+ }
+ return deviceProfile.allAppsLeftRightMargin;
+ }
+
+ @Override
protected void onUserSwipeToDismissProgressChanged() {
super.onUserSwipeToDismissProgressChanged();
boolean isSwipeToDismissInProgress = mSwipeToDismissProgress.value > 0;
@@ -423,6 +445,23 @@
return true;
}
+ @Override
+ protected int getHeaderTopClip(@NonNull WidgetCell cell) {
+ return 0;
+ }
+
+ @Override
+ protected void scrollCellContainerByY(WidgetCell wc, int scrollByY) {
+ for (ViewParent parent = wc.getParent(); parent != null; parent = parent.getParent()) {
+ if (parent instanceof ScrollView scrollView) {
+ scrollView.smoothScrollBy(0, scrollByY);
+ return;
+ } else if (parent == this) {
+ return;
+ }
+ }
+ }
+
/**
* This is a listener for when the selected header gets changed in the left pane.
*/
diff --git a/src_no_quickstep/com/android/launcher3/uioverrides/PredictedAppIconInflater.java b/src_no_quickstep/com/android/launcher3/uioverrides/PredictedAppIconInflater.java
deleted file mode 100644
index 4893c17..0000000
--- a/src_no_quickstep/com/android/launcher3/uioverrides/PredictedAppIconInflater.java
+++ /dev/null
@@ -1,29 +0,0 @@
-/*
- * Copyright (C) 2020 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.uioverrides;
-
-import android.view.LayoutInflater;
-import android.view.View;
-import android.view.ViewGroup;
-
-import com.android.launcher3.model.data.WorkspaceItemInfo;
-
-/** A util class that inflates a predicted app icon */
-public class PredictedAppIconInflater {
- public static View inflate(LayoutInflater inflater, ViewGroup parent, WorkspaceItemInfo info) {
- return null;
- }
-}
diff --git a/src_no_quickstep/com/android/launcher3/uioverrides/flags/DeveloperOptionsUI.java b/src_no_quickstep/com/android/launcher3/uioverrides/flags/DeveloperOptionsUI.java
deleted file mode 100644
index 6afa446..0000000
--- a/src_no_quickstep/com/android/launcher3/uioverrides/flags/DeveloperOptionsUI.java
+++ /dev/null
@@ -1,27 +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.uioverrides.flags;
-
-import androidx.preference.PreferenceCategory;
-import androidx.preference.PreferenceFragmentCompat;
-
-/**
- * Place holder class for developer options.
- */
-public class DeveloperOptionsUI {
-
- public DeveloperOptionsUI(PreferenceFragmentCompat fragment, PreferenceCategory flags) { }
-}
diff --git a/tests/assets/dumpTests/DeviceProfileDumpTest/phonePortrait.txt b/tests/assets/dumpTests/DeviceProfileDumpTest/phonePortrait.txt
index 197e687..82a6310 100644
--- a/tests/assets/dumpTests/DeviceProfileDumpTest/phonePortrait.txt
+++ b/tests/assets/dumpTests/DeviceProfileDumpTest/phonePortrait.txt
@@ -71,7 +71,8 @@
allAppsPadding.right: 0.0px (0.0dp)
allAppsLeftRightMargin: 0.0px (0.0dp)
hotseatBarSizePx: 273.0px (104.0dp)
- inv.hotseatColumnSpan: 5
+ mHotseatColumnSpan: 5
+ mHotseatWidthPx: 0.0px (0.0dp)
hotseatCellHeightPx: 166.0px (63.238094dp)
hotseatBarBottomSpacePx: 126.0px (48.0dp)
mHotseatBarEdgePaddingPx: 0.0px (0.0dp)
diff --git a/tests/assets/dumpTests/DeviceProfileDumpTest/phonePortrait3Button.txt b/tests/assets/dumpTests/DeviceProfileDumpTest/phonePortrait3Button.txt
index 4a9e2e6..4271105 100644
--- a/tests/assets/dumpTests/DeviceProfileDumpTest/phonePortrait3Button.txt
+++ b/tests/assets/dumpTests/DeviceProfileDumpTest/phonePortrait3Button.txt
@@ -71,7 +71,8 @@
allAppsPadding.right: 0.0px (0.0dp)
allAppsLeftRightMargin: 0.0px (0.0dp)
hotseatBarSizePx: 294.0px (112.0dp)
- inv.hotseatColumnSpan: 5
+ mHotseatColumnSpan: 5
+ mHotseatWidthPx: 0.0px (0.0dp)
hotseatCellHeightPx: 166.0px (63.238094dp)
hotseatBarBottomSpacePx: 147.0px (56.0dp)
mHotseatBarEdgePaddingPx: 0.0px (0.0dp)
diff --git a/tests/assets/dumpTests/DeviceProfileDumpTest/phoneVerticalBar.txt b/tests/assets/dumpTests/DeviceProfileDumpTest/phoneVerticalBar.txt
index 9e89a16..8bd6b99 100644
--- a/tests/assets/dumpTests/DeviceProfileDumpTest/phoneVerticalBar.txt
+++ b/tests/assets/dumpTests/DeviceProfileDumpTest/phoneVerticalBar.txt
@@ -71,7 +71,8 @@
allAppsPadding.right: 0.0px (0.0dp)
allAppsLeftRightMargin: 0.0px (0.0dp)
hotseatBarSizePx: 252.0px (96.0dp)
- inv.hotseatColumnSpan: 5
+ mHotseatColumnSpan: 5
+ mHotseatWidthPx: 0.0px (0.0dp)
hotseatCellHeightPx: 166.0px (63.238094dp)
hotseatBarBottomSpacePx: 0.0px (0.0dp)
mHotseatBarEdgePaddingPx: 63.0px (24.0dp)
diff --git a/tests/assets/dumpTests/DeviceProfileDumpTest/phoneVerticalBar3Button.txt b/tests/assets/dumpTests/DeviceProfileDumpTest/phoneVerticalBar3Button.txt
index ce168b4..8dbb413 100644
--- a/tests/assets/dumpTests/DeviceProfileDumpTest/phoneVerticalBar3Button.txt
+++ b/tests/assets/dumpTests/DeviceProfileDumpTest/phoneVerticalBar3Button.txt
@@ -71,7 +71,8 @@
allAppsPadding.right: 0.0px (0.0dp)
allAppsLeftRightMargin: 0.0px (0.0dp)
hotseatBarSizePx: 252.0px (96.0dp)
- inv.hotseatColumnSpan: 5
+ mHotseatColumnSpan: 5
+ mHotseatWidthPx: 0.0px (0.0dp)
hotseatCellHeightPx: 166.0px (63.238094dp)
hotseatBarBottomSpacePx: 0.0px (0.0dp)
mHotseatBarEdgePaddingPx: 63.0px (24.0dp)
diff --git a/tests/assets/dumpTests/DeviceProfileDumpTest/tabletLandscape.txt b/tests/assets/dumpTests/DeviceProfileDumpTest/tabletLandscape.txt
index 7926033..ab4b286 100644
--- a/tests/assets/dumpTests/DeviceProfileDumpTest/tabletLandscape.txt
+++ b/tests/assets/dumpTests/DeviceProfileDumpTest/tabletLandscape.txt
@@ -71,7 +71,8 @@
allAppsPadding.right: 32.0px (16.0dp)
allAppsLeftRightMargin: 412.0px (206.0dp)
hotseatBarSizePx: 200.0px (100.0dp)
- inv.hotseatColumnSpan: 4
+ mHotseatColumnSpan: 6
+ mHotseatWidthPx: 1960.0px (980.0dp)
hotseatCellHeightPx: 135.0px (67.5dp)
hotseatBarBottomSpacePx: 80.0px (40.0dp)
mHotseatBarEdgePaddingPx: 0.0px (0.0dp)
@@ -82,12 +83,12 @@
springLoadedHotseatBarTopMarginPx: 128.0px (64.0dp)
getHotseatLayoutPadding(context).top: 0.0px (0.0dp)
getHotseatLayoutPadding(context).bottom: 65.0px (32.5dp)
- getHotseatLayoutPadding(context).left: 668.0px (334.0dp)
- getHotseatLayoutPadding(context).right: 668.0px (334.0dp)
+ getHotseatLayoutPadding(context).left: 300.0px (150.0dp)
+ getHotseatLayoutPadding(context).right: 300.0px (150.0dp)
numShownHotseatIcons: 6
- hotseatBorderSpace: 100.0px (50.0dp)
+ hotseatBorderSpace: 248.0px (124.0dp)
isQsbInline: false
- hotseatQsbWidth: 1214.0px (607.0dp)
+ hotseatQsbWidth: 1950.0px (975.0dp)
isTaskbarPresent:false
isTaskbarPresentInApps:true
taskbarHeight: 0.0px (0.0dp)
diff --git a/tests/assets/dumpTests/DeviceProfileDumpTest/tabletLandscape3Button.txt b/tests/assets/dumpTests/DeviceProfileDumpTest/tabletLandscape3Button.txt
index eb20578..80835bc 100644
--- a/tests/assets/dumpTests/DeviceProfileDumpTest/tabletLandscape3Button.txt
+++ b/tests/assets/dumpTests/DeviceProfileDumpTest/tabletLandscape3Button.txt
@@ -71,7 +71,8 @@
allAppsPadding.right: 32.0px (16.0dp)
allAppsLeftRightMargin: 412.0px (206.0dp)
hotseatBarSizePx: 200.0px (100.0dp)
- inv.hotseatColumnSpan: 4
+ mHotseatColumnSpan: 6
+ mHotseatWidthPx: 1960.0px (980.0dp)
hotseatCellHeightPx: 135.0px (67.5dp)
hotseatBarBottomSpacePx: 80.0px (40.0dp)
mHotseatBarEdgePaddingPx: 0.0px (0.0dp)
@@ -82,12 +83,12 @@
springLoadedHotseatBarTopMarginPx: 128.0px (64.0dp)
getHotseatLayoutPadding(context).top: 0.0px (0.0dp)
getHotseatLayoutPadding(context).bottom: 65.0px (32.5dp)
- getHotseatLayoutPadding(context).left: 668.0px (334.0dp)
- getHotseatLayoutPadding(context).right: 668.0px (334.0dp)
+ getHotseatLayoutPadding(context).left: 300.0px (150.0dp)
+ getHotseatLayoutPadding(context).right: 300.0px (150.0dp)
numShownHotseatIcons: 6
- hotseatBorderSpace: 100.0px (50.0dp)
+ hotseatBorderSpace: 248.0px (124.0dp)
isQsbInline: false
- hotseatQsbWidth: 1214.0px (607.0dp)
+ hotseatQsbWidth: 1950.0px (975.0dp)
isTaskbarPresent:false
isTaskbarPresentInApps:true
taskbarHeight: 0.0px (0.0dp)
diff --git a/tests/assets/dumpTests/DeviceProfileDumpTest/tabletPortrait.txt b/tests/assets/dumpTests/DeviceProfileDumpTest/tabletPortrait.txt
index dba0ec4..fc53107 100644
--- a/tests/assets/dumpTests/DeviceProfileDumpTest/tabletPortrait.txt
+++ b/tests/assets/dumpTests/DeviceProfileDumpTest/tabletPortrait.txt
@@ -71,7 +71,8 @@
allAppsPadding.right: 32.0px (16.0dp)
allAppsLeftRightMargin: 152.0px (76.0dp)
hotseatBarSizePx: 272.0px (136.0dp)
- inv.hotseatColumnSpan: 6
+ mHotseatColumnSpan: 6
+ mHotseatWidthPx: 1300.0px (650.0dp)
hotseatCellHeightPx: 135.0px (67.5dp)
hotseatBarBottomSpacePx: 152.0px (76.0dp)
mHotseatBarEdgePaddingPx: 0.0px (0.0dp)
diff --git a/tests/assets/dumpTests/DeviceProfileDumpTest/tabletPortrait3Button.txt b/tests/assets/dumpTests/DeviceProfileDumpTest/tabletPortrait3Button.txt
index 495afb2..836819f 100644
--- a/tests/assets/dumpTests/DeviceProfileDumpTest/tabletPortrait3Button.txt
+++ b/tests/assets/dumpTests/DeviceProfileDumpTest/tabletPortrait3Button.txt
@@ -71,7 +71,8 @@
allAppsPadding.right: 32.0px (16.0dp)
allAppsLeftRightMargin: 152.0px (76.0dp)
hotseatBarSizePx: 272.0px (136.0dp)
- inv.hotseatColumnSpan: 6
+ mHotseatColumnSpan: 6
+ mHotseatWidthPx: 1300.0px (650.0dp)
hotseatCellHeightPx: 135.0px (67.5dp)
hotseatBarBottomSpacePx: 152.0px (76.0dp)
mHotseatBarEdgePaddingPx: 0.0px (0.0dp)
diff --git a/tests/assets/dumpTests/DeviceProfileDumpTest/twoPanelLandscape.txt b/tests/assets/dumpTests/DeviceProfileDumpTest/twoPanelLandscape.txt
index e7dd3e0..108182f 100644
--- a/tests/assets/dumpTests/DeviceProfileDumpTest/twoPanelLandscape.txt
+++ b/tests/assets/dumpTests/DeviceProfileDumpTest/twoPanelLandscape.txt
@@ -71,7 +71,8 @@
allAppsPadding.right: 42.0px (16.0dp)
allAppsLeftRightMargin: 183.0px (69.71429dp)
hotseatBarSizePx: 267.0px (101.71429dp)
- inv.hotseatColumnSpan: 4
+ mHotseatColumnSpan: 4
+ mHotseatWidthPx: 0.0px (0.0dp)
hotseatCellHeightPx: 159.0px (60.57143dp)
hotseatBarBottomSpacePx: 126.0px (48.0dp)
mHotseatBarEdgePaddingPx: 0.0px (0.0dp)
diff --git a/tests/assets/dumpTests/DeviceProfileDumpTest/twoPanelLandscape3Button.txt b/tests/assets/dumpTests/DeviceProfileDumpTest/twoPanelLandscape3Button.txt
index fcbd427..313d2a3 100644
--- a/tests/assets/dumpTests/DeviceProfileDumpTest/twoPanelLandscape3Button.txt
+++ b/tests/assets/dumpTests/DeviceProfileDumpTest/twoPanelLandscape3Button.txt
@@ -71,7 +71,8 @@
allAppsPadding.right: 42.0px (16.0dp)
allAppsLeftRightMargin: 183.0px (69.71429dp)
hotseatBarSizePx: 267.0px (101.71429dp)
- inv.hotseatColumnSpan: 4
+ mHotseatColumnSpan: 4
+ mHotseatWidthPx: 0.0px (0.0dp)
hotseatCellHeightPx: 159.0px (60.57143dp)
hotseatBarBottomSpacePx: 126.0px (48.0dp)
mHotseatBarEdgePaddingPx: 0.0px (0.0dp)
diff --git a/tests/assets/dumpTests/DeviceProfileDumpTest/twoPanelPortrait.txt b/tests/assets/dumpTests/DeviceProfileDumpTest/twoPanelPortrait.txt
index 319247c..fb392a8 100644
--- a/tests/assets/dumpTests/DeviceProfileDumpTest/twoPanelPortrait.txt
+++ b/tests/assets/dumpTests/DeviceProfileDumpTest/twoPanelPortrait.txt
@@ -71,7 +71,8 @@
allAppsPadding.right: 42.0px (16.0dp)
allAppsLeftRightMargin: 1.0px (0.3809524dp)
hotseatBarSizePx: 267.0px (101.71429dp)
- inv.hotseatColumnSpan: 4
+ mHotseatColumnSpan: 4
+ mHotseatWidthPx: 0.0px (0.0dp)
hotseatCellHeightPx: 159.0px (60.57143dp)
hotseatBarBottomSpacePx: 126.0px (48.0dp)
mHotseatBarEdgePaddingPx: 0.0px (0.0dp)
diff --git a/tests/assets/dumpTests/DeviceProfileDumpTest/twoPanelPortrait3Button.txt b/tests/assets/dumpTests/DeviceProfileDumpTest/twoPanelPortrait3Button.txt
index 50c1d4b..2c4b3c3 100644
--- a/tests/assets/dumpTests/DeviceProfileDumpTest/twoPanelPortrait3Button.txt
+++ b/tests/assets/dumpTests/DeviceProfileDumpTest/twoPanelPortrait3Button.txt
@@ -71,7 +71,8 @@
allAppsPadding.right: 42.0px (16.0dp)
allAppsLeftRightMargin: 1.0px (0.3809524dp)
hotseatBarSizePx: 267.0px (101.71429dp)
- inv.hotseatColumnSpan: 4
+ mHotseatColumnSpan: 4
+ mHotseatWidthPx: 0.0px (0.0dp)
hotseatCellHeightPx: 159.0px (60.57143dp)
hotseatBarBottomSpacePx: 126.0px (48.0dp)
mHotseatBarEdgePaddingPx: 0.0px (0.0dp)
diff --git a/tests/src/com/android/launcher3/FakeInvariantDeviceProfileTest.kt b/tests/src/com/android/launcher3/FakeInvariantDeviceProfileTest.kt
index 251a401..13d7499 100644
--- a/tests/src/com/android/launcher3/FakeInvariantDeviceProfileTest.kt
+++ b/tests/src/com/android/launcher3/FakeInvariantDeviceProfileTest.kt
@@ -157,7 +157,6 @@
numDatabaseHotseatIcons = 4
- hotseatColumnSpan = IntArray(4) { 4 }
hotseatBarBottomSpace = FloatArray(4) { 48f }
hotseatQsbSpace = FloatArray(4) { 36f }
@@ -240,7 +239,6 @@
numDatabaseHotseatIcons = 6
- hotseatColumnSpan = intArrayOf(6, 4, 6, 6)
hotseatBarBottomSpace = floatArrayOf(36f, 40f, 36f, 36f)
hotseatQsbSpace = FloatArray(4) { 32f }
@@ -259,8 +257,10 @@
}
protected fun initializeVarsForTwoPanel(
- isLandscape: Boolean = false,
- isGestureMode: Boolean = true
+ isLandscape: Boolean = false,
+ isGestureMode: Boolean = true,
+ rows: Int = 4,
+ cols: Int = 4,
) {
val (x, y) = if (isLandscape) Pair(2208, 1840) else Pair(1840, 2208)
@@ -276,9 +276,9 @@
inv =
InvariantDeviceProfile().apply {
- numRows = 4
- numColumns = 4
- numSearchContainerColumns = 4
+ numRows = rows
+ numColumns = cols
+ numSearchContainerColumns = cols
iconSize = floatArrayOf(60f, 52f, 52f, 60f)
iconTextSize = floatArrayOf(14f, 14f, 12f, 14f)
@@ -319,7 +319,6 @@
numDatabaseHotseatIcons = 6
- hotseatColumnSpan = IntArray(4) { 6 }
hotseatBarBottomSpace = floatArrayOf(48f, 48f, 36f, 20f)
hotseatQsbSpace = floatArrayOf(36f, 36f, 36f, 28f)
diff --git a/tests/src/com/android/launcher3/LauncherPrefsTest.kt b/tests/src/com/android/launcher3/LauncherPrefsTest.kt
index 88a430b..b813095 100644
--- a/tests/src/com/android/launcher3/LauncherPrefsTest.kt
+++ b/tests/src/com/android/launcher3/LauncherPrefsTest.kt
@@ -25,8 +25,6 @@
import com.google.common.truth.Truth.assertThat
import java.util.concurrent.CountDownLatch
import java.util.concurrent.TimeUnit
-import org.junit.AfterClass
-import org.junit.BeforeClass
import org.junit.Test
import org.junit.runner.RunWith
@@ -48,20 +46,6 @@
private val context by lazy { InstrumentationRegistry.getInstrumentation().targetContext }
private val launcherPrefs by lazy { LauncherPrefs.get(context) }
- companion object {
- @BeforeClass
- @JvmStatic
- fun setup() {
- moveStartupDataToDeviceProtectedStorageIsEnabled = true
- }
-
- @AfterClass
- @JvmStatic
- fun teardown() {
- moveStartupDataToDeviceProtectedStorageIsEnabled = false
- }
- }
-
@Test
fun has_keyMissingFromLauncherPrefs_returnsFalse() {
assertThat(launcherPrefs.has(TEST_BOOLEAN_ITEM)).isFalse()
@@ -223,31 +207,12 @@
}
@Test
- fun put_bootAwareItem_updatesEncryptedStorage() {
- val bootAwareItem =
- LauncherPrefs.backedUpItem(
- TEST_PREF_KEY,
- TEST_DEFAULT_VALUE,
- EncryptionType.MOVE_TO_DEVICE_PROTECTED
- )
-
- val encryptedPrefs: SharedPreferences =
- context.getSharedPreferences(bootAwareItem.sharedPrefFile, Context.MODE_PRIVATE)
- encryptedPrefs.edit().remove(bootAwareItem.sharedPrefKey).commit()
-
- launcherPrefs.putSync(bootAwareItem.to(TEST_STRING_ITEM.defaultValue))
- assertThat(encryptedPrefs.contains(bootAwareItem.sharedPrefKey)).isTrue()
-
- launcherPrefs.removeSync(bootAwareItem)
- }
-
- @Test
fun remove_bootAwareItem_removesFromDeviceProtectedStorage() {
val bootAwareItem =
LauncherPrefs.backedUpItem(
TEST_PREF_KEY,
TEST_DEFAULT_VALUE,
- EncryptionType.MOVE_TO_DEVICE_PROTECTED
+ EncryptionType.DEVICE_PROTECTED
)
val bootAwarePrefs: SharedPreferences =
@@ -263,90 +228,4 @@
launcherPrefs.removeSync(bootAwareItem)
assertThat(bootAwarePrefs.contains(bootAwareItem.sharedPrefKey)).isFalse()
}
-
- @Test
- fun remove_bootAwareItem_removesFromEncryptedStorage() {
- val bootAwareItem =
- LauncherPrefs.backedUpItem(
- TEST_PREF_KEY,
- TEST_DEFAULT_VALUE,
- EncryptionType.MOVE_TO_DEVICE_PROTECTED
- )
-
- val encryptedPrefs: SharedPreferences =
- context.getSharedPreferences(bootAwareItem.sharedPrefFile, Context.MODE_PRIVATE)
-
- encryptedPrefs
- .edit()
- .putString(bootAwareItem.sharedPrefKey, bootAwareItem.defaultValue)
- .commit()
-
- launcherPrefs.removeSync(bootAwareItem)
- assertThat(encryptedPrefs.contains(bootAwareItem.sharedPrefKey)).isFalse()
- }
-
- @Test
- fun migrate_bootAwareItemsToDeviceProtectedStorage_worksAsIntended() {
- val bootAwareItem =
- LauncherPrefs.backedUpItem(
- TEST_PREF_KEY,
- TEST_DEFAULT_VALUE,
- EncryptionType.MOVE_TO_DEVICE_PROTECTED
- )
- launcherPrefs.removeSync(bootAwareItem)
-
- val bootAwarePrefs: SharedPreferences =
- context
- .createDeviceProtectedStorageContext()
- .getSharedPreferences(BOOT_AWARE_PREFS_KEY, Context.MODE_PRIVATE)
-
- if (bootAwarePrefs.contains(bootAwareItem.sharedPrefKey)) {
- bootAwarePrefs.edit().remove(bootAwareItem.sharedPrefKey).commit()
- }
-
- val encryptedPrefs: SharedPreferences =
- context.getSharedPreferences(bootAwareItem.sharedPrefFile, Context.MODE_PRIVATE)
-
- encryptedPrefs
- .edit()
- .putString(bootAwareItem.sharedPrefKey, bootAwareItem.defaultValue)
- .commit()
-
- launcherPrefs.migrateStartupDataToDeviceProtectedStorage()
- assertThat(bootAwarePrefs.contains(bootAwareItem.sharedPrefKey)).isTrue()
-
- launcherPrefs.removeSync(bootAwareItem)
- }
-
- @Test
- fun migrate_onlyEncryptedItemsToDeviceProtectedStorage_doesNotHappen() {
- val onlyEncryptedItem =
- LauncherPrefs.backedUpItem(
- TEST_PREF_KEY + "_",
- TEST_DEFAULT_VALUE + "_",
- EncryptionType.ENCRYPTED
- )
-
- val bootAwarePrefs: SharedPreferences =
- context
- .createDeviceProtectedStorageContext()
- .getSharedPreferences(BOOT_AWARE_PREFS_KEY, Context.MODE_PRIVATE)
-
- if (bootAwarePrefs.contains(onlyEncryptedItem.sharedPrefKey)) {
- bootAwarePrefs.edit().remove(onlyEncryptedItem.sharedPrefKey).commit()
- }
-
- val encryptedPrefs: SharedPreferences =
- context.getSharedPreferences(onlyEncryptedItem.sharedPrefFile, Context.MODE_PRIVATE)
-
- encryptedPrefs
- .edit()
- .putString(onlyEncryptedItem.sharedPrefKey, onlyEncryptedItem.defaultValue)
- .commit()
-
- launcherPrefs.migrateStartupDataToDeviceProtectedStorage()
- assertThat(bootAwarePrefs.contains(onlyEncryptedItem.sharedPrefKey)).isFalse()
-
- encryptedPrefs.edit().remove(onlyEncryptedItem.sharedPrefKey).commit()
- }
}
diff --git a/tests/src/com/android/launcher3/allapps/PrivateProfileManagerTest.java b/tests/src/com/android/launcher3/allapps/PrivateProfileManagerTest.java
index 2dcbda4..2a4d21d 100644
--- a/tests/src/com/android/launcher3/allapps/PrivateProfileManagerTest.java
+++ b/tests/src/com/android/launcher3/allapps/PrivateProfileManagerTest.java
@@ -29,6 +29,7 @@
import static org.mockito.ArgumentMatchers.any;
import static org.mockito.ArgumentMatchers.anyInt;
import static org.mockito.Mockito.doNothing;
+import static org.mockito.Mockito.doReturn;
import static org.mockito.Mockito.spy;
import static org.mockito.Mockito.when;
@@ -150,6 +151,7 @@
PrivateProfileManager privateProfileManager = spy(mPrivateProfileManager);
doNothing().when(privateProfileManager).resetPrivateSpaceDecorator(anyInt());
doNothing().when(privateProfileManager).executeLock();
+ doReturn(mAllAppsRecyclerView).when(privateProfileManager).getMainRecyclerView();
when(mAllAppsStore.hasModelFlag(FLAG_PRIVATE_PROFILE_QUIET_MODE_ENABLED))
.thenReturn(false, true);
@@ -169,6 +171,7 @@
public void transitioningToUnlocked_resetCallsPostUnlock() throws Exception {
PrivateProfileManager privateProfileManager = spy(mPrivateProfileManager);
doNothing().when(privateProfileManager).resetPrivateSpaceDecorator(anyInt());
+ doReturn(mAllAppsRecyclerView).when(privateProfileManager).getMainRecyclerView();
when(mAllAppsStore.hasModelFlag(FLAG_PRIVATE_PROFILE_QUIET_MODE_ENABLED))
.thenReturn(false);
doNothing().when(privateProfileManager).expandPrivateSpace();
@@ -187,6 +190,7 @@
PrivateProfileManager privateProfileManager = spy(mPrivateProfileManager);
doNothing().when(privateProfileManager).resetPrivateSpaceDecorator(anyInt());
doNothing().when(privateProfileManager).executeLock();
+ doReturn(mAllAppsRecyclerView).when(privateProfileManager).getMainRecyclerView();
when(mAllAppsStore.hasModelFlag(FLAG_PRIVATE_PROFILE_QUIET_MODE_ENABLED))
.thenReturn(true);
doNothing().when(privateProfileManager).expandPrivateSpace();
@@ -205,7 +209,7 @@
ArgumentCaptor<Intent> acIntent = ArgumentCaptor.forClass(Intent.class);
mPrivateProfileManager.setPrivateSpaceSettingsAvailable(true);
- mPrivateProfileManager.openPrivateSpaceSettings();
+ mPrivateProfileManager.openPrivateSpaceSettings(null);
Mockito.verify(mContext).startActivity(acIntent.capture());
assertEquals("Intent Action is different",
diff --git a/tests/src/com/android/launcher3/model/WorkspaceItemProcessorTest.kt b/tests/src/com/android/launcher3/model/WorkspaceItemProcessorTest.kt
index 30957fc..c2e73fc 100644
--- a/tests/src/com/android/launcher3/model/WorkspaceItemProcessorTest.kt
+++ b/tests/src/com/android/launcher3/model/WorkspaceItemProcessorTest.kt
@@ -37,10 +37,12 @@
import com.android.launcher3.model.data.IconRequestInfo
import com.android.launcher3.model.data.ItemInfo
import com.android.launcher3.model.data.WorkspaceItemInfo
+import com.android.launcher3.pm.UserCache
import com.android.launcher3.shortcuts.ShortcutKey
import com.android.launcher3.util.ComponentKey
import com.android.launcher3.util.PackageManagerHelper
import com.android.launcher3.util.PackageUserKey
+import com.android.launcher3.util.UserIconInfo
import com.android.launcher3.widget.WidgetInflater
import com.google.common.truth.Truth.assertThat
import com.google.common.truth.Truth.assertWithMessage
@@ -64,13 +66,14 @@
@Mock private lateinit var mockBgDataModel: BgDataModel
@Mock private lateinit var mockContext: Context
@Mock private lateinit var mockAppState: LauncherAppState
- @Mock private lateinit var mockIntent: Intent
@Mock private lateinit var mockPmHelper: PackageManagerHelper
@Mock private lateinit var mockLauncherApps: LauncherApps
@Mock private lateinit var mockCursor: LoaderCursor
+ @Mock private lateinit var mockUserCache: UserCache
@Mock private lateinit var mockUserManagerState: UserManagerState
@Mock private lateinit var mockWidgetInflater: WidgetInflater
+ private lateinit var intent: Intent
private lateinit var userHandle: UserHandle
private lateinit var iconRequestInfos: MutableList<IconRequestInfo<WorkspaceItemInfo>>
private lateinit var componentName: ComponentName
@@ -90,11 +93,11 @@
mockBgDataModel = mock<BgDataModel>()
componentName = ComponentName("package", "class")
unlockedUsersArray = LongSparseArray<Boolean>(1).apply { put(101, true) }
- mockIntent =
- mock<Intent>().apply {
- whenever(component).thenReturn(componentName)
- whenever(`package`).thenReturn("pkg")
- whenever(getStringExtra(ShortcutKey.EXTRA_SHORTCUT_ID)).thenReturn("")
+ intent =
+ Intent().apply {
+ component = componentName
+ `package` = "pkg"
+ putExtra(ShortcutKey.EXTRA_SHORTCUT_ID, "")
}
mockContext =
mock<Context>().apply {
@@ -110,7 +113,7 @@
mockPmHelper =
mock<PackageManagerHelper>().apply {
whenever(getAppLaunchIntent(componentName.packageName, userHandle))
- .thenReturn(mockIntent)
+ .thenReturn(intent)
}
mockLauncherApps =
mock<LauncherApps>().apply {
@@ -124,14 +127,20 @@
id = 1
restoreFlag = 1
serialNumber = 101
- whenever(parseIntent()).thenReturn(mockIntent)
+ whenever(parseIntent()).thenReturn(intent)
whenever(markRestored()).doAnswer { restoreFlag = 0 }
- whenever(updater().put(Favorites.INTENT, mockIntent.toUri(0)).commit())
- .thenReturn(1)
+ whenever(updater().put(Favorites.INTENT, intent.toUri(0)).commit()).thenReturn(1)
whenever(getAppShortcutInfo(any(), any(), any(), any()))
.thenReturn(mockWorkspaceInfo)
whenever(createIconRequestInfo(any(), any())).thenReturn(mockIconRequestInfo)
}
+ mockUserCache =
+ mock<UserCache>().apply {
+ val userIconInfo =
+ mock<UserIconInfo>().apply() { whenever(isPrivate).thenReturn(false) }
+ whenever(getUserInfo(any())).thenReturn(userIconInfo)
+ }
+
mockUserManagerState = mock<UserManagerState>()
mockWidgetInflater = mock<WidgetInflater>()
keyToPinnedShortcutsMap = mutableMapOf()
@@ -147,6 +156,7 @@
private fun createWorkspaceItemProcessorUnderTest(
cursor: LoaderCursor = mockCursor,
memoryLogger: LoaderMemoryLogger? = null,
+ userCache: UserCache = mockUserCache,
userManagerState: UserManagerState = mockUserManagerState,
launcherApps: LauncherApps = mockLauncherApps,
shortcutKeyToPinnedShortcuts: Map<ShortcutKey, ShortcutInfo> = keyToPinnedShortcutsMap,
@@ -165,6 +175,7 @@
WorkspaceItemProcessor(
c = cursor,
memoryLogger = memoryLogger,
+ userCache = userCache,
userManagerState = userManagerState,
launcherApps = launcherApps,
app = app,
@@ -185,9 +196,11 @@
fun `When user is null then mark item deleted`() {
// Given
mockCursor = mock<LoaderCursor>().apply { id = 1 }
- itemProcessorUnderTest = createWorkspaceItemProcessorUnderTest()
+
// When
+ itemProcessorUnderTest = createWorkspaceItemProcessorUnderTest()
itemProcessorUnderTest.processItem()
+
// Then
verify(mockCursor).markDeleted("User has been deleted for item id=1", PROFILE_DELETED)
verify(mockCursor, times(0)).checkAndAddItem(any(), any(), anyOrNull())
@@ -197,8 +210,9 @@
fun `When app has null intent then mark deleted`() {
// Given
mockCursor.apply { whenever(parseIntent()).thenReturn(null) }
- itemProcessorUnderTest = createWorkspaceItemProcessorUnderTest()
+
// When
+ itemProcessorUnderTest = createWorkspaceItemProcessorUnderTest()
itemProcessorUnderTest.processItem()
// Then
verify(mockCursor).markDeleted("Null intent from db for item id=1", MISSING_INFO)
@@ -209,13 +223,13 @@
fun `When app has null target package then mark deleted`() {
// Given
- mockIntent.apply {
- whenever(component).thenReturn(null)
- whenever(`package`).thenReturn(null)
+ intent.apply {
+ component = null
+ `package` = null
}
- itemProcessorUnderTest = createWorkspaceItemProcessorUnderTest()
// When
+ itemProcessorUnderTest = createWorkspaceItemProcessorUnderTest()
itemProcessorUnderTest.processItem()
// Then
@@ -228,11 +242,11 @@
// Given
componentName = ComponentName("", "")
- whenever(mockIntent.component).thenReturn(componentName)
- whenever(mockCursor.parseIntent()).thenReturn(mockIntent)
- itemProcessorUnderTest = createWorkspaceItemProcessorUnderTest()
+ intent.component = componentName
+ intent.`package` = ""
// When
+ itemProcessorUnderTest = createWorkspaceItemProcessorUnderTest()
itemProcessorUnderTest.processItem()
// Then
@@ -243,10 +257,8 @@
@Test
fun `When valid app then mark restored`() {
- // Given
- itemProcessorUnderTest = createWorkspaceItemProcessorUnderTest()
-
// When
+ itemProcessorUnderTest = createWorkspaceItemProcessorUnderTest()
itemProcessorUnderTest.processItem()
// Then
@@ -271,18 +283,18 @@
mockPmHelper =
mock<PackageManagerHelper>().apply {
whenever(getAppLaunchIntent(componentName.packageName, userHandle))
- .thenReturn(mockIntent)
+ .thenReturn(intent)
}
- itemProcessorUnderTest = createWorkspaceItemProcessorUnderTest()
// When
+ itemProcessorUnderTest = createWorkspaceItemProcessorUnderTest()
itemProcessorUnderTest.processItem()
// Then
assertWithMessage("item restoreFlag should be set to 0")
.that(mockCursor.restoreFlag)
.isEqualTo(0)
- verify(mockCursor.updater().put(Favorites.INTENT, mockIntent.toUri(0))).commit()
+ verify(mockCursor.updater().put(Favorites.INTENT, intent.toUri(0))).commit()
assertThat(iconRequestInfos).containsExactly(mockIconRequestInfo)
verify(mockCursor).checkAndAddItem(mockWorkspaceInfo, mockBgDataModel, null)
}
@@ -300,9 +312,9 @@
mock<PackageManagerHelper>().apply {
whenever(getAppLaunchIntent(componentName.packageName, userHandle)).thenReturn(null)
}
- itemProcessorUnderTest = createWorkspaceItemProcessorUnderTest()
// When
+ itemProcessorUnderTest = createWorkspaceItemProcessorUnderTest()
itemProcessorUnderTest.processItem()
// Then
@@ -336,13 +348,13 @@
whenever(disabledReason).thenReturn(0)
whenever(persons).thenReturn(EMPTY_PERSON_ARRAY)
}
- val shortcutKey = ShortcutKey.fromIntent(mockIntent, mockCursor.user)
+ val shortcutKey = ShortcutKey.fromIntent(intent, mockCursor.user)
keyToPinnedShortcutsMap[shortcutKey] = expectedShortcutInfo
iconRequestInfos = mutableListOf()
- itemProcessorUnderTest =
- createWorkspaceItemProcessorUnderTest(allDeepShortcuts = allDeepShortcuts)
// When
+ itemProcessorUnderTest =
+ createWorkspaceItemProcessorUnderTest(allDeepShortcuts = allDeepShortcuts)
itemProcessorUnderTest.processItem()
// Then
@@ -362,9 +374,9 @@
mockCursor.itemType = ITEM_TYPE_DEEP_SHORTCUT
iconRequestInfos = mutableListOf()
keyToPinnedShortcutsMap = hashMapOf()
- itemProcessorUnderTest = createWorkspaceItemProcessorUnderTest()
// When
+ itemProcessorUnderTest = createWorkspaceItemProcessorUnderTest()
itemProcessorUnderTest.processItem()
// Then
@@ -381,6 +393,45 @@
}
@Test
+ fun `When valid Pinned Deep Shortcut with null intent package then use targetPkg`() {
+
+ // Given
+ mockCursor.itemType = ITEM_TYPE_DEEP_SHORTCUT
+ val expectedShortcutInfo =
+ mock<ShortcutInfo>().apply {
+ whenever(id).thenReturn("")
+ whenever(`package`).thenReturn("")
+ whenever(activity).thenReturn(mock())
+ whenever(longLabel).thenReturn("")
+ whenever(isEnabled).thenReturn(true)
+ whenever(disabledMessage).thenReturn("")
+ whenever(disabledReason).thenReturn(0)
+ whenever(persons).thenReturn(EMPTY_PERSON_ARRAY)
+ }
+ iconRequestInfos = mutableListOf()
+ // Make sure shortcuts map has expected key from expected package
+ intent.`package` = componentName.packageName
+ val shortcutKey = ShortcutKey.fromIntent(intent, mockCursor.user)
+ keyToPinnedShortcutsMap[shortcutKey] = expectedShortcutInfo
+ // set intent package back to null to test scenario
+ intent.`package` = null
+
+ // When
+ itemProcessorUnderTest =
+ createWorkspaceItemProcessorUnderTest(allDeepShortcuts = allDeepShortcuts)
+ itemProcessorUnderTest.processItem()
+
+ // Then
+ assertWithMessage("item restoreFlag should be set to 0")
+ .that(mockCursor.restoreFlag)
+ .isEqualTo(0)
+ assertThat(iconRequestInfos).isEmpty()
+ assertThat(allDeepShortcuts).containsExactly(expectedShortcutInfo)
+ verify(mockCursor).markRestored()
+ verify(mockCursor).checkAndAddItem(any(), any(), anyOrNull())
+ }
+
+ @Test
fun `When processing Folder then create FolderInfo and mark restored`() {
val actualFolderInfo = FolderInfo()
mockBgDataModel =
diff --git a/tests/src/com/android/launcher3/nonquickstep/HotseatWidthCalculationTest.kt b/tests/src/com/android/launcher3/nonquickstep/HotseatWidthCalculationTest.kt
index 9912a34..408691c 100644
--- a/tests/src/com/android/launcher3/nonquickstep/HotseatWidthCalculationTest.kt
+++ b/tests/src/com/android/launcher3/nonquickstep/HotseatWidthCalculationTest.kt
@@ -42,6 +42,8 @@
assertThat(dp.hotseatBarEndOffset).isEqualTo(0)
assertThat(dp.numShownHotseatIcons).isEqualTo(6)
assertThat(dp.hotseatBorderSpace).isEqualTo(145)
+ assertThat(dp.hotseatColumnSpan).isEqualTo(6)
+ assertThat(dp.hotseatWidthPx).isEqualTo(1445)
assertThat(dp.getHotseatLayoutPadding(context).left).isEqualTo(177)
assertThat(dp.getHotseatLayoutPadding(context).right).isEqualTo(177)
@@ -64,6 +66,8 @@
assertThat(dp.hotseatBarEndOffset).isEqualTo(0)
assertThat(dp.numShownHotseatIcons).isEqualTo(6)
assertThat(dp.hotseatBorderSpace).isEqualTo(72)
+ assertThat(dp.hotseatColumnSpan).isEqualTo(6)
+ assertThat(dp.hotseatWidthPx).isEqualTo(1080)
assertThat(dp.getHotseatLayoutPadding(context).left).isEqualTo(110)
assertThat(dp.getHotseatLayoutPadding(context).right).isEqualTo(110)
@@ -85,6 +89,8 @@
assertThat(dp.hotseatBarEndOffset).isEqualTo(0)
assertThat(dp.numShownHotseatIcons).isEqualTo(6)
assertThat(dp.hotseatBorderSpace).isEqualTo(104)
+ assertThat(dp.hotseatColumnSpan).isEqualTo(6)
+ assertThat(dp.hotseatWidthPx).isEqualTo(1468)
assertThat(dp.getHotseatLayoutPadding(context).left).isEqualTo(370)
assertThat(dp.getHotseatLayoutPadding(context).right).isEqualTo(370)
@@ -100,22 +106,21 @@
@Test
fun nav_buttons_dont_interfere_with_required_hotseat_width() {
initializeVarsForTablet(isGestureMode = false, isLandscape = true)
- inv?.apply {
- hotseatColumnSpan = IntArray(4) { 4 }
- inlineQsb = BooleanArray(4) { false }
- }
+ inv?.apply { inlineQsb = BooleanArray(4) { false } }
val dp = newDP()
dp.isTaskbarPresentInApps = true
assertThat(dp.hotseatBarEndOffset).isEqualTo(0)
assertThat(dp.numShownHotseatIcons).isEqualTo(6)
- assertThat(dp.hotseatBorderSpace).isEqualTo(100)
+ assertThat(dp.hotseatBorderSpace).isEqualTo(248)
+ assertThat(dp.hotseatColumnSpan).isEqualTo(6)
+ assertThat(dp.hotseatWidthPx).isEqualTo(1960)
- assertThat(dp.getHotseatLayoutPadding(context).left).isEqualTo(668)
- assertThat(dp.getHotseatLayoutPadding(context).right).isEqualTo(668)
+ assertThat(dp.getHotseatLayoutPadding(context).left).isEqualTo(300)
+ assertThat(dp.getHotseatLayoutPadding(context).right).isEqualTo(300)
assertThat(dp.isQsbInline).isFalse()
- assertThat(dp.hotseatQsbWidth).isEqualTo(1214)
+ assertThat(dp.hotseatQsbWidth).isEqualTo(1950)
}
/** This is a case when after setting the hotseat, the QSB width needs to be changed to fit */
@@ -128,13 +133,15 @@
assertThat(dp.hotseatBarEndOffset).isEqualTo(0)
assertThat(dp.numShownHotseatIcons).isEqualTo(6)
- assertThat(dp.hotseatBorderSpace).isEqualTo(91)
+ assertThat(dp.hotseatBorderSpace).isEqualTo(233)
+ assertThat(dp.hotseatColumnSpan).isEqualTo(6)
+ assertThat(dp.hotseatWidthPx).isEqualTo(1885)
- assertThat(dp.getHotseatLayoutPadding(context).left).isEqualTo(640)
- assertThat(dp.getHotseatLayoutPadding(context).right).isEqualTo(640)
+ assertThat(dp.getHotseatLayoutPadding(context).left).isEqualTo(287)
+ assertThat(dp.getHotseatLayoutPadding(context).right).isEqualTo(287)
assertThat(dp.isQsbInline).isFalse()
- assertThat(dp.hotseatQsbWidth).isEqualTo(1169)
+ assertThat(dp.hotseatQsbWidth).isEqualTo(1875)
}
/**
@@ -150,13 +157,15 @@
assertThat(dp.hotseatBarEndOffset).isEqualTo(0)
assertThat(dp.numShownHotseatIcons).isEqualTo(6)
- assertThat(dp.hotseatBorderSpace).isEqualTo(75)
+ assertThat(dp.hotseatBorderSpace).isEqualTo(205)
+ assertThat(dp.hotseatColumnSpan).isEqualTo(6)
+ assertThat(dp.hotseatWidthPx).isEqualTo(1745)
- assertThat(dp.getHotseatLayoutPadding(context).left).isEqualTo(582)
- assertThat(dp.getHotseatLayoutPadding(context).right).isEqualTo(582)
+ assertThat(dp.getHotseatLayoutPadding(context).left).isEqualTo(257)
+ assertThat(dp.getHotseatLayoutPadding(context).right).isEqualTo(257)
assertThat(dp.isQsbInline).isFalse()
- assertThat(dp.hotseatQsbWidth).isEqualTo(1085)
+ assertThat(dp.hotseatQsbWidth).isEqualTo(1735)
}
@Test
@@ -179,4 +188,23 @@
assertThat(dp.hotseatQsbWidth).isEqualTo(1435)
}
}
+
+ @Test
+ fun increase_span_when_space_between_icons_is_less_than_minimum() {
+ initializeVarsForTwoPanel(isGestureMode = false, isLandscape = false, rows = 5, cols = 5)
+ val dp = newDP()
+ dp.isTaskbarPresentInApps = true
+
+ assertThat(dp.hotseatBarEndOffset).isEqualTo(0)
+ assertThat(dp.numShownHotseatIcons).isEqualTo(6)
+ assertThat(dp.hotseatBorderSpace).isEqualTo(112)
+ assertThat(dp.hotseatColumnSpan).isEqualTo(8)
+ assertThat(dp.hotseatWidthPx).isEqualTo(1383)
+
+ assertThat(dp.getHotseatLayoutPadding(context).left).isEqualTo(228)
+ assertThat(dp.getHotseatLayoutPadding(context).right).isEqualTo(228)
+
+ assertThat(dp.isQsbInline).isFalse()
+ assertThat(dp.hotseatQsbWidth).isEqualTo(1372)
+ }
}
diff --git a/tests/src/com/android/launcher3/ui/widget/TaplWidgetPickerTest.java b/tests/src/com/android/launcher3/ui/widget/TaplWidgetPickerTest.java
index 79724e1..19c5850 100644
--- a/tests/src/com/android/launcher3/ui/widget/TaplWidgetPickerTest.java
+++ b/tests/src/com/android/launcher3/ui/widget/TaplWidgetPickerTest.java
@@ -15,8 +15,6 @@
*/
package com.android.launcher3.ui.widget;
-import static com.android.launcher3.util.rule.ShellCommandRule.createEnableInputTransportPublisherRule;
-
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.assertTrue;
@@ -32,9 +30,7 @@
import com.android.launcher3.widget.picker.WidgetsFullSheet;
import com.android.launcher3.widget.picker.WidgetsRecyclerView;
-import org.junit.Rule;
import org.junit.Test;
-import org.junit.rules.TestRule;
import org.junit.runner.RunWith;
/**
@@ -44,9 +40,6 @@
@MediumTest
@RunWith(AndroidJUnit4.class)
public class TaplWidgetPickerTest extends AbstractLauncherUiTest<Launcher> {
- // b/325377690 : To get the log printed where DOWN key event is getting lost from TAPL.
- @Rule public final TestRule mEnableInputTransportPublisherRule =
- createEnableInputTransportPublisherRule();
private WidgetsRecyclerView getWidgetsView(Launcher launcher) {
return WidgetsFullSheet.getWidgetsView(launcher);
diff --git a/tests/src/com/android/launcher3/util/rule/SetPropRule.java b/tests/src/com/android/launcher3/util/rule/SetPropRule.java
new file mode 100644
index 0000000..74fec35
--- /dev/null
+++ b/tests/src/com/android/launcher3/util/rule/SetPropRule.java
@@ -0,0 +1,75 @@
+/*
+ * 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.rule;
+
+import static androidx.test.platform.app.InstrumentationRegistry.getInstrumentation;
+
+import android.text.TextUtils;
+
+import androidx.annotation.NonNull;
+import androidx.test.uiautomator.UiDevice;
+
+import org.junit.rules.TestRule;
+import org.junit.runner.Description;
+import org.junit.runners.model.Statement;
+
+/**
+ * Test rule which executes a set prop command at the start of the test.
+ * This rule needs the property tag and property value so that value can be set to a tag.
+ */
+public class SetPropRule implements TestRule {
+ private static final String SETPROP_PREFIX = "setprop";
+ private static final String GETPROP_PREFIX = "getprop";
+ private static final String UNKNOWN = "UNKNOWN";
+ @NonNull private final String mPropTag;
+ @NonNull private final String mPropValue;
+
+ public SetPropRule(@NonNull String propTag, @NonNull String propValue) {
+ mPropTag = propTag.trim();
+ mPropValue = propValue.trim();
+ }
+
+ @Override
+ public Statement apply(Statement base, Description description) {
+ return new Statement() {
+ @Override
+ public void evaluate() throws Throwable {
+ String getpropCmd = GETPROP_PREFIX + " " + mPropTag;
+ String initialValue = UiDevice.getInstance(getInstrumentation())
+ .executeShellCommand(getpropCmd);
+ if (TextUtils.isEmpty(initialValue.trim())) {
+ initialValue = UNKNOWN;
+ }
+ // setprop command always follows format : setprop <TAG> <value>
+ String revertSetPropCmd = SETPROP_PREFIX + " " + mPropTag + " " + initialValue;
+ String setPropCmd = SETPROP_PREFIX + " " + mPropTag + " " + mPropValue;
+ new ShellCommandRule(setPropCmd, revertSetPropCmd)
+ .apply(base, description).evaluate();
+ }
+ };
+ }
+
+ /**
+ * Enables "InputTransportPublisher" debug flag. This prints the key input events dispatched by
+ * the system server.
+ * adb shell setprop log.tag.InputTransportPublisher DEBUG
+ * See {@link com.android.cts.input.DebugInputRule} for more details.
+ */
+ public static SetPropRule createEnableInputTransportPublisherRule() {
+ return new SetPropRule("log.tag.InputTransportPublisher", "DEBUG");
+ }
+}
diff --git a/tests/src/com/android/launcher3/util/rule/ShellCommandRule.java b/tests/src/com/android/launcher3/util/rule/ShellCommandRule.java
index 977995e..2219003 100644
--- a/tests/src/com/android/launcher3/util/rule/ShellCommandRule.java
+++ b/tests/src/com/android/launcher3/util/rule/ShellCommandRule.java
@@ -15,13 +15,12 @@
*/
package com.android.launcher3.util.rule;
-import static androidx.test.InstrumentationRegistry.getInstrumentation;
+import static androidx.test.platform.app.InstrumentationRegistry.getInstrumentation;
import static com.android.launcher3.tapl.TestHelpers.getLauncherInMyProcess;
import android.content.ComponentName;
import android.content.pm.ActivityInfo;
-import android.text.TextUtils;
import androidx.annotation.Nullable;
import androidx.test.InstrumentationRegistry;
@@ -40,10 +39,6 @@
* Test rule which executes a shell command at the start of the test.
*/
public class ShellCommandRule implements TestRule {
-
- private static final String SETPROP_PREFIX = "setprop";
- private static final String GETPROP_PREFIX = "getprop";
- private static final String UNKNOWN = "UNKNOWN";
private final String mCmd;
private final String mRevertCommand;
private final boolean mCheckSuccess;
@@ -66,19 +61,6 @@
return new Statement() {
@Override
public void evaluate() throws Throwable {
- String revertSetPropCmd = null;
- if (mCmd.startsWith(SETPROP_PREFIX) && mRevertCommand == null) {
- // setprop command always follows format : setprop <TAG> <value>
- // We are stripping out only the TAG here
- String tag = mCmd.split("\\s")[1];
- String getpropCmd = GETPROP_PREFIX + " " + tag;
- String initialValue = UiDevice.getInstance(
- getInstrumentation()).executeShellCommand(getpropCmd);
- if (TextUtils.isEmpty(initialValue.trim())) {
- initialValue = UNKNOWN;
- }
- revertSetPropCmd = SETPROP_PREFIX + " " + tag + " " + initialValue;
- }
final String result =
UiDevice.getInstance(getInstrumentation()).executeShellCommand(mCmd);
if (mCheckSuccess) {
@@ -90,15 +72,12 @@
try {
base.evaluate();
} finally {
- if (mRevertCommand != null || revertSetPropCmd != null) {
- String revertCmd =
- mRevertCommand != null ? mRevertCommand : revertSetPropCmd;
+ if (mRevertCommand != null) {
final String revertResult = UiDevice.getInstance(
- getInstrumentation()).executeShellCommand(
- revertCmd);
+ getInstrumentation()).executeShellCommand(mRevertCommand);
if (mCheckSuccess) {
Assert.assertTrue(
- "Failed command: " + revertCmd
+ "Failed command: " + mRevertCommand
+ ", result: " + revertResult,
"Success".equals(result.replaceAll("\\s", "")));
}
@@ -141,14 +120,4 @@
return new ShellCommandRule("settings put global heads_up_notifications_enabled 0",
"settings put global heads_up_notifications_enabled 1");
}
-
- /**
- * Enables "InputTransportPublisher" debug flag. This prints the key input events dispatched by
- * the system server.
- * adb shell setprop log.tag.InputTransportPublisher DEBUG
- * See {@link com.android.cts.input.DebugInputRule} for more details.
- */
- public static ShellCommandRule createEnableInputTransportPublisherRule() {
- return new ShellCommandRule("setprop log.tag.InputTransportPublisher DEBUG", null);
- }
}