Merge "Add divider line into taskbar." into tm-qpr-dev
diff --git a/protos/launcher_atom.proto b/protos/launcher_atom.proto
index 677c992..c8a7d85 100644
--- a/protos/launcher_atom.proto
+++ b/protos/launcher_atom.proto
@@ -130,7 +130,7 @@
optional int32 cardinality = 2;
}
-// Next value 41
+// Next value 43
enum Attribute {
UNKNOWN = 0;
DEFAULT_LAYOUT = 1; // icon automatically placed in workspace, folder, hotseat
@@ -174,6 +174,8 @@
ALL_APPS_SEARCH_RESULT_PEOPLE_TILE = 27;
ALL_APPS_SEARCH_RESULT_LEGACY_SHORTCUT = 30;
ALL_APPS_SEARCH_RESULT_ASSISTANT_MEMORY = 31;
+ ALL_APPS_SEARCH_RESULT_VIDEO = 41;
+ ALL_APPS_SEARCH_RESULT_SYSTEM_POINTER = 42;
// Web suggestions provided by AGA
ALL_APPS_SEARCH_RESULT_WEB_SUGGEST = 39;
diff --git a/quickstep/res/values-af/strings.xml b/quickstep/res/values-af/strings.xml
index 1605c24..d1a5d5c 100644
--- a/quickstep/res/values-af/strings.xml
+++ b/quickstep/res/values-af/strings.xml
@@ -95,9 +95,10 @@
<string name="taskbar_edu_a11y_title" msgid="5417986057866415355">"Taakbalkopvoeding"</string>
<string name="taskbar_edu_opened" msgid="3950252793551919129">"Taakbalkopvoeding het verskyn"</string>
<string name="taskbar_edu_closed" msgid="126643734478892862">"Taakbalkopvoeding is toegemaak"</string>
- <string name="taskbar_edu_splitscreen" msgid="5563823414110661454">"Sleep na die kant om 2 apps tegelyk te gebruik"</string>
+ <string name="taskbar_edu_splitscreen" msgid="5605512479258053350">"Sleep ’n app na die kant toe om 2 apps tegelyk te gebruik"</string>
<string name="taskbar_edu_stashing" msgid="2805035263048176462">"Kortswiep op om die taakbalk te wys"</string>
- <string name="taskbar_edu_suggestions" msgid="1416699696825090402">"Die taakbalk stel apps op grond van jou roetine voor"</string>
+ <string name="taskbar_edu_suggestions" msgid="8215044496435527982">"Kry appvoorstelle op grond van jou roetine"</string>
+ <string name="taskbar_edu_features" msgid="2338325667726857642">"Doen meer met die taakbalk"</string>
<string name="taskbar_edu_next" msgid="4007618274426775841">"Volgende"</string>
<string name="taskbar_edu_previous" msgid="459202320127201702">"Terug"</string>
<string name="taskbar_edu_close" msgid="887022990168191073">"Maak toe"</string>
diff --git a/quickstep/res/values-am/strings.xml b/quickstep/res/values-am/strings.xml
index df9fe66..6b63deb 100644
--- a/quickstep/res/values-am/strings.xml
+++ b/quickstep/res/values-am/strings.xml
@@ -95,9 +95,13 @@
<string name="taskbar_edu_a11y_title" msgid="5417986057866415355">"የተግባር አሞሌ ትምህርት"</string>
<string name="taskbar_edu_opened" msgid="3950252793551919129">"የተግባር አሞሌ ትምህርት ይታያል"</string>
<string name="taskbar_edu_closed" msgid="126643734478892862">"የተግባር አሞሌ ትምህርት ተዘግቷል"</string>
- <string name="taskbar_edu_splitscreen" msgid="5563823414110661454">"በአንድ ጊዜ 2 መተግበሪያዎችን ለመጠቀም ወደ ጎን ይጎትቱ"</string>
+ <!-- no translation found for taskbar_edu_splitscreen (5605512479258053350) -->
+ <skip />
<string name="taskbar_edu_stashing" msgid="2805035263048176462">"የተግባር አሞሌውን ለማሳየት አጭር ወደ ላይ ያንሸራትቱ"</string>
- <string name="taskbar_edu_suggestions" msgid="1416699696825090402">"የተግባር አሞሌው የዕለት ተዕለት ተግባርዎ ላይ በመመስረት መተግበሪያዎችን ይጠቁማል"</string>
+ <!-- no translation found for taskbar_edu_suggestions (8215044496435527982) -->
+ <skip />
+ <!-- no translation found for taskbar_edu_features (2338325667726857642) -->
+ <skip />
<string name="taskbar_edu_next" msgid="4007618274426775841">"ቀጣይ"</string>
<string name="taskbar_edu_previous" msgid="459202320127201702">"ተመለስ"</string>
<string name="taskbar_edu_close" msgid="887022990168191073">"ዝጋ"</string>
diff --git a/quickstep/res/values-ar/strings.xml b/quickstep/res/values-ar/strings.xml
index a6781ef..ed98f69 100644
--- a/quickstep/res/values-ar/strings.xml
+++ b/quickstep/res/values-ar/strings.xml
@@ -95,9 +95,13 @@
<string name="taskbar_edu_a11y_title" msgid="5417986057866415355">"التعريف بشريط التطبيقات"</string>
<string name="taskbar_edu_opened" msgid="3950252793551919129">"ظهرت لوحة تعليم استخدام شريط المهام."</string>
<string name="taskbar_edu_closed" msgid="126643734478892862">"تم إغلاق لوحة تعليم استخدام شريط المهام."</string>
- <string name="taskbar_edu_splitscreen" msgid="5563823414110661454">"اسحبه إلى جانب الشاشة لاستخدام تطبيقَين في آنٍ واحد."</string>
+ <!-- no translation found for taskbar_edu_splitscreen (5605512479258053350) -->
+ <skip />
<string name="taskbar_edu_stashing" msgid="2805035263048176462">"مرِّر سريعًا للأعلى تمريرة قصيرة لإظهار شريط التطبيقات."</string>
- <string name="taskbar_edu_suggestions" msgid="1416699696825090402">"يقترح شريط المهام تطبيقات بناءً على روتينك."</string>
+ <!-- no translation found for taskbar_edu_suggestions (8215044496435527982) -->
+ <skip />
+ <!-- no translation found for taskbar_edu_features (2338325667726857642) -->
+ <skip />
<string name="taskbar_edu_next" msgid="4007618274426775841">"الشاشة التالية"</string>
<string name="taskbar_edu_previous" msgid="459202320127201702">"رجوع"</string>
<string name="taskbar_edu_close" msgid="887022990168191073">"إغلاق"</string>
diff --git a/quickstep/res/values-as/strings.xml b/quickstep/res/values-as/strings.xml
index 6e43c19..a9be2c3 100644
--- a/quickstep/res/values-as/strings.xml
+++ b/quickstep/res/values-as/strings.xml
@@ -95,9 +95,13 @@
<string name="taskbar_edu_a11y_title" msgid="5417986057866415355">"টাস্কবাৰৰ শিক্ষা"</string>
<string name="taskbar_edu_opened" msgid="3950252793551919129">"টাস্কবাৰৰ শিক্ষাৰ পেনেলটো প্ৰদর্শিত হৈছে"</string>
<string name="taskbar_edu_closed" msgid="126643734478892862">"টাস্কবাৰৰ শিক্ষাৰ পেনেলটো বন্ধ হৈছে"</string>
- <string name="taskbar_edu_splitscreen" msgid="5563823414110661454">"এবাৰতে দুটা এপ্ ব্যৱহাৰ কৰিবলৈ কাষলৈ টানি আনি এৰক"</string>
+ <!-- no translation found for taskbar_edu_splitscreen (5605512479258053350) -->
+ <skip />
<string name="taskbar_edu_stashing" msgid="2805035263048176462">"টাস্কবাৰ দেখুৱাবলৈ সামান্য পৰিমাণে ওপৰলৈ ছোৱাইপ কৰক"</string>
- <string name="taskbar_edu_suggestions" msgid="1416699696825090402">"টাস্কবাৰে আপোনাৰ ৰুটিনৰ ভিত্তিত এপৰ পৰামৰ্শ দিয়ে"</string>
+ <!-- no translation found for taskbar_edu_suggestions (8215044496435527982) -->
+ <skip />
+ <!-- no translation found for taskbar_edu_features (2338325667726857642) -->
+ <skip />
<string name="taskbar_edu_next" msgid="4007618274426775841">"পৰৱৰ্তী"</string>
<string name="taskbar_edu_previous" msgid="459202320127201702">"উভতি যাওক"</string>
<string name="taskbar_edu_close" msgid="887022990168191073">"বন্ধ কৰক"</string>
diff --git a/quickstep/res/values-az/strings.xml b/quickstep/res/values-az/strings.xml
index e844ec1..c538613 100644
--- a/quickstep/res/values-az/strings.xml
+++ b/quickstep/res/values-az/strings.xml
@@ -95,9 +95,10 @@
<string name="taskbar_edu_a11y_title" msgid="5417986057866415355">"Tapşırıq panelində təhsil"</string>
<string name="taskbar_edu_opened" msgid="3950252793551919129">"Tapşırıq panelindəki təlim bölməsi görünür"</string>
<string name="taskbar_edu_closed" msgid="126643734478892862">"Tapşırıq panelindəki təlim bölməsi bağlanıb"</string>
- <string name="taskbar_edu_splitscreen" msgid="5563823414110661454">"Eyni anda 2 tətbiqi istifadə etmək üçün yan tərəfə çəkin"</string>
+ <string name="taskbar_edu_splitscreen" msgid="5605512479258053350">"Eyni anda 2 tətbiqi istifadə etmək üçün bir tətbiqi yan tərəfə çəkin"</string>
<string name="taskbar_edu_stashing" msgid="2805035263048176462">"Tapşırıq panelini göstərmək üçün azca yuxarı sürüşdürün"</string>
- <string name="taskbar_edu_suggestions" msgid="1416699696825090402">"Tapşırıq paneli rejiminizə əsasən tətbiqlər təklif edir"</string>
+ <string name="taskbar_edu_suggestions" msgid="8215044496435527982">"Rejiminizə əsasən tətbiq təklifləri alın"</string>
+ <string name="taskbar_edu_features" msgid="2338325667726857642">"Tapşırıq paneli ilə daha çox şey edin"</string>
<string name="taskbar_edu_next" msgid="4007618274426775841">"Sonra"</string>
<string name="taskbar_edu_previous" msgid="459202320127201702">"Geri"</string>
<string name="taskbar_edu_close" msgid="887022990168191073">"Bağlayın"</string>
diff --git a/quickstep/res/values-b+sr+Latn/strings.xml b/quickstep/res/values-b+sr+Latn/strings.xml
index 2699c3e..1bd9d10 100644
--- a/quickstep/res/values-b+sr+Latn/strings.xml
+++ b/quickstep/res/values-b+sr+Latn/strings.xml
@@ -95,9 +95,10 @@
<string name="taskbar_edu_a11y_title" msgid="5417986057866415355">"Uputstva na traci zadataka"</string>
<string name="taskbar_edu_opened" msgid="3950252793551919129">"Edukativno okno iz trake zadataka se pojavilo"</string>
<string name="taskbar_edu_closed" msgid="126643734478892862">"Edukativno okno iz trake zadataka je zatvoreno"</string>
- <string name="taskbar_edu_splitscreen" msgid="5563823414110661454">"Prevucite na stranu da biste koristili 2 aplikacije odjednom"</string>
+ <string name="taskbar_edu_splitscreen" msgid="5605512479258053350">"Prevucite na stranu da biste koristili 2 aplikacije odjednom"</string>
<string name="taskbar_edu_stashing" msgid="2805035263048176462">"Nakratko prevucite nagore da biste prikazali traku zadataka"</string>
- <string name="taskbar_edu_suggestions" msgid="1416699696825090402">"Traka zadataka predlaže aplikacije na osnovu rutine"</string>
+ <string name="taskbar_edu_suggestions" msgid="8215044496435527982">"Dobijajte predloge aplikacija na osnovu rutine"</string>
+ <string name="taskbar_edu_features" msgid="2338325667726857642">"Uradite više pomoću trake zadataka"</string>
<string name="taskbar_edu_next" msgid="4007618274426775841">"Dalje"</string>
<string name="taskbar_edu_previous" msgid="459202320127201702">"Nazad"</string>
<string name="taskbar_edu_close" msgid="887022990168191073">"Zatvori"</string>
diff --git a/quickstep/res/values-be/strings.xml b/quickstep/res/values-be/strings.xml
index 0f38c75..b951c7a 100644
--- a/quickstep/res/values-be/strings.xml
+++ b/quickstep/res/values-be/strings.xml
@@ -95,9 +95,13 @@
<string name="taskbar_edu_a11y_title" msgid="5417986057866415355">"Інфармацыя пра панэль задач"</string>
<string name="taskbar_edu_opened" msgid="3950252793551919129">"З\'явілася панэль навучання на панэлі задач"</string>
<string name="taskbar_edu_closed" msgid="126643734478892862">"Панэль навучання на панэлі задач закрыта"</string>
- <string name="taskbar_edu_splitscreen" msgid="5563823414110661454">"Перацягніце ўбок, каб адначасова скарыстаць 2 праграмы"</string>
+ <!-- no translation found for taskbar_edu_splitscreen (5605512479258053350) -->
+ <skip />
<string name="taskbar_edu_stashing" msgid="2805035263048176462">"Хутка правядзіце пальцам уверх, каб убачыць панэль задач"</string>
- <string name="taskbar_edu_suggestions" msgid="1416699696825090402">"На панэлі задач праграмы паказваюцца з улікам вашых дзеянняў"</string>
+ <!-- no translation found for taskbar_edu_suggestions (8215044496435527982) -->
+ <skip />
+ <!-- no translation found for taskbar_edu_features (2338325667726857642) -->
+ <skip />
<string name="taskbar_edu_next" msgid="4007618274426775841">"Далей"</string>
<string name="taskbar_edu_previous" msgid="459202320127201702">"Назад"</string>
<string name="taskbar_edu_close" msgid="887022990168191073">"Закрыць"</string>
diff --git a/quickstep/res/values-bg/strings.xml b/quickstep/res/values-bg/strings.xml
index a284394..4900627 100644
--- a/quickstep/res/values-bg/strings.xml
+++ b/quickstep/res/values-bg/strings.xml
@@ -95,9 +95,13 @@
<string name="taskbar_edu_a11y_title" msgid="5417986057866415355">"Урок за лентата на задачите"</string>
<string name="taskbar_edu_opened" msgid="3950252793551919129">"Показва се урокът за лентата на задачите"</string>
<string name="taskbar_edu_closed" msgid="126643734478892862">"Урокът за лентата на задачите бе затворен"</string>
- <string name="taskbar_edu_splitscreen" msgid="5563823414110661454">"Плъзнете встрани, за да използвате едновременно 2 приложения"</string>
+ <!-- no translation found for taskbar_edu_splitscreen (5605512479258053350) -->
+ <skip />
<string name="taskbar_edu_stashing" msgid="2805035263048176462">"Прекарайте пръст нагоре, за да видите лентата на задачите"</string>
- <string name="taskbar_edu_suggestions" msgid="1416699696825090402">"Лентата на задачите предлага приложения според навиците ви"</string>
+ <!-- no translation found for taskbar_edu_suggestions (8215044496435527982) -->
+ <skip />
+ <!-- no translation found for taskbar_edu_features (2338325667726857642) -->
+ <skip />
<string name="taskbar_edu_next" msgid="4007618274426775841">"Напред"</string>
<string name="taskbar_edu_previous" msgid="459202320127201702">"Назад"</string>
<string name="taskbar_edu_close" msgid="887022990168191073">"Затваряне"</string>
diff --git a/quickstep/res/values-bn/strings.xml b/quickstep/res/values-bn/strings.xml
index e769131..0bd38d1 100644
--- a/quickstep/res/values-bn/strings.xml
+++ b/quickstep/res/values-bn/strings.xml
@@ -95,9 +95,10 @@
<string name="taskbar_edu_a11y_title" msgid="5417986057866415355">"টাস্কবার এডুকেশন"</string>
<string name="taskbar_edu_opened" msgid="3950252793551919129">"টাস্কবার এডুকেশন দেখানো হয়েছে"</string>
<string name="taskbar_edu_closed" msgid="126643734478892862">"টাস্কবার এডুকেশন বন্ধ করা আছে"</string>
- <string name="taskbar_edu_splitscreen" msgid="5563823414110661454">"একসাথে ২টি অ্যাপ ব্যবহার করতে পাশে টেনে আনুন"</string>
+ <string name="taskbar_edu_splitscreen" msgid="5605512479258053350">"একসাথে ২টি অ্যাপ ব্যবহার করতে একটি অ্যাপ পাশে টেনে আনুন"</string>
<string name="taskbar_edu_stashing" msgid="2805035263048176462">"টাস্কবার দেখানোর জন্য শর্ট সোয়াইপ করুন"</string>
- <string name="taskbar_edu_suggestions" msgid="1416699696825090402">"আপনার রুটিনের উপর নির্ভর করে টাস্কবার অ্যাপ সাজেস্ট করে"</string>
+ <string name="taskbar_edu_suggestions" msgid="8215044496435527982">"আপনার রুটিন অনুযায়ী অ্যাপ থেকে সাজেশন পান"</string>
+ <string name="taskbar_edu_features" msgid="2338325667726857642">"\'টাস্কবার\' ফিচারের সাহায্যে আরও অনেক কিছু করুন"</string>
<string name="taskbar_edu_next" msgid="4007618274426775841">"পরবর্তী"</string>
<string name="taskbar_edu_previous" msgid="459202320127201702">"ফিরুন"</string>
<string name="taskbar_edu_close" msgid="887022990168191073">"বন্ধ করুন"</string>
diff --git a/quickstep/res/values-bs/strings.xml b/quickstep/res/values-bs/strings.xml
index f0118a7..e50d45c 100644
--- a/quickstep/res/values-bs/strings.xml
+++ b/quickstep/res/values-bs/strings.xml
@@ -95,9 +95,10 @@
<string name="taskbar_edu_a11y_title" msgid="5417986057866415355">"Edukacija o traci zadataka"</string>
<string name="taskbar_edu_opened" msgid="3950252793551919129">"Edukacija o programskoj traci je prikazana"</string>
<string name="taskbar_edu_closed" msgid="126643734478892862">"Edukacija o programskoj traci je zatvorena"</string>
- <string name="taskbar_edu_splitscreen" msgid="5563823414110661454">"Prevucite u stranu da istovremeno koristite 2 aplikacije"</string>
+ <string name="taskbar_edu_splitscreen" msgid="5605512479258053350">"Povucite apl. u stranu radi istodobne upotrebe 2 aplikacije"</string>
<string name="taskbar_edu_stashing" msgid="2805035263048176462">"Nakratko prevucite nagore da prikažete traku zadataka"</string>
- <string name="taskbar_edu_suggestions" msgid="1416699696825090402">"Traka zadataka predlaže aplikacije na osnovu vaše rutine"</string>
+ <string name="taskbar_edu_suggestions" msgid="8215044496435527982">"Primajte prijedloge aplikacija na temelju svoje rutine"</string>
+ <string name="taskbar_edu_features" msgid="2338325667726857642">"Učinite više uz pomoć trake sa zadacima"</string>
<string name="taskbar_edu_next" msgid="4007618274426775841">"Naprijed"</string>
<string name="taskbar_edu_previous" msgid="459202320127201702">"Nazad"</string>
<string name="taskbar_edu_close" msgid="887022990168191073">"Zatvori"</string>
diff --git a/quickstep/res/values-ca/strings.xml b/quickstep/res/values-ca/strings.xml
index d1219ad..0eb529b 100644
--- a/quickstep/res/values-ca/strings.xml
+++ b/quickstep/res/values-ca/strings.xml
@@ -95,9 +95,13 @@
<string name="taskbar_edu_a11y_title" msgid="5417986057866415355">"Informació sobre Barra de tasques"</string>
<string name="taskbar_edu_opened" msgid="3950252793551919129">"Ha aparegut el tauler educatiu de la barra de tasques"</string>
<string name="taskbar_edu_closed" msgid="126643734478892862">"S\'ha tancat el tauler educatiu de la barra de tasques"</string>
- <string name="taskbar_edu_splitscreen" msgid="5563823414110661454">"Arrossega al costat per utilitzar 2 aplicacions alhora"</string>
+ <!-- no translation found for taskbar_edu_splitscreen (5605512479258053350) -->
+ <skip />
<string name="taskbar_edu_stashing" msgid="2805035263048176462">"Llisca una mica cap amunt per mostrar la barra de tasques"</string>
- <string name="taskbar_edu_suggestions" msgid="1416699696825090402">"La barra de tasques suggereix apps basades en la teva rutina"</string>
+ <!-- no translation found for taskbar_edu_suggestions (8215044496435527982) -->
+ <skip />
+ <!-- no translation found for taskbar_edu_features (2338325667726857642) -->
+ <skip />
<string name="taskbar_edu_next" msgid="4007618274426775841">"Següent"</string>
<string name="taskbar_edu_previous" msgid="459202320127201702">"Enrere"</string>
<string name="taskbar_edu_close" msgid="887022990168191073">"Tanca"</string>
diff --git a/quickstep/res/values-cs/strings.xml b/quickstep/res/values-cs/strings.xml
index 868393d..23a98cb 100644
--- a/quickstep/res/values-cs/strings.xml
+++ b/quickstep/res/values-cs/strings.xml
@@ -95,9 +95,13 @@
<string name="taskbar_edu_a11y_title" msgid="5417986057866415355">"Informace o panelu aplikací"</string>
<string name="taskbar_edu_opened" msgid="3950252793551919129">"Zobrazila se výuka k hlavnímu panelu"</string>
<string name="taskbar_edu_closed" msgid="126643734478892862">"Výuka k hlavnímu panelu byla zavřena"</string>
- <string name="taskbar_edu_splitscreen" msgid="5563823414110661454">"Po přetažení na stranu lze používat dvě aplikace současně"</string>
+ <!-- no translation found for taskbar_edu_splitscreen (5605512479258053350) -->
+ <skip />
<string name="taskbar_edu_stashing" msgid="2805035263048176462">"Krátkým přejetím nahoru zobrazíte panel aplikací"</string>
- <string name="taskbar_edu_suggestions" msgid="1416699696825090402">"Panel aplikací navrhuje aplikace na základě vašeho používání"</string>
+ <!-- no translation found for taskbar_edu_suggestions (8215044496435527982) -->
+ <skip />
+ <!-- no translation found for taskbar_edu_features (2338325667726857642) -->
+ <skip />
<string name="taskbar_edu_next" msgid="4007618274426775841">"Další"</string>
<string name="taskbar_edu_previous" msgid="459202320127201702">"Zpět"</string>
<string name="taskbar_edu_close" msgid="887022990168191073">"Zavřít"</string>
diff --git a/quickstep/res/values-da/strings.xml b/quickstep/res/values-da/strings.xml
index ae2a00a..ce1bdf8 100644
--- a/quickstep/res/values-da/strings.xml
+++ b/quickstep/res/values-da/strings.xml
@@ -95,9 +95,13 @@
<string name="taskbar_edu_a11y_title" msgid="5417986057866415355">"Oplysninger om proceslinjen"</string>
<string name="taskbar_edu_opened" msgid="3950252793551919129">"Vejledningen om proceslinjen blev åbnet"</string>
<string name="taskbar_edu_closed" msgid="126643734478892862">"Vejledningen om proceslinjen blev lukket"</string>
- <string name="taskbar_edu_splitscreen" msgid="5563823414110661454">"Træk til siden for at bruge 2 apps samtidig"</string>
+ <!-- no translation found for taskbar_edu_splitscreen (5605512479258053350) -->
+ <skip />
<string name="taskbar_edu_stashing" msgid="2805035263048176462">"Stryg hurtigt opad for at se proceslinjen"</string>
- <string name="taskbar_edu_suggestions" msgid="1416699696825090402">"Proceslinjen foreslår apps baseret på din rutine"</string>
+ <!-- no translation found for taskbar_edu_suggestions (8215044496435527982) -->
+ <skip />
+ <!-- no translation found for taskbar_edu_features (2338325667726857642) -->
+ <skip />
<string name="taskbar_edu_next" msgid="4007618274426775841">"Næste"</string>
<string name="taskbar_edu_previous" msgid="459202320127201702">"Tilbage"</string>
<string name="taskbar_edu_close" msgid="887022990168191073">"Luk"</string>
diff --git a/quickstep/res/values-de/strings.xml b/quickstep/res/values-de/strings.xml
index c7664be..389486a 100644
--- a/quickstep/res/values-de/strings.xml
+++ b/quickstep/res/values-de/strings.xml
@@ -95,9 +95,10 @@
<string name="taskbar_edu_a11y_title" msgid="5417986057866415355">"Informationen zur Taskleiste"</string>
<string name="taskbar_edu_opened" msgid="3950252793551919129">"Anleitung für Taskleiste eingeblendet"</string>
<string name="taskbar_edu_closed" msgid="126643734478892862">"Anleitung für Taskleiste geschlossen"</string>
- <string name="taskbar_edu_splitscreen" msgid="5563823414110661454">"Zur Seite ziehen, um zwei Apps gleichzeitig zu verwenden"</string>
+ <string name="taskbar_edu_splitscreen" msgid="5605512479258053350">"App zur Seite ziehen, um zwei Apps gleichzeitig zu nutzen"</string>
<string name="taskbar_edu_stashing" msgid="2805035263048176462">"Kurz nach oben wischen, um die Taskleiste anzuzeigen"</string>
- <string name="taskbar_edu_suggestions" msgid="1416699696825090402">"Taskleiste empfiehlt Apps basierend auf deinen Gewohnheiten"</string>
+ <string name="taskbar_edu_suggestions" msgid="8215044496435527982">"App-Vorschläge auf Grundlage deiner Nutzung erhalten"</string>
+ <string name="taskbar_edu_features" msgid="2338325667726857642">"Mehr Möglichkeiten mit der Taskleiste"</string>
<string name="taskbar_edu_next" msgid="4007618274426775841">"Weiter"</string>
<string name="taskbar_edu_previous" msgid="459202320127201702">"Zurück"</string>
<string name="taskbar_edu_close" msgid="887022990168191073">"Schließen"</string>
diff --git a/quickstep/res/values-el/strings.xml b/quickstep/res/values-el/strings.xml
index 807ce43..b21ef88 100644
--- a/quickstep/res/values-el/strings.xml
+++ b/quickstep/res/values-el/strings.xml
@@ -95,9 +95,10 @@
<string name="taskbar_edu_a11y_title" msgid="5417986057866415355">"Πληροφορίες χρήσης της Γραμμής εργαλείων"</string>
<string name="taskbar_edu_opened" msgid="3950252793551919129">"Η εκπαίδευση για τη γραμμή εργασιών εμφανίστηκε"</string>
<string name="taskbar_edu_closed" msgid="126643734478892862">"Η εκπαίδευση για τη γραμμή εργασιών έκλεισε"</string>
- <string name="taskbar_edu_splitscreen" msgid="5563823414110661454">"Σύρετε στο πλάι για ταυτόχρονη χρήση δύο εφαρμογών"</string>
+ <string name="taskbar_edu_splitscreen" msgid="5605512479258053350">"Σύρετε μια εφαρμ. στην άκρη για χρήση δύο εφαρμ. ταυτόχρονα"</string>
<string name="taskbar_edu_stashing" msgid="2805035263048176462">"Σύρετε σύντομα προς τα πάνω για εμφάνιση γραμμής εργαλείων"</string>
- <string name="taskbar_edu_suggestions" msgid="1416699696825090402">"Η γραμμή εργαλείων συνιστά εφαρμογές βάσει της ρουτίνας σας"</string>
+ <string name="taskbar_edu_suggestions" msgid="8215044496435527982">"Λάβετε προτεινόμενες εφαρμογές με βάση τη ρουτίνα σας"</string>
+ <string name="taskbar_edu_features" msgid="2338325667726857642">"Κάντε περισσότερα με τη γραμμή εργαλείων"</string>
<string name="taskbar_edu_next" msgid="4007618274426775841">"Επόμενο"</string>
<string name="taskbar_edu_previous" msgid="459202320127201702">"Πίσω"</string>
<string name="taskbar_edu_close" msgid="887022990168191073">"Κλείσιμο"</string>
diff --git a/quickstep/res/values-en-rAU/strings.xml b/quickstep/res/values-en-rAU/strings.xml
index 414593a..2daea5a 100644
--- a/quickstep/res/values-en-rAU/strings.xml
+++ b/quickstep/res/values-en-rAU/strings.xml
@@ -95,9 +95,10 @@
<string name="taskbar_edu_a11y_title" msgid="5417986057866415355">"Taskbar education"</string>
<string name="taskbar_edu_opened" msgid="3950252793551919129">"Taskbar education appeared"</string>
<string name="taskbar_edu_closed" msgid="126643734478892862">"Taskbar education closed"</string>
- <string name="taskbar_edu_splitscreen" msgid="5563823414110661454">"Drag to the side to use two apps at once"</string>
+ <string name="taskbar_edu_splitscreen" msgid="5605512479258053350">"Drag an app to the side to use two apps at once"</string>
<string name="taskbar_edu_stashing" msgid="2805035263048176462">"Short swipe up to show the taskbar"</string>
- <string name="taskbar_edu_suggestions" msgid="1416699696825090402">"The taskbar suggests apps based on your routine"</string>
+ <string name="taskbar_edu_suggestions" msgid="8215044496435527982">"Get app suggestions based on your routine"</string>
+ <string name="taskbar_edu_features" msgid="2338325667726857642">"Do more with the taskbar"</string>
<string name="taskbar_edu_next" msgid="4007618274426775841">"Next"</string>
<string name="taskbar_edu_previous" msgid="459202320127201702">"Back"</string>
<string name="taskbar_edu_close" msgid="887022990168191073">"Close"</string>
diff --git a/quickstep/res/values-en-rCA/strings.xml b/quickstep/res/values-en-rCA/strings.xml
index 41fb803..14fc636 100644
--- a/quickstep/res/values-en-rCA/strings.xml
+++ b/quickstep/res/values-en-rCA/strings.xml
@@ -95,9 +95,10 @@
<string name="taskbar_edu_a11y_title" msgid="5417986057866415355">"Taskbar education"</string>
<string name="taskbar_edu_opened" msgid="3950252793551919129">"Taskbar education appeared"</string>
<string name="taskbar_edu_closed" msgid="126643734478892862">"Taskbar education closed"</string>
- <string name="taskbar_edu_splitscreen" msgid="5563823414110661454">"Drag to the side to use 2 apps at once"</string>
+ <string name="taskbar_edu_splitscreen" msgid="5605512479258053350">"Drag an app to the side to use 2 apps at once"</string>
<string name="taskbar_edu_stashing" msgid="2805035263048176462">"Short swipe up to show the taskbar"</string>
- <string name="taskbar_edu_suggestions" msgid="1416699696825090402">"The taskbar suggests apps based on your routine"</string>
+ <string name="taskbar_edu_suggestions" msgid="8215044496435527982">"Get app suggestions based on your routine"</string>
+ <string name="taskbar_edu_features" msgid="2338325667726857642">"Do more with the taskbar"</string>
<string name="taskbar_edu_next" msgid="4007618274426775841">"Next"</string>
<string name="taskbar_edu_previous" msgid="459202320127201702">"Back"</string>
<string name="taskbar_edu_close" msgid="887022990168191073">"Close"</string>
diff --git a/quickstep/res/values-en-rGB/strings.xml b/quickstep/res/values-en-rGB/strings.xml
index 414593a..2daea5a 100644
--- a/quickstep/res/values-en-rGB/strings.xml
+++ b/quickstep/res/values-en-rGB/strings.xml
@@ -95,9 +95,10 @@
<string name="taskbar_edu_a11y_title" msgid="5417986057866415355">"Taskbar education"</string>
<string name="taskbar_edu_opened" msgid="3950252793551919129">"Taskbar education appeared"</string>
<string name="taskbar_edu_closed" msgid="126643734478892862">"Taskbar education closed"</string>
- <string name="taskbar_edu_splitscreen" msgid="5563823414110661454">"Drag to the side to use two apps at once"</string>
+ <string name="taskbar_edu_splitscreen" msgid="5605512479258053350">"Drag an app to the side to use two apps at once"</string>
<string name="taskbar_edu_stashing" msgid="2805035263048176462">"Short swipe up to show the taskbar"</string>
- <string name="taskbar_edu_suggestions" msgid="1416699696825090402">"The taskbar suggests apps based on your routine"</string>
+ <string name="taskbar_edu_suggestions" msgid="8215044496435527982">"Get app suggestions based on your routine"</string>
+ <string name="taskbar_edu_features" msgid="2338325667726857642">"Do more with the taskbar"</string>
<string name="taskbar_edu_next" msgid="4007618274426775841">"Next"</string>
<string name="taskbar_edu_previous" msgid="459202320127201702">"Back"</string>
<string name="taskbar_edu_close" msgid="887022990168191073">"Close"</string>
diff --git a/quickstep/res/values-en-rIN/strings.xml b/quickstep/res/values-en-rIN/strings.xml
index 414593a..2daea5a 100644
--- a/quickstep/res/values-en-rIN/strings.xml
+++ b/quickstep/res/values-en-rIN/strings.xml
@@ -95,9 +95,10 @@
<string name="taskbar_edu_a11y_title" msgid="5417986057866415355">"Taskbar education"</string>
<string name="taskbar_edu_opened" msgid="3950252793551919129">"Taskbar education appeared"</string>
<string name="taskbar_edu_closed" msgid="126643734478892862">"Taskbar education closed"</string>
- <string name="taskbar_edu_splitscreen" msgid="5563823414110661454">"Drag to the side to use two apps at once"</string>
+ <string name="taskbar_edu_splitscreen" msgid="5605512479258053350">"Drag an app to the side to use two apps at once"</string>
<string name="taskbar_edu_stashing" msgid="2805035263048176462">"Short swipe up to show the taskbar"</string>
- <string name="taskbar_edu_suggestions" msgid="1416699696825090402">"The taskbar suggests apps based on your routine"</string>
+ <string name="taskbar_edu_suggestions" msgid="8215044496435527982">"Get app suggestions based on your routine"</string>
+ <string name="taskbar_edu_features" msgid="2338325667726857642">"Do more with the taskbar"</string>
<string name="taskbar_edu_next" msgid="4007618274426775841">"Next"</string>
<string name="taskbar_edu_previous" msgid="459202320127201702">"Back"</string>
<string name="taskbar_edu_close" msgid="887022990168191073">"Close"</string>
diff --git a/quickstep/res/values-en-rXC/strings.xml b/quickstep/res/values-en-rXC/strings.xml
index 45ce0c1..4c92a72 100644
--- a/quickstep/res/values-en-rXC/strings.xml
+++ b/quickstep/res/values-en-rXC/strings.xml
@@ -95,9 +95,10 @@
<string name="taskbar_edu_a11y_title" msgid="5417986057866415355">"Taskbar education"</string>
<string name="taskbar_edu_opened" msgid="3950252793551919129">"Taskbar education appeared"</string>
<string name="taskbar_edu_closed" msgid="126643734478892862">"Taskbar education closed"</string>
- <string name="taskbar_edu_splitscreen" msgid="5563823414110661454">"Drag to the side to use 2 apps at once"</string>
+ <string name="taskbar_edu_splitscreen" msgid="5605512479258053350">"Drag an app to the side to use 2 apps at once"</string>
<string name="taskbar_edu_stashing" msgid="2805035263048176462">"Short swipe up to show the taskbar"</string>
- <string name="taskbar_edu_suggestions" msgid="1416699696825090402">"The taskbar suggests apps based on your routine"</string>
+ <string name="taskbar_edu_suggestions" msgid="8215044496435527982">"Get app suggestions based on your routine"</string>
+ <string name="taskbar_edu_features" msgid="2338325667726857642">"Do more with the taskbar"</string>
<string name="taskbar_edu_next" msgid="4007618274426775841">"Next"</string>
<string name="taskbar_edu_previous" msgid="459202320127201702">"Back"</string>
<string name="taskbar_edu_close" msgid="887022990168191073">"Close"</string>
diff --git a/quickstep/res/values-es-rUS/strings.xml b/quickstep/res/values-es-rUS/strings.xml
index cb7f519..0f4143b 100644
--- a/quickstep/res/values-es-rUS/strings.xml
+++ b/quickstep/res/values-es-rUS/strings.xml
@@ -95,9 +95,10 @@
<string name="taskbar_edu_a11y_title" msgid="5417986057866415355">"Información sobre la barra de tareas"</string>
<string name="taskbar_edu_opened" msgid="3950252793551919129">"Se abrió la barra de herramientas Educación"</string>
<string name="taskbar_edu_closed" msgid="126643734478892862">"Se cerró la barra de herramientas Educación"</string>
- <string name="taskbar_edu_splitscreen" msgid="5563823414110661454">"Arrastra a un lado para usar 2 apps a la vez"</string>
+ <string name="taskbar_edu_splitscreen" msgid="5605512479258053350">"Arrastra una app a un lado para usar 2 apps a la vez"</string>
<string name="taskbar_edu_stashing" msgid="2805035263048176462">"Desliza un poco hacia arriba para mostrar la barra de tareas"</string>
- <string name="taskbar_edu_suggestions" msgid="1416699696825090402">"La barra de tareas sugiere apps según tu rutina"</string>
+ <string name="taskbar_edu_suggestions" msgid="8215044496435527982">"Recibe sugerencias de aplicaciones basadas en tu rutina"</string>
+ <string name="taskbar_edu_features" msgid="2338325667726857642">"Haz más con la barra de tareas"</string>
<string name="taskbar_edu_next" msgid="4007618274426775841">"Siguiente"</string>
<string name="taskbar_edu_previous" msgid="459202320127201702">"Atrás"</string>
<string name="taskbar_edu_close" msgid="887022990168191073">"Cerrar"</string>
diff --git a/quickstep/res/values-es/strings.xml b/quickstep/res/values-es/strings.xml
index 09cd305..84c078c 100644
--- a/quickstep/res/values-es/strings.xml
+++ b/quickstep/res/values-es/strings.xml
@@ -95,9 +95,13 @@
<string name="taskbar_edu_a11y_title" msgid="5417986057866415355">"Información sobre la barra de tareas"</string>
<string name="taskbar_edu_opened" msgid="3950252793551919129">"Ha aparecido una nota sobre la barra de tareas"</string>
<string name="taskbar_edu_closed" msgid="126643734478892862">"Nota sobre la barra de tareas cerrada"</string>
- <string name="taskbar_edu_splitscreen" msgid="5563823414110661454">"Arrastra hacia un lado para usar 2 aplicaciones a la vez"</string>
+ <!-- no translation found for taskbar_edu_splitscreen (5605512479258053350) -->
+ <skip />
<string name="taskbar_edu_stashing" msgid="2805035263048176462">"Desliza un poco hacia arriba para ver la barra de tareas"</string>
- <string name="taskbar_edu_suggestions" msgid="1416699696825090402">"La barra de tareas sugiere aplicaciones según tus hábitos"</string>
+ <!-- no translation found for taskbar_edu_suggestions (8215044496435527982) -->
+ <skip />
+ <!-- no translation found for taskbar_edu_features (2338325667726857642) -->
+ <skip />
<string name="taskbar_edu_next" msgid="4007618274426775841">"Siguiente"</string>
<string name="taskbar_edu_previous" msgid="459202320127201702">"Atrás"</string>
<string name="taskbar_edu_close" msgid="887022990168191073">"Cerrar"</string>
diff --git a/quickstep/res/values-et/strings.xml b/quickstep/res/values-et/strings.xml
index 4160316..5badec9 100644
--- a/quickstep/res/values-et/strings.xml
+++ b/quickstep/res/values-et/strings.xml
@@ -95,9 +95,13 @@
<string name="taskbar_edu_a11y_title" msgid="5417986057866415355">"Tegumiriba tutvustus"</string>
<string name="taskbar_edu_opened" msgid="3950252793551919129">"Tegumiriba juhised kuvati"</string>
<string name="taskbar_edu_closed" msgid="126643734478892862">"Tegumiriba juhised on suletud"</string>
- <string name="taskbar_edu_splitscreen" msgid="5563823414110661454">"Kahe rakenduse korraga kasutamiseks lohistage külje poole"</string>
+ <!-- no translation found for taskbar_edu_splitscreen (5605512479258053350) -->
+ <skip />
<string name="taskbar_edu_stashing" msgid="2805035263048176462">"Tegumiriba kuvamiseks pühkige korraks"</string>
- <string name="taskbar_edu_suggestions" msgid="1416699696825090402">"Tegumiribal soovitatakse rakendusi teie rutiinide põhjal"</string>
+ <!-- no translation found for taskbar_edu_suggestions (8215044496435527982) -->
+ <skip />
+ <!-- no translation found for taskbar_edu_features (2338325667726857642) -->
+ <skip />
<string name="taskbar_edu_next" msgid="4007618274426775841">"Järgmine"</string>
<string name="taskbar_edu_previous" msgid="459202320127201702">"Tagasi"</string>
<string name="taskbar_edu_close" msgid="887022990168191073">"Sule"</string>
diff --git a/quickstep/res/values-eu/strings.xml b/quickstep/res/values-eu/strings.xml
index b302888..e2912ef 100644
--- a/quickstep/res/values-eu/strings.xml
+++ b/quickstep/res/values-eu/strings.xml
@@ -95,9 +95,13 @@
<string name="taskbar_edu_a11y_title" msgid="5417986057866415355">"Zereginen barra erabiltzeko argibideak"</string>
<string name="taskbar_edu_opened" msgid="3950252793551919129">"Agertu egin da zereginen barraren tutoriala"</string>
<string name="taskbar_edu_closed" msgid="126643734478892862">"Itxi egin da zereginen barraren tutoriala"</string>
- <string name="taskbar_edu_splitscreen" msgid="5563823414110661454">"Bi aplikazio batera erabiltzeko, arrastatu hatza albo batera"</string>
+ <!-- no translation found for taskbar_edu_splitscreen (5605512479258053350) -->
+ <skip />
<string name="taskbar_edu_stashing" msgid="2805035263048176462">"Ataza-barra ikusteko, pasatu hatza bizkor gora"</string>
- <string name="taskbar_edu_suggestions" msgid="1416699696825090402">"Ataza-barran erabileran oinarritutako aplikazioak iradokitzen dira"</string>
+ <!-- no translation found for taskbar_edu_suggestions (8215044496435527982) -->
+ <skip />
+ <!-- no translation found for taskbar_edu_features (2338325667726857642) -->
+ <skip />
<string name="taskbar_edu_next" msgid="4007618274426775841">"Hurrengoa"</string>
<string name="taskbar_edu_previous" msgid="459202320127201702">"Atzera"</string>
<string name="taskbar_edu_close" msgid="887022990168191073">"Itxi"</string>
diff --git a/quickstep/res/values-fa/strings.xml b/quickstep/res/values-fa/strings.xml
index c922f80..0b9e557 100644
--- a/quickstep/res/values-fa/strings.xml
+++ b/quickstep/res/values-fa/strings.xml
@@ -95,9 +95,10 @@
<string name="taskbar_edu_a11y_title" msgid="5417986057866415355">"آموزش نوار وظیفه"</string>
<string name="taskbar_edu_opened" msgid="3950252793551919129">"پانل آموزشی نوار وظیفه نمایان شد"</string>
<string name="taskbar_edu_closed" msgid="126643734478892862">"پانل آموزشی نوار وظیفه بسته شد"</string>
- <string name="taskbar_edu_splitscreen" msgid="5563823414110661454">"برای استفاده همزمان از دو برنامه، آن را به کنار بکشید"</string>
+ <string name="taskbar_edu_splitscreen" msgid="5605512479258053350">"برای استفاده همزمان از ۲ برنامه، برنامهای را بهکنار بکشید"</string>
<string name="taskbar_edu_stashing" msgid="2805035263048176462">"برای نمایش نوار وظیفه، کمی به بالا بکشید"</string>
- <string name="taskbar_edu_suggestions" msgid="1416699696825090402">"نوار وظیفه برنامهها را براساس روال شما پیشنهاد میدهد"</string>
+ <string name="taskbar_edu_suggestions" msgid="8215044496435527982">"دریافت «پیشنهادهای برنامه» براساس روال همیشگی"</string>
+ <string name="taskbar_edu_features" msgid="2338325667726857642">"انجام کارهای بیشتر با نوار وظیفه"</string>
<string name="taskbar_edu_next" msgid="4007618274426775841">"بعدی"</string>
<string name="taskbar_edu_previous" msgid="459202320127201702">"برگشت"</string>
<string name="taskbar_edu_close" msgid="887022990168191073">"بستن"</string>
diff --git a/quickstep/res/values-fi/strings.xml b/quickstep/res/values-fi/strings.xml
index a07fdea..c3cd69e 100644
--- a/quickstep/res/values-fi/strings.xml
+++ b/quickstep/res/values-fi/strings.xml
@@ -95,9 +95,13 @@
<string name="taskbar_edu_a11y_title" msgid="5417986057866415355">"Tehtäväpalkin ohje"</string>
<string name="taskbar_edu_opened" msgid="3950252793551919129">"Tehtäväpalkin ohje näkyvissä"</string>
<string name="taskbar_edu_closed" msgid="126643734478892862">"Tehtäväpalkin ohje suljettu"</string>
- <string name="taskbar_edu_splitscreen" msgid="5563823414110661454">"Vetämällä sivuun voit käyttää kahta sovellusta samaan aikaan"</string>
+ <!-- no translation found for taskbar_edu_splitscreen (5605512479258053350) -->
+ <skip />
<string name="taskbar_edu_stashing" msgid="2805035263048176462">"Näytä tehtäväpalkki pyyhkäisemällä ylös lyhyesti"</string>
- <string name="taskbar_edu_suggestions" msgid="1416699696825090402">"Tehtäväpalkki ehdottaa sovelluksia ohjelmasi perusteella"</string>
+ <!-- no translation found for taskbar_edu_suggestions (8215044496435527982) -->
+ <skip />
+ <!-- no translation found for taskbar_edu_features (2338325667726857642) -->
+ <skip />
<string name="taskbar_edu_next" msgid="4007618274426775841">"Seuraava"</string>
<string name="taskbar_edu_previous" msgid="459202320127201702">"Takaisin"</string>
<string name="taskbar_edu_close" msgid="887022990168191073">"Sulje"</string>
diff --git a/quickstep/res/values-fr-rCA/strings.xml b/quickstep/res/values-fr-rCA/strings.xml
index cf0fef5..5293ed6 100644
--- a/quickstep/res/values-fr-rCA/strings.xml
+++ b/quickstep/res/values-fr-rCA/strings.xml
@@ -95,9 +95,13 @@
<string name="taskbar_edu_a11y_title" msgid="5417986057866415355">"Informations sur la barre des tâches"</string>
<string name="taskbar_edu_opened" msgid="3950252793551919129">"La barre des tâches éducatives s\'est affichée"</string>
<string name="taskbar_edu_closed" msgid="126643734478892862">"La barre des tâches éducatives est fermée"</string>
- <string name="taskbar_edu_splitscreen" msgid="5563823414110661454">"Faites glisser vers le côté pour utiliser 2 applis à la fois"</string>
+ <!-- no translation found for taskbar_edu_splitscreen (5605512479258053350) -->
+ <skip />
<string name="taskbar_edu_stashing" msgid="2805035263048176462">"Faites glisser vers le haut pour afficher la barre de tâches"</string>
- <string name="taskbar_edu_suggestions" msgid="1416699696825090402">"La barre des tâches suggère des applis selon votre routine"</string>
+ <!-- no translation found for taskbar_edu_suggestions (8215044496435527982) -->
+ <skip />
+ <!-- no translation found for taskbar_edu_features (2338325667726857642) -->
+ <skip />
<string name="taskbar_edu_next" msgid="4007618274426775841">"Suivant"</string>
<string name="taskbar_edu_previous" msgid="459202320127201702">"Retour"</string>
<string name="taskbar_edu_close" msgid="887022990168191073">"Fermer"</string>
diff --git a/quickstep/res/values-fr/strings.xml b/quickstep/res/values-fr/strings.xml
index a20fbc4..cff4659 100644
--- a/quickstep/res/values-fr/strings.xml
+++ b/quickstep/res/values-fr/strings.xml
@@ -95,9 +95,13 @@
<string name="taskbar_edu_a11y_title" msgid="5417986057866415355">"Fonctionnement de la barre des tâches"</string>
<string name="taskbar_edu_opened" msgid="3950252793551919129">"Infos sur la barre des tâches affichées"</string>
<string name="taskbar_edu_closed" msgid="126643734478892862">"Infos sur la barre des tâches fermées"</string>
- <string name="taskbar_edu_splitscreen" msgid="5563823414110661454">"Faites glisser sur le côté pour utiliser 2 applis à la fois"</string>
+ <!-- no translation found for taskbar_edu_splitscreen (5605512479258053350) -->
+ <skip />
<string name="taskbar_edu_stashing" msgid="2805035263048176462">"Balayez rapidement vers haut pour afficher barre des tâches"</string>
- <string name="taskbar_edu_suggestions" msgid="1416699696825090402">"La barre des tâches suggère des applis selon vos habitudes"</string>
+ <!-- no translation found for taskbar_edu_suggestions (8215044496435527982) -->
+ <skip />
+ <!-- no translation found for taskbar_edu_features (2338325667726857642) -->
+ <skip />
<string name="taskbar_edu_next" msgid="4007618274426775841">"Suivant"</string>
<string name="taskbar_edu_previous" msgid="459202320127201702">"Retour"</string>
<string name="taskbar_edu_close" msgid="887022990168191073">"Fermer"</string>
diff --git a/quickstep/res/values-gl/strings.xml b/quickstep/res/values-gl/strings.xml
index 528dd0a..5988433 100644
--- a/quickstep/res/values-gl/strings.xml
+++ b/quickstep/res/values-gl/strings.xml
@@ -95,9 +95,13 @@
<string name="taskbar_edu_a11y_title" msgid="5417986057866415355">"Información sobre a función Barra de tarefas"</string>
<string name="taskbar_edu_opened" msgid="3950252793551919129">"Panel de información de barra de tarefas aberto"</string>
<string name="taskbar_edu_closed" msgid="126643734478892862">"Panel de información de barra de tarefas pechado"</string>
- <string name="taskbar_edu_splitscreen" msgid="5563823414110661454">"Para usar 2 aplicacións á vez, arrastra cara ao lado"</string>
+ <!-- no translation found for taskbar_edu_splitscreen (5605512479258053350) -->
+ <skip />
<string name="taskbar_edu_stashing" msgid="2805035263048176462">"Pasa o dedo un pouco cara arriba para ver a barra de tarefas"</string>
- <string name="taskbar_edu_suggestions" msgid="1416699696825090402">"Na barra de tarefas suxírense apps segundo a túa rutina"</string>
+ <!-- no translation found for taskbar_edu_suggestions (8215044496435527982) -->
+ <skip />
+ <!-- no translation found for taskbar_edu_features (2338325667726857642) -->
+ <skip />
<string name="taskbar_edu_next" msgid="4007618274426775841">"Seguinte"</string>
<string name="taskbar_edu_previous" msgid="459202320127201702">"Atrás"</string>
<string name="taskbar_edu_close" msgid="887022990168191073">"Pechar"</string>
diff --git a/quickstep/res/values-gu/strings.xml b/quickstep/res/values-gu/strings.xml
index 0ae9b03..f5cdbd0 100644
--- a/quickstep/res/values-gu/strings.xml
+++ b/quickstep/res/values-gu/strings.xml
@@ -95,9 +95,10 @@
<string name="taskbar_edu_a11y_title" msgid="5417986057866415355">"ટાસ્કબાર વિશે શિક્ષણ"</string>
<string name="taskbar_edu_opened" msgid="3950252793551919129">"ટાસ્કબારનું શિક્ષણ આપતી પૅનલ દેખાય છે"</string>
<string name="taskbar_edu_closed" msgid="126643734478892862">"ટાસ્કબારનું શિક્ષણ આપતી પૅનલ બંધ થઈ છે"</string>
- <string name="taskbar_edu_splitscreen" msgid="5563823414110661454">"એક જ સમયે 2 ઍપનો ઉપયોગ કરવા માટે, ખેંચીને બાજુ પર લઈ જાઓ"</string>
+ <string name="taskbar_edu_splitscreen" msgid="5605512479258053350">"એક સાથે 2 ઍપનો ઉપયોગ કરવા માટે, ઍપને ખેંચીને બાજુ પર લઈ જાઓ"</string>
<string name="taskbar_edu_stashing" msgid="2805035263048176462">"ટાસ્કબાર બતાવવા માટે ઉપર થોડું સ્વાઇપ કરો"</string>
- <string name="taskbar_edu_suggestions" msgid="1416699696825090402">"ટાસ્કબાર તમારા રૂટિનના આધારે ઍપ સૂચવે છે"</string>
+ <string name="taskbar_edu_suggestions" msgid="8215044496435527982">"તમારા રૂટિનના આધારે ઍપના સુઝાવો મેળવો"</string>
+ <string name="taskbar_edu_features" msgid="2338325667726857642">"ટાસ્કબાર વડે બીજું ઘણું કરો"</string>
<string name="taskbar_edu_next" msgid="4007618274426775841">"આગળ"</string>
<string name="taskbar_edu_previous" msgid="459202320127201702">"પાછળ"</string>
<string name="taskbar_edu_close" msgid="887022990168191073">"બંધ કરો"</string>
diff --git a/quickstep/res/values-hi/strings.xml b/quickstep/res/values-hi/strings.xml
index c9f3930..540530d 100644
--- a/quickstep/res/values-hi/strings.xml
+++ b/quickstep/res/values-hi/strings.xml
@@ -95,9 +95,13 @@
<string name="taskbar_edu_a11y_title" msgid="5417986057866415355">"टास्कबार का ट्यूटोरियल"</string>
<string name="taskbar_edu_opened" msgid="3950252793551919129">"टास्कबार ट्यूटोरियल दिखाया गया"</string>
<string name="taskbar_edu_closed" msgid="126643734478892862">"टास्कबार ट्यूटोरियल बंद किया गया"</string>
- <string name="taskbar_edu_splitscreen" msgid="5563823414110661454">"एक साथ दो ऐप इस्तेमाल करने के लिए, उन्हें किनारे की ओर खींचें और छोड़ें"</string>
+ <!-- no translation found for taskbar_edu_splitscreen (5605512479258053350) -->
+ <skip />
<string name="taskbar_edu_stashing" msgid="2805035263048176462">"टास्कबार दिखाने के लिए, ऊपर की ओर थोड़ा स्वाइप करें"</string>
- <string name="taskbar_edu_suggestions" msgid="1416699696825090402">"टास्कबार, डिवाइस के इस्तेमाल के आधार पर ऐप के सुझाव देता है"</string>
+ <!-- no translation found for taskbar_edu_suggestions (8215044496435527982) -->
+ <skip />
+ <!-- no translation found for taskbar_edu_features (2338325667726857642) -->
+ <skip />
<string name="taskbar_edu_next" msgid="4007618274426775841">"आगे बढ़ें"</string>
<string name="taskbar_edu_previous" msgid="459202320127201702">"वापस जाएं"</string>
<string name="taskbar_edu_close" msgid="887022990168191073">"बंद करें"</string>
diff --git a/quickstep/res/values-hr/strings.xml b/quickstep/res/values-hr/strings.xml
index dd7de8c..e9c6bab 100644
--- a/quickstep/res/values-hr/strings.xml
+++ b/quickstep/res/values-hr/strings.xml
@@ -95,9 +95,10 @@
<string name="taskbar_edu_a11y_title" msgid="5417986057866415355">"Upute za traku sa zadacima"</string>
<string name="taskbar_edu_opened" msgid="3950252793551919129">"Upute za programsku traku su se pojavile"</string>
<string name="taskbar_edu_closed" msgid="126643734478892862">"Upute za programsku traku su zatvorene"</string>
- <string name="taskbar_edu_splitscreen" msgid="5563823414110661454">"Povucite u stranu za istovremeno korištenje 2 aplikacije"</string>
+ <string name="taskbar_edu_splitscreen" msgid="5605512479258053350">"Povucite apl. u stranu radi istodobne upotrebe 2 aplikacije"</string>
<string name="taskbar_edu_stashing" msgid="2805035263048176462">"Kratki pokret prema gore za prikaz trake sa zadacima"</string>
- <string name="taskbar_edu_suggestions" msgid="1416699696825090402">"Traka sa zadacima predlaže aplikacije na temelju vaše rutine"</string>
+ <string name="taskbar_edu_suggestions" msgid="8215044496435527982">"Primajte prijedloge aplikacija na temelju svoje rutine"</string>
+ <string name="taskbar_edu_features" msgid="2338325667726857642">"Učinite više uz pomoć trake sa zadacima"</string>
<string name="taskbar_edu_next" msgid="4007618274426775841">"Dalje"</string>
<string name="taskbar_edu_previous" msgid="459202320127201702">"Natrag"</string>
<string name="taskbar_edu_close" msgid="887022990168191073">"Zatvori"</string>
diff --git a/quickstep/res/values-hu/strings.xml b/quickstep/res/values-hu/strings.xml
index 4d01f69..9646f3e 100644
--- a/quickstep/res/values-hu/strings.xml
+++ b/quickstep/res/values-hu/strings.xml
@@ -95,9 +95,13 @@
<string name="taskbar_edu_a11y_title" msgid="5417986057866415355">"Tálca használatának ismertetése"</string>
<string name="taskbar_edu_opened" msgid="3950252793551919129">"Az eszköztár használatát ismertető panel megjelent"</string>
<string name="taskbar_edu_closed" msgid="126643734478892862">"Az eszköztár használatát ismertető panel bezárult"</string>
- <string name="taskbar_edu_splitscreen" msgid="5563823414110661454">"Húzza oldalra, ha egyszerre két appot szeretne használni"</string>
+ <!-- no translation found for taskbar_edu_splitscreen (5605512479258053350) -->
+ <skip />
<string name="taskbar_edu_stashing" msgid="2805035263048176462">"Röviden csúsztasson fel a Feladatsáv megjelenítéséhez"</string>
- <string name="taskbar_edu_suggestions" msgid="1416699696825090402">"A Feladatsávban a szokásai alapján javasolt appok láthatók"</string>
+ <!-- no translation found for taskbar_edu_suggestions (8215044496435527982) -->
+ <skip />
+ <!-- no translation found for taskbar_edu_features (2338325667726857642) -->
+ <skip />
<string name="taskbar_edu_next" msgid="4007618274426775841">"Tovább"</string>
<string name="taskbar_edu_previous" msgid="459202320127201702">"Vissza"</string>
<string name="taskbar_edu_close" msgid="887022990168191073">"Bezárás"</string>
diff --git a/quickstep/res/values-hy/strings.xml b/quickstep/res/values-hy/strings.xml
index 28f13a9..fa32a31 100644
--- a/quickstep/res/values-hy/strings.xml
+++ b/quickstep/res/values-hy/strings.xml
@@ -95,9 +95,13 @@
<string name="taskbar_edu_a11y_title" msgid="5417986057866415355">"Խնդրագոտու «Կրթություն» պատուհան"</string>
<string name="taskbar_edu_opened" msgid="3950252793551919129">"Խնդրագոտու «Կրթություն» վահանակը բացվեց"</string>
<string name="taskbar_edu_closed" msgid="126643734478892862">"Խնդրագոտու «Կրթություն» վահանակը փակվեց"</string>
- <string name="taskbar_edu_splitscreen" msgid="5563823414110661454">"Քաշեք մի կողմ՝ միաժամանակ 2 հավելված օգտագործելու համար"</string>
+ <!-- no translation found for taskbar_edu_splitscreen (5605512479258053350) -->
+ <skip />
<string name="taskbar_edu_stashing" msgid="2805035263048176462">"Հավելվածների վահանակը բացելու համար մատն արագ սահեցրեք վերև"</string>
- <string name="taskbar_edu_suggestions" msgid="1416699696825090402">"Վահանակն առաջարկում է հավելվածներ ձեր գործողությունների հիման վրա"</string>
+ <!-- no translation found for taskbar_edu_suggestions (8215044496435527982) -->
+ <skip />
+ <!-- no translation found for taskbar_edu_features (2338325667726857642) -->
+ <skip />
<string name="taskbar_edu_next" msgid="4007618274426775841">"Առաջ"</string>
<string name="taskbar_edu_previous" msgid="459202320127201702">"Հետ"</string>
<string name="taskbar_edu_close" msgid="887022990168191073">"Փակել"</string>
diff --git a/quickstep/res/values-in/strings.xml b/quickstep/res/values-in/strings.xml
index 6d42c3d..4e4a3ea 100644
--- a/quickstep/res/values-in/strings.xml
+++ b/quickstep/res/values-in/strings.xml
@@ -95,9 +95,13 @@
<string name="taskbar_edu_a11y_title" msgid="5417986057866415355">"Pengantar Taskbar"</string>
<string name="taskbar_edu_opened" msgid="3950252793551919129">"Edukasi taskbar ditampilkan"</string>
<string name="taskbar_edu_closed" msgid="126643734478892862">"Edukasi taskbar ditutup"</string>
- <string name="taskbar_edu_splitscreen" msgid="5563823414110661454">"Tarik ke samping untuk menggunakan 2 aplikasi sekaligus"</string>
+ <!-- no translation found for taskbar_edu_splitscreen (5605512479258053350) -->
+ <skip />
<string name="taskbar_edu_stashing" msgid="2805035263048176462">"Geser sedikit ke atas untuk menampilkan taskbar"</string>
- <string name="taskbar_edu_suggestions" msgid="1416699696825090402">"Taskbar menyarankan aplikasi berdasarkan rutinitas Anda"</string>
+ <!-- no translation found for taskbar_edu_suggestions (8215044496435527982) -->
+ <skip />
+ <!-- no translation found for taskbar_edu_features (2338325667726857642) -->
+ <skip />
<string name="taskbar_edu_next" msgid="4007618274426775841">"Berikutnya"</string>
<string name="taskbar_edu_previous" msgid="459202320127201702">"Kembali"</string>
<string name="taskbar_edu_close" msgid="887022990168191073">"Tutup"</string>
diff --git a/quickstep/res/values-is/strings.xml b/quickstep/res/values-is/strings.xml
index 1b4ea2b..0a9fa11 100644
--- a/quickstep/res/values-is/strings.xml
+++ b/quickstep/res/values-is/strings.xml
@@ -95,9 +95,10 @@
<string name="taskbar_edu_a11y_title" msgid="5417986057866415355">"Leiðsögn verkefnastiku"</string>
<string name="taskbar_edu_opened" msgid="3950252793551919129">"Leiðsögn verkefnastiku sýnileg"</string>
<string name="taskbar_edu_closed" msgid="126643734478892862">"Leiðsögn verkefnastiku lokað"</string>
- <string name="taskbar_edu_splitscreen" msgid="5563823414110661454">"Dragðu til hliðar til að nota 2 forrit í einu"</string>
+ <string name="taskbar_edu_splitscreen" msgid="5605512479258053350">"Dragðu forrit til hliðar til að nota 2 forrit í einu"</string>
<string name="taskbar_edu_stashing" msgid="2805035263048176462">"Stutt stroka upp til að sýna forritastiku"</string>
- <string name="taskbar_edu_suggestions" msgid="1416699696825090402">"Forritastikan mælir með forritum byggt á rútínunni þinni"</string>
+ <string name="taskbar_edu_suggestions" msgid="8215044496435527982">"Fáðu forritatillögur sem byggjast á rútínunni þinni"</string>
+ <string name="taskbar_edu_features" msgid="2338325667726857642">"Nýttu forritastikuna betur"</string>
<string name="taskbar_edu_next" msgid="4007618274426775841">"Áfram"</string>
<string name="taskbar_edu_previous" msgid="459202320127201702">"Til baka"</string>
<string name="taskbar_edu_close" msgid="887022990168191073">"Loka"</string>
diff --git a/quickstep/res/values-it/strings.xml b/quickstep/res/values-it/strings.xml
index 9a5cc98..0ab984f 100644
--- a/quickstep/res/values-it/strings.xml
+++ b/quickstep/res/values-it/strings.xml
@@ -95,9 +95,10 @@
<string name="taskbar_edu_a11y_title" msgid="5417986057866415355">"Informazioni sulla barra delle applicazioni"</string>
<string name="taskbar_edu_opened" msgid="3950252793551919129">"Riquadro Formazione barra delle applicazioni visualizzato"</string>
<string name="taskbar_edu_closed" msgid="126643734478892862">"Riquadro Formazione barra delle applicazioni chiuso"</string>
- <string name="taskbar_edu_splitscreen" msgid="5563823414110661454">"Trascina di lato per usare 2 app contemporaneamente"</string>
+ <string name="taskbar_edu_splitscreen" msgid="5605512479258053350">"Trascina un\'app di lato per usare due app contemporaneamente"</string>
<string name="taskbar_edu_stashing" msgid="2805035263048176462">"Scorri verso l\'alto per mostrare la barra delle applicazioni"</string>
- <string name="taskbar_edu_suggestions" msgid="1416699696825090402">"Barra delle applicazioni suggerisce app in base alla routine"</string>
+ <string name="taskbar_edu_suggestions" msgid="8215044496435527982">"Ottieni app suggerite in base alla tua routine"</string>
+ <string name="taskbar_edu_features" msgid="2338325667726857642">"Fai di più con la barra delle app"</string>
<string name="taskbar_edu_next" msgid="4007618274426775841">"Avanti"</string>
<string name="taskbar_edu_previous" msgid="459202320127201702">"Indietro"</string>
<string name="taskbar_edu_close" msgid="887022990168191073">"Chiudi"</string>
diff --git a/quickstep/res/values-iw/strings.xml b/quickstep/res/values-iw/strings.xml
index 8722476..cef57e0 100644
--- a/quickstep/res/values-iw/strings.xml
+++ b/quickstep/res/values-iw/strings.xml
@@ -95,9 +95,13 @@
<string name="taskbar_edu_a11y_title" msgid="5417986057866415355">"הסבר על סרגל האפליקציות"</string>
<string name="taskbar_edu_opened" msgid="3950252793551919129">"חלונית ההסברים על שורת המשימות מופיעה"</string>
<string name="taskbar_edu_closed" msgid="126643734478892862">"חלונית ההסברים על שורת המשימות נסגרה"</string>
- <string name="taskbar_edu_splitscreen" msgid="5563823414110661454">"כדי להשתמש בשתי אפליקציות בו-זמנית, צריך לגרור לצד"</string>
+ <!-- no translation found for taskbar_edu_splitscreen (5605512479258053350) -->
+ <skip />
<string name="taskbar_edu_stashing" msgid="2805035263048176462">"צריך להחליק מעט כדי להציג את סרגל האפליקציות"</string>
- <string name="taskbar_edu_suggestions" msgid="1416699696825090402">"האפליקציות מוצעות בסרגל האפליקציות על סמך השימוש השגרתי שלך"</string>
+ <!-- no translation found for taskbar_edu_suggestions (8215044496435527982) -->
+ <skip />
+ <!-- no translation found for taskbar_edu_features (2338325667726857642) -->
+ <skip />
<string name="taskbar_edu_next" msgid="4007618274426775841">"הבא"</string>
<string name="taskbar_edu_previous" msgid="459202320127201702">"חזרה"</string>
<string name="taskbar_edu_close" msgid="887022990168191073">"סגירה"</string>
diff --git a/quickstep/res/values-ja/strings.xml b/quickstep/res/values-ja/strings.xml
index 7bdb5ec..ea3d69b 100644
--- a/quickstep/res/values-ja/strings.xml
+++ b/quickstep/res/values-ja/strings.xml
@@ -95,9 +95,10 @@
<string name="taskbar_edu_a11y_title" msgid="5417986057866415355">"タスクバーの説明"</string>
<string name="taskbar_edu_opened" msgid="3950252793551919129">"タスクバーの説明を開きました"</string>
<string name="taskbar_edu_closed" msgid="126643734478892862">"タスクバーの説明を閉じました"</string>
- <string name="taskbar_edu_splitscreen" msgid="5563823414110661454">"2 個のアプリを同時に使用するには、横にドラッグします"</string>
+ <string name="taskbar_edu_splitscreen" msgid="5605512479258053350">"アプリを横にドラッグして 2 個のアプリを同時に使用できます"</string>
<string name="taskbar_edu_stashing" msgid="2805035263048176462">"タスクバーを表示するには、上に短くスワイプします"</string>
- <string name="taskbar_edu_suggestions" msgid="1416699696825090402">"ルーティンに基づくおすすめのアプリがタスクバーに表示されます"</string>
+ <string name="taskbar_edu_suggestions" msgid="8215044496435527982">"毎日の使用状況に基づいてアプリの候補が表示されます"</string>
+ <string name="taskbar_edu_features" msgid="2338325667726857642">"タスクバーの各種機能"</string>
<string name="taskbar_edu_next" msgid="4007618274426775841">"次へ"</string>
<string name="taskbar_edu_previous" msgid="459202320127201702">"戻る"</string>
<string name="taskbar_edu_close" msgid="887022990168191073">"閉じる"</string>
diff --git a/quickstep/res/values-ka/strings.xml b/quickstep/res/values-ka/strings.xml
index 7259f04..86d369b 100644
--- a/quickstep/res/values-ka/strings.xml
+++ b/quickstep/res/values-ka/strings.xml
@@ -95,9 +95,13 @@
<string name="taskbar_edu_a11y_title" msgid="5417986057866415355">"ამოცანათა ზოლი: განათლება"</string>
<string name="taskbar_edu_opened" msgid="3950252793551919129">"ამოცანების ზოლის სასწავლო არე გამოჩნდა"</string>
<string name="taskbar_edu_closed" msgid="126643734478892862">"ამოცანების ზოლის სასწავლო არე დაიხურა"</string>
- <string name="taskbar_edu_splitscreen" msgid="5563823414110661454">"გადაათრიეთ კიდეზე 2 აპის ერთდროულად გამოსაყენებლად"</string>
+ <!-- no translation found for taskbar_edu_splitscreen (5605512479258053350) -->
+ <skip />
<string name="taskbar_edu_stashing" msgid="2805035263048176462">"მოკლედ გადაფურცლეთ ზემოთ, რომ ამოცანათა ზოლი გამოაჩინოთ"</string>
- <string name="taskbar_edu_suggestions" msgid="1416699696825090402">"ამოცანათა ზოლი გთავაზობთ აპებს თქვენი რუტინის მიხედვით"</string>
+ <!-- no translation found for taskbar_edu_suggestions (8215044496435527982) -->
+ <skip />
+ <!-- no translation found for taskbar_edu_features (2338325667726857642) -->
+ <skip />
<string name="taskbar_edu_next" msgid="4007618274426775841">"შემდეგი"</string>
<string name="taskbar_edu_previous" msgid="459202320127201702">"უკან"</string>
<string name="taskbar_edu_close" msgid="887022990168191073">"დახურვა"</string>
diff --git a/quickstep/res/values-kk/strings.xml b/quickstep/res/values-kk/strings.xml
index d0f6a9a..f4f33ca 100644
--- a/quickstep/res/values-kk/strings.xml
+++ b/quickstep/res/values-kk/strings.xml
@@ -95,9 +95,13 @@
<string name="taskbar_edu_a11y_title" msgid="5417986057866415355">"Тапсырмалар жолағы: үйрену"</string>
<string name="taskbar_edu_opened" msgid="3950252793551919129">"Тапсырмалар тақтасы бойынша нұсқаулық ашылды."</string>
<string name="taskbar_edu_closed" msgid="126643734478892862">"Тапсырмалар тақтасы бойынша нұсқаулық жабылды."</string>
- <string name="taskbar_edu_splitscreen" msgid="5563823414110661454">"Екі қолданбаны бір уақытта пайдалану үшін шетке сүйреңіз."</string>
+ <!-- no translation found for taskbar_edu_splitscreen (5605512479258053350) -->
+ <skip />
<string name="taskbar_edu_stashing" msgid="2805035263048176462">"Тапсырмалар жолағын көру үшін жоғары қарай тез сырғытыңыз."</string>
- <string name="taskbar_edu_suggestions" msgid="1416699696825090402">"Тапсырмалар жолағындағы ұсыныстар әдеттеріңізге негізделеді."</string>
+ <!-- no translation found for taskbar_edu_suggestions (8215044496435527982) -->
+ <skip />
+ <!-- no translation found for taskbar_edu_features (2338325667726857642) -->
+ <skip />
<string name="taskbar_edu_next" msgid="4007618274426775841">"Келесі"</string>
<string name="taskbar_edu_previous" msgid="459202320127201702">"Артқа"</string>
<string name="taskbar_edu_close" msgid="887022990168191073">"Жабу"</string>
diff --git a/quickstep/res/values-km/strings.xml b/quickstep/res/values-km/strings.xml
index f9a7209..6ee5bd7 100644
--- a/quickstep/res/values-km/strings.xml
+++ b/quickstep/res/values-km/strings.xml
@@ -95,9 +95,10 @@
<string name="taskbar_edu_a11y_title" msgid="5417986057866415355">"ការអប់រំលើរបារកិច្ចការ"</string>
<string name="taskbar_edu_opened" msgid="3950252793551919129">"ការបង្រៀនអំពីរបារកិច្ចការបានបង្ហាញ"</string>
<string name="taskbar_edu_closed" msgid="126643734478892862">"ការបង្រៀនអំពីរបារកិច្ចការត្រូវបានបិទ"</string>
- <string name="taskbar_edu_splitscreen" msgid="5563823414110661454">"អូសទៅចំហៀង ដើម្បីប្រើកម្មវិធី 2 ក្នុងពេលតែមួយ"</string>
+ <string name="taskbar_edu_splitscreen" msgid="5605512479258053350">"អូសកម្មវិធីទៅចំហៀង ដើម្បីប្រើកម្មវិធី 2 ក្នុងពេលតែមួយ"</string>
<string name="taskbar_edu_stashing" msgid="2805035263048176462">"អូសឡើងលើបន្តិច ដើម្បីបង្ហាញរបារកិច្ចការ"</string>
- <string name="taskbar_edu_suggestions" msgid="1416699696825090402">"របារកិច្ចការនេះណែនាំកម្មវិធីផ្អែកលើទម្លាប់របស់អ្នក"</string>
+ <string name="taskbar_edu_suggestions" msgid="8215044496435527982">"ទទួលការណែនាំកម្មវិធីដោយផ្អែកលើទម្លាប់របស់អ្នក"</string>
+ <string name="taskbar_edu_features" msgid="2338325667726857642">"ធ្វើបានកាន់តែច្រើនដោយប្រើរបារកិច្ចការ"</string>
<string name="taskbar_edu_next" msgid="4007618274426775841">"បន្ទាប់"</string>
<string name="taskbar_edu_previous" msgid="459202320127201702">"ថយក្រោយ"</string>
<string name="taskbar_edu_close" msgid="887022990168191073">"បិទ"</string>
diff --git a/quickstep/res/values-kn/strings.xml b/quickstep/res/values-kn/strings.xml
index b7c774a..0d7cc2e 100644
--- a/quickstep/res/values-kn/strings.xml
+++ b/quickstep/res/values-kn/strings.xml
@@ -95,9 +95,10 @@
<string name="taskbar_edu_a11y_title" msgid="5417986057866415355">"ಟಾಸ್ಕ್ಬಾರ್ ಶಿಕ್ಷಣ"</string>
<string name="taskbar_edu_opened" msgid="3950252793551919129">"ಟಾಸ್ಕ್ಬಾರ್ ಶಿಕ್ಷಣ ಕಾಣಿಸಿಕೊಂಡಿದೆ"</string>
<string name="taskbar_edu_closed" msgid="126643734478892862">"ಟಾಸ್ಕ್ಬಾರ್ ಶಿಕ್ಷಣ ಮುಚ್ಚಿದೆ"</string>
- <string name="taskbar_edu_splitscreen" msgid="5563823414110661454">"ಏಕಕಾಲದಲ್ಲಿ 2 ಆ್ಯಪ್ಗಳನ್ನು ಬಳಸಲು ಬದಿಗೆ ಡ್ರ್ಯಾಗ್ ಮಾಡಿ"</string>
+ <string name="taskbar_edu_splitscreen" msgid="5605512479258053350">"ಒಂದೇ ಬಾರಿಗೆ 2 ಆ್ಯಪ್ಗಳನ್ನು ಬಳಸಲು ಆ್ಯಪ್ ಅನ್ನು ಬದಿಗೆ ಎಳೆಯಿರಿ"</string>
<string name="taskbar_edu_stashing" msgid="2805035263048176462">"ಟಾಸ್ಕ್ಬಾರ್ ಅನ್ನು ತೋರಿಸಲು ಚಿಕ್ಕದಾಗಿ ಮೇಲಕ್ಕೆ ಸ್ವೈಪ್ ಮಾಡಿ"</string>
- <string name="taskbar_edu_suggestions" msgid="1416699696825090402">"ಟಾಸ್ಕ್ಬಾರ್ ನಿಮ್ಮ ದಿನಚರಿ ಆಧರಿಸಿ ಆ್ಯಪ್ಗಳನ್ನು ಸೂಚಿಸುತ್ತದೆ"</string>
+ <string name="taskbar_edu_suggestions" msgid="8215044496435527982">"ನಿಮ್ಮ ದಿನಚರಿಯ ಆಧಾರದ ಮೇಲೆ ಆ್ಯಪ್ ಸಲಹೆಗಳನ್ನು ಪಡೆಯಿರಿ"</string>
+ <string name="taskbar_edu_features" msgid="2338325667726857642">"ಟಾಸ್ಕ್ಬಾರ್ ಮೂಲಕ ಹೆಚ್ಚಿನದನ್ನು ಮಾಡಿ"</string>
<string name="taskbar_edu_next" msgid="4007618274426775841">"ಮುಂದೆ"</string>
<string name="taskbar_edu_previous" msgid="459202320127201702">"ಹಿಂದೆ"</string>
<string name="taskbar_edu_close" msgid="887022990168191073">"ಮುಚ್ಚಿರಿ"</string>
diff --git a/quickstep/res/values-ko/strings.xml b/quickstep/res/values-ko/strings.xml
index 99309d2..bcf6a4e 100644
--- a/quickstep/res/values-ko/strings.xml
+++ b/quickstep/res/values-ko/strings.xml
@@ -95,9 +95,13 @@
<string name="taskbar_edu_a11y_title" msgid="5417986057866415355">"태스크 바 정보"</string>
<string name="taskbar_edu_opened" msgid="3950252793551919129">"작업 표시줄 튜토리얼 패널 표시됨"</string>
<string name="taskbar_edu_closed" msgid="126643734478892862">"작업 표시줄 튜토리얼 패널 닫힘"</string>
- <string name="taskbar_edu_splitscreen" msgid="5563823414110661454">"옆으로 드래그하여 2개의 앱을 동시에 사용합니다."</string>
+ <!-- no translation found for taskbar_edu_splitscreen (5605512479258053350) -->
+ <skip />
<string name="taskbar_edu_stashing" msgid="2805035263048176462">"위로 짧게 스와이프하여 태스크 바를 표시합니다."</string>
- <string name="taskbar_edu_suggestions" msgid="1416699696825090402">"태스크 바에서 루틴에 따라 앱을 제안합니다."</string>
+ <!-- no translation found for taskbar_edu_suggestions (8215044496435527982) -->
+ <skip />
+ <!-- no translation found for taskbar_edu_features (2338325667726857642) -->
+ <skip />
<string name="taskbar_edu_next" msgid="4007618274426775841">"다음"</string>
<string name="taskbar_edu_previous" msgid="459202320127201702">"뒤로"</string>
<string name="taskbar_edu_close" msgid="887022990168191073">"닫기"</string>
diff --git a/quickstep/res/values-ky/strings.xml b/quickstep/res/values-ky/strings.xml
index bb22c2f..f6177f9 100644
--- a/quickstep/res/values-ky/strings.xml
+++ b/quickstep/res/values-ky/strings.xml
@@ -22,7 +22,7 @@
<string name="recent_task_option_pin" msgid="7929860679018978258">"Кадап коюу"</string>
<string name="recent_task_option_freeform" msgid="48863056265284071">"Эркин форма режими"</string>
<string name="recents_empty_message" msgid="7040467240571714191">"Акыркы колдонмолор жок"</string>
- <string name="accessibility_app_usage_settings" msgid="6312864233673544149">"Колдонмону пайдалануу жөндөөлөрү"</string>
+ <string name="accessibility_app_usage_settings" msgid="6312864233673544149">"Колдонмону пайдалануу параметрлери"</string>
<string name="recents_clear_all" msgid="5328176793634888831">"Баарын тазалоо"</string>
<string name="accessibility_recent_apps" msgid="4058661986695117371">"Акыркы колдонмолор"</string>
<string name="task_view_closed" msgid="9170038230110856166">"Тапшырма жабылды"</string>
@@ -95,9 +95,10 @@
<string name="taskbar_edu_a11y_title" msgid="5417986057866415355">"Тапшырмалар панели жөнүндө маалымат"</string>
<string name="taskbar_edu_opened" msgid="3950252793551919129">"Тапшырмалар тактасынын окутуу панели көрсөтүлдү"</string>
<string name="taskbar_edu_closed" msgid="126643734478892862">"Тапшырмалар тактасынын окутуу панели жабылды"</string>
- <string name="taskbar_edu_splitscreen" msgid="5563823414110661454">"2 колдонмону бир убакта пайдалануу үчүн капталга сүйрөңүз"</string>
+ <string name="taskbar_edu_splitscreen" msgid="5605512479258053350">"2 колдонмону бир убакта пайдалануу үчүн капталга сүйрөңүз"</string>
<string name="taskbar_edu_stashing" msgid="2805035263048176462">"Тапшырмалар тактасын көрүү үчүн экранды өйдө серпиңиз"</string>
- <string name="taskbar_edu_suggestions" msgid="1416699696825090402">"Тапшырмалар тактасы колдонмолорду аракеттериңизге жараша сунуштайт"</string>
+ <string name="taskbar_edu_suggestions" msgid="8215044496435527982">"Программаңыздын негизинде сунушталган колдонмолорду алуу"</string>
+ <string name="taskbar_edu_features" msgid="2338325667726857642">"Тапшырмалар панели менен көбүрөөк нерселерди аткарыңыз"</string>
<string name="taskbar_edu_next" msgid="4007618274426775841">"Кийинки"</string>
<string name="taskbar_edu_previous" msgid="459202320127201702">"Артка"</string>
<string name="taskbar_edu_close" msgid="887022990168191073">"Жабуу"</string>
diff --git a/quickstep/res/values-lo/strings.xml b/quickstep/res/values-lo/strings.xml
index 4be7c8c..963f497 100644
--- a/quickstep/res/values-lo/strings.xml
+++ b/quickstep/res/values-lo/strings.xml
@@ -95,9 +95,13 @@
<string name="taskbar_edu_a11y_title" msgid="5417986057866415355">"ແຖບໜ້າວຽກ Education"</string>
<string name="taskbar_edu_opened" msgid="3950252793551919129">"ສະແດງການສຶກສາແຖບໜ້າວຽກແລ້ວ"</string>
<string name="taskbar_edu_closed" msgid="126643734478892862">"ປິດການສຶກສາແຖບໜ້າວຽກແລ້ວ"</string>
- <string name="taskbar_edu_splitscreen" msgid="5563823414110661454">"ລາກໄປທາງຂ້າງເພື່ອໃຊ້ 2 ແອັບພ້ອມກັນ"</string>
+ <!-- no translation found for taskbar_edu_splitscreen (5605512479258053350) -->
+ <skip />
<string name="taskbar_edu_stashing" msgid="2805035263048176462">"ປັດຂຶ້ນສັ້ນໆເພື່ອສະແດງແຖບໜ້າວຽກ"</string>
- <string name="taskbar_edu_suggestions" msgid="1416699696825090402">"ແຖບໜ້າວຽກຈະແນະນຳແອັບໂດຍອີງຕາມສິ່ງທີ່ເຮັດປະຈຳຂອງທ່ານ"</string>
+ <!-- no translation found for taskbar_edu_suggestions (8215044496435527982) -->
+ <skip />
+ <!-- no translation found for taskbar_edu_features (2338325667726857642) -->
+ <skip />
<string name="taskbar_edu_next" msgid="4007618274426775841">"ຕໍ່ໄປ"</string>
<string name="taskbar_edu_previous" msgid="459202320127201702">"ກັບຄືນ"</string>
<string name="taskbar_edu_close" msgid="887022990168191073">"ປິດ"</string>
diff --git a/quickstep/res/values-lt/strings.xml b/quickstep/res/values-lt/strings.xml
index 56a5d08..b94edb2 100644
--- a/quickstep/res/values-lt/strings.xml
+++ b/quickstep/res/values-lt/strings.xml
@@ -95,9 +95,10 @@
<string name="taskbar_edu_a11y_title" msgid="5417986057866415355">"Užduočių juostos mokomoji informacija"</string>
<string name="taskbar_edu_opened" msgid="3950252793551919129">"Užduočių juostos patarimai rodomi"</string>
<string name="taskbar_edu_closed" msgid="126643734478892862">"Užduočių juostos patarimai uždaryti"</string>
- <string name="taskbar_edu_splitscreen" msgid="5563823414110661454">"Nuvilkite į šoną, kad vienu metu naudotumėte dvi programas"</string>
+ <string name="taskbar_edu_splitscreen" msgid="5605512479258053350">"Nuvilkę programą į šoną vienu metu naudokite dvi programas"</string>
<string name="taskbar_edu_stashing" msgid="2805035263048176462">"Trumpai perbraukite, kad būtų rodoma užduočių juosta"</string>
- <string name="taskbar_edu_suggestions" msgid="1416699696825090402">"Užduočių juostoje siūlomos programos pagal jūsų veiklą"</string>
+ <string name="taskbar_edu_suggestions" msgid="8215044496435527982">"Gaukite programų pasiūlymų pagal savo veiklą"</string>
+ <string name="taskbar_edu_features" msgid="2338325667726857642">"Atlikite daugiau naudodami užduočių juostą"</string>
<string name="taskbar_edu_next" msgid="4007618274426775841">"Kitas"</string>
<string name="taskbar_edu_previous" msgid="459202320127201702">"Atgal"</string>
<string name="taskbar_edu_close" msgid="887022990168191073">"Uždaryti"</string>
diff --git a/quickstep/res/values-lv/strings.xml b/quickstep/res/values-lv/strings.xml
index da911c1..7f6ba09 100644
--- a/quickstep/res/values-lv/strings.xml
+++ b/quickstep/res/values-lv/strings.xml
@@ -95,9 +95,10 @@
<string name="taskbar_edu_a11y_title" msgid="5417986057866415355">"Informācija par uzdevumu joslu"</string>
<string name="taskbar_edu_opened" msgid="3950252793551919129">"Tika atvērta uzdevumjoslas apmācība"</string>
<string name="taskbar_edu_closed" msgid="126643734478892862">"Tika aizvērta uzdevumjoslas apmācība"</string>
- <string name="taskbar_edu_splitscreen" msgid="5563823414110661454">"Velciet uz malu, lai izmantotu divas lietotnes vienlaikus"</string>
+ <string name="taskbar_edu_splitscreen" msgid="5605512479258053350">"Velciet lietotni sānis, lai izmantotu 2 lietotnes vienlaikus"</string>
<string name="taskbar_edu_stashing" msgid="2805035263048176462">"Īsi velciet augšup, lai skatītu uzdevumu joslu"</string>
- <string name="taskbar_edu_suggestions" msgid="1416699696825090402">"Uzdevumu joslā tiek rādītas lietotnes, ņemot vērā lietojumu"</string>
+ <string name="taskbar_edu_suggestions" msgid="8215044496435527982">"Skatiet ieteiktās lietotnes, balstoties uz jūsu ieradumiem"</string>
+ <string name="taskbar_edu_features" msgid="2338325667726857642">"Plašākas iespējas, izmantojot uzdevumu joslu"</string>
<string name="taskbar_edu_next" msgid="4007618274426775841">"Tālāk"</string>
<string name="taskbar_edu_previous" msgid="459202320127201702">"Atpakaļ"</string>
<string name="taskbar_edu_close" msgid="887022990168191073">"Aizvērt"</string>
diff --git a/quickstep/res/values-mk/strings.xml b/quickstep/res/values-mk/strings.xml
index 9deb0dc..07af6dd 100644
--- a/quickstep/res/values-mk/strings.xml
+++ b/quickstep/res/values-mk/strings.xml
@@ -95,9 +95,13 @@
<string name="taskbar_edu_a11y_title" msgid="5417986057866415355">"Обука за лентата со задачи"</string>
<string name="taskbar_edu_opened" msgid="3950252793551919129">"Се појави лентата за задачи за образование"</string>
<string name="taskbar_edu_closed" msgid="126643734478892862">"Затворена е лентата за задачи за образование"</string>
- <string name="taskbar_edu_splitscreen" msgid="5563823414110661454">"Повлечете кон страната за да користите две апликации одеднаш"</string>
+ <!-- no translation found for taskbar_edu_splitscreen (5605512479258053350) -->
+ <skip />
<string name="taskbar_edu_stashing" msgid="2805035263048176462">"Кратко повлечете нагоре за да се прикаже лентата со задачи"</string>
- <string name="taskbar_edu_suggestions" msgid="1416699696825090402">"Лентата со задачи предложува апликации според вашата рутина"</string>
+ <!-- no translation found for taskbar_edu_suggestions (8215044496435527982) -->
+ <skip />
+ <!-- no translation found for taskbar_edu_features (2338325667726857642) -->
+ <skip />
<string name="taskbar_edu_next" msgid="4007618274426775841">"Следно"</string>
<string name="taskbar_edu_previous" msgid="459202320127201702">"Назад"</string>
<string name="taskbar_edu_close" msgid="887022990168191073">"Затвори"</string>
diff --git a/quickstep/res/values-ml/strings.xml b/quickstep/res/values-ml/strings.xml
index bca7e35..3d6648b 100644
--- a/quickstep/res/values-ml/strings.xml
+++ b/quickstep/res/values-ml/strings.xml
@@ -95,9 +95,10 @@
<string name="taskbar_edu_a11y_title" msgid="5417986057866415355">"ടാസ്ക്ബാർ മാർഗ്ഗനിർദ്ദേശ വിൻഡോ"</string>
<string name="taskbar_edu_opened" msgid="3950252793551919129">"ടാസ്ക്ക്ബാർ വിവര പാനൽ ദൃശ്യമായി"</string>
<string name="taskbar_edu_closed" msgid="126643734478892862">"ടാസ്ക്ക്ബാർ വിവര പാനൽ അടച്ചു"</string>
- <string name="taskbar_edu_splitscreen" msgid="5563823414110661454">"ഒരേ സമയം 2 ആപ്പുകൾ ഉപയോഗിക്കാൻ വശത്തേയ്ക്ക് വലിച്ചിടുക"</string>
+ <string name="taskbar_edu_splitscreen" msgid="5605512479258053350">"ഒരേ സമയം 2 ആപ്പുകൾ ഉപയോഗിക്കാൻ ഒരു ആപ്പ് വശത്തേക്ക് വലിച്ചിടൂ"</string>
<string name="taskbar_edu_stashing" msgid="2805035263048176462">"ടാസ്ക്ബാർ ദൃശ്യമാക്കാൻ മുകളിലേക്ക് ചെറുതായി സ്വൈപ്പ് ചെയ്യൂ"</string>
- <string name="taskbar_edu_suggestions" msgid="1416699696825090402">"ടാസ്ക്ബാർ നിങ്ങളുടെ ദിനചര്യ അനുസരിച്ച് ആപ്പുകൾ നിർദ്ദേശിക്കുന്നു"</string>
+ <string name="taskbar_edu_suggestions" msgid="8215044496435527982">"നിങ്ങളുടെ ദിനചര്യ അനുസരിച്ച് ആപ്പ് നിർദ്ദേശങ്ങൾ നേടുക"</string>
+ <string name="taskbar_edu_features" msgid="2338325667726857642">"ടാസ്ക്ബാർ ഉപയോഗിച്ച് കൂടുതൽ ചെയ്യുക"</string>
<string name="taskbar_edu_next" msgid="4007618274426775841">"അടുത്തത്"</string>
<string name="taskbar_edu_previous" msgid="459202320127201702">"മടങ്ങുക"</string>
<string name="taskbar_edu_close" msgid="887022990168191073">"അടയ്ക്കുക"</string>
diff --git a/quickstep/res/values-mn/strings.xml b/quickstep/res/values-mn/strings.xml
index 9ad53c2..f9fd5fb 100644
--- a/quickstep/res/values-mn/strings.xml
+++ b/quickstep/res/values-mn/strings.xml
@@ -95,9 +95,13 @@
<string name="taskbar_edu_a11y_title" msgid="5417986057866415355">"Ажлын хэсгийн боловсрол"</string>
<string name="taskbar_edu_opened" msgid="3950252793551919129">"Боловсролын ажлын талбар гарч ирсэн"</string>
<string name="taskbar_edu_closed" msgid="126643734478892862">"Боловсролын ажлын талбарыг хаасан"</string>
- <string name="taskbar_edu_splitscreen" msgid="5563823414110661454">"2 аппыг зэрэг ашиглахын тулд хажуу тийш чирнэ үү"</string>
+ <!-- no translation found for taskbar_edu_splitscreen (5605512479258053350) -->
+ <skip />
<string name="taskbar_edu_stashing" msgid="2805035263048176462">"Ажлын хэсгийг харуулахын тулд бага зэрэг дээш шударна уу"</string>
- <string name="taskbar_edu_suggestions" msgid="1416699696825090402">"Ажлын хэсэг таны хэвшилд тулгуурлан аппууд санал болгодог"</string>
+ <!-- no translation found for taskbar_edu_suggestions (8215044496435527982) -->
+ <skip />
+ <!-- no translation found for taskbar_edu_features (2338325667726857642) -->
+ <skip />
<string name="taskbar_edu_next" msgid="4007618274426775841">"Дараах"</string>
<string name="taskbar_edu_previous" msgid="459202320127201702">"Буцах"</string>
<string name="taskbar_edu_close" msgid="887022990168191073">"Хаах"</string>
diff --git a/quickstep/res/values-mr/strings.xml b/quickstep/res/values-mr/strings.xml
index ab97cc9..60e5a64 100644
--- a/quickstep/res/values-mr/strings.xml
+++ b/quickstep/res/values-mr/strings.xml
@@ -95,9 +95,13 @@
<string name="taskbar_edu_a11y_title" msgid="5417986057866415355">"टास्कबारशी संबंधित माहिती"</string>
<string name="taskbar_edu_opened" msgid="3950252793551919129">"टास्कबारशी संबंधित माहिती देणारे पॅनल उघडले आहे"</string>
<string name="taskbar_edu_closed" msgid="126643734478892862">"टास्कबारशी संबंधित माहिती देणारे पॅनल बंद केले आहे"</string>
- <string name="taskbar_edu_splitscreen" msgid="5563823414110661454">"दोन ॲप्स एकत्र वापरण्यासाठी, ती बाजूला ड्रॅग करा"</string>
+ <!-- no translation found for taskbar_edu_splitscreen (5605512479258053350) -->
+ <skip />
<string name="taskbar_edu_stashing" msgid="2805035263048176462">"टास्कबार दाखवण्यासाठी थोडे वरती स्वाइप करा"</string>
- <string name="taskbar_edu_suggestions" msgid="1416699696825090402">"टास्कबार हे तुमच्या दिनक्रमानुसार अॅप्स सुचवते"</string>
+ <!-- no translation found for taskbar_edu_suggestions (8215044496435527982) -->
+ <skip />
+ <!-- no translation found for taskbar_edu_features (2338325667726857642) -->
+ <skip />
<string name="taskbar_edu_next" msgid="4007618274426775841">"पुढे"</string>
<string name="taskbar_edu_previous" msgid="459202320127201702">"मागे जा"</string>
<string name="taskbar_edu_close" msgid="887022990168191073">"बंद करा"</string>
diff --git a/quickstep/res/values-ms/strings.xml b/quickstep/res/values-ms/strings.xml
index b7e82d0..7eda4d3 100644
--- a/quickstep/res/values-ms/strings.xml
+++ b/quickstep/res/values-ms/strings.xml
@@ -95,9 +95,10 @@
<string name="taskbar_edu_a11y_title" msgid="5417986057866415355">"Pendidikan bar tugas"</string>
<string name="taskbar_edu_opened" msgid="3950252793551919129">"Pendidikan bar tugas muncul"</string>
<string name="taskbar_edu_closed" msgid="126643734478892862">"Pendidikan bar tugas ditutup"</string>
- <string name="taskbar_edu_splitscreen" msgid="5563823414110661454">"Seret ke tepi untuk menggunakan 2 apl serentak"</string>
+ <string name="taskbar_edu_splitscreen" msgid="5605512479258053350">"Seret apl ke tepi untuk menggunakan 2 apl serentak"</string>
<string name="taskbar_edu_stashing" msgid="2805035263048176462">"Leret pendek ke atas untuk menunjukkan bar tugas"</string>
- <string name="taskbar_edu_suggestions" msgid="1416699696825090402">"Bar tugas mencadangkan apl berdasarkan rutin anda"</string>
+ <string name="taskbar_edu_suggestions" msgid="8215044496435527982">"Dapatkan cadangan apl berdasarkan rutin anda"</string>
+ <string name="taskbar_edu_features" msgid="2338325667726857642">"Lakukan lebih banyak perkara dengan bar tugas"</string>
<string name="taskbar_edu_next" msgid="4007618274426775841">"Seterusnya"</string>
<string name="taskbar_edu_previous" msgid="459202320127201702">"Kembali"</string>
<string name="taskbar_edu_close" msgid="887022990168191073">"Tutup"</string>
diff --git a/quickstep/res/values-my/strings.xml b/quickstep/res/values-my/strings.xml
index a5100f1..b459c60 100644
--- a/quickstep/res/values-my/strings.xml
+++ b/quickstep/res/values-my/strings.xml
@@ -95,9 +95,13 @@
<string name="taskbar_edu_a11y_title" msgid="5417986057866415355">"လုပ်ဆောင်စရာဘား ပညာပေး"</string>
<string name="taskbar_edu_opened" msgid="3950252793551919129">"ပညာရေး လုပ်ဆောင်စရာဘား ပြထားသည်"</string>
<string name="taskbar_edu_closed" msgid="126643734478892862">"ပညာရေး လုပ်ဆောင်စရာဘား ပိတ်ထားသည်"</string>
- <string name="taskbar_edu_splitscreen" msgid="5563823414110661454">"အက်ပ် ၂ ခု တစ်ပြိုင်တည်းသုံးရန် ဘေးဖက်သို့ ဖိဆွဲပါ"</string>
+ <!-- no translation found for taskbar_edu_splitscreen (5605512479258053350) -->
+ <skip />
<string name="taskbar_edu_stashing" msgid="2805035263048176462">"လုပ်ဆောင်စရာဘားပြရန် အမြန် အပေါ်ပွတ်ဆွဲပါ"</string>
- <string name="taskbar_edu_suggestions" msgid="1416699696825090402">"ပုံမှန်အစီအစဉ်ပေါ် အခြေခံ၍ လုပ်ဆောင်စရာဘားက အက်ပ်အကြံပြုသည်"</string>
+ <!-- no translation found for taskbar_edu_suggestions (8215044496435527982) -->
+ <skip />
+ <!-- no translation found for taskbar_edu_features (2338325667726857642) -->
+ <skip />
<string name="taskbar_edu_next" msgid="4007618274426775841">"ရှေ့သို့"</string>
<string name="taskbar_edu_previous" msgid="459202320127201702">"နောက်သို့"</string>
<string name="taskbar_edu_close" msgid="887022990168191073">"ပိတ်ရန်"</string>
diff --git a/quickstep/res/values-nb/strings.xml b/quickstep/res/values-nb/strings.xml
index ce7634b..6b6094f 100644
--- a/quickstep/res/values-nb/strings.xml
+++ b/quickstep/res/values-nb/strings.xml
@@ -95,9 +95,13 @@
<string name="taskbar_edu_a11y_title" msgid="5417986057866415355">"Veiledning for oppgavelinjen"</string>
<string name="taskbar_edu_opened" msgid="3950252793551919129">"Opplæringen for oppgavelinjen vises"</string>
<string name="taskbar_edu_closed" msgid="126643734478892862">"Opplæringen for oppgavelinjen er lukket"</string>
- <string name="taskbar_edu_splitscreen" msgid="5563823414110661454">"Dra til siden for å bruke to apper samtidig"</string>
+ <!-- no translation found for taskbar_edu_splitscreen (5605512479258053350) -->
+ <skip />
<string name="taskbar_edu_stashing" msgid="2805035263048176462">"Kort sveip opp for å vise oppgavelinjen"</string>
- <string name="taskbar_edu_suggestions" msgid="1416699696825090402">"Oppgavelinjen foreslår apper basert på rutinene dine"</string>
+ <!-- no translation found for taskbar_edu_suggestions (8215044496435527982) -->
+ <skip />
+ <!-- no translation found for taskbar_edu_features (2338325667726857642) -->
+ <skip />
<string name="taskbar_edu_next" msgid="4007618274426775841">"Neste"</string>
<string name="taskbar_edu_previous" msgid="459202320127201702">"Tilbake"</string>
<string name="taskbar_edu_close" msgid="887022990168191073">"Lukk"</string>
diff --git a/quickstep/res/values-ne/strings.xml b/quickstep/res/values-ne/strings.xml
index b984de8..2af016e 100644
--- a/quickstep/res/values-ne/strings.xml
+++ b/quickstep/res/values-ne/strings.xml
@@ -95,9 +95,13 @@
<string name="taskbar_edu_a11y_title" msgid="5417986057866415355">"टास्कबार एजुकेसन"</string>
<string name="taskbar_edu_opened" msgid="3950252793551919129">"टास्कबार एजुकेसन देखिएको छ"</string>
<string name="taskbar_edu_closed" msgid="126643734478892862">"टास्कबार एजुकेसन बन्द गरिएको छ"</string>
- <string name="taskbar_edu_splitscreen" msgid="5563823414110661454">"टास्कबार छेउतिर ड्र्याग गरेर एकै पटक २ वटा एप चलाउनुहोस्"</string>
+ <!-- no translation found for taskbar_edu_splitscreen (5605512479258053350) -->
+ <skip />
<string name="taskbar_edu_stashing" msgid="2805035263048176462">"टास्कबार देखाउन माथितिर थोरै स्वाइप गर्नुहोस्"</string>
- <string name="taskbar_edu_suggestions" msgid="1416699696825090402">"टास्कबारले तपाईंको रुटिनका आधारमा एपसम्बन्धी सुझाव देखाउँछ"</string>
+ <!-- no translation found for taskbar_edu_suggestions (8215044496435527982) -->
+ <skip />
+ <!-- no translation found for taskbar_edu_features (2338325667726857642) -->
+ <skip />
<string name="taskbar_edu_next" msgid="4007618274426775841">"अर्को"</string>
<string name="taskbar_edu_previous" msgid="459202320127201702">"पछाडि"</string>
<string name="taskbar_edu_close" msgid="887022990168191073">"बन्द गर्नुहोस्"</string>
diff --git a/quickstep/res/values-nl/strings.xml b/quickstep/res/values-nl/strings.xml
index ad207c0..952b7f1 100644
--- a/quickstep/res/values-nl/strings.xml
+++ b/quickstep/res/values-nl/strings.xml
@@ -95,9 +95,10 @@
<string name="taskbar_edu_a11y_title" msgid="5417986057866415355">"Taakbalk Onderwijs"</string>
<string name="taskbar_edu_opened" msgid="3950252793551919129">"Uitleg van taakbalk geopend"</string>
<string name="taskbar_edu_closed" msgid="126643734478892862">"Uitleg van taakbalk gesloten"</string>
- <string name="taskbar_edu_splitscreen" msgid="5563823414110661454">"Sleep naar de zijkant om 2 apps tegelijk te gebruiken"</string>
+ <string name="taskbar_edu_splitscreen" msgid="5605512479258053350">"Sleep een app naar de zijkant om 2 apps tegelijk te gebruiken"</string>
<string name="taskbar_edu_stashing" msgid="2805035263048176462">"Swipe kort omhoog om de taakbalk te bekijken"</string>
- <string name="taskbar_edu_suggestions" msgid="1416699696825090402">"De taakbalk stelt apps voor op basis van je routine"</string>
+ <string name="taskbar_edu_suggestions" msgid="8215044496435527982">"Krijg app-suggesties op basis van je routine"</string>
+ <string name="taskbar_edu_features" msgid="2338325667726857642">"Doe meer met de taakbalk"</string>
<string name="taskbar_edu_next" msgid="4007618274426775841">"Volgende"</string>
<string name="taskbar_edu_previous" msgid="459202320127201702">"Terug"</string>
<string name="taskbar_edu_close" msgid="887022990168191073">"Sluiten"</string>
diff --git a/quickstep/res/values-or/strings.xml b/quickstep/res/values-or/strings.xml
index 2f0614c..b2f2484 100644
--- a/quickstep/res/values-or/strings.xml
+++ b/quickstep/res/values-or/strings.xml
@@ -95,9 +95,13 @@
<string name="taskbar_edu_a11y_title" msgid="5417986057866415355">"ଟାସ୍କବାର ଶିକ୍ଷା"</string>
<string name="taskbar_edu_opened" msgid="3950252793551919129">"ଟାସ୍କବାର୍ ଶିକ୍ଷା ଦେଖାଯାଇଛି"</string>
<string name="taskbar_edu_closed" msgid="126643734478892862">"ଟାସ୍କବାର୍ ଶିକ୍ଷା ବନ୍ଦ ହୋଇଯାଇଛି"</string>
- <string name="taskbar_edu_splitscreen" msgid="5563823414110661454">"ଥରକେ 2ଟି ଆପ୍ସ ବ୍ୟବହାର କରିବା ପାଇଁ ପାର୍ଶ୍ୱକୁ ଡ୍ରାଗ କରନ୍ତୁ"</string>
+ <!-- no translation found for taskbar_edu_splitscreen (5605512479258053350) -->
+ <skip />
<string name="taskbar_edu_stashing" msgid="2805035263048176462">"ଟାସ୍କବାର ଦେଖାଇବା ପାଇଁ ଉପରକୁ ଅଳ୍ପ ସମୟ ସ୍ୱାଇପ କରନ୍ତୁ"</string>
- <string name="taskbar_edu_suggestions" msgid="1416699696825090402">"ଟାସ୍କବାର ଆପଣଙ୍କ ରୁଟିନ ଆଧାରରେ ଆପ୍ସ ପରାମର୍ଶ ଦିଏ"</string>
+ <!-- no translation found for taskbar_edu_suggestions (8215044496435527982) -->
+ <skip />
+ <!-- no translation found for taskbar_edu_features (2338325667726857642) -->
+ <skip />
<string name="taskbar_edu_next" msgid="4007618274426775841">"ପରବର୍ତ୍ତୀ"</string>
<string name="taskbar_edu_previous" msgid="459202320127201702">"ପଛକୁ ଫେରନ୍ତୁ"</string>
<string name="taskbar_edu_close" msgid="887022990168191073">"ବନ୍ଦ କରନ୍ତୁ"</string>
diff --git a/quickstep/res/values-pa/strings.xml b/quickstep/res/values-pa/strings.xml
index dc9d78e..963486d 100644
--- a/quickstep/res/values-pa/strings.xml
+++ b/quickstep/res/values-pa/strings.xml
@@ -95,9 +95,13 @@
<string name="taskbar_edu_a11y_title" msgid="5417986057866415355">"ਟਾਸਕਬਾਰ ਸਿੱਖਿਆ"</string>
<string name="taskbar_edu_opened" msgid="3950252793551919129">"ਟਾਸਕਵਾਰ ਸਿੱਖਿਆ ਪੈਨਲ ਦਿਖਾਇਆ ਗਿਆ"</string>
<string name="taskbar_edu_closed" msgid="126643734478892862">"ਟਾਸਕਵਾਰ ਸਿੱਖਿਆ ਪੈਨਲ ਬੰਦ ਕੀਤਾ ਗਿਆ"</string>
- <string name="taskbar_edu_splitscreen" msgid="5563823414110661454">"ਇੱਕ ਵਾਰ ਵਿੱਚ 2 ਐਪਾਂ ਵਰਤਣ ਲਈ ਉਨ੍ਹਾਂ ਨੂੰ ਸਾਈਡ ਵੱਲ ਘਸੀਟੋ"</string>
+ <!-- no translation found for taskbar_edu_splitscreen (5605512479258053350) -->
+ <skip />
<string name="taskbar_edu_stashing" msgid="2805035263048176462">"ਟਾਸਕਬਾਰ ਦਿਖਾਉਣ ਲਈ ਥੋੜ੍ਹਾ ਉੱਪਰ ਵੱਲ ਸਵਾਈਪ ਕਰੋ"</string>
- <string name="taskbar_edu_suggestions" msgid="1416699696825090402">"ਟਾਸਕਬਾਰ ਤੁਹਾਡੇ ਨਿਯਮਬੱਧ ਕੰਮ ਮੁਤਾਬਕ ਐਪਾਂ ਦਾ ਸੁਝਾਅ ਦਿੰਦਾ ਹੈ"</string>
+ <!-- no translation found for taskbar_edu_suggestions (8215044496435527982) -->
+ <skip />
+ <!-- no translation found for taskbar_edu_features (2338325667726857642) -->
+ <skip />
<string name="taskbar_edu_next" msgid="4007618274426775841">"ਅੱਗੇ"</string>
<string name="taskbar_edu_previous" msgid="459202320127201702">"ਪਿੱਛੇ"</string>
<string name="taskbar_edu_close" msgid="887022990168191073">"ਬੰਦ ਕਰੋ"</string>
diff --git a/quickstep/res/values-pl/strings.xml b/quickstep/res/values-pl/strings.xml
index 08fc4e2..f9d0853 100644
--- a/quickstep/res/values-pl/strings.xml
+++ b/quickstep/res/values-pl/strings.xml
@@ -95,9 +95,13 @@
<string name="taskbar_edu_a11y_title" msgid="5417986057866415355">"Informacje o pasku aplikacji"</string>
<string name="taskbar_edu_opened" msgid="3950252793551919129">"Wskazówki na temat paska zadań zostały wyświetlone"</string>
<string name="taskbar_edu_closed" msgid="126643734478892862">"Wskazówki na temat paska zadań zostały zamknięte"</string>
- <string name="taskbar_edu_splitscreen" msgid="5563823414110661454">"Przeciągnij w bok, aby używać 2 aplikacji jednocześnie"</string>
+ <!-- no translation found for taskbar_edu_splitscreen (5605512479258053350) -->
+ <skip />
<string name="taskbar_edu_stashing" msgid="2805035263048176462">"Przesuń palcem krótko w górę, aby wyświetlić pasek aplikacji"</string>
- <string name="taskbar_edu_suggestions" msgid="1416699696825090402">"Aplikacje na pasku są dobierane na podstawie Twojej rutyny"</string>
+ <!-- no translation found for taskbar_edu_suggestions (8215044496435527982) -->
+ <skip />
+ <!-- no translation found for taskbar_edu_features (2338325667726857642) -->
+ <skip />
<string name="taskbar_edu_next" msgid="4007618274426775841">"Dalej"</string>
<string name="taskbar_edu_previous" msgid="459202320127201702">"Wstecz"</string>
<string name="taskbar_edu_close" msgid="887022990168191073">"Zamknij"</string>
diff --git a/quickstep/res/values-pt-rPT/strings.xml b/quickstep/res/values-pt-rPT/strings.xml
index b663528..b9bee0c 100644
--- a/quickstep/res/values-pt-rPT/strings.xml
+++ b/quickstep/res/values-pt-rPT/strings.xml
@@ -95,9 +95,10 @@
<string name="taskbar_edu_a11y_title" msgid="5417986057866415355">"Educação da Barra de tarefas"</string>
<string name="taskbar_edu_opened" msgid="3950252793551919129">"Informação da barra de tarefas apresentada"</string>
<string name="taskbar_edu_closed" msgid="126643734478892862">"Informação da barra de tarefas fechada"</string>
- <string name="taskbar_edu_splitscreen" msgid="5563823414110661454">"Arraste para o lado para usar duas apps em simultâneo"</string>
+ <string name="taskbar_edu_splitscreen" msgid="5605512479258053350">"Arraste uma app para o lado para usar 2 apps em simultâneo"</string>
<string name="taskbar_edu_stashing" msgid="2805035263048176462">"Deslize rápido curto para cima para ver a barra de tarefas"</string>
- <string name="taskbar_edu_suggestions" msgid="1416699696825090402">"A barra de tarefas sugere apps baseadas na sua rotina"</string>
+ <string name="taskbar_edu_suggestions" msgid="8215044496435527982">"Obtenha sugestões de apps baseadas na sua rotina"</string>
+ <string name="taskbar_edu_features" msgid="2338325667726857642">"Faça mais com a Barra de tarefas"</string>
<string name="taskbar_edu_next" msgid="4007618274426775841">"Seguinte"</string>
<string name="taskbar_edu_previous" msgid="459202320127201702">"Anterior"</string>
<string name="taskbar_edu_close" msgid="887022990168191073">"Fechar"</string>
diff --git a/quickstep/res/values-pt/strings.xml b/quickstep/res/values-pt/strings.xml
index fbd5b78..77d2079 100644
--- a/quickstep/res/values-pt/strings.xml
+++ b/quickstep/res/values-pt/strings.xml
@@ -95,9 +95,10 @@
<string name="taskbar_edu_a11y_title" msgid="5417986057866415355">"Informações sobre a barra de tarefas"</string>
<string name="taskbar_edu_opened" msgid="3950252793551919129">"As dicas sobre a barra de tarefas foram abertas"</string>
<string name="taskbar_edu_closed" msgid="126643734478892862">"As dicas sobre a barra de tarefas foram fechadas"</string>
- <string name="taskbar_edu_splitscreen" msgid="5563823414110661454">"Arraste para o lado para usar dois apps ao mesmo tempo"</string>
+ <string name="taskbar_edu_splitscreen" msgid="5605512479258053350">"Arraste um app para o lado e use dois apps ao mesmo tempo"</string>
<string name="taskbar_edu_stashing" msgid="2805035263048176462">"Deslize para cima para mostrar a barra de tarefas"</string>
- <string name="taskbar_edu_suggestions" msgid="1416699696825090402">"A barra de tarefas sugere apps com base na sua rotina"</string>
+ <string name="taskbar_edu_suggestions" msgid="8215044496435527982">"Receba sugestões de apps com base na sua rotina"</string>
+ <string name="taskbar_edu_features" msgid="2338325667726857642">"Aproveite ainda mais a barra de tarefas"</string>
<string name="taskbar_edu_next" msgid="4007618274426775841">"Próxima"</string>
<string name="taskbar_edu_previous" msgid="459202320127201702">"Voltar"</string>
<string name="taskbar_edu_close" msgid="887022990168191073">"Fechar"</string>
diff --git a/quickstep/res/values-ro/strings.xml b/quickstep/res/values-ro/strings.xml
index a324d4a..375d431 100644
--- a/quickstep/res/values-ro/strings.xml
+++ b/quickstep/res/values-ro/strings.xml
@@ -95,9 +95,10 @@
<string name="taskbar_edu_a11y_title" msgid="5417986057866415355">"Informații despre bara de activități"</string>
<string name="taskbar_edu_opened" msgid="3950252793551919129">"Panoul cu informații despre bara de activități s-a afișat"</string>
<string name="taskbar_edu_closed" msgid="126643734478892862">"Panoul cu informații despre bara de activități s-a închis"</string>
- <string name="taskbar_edu_splitscreen" msgid="5563823414110661454">"Trage în lateral ca să folosești două aplicații deodată"</string>
+ <string name="taskbar_edu_splitscreen" msgid="5605512479258053350">"Trage în lateral o aplicație ca să folosești 2 aplicații deodată"</string>
<string name="taskbar_edu_stashing" msgid="2805035263048176462">"Glisează scurt în sus pentru a afișa bara de activități"</string>
- <string name="taskbar_edu_suggestions" msgid="1416699696825090402">"Bara de activități sugerează aplicații în funcție de rutina ta"</string>
+ <string name="taskbar_edu_suggestions" msgid="8215044496435527982">"Primește sugestii de aplicații în funcție de rutina ta"</string>
+ <string name="taskbar_edu_features" msgid="2338325667726857642">"Fă mai multe din bara de activități"</string>
<string name="taskbar_edu_next" msgid="4007618274426775841">"Înainte"</string>
<string name="taskbar_edu_previous" msgid="459202320127201702">"Înapoi"</string>
<string name="taskbar_edu_close" msgid="887022990168191073">"Închide"</string>
diff --git a/quickstep/res/values-ru/strings.xml b/quickstep/res/values-ru/strings.xml
index d1c2e8d..f9f38c1 100644
--- a/quickstep/res/values-ru/strings.xml
+++ b/quickstep/res/values-ru/strings.xml
@@ -95,9 +95,10 @@
<string name="taskbar_edu_a11y_title" msgid="5417986057866415355">"Обучение по работе с панелью задач"</string>
<string name="taskbar_edu_opened" msgid="3950252793551919129">"Обучение по работе с панелью задач показано"</string>
<string name="taskbar_edu_closed" msgid="126643734478892862">"Обучение по работе с панелью задач скрыто"</string>
- <string name="taskbar_edu_splitscreen" msgid="5563823414110661454">"Перетащите в сторону, чтобы использовать 2 приложения сразу."</string>
+ <string name="taskbar_edu_splitscreen" msgid="5605512479258053350">"Используйте два приложения сразу, перетащив одно в сторону."</string>
<string name="taskbar_edu_stashing" msgid="2805035263048176462">"Чтобы открыть панель задач, быстро проведите снизу вверх."</string>
- <string name="taskbar_edu_suggestions" msgid="1416699696825090402">"Панель задач предлагает приложения, учитывая ваши действия."</string>
+ <string name="taskbar_edu_suggestions" msgid="8215044496435527982">"Получайте рекомендации, основанные на ваших действиях."</string>
+ <string name="taskbar_edu_features" msgid="2338325667726857642">"Используйте все возможности панели задач"</string>
<string name="taskbar_edu_next" msgid="4007618274426775841">"Далее"</string>
<string name="taskbar_edu_previous" msgid="459202320127201702">"Назад"</string>
<string name="taskbar_edu_close" msgid="887022990168191073">"Закрыть"</string>
diff --git a/quickstep/res/values-si/strings.xml b/quickstep/res/values-si/strings.xml
index e2f0944..6f9734a 100644
--- a/quickstep/res/values-si/strings.xml
+++ b/quickstep/res/values-si/strings.xml
@@ -95,9 +95,13 @@
<string name="taskbar_edu_a11y_title" msgid="5417986057866415355">"කාර්ය තීරු අධ්යාපනය"</string>
<string name="taskbar_edu_opened" msgid="3950252793551919129">"කාර්ය තීරු අධ්යාපනය දිස් විය"</string>
<string name="taskbar_edu_closed" msgid="126643734478892862">"කාර්ය තීරු අධ්යාපනය වසා ඇත"</string>
- <string name="taskbar_edu_splitscreen" msgid="5563823414110661454">"එකවර යෙදුම් 2 ක් භාවිත කිරීමට පැත්තට අදින්න"</string>
+ <!-- no translation found for taskbar_edu_splitscreen (5605512479258053350) -->
+ <skip />
<string name="taskbar_edu_stashing" msgid="2805035263048176462">"කාර්ය තීරුව පෙන්වීමට ඉහළට කෙටි ස්වයිප් කරන්න"</string>
- <string name="taskbar_edu_suggestions" msgid="1416699696825090402">"කාර්ය තීරුව ඔබේ දිනචරියාව මත පදනම්ව යෙදුම් යෝජනා කරයි"</string>
+ <!-- no translation found for taskbar_edu_suggestions (8215044496435527982) -->
+ <skip />
+ <!-- no translation found for taskbar_edu_features (2338325667726857642) -->
+ <skip />
<string name="taskbar_edu_next" msgid="4007618274426775841">"ඊළඟ"</string>
<string name="taskbar_edu_previous" msgid="459202320127201702">"ආපසු"</string>
<string name="taskbar_edu_close" msgid="887022990168191073">"වසන්න"</string>
diff --git a/quickstep/res/values-sk/strings.xml b/quickstep/res/values-sk/strings.xml
index 573c17b..13b175c 100644
--- a/quickstep/res/values-sk/strings.xml
+++ b/quickstep/res/values-sk/strings.xml
@@ -95,9 +95,10 @@
<string name="taskbar_edu_a11y_title" msgid="5417986057866415355">"Panel vzdelávacích aplikácií"</string>
<string name="taskbar_edu_opened" msgid="3950252793551919129">"Zobrazila sa výuka k hlavnému panelu"</string>
<string name="taskbar_edu_closed" msgid="126643734478892862">"Výuka k hlavnému panelu bola zatvorená"</string>
- <string name="taskbar_edu_splitscreen" msgid="5563823414110661454">"Po presunutí na stranu je možné používať dve aplikácie naraz"</string>
+ <string name="taskbar_edu_splitscreen" msgid="5605512479258053350">"Ak chcete použ. dve aplikácie naraz, presuňte aplik. nabok"</string>
<string name="taskbar_edu_stashing" msgid="2805035263048176462">"Krátkym potiahnutím nahor zobrazíte panel aplikácií"</string>
- <string name="taskbar_edu_suggestions" msgid="1416699696825090402">"Panel aplikácií navrhuje aplikácie na základe vašich zvykov"</string>
+ <string name="taskbar_edu_suggestions" msgid="8215044496435527982">"Získavajte návrhy aplikácií na základe svojich zvykov"</string>
+ <string name="taskbar_edu_features" msgid="2338325667726857642">"Panel aplikácií vám ponúka ďalšie možnosti"</string>
<string name="taskbar_edu_next" msgid="4007618274426775841">"Ďalej"</string>
<string name="taskbar_edu_previous" msgid="459202320127201702">"Späť"</string>
<string name="taskbar_edu_close" msgid="887022990168191073">"Zavrieť"</string>
diff --git a/quickstep/res/values-sl/strings.xml b/quickstep/res/values-sl/strings.xml
index 491b13d..3753acf 100644
--- a/quickstep/res/values-sl/strings.xml
+++ b/quickstep/res/values-sl/strings.xml
@@ -95,9 +95,13 @@
<string name="taskbar_edu_a11y_title" msgid="5417986057866415355">"Poučni nasveti o opravilni vrstici"</string>
<string name="taskbar_edu_opened" msgid="3950252793551919129">"Poučni nasveti o opravilni vrstici so prikazani."</string>
<string name="taskbar_edu_closed" msgid="126643734478892862">"Poučni nasveti o opravilni vrstici so zaprti."</string>
- <string name="taskbar_edu_splitscreen" msgid="5563823414110661454">"Povlecite vstran za uporabo dveh aplikacij hkrati."</string>
+ <!-- no translation found for taskbar_edu_splitscreen (5605512479258053350) -->
+ <skip />
<string name="taskbar_edu_stashing" msgid="2805035263048176462">"Na kratko povlecite navzgor za prikaz opravilne vrstice."</string>
- <string name="taskbar_edu_suggestions" msgid="1416699696825090402">"Opravilna vrstica predlaga aplikacije na podlagi vaših navad."</string>
+ <!-- no translation found for taskbar_edu_suggestions (8215044496435527982) -->
+ <skip />
+ <!-- no translation found for taskbar_edu_features (2338325667726857642) -->
+ <skip />
<string name="taskbar_edu_next" msgid="4007618274426775841">"Naprej"</string>
<string name="taskbar_edu_previous" msgid="459202320127201702">"Nazaj"</string>
<string name="taskbar_edu_close" msgid="887022990168191073">"Zapri"</string>
diff --git a/quickstep/res/values-sq/strings.xml b/quickstep/res/values-sq/strings.xml
index d73aa48..0e600dd 100644
--- a/quickstep/res/values-sq/strings.xml
+++ b/quickstep/res/values-sq/strings.xml
@@ -95,9 +95,10 @@
<string name="taskbar_edu_a11y_title" msgid="5417986057866415355">"Edukimi për shiritin e detyrave"</string>
<string name="taskbar_edu_opened" msgid="3950252793551919129">"Edukimi i shiritit të detyrave u shfaq"</string>
<string name="taskbar_edu_closed" msgid="126643734478892862">"Edukimi nga shiriti i detyrave u mbyll"</string>
- <string name="taskbar_edu_splitscreen" msgid="5563823414110661454">"Zvarrit në anë për të përdorur 2 aplikacione njëherësh"</string>
+ <string name="taskbar_edu_splitscreen" msgid="5605512479258053350">"Zvarrit një aplikacion në anë për të përdorur 2 aplikacione njëherësh"</string>
<string name="taskbar_edu_stashing" msgid="2805035263048176462">"Kryej një rrëshqitje të shkurtër lart për të shfaqur shiritin e detyrave"</string>
- <string name="taskbar_edu_suggestions" msgid="1416699696825090402">"Shiriti i detyrave sugjeron aplikacione bazuar në rutinën tënde"</string>
+ <string name="taskbar_edu_suggestions" msgid="8215044496435527982">"Merr sugjerime për aplikacion bazuar në rutinën tënde"</string>
+ <string name="taskbar_edu_features" msgid="2338325667726857642">"Bëj më shumë me shiritin e detyrave"</string>
<string name="taskbar_edu_next" msgid="4007618274426775841">"Para"</string>
<string name="taskbar_edu_previous" msgid="459202320127201702">"Pas"</string>
<string name="taskbar_edu_close" msgid="887022990168191073">"Mbyll"</string>
diff --git a/quickstep/res/values-sr/strings.xml b/quickstep/res/values-sr/strings.xml
index 6e819ab..5c43c01 100644
--- a/quickstep/res/values-sr/strings.xml
+++ b/quickstep/res/values-sr/strings.xml
@@ -95,9 +95,10 @@
<string name="taskbar_edu_a11y_title" msgid="5417986057866415355">"Упутства на траци задатака"</string>
<string name="taskbar_edu_opened" msgid="3950252793551919129">"Едукативно окно из траке задатака се појавило"</string>
<string name="taskbar_edu_closed" msgid="126643734478892862">"Едукативно окно из траке задатака је затворено"</string>
- <string name="taskbar_edu_splitscreen" msgid="5563823414110661454">"Превуците на страну да бисте користили 2 апликације одједном"</string>
+ <string name="taskbar_edu_splitscreen" msgid="5605512479258053350">"Превуците на страну да бисте користили 2 апликације одједном"</string>
<string name="taskbar_edu_stashing" msgid="2805035263048176462">"Накратко превуците нагоре да бисте приказали траку задатака"</string>
- <string name="taskbar_edu_suggestions" msgid="1416699696825090402">"Трака задатака предлаже апликације на основу рутине"</string>
+ <string name="taskbar_edu_suggestions" msgid="8215044496435527982">"Добијајте предлоге апликација на основу рутине"</string>
+ <string name="taskbar_edu_features" msgid="2338325667726857642">"Урадите више помоћу траке задатака"</string>
<string name="taskbar_edu_next" msgid="4007618274426775841">"Даље"</string>
<string name="taskbar_edu_previous" msgid="459202320127201702">"Назад"</string>
<string name="taskbar_edu_close" msgid="887022990168191073">"Затвори"</string>
diff --git a/quickstep/res/values-sv/strings.xml b/quickstep/res/values-sv/strings.xml
index bab1952..387eb69 100644
--- a/quickstep/res/values-sv/strings.xml
+++ b/quickstep/res/values-sv/strings.xml
@@ -95,9 +95,13 @@
<string name="taskbar_edu_a11y_title" msgid="5417986057866415355">"Aktivitetsfältsutbildning"</string>
<string name="taskbar_edu_opened" msgid="3950252793551919129">"Information om aktivitetsfältet visades"</string>
<string name="taskbar_edu_closed" msgid="126643734478892862">"Information om aktivitetsfältet stängdes"</string>
- <string name="taskbar_edu_splitscreen" msgid="5563823414110661454">"Dra till sidan om du vill använda två appar samtidigt"</string>
+ <!-- no translation found for taskbar_edu_splitscreen (5605512479258053350) -->
+ <skip />
<string name="taskbar_edu_stashing" msgid="2805035263048176462">"Svep en kort bit uppåt för att visa aktivitetsfältet"</string>
- <string name="taskbar_edu_suggestions" msgid="1416699696825090402">"I aktivitetsfältet visas förslag på appar utifrån din rutin"</string>
+ <!-- no translation found for taskbar_edu_suggestions (8215044496435527982) -->
+ <skip />
+ <!-- no translation found for taskbar_edu_features (2338325667726857642) -->
+ <skip />
<string name="taskbar_edu_next" msgid="4007618274426775841">"Nästa"</string>
<string name="taskbar_edu_previous" msgid="459202320127201702">"Tillbaka"</string>
<string name="taskbar_edu_close" msgid="887022990168191073">"Stäng"</string>
diff --git a/quickstep/res/values-sw/strings.xml b/quickstep/res/values-sw/strings.xml
index f0990b3..a0360f1 100644
--- a/quickstep/res/values-sw/strings.xml
+++ b/quickstep/res/values-sw/strings.xml
@@ -95,9 +95,13 @@
<string name="taskbar_edu_a11y_title" msgid="5417986057866415355">"Elimu ya Upauzana"</string>
<string name="taskbar_edu_opened" msgid="3950252793551919129">"Paneli ya elimu kwenye upau wa shughuli inaonyeshwa"</string>
<string name="taskbar_edu_closed" msgid="126643734478892862">"Paneli ya elimu kwenye upau wa shughuli imefungwa"</string>
- <string name="taskbar_edu_splitscreen" msgid="5563823414110661454">"Buruta pembeni ili utumie programu 2 kwa wakati mmoja"</string>
+ <!-- no translation found for taskbar_edu_splitscreen (5605512479258053350) -->
+ <skip />
<string name="taskbar_edu_stashing" msgid="2805035263048176462">"Telezesha kidole juu ili uonyeshe upauzana"</string>
- <string name="taskbar_edu_suggestions" msgid="1416699696825090402">"Upauzana hupendekeza programu kulingana na ratiba yako"</string>
+ <!-- no translation found for taskbar_edu_suggestions (8215044496435527982) -->
+ <skip />
+ <!-- no translation found for taskbar_edu_features (2338325667726857642) -->
+ <skip />
<string name="taskbar_edu_next" msgid="4007618274426775841">"Endelea"</string>
<string name="taskbar_edu_previous" msgid="459202320127201702">"Nyuma"</string>
<string name="taskbar_edu_close" msgid="887022990168191073">"Funga"</string>
diff --git a/quickstep/res/values-ta/strings.xml b/quickstep/res/values-ta/strings.xml
index 1db0fab..51aaed1 100644
--- a/quickstep/res/values-ta/strings.xml
+++ b/quickstep/res/values-ta/strings.xml
@@ -95,9 +95,10 @@
<string name="taskbar_edu_a11y_title" msgid="5417986057866415355">"செயல் பட்டியைப் பயன்படுத்தும் விதம்"</string>
<string name="taskbar_edu_opened" msgid="3950252793551919129">"பணிப்பட்டியை எவ்வாறு பயன்படுத்துவது என்பது பற்றிய பலகம் காட்டப்படுகிறது"</string>
<string name="taskbar_edu_closed" msgid="126643734478892862">"பணிப்பட்டியை எவ்வாறு பயன்படுத்துவது என்பது பற்றிய பலகம் மூடப்பட்டது"</string>
- <string name="taskbar_edu_splitscreen" msgid="5563823414110661454">"ஒரே நேரத்தில் 2 ஆப்ஸை உபயோகிக்க பக்கவாட்டிற்கு இழுக்கவும்"</string>
+ <string name="taskbar_edu_splitscreen" msgid="5605512479258053350">"ஒரே நேரத்தில் 2 ஆப்ஸைப் பயன்படுத்தப் பக்கவாட்டில் இழுக்கவும்"</string>
<string name="taskbar_edu_stashing" msgid="2805035263048176462">"செயல் பட்டியைக் காட்டுவதற்கு மேலே சிறிது ஸ்வைப் செய்யவும்"</string>
- <string name="taskbar_edu_suggestions" msgid="1416699696825090402">"உங்கள் வழக்கத்திற்கேற்ப ஆப்ஸை செயல் பட்டி பரிந்துரைக்கும்"</string>
+ <string name="taskbar_edu_suggestions" msgid="8215044496435527982">"உங்கள் வழக்கத்திற்கேற்ப ஆப்ஸ் பரிந்துரைகளைப் பெறுவீர்கள்"</string>
+ <string name="taskbar_edu_features" msgid="2338325667726857642">"செயல் பட்டி மூலம் மேலும் பலவற்றைச் செய்யலாம்"</string>
<string name="taskbar_edu_next" msgid="4007618274426775841">"அடுத்து"</string>
<string name="taskbar_edu_previous" msgid="459202320127201702">"பின்செல்"</string>
<string name="taskbar_edu_close" msgid="887022990168191073">"மூடுக"</string>
diff --git a/quickstep/res/values-te/strings.xml b/quickstep/res/values-te/strings.xml
index c5564dd..e68fbec 100644
--- a/quickstep/res/values-te/strings.xml
+++ b/quickstep/res/values-te/strings.xml
@@ -95,9 +95,10 @@
<string name="taskbar_edu_a11y_title" msgid="5417986057866415355">"టాస్క్బార్ ఎడ్యుకేషన్"</string>
<string name="taskbar_edu_opened" msgid="3950252793551919129">"టాస్క్బార్ శిక్షణకు సంబంధించిన ప్యానెల్ కనిపించింది"</string>
<string name="taskbar_edu_closed" msgid="126643734478892862">"టాస్క్బార్ శిక్షణకు సంబంధించిన ప్యానెల్ మూసివేయబడింది"</string>
- <string name="taskbar_edu_splitscreen" msgid="5563823414110661454">"ఒకేసారి 2 యాప్లను ఉపయోగించడానికి పక్కకు లాగండి"</string>
+ <string name="taskbar_edu_splitscreen" msgid="5605512479258053350">"ఒకేసారి 2 యాప్లను ఉపయోగించడానికి యాప్ను పక్కకు లాగండి"</string>
<string name="taskbar_edu_stashing" msgid="2805035263048176462">"టాస్క్బార్ను చూపడానికి చిన్నగా పైకి స్వైప్ చేయండి"</string>
- <string name="taskbar_edu_suggestions" msgid="1416699696825090402">"మీ రొటీన్ ఆధారంగా టాస్క్బార్ యాప్లను సూచిస్తుంది"</string>
+ <string name="taskbar_edu_suggestions" msgid="8215044496435527982">"మీ రొటీన్ ఆధారంగా యాప్ సూచనలను పొందండి"</string>
+ <string name="taskbar_edu_features" msgid="2338325667726857642">"టాస్క్బార్తో మరిన్ని చేయండి"</string>
<string name="taskbar_edu_next" msgid="4007618274426775841">"తర్వాత"</string>
<string name="taskbar_edu_previous" msgid="459202320127201702">"వెనుకకు"</string>
<string name="taskbar_edu_close" msgid="887022990168191073">"మూసివేయండి"</string>
diff --git a/quickstep/res/values-th/strings.xml b/quickstep/res/values-th/strings.xml
index 7c7f44d..2fa2a34 100644
--- a/quickstep/res/values-th/strings.xml
+++ b/quickstep/res/values-th/strings.xml
@@ -95,9 +95,10 @@
<string name="taskbar_edu_a11y_title" msgid="5417986057866415355">"แถบงาน Education"</string>
<string name="taskbar_edu_opened" msgid="3950252793551919129">"แถบงาน Education ปรากฎขึ้น"</string>
<string name="taskbar_edu_closed" msgid="126643734478892862">"ปิดแถบงาน Education แล้ว"</string>
- <string name="taskbar_edu_splitscreen" msgid="5563823414110661454">"ลากไปด้านข้างเพื่อใช้ 2 แอปพร้อมกัน"</string>
+ <string name="taskbar_edu_splitscreen" msgid="5605512479258053350">"ลากแอปไปด้านข้างเพื่อใช้ 2 แอปพร้อมกัน"</string>
<string name="taskbar_edu_stashing" msgid="2805035263048176462">"ปัดขึ้นสั้นๆ เพื่อแสดงแถบงาน"</string>
- <string name="taskbar_edu_suggestions" msgid="1416699696825090402">"แถบงานจะแนะนำแอปโดยอิงตามกิจวัตรของคุณ"</string>
+ <string name="taskbar_edu_suggestions" msgid="8215044496435527982">"รับคำแนะนำเกี่ยวกับแอปตามกิจวัตรของคุณ"</string>
+ <string name="taskbar_edu_features" msgid="2338325667726857642">"ทำสิ่งต่างๆ ได้มากขึ้นด้วยแถบงาน"</string>
<string name="taskbar_edu_next" msgid="4007618274426775841">"ถัดไป"</string>
<string name="taskbar_edu_previous" msgid="459202320127201702">"กลับ"</string>
<string name="taskbar_edu_close" msgid="887022990168191073">"ปิด"</string>
diff --git a/quickstep/res/values-tl/strings.xml b/quickstep/res/values-tl/strings.xml
index 7dcae6b..4c2d5ec 100644
--- a/quickstep/res/values-tl/strings.xml
+++ b/quickstep/res/values-tl/strings.xml
@@ -95,9 +95,10 @@
<string name="taskbar_edu_a11y_title" msgid="5417986057866415355">"Impormasyon sa taskbar"</string>
<string name="taskbar_edu_opened" msgid="3950252793551919129">"Lumabas ang edukasyon sa taskbar"</string>
<string name="taskbar_edu_closed" msgid="126643734478892862">"Sarado ang edukasyon sa taskbar"</string>
- <string name="taskbar_edu_splitscreen" msgid="5563823414110661454">"I-drag sa gilid para makagamit ng 2 app nang sabay"</string>
+ <string name="taskbar_edu_splitscreen" msgid="5605512479258053350">"Mag-drag ng app sa gilid para makagamit ng 2 app nang sabay"</string>
<string name="taskbar_edu_stashing" msgid="2805035263048176462">"Mag-swipe nang bahagya pataas para ipakita ang taskbar"</string>
- <string name="taskbar_edu_suggestions" msgid="1416699696825090402">"Nagmumungkahi ang taskbar ng mga app batay sa iyong routine"</string>
+ <string name="taskbar_edu_suggestions" msgid="8215044496435527982">"Makakuha ng mga iminumungkahing app batay sa iyong routine"</string>
+ <string name="taskbar_edu_features" msgid="2338325667726857642">"Gumawa ng higit pa sa taskbar"</string>
<string name="taskbar_edu_next" msgid="4007618274426775841">"Susunod"</string>
<string name="taskbar_edu_previous" msgid="459202320127201702">"Bumalik"</string>
<string name="taskbar_edu_close" msgid="887022990168191073">"Isara"</string>
diff --git a/quickstep/res/values-tr/strings.xml b/quickstep/res/values-tr/strings.xml
index ea3fb5e..3347074 100644
--- a/quickstep/res/values-tr/strings.xml
+++ b/quickstep/res/values-tr/strings.xml
@@ -95,9 +95,13 @@
<string name="taskbar_edu_a11y_title" msgid="5417986057866415355">"Görev çubuğu eğitimi"</string>
<string name="taskbar_edu_opened" msgid="3950252793551919129">"Görev çubuğu eğitimi görüntülendi"</string>
<string name="taskbar_edu_closed" msgid="126643734478892862">"Görev çubuğu eğitimi kapatıldı"</string>
- <string name="taskbar_edu_splitscreen" msgid="5563823414110661454">"Tek seferde iki uygulamayı kullanmak için yana sürükleyin"</string>
+ <!-- no translation found for taskbar_edu_splitscreen (5605512479258053350) -->
+ <skip />
<string name="taskbar_edu_stashing" msgid="2805035263048176462">"Görev çubuğunu göstermek için yukarı doğru kısa kaydırın"</string>
- <string name="taskbar_edu_suggestions" msgid="1416699696825090402">"Görev çubuğu, rutininize dayalı olarak uygulamalar önerir"</string>
+ <!-- no translation found for taskbar_edu_suggestions (8215044496435527982) -->
+ <skip />
+ <!-- no translation found for taskbar_edu_features (2338325667726857642) -->
+ <skip />
<string name="taskbar_edu_next" msgid="4007618274426775841">"İleri"</string>
<string name="taskbar_edu_previous" msgid="459202320127201702">"Geri"</string>
<string name="taskbar_edu_close" msgid="887022990168191073">"Kapat"</string>
diff --git a/quickstep/res/values-uk/strings.xml b/quickstep/res/values-uk/strings.xml
index b426c8b..ee0314b 100644
--- a/quickstep/res/values-uk/strings.xml
+++ b/quickstep/res/values-uk/strings.xml
@@ -95,9 +95,13 @@
<string name="taskbar_edu_a11y_title" msgid="5417986057866415355">"Панель завдань Education"</string>
<string name="taskbar_edu_opened" msgid="3950252793551919129">"Панель завдань Education відкрито"</string>
<string name="taskbar_edu_closed" msgid="126643734478892862">"Панель завдань Education закрито"</string>
- <string name="taskbar_edu_splitscreen" msgid="5563823414110661454">"Перетягніть убік, щоб використовувати 2 додатки одночасно"</string>
+ <!-- no translation found for taskbar_edu_splitscreen (5605512479258053350) -->
+ <skip />
<string name="taskbar_edu_stashing" msgid="2805035263048176462">"Швидко проведіть пальцем угору, щоб відкрити панель завдань"</string>
- <string name="taskbar_edu_suggestions" msgid="1416699696825090402">"Панель завдань пропонує додатки на основі вашої програми"</string>
+ <!-- no translation found for taskbar_edu_suggestions (8215044496435527982) -->
+ <skip />
+ <!-- no translation found for taskbar_edu_features (2338325667726857642) -->
+ <skip />
<string name="taskbar_edu_next" msgid="4007618274426775841">"Далі"</string>
<string name="taskbar_edu_previous" msgid="459202320127201702">"Назад"</string>
<string name="taskbar_edu_close" msgid="887022990168191073">"Закрити"</string>
diff --git a/quickstep/res/values-ur/strings.xml b/quickstep/res/values-ur/strings.xml
index 576386a..4ddcb3b 100644
--- a/quickstep/res/values-ur/strings.xml
+++ b/quickstep/res/values-ur/strings.xml
@@ -95,9 +95,10 @@
<string name="taskbar_edu_a11y_title" msgid="5417986057866415355">"ٹاسک بار کی تعلیم"</string>
<string name="taskbar_edu_opened" msgid="3950252793551919129">"ٹاکس بار کا تعلیمی پینل ظاہر ہو گیا"</string>
<string name="taskbar_edu_closed" msgid="126643734478892862">"ٹاسک بار کا تعلیمی پینل بند ہو گیا"</string>
- <string name="taskbar_edu_splitscreen" msgid="5563823414110661454">"ایک وقت میں 2 ایپس استعمال کرنے کے لیے سائیڈ پر گھسیٹیں"</string>
+ <string name="taskbar_edu_splitscreen" msgid="5605512479258053350">"ایک وقت میں 2 ایپس استعمال کرنے کیلئے ایپ سائیڈ پر گھسیٹیں"</string>
<string name="taskbar_edu_stashing" msgid="2805035263048176462">"ٹاسک بار دکھانے کے لیے تھوڑا اوپر سوائپ کریں"</string>
- <string name="taskbar_edu_suggestions" msgid="1416699696825090402">"ٹاسک بار آپ کی روٹین کی بنیاد پر ایپس تجویز کرتا ہے"</string>
+ <string name="taskbar_edu_suggestions" msgid="8215044496435527982">"اپنی روٹین پر مبنی ایپس کی تجاویز حاصل کریں"</string>
+ <string name="taskbar_edu_features" msgid="2338325667726857642">"ٹاسک بار سے بہت کچھ کریں"</string>
<string name="taskbar_edu_next" msgid="4007618274426775841">"آگے"</string>
<string name="taskbar_edu_previous" msgid="459202320127201702">"پیچھے"</string>
<string name="taskbar_edu_close" msgid="887022990168191073">"بند کریں"</string>
diff --git a/quickstep/res/values-uz/strings.xml b/quickstep/res/values-uz/strings.xml
index 65197a4..f188000 100644
--- a/quickstep/res/values-uz/strings.xml
+++ b/quickstep/res/values-uz/strings.xml
@@ -95,9 +95,10 @@
<string name="taskbar_edu_a11y_title" msgid="5417986057866415355">"Vazifalar paneli qoʻllanmasi"</string>
<string name="taskbar_edu_opened" msgid="3950252793551919129">"Taʼlim vazifalar paneli chiqdi"</string>
<string name="taskbar_edu_closed" msgid="126643734478892862">"Taʼlim vazifalar paneli yopildi"</string>
- <string name="taskbar_edu_splitscreen" msgid="5563823414110661454">"Bir vaqtda 2 ta ilova ochish uchun birini yoniga torting"</string>
+ <string name="taskbar_edu_splitscreen" msgid="5605512479258053350">"Bitta ilovani yon tomonga sudrab, bir vaqtda 2 ta ilovadan foydalaning."</string>
<string name="taskbar_edu_stashing" msgid="2805035263048176462">"Vazifalar panelini koʻrsatish uchun tepaga qisqa suring"</string>
- <string name="taskbar_edu_suggestions" msgid="1416699696825090402">"Vazifalar paneli harakatlaringiz asosida ilova taklif qiladi"</string>
+ <string name="taskbar_edu_suggestions" msgid="8215044496435527982">"Harakatlaringiz asosida tavsiyalar oling."</string>
+ <string name="taskbar_edu_features" msgid="2338325667726857642">"Vazifalar panelidan maksimal darajada foydalaning"</string>
<string name="taskbar_edu_next" msgid="4007618274426775841">"Keyingisi"</string>
<string name="taskbar_edu_previous" msgid="459202320127201702">"Orqaga"</string>
<string name="taskbar_edu_close" msgid="887022990168191073">"Yopish"</string>
diff --git a/quickstep/res/values-vi/strings.xml b/quickstep/res/values-vi/strings.xml
index b0a6dab..5591c52 100644
--- a/quickstep/res/values-vi/strings.xml
+++ b/quickstep/res/values-vi/strings.xml
@@ -95,9 +95,13 @@
<string name="taskbar_edu_a11y_title" msgid="5417986057866415355">"Cách sử dụng thanh tác vụ"</string>
<string name="taskbar_edu_opened" msgid="3950252793551919129">"Đã hiện bảng hướng dẫn trên thanh tác vụ"</string>
<string name="taskbar_edu_closed" msgid="126643734478892862">"Đã đóng bảng hướng dẫn trên thanh tác vụ"</string>
- <string name="taskbar_edu_splitscreen" msgid="5563823414110661454">"Kéo sang bên để dùng 2 ứng dụng cùng một lúc"</string>
+ <!-- no translation found for taskbar_edu_splitscreen (5605512479258053350) -->
+ <skip />
<string name="taskbar_edu_stashing" msgid="2805035263048176462">"Vuốt lên một chút để hiển thị thanh tác vụ"</string>
- <string name="taskbar_edu_suggestions" msgid="1416699696825090402">"Thanh tác vụ đề xuất các ứng dụng dựa trên thói quen của bạn"</string>
+ <!-- no translation found for taskbar_edu_suggestions (8215044496435527982) -->
+ <skip />
+ <!-- no translation found for taskbar_edu_features (2338325667726857642) -->
+ <skip />
<string name="taskbar_edu_next" msgid="4007618274426775841">"Tiếp theo"</string>
<string name="taskbar_edu_previous" msgid="459202320127201702">"Quay lại"</string>
<string name="taskbar_edu_close" msgid="887022990168191073">"Đóng"</string>
diff --git a/quickstep/res/values-zh-rCN/strings.xml b/quickstep/res/values-zh-rCN/strings.xml
index 6b8f3e3..c15c40d 100644
--- a/quickstep/res/values-zh-rCN/strings.xml
+++ b/quickstep/res/values-zh-rCN/strings.xml
@@ -95,9 +95,13 @@
<string name="taskbar_edu_a11y_title" msgid="5417986057866415355">"任务栏教程"</string>
<string name="taskbar_edu_opened" msgid="3950252793551919129">"任务栏教程已显示"</string>
<string name="taskbar_edu_closed" msgid="126643734478892862">"任务栏教程已关闭"</string>
- <string name="taskbar_edu_splitscreen" msgid="5563823414110661454">"拖动到一侧,即可一次使用两个应用"</string>
+ <!-- no translation found for taskbar_edu_splitscreen (5605512479258053350) -->
+ <skip />
<string name="taskbar_edu_stashing" msgid="2805035263048176462">"稍微向上滑动即可显示任务栏"</string>
- <string name="taskbar_edu_suggestions" msgid="1416699696825090402">"任务栏会根据您的日常安排向您推荐应用"</string>
+ <!-- no translation found for taskbar_edu_suggestions (8215044496435527982) -->
+ <skip />
+ <!-- no translation found for taskbar_edu_features (2338325667726857642) -->
+ <skip />
<string name="taskbar_edu_next" msgid="4007618274426775841">"继续"</string>
<string name="taskbar_edu_previous" msgid="459202320127201702">"返回"</string>
<string name="taskbar_edu_close" msgid="887022990168191073">"关闭"</string>
diff --git a/quickstep/res/values-zh-rHK/strings.xml b/quickstep/res/values-zh-rHK/strings.xml
index 5a9e0a1..cefea7a 100644
--- a/quickstep/res/values-zh-rHK/strings.xml
+++ b/quickstep/res/values-zh-rHK/strings.xml
@@ -95,9 +95,10 @@
<string name="taskbar_edu_a11y_title" msgid="5417986057866415355">"工作列教學"</string>
<string name="taskbar_edu_opened" msgid="3950252793551919129">"顯示咗工作列教學"</string>
<string name="taskbar_edu_closed" msgid="126643734478892862">"閂咗工作列教學"</string>
- <string name="taskbar_edu_splitscreen" msgid="5563823414110661454">"拖曳到一邊即可同時使用 2 個應用程式"</string>
+ <string name="taskbar_edu_splitscreen" msgid="5605512479258053350">"將應用程式拖曳到一邊,即可同時使用 2 個應用程式"</string>
<string name="taskbar_edu_stashing" msgid="2805035263048176462">"輕輕向上滑動即可顯示工作列"</string>
- <string name="taskbar_edu_suggestions" msgid="1416699696825090402">"工作列會根據您的日常安排提供應用程式建議"</string>
+ <string name="taskbar_edu_suggestions" msgid="8215044496435527982">"根據您的日常安排提供應用程式建議"</string>
+ <string name="taskbar_edu_features" msgid="2338325667726857642">"工作列助您事半功倍"</string>
<string name="taskbar_edu_next" msgid="4007618274426775841">"繼續"</string>
<string name="taskbar_edu_previous" msgid="459202320127201702">"返回"</string>
<string name="taskbar_edu_close" msgid="887022990168191073">"關閉"</string>
diff --git a/quickstep/res/values-zh-rTW/strings.xml b/quickstep/res/values-zh-rTW/strings.xml
index 30ea100..28cf4fc 100644
--- a/quickstep/res/values-zh-rTW/strings.xml
+++ b/quickstep/res/values-zh-rTW/strings.xml
@@ -95,9 +95,13 @@
<string name="taskbar_edu_a11y_title" msgid="5417986057866415355">"工作列教學課程"</string>
<string name="taskbar_edu_opened" msgid="3950252793551919129">"工作列教學課程已顯示"</string>
<string name="taskbar_edu_closed" msgid="126643734478892862">"工作列教學課程已關閉"</string>
- <string name="taskbar_edu_splitscreen" msgid="5563823414110661454">"拖曳到一邊即可同時使用 2 個應用程式"</string>
+ <!-- no translation found for taskbar_edu_splitscreen (5605512479258053350) -->
+ <skip />
<string name="taskbar_edu_stashing" msgid="2805035263048176462">"稍微向上滑動即可讓工作列顯示在畫面上"</string>
- <string name="taskbar_edu_suggestions" msgid="1416699696825090402">"工作列會根據你的日常習慣提供應用程式建議"</string>
+ <!-- no translation found for taskbar_edu_suggestions (8215044496435527982) -->
+ <skip />
+ <!-- no translation found for taskbar_edu_features (2338325667726857642) -->
+ <skip />
<string name="taskbar_edu_next" msgid="4007618274426775841">"繼續"</string>
<string name="taskbar_edu_previous" msgid="459202320127201702">"返回"</string>
<string name="taskbar_edu_close" msgid="887022990168191073">"關閉"</string>
diff --git a/quickstep/res/values-zu/strings.xml b/quickstep/res/values-zu/strings.xml
index 0a7e418..18b8efb 100644
--- a/quickstep/res/values-zu/strings.xml
+++ b/quickstep/res/values-zu/strings.xml
@@ -95,9 +95,13 @@
<string name="taskbar_edu_a11y_title" msgid="5417986057866415355">"Imfundo ye-taskbar"</string>
<string name="taskbar_edu_opened" msgid="3950252793551919129">"Imfuno yebha yomsebenzi ivelile"</string>
<string name="taskbar_edu_closed" msgid="126643734478892862">"Imfundo yebha yomsebenzi ivaliwe"</string>
- <string name="taskbar_edu_splitscreen" msgid="5563823414110661454">"Hudula ngaseceleni ukuze usebenzise ama-app angu-2 ngesikhathi esisodwa"</string>
+ <!-- no translation found for taskbar_edu_splitscreen (5605512479258053350) -->
+ <skip />
<string name="taskbar_edu_stashing" msgid="2805035263048176462">"Swayiphela phezulu okufushane ukuze ubonise i-taskbar"</string>
- <string name="taskbar_edu_suggestions" msgid="1416699696825090402">"I-taskbar iphakamisa ama-app ezisuselwe kumjikelezo wakho"</string>
+ <!-- no translation found for taskbar_edu_suggestions (8215044496435527982) -->
+ <skip />
+ <!-- no translation found for taskbar_edu_features (2338325667726857642) -->
+ <skip />
<string name="taskbar_edu_next" msgid="4007618274426775841">"Okulandelayo"</string>
<string name="taskbar_edu_previous" msgid="459202320127201702">"Emuva"</string>
<string name="taskbar_edu_close" msgid="887022990168191073">"Vala"</string>
diff --git a/quickstep/res/values/strings.xml b/quickstep/res/values/strings.xml
index 761934e..4f30791 100644
--- a/quickstep/res/values/strings.xml
+++ b/quickstep/res/values/strings.xml
@@ -231,20 +231,20 @@
<string name="accessibility_rotate_button">Rotate screen</string>
<!-- ******* Taskbar Edu ******* -->
- <!-- Accessibility title for the taskbar education window. [CHAR_LIMIT=NONE] -->
+ <!-- Accessibility title for the Taskbar education window. [CHAR_LIMIT=NONE] -->
<string name="taskbar_edu_a11y_title">Taskbar education</string>
- <!-- Accessibility text spoken when the taskbar education panel appears [CHAR_LIMIT=NONE] -->
+ <!-- Accessibility text spoken when the Taskbar education panel appears [CHAR_LIMIT=NONE] -->
<string name="taskbar_edu_opened">Taskbar education appeared</string>
- <!-- Accessibility text spoken when the taskbar education panel disappears [CHAR_LIMIT=NONE] -->
+ <!-- Accessibility text spoken when the Taskbar education panel disappears [CHAR_LIMIT=NONE] -->
<string name="taskbar_edu_closed">Taskbar education closed</string>
- <!-- Text in dialog that lets a user know how they can use the taskbar to use multiple apps at once on their device. [CHAR_LIMIT=60] -->
+ <!-- Text in dialog that lets a user know how they can use the Taskbar to use multiple apps at once on their device. [CHAR_LIMIT=60] -->
<string name="taskbar_edu_splitscreen">Drag an app to the side to use 2 apps at once</string>
- <!-- Text in dialog that lets a user know how they can show the taskbar on their device. [CHAR_LIMIT=60] -->
- <string name="taskbar_edu_stashing">Short swipe up to show the taskbar</string>
- <!-- Text in dialog that lets a user know how the taskbar suggests apps based on their usage. [CHAR_LIMIT=60] -->
+ <!-- Text in dialog that lets a user know how they can show the Taskbar on their device. [CHAR_LIMIT=60] -->
+ <string name="taskbar_edu_stashing">Slow swipe up to show the Taskbar</string>
+ <!-- Text in dialog that lets a user know how the Taskbar suggests apps based on their usage. [CHAR_LIMIT=60] -->
<string name="taskbar_edu_suggestions">Get app suggestions based on your routine</string>
- <!-- Title in dialog that shows a user what they can do with the taskbar. [CHAR_LIMIT=60] -->
- <string name="taskbar_edu_features">Do more with the taskbar</string>
+ <!-- Title in dialog that shows a user what they can do with the Taskbar. [CHAR_LIMIT=60] -->
+ <string name="taskbar_edu_features">Do more with the Taskbar</string>
<!-- Text on button to go to the next screen of a tutorial [CHAR_LIMIT=16] -->
<string name="taskbar_edu_next">Next</string>
<!-- Text on button to go to the previous screen of a tutorial [CHAR_LIMIT=16] -->
@@ -267,13 +267,13 @@
<string name="taskbar_button_notifications">Notifications</string>
<!-- Content description for quick settings button [CHAR_LIMIT=16] -->
<string name="taskbar_button_quick_settings">Quick Settings</string>
- <!-- Accessibility title for the taskbar window. [CHAR_LIMIT=NONE] -->
+ <!-- Accessibility title for the Taskbar window. [CHAR_LIMIT=NONE] -->
<string name="taskbar_a11y_title">Taskbar</string>
- <!-- Accessibility title for the taskbar window on phones. [CHAR_LIMIT=NONE] -->
+ <!-- Accessibility title for the Taskbar window on phones. [CHAR_LIMIT=NONE] -->
<string name="taskbar_phone_a11y_title">Navigation bar</string>
- <!-- Label for moving drop target to the top or left side of the screen, depending on orientation (from the taskbar only). -->
+ <!-- Label for moving drop target to the top or left side of the screen, depending on orientation (from the Taskbar only). -->
<string name="move_drop_target_top_or_left">Move to top/left</string>
- <!-- Label for moving drop target to the bottom or right side of the screen, depending on orientation (from the taskbar only). -->
+ <!-- Label for moving drop target to the bottom or right side of the screen, depending on orientation (from the Taskbar only). -->
<string name="move_drop_target_bottom_or_right">Move to bottom/right</string>
</resources>
diff --git a/quickstep/src/com/android/launcher3/model/WellbeingModel.java b/quickstep/src/com/android/launcher3/model/WellbeingModel.java
index fb2d0dc..d8fd51a 100644
--- a/quickstep/src/com/android/launcher3/model/WellbeingModel.java
+++ b/quickstep/src/com/android/launcher3/model/WellbeingModel.java
@@ -18,6 +18,8 @@
import static android.content.ContentResolver.SCHEME_CONTENT;
+import static com.android.launcher3.util.SimpleBroadcastReceiver.getPackageFilter;
+
import android.annotation.TargetApi;
import android.app.RemoteAction;
import android.content.ContentProviderClient;
@@ -55,7 +57,6 @@
import com.android.launcher3.popup.SystemShortcut;
import com.android.launcher3.util.BgObjectWithLooper;
import com.android.launcher3.util.MainThreadInitializedObject;
-import com.android.launcher3.util.PackageManagerHelper;
import com.android.launcher3.util.Preconditions;
import com.android.launcher3.util.SimpleBroadcastReceiver;
@@ -117,7 +118,7 @@
if (!TextUtils.isEmpty(mWellbeingProviderPkg)) {
mContext.registerReceiver(
new SimpleBroadcastReceiver(t -> restartObserver()),
- PackageManagerHelper.getPackageFilter(mWellbeingProviderPkg,
+ getPackageFilter(mWellbeingProviderPkg,
Intent.ACTION_PACKAGE_ADDED, Intent.ACTION_PACKAGE_CHANGED,
Intent.ACTION_PACKAGE_REMOVED, Intent.ACTION_PACKAGE_DATA_CLEARED,
Intent.ACTION_PACKAGE_RESTARTED),
diff --git a/quickstep/src/com/android/launcher3/taskbar/TaskbarDragLayer.java b/quickstep/src/com/android/launcher3/taskbar/TaskbarDragLayer.java
index d0059f7..7114849 100644
--- a/quickstep/src/com/android/launcher3/taskbar/TaskbarDragLayer.java
+++ b/quickstep/src/com/android/launcher3/taskbar/TaskbarDragLayer.java
@@ -194,7 +194,8 @@
public boolean dispatchKeyEvent(KeyEvent event) {
if (event.getAction() == ACTION_UP && event.getKeyCode() == KEYCODE_BACK) {
AbstractFloatingView topView = AbstractFloatingView.getTopOpenView(mActivity);
- if (topView != null && topView.onBackPressed()) {
+ if (topView != null && topView.canHandleBack()) {
+ topView.onBackInvoked();
// Handled by the floating view.
return true;
}
diff --git a/quickstep/src/com/android/launcher3/taskbar/TaskbarKeyguardController.java b/quickstep/src/com/android/launcher3/taskbar/TaskbarKeyguardController.java
index 0808fab..edf4648 100644
--- a/quickstep/src/com/android/launcher3/taskbar/TaskbarKeyguardController.java
+++ b/quickstep/src/com/android/launcher3/taskbar/TaskbarKeyguardController.java
@@ -10,12 +10,10 @@
import static com.android.systemui.shared.system.QuickStepContract.SYSUI_STATE_STATUS_BAR_KEYGUARD_SHOWING_OCCLUDED;
import android.app.KeyguardManager;
-import android.content.BroadcastReceiver;
-import android.content.Context;
-import android.content.Intent;
-import android.content.IntentFilter;
import com.android.launcher3.AbstractFloatingView;
+import com.android.launcher3.util.ScreenOnTracker;
+import com.android.launcher3.util.ScreenOnTracker.ScreenOnListener;
import com.android.systemui.shared.system.QuickStepContract;
import java.io.PrintWriter;
@@ -30,6 +28,7 @@
SYSUI_STATE_OVERVIEW_DISABLED | SYSUI_STATE_HOME_DISABLED |
SYSUI_STATE_BACK_DISABLED | SYSUI_STATE_STATUS_BAR_KEYGUARD_SHOWING_OCCLUDED;
+ private final ScreenOnListener mScreenOnListener;
private final TaskbarActivityContext mContext;
private int mKeyguardSysuiFlags;
private boolean mBouncerShowing;
@@ -37,22 +36,20 @@
private final KeyguardManager mKeyguardManager;
private boolean mIsScreenOff;
- private final BroadcastReceiver mScreenOffReceiver = new BroadcastReceiver() {
- @Override
- public void onReceive(Context context, Intent intent) {
- mIsScreenOff = true;
- AbstractFloatingView.closeOpenViews(mContext, false, TYPE_ALL);
- }
- };
-
public TaskbarKeyguardController(TaskbarActivityContext context) {
mContext = context;
+ mScreenOnListener = isOn -> {
+ if (!isOn) {
+ mIsScreenOff = true;
+ AbstractFloatingView.closeOpenViews(mContext, false, TYPE_ALL);
+ }
+ };
mKeyguardManager = mContext.getSystemService(KeyguardManager.class);
}
public void init(NavbarButtonsViewController navbarButtonUIController) {
mNavbarButtonsViewController = navbarButtonUIController;
- mContext.registerReceiver(mScreenOffReceiver, new IntentFilter(Intent.ACTION_SCREEN_OFF));
+ ScreenOnTracker.INSTANCE.get(mContext).addListener(mScreenOnListener);
}
public void updateStateForSysuiFlags(int systemUiStateFlags) {
@@ -104,7 +101,7 @@
}
public void onDestroy() {
- mContext.unregisterReceiver(mScreenOffReceiver);
+ ScreenOnTracker.INSTANCE.get(mContext).removeListener(mScreenOnListener);
}
@Override
diff --git a/quickstep/src/com/android/launcher3/taskbar/TaskbarManager.java b/quickstep/src/com/android/launcher3/taskbar/TaskbarManager.java
index 98c45d5..a58906f 100644
--- a/quickstep/src/com/android/launcher3/taskbar/TaskbarManager.java
+++ b/quickstep/src/com/android/launcher3/taskbar/TaskbarManager.java
@@ -156,10 +156,14 @@
} else {
// Config change might be handled without re-creating the taskbar
if (mTaskbarActivityContext != null) {
- if (dp != null && isTaskbarPresent(dp)) {
- mTaskbarActivityContext.updateDeviceProfile(dp, mNavMode);
+ if (dp != null && !isTaskbarPresent(dp)) {
+ destroyExistingTaskbar();
+ } else {
+ if (dp != null && isTaskbarPresent(dp)) {
+ mTaskbarActivityContext.updateDeviceProfile(dp, mNavMode);
+ }
+ mTaskbarActivityContext.onConfigurationChanged(configDiff);
}
- mTaskbarActivityContext.onConfigurationChanged(configDiff);
}
}
mOldConfig = newConfig;
diff --git a/quickstep/src/com/android/launcher3/taskbar/overlay/TaskbarOverlayDragLayer.java b/quickstep/src/com/android/launcher3/taskbar/overlay/TaskbarOverlayDragLayer.java
index 044afd6..d91b650 100644
--- a/quickstep/src/com/android/launcher3/taskbar/overlay/TaskbarOverlayDragLayer.java
+++ b/quickstep/src/com/android/launcher3/taskbar/overlay/TaskbarOverlayDragLayer.java
@@ -71,7 +71,8 @@
public boolean dispatchKeyEvent(KeyEvent event) {
if (event.getAction() == ACTION_UP && event.getKeyCode() == KEYCODE_BACK) {
AbstractFloatingView topView = AbstractFloatingView.getTopOpenView(mActivity);
- if (topView != null && topView.onBackPressed()) {
+ if (topView != null && topView.canHandleBack()) {
+ topView.onBackInvoked();
return true;
}
}
diff --git a/quickstep/src/com/android/launcher3/uioverrides/QuickstepLauncher.java b/quickstep/src/com/android/launcher3/uioverrides/QuickstepLauncher.java
index 078865f..30850b9 100644
--- a/quickstep/src/com/android/launcher3/uioverrides/QuickstepLauncher.java
+++ b/quickstep/src/com/android/launcher3/uioverrides/QuickstepLauncher.java
@@ -84,6 +84,7 @@
import com.android.launcher3.Launcher;
import com.android.launcher3.LauncherSettings.Favorites;
import com.android.launcher3.LauncherState;
+import com.android.launcher3.OnBackPressedHandler;
import com.android.launcher3.QuickstepAccessibilityDelegate;
import com.android.launcher3.QuickstepTransitionManager;
import com.android.launcher3.R;
@@ -609,10 +610,12 @@
}
@Override
- protected void onScreenOff() {
- super.onScreenOff();
- RecentsView recentsView = getOverviewPanel();
- recentsView.finishRecentsAnimation(true /* toRecents */, null);
+ protected void onScreenOnChanged(boolean isOn) {
+ super.onScreenOnChanged(isOn);
+ if (!isOn) {
+ RecentsView recentsView = getOverviewPanel();
+ recentsView.finishRecentsAnimation(true /* toRecents */, null);
+ }
}
@Override
@@ -636,20 +639,49 @@
getOnBackInvokedDispatcher().registerOnBackInvokedCallback(
OnBackInvokedDispatcher.PRIORITY_DEFAULT,
new OnBackAnimationCallback() {
+
+ @Nullable OnBackPressedHandler mActiveOnBackPressedHandler;
+
+ @Override
+ public void onBackStarted(@NonNull BackEvent backEvent) {
+ if (mActiveOnBackPressedHandler != null) {
+ mActiveOnBackPressedHandler.onBackCancelled();
+ }
+ mActiveOnBackPressedHandler = getOnBackPressedHandler();
+ mActiveOnBackPressedHandler.onBackStarted();
+ }
+
@Override
public void onBackInvoked() {
- onBackPressed();
+ // Recreate mActiveOnBackPressedHandler if necessary to avoid NPE because:
+ // 1. b/260636433: In 3-button-navigation mode, onBackStarted() is not
+ // called on ACTION_DOWN before onBackInvoked() is called in ACTION_UP.
+ // 2. Launcher#onBackPressed() will call onBackInvoked() without calling
+ // onBackInvoked() beforehand.
+ if (mActiveOnBackPressedHandler == null) {
+ mActiveOnBackPressedHandler = getOnBackPressedHandler();
+ }
+ mActiveOnBackPressedHandler.onBackInvoked();
+ mActiveOnBackPressedHandler = null;
TestLogging.recordEvent(TestProtocol.SEQUENCE_MAIN, "onBackInvoked");
}
@Override
public void onBackProgressed(@NonNull BackEvent backEvent) {
- QuickstepLauncher.this.onBackProgressed(backEvent.getProgress());
+ if (!FeatureFlags.IS_STUDIO_BUILD && mActiveOnBackPressedHandler == null) {
+ return;
+ }
+ mActiveOnBackPressedHandler
+ .onBackProgressed(backEvent.getProgress());
}
@Override
public void onBackCancelled() {
- QuickstepLauncher.this.onBackCancelled();
+ if (!FeatureFlags.IS_STUDIO_BUILD && mActiveOnBackPressedHandler == null) {
+ return;
+ }
+ mActiveOnBackPressedHandler.onBackCancelled();
+ mActiveOnBackPressedHandler = null;
}
});
}
diff --git a/quickstep/src/com/android/quickstep/AbsSwipeUpHandler.java b/quickstep/src/com/android/quickstep/AbsSwipeUpHandler.java
index e3427b7..deeb027 100644
--- a/quickstep/src/com/android/quickstep/AbsSwipeUpHandler.java
+++ b/quickstep/src/com/android/quickstep/AbsSwipeUpHandler.java
@@ -51,6 +51,7 @@
import static com.android.quickstep.MultiStateCallback.DEBUG_STATES;
import static com.android.quickstep.util.ActiveGestureErrorDetector.GestureEvent.CANCEL_RECENTS_ANIMATION;
import static com.android.quickstep.util.ActiveGestureErrorDetector.GestureEvent.EXPECTING_TASK_APPEARED;
+import static com.android.quickstep.util.ActiveGestureErrorDetector.GestureEvent.LAUNCHER_DESTROYED;
import static com.android.quickstep.util.ActiveGestureErrorDetector.GestureEvent.ON_SETTLED_ON_END_TARGET;
import static com.android.quickstep.views.RecentsView.UPDATE_SYSUI_FLAGS_THRESHOLD;
import static com.android.systemui.shared.system.ActivityManagerWrapper.CLOSE_SYSTEM_WINDOWS_REASON_RECENTS;
@@ -182,6 +183,7 @@
if (mActivity != activity) {
return;
}
+ handleActivityDestroyed();
mRecentsView = null;
mActivity = null;
}
@@ -462,6 +464,7 @@
if (mStateCallback.hasStates(STATE_HANDLER_INVALIDATED)) {
return false;
}
+ mStateCallback.resumeCallbacks();
T createdActivity = mActivityInterface.getCreatedActivity();
if (createdActivity != null) {
@@ -531,6 +534,15 @@
return true;
}
+ private void handleActivityDestroyed() {
+ ActiveGestureLog.INSTANCE.addLog("Launcher activity destroyed", LAUNCHER_DESTROYED);
+ if (mActivityInterface.shouldCancelGestureOnDestroy()) {
+ onGestureCancelled();
+ } else {
+ mStateCallback.pauseCallbacks();
+ }
+ }
+
/**
* Return true if the window should be translated horizontally if the recents view scrolls
*/
diff --git a/quickstep/src/com/android/quickstep/BaseActivityInterface.java b/quickstep/src/com/android/quickstep/BaseActivityInterface.java
index 274b686..22eaa97 100644
--- a/quickstep/src/com/android/quickstep/BaseActivityInterface.java
+++ b/quickstep/src/com/android/quickstep/BaseActivityInterface.java
@@ -123,6 +123,14 @@
public abstract AnimationFactory prepareRecentsUI(RecentsAnimationDeviceState deviceState,
boolean activityVisible, Consumer<AnimatorControllerWithResistance> callback);
+ /**
+ * Returns {@code true} iff an ongoing navigational gesture should be cancelled on activity
+ * destroy. Otherwise, the MultiStateCallbacks will be paused until the activity is recreated.
+ */
+ public boolean shouldCancelGestureOnDestroy() {
+ return true;
+ }
+
public abstract ActivityInitListener createActivityInitListener(
Predicate<Boolean> onInitListener);
diff --git a/quickstep/src/com/android/quickstep/FallbackActivityInterface.java b/quickstep/src/com/android/quickstep/FallbackActivityInterface.java
index ae9fb0b..4cb4665 100644
--- a/quickstep/src/com/android/quickstep/FallbackActivityInterface.java
+++ b/quickstep/src/com/android/quickstep/FallbackActivityInterface.java
@@ -88,6 +88,11 @@
}
@Override
+ public boolean shouldCancelGestureOnDestroy() {
+ return false;
+ }
+
+ @Override
public ActivityInitListener createActivityInitListener(
Predicate<Boolean> onInitListener) {
return new ActivityInitListener<>((activity, alreadyOnHome) ->
diff --git a/quickstep/src/com/android/quickstep/MultiStateCallback.java b/quickstep/src/com/android/quickstep/MultiStateCallback.java
index a68bea2..6d767ed 100644
--- a/quickstep/src/com/android/quickstep/MultiStateCallback.java
+++ b/quickstep/src/com/android/quickstep/MultiStateCallback.java
@@ -31,6 +31,7 @@
import java.util.ArrayList;
import java.util.LinkedList;
+import java.util.List;
import java.util.StringJoiner;
import java.util.function.Consumer;
@@ -52,6 +53,9 @@
private int mState = 0;
+ private boolean mCallbacksPaused = false;
+ private final List<Runnable> mPendingCallbacks = new ArrayList<>();
+
public MultiStateCallback(String[] stateNames) {
this(stateNames, stateFlag -> null);
}
@@ -78,6 +82,24 @@
}
}
+ /** Pauses callbacks. */
+ public void pauseCallbacks() {
+ mCallbacksPaused = true;
+ }
+
+ /** Immediately queues any callbacks that were pending paused. */
+ public void resumeCallbacks() {
+ if (!mCallbacksPaused) {
+ return;
+ }
+ mCallbacksPaused = false;
+ List<Runnable> queuedCallbacks = new ArrayList<>(mPendingCallbacks);
+ mPendingCallbacks.clear();
+ for (Runnable runnable : queuedCallbacks) {
+ runnable.run();
+ }
+ }
+
/**
* Adds the provided state flags to the global state and executes any callbacks as a result.
*/
@@ -99,7 +121,12 @@
if ((mState & state) == state) {
LinkedList<Runnable> callbacks = mCallbacks.valueAt(i);
while (!callbacks.isEmpty()) {
- callbacks.pollFirst().run();
+ Runnable cb = callbacks.pollFirst();
+ if (mCallbacksPaused) {
+ mPendingCallbacks.add(cb);
+ } else {
+ cb.run();
+ }
}
}
}
@@ -151,7 +178,11 @@
if (wasOn != isOn) {
ArrayList<Consumer<Boolean>> listeners = mStateChangeListeners.valueAt(i);
for (Consumer<Boolean> listener : listeners) {
- listener.accept(isOn);
+ if (mCallbacksPaused) {
+ mPendingCallbacks.add(() -> listener.accept(isOn));
+ } else {
+ listener.accept(isOn);
+ }
}
}
}
diff --git a/quickstep/src/com/android/quickstep/OverviewComponentObserver.java b/quickstep/src/com/android/quickstep/OverviewComponentObserver.java
index 83f2a0a..589459f 100644
--- a/quickstep/src/com/android/quickstep/OverviewComponentObserver.java
+++ b/quickstep/src/com/android/quickstep/OverviewComponentObserver.java
@@ -21,15 +21,12 @@
import static android.content.Intent.ACTION_PACKAGE_REMOVED;
import static com.android.launcher3.config.FeatureFlags.SEPARATE_RECENTS_ACTIVITY;
-import static com.android.launcher3.util.PackageManagerHelper.getPackageFilter;
import static com.android.systemui.shared.system.PackageManagerWrapper.ACTION_PREFERRED_ACTIVITY_CHANGED;
import android.content.ActivityNotFoundException;
-import android.content.BroadcastReceiver;
import android.content.ComponentName;
import android.content.Context;
import android.content.Intent;
-import android.content.IntentFilter;
import android.content.pm.ActivityInfo;
import android.content.pm.PackageManager;
import android.content.pm.ResolveInfo;
@@ -57,9 +54,9 @@
public final class OverviewComponentObserver {
private static final String TAG = "OverviewComponentObserver";
- private final BroadcastReceiver mUserPreferenceChangeReceiver =
+ private final SimpleBroadcastReceiver mUserPreferenceChangeReceiver =
new SimpleBroadcastReceiver(this::updateOverviewTargets);
- private final BroadcastReceiver mOtherHomeAppUpdateReceiver =
+ private final SimpleBroadcastReceiver mOtherHomeAppUpdateReceiver =
new SimpleBroadcastReceiver(this::updateOverviewTargets);
private final Context mContext;
@@ -102,8 +99,7 @@
mConfigChangesMap.append(fallbackComponent.hashCode(), fallbackInfo.configChanges);
} catch (PackageManager.NameNotFoundException ignored) { /* Impossible */ }
- mContext.registerReceiver(mUserPreferenceChangeReceiver,
- new IntentFilter(ACTION_PREFERRED_ACTIVITY_CHANGED));
+ mUserPreferenceChangeReceiver.register(mContext, ACTION_PREFERRED_ACTIVITY_CHANGED);
updateOverviewTargets();
}
@@ -181,9 +177,8 @@
unregisterOtherHomeAppUpdateReceiver();
mUpdateRegisteredPackage = defaultHome.getPackageName();
- mContext.registerReceiver(mOtherHomeAppUpdateReceiver, getPackageFilter(
- mUpdateRegisteredPackage, ACTION_PACKAGE_ADDED, ACTION_PACKAGE_CHANGED,
- ACTION_PACKAGE_REMOVED));
+ mOtherHomeAppUpdateReceiver.registerPkgActions(mContext, mUpdateRegisteredPackage,
+ ACTION_PACKAGE_ADDED, ACTION_PACKAGE_CHANGED, ACTION_PACKAGE_REMOVED);
}
}
mOverviewChangeListener.accept(mIsHomeAndOverviewSame);
diff --git a/quickstep/src/com/android/quickstep/RecentsAnimationDeviceState.java b/quickstep/src/com/android/quickstep/RecentsAnimationDeviceState.java
index f1c0f3e..1f522c1 100644
--- a/quickstep/src/com/android/quickstep/RecentsAnimationDeviceState.java
+++ b/quickstep/src/com/android/quickstep/RecentsAnimationDeviceState.java
@@ -32,6 +32,7 @@
import static com.android.systemui.shared.system.QuickStepContract.SYSUI_STATE_ALLOW_GESTURE_IGNORING_BAR_VISIBILITY;
import static com.android.systemui.shared.system.QuickStepContract.SYSUI_STATE_ASSIST_GESTURE_CONSTRAINED;
import static com.android.systemui.shared.system.QuickStepContract.SYSUI_STATE_BUBBLES_EXPANDED;
+import static com.android.systemui.shared.system.QuickStepContract.SYSUI_STATE_DEVICE_DREAMING;
import static com.android.systemui.shared.system.QuickStepContract.SYSUI_STATE_DIALOG_SHOWING;
import static com.android.systemui.shared.system.QuickStepContract.SYSUI_STATE_HOME_DISABLED;
import static com.android.systemui.shared.system.QuickStepContract.SYSUI_STATE_IME_SHOWING;
@@ -42,6 +43,7 @@
import static com.android.systemui.shared.system.QuickStepContract.SYSUI_STATE_OVERVIEW_DISABLED;
import static com.android.systemui.shared.system.QuickStepContract.SYSUI_STATE_QUICK_SETTINGS_EXPANDED;
import static com.android.systemui.shared.system.QuickStepContract.SYSUI_STATE_SCREEN_PINNING;
+import static com.android.systemui.shared.system.QuickStepContract.SYSUI_STATE_STATUS_BAR_KEYGUARD_SHOWING;
import static com.android.systemui.shared.system.QuickStepContract.SYSUI_STATE_STATUS_BAR_KEYGUARD_SHOWING_OCCLUDED;
import android.app.ActivityTaskManager;
@@ -334,10 +336,12 @@
|| mRotationTouchHelper.isTaskListFrozen();
return canStartWithNavHidden
&& (mSystemUiStateFlags & SYSUI_STATE_NOTIFICATION_PANEL_EXPANDED) == 0
+ && (mSystemUiStateFlags & SYSUI_STATE_STATUS_BAR_KEYGUARD_SHOWING) == 0
&& (mSystemUiStateFlags & SYSUI_STATE_QUICK_SETTINGS_EXPANDED) == 0
&& (mSystemUiStateFlags & SYSUI_STATE_MAGNIFICATION_OVERLAP) == 0
&& ((mSystemUiStateFlags & SYSUI_STATE_HOME_DISABLED) == 0
- || (mSystemUiStateFlags & SYSUI_STATE_OVERVIEW_DISABLED) == 0);
+ || (mSystemUiStateFlags & SYSUI_STATE_OVERVIEW_DISABLED) == 0)
+ && (mSystemUiStateFlags & SYSUI_STATE_DEVICE_DREAMING) == 0;
}
/**
diff --git a/quickstep/src/com/android/quickstep/inputconsumers/ProgressDelegateInputConsumer.java b/quickstep/src/com/android/quickstep/inputconsumers/ProgressDelegateInputConsumer.java
index 45ffa1c..ab70272 100644
--- a/quickstep/src/com/android/quickstep/inputconsumers/ProgressDelegateInputConsumer.java
+++ b/quickstep/src/com/android/quickstep/inputconsumers/ProgressDelegateInputConsumer.java
@@ -20,6 +20,7 @@
import static com.android.launcher3.touch.SingleAxisSwipeDetector.DIRECTION_POSITIVE;
import static com.android.launcher3.touch.SingleAxisSwipeDetector.VERTICAL;
import static com.android.quickstep.MultiStateCallback.DEBUG_STATES;
+import static com.android.quickstep.OverviewComponentObserver.startHomeIntentSafely;
import static com.android.quickstep.util.ActiveGestureLog.INTENT_EXTRA_LOG_TRACE_ID;
import android.animation.ObjectAnimator;
@@ -102,8 +103,7 @@
mStateCallback = new MultiStateCallback(STATE_NAMES);
mStateCallback.runOnceAtState(STATE_TARGET_RECEIVED | STATE_HANDLER_INVALIDATED,
this::endRemoteAnimation);
- mStateCallback.runOnceAtState(STATE_TARGET_RECEIVED | STATE_FLING_FINISHED,
- this::onFlingFinished);
+ mStateCallback.runOnceAtState(STATE_FLING_FINISHED, this::onFlingFinished);
mSwipeDetector = new SingleAxisSwipeDetector(mContext, this, VERTICAL);
mSwipeDetector.setDetectableScrollConditions(DIRECTION_POSITIVE, false);
@@ -159,10 +159,12 @@
}
private void onFlingFinished() {
+ boolean endToRecents = mFlingEndsOnHome == null ? true : mFlingEndsOnHome;
if (mRecentsAnimationController != null) {
- boolean endToRecents = mFlingEndsOnHome == null ? true : mFlingEndsOnHome;
mRecentsAnimationController.finishController(endToRecents /* toRecents */,
null /* callback */, false /* sendUserLeaveHint */);
+ } else if (endToRecents) {
+ startHomeIntentSafely(mContext, null);
}
}
diff --git a/quickstep/src/com/android/quickstep/util/ActiveGestureErrorDetector.java b/quickstep/src/com/android/quickstep/util/ActiveGestureErrorDetector.java
index 60065fb..0fdd8b5 100644
--- a/quickstep/src/com/android/quickstep/util/ActiveGestureErrorDetector.java
+++ b/quickstep/src/com/android/quickstep/util/ActiveGestureErrorDetector.java
@@ -37,7 +37,7 @@
ON_SETTLED_ON_END_TARGET, START_RECENTS_ANIMATION, FINISH_RECENTS_ANIMATION,
CANCEL_RECENTS_ANIMATION, SET_ON_PAGE_TRANSITION_END_CALLBACK, CANCEL_CURRENT_ANIMATION,
CLEANUP_SCREENSHOT, SCROLLER_ANIMATION_ABORTED, TASK_APPEARED, EXPECTING_TASK_APPEARED,
- FLAG_USING_OTHER_ACTIVITY_INPUT_CONSUMER,
+ FLAG_USING_OTHER_ACTIVITY_INPUT_CONSUMER, LAUNCHER_DESTROYED,
/**
* These GestureEvents are specifically associated to state flags that get set in
@@ -162,6 +162,13 @@
+ "before/without setting end target to new task",
writer);
break;
+ case LAUNCHER_DESTROYED:
+ errorDetected |= printErrorIfTrue(
+ true,
+ prefix,
+ /* errorMessage= */ "Launcher destroyed mid-gesture",
+ writer);
+ break;
case STATE_GESTURE_COMPLETED:
errorDetected |= printErrorIfTrue(
!encounteredEvents.contains(GestureEvent.MOTION_UP),
diff --git a/quickstep/src/com/android/quickstep/views/AllAppsEduView.java b/quickstep/src/com/android/quickstep/views/AllAppsEduView.java
index d79b318..716d389 100644
--- a/quickstep/src/com/android/quickstep/views/AllAppsEduView.java
+++ b/quickstep/src/com/android/quickstep/views/AllAppsEduView.java
@@ -112,11 +112,6 @@
}
@Override
- public boolean onBackPressed() {
- return true;
- }
-
- @Override
public boolean canInterceptEventsInSystemGestureRegion() {
return true;
}
diff --git a/quickstep/src/com/android/quickstep/views/DesktopTaskView.java b/quickstep/src/com/android/quickstep/views/DesktopTaskView.java
index 858f6ab..44aa41a 100644
--- a/quickstep/src/com/android/quickstep/views/DesktopTaskView.java
+++ b/quickstep/src/com/android/quickstep/views/DesktopTaskView.java
@@ -18,6 +18,7 @@
import static android.view.ViewGroup.LayoutParams.WRAP_CONTENT;
+import static com.android.launcher3.LauncherState.NORMAL;
import static com.android.launcher3.util.SplitConfigurationOptions.STAGE_POSITION_UNDEFINED;
import android.content.Context;
@@ -35,6 +36,7 @@
import androidx.annotation.Nullable;
import com.android.launcher3.DeviceProfile;
+import com.android.launcher3.Launcher;
import com.android.launcher3.Utilities;
import com.android.launcher3.touch.PagedOrientationHandler;
import com.android.launcher3.util.RunnableList;
@@ -295,7 +297,7 @@
@Override
public RunnableList launchTasks() {
SystemUiProxy.INSTANCE.get(getContext()).showDesktopApps();
- getRecentsView().startHome();
+ Launcher.getLauncher(mActivity).getStateManager().goToState(NORMAL, false /* animated */);
return null;
}
diff --git a/quickstep/tests/src/com/android/quickstep/FallbackRecentsTest.java b/quickstep/tests/src/com/android/quickstep/FallbackRecentsTest.java
index 47bef7b..a4dbf6a 100644
--- a/quickstep/tests/src/com/android/quickstep/FallbackRecentsTest.java
+++ b/quickstep/tests/src/com/android/quickstep/FallbackRecentsTest.java
@@ -168,7 +168,6 @@
// b/143488140
//@NavigationModeSwitch
- @Ignore
@Test
public void goToOverviewFromHome() {
mDevice.pressHome();
@@ -216,7 +215,6 @@
// b/143488140
//@NavigationModeSwitch
- @Ignore
@Test
public void testOverview() {
startAppFast(getAppPackageName());
diff --git a/quickstep/tests/src/com/android/quickstep/TaplTestsTaskbar.java b/quickstep/tests/src/com/android/quickstep/TaplTestsTaskbar.java
index 0b8bc10..aed26d3 100644
--- a/quickstep/tests/src/com/android/quickstep/TaplTestsTaskbar.java
+++ b/quickstep/tests/src/com/android/quickstep/TaplTestsTaskbar.java
@@ -18,6 +18,7 @@
import static androidx.test.InstrumentationRegistry.getInstrumentation;
import static com.android.quickstep.TaskbarModeSwitchRule.Mode.PERSISTENT;
+import static com.android.quickstep.TaskbarModeSwitchRule.Mode.TRANSIENT;
import static junit.framework.TestCase.assertEquals;
@@ -82,19 +83,31 @@
}
@Test
- @TaskbarModeSwitch
+ @TaskbarModeSwitch(mode = PERSISTENT)
public void testLaunchApp() throws Exception {
getTaskbar().getAppIcon(TEST_APP_NAME).launch(TEST_APP_PACKAGE);
}
@Test
- @TaskbarModeSwitch
+ @TaskbarModeSwitch(mode = TRANSIENT)
+ public void testTransientLaunchApp() throws Exception {
+ getTaskbar().getAppIcon(TEST_APP_NAME).launch(TEST_APP_PACKAGE);
+ }
+
+ @Test
+ @TaskbarModeSwitch(mode = PERSISTENT)
public void testOpenMenu() throws Exception {
getTaskbar().getAppIcon(TEST_APP_NAME).openMenu();
}
@Test
- @TaskbarModeSwitch
+ @TaskbarModeSwitch(mode = TRANSIENT)
+ public void testTransientOpenMenu() throws Exception {
+ getTaskbar().getAppIcon(TEST_APP_NAME).openMenu();
+ }
+
+ @Test
+ @TaskbarModeSwitch(mode = PERSISTENT)
public void testLaunchShortcut() throws Exception {
getTaskbar().getAppIcon(TEST_APP_NAME)
.openDeepShortcutMenu()
@@ -103,9 +116,18 @@
}
@Test
+ @TaskbarModeSwitch(mode = TRANSIENT)
+ public void testTransientLaunchShortcut() throws Exception {
+ getTaskbar().getAppIcon(TEST_APP_NAME)
+ .openDeepShortcutMenu()
+ .getMenuItem("Shortcut 1")
+ .launch(TEST_APP_PACKAGE);
+ }
+
+ @Test
@ScreenRecord // b/231615831
@PortraitLandscape
- @TaskbarModeSwitch
+ @TaskbarModeSwitch(mode = PERSISTENT)
public void testLaunchAppInSplitscreen() throws Exception {
getTaskbar().getAppIcon(TEST_APP_NAME).dragToSplitscreen(
TEST_APP_PACKAGE, CALCULATOR_APP_PACKAGE);
@@ -114,7 +136,16 @@
@Test
@ScreenRecord // b/231615831
@PortraitLandscape
- @TaskbarModeSwitch
+ @TaskbarModeSwitch(mode = TRANSIENT)
+ public void testTransientLaunchAppInSplitscreen() throws Exception {
+ getTaskbar().getAppIcon(TEST_APP_NAME).dragToSplitscreen(
+ TEST_APP_PACKAGE, CALCULATOR_APP_PACKAGE);
+ }
+
+ @Test
+ @ScreenRecord // b/231615831
+ @PortraitLandscape
+ @TaskbarModeSwitch(mode = PERSISTENT)
public void testLaunchShortcutInSplitscreen() throws Exception {
getTaskbar().getAppIcon(TEST_APP_NAME)
.openDeepShortcutMenu()
@@ -123,19 +154,42 @@
}
@Test
- @TaskbarModeSwitch
+ @ScreenRecord // b/231615831
+ @PortraitLandscape
+ @TaskbarModeSwitch(mode = TRANSIENT)
+ public void testTransientLaunchShortcutInSplitscreen() throws Exception {
+ getTaskbar().getAppIcon(TEST_APP_NAME)
+ .openDeepShortcutMenu()
+ .getMenuItem("Shortcut 1")
+ .dragToSplitscreen(TEST_APP_PACKAGE, CALCULATOR_APP_PACKAGE);
+ }
+
+ @Test
+ @TaskbarModeSwitch(mode = PERSISTENT)
public void testLaunchApp_FromTaskbarAllApps() throws Exception {
getTaskbar().openAllApps().getAppIcon(TEST_APP_NAME).launch(TEST_APP_PACKAGE);
}
@Test
- @TaskbarModeSwitch
+ @TaskbarModeSwitch(mode = TRANSIENT)
+ public void testTransientLaunchApp_FromTaskbarAllApps() throws Exception {
+ getTaskbar().openAllApps().getAppIcon(TEST_APP_NAME).launch(TEST_APP_PACKAGE);
+ }
+
+ @Test
+ @TaskbarModeSwitch(mode = PERSISTENT)
public void testOpenMenu_FromTaskbarAllApps() throws Exception {
getTaskbar().openAllApps().getAppIcon(TEST_APP_NAME).openMenu();
}
@Test
- @TaskbarModeSwitch
+ @TaskbarModeSwitch(mode = TRANSIENT)
+ public void testTransientOpenMenu_FromTaskbarAllApps() throws Exception {
+ getTaskbar().openAllApps().getAppIcon(TEST_APP_NAME).openMenu();
+ }
+
+ @Test
+ @TaskbarModeSwitch(mode = PERSISTENT)
public void testLaunchShortcut_FromTaskbarAllApps() throws Exception {
getTaskbar().openAllApps()
.getAppIcon(TEST_APP_NAME)
@@ -145,9 +199,19 @@
}
@Test
+ @TaskbarModeSwitch(mode = TRANSIENT)
+ public void testTransientLaunchShortcut_FromTaskbarAllApps() throws Exception {
+ getTaskbar().openAllApps()
+ .getAppIcon(TEST_APP_NAME)
+ .openDeepShortcutMenu()
+ .getMenuItem("Shortcut 1")
+ .launch(TEST_APP_PACKAGE);
+ }
+
+ @Test
@ScreenRecord // b/231615831
@PortraitLandscape
- @TaskbarModeSwitch
+ @TaskbarModeSwitch(mode = PERSISTENT)
public void testLaunchAppInSplitscreen_FromTaskbarAllApps() throws Exception {
getTaskbar().openAllApps()
.getAppIcon(TEST_APP_NAME)
@@ -157,7 +221,17 @@
@Test
@ScreenRecord // b/231615831
@PortraitLandscape
- @TaskbarModeSwitch
+ @TaskbarModeSwitch(mode = TRANSIENT)
+ public void testTransientLaunchAppInSplitscreen_FromTaskbarAllApps() throws Exception {
+ getTaskbar().openAllApps()
+ .getAppIcon(TEST_APP_NAME)
+ .dragToSplitscreen(TEST_APP_PACKAGE, CALCULATOR_APP_PACKAGE);
+ }
+
+ @Test
+ @ScreenRecord // b/231615831
+ @PortraitLandscape
+ @TaskbarModeSwitch(mode = PERSISTENT)
public void testLaunchShortcutInSplitscreen_FromTaskbarAllApps() throws Exception {
getTaskbar().openAllApps()
.getAppIcon(TEST_APP_NAME)
@@ -166,6 +240,18 @@
.dragToSplitscreen(TEST_APP_PACKAGE, CALCULATOR_APP_PACKAGE);
}
+ @Test
+ @ScreenRecord // b/231615831
+ @PortraitLandscape
+ @TaskbarModeSwitch(mode = TRANSIENT)
+ public void testTransientLaunchShortcutInSplitscreen_FromTaskbarAllApps() throws Exception {
+ getTaskbar().openAllApps()
+ .getAppIcon(TEST_APP_NAME)
+ .openDeepShortcutMenu()
+ .getMenuItem("Shortcut 1")
+ .dragToSplitscreen(TEST_APP_PACKAGE, CALCULATOR_APP_PACKAGE);
+ }
+
private Taskbar getTaskbar() {
Taskbar taskbar = mLauncher.getLaunchedAppState().getTaskbar();
List<String> taskbarIconNames = taskbar.getIconNames();
diff --git a/res/layout/widget_cell_content.xml b/res/layout/widget_cell_content.xml
index feebfe1..3f61aaa 100644
--- a/res/layout/widget_cell_content.xml
+++ b/res/layout/widget_cell_content.xml
@@ -23,6 +23,7 @@
android:layout_height="0dp"
android:layout_weight="1"
android:importantForAccessibility="noHideDescendants"
+ android:hapticFeedbackEnabled="false"
android:layout_marginVertical="8dp">
<!-- The image of the widget. This view does not support padding. Any placement adjustment
should be done using margins. Width & height are set at runtime after scaling the
diff --git a/res/values-ky/strings.xml b/res/values-ky/strings.xml
index 3a58b85..46358cd 100644
--- a/res/values-ky/strings.xml
+++ b/res/values-ky/strings.xml
@@ -53,9 +53,9 @@
<string name="widget_category_conversations" msgid="8894438636213590446">"Сүйлөшүүлөр"</string>
<string name="widget_education_header" msgid="4874760613775913787">"Керектүү маалымат манжаңыздын учунда"</string>
<string name="widget_education_content" msgid="1731667670753497052">"Бир нерсе билүү үчүн колдонмолорду улам ачып убара болбостон, башкы экранга виджеттерди кошуп коюңуз."</string>
- <string name="reconfigurable_widget_education_tip" msgid="6336962690888067057">"Виджеттин жөндөөлөрүн өзгөртүү үчүн таптап коюңуз"</string>
+ <string name="reconfigurable_widget_education_tip" msgid="6336962690888067057">"Виджеттин параметрлерин өзгөртүү үчүн таптап коюңуз"</string>
<string name="widget_education_close_button" msgid="8676165703104836580">"Түшүндүм"</string>
- <string name="widget_reconfigure_button_content_description" msgid="8811472721881205250">"Виджеттин жөндөөлөрүн өзгөртүү"</string>
+ <string name="widget_reconfigure_button_content_description" msgid="8811472721881205250">"Виджеттин параметрлерин өзгөртүү"</string>
<string name="all_apps_search_bar_hint" msgid="1390553134053255246">"Колдонмолорду издөө"</string>
<string name="all_apps_loading_message" msgid="5813968043155271636">"Колдонмолор жүктөлүүдө…"</string>
<string name="all_apps_no_search_results" msgid="3200346862396363786">"\"<xliff:g id="QUERY">%1$s</xliff:g>\" сурамына дал келген колдонмолор табылган жок"</string>
@@ -78,13 +78,13 @@
<string name="pin_prediction" msgid="4196423321649756498">"Божомолдонгон колдонмону кадап коюу"</string>
<string name="permlab_install_shortcut" msgid="5632423390354674437">"тез чакырмаларды орнотуу"</string>
<string name="permdesc_install_shortcut" msgid="923466509822011139">"Колдонмого колдонуучуга кайрылбастан тез чакырма кошууга уруксат берет."</string>
- <string name="permlab_read_settings" msgid="5136500343007704955">"үйдүн жөндөөлөрүн жана ыкчам баскычтарын окуу"</string>
- <string name="permdesc_read_settings" msgid="4208061150510996676">"Колдонмого үйдүн жөндөөлөрүн жана ыкчам баскычтарын окууга уруксат берет."</string>
- <string name="permlab_write_settings" msgid="4820028712156303762">"үйдүн жөндөөлөрүн жана ыкчам баскычтарын жазуу"</string>
- <string name="permdesc_write_settings" msgid="726859348127868466">"Колдонмого үйдүн жөндөөлөрүн жана ыкчам баскычтарын өзгөртүүгө уруксат берет."</string>
+ <string name="permlab_read_settings" msgid="5136500343007704955">"үйдүн параметрлерин жана ыкчам баскычтарын окуу"</string>
+ <string name="permdesc_read_settings" msgid="4208061150510996676">"Колдонмого үйдүн параметрлерин жана ыкчам баскычтарын окууга уруксат берет."</string>
+ <string name="permlab_write_settings" msgid="4820028712156303762">"үйдүн параметрлерин жана ыкчам баскычтарын жазуу"</string>
+ <string name="permdesc_write_settings" msgid="726859348127868466">"Колдонмого үйдүн параметрлерин жана ыкчам баскычтарын өзгөртүүгө уруксат берет."</string>
<string name="msg_no_phone_permission" msgid="9208659281529857371">"<xliff:g id="APP_NAME">%1$s</xliff:g> телефон чалууларды аткарууга уруксаты жок"</string>
<string name="gadget_error_text" msgid="740356548025791839">"Виджет жүктөлбөй жатат"</string>
- <string name="gadget_setup_text" msgid="8348374825537681407">"Виджеттин жөндөөлөрү"</string>
+ <string name="gadget_setup_text" msgid="8348374825537681407">"Виджеттин параметрлери"</string>
<string name="gadget_complete_setup_text" msgid="309040266978007925">"Аягына чейин тууралоо үчүн басып коюңуз"</string>
<string name="uninstall_system_app_text" msgid="4172046090762920660">"Бул системдик колдонмо жана аны чечкенге болбойт."</string>
<string name="folder_hint_text" msgid="5174843001373488816">"Аталышын түзөтүү"</string>
@@ -102,7 +102,7 @@
<string name="folder_name_format_overflow" msgid="4270108890534995199">"<xliff:g id="NAME">%1$s</xliff:g> папкасындагы объекттер: <xliff:g id="SIZE">%2$d</xliff:g> же андан көбүрөөк"</string>
<string name="wallpaper_button_text" msgid="8404103075899945851">"Тушкагаздар"</string>
<string name="styles_wallpaper_button_text" msgid="8216961355289236794">"Тушкагаз жана стиль"</string>
- <string name="settings_button_text" msgid="8873672322605444408">"Башкы бет жөндөөлөрү"</string>
+ <string name="settings_button_text" msgid="8873672322605444408">"Башкы бет параметрлери"</string>
<string name="msg_disabled_by_admin" msgid="6898038085516271325">"Администраторуңуз өчүрүп койгон"</string>
<string name="allow_rotation_title" msgid="7222049633713050106">"Башкы экранды бурууга уруксат берүү"</string>
<string name="allow_rotation_desc" msgid="8662546029078692509">"Телефон бурулганда"</string>
diff --git a/res/values-land/styles.xml b/res/values-land/styles.xml
new file mode 100644
index 0000000..52474da
--- /dev/null
+++ b/res/values-land/styles.xml
@@ -0,0 +1,21 @@
+<?xml version="1.0" encoding="utf-8"?><!--
+ ~ 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.
+ -->
+
+<resources>
+ <style name="CellStyleDefault">
+ <item name="iconDrawablePadding">4dp</item>
+ </style>
+</resources>
\ No newline at end of file
diff --git a/res/values-pt-rPT/strings.xml b/res/values-pt-rPT/strings.xml
index bb1fb36..4dda225 100644
--- a/res/values-pt-rPT/strings.xml
+++ b/res/values-pt-rPT/strings.xml
@@ -162,7 +162,7 @@
<string name="work_profile_toggle_label" msgid="3081029915775481146">"Perfil de trabalho"</string>
<string name="work_profile_edu_work_apps" msgid="7895468576497746520">"As apps de trabalho têm um emblema e estão visíveis para o seu administrador de TI"</string>
<string name="work_profile_edu_accept" msgid="6069788082535149071">"OK"</string>
- <string name="work_apps_paused_title" msgid="3040901117349444598">"As apps de trabalho estão em pausa"</string>
+ <string name="work_apps_paused_title" msgid="3040901117349444598">"As apps de trabalho estão suspensas."</string>
<string name="work_apps_paused_body" msgid="261634750995824906">"As apps de trabalho não podem enviar-lhe notificações, utilizar a bateria ou aceder à sua localização"</string>
<string name="work_apps_paused_content_description" msgid="5149623040804051095">"As apps de trabalho estão desativadas. As apps de trabalho não podem enviar-lhe notificações, utilizar a bateria ou aceder à sua localização"</string>
<string name="work_apps_paused_edu_banner" msgid="8872412121608402058">"As apps de trabalho têm um emblema e estão visíveis para o seu administrador de TI"</string>
diff --git a/res/values/attrs.xml b/res/values/attrs.xml
index 08561d5..e6f285c 100644
--- a/res/values/attrs.xml
+++ b/res/values/attrs.xml
@@ -142,9 +142,13 @@
<!-- numSearchContainerColumns defaults to numColumns, if not specified -->
<attr name="numSearchContainerColumns" format="integer" />
+ <!-- Support attributes in CellStyle. defaults to CellStyleDefault -->
+ <attr name="cellStyle" format="reference" />
+
<!-- numFolderRows & numFolderColumns defaults to numRows & numColumns, if not specified -->
<attr name="numFolderRows" format="integer" />
<attr name="numFolderColumns" format="integer" />
+ <!-- Support attributes in FolderStyle -->
<attr name="folderStyle" format="reference" />
<!-- numAllAppsColumns defaults to numColumns, if not specified -->
@@ -387,7 +391,7 @@
</declare-styleable>
- <declare-styleable name="FolderDisplayStyle">
+ <declare-styleable name="FolderStyle">
<!-- defaults to minCellHeight if not specified
when GridDisplayOption#isScalable is true. -->
<attr name="folderCellHeight" format="dimension" />
@@ -402,7 +406,6 @@
<attr name="folderTopPadding" format="dimension" />
</declare-styleable>
-
<declare-styleable name="CellLayout">
<attr name="containerType" format="integer">
<enum name="workspace" value="0" />
@@ -411,6 +414,10 @@
</attr>
</declare-styleable>
+ <declare-styleable name="CellStyle">
+ <attr name="iconDrawablePadding" format="dimension" />
+ </declare-styleable>
+
<declare-styleable name="ShadowDrawable">
<attr name="android:src" />
<attr name="android:shadowColor" />
diff --git a/res/values/styles.xml b/res/values/styles.xml
index 7582a30..dfff926 100644
--- a/res/values/styles.xml
+++ b/res/values/styles.xml
@@ -293,7 +293,7 @@
<item name="android:windowTranslucentStatus">true</item>
</style>
- <style name="FolderDefaultStyle">
+ <style name="FolderStyleDefault">
<item name="folderTopPadding">24dp</item>
<item name="folderCellHeight">94dp</item>
<item name="folderCellWidth">80dp</item>
@@ -301,4 +301,8 @@
<item name="folderFooterHeight">56dp</item>
</style>
+ <style name="CellStyleDefault">
+ <item name="iconDrawablePadding">7dp</item>
+ </style>
+
</resources>
diff --git a/src/com/android/launcher3/AbstractFloatingView.java b/src/com/android/launcher3/AbstractFloatingView.java
index 28d4a9f..796fa80 100644
--- a/src/com/android/launcher3/AbstractFloatingView.java
+++ b/src/com/android/launcher3/AbstractFloatingView.java
@@ -46,7 +46,8 @@
/**
* Base class for a View which shows a floating UI on top of the launcher UI.
*/
-public abstract class AbstractFloatingView extends LinearLayout implements TouchController {
+public abstract class AbstractFloatingView extends LinearLayout implements TouchController,
+ OnBackPressedHandler {
@IntDef(flag = true, value = {
TYPE_FOLDER,
@@ -63,11 +64,13 @@
TYPE_TASK_MENU,
TYPE_OPTIONS_POPUP,
TYPE_ICON_SURFACE,
+ TYPE_OPTIONS_POPUP_DIALOG,
TYPE_PIN_WIDGET_FROM_EXTERNAL_POPUP,
TYPE_WIDGETS_EDUCATION_DIALOG,
TYPE_TASKBAR_EDUCATION_DIALOG,
TYPE_TASKBAR_ALL_APPS,
- TYPE_OPTIONS_POPUP_DIALOG
+ TYPE_ADD_TO_HOME_CONFIRMATION,
+ TYPE_TASKBAR_OVERLAY_PROXY
})
@Retention(RetentionPolicy.SOURCE)
public @interface FloatingViewType {}
@@ -87,14 +90,14 @@
public static final int TYPE_TASK_MENU = 1 << 11;
public static final int TYPE_OPTIONS_POPUP = 1 << 12;
public static final int TYPE_ICON_SURFACE = 1 << 13;
- public static final int TYPE_OPTIONS_POPUP_DIALOG = 1 << 18;
+ public static final int TYPE_OPTIONS_POPUP_DIALOG = 1 << 14;
- public static final int TYPE_PIN_WIDGET_FROM_EXTERNAL_POPUP = 1 << 14;
- public static final int TYPE_WIDGETS_EDUCATION_DIALOG = 1 << 15;
- public static final int TYPE_TASKBAR_EDUCATION_DIALOG = 1 << 16;
- public static final int TYPE_TASKBAR_ALL_APPS = 1 << 17;
- public static final int TYPE_ADD_TO_HOME_CONFIRMATION = 1 << 18;
- public static final int TYPE_TASKBAR_OVERLAY_PROXY = 1 << 19;
+ public static final int TYPE_PIN_WIDGET_FROM_EXTERNAL_POPUP = 1 << 15;
+ public static final int TYPE_WIDGETS_EDUCATION_DIALOG = 1 << 16;
+ public static final int TYPE_TASKBAR_EDUCATION_DIALOG = 1 << 17;
+ public static final int TYPE_TASKBAR_ALL_APPS = 1 << 18;
+ public static final int TYPE_ADD_TO_HOME_CONFIRMATION = 1 << 19;
+ public static final int TYPE_TASKBAR_OVERLAY_PROXY = 1 << 20;
public static final int TYPE_ALL = TYPE_FOLDER | TYPE_ACTION_POPUP
| TYPE_WIDGETS_BOTTOM_SHEET | TYPE_WIDGET_RESIZE_FRAME | TYPE_WIDGETS_FULL_SHEET
@@ -163,13 +166,17 @@
protected abstract boolean isOfType(@FloatingViewType int type);
- /** @return Whether the back is consumed. If false, Launcher will handle the back as well. */
- public boolean onBackPressed() {
- close(true);
+ /** Return true if this view can consume back press. */
+ public boolean canHandleBack() {
return true;
}
@Override
+ public void onBackInvoked() {
+ close(true);
+ }
+
+ @Override
public boolean onControllerTouchEvent(MotionEvent ev) {
return false;
}
diff --git a/src/com/android/launcher3/BaseDraggingActivity.java b/src/com/android/launcher3/BaseDraggingActivity.java
index ca1fe40..6f3e948 100644
--- a/src/com/android/launcher3/BaseDraggingActivity.java
+++ b/src/com/android/launcher3/BaseDraggingActivity.java
@@ -125,9 +125,13 @@
mCurrentActionMode = null;
}
+ protected boolean isInAutoCancelActionMode() {
+ return mCurrentActionMode != null && AUTO_CANCEL_ACTION_MODE == mCurrentActionMode.getTag();
+ }
+
@Override
public boolean finishAutoCancelActionMode() {
- if (mCurrentActionMode != null && AUTO_CANCEL_ACTION_MODE == mCurrentActionMode.getTag()) {
+ if (isInAutoCancelActionMode()) {
mCurrentActionMode.finish();
return true;
}
diff --git a/src/com/android/launcher3/DeviceProfile.java b/src/com/android/launcher3/DeviceProfile.java
index 8391b91..9f9c6f9 100644
--- a/src/com/android/launcher3/DeviceProfile.java
+++ b/src/com/android/launcher3/DeviceProfile.java
@@ -376,19 +376,19 @@
if (inv.folderStyle != INVALID_RESOURCE_HANDLE) {
TypedArray folderStyle = context.obtainStyledAttributes(inv.folderStyle,
- R.styleable.FolderDisplayStyle);
+ R.styleable.FolderStyle);
// These are re-set in #updateFolderCellSize if the grid is not scalable
folderCellHeightPx = folderStyle.getDimensionPixelSize(
- R.styleable.FolderDisplayStyle_folderCellHeight, 0);
+ R.styleable.FolderStyle_folderCellHeight, 0);
folderCellWidthPx = folderStyle.getDimensionPixelSize(
- R.styleable.FolderDisplayStyle_folderCellWidth, 0);
+ R.styleable.FolderStyle_folderCellWidth, 0);
folderContentPaddingTop = folderStyle.getDimensionPixelSize(
- R.styleable.FolderDisplayStyle_folderTopPadding, 0);
+ R.styleable.FolderStyle_folderTopPadding, 0);
folderCellLayoutBorderSpacePx = folderStyle.getDimensionPixelSize(
- R.styleable.FolderDisplayStyle_folderBorderSpace, 0);
+ R.styleable.FolderStyle_folderBorderSpace, 0);
folderFooterHeightPx = folderStyle.getDimensionPixelSize(
- R.styleable.FolderDisplayStyle_folderFooterHeight, 0);
+ R.styleable.FolderStyle_folderFooterHeight, 0);
folderStyle.recycle();
} else {
folderCellLayoutBorderSpacePx = 0;
@@ -407,8 +407,17 @@
mWorkspacePageIndicatorOverlapWorkspace =
res.getDimensionPixelSize(R.dimen.workspace_page_indicator_overlap_workspace);
- iconDrawablePaddingOriginalPx =
- res.getDimensionPixelSize(R.dimen.dynamic_grid_icon_drawable_padding);
+ TypedArray cellStyle;
+ if (inv.cellStyle != INVALID_RESOURCE_HANDLE) {
+ cellStyle = context.obtainStyledAttributes(inv.cellStyle,
+ R.styleable.CellStyle);
+ } else {
+ cellStyle = context.obtainStyledAttributes(R.style.CellStyleDefault,
+ R.styleable.CellStyle);
+ }
+ iconDrawablePaddingOriginalPx = cellStyle.getDimensionPixelSize(
+ R.styleable.CellStyle_iconDrawablePadding, 0);
+ cellStyle.recycle();
dropTargetBarSizePx = res.getDimensionPixelSize(R.dimen.dynamic_grid_drop_target_size);
dropTargetBarTopMarginPx = res.getDimensionPixelSize(R.dimen.drop_target_top_margin);
diff --git a/src/com/android/launcher3/InvariantDeviceProfile.java b/src/com/android/launcher3/InvariantDeviceProfile.java
index a4020f9..d97eac9 100644
--- a/src/com/android/launcher3/InvariantDeviceProfile.java
+++ b/src/com/android/launcher3/InvariantDeviceProfile.java
@@ -143,6 +143,8 @@
public @StyleRes int folderStyle;
+ public @StyleRes int cellStyle;
+
public float[] horizontalMargin;
public PointF[] allAppsCellSize;
@@ -206,8 +208,6 @@
if (!newGridName.equals(gridName)) {
LauncherPrefs.getPrefs(context).edit().putString(KEY_IDP_GRID_NAME, newGridName)
.apply();
- Log.d("b/258560494", "InvariantDeviceProfile - setting newGridName: " + newGridName
- + ", gridName: " + gridName);
}
new DeviceGridState(this).writeToPrefs(context);
@@ -351,6 +351,8 @@
numFolderColumns = closestProfile.numFolderColumns;
folderStyle = closestProfile.folderStyle;
+ cellStyle = closestProfile.cellStyle;
+
isScalable = closestProfile.isScalable;
devicePaddingId = closestProfile.devicePaddingId;
this.deviceType = deviceType;
@@ -455,7 +457,6 @@
public void setCurrentGrid(Context context, String gridName) {
Context appContext = context.getApplicationContext();
LauncherPrefs.getPrefs(appContext).edit().putString(KEY_IDP_GRID_NAME, gridName).apply();
- Log.d("b/258560494", "setCurrentGrid: " + gridName);
MAIN_EXECUTOR.execute(() -> onConfigChanged(appContext));
}
@@ -520,10 +521,6 @@
}
}
if (filteredProfiles.isEmpty()) {
- if (gridName != null) {
- Log.d("b/258560494", "No matching grid from for gridName: " + gridName
- + ", deviceType: " + deviceType);
- }
// No grid found, use the default options
for (DisplayOption option : profiles) {
if (option.canBeDefault) {
@@ -790,6 +787,7 @@
private final int numFolderRows;
private final int numFolderColumns;
private final @StyleRes int folderStyle;
+ private final @StyleRes int cellStyle;
private final int numAllAppsColumns;
private final int numDatabaseAllAppsColumns;
@@ -859,6 +857,9 @@
folderStyle = a.getResourceId(R.styleable.GridDisplayOption_folderStyle,
INVALID_RESOURCE_HANDLE);
+ cellStyle = a.getResourceId(R.styleable.GridDisplayOption_cellStyle,
+ R.style.CellStyleDefault);
+
isScalable = a.getBoolean(
R.styleable.GridDisplayOption_isScalable, false);
devicePaddingId = a.getResourceId(
diff --git a/src/com/android/launcher3/Launcher.java b/src/com/android/launcher3/Launcher.java
index af6935f..e9b9f31 100644
--- a/src/com/android/launcher3/Launcher.java
+++ b/src/com/android/launcher3/Launcher.java
@@ -76,11 +76,9 @@
import android.appwidget.AppWidgetHostView;
import android.appwidget.AppWidgetManager;
import android.content.ActivityNotFoundException;
-import android.content.BroadcastReceiver;
import android.content.ComponentCallbacks2;
import android.content.Context;
import android.content.Intent;
-import android.content.IntentFilter;
import android.content.IntentSender;
import android.content.SharedPreferences;
import android.content.pm.PackageManager;
@@ -134,7 +132,6 @@
import com.android.launcher3.allapps.AllAppsRecyclerView;
import com.android.launcher3.allapps.AllAppsStore;
import com.android.launcher3.allapps.AllAppsTransitionController;
-import com.android.launcher3.allapps.BaseAllAppsContainerView;
import com.android.launcher3.allapps.BaseSearchConfig;
import com.android.launcher3.allapps.DiscoveryBounce;
import com.android.launcher3.anim.PropertyListBuilder;
@@ -198,6 +195,8 @@
import com.android.launcher3.util.PendingRequestArgs;
import com.android.launcher3.util.RunnableList;
import com.android.launcher3.util.SafeCloseable;
+import com.android.launcher3.util.ScreenOnTracker;
+import com.android.launcher3.util.ScreenOnTracker.ScreenOnListener;
import com.android.launcher3.util.SystemUiController;
import com.android.launcher3.util.Themes;
import com.android.launcher3.util.Thunk;
@@ -536,9 +535,8 @@
}
getRootView().dispatchInsets();
- // Listen for broadcasts
- registerReceiver(mScreenOffReceiver, new IntentFilter(Intent.ACTION_SCREEN_OFF));
-
+ // Listen for screen turning off
+ ScreenOnTracker.INSTANCE.get(this).addListener(mScreenOnListener);
getSystemUiController().updateUiState(SystemUiController.UI_STATE_BASE_WINDOW,
Themes.getAttrBoolean(this, R.attr.isWorkspaceDarkText));
@@ -561,6 +559,61 @@
setTitle(R.string.home_screen);
}
+ /**
+ * Provide {@link OnBackPressedHandler} in below order:
+ * <ol>
+ * <li> auto cancel action mode handler
+ * <li> drag handler
+ * <li> view handler
+ * <li> state handler
+ * </ol>
+ *
+ * A back gesture (a single click on back button, or a swipe back gesture that contains a series
+ * of swipe events) should be handled by the same handler from above list. For a new back
+ * gesture, a new handler should be regenerated.
+ *
+ * Note that state handler will always be handling the back press event if the previous 3 don't.
+ */
+ @NonNull
+ protected OnBackPressedHandler getOnBackPressedHandler() {
+ // #1 auto cancel action mode handler
+ if (isInAutoCancelActionMode()) {
+ return this::finishAutoCancelActionMode;
+ }
+
+ // #2 drag handler
+ if (mDragController.isDragging()) {
+ return mDragController::cancelDrag;
+ }
+
+ // #3 view handler
+ AbstractFloatingView topView =
+ AbstractFloatingView.getTopOpenView(Launcher.this);
+ if (topView != null && topView.canHandleBack()) {
+ return topView;
+ }
+
+ // #4 state handler
+ return new OnBackPressedHandler() {
+ @Override
+ public void onBackInvoked() {
+ onStateBack();
+ }
+
+ @Override
+ public void onBackProgressed(
+ @FloatRange(from = 0.0, to = 1.0) float backProgress) {
+ mStateManager.getState().onBackProgressed(
+ Launcher.this, backProgress);
+ }
+
+ @Override
+ public void onBackCancelled() {
+ mStateManager.getState().onBackCancelled(Launcher.this);
+ }
+ };
+ }
+
protected LauncherOverlayManager getDefaultOverlay() {
return new LauncherOverlayManager() { };
}
@@ -1476,12 +1529,7 @@
hostView.setOnFocusChangeListener(mFocusHandler);
}
- private final BroadcastReceiver mScreenOffReceiver = new BroadcastReceiver() {
- @Override
- public void onReceive(Context context, Intent intent) {
- onScreenOff();
- }
- };
+ private final ScreenOnListener mScreenOnListener = this::onScreenOnChanged;
private void updateNotificationDots(Predicate<PackageUserKey> updatedDots) {
mWorkspace.updateNotificationDots(updatedDots);
@@ -1648,7 +1696,7 @@
private void showAllAppsWorkTabFromIntent(boolean alreadyOnHome) {
showAllAppsFromIntent(alreadyOnHome);
- mAppsView.switchToTab(BaseAllAppsContainerView.AdapterHolder.WORK);
+ mAppsView.switchToTab(ActivityAllAppsContainerView.AdapterHolder.WORK);
}
/**
@@ -1715,7 +1763,7 @@
super.onDestroy();
ACTIVITY_TRACKER.onActivityDestroyed(this);
- unregisterReceiver(mScreenOffReceiver);
+ ScreenOnTracker.INSTANCE.get(this).removeListener(mScreenOnListener);
mWorkspace.removeFolderListeners();
PluginManagerWrapper.INSTANCE.get(this).removePluginListener(this);
@@ -2053,40 +2101,17 @@
@Override
public void onBackPressed() {
- if (finishAutoCancelActionMode()) {
- return;
- }
-
- if (mDragController.isDragging()) {
- mDragController.cancelDrag();
- return;
- }
-
- // Note: There should be at most one log per method call. This is enforced implicitly
- // by using if-else statements.
- AbstractFloatingView topView = AbstractFloatingView.getTopOpenView(this);
- if (topView == null || !topView.onBackPressed()) {
- // Not handled by the floating view.
- onStateBack();
- }
+ getOnBackPressedHandler().onBackInvoked();
}
protected void onStateBack() {
mStateManager.getState().onBackPressed(this);
}
- protected void onBackProgressed(@FloatRange(from = 0.0, to = 1.0) float backProgress) {
- mStateManager.getState().onBackProgressed(this, backProgress);
- }
-
- protected void onBackCancelled() {
- mStateManager.getState().onBackCancelled(this);
- }
-
- protected void onScreenOff() {
+ protected void onScreenOnChanged(boolean isOn) {
// Reset AllApps to its initial state only if we are not in the middle of
// processing a multi-step drop
- if (mPendingRequestArgs == null) {
+ if (!isOn && mPendingRequestArgs == null) {
if (!isInState(NORMAL)) {
onUiChangedWhileSleeping();
}
diff --git a/src/com/android/launcher3/LauncherAppState.java b/src/com/android/launcher3/LauncherAppState.java
index 3461601..2b98d98 100644
--- a/src/com/android/launcher3/LauncherAppState.java
+++ b/src/com/android/launcher3/LauncherAppState.java
@@ -102,7 +102,7 @@
Intent.ACTION_MANAGED_PROFILE_UNLOCKED,
ACTION_DEVICE_POLICY_RESOURCE_UPDATED);
if (FeatureFlags.IS_STUDIO_BUILD) {
- modelChangeReceiver.register(mContext, Context.RECEIVER_EXPORTED, ACTION_FORCE_ROLOAD);
+ modelChangeReceiver.register(mContext, ACTION_FORCE_ROLOAD);
}
mOnTerminateCallback.add(() -> mContext.unregisterReceiver(modelChangeReceiver));
diff --git a/src/com/android/launcher3/OnBackPressedHandler.java b/src/com/android/launcher3/OnBackPressedHandler.java
new file mode 100644
index 0000000..485aa0a
--- /dev/null
+++ b/src/com/android/launcher3/OnBackPressedHandler.java
@@ -0,0 +1,45 @@
+/*
+ * 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;
+
+import androidx.annotation.FloatRange;
+
+/**
+ * Interface that mimics {@link android.window.OnBackInvokedCallback} without dependencies on U's
+ * API such as {@link android.window.BackEvent}.
+ *
+ * <p> Impl can assume below order during a back gesture:
+ * <ol>
+ * <li> [optional] one {@link #onBackStarted()} will be called to start the gesture
+ * <li> zero or multiple {@link #onBackProgressed(float)} will be called during swipe gesture
+ * <li> either one of {@link #onBackInvoked()} or {@link #onBackCancelled()} will be called to end
+ * the gesture
+ */
+public interface OnBackPressedHandler {
+
+ /** Called when back has started. */
+ default void onBackStarted() {}
+
+ /** Called when back is committed. */
+ void onBackInvoked();
+
+ /** Called with back gesture's progress. */
+ default void onBackProgressed(@FloatRange(from = 0.0, to = 1.0) float backProgress) {}
+
+ /** Called when user drops the back gesture. */
+ default void onBackCancelled() {}
+}
diff --git a/src/com/android/launcher3/allapps/ActivityAllAppsContainerView.java b/src/com/android/launcher3/allapps/ActivityAllAppsContainerView.java
index 2511cada..3aa9f7c 100644
--- a/src/com/android/launcher3/allapps/ActivityAllAppsContainerView.java
+++ b/src/com/android/launcher3/allapps/ActivityAllAppsContainerView.java
@@ -15,25 +15,74 @@
*/
package com.android.launcher3.allapps;
-import static com.android.launcher3.allapps.BaseAllAppsContainerView.AdapterHolder.SEARCH;
+import static com.android.launcher3.allapps.ActivityAllAppsContainerView.AdapterHolder.SEARCH;
+import static com.android.launcher3.logging.StatsLogManager.LauncherEvent.LAUNCHER_ALLAPPS_COUNT;
+import static com.android.launcher3.logging.StatsLogManager.LauncherEvent.LAUNCHER_ALLAPPS_TAP_ON_PERSONAL_TAB;
+import static com.android.launcher3.logging.StatsLogManager.LauncherEvent.LAUNCHER_ALLAPPS_TAP_ON_WORK_TAB;
+import android.animation.Animator;
+import android.animation.AnimatorListenerAdapter;
+import android.animation.ValueAnimator;
import android.content.Context;
+import android.graphics.Canvas;
+import android.graphics.Color;
+import android.graphics.Paint;
+import android.graphics.Path;
+import android.graphics.Path.Direction;
+import android.graphics.Point;
+import android.graphics.Rect;
+import android.graphics.RectF;
+import android.os.Bundle;
+import android.os.Parcelable;
+import android.os.Process;
+import android.os.UserManager;
import android.util.AttributeSet;
+import android.util.Log;
+import android.util.SparseArray;
+import android.util.TypedValue;
import android.view.KeyEvent;
+import android.view.LayoutInflater;
import android.view.MotionEvent;
import android.view.View;
+import android.view.WindowInsets;
+import android.widget.Button;
import android.widget.RelativeLayout;
+import androidx.annotation.NonNull;
+import androidx.annotation.Nullable;
+import androidx.annotation.VisibleForTesting;
import androidx.core.graphics.ColorUtils;
import androidx.recyclerview.widget.RecyclerView;
+import com.android.launcher3.DeviceProfile;
+import com.android.launcher3.DeviceProfile.OnDeviceProfileChangeListener;
+import com.android.launcher3.DragSource;
+import com.android.launcher3.DropTarget.DragObject;
+import com.android.launcher3.Insettable;
+import com.android.launcher3.InsettableFrameLayout;
import com.android.launcher3.R;
import com.android.launcher3.Utilities;
import com.android.launcher3.allapps.BaseAllAppsAdapter.AdapterItem;
+import com.android.launcher3.allapps.search.DefaultSearchAdapterProvider;
+import com.android.launcher3.allapps.search.SearchAdapterProvider;
import com.android.launcher3.config.FeatureFlags;
+import com.android.launcher3.keyboard.FocusedItemDecorator;
+import com.android.launcher3.model.StringCache;
+import com.android.launcher3.model.data.ItemInfo;
+import com.android.launcher3.util.ItemInfoMatcher;
+import com.android.launcher3.util.Themes;
import com.android.launcher3.views.ActivityContext;
+import com.android.launcher3.views.BaseDragLayer;
+import com.android.launcher3.views.RecyclerViewFastScroller;
+import com.android.launcher3.views.ScrimView;
+import com.android.launcher3.views.SpringRelativeLayout;
+import com.android.launcher3.workprofile.PersonalWorkSlidingTabStrip;
import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.List;
+import java.util.function.Predicate;
+import java.util.stream.Stream;
/**
* All apps container view with search support for use in a dragging activity.
@@ -41,16 +90,67 @@
* @param <T> Type of context inflating all apps.
*/
public class ActivityAllAppsContainerView<T extends Context & ActivityContext>
- extends BaseAllAppsContainerView<T> {
+ extends SpringRelativeLayout implements DragSource, Insettable,
+ OnDeviceProfileChangeListener, PersonalWorkSlidingTabStrip.OnActivePageChangedListener,
+ ScrimView.ScrimDrawingController {
+ public static final float PULL_MULTIPLIER = .02f;
+ public static final float FLING_VELOCITY_MULTIPLIER = 1200f;
+ protected static final String BUNDLE_KEY_CURRENT_PAGE = "launcher.allapps.current_page";
private static final long DEFAULT_SEARCH_TRANSITION_DURATION_MS = 300;
+ // Render the header protection at all times to debug clipping issues.
+ private static final boolean DEBUG_HEADER_PROTECTION = false;
+ /** Context of an activity or window that is inflating this container. */
+
+ protected final T mActivityContext;
+ protected final List<AdapterHolder> mAH;
+ protected final Predicate<ItemInfo> mPersonalMatcher = ItemInfoMatcher.ofUser(
+ Process.myUserHandle());
+ protected final WorkProfileManager mWorkManager;
+ protected final Point mFastScrollerOffset = new Point();
+ protected final int mScrimColor;
+ protected final float mHeaderThreshold;
// Used to animate Search results out and A-Z apps in, or vice-versa.
private final SearchTransitionController mSearchTransitionController;
+ private final Paint mHeaderPaint = new Paint(Paint.ANTI_ALIAS_FLAG);
+ private final Rect mInsets = new Rect();
+ private final AllAppsStore mAllAppsStore = new AllAppsStore();
+ private final RecyclerView.OnScrollListener mScrollListener =
+ new RecyclerView.OnScrollListener() {
+ @Override
+ public void onScrolled(@NonNull RecyclerView recyclerView, int dx, int dy) {
+ updateHeaderScroll(recyclerView.computeVerticalScrollOffset());
+ }
+ };
+ private final Paint mNavBarScrimPaint;
+ private final int mHeaderProtectionColor;
+ private final Path mTmpPath = new Path();
+ private final RectF mTmpRectF = new RectF();
+ protected AllAppsPagedView mViewPager;
+ protected FloatingHeaderView mHeader;
+ protected View mBottomSheetBackground;
+ /**
+ * View that defines the search box. Result is rendered inside {@link #mSearchRecyclerView}.
+ */
+ protected View mSearchContainer;
+ protected SearchUiManager mSearchUiManager;
+ protected boolean mUsingTabs;
+ protected RecyclerViewFastScroller mTouchHandler;
/** {@code true} when rendered view is in search state instead of the scroll state. */
private boolean mIsSearching;
private boolean mRebindAdaptersAfterSearchAnimation;
+ private int mNavBarScrimHeight = 0;
+ private SearchRecyclerView mSearchRecyclerView;
+ protected SearchAdapterProvider<?> mMainAdapterProvider;
+ private View mBottomSheetHandleArea;
+ private boolean mHasWorkApps;
+ private float[] mBottomSheetCornerRadii;
+ private ScrimView mScrimView;
+ private int mHeaderColor;
+ private int mBottomSheetBackgroundColor;
+ private int mTabsProtectionAlpha;
public ActivityAllAppsContainerView(Context context) {
this(context, null);
@@ -62,13 +162,87 @@
public ActivityAllAppsContainerView(Context context, AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
+ mActivityContext = ActivityContext.lookupContext(context);
+
+ mScrimColor = Themes.getAttrColor(context, R.attr.allAppsScrimColor);
+ mHeaderThreshold = getResources().getDimensionPixelSize(
+ R.dimen.dynamic_grid_cell_border_spacing);
+ mHeaderProtectionColor = Themes.getAttrColor(context, R.attr.allappsHeaderProtectionColor);
+
+ mWorkManager = new WorkProfileManager(
+ mActivityContext.getSystemService(UserManager.class),
+ this, mActivityContext.getStatsLogManager());
+ mAH = Arrays.asList(null, null, null);
+ mNavBarScrimPaint = new Paint();
+ mNavBarScrimPaint.setColor(Themes.getAttrColor(context, R.attr.allAppsNavBarScrimColor));
+
+ mAllAppsStore.addUpdateListener(this::onAppsUpdated);
+ mActivityContext.addOnDeviceProfileChangeListener(this);
+
+ // This is a focus listener that proxies focus from a view into the list view. This is to
+ // work around the search box from getting first focus and showing the cursor.
+ setOnFocusChangeListener((v, hasFocus) -> {
+ if (hasFocus && getActiveRecyclerView() != null) {
+ getActiveRecyclerView().requestFocus();
+ }
+ });
+ initContent();
mSearchTransitionController = new SearchTransitionController(this);
}
+ /**
+ * Initializes the view hierarchy and internal variables. Any initialization which actually uses
+ * these members should be done in {@link #onFinishInflate()}.
+ * In terms of subclass initialization, the following would be parallel order for activity:
+ * initContent -> onPreCreate
+ * constructor/init -> onCreate
+ * onFinishInflate -> onPostCreate
+ */
+ protected void initContent() {
+ mMainAdapterProvider = createMainAdapterProvider();
+
+ mAH.set(AdapterHolder.MAIN, new AdapterHolder(AdapterHolder.MAIN,
+ new AlphabeticalAppsList<>(mActivityContext, mAllAppsStore, null)));
+ mAH.set(AdapterHolder.WORK, new AdapterHolder(AdapterHolder.WORK,
+ new AlphabeticalAppsList<>(mActivityContext, mAllAppsStore, mWorkManager)));
+ mAH.set(SEARCH, new AdapterHolder(SEARCH,
+ new AlphabeticalAppsList<>(mActivityContext, null, null)));
+
+ getLayoutInflater().inflate(R.layout.all_apps_content, this);
+ mHeader = findViewById(R.id.all_apps_header);
+ mBottomSheetBackground = findViewById(R.id.bottom_sheet_background);
+ mBottomSheetHandleArea = findViewById(R.id.bottom_sheet_handle_area);
+ mSearchRecyclerView = findViewById(R.id.search_results_list_view);
+
+ // Add the search box next to the header
+ mSearchContainer = inflateSearchBox();
+ addView(mSearchContainer, indexOfChild(mHeader) + 1);
+ mSearchUiManager = (SearchUiManager) mSearchContainer;
+ }
+
@Override
protected void onFinishInflate() {
super.onFinishInflate();
+
+ mAH.get(SEARCH).setup(mSearchRecyclerView,
+ /* Filter out A-Z apps */ itemInfo -> false);
+ rebindAdapters(true /* force */);
+ float cornerRadius = Themes.getDialogCornerRadius(getContext());
+ mBottomSheetCornerRadii = new float[]{
+ cornerRadius,
+ cornerRadius, // Top left radius in px
+ cornerRadius,
+ cornerRadius, // Top right radius in px
+ 0,
+ 0, // Bottom right
+ 0,
+ 0 // Bottom left
+ };
+ final TypedValue value = new TypedValue();
+ getContext().getTheme().resolveAttribute(android.R.attr.colorBackground, value, true);
+ mBottomSheetBackgroundColor = value.data;
+ updateBackground(mActivityContext.getDeviceProfile());
mSearchUiManager.initializeSearch(this);
}
@@ -141,19 +315,43 @@
});
}
- @Override
public boolean shouldContainerScroll(MotionEvent ev) {
+ BaseDragLayer dragLayer = mActivityContext.getDragLayer();
// IF the MotionEvent is inside the search box, and the container keeps on receiving
// touch input, container should move down.
- if (mActivityContext.getDragLayer().isEventOverView(mSearchContainer, ev)) {
+ if (dragLayer.isEventOverView(mSearchContainer, ev)) {
return true;
}
- return super.shouldContainerScroll(ev);
+ // Scroll if not within the container view (e.g. over large-screen scrim).
+ if (!dragLayer.isEventOverView(getVisibleContainerView(), ev)) {
+ return true;
+ }
+ if (dragLayer.isEventOverView(mBottomSheetHandleArea, ev)) {
+ return true;
+ }
+ AllAppsRecyclerView rv = getActiveRecyclerView();
+ if (rv == null) {
+ return true;
+ }
+ if (rv.getScrollbar() != null
+ && rv.getScrollbar().getThumbOffsetY() >= 0
+ && dragLayer.isEventOverView(rv.getScrollbar(), ev)) {
+ return false;
+ }
+ return rv.shouldContainerScroll(ev, dragLayer);
}
- @Override
public void reset(boolean animate) {
- super.reset(animate);
+ for (int i = 0; i < mAH.size(); i++) {
+ if (mAH.get(i).mRecyclerView != null) {
+ mAH.get(i).mRecyclerView.scrollToTop();
+ }
+ }
+ if (mHeader != null && mHeader.getVisibility() == VISIBLE) {
+ mHeader.reset(animate);
+ }
+ // Reset the base recycler view after transitioning home.
+ updateHeaderScroll(0);
// Reset the search bar after transitioning home.
mSearchUiManager.resetSearch();
// Animate to A-Z with 0 time to reset the animation with proper state management.
@@ -166,16 +364,26 @@
return super.dispatchKeyEvent(event);
}
- @Override
public String getDescription() {
if (!mUsingTabs && isSearching()) {
return getContext().getString(R.string.all_apps_search_results);
} else {
- return super.getDescription();
+ StringCache cache = mActivityContext.getStringCache();
+ if (mUsingTabs) {
+ if (cache != null) {
+ return isPersonalTab()
+ ? cache.allAppsPersonalTabAccessibility
+ : cache.allAppsWorkTabAccessibility;
+ } else {
+ return isPersonalTab()
+ ? getContext().getString(R.string.all_apps_button_personal_label)
+ : getContext().getString(R.string.all_apps_button_work_label);
+ }
+ }
+ return getContext().getString(R.string.all_apps_button_label);
}
}
- @Override
public boolean isSearching() {
return mIsSearching;
}
@@ -186,30 +394,112 @@
// Will be called at the end of the animation.
return;
}
- super.onActivePageChanged(currentActivePage);
+ if (mAH.get(currentActivePage).mRecyclerView != null) {
+ mAH.get(currentActivePage).mRecyclerView.bindFastScrollbar();
+ }
+ // Header keeps track of active recycler view to properly render header protection.
+ mHeader.setActiveRV(currentActivePage);
+ reset(true /* animate */);
+
+ mWorkManager.onActivePageChanged(currentActivePage);
}
- @Override
+ protected void rebindAdapters() {
+ rebindAdapters(false /* force */);
+ }
+
protected void rebindAdapters(boolean force) {
if (mSearchTransitionController.isRunning()) {
mRebindAdaptersAfterSearchAnimation = true;
return;
}
- super.rebindAdapters(force);
- if (!FeatureFlags.ENABLE_DEVICE_SEARCH.get()
- || getMainAdapterProvider().getDecorator() == null
- || getSearchRecyclerView() == null) {
+ updateSearchResultsVisibility();
+
+ boolean showTabs = shouldShowTabs();
+ if (showTabs == mUsingTabs && !force) {
return;
}
- RecyclerView.ItemDecoration decoration = getMainAdapterProvider().getDecorator();
- getSearchRecyclerView().removeItemDecoration(decoration); // In case it is already added.
- getSearchRecyclerView().addItemDecoration(decoration);
+ if (isSearching()) {
+ mUsingTabs = showTabs;
+ mWorkManager.detachWorkModeSwitch();
+ return;
+ }
+
+ // replaceAppsRVcontainer() needs to use both mUsingTabs value to remove the old view AND
+ // showTabs value to create new view. Hence the mUsingTabs new value assignment MUST happen
+ // after this call.
+ replaceAppsRVContainer(showTabs);
+ mUsingTabs = showTabs;
+
+ mAllAppsStore.unregisterIconContainer(mAH.get(AdapterHolder.MAIN).mRecyclerView);
+ mAllAppsStore.unregisterIconContainer(mAH.get(AdapterHolder.WORK).mRecyclerView);
+ mAllAppsStore.unregisterIconContainer(mAH.get(AdapterHolder.SEARCH).mRecyclerView);
+
+ if (mUsingTabs) {
+ mAH.get(AdapterHolder.MAIN).setup(mViewPager.getChildAt(0), mPersonalMatcher);
+ mAH.get(AdapterHolder.WORK).setup(mViewPager.getChildAt(1), mWorkManager.getMatcher());
+ mAH.get(AdapterHolder.WORK).mRecyclerView.setId(R.id.apps_list_view_work);
+ if (FeatureFlags.ENABLE_EXPANDING_PAUSE_WORK_BUTTON.get()) {
+ mAH.get(AdapterHolder.WORK).mRecyclerView.addOnScrollListener(
+ mWorkManager.newScrollListener());
+ }
+ mViewPager.getPageIndicator().setActiveMarker(AdapterHolder.MAIN);
+ findViewById(R.id.tab_personal)
+ .setOnClickListener((View view) -> {
+ if (mViewPager.snapToPage(AdapterHolder.MAIN)) {
+ mActivityContext.getStatsLogManager().logger()
+ .log(LAUNCHER_ALLAPPS_TAP_ON_PERSONAL_TAB);
+ }
+ mActivityContext.hideKeyboard();
+ });
+ findViewById(R.id.tab_work)
+ .setOnClickListener((View view) -> {
+ if (mViewPager.snapToPage(AdapterHolder.WORK)) {
+ mActivityContext.getStatsLogManager().logger()
+ .log(LAUNCHER_ALLAPPS_TAP_ON_WORK_TAB);
+ }
+ mActivityContext.hideKeyboard();
+ });
+ setDeviceManagementResources();
+ onActivePageChanged(mViewPager.getNextPage());
+ } else {
+ mAH.get(AdapterHolder.MAIN).setup(findViewById(R.id.apps_list_view), null);
+ mAH.get(AdapterHolder.WORK).mRecyclerView = null;
+ }
+ setupHeader();
+
+ mAllAppsStore.registerIconContainer(mAH.get(AdapterHolder.MAIN).mRecyclerView);
+ mAllAppsStore.registerIconContainer(mAH.get(AdapterHolder.WORK).mRecyclerView);
+ mAllAppsStore.registerIconContainer(mAH.get(AdapterHolder.SEARCH).mRecyclerView);
}
- @Override
protected View replaceAppsRVContainer(boolean showTabs) {
- View rvContainer = super.replaceAppsRVContainer(showTabs);
+ for (int i = AdapterHolder.MAIN; i <= AdapterHolder.WORK; i++) {
+ AdapterHolder adapterHolder = mAH.get(i);
+ if (adapterHolder.mRecyclerView != null) {
+ adapterHolder.mRecyclerView.setLayoutManager(null);
+ adapterHolder.mRecyclerView.setAdapter(null);
+ }
+ }
+ View oldView = getAppsRecyclerViewContainer();
+ int index = indexOfChild(oldView);
+ removeView(oldView);
+ int layout = showTabs ? R.layout.all_apps_tabs : R.layout.all_apps_rv_layout;
+ final View rvContainer = getLayoutInflater().inflate(layout, this, false);
+ addView(rvContainer, index);
+ if (showTabs) {
+ mViewPager = (AllAppsPagedView) rvContainer;
+ mViewPager.initParentViews(this);
+ mViewPager.getPageIndicator().setOnActivePageChangedListener(this);
+
+ mWorkManager.reset();
+ post(() -> mAH.get(AdapterHolder.WORK).applyPadding());
+
+ } else {
+ mWorkManager.detachWorkModeSwitch();
+ mViewPager = null;
+ }
removeCustomRules(rvContainer);
removeCustomRules(getSearchRecyclerView());
@@ -228,21 +518,47 @@
return rvContainer;
}
- @Override
void setupHeader() {
- super.setupHeader();
+ mHeader.setVisibility(View.VISIBLE);
+ boolean tabsHidden = !mUsingTabs;
+ mHeader.setup(
+ mAH.get(AdapterHolder.MAIN).mRecyclerView,
+ mAH.get(AdapterHolder.WORK).mRecyclerView,
+ (SearchRecyclerView) mAH.get(SEARCH).mRecyclerView,
+ getCurrentPage(),
+ tabsHidden);
+
+ int padding = mHeader.getMaxTranslation();
+ mAH.forEach(adapterHolder -> {
+ adapterHolder.mPadding.top = padding;
+ adapterHolder.applyPadding();
+ if (adapterHolder.mRecyclerView != null) {
+ adapterHolder.mRecyclerView.scrollToTop();
+ }
+ });
removeCustomRules(mHeader);
- if (FeatureFlags.ENABLE_FLOATING_SEARCH_BAR.get()) {
+ if (!isSearchSupported()) {
+ layoutWithoutSearchContainer(mHeader, false /* includeTabsMargin */);
+ } else if (FeatureFlags.ENABLE_FLOATING_SEARCH_BAR.get()) {
alignParentTop(mHeader, false /* includeTabsMargin */);
} else {
layoutBelowSearchContainer(mHeader, false /* includeTabsMargin */);
}
}
- @Override
protected void updateHeaderScroll(int scrolledOffset) {
- super.updateHeaderScroll(scrolledOffset);
+ float prog1 = Utilities.boundToRange((float) scrolledOffset / mHeaderThreshold, 0f, 1f);
+ int headerColor = getHeaderColor(prog1);
+ int tabsAlpha = mHeader.getPeripheralProtectionHeight() == 0 ? 0
+ : (int) (Utilities.boundToRange(
+ (scrolledOffset + mHeader.mSnappedScrolledY) / mHeaderThreshold, 0f, 1f)
+ * 255);
+ if (headerColor != mHeaderColor || mTabsProtectionAlpha != tabsAlpha) {
+ mHeaderColor = headerColor;
+ mTabsProtectionAlpha = tabsAlpha;
+ invalidateHeader();
+ }
if (mSearchUiManager.getEditText() == null) {
return;
}
@@ -257,10 +573,9 @@
mSearchUiManager.setBackgroundVisibility(bgVisible, 1 - prog);
}
- @Override
protected int getHeaderColor(float blendRatio) {
return ColorUtils.setAlphaComponent(
- super.getHeaderColor(blendRatio),
+ ColorUtils.blendARGB(mScrimColor, mHeaderProtectionColor, blendRatio),
(int) (mSearchContainer.getAlpha() * 255));
}
@@ -315,11 +630,9 @@
layoutParams.removeRule(RelativeLayout.ALIGN_PARENT_TOP);
}
- @Override
- protected BaseAllAppsAdapter<T> createAdapter(AlphabeticalAppsList<T> appsList,
- BaseAdapterProvider[] adapterProviders) {
+ protected BaseAllAppsAdapter<T> createAdapter(AlphabeticalAppsList<T> appsList) {
return new AllAppsGridAdapter<>(mActivityContext, getLayoutInflater(), appsList,
- adapterProviders);
+ mMainAdapterProvider);
}
// TODO(b/216683257): Remove when Taskbar All Apps supports search.
@@ -339,9 +652,549 @@
: R.dimen.all_apps_header_top_margin);
}
- @Override
public boolean isInAllApps() {
// TODO: Make this abstract
return true;
}
+
+ /**
+ * Inflates the search box
+ */
+ protected View inflateSearchBox() {
+ return getLayoutInflater().inflate(R.layout.search_container_all_apps, this, false);
+ }
+
+ /** Creates the adapter provider for the main section. */
+ protected SearchAdapterProvider<?> createMainAdapterProvider() {
+ return new DefaultSearchAdapterProvider(mActivityContext);
+ }
+
+ /** The adapter provider for the main section. */
+ public final SearchAdapterProvider<?> getMainAdapterProvider() {
+ return mMainAdapterProvider;
+ }
+
+ @Override
+ protected void dispatchRestoreInstanceState(SparseArray<Parcelable> sparseArray) {
+ try {
+ // Many slice view id is not properly assigned, and hence throws null
+ // pointer exception in the underneath method. Catching the exception
+ // simply doesn't restore these slice views. This doesn't have any
+ // user visible effect because because we query them again.
+ super.dispatchRestoreInstanceState(sparseArray);
+ } catch (Exception e) {
+ Log.e("AllAppsContainerView", "restoreInstanceState viewId = 0", e);
+ }
+
+ Bundle state = (Bundle) sparseArray.get(R.id.work_tab_state_id, null);
+ if (state != null) {
+ int currentPage = state.getInt(BUNDLE_KEY_CURRENT_PAGE, 0);
+ if (currentPage == AdapterHolder.WORK && mViewPager != null) {
+ mViewPager.setCurrentPage(currentPage);
+ rebindAdapters();
+ } else {
+ reset(true);
+ }
+ }
+ }
+
+ @Override
+ protected void dispatchSaveInstanceState(SparseArray<Parcelable> container) {
+ super.dispatchSaveInstanceState(container);
+ Bundle state = new Bundle();
+ state.putInt(BUNDLE_KEY_CURRENT_PAGE, getCurrentPage());
+ container.put(R.id.work_tab_state_id, state);
+ }
+
+ /**
+ * Sets the long click listener for icons
+ */
+ public void setOnIconLongClickListener(OnLongClickListener listener) {
+ for (AdapterHolder holder : mAH) {
+ holder.mAdapter.setOnIconLongClickListener(listener);
+ }
+ }
+
+ public AllAppsStore getAppsStore() {
+ return mAllAppsStore;
+ }
+
+ public WorkProfileManager getWorkManager() {
+ return mWorkManager;
+ }
+
+ @Override
+ public void onDeviceProfileChanged(DeviceProfile dp) {
+ for (AdapterHolder holder : mAH) {
+ holder.mAdapter.setAppsPerRow(dp.numShownAllAppsColumns);
+ if (holder.mRecyclerView != null) {
+ // Remove all views and clear the pool, while keeping the data same. After this
+ // call, all the viewHolders will be recreated.
+ holder.mRecyclerView.swapAdapter(holder.mRecyclerView.getAdapter(), true);
+ holder.mRecyclerView.getRecycledViewPool().clear();
+ }
+ }
+ updateBackground(dp);
+ }
+
+ protected void updateBackground(DeviceProfile deviceProfile) {
+ mBottomSheetBackground.setVisibility(deviceProfile.isTablet ? View.VISIBLE : View.GONE);
+ // Note: For tablets, the opaque background and header protection are added in drawOnScrim.
+ // For the taskbar entrypoint, the scrim is drawn differently, so a static background is
+ // added in TaskbarAllAppsContainerView and header protection is not yet supported.
+ }
+
+ private void onAppsUpdated() {
+ mHasWorkApps = Stream.of(mAllAppsStore.getApps()).anyMatch(mWorkManager.getMatcher());
+ if (!isSearching()) {
+ rebindAdapters();
+ if (mHasWorkApps) {
+ mWorkManager.reset();
+ }
+ }
+
+ mActivityContext.getStatsLogManager().logger()
+ .withCardinality(mAllAppsStore.getApps().length)
+ .log(LAUNCHER_ALLAPPS_COUNT);
+ }
+
+ @Override
+ public boolean onInterceptTouchEvent(MotionEvent ev) {
+ // The AllAppsContainerView houses the QSB and is hence visible from the Workspace
+ // Overview states. We shouldn't intercept for the scrubber in these cases.
+ if (!isInAllApps()) {
+ mTouchHandler = null;
+ return false;
+ }
+
+ if (ev.getAction() == MotionEvent.ACTION_DOWN) {
+ AllAppsRecyclerView rv = getActiveRecyclerView();
+ if (rv != null && rv.getScrollbar() != null
+ && rv.getScrollbar().isHitInParent(ev.getX(), ev.getY(), mFastScrollerOffset)) {
+ mTouchHandler = rv.getScrollbar();
+ } else {
+ mTouchHandler = null;
+ }
+ }
+ if (mTouchHandler != null) {
+ return mTouchHandler.handleTouchEvent(ev, mFastScrollerOffset);
+ }
+ return false;
+ }
+
+ @Override
+ public boolean onTouchEvent(MotionEvent ev) {
+ if (!isInAllApps()) {
+ return false;
+ }
+
+ if (ev.getAction() == MotionEvent.ACTION_DOWN) {
+ AllAppsRecyclerView rv = getActiveRecyclerView();
+ if (rv != null && rv.getScrollbar() != null
+ && rv.getScrollbar().isHitInParent(ev.getX(), ev.getY(), mFastScrollerOffset)) {
+ mTouchHandler = rv.getScrollbar();
+ } else {
+ mTouchHandler = null;
+
+ }
+ }
+ if (mTouchHandler != null) {
+ mTouchHandler.handleTouchEvent(ev, mFastScrollerOffset);
+ return true;
+ }
+ if (isSearching()
+ && mActivityContext.getDragLayer().isEventOverView(getVisibleContainerView(), ev)) {
+ // if in search state, consume touch event.
+ return true;
+ }
+ return false;
+ }
+
+ /** The current active recycler view (A-Z list from one of the profiles, or search results). */
+ public AllAppsRecyclerView getActiveRecyclerView() {
+ if (isSearching()) {
+ return getSearchRecyclerView();
+ }
+ return getActiveAppsRecyclerView();
+ }
+
+ /** The current apps recycler view in the container. */
+ private AllAppsRecyclerView getActiveAppsRecyclerView() {
+ if (!mUsingTabs || isPersonalTab()) {
+ return mAH.get(AdapterHolder.MAIN).mRecyclerView;
+ } else {
+ return mAH.get(AdapterHolder.WORK).mRecyclerView;
+ }
+ }
+
+ /**
+ * The container for A-Z apps (the ViewPager for main+work tabs, or main RV). This is currently
+ * hidden while searching.
+ **/
+ protected View getAppsRecyclerViewContainer() {
+ return mViewPager != null ? mViewPager : findViewById(R.id.apps_list_view);
+ }
+
+ /** The RV for search results, which is hidden while A-Z apps are visible. */
+ public SearchRecyclerView getSearchRecyclerView() {
+ return mSearchRecyclerView;
+ }
+
+ protected boolean isPersonalTab() {
+ return mViewPager == null || mViewPager.getNextPage() == 0;
+ }
+
+ /**
+ * Switches the current page to the provided {@code tab} if tabs are supported, otherwise does
+ * nothing.
+ */
+ public void switchToTab(int tab) {
+ if (mUsingTabs) {
+ mViewPager.setCurrentPage(tab);
+ }
+ }
+
+ public LayoutInflater getLayoutInflater() {
+ return LayoutInflater.from(getContext());
+ }
+
+ @Override
+ public void onDropCompleted(View target, DragObject d, boolean success) {}
+
+ @Override
+ public void setInsets(Rect insets) {
+ mInsets.set(insets);
+ DeviceProfile grid = mActivityContext.getDeviceProfile();
+
+ applyAdapterSideAndBottomPaddings(grid);
+
+ MarginLayoutParams mlp = (MarginLayoutParams) getLayoutParams();
+ mlp.leftMargin = insets.left;
+ mlp.rightMargin = insets.right;
+ setLayoutParams(mlp);
+
+ if (grid.isVerticalBarLayout()) {
+ setPadding(grid.workspacePadding.left, 0, grid.workspacePadding.right, 0);
+ } else {
+ int topPadding = grid.allAppsTopPadding;
+ if (FeatureFlags.ENABLE_FLOATING_SEARCH_BAR.get() && !grid.isTablet) {
+ topPadding += getResources().getDimensionPixelSize(
+ R.dimen.all_apps_additional_top_padding_floating_search);
+ }
+ setPadding(grid.allAppsLeftRightMargin, topPadding, grid.allAppsLeftRightMargin, 0);
+ }
+
+ InsettableFrameLayout.dispatchInsets(this, insets);
+ }
+
+ /**
+ * Returns a padding in case a scrim is shown on the bottom of the view and a padding is needed.
+ */
+ protected int computeNavBarScrimHeight(WindowInsets insets) {
+ return 0;
+ }
+
+ /**
+ * Returns the current height of nav bar scrim
+ */
+ public int getNavBarScrimHeight() {
+ return mNavBarScrimHeight;
+ }
+
+ @Override
+ public WindowInsets dispatchApplyWindowInsets(WindowInsets insets) {
+ mNavBarScrimHeight = computeNavBarScrimHeight(insets);
+ applyAdapterSideAndBottomPaddings(mActivityContext.getDeviceProfile());
+ return super.dispatchApplyWindowInsets(insets);
+ }
+
+ @Override
+ protected void dispatchDraw(Canvas canvas) {
+ super.dispatchDraw(canvas);
+
+ if (mNavBarScrimHeight > 0) {
+ canvas.drawRect(0, getHeight() - mNavBarScrimHeight, getWidth(), getHeight(),
+ mNavBarScrimPaint);
+ }
+ }
+
+ protected void updateSearchResultsVisibility() {
+ if (isSearching()) {
+ getSearchRecyclerView().setVisibility(VISIBLE);
+ getAppsRecyclerViewContainer().setVisibility(GONE);
+ mHeader.setVisibility(GONE);
+ } else {
+ getSearchRecyclerView().setVisibility(GONE);
+ getAppsRecyclerViewContainer().setVisibility(VISIBLE);
+ mHeader.setVisibility(VISIBLE);
+ }
+ if (mHeader.isSetUp()) {
+ mHeader.setActiveRV(getCurrentPage());
+ }
+ }
+
+ private void applyAdapterSideAndBottomPaddings(DeviceProfile grid) {
+ int bottomPadding = Math.max(mInsets.bottom, mNavBarScrimHeight);
+ mAH.forEach(adapterHolder -> {
+ adapterHolder.mPadding.bottom = bottomPadding;
+ adapterHolder.mPadding.left =
+ adapterHolder.mPadding.right = grid.allAppsLeftRightPadding;
+ adapterHolder.applyPadding();
+ });
+ }
+
+ private void setDeviceManagementResources() {
+ if (mActivityContext.getStringCache() != null) {
+ Button personalTab = findViewById(R.id.tab_personal);
+ personalTab.setText(mActivityContext.getStringCache().allAppsPersonalTab);
+
+ Button workTab = findViewById(R.id.tab_work);
+ workTab.setText(mActivityContext.getStringCache().allAppsWorkTab);
+ }
+ }
+
+ protected boolean shouldShowTabs() {
+ return mHasWorkApps;
+ }
+
+ // Used by tests only
+ private boolean isDescendantViewVisible(int viewId) {
+ final View view = findViewById(viewId);
+ if (view == null) return false;
+
+ if (!view.isShown()) return false;
+
+ return view.getGlobalVisibleRect(new Rect());
+ }
+
+ @VisibleForTesting
+ public boolean isPersonalTabVisible() {
+ return isDescendantViewVisible(R.id.tab_personal);
+ }
+
+ @VisibleForTesting
+ public boolean isWorkTabVisible() {
+ return isDescendantViewVisible(R.id.tab_work);
+ }
+
+ public AlphabeticalAppsList<T> getSearchResultList() {
+ return mAH.get(SEARCH).mAppsList;
+ }
+
+ public FloatingHeaderView getFloatingHeaderView() {
+ return mHeader;
+ }
+
+ @VisibleForTesting
+ public View getContentView() {
+ return isSearching() ? getSearchRecyclerView() : getAppsRecyclerViewContainer();
+ }
+
+ /** The current page visible in all apps. */
+ public int getCurrentPage() {
+ return isSearching()
+ ? SEARCH
+ : mViewPager == null ? AdapterHolder.MAIN : mViewPager.getNextPage();
+ }
+
+ /** The scroll bar for the active apps recycler view. */
+ public RecyclerViewFastScroller getScrollBar() {
+ AllAppsRecyclerView rv = getActiveAppsRecyclerView();
+ return rv == null ? null : rv.getScrollbar();
+ }
+
+ /**
+ * Adds an update listener to animator that adds springs to the animation.
+ */
+ public void addSpringFromFlingUpdateListener(ValueAnimator animator,
+ float velocity /* release velocity */,
+ float progress /* portion of the distance to travel*/) {
+ animator.addListener(new AnimatorListenerAdapter() {
+ @Override
+ public void onAnimationStart(Animator animator) {
+ float distance = (1 - progress) * getHeight(); // px
+ float settleVelocity = Math.min(0, distance
+ / (AllAppsTransitionController.INTERP_COEFF * animator.getDuration())
+ + velocity);
+ absorbSwipeUpVelocity(Math.max(1000, Math.abs(
+ Math.round(settleVelocity * FLING_VELOCITY_MULTIPLIER))));
+ }
+ });
+ }
+
+ /** Invoked when the container is pulled. */
+ public void onPull(float deltaDistance, float displacement) {
+ absorbPullDeltaDistance(PULL_MULTIPLIER * deltaDistance, PULL_MULTIPLIER * displacement);
+ // Current motion spec is to actually push and not pull
+ // on this surface. However, until EdgeEffect.onPush (b/190612804) is
+ // implemented at view level, we will simply pull
+ }
+
+ @Override
+ public void getDrawingRect(Rect outRect) {
+ super.getDrawingRect(outRect);
+ outRect.offset(0, (int) getTranslationY());
+ }
+
+ @Override
+ public void setTranslationY(float translationY) {
+ super.setTranslationY(translationY);
+ invalidateHeader();
+ }
+
+ public void setScrimView(ScrimView scrimView) {
+ mScrimView = scrimView;
+ }
+
+ @Override
+ public void drawOnScrimWithScale(Canvas canvas, float scale) {
+ boolean isTablet = mActivityContext.getDeviceProfile().isTablet;
+
+ // Draw full background panel for tablets.
+ if (isTablet) {
+ mHeaderPaint.setColor(mBottomSheetBackgroundColor);
+ View panel = (View) mBottomSheetBackground;
+ float translationY = ((View) panel.getParent()).getTranslationY();
+ mTmpRectF.set(panel.getLeft(), panel.getTop() + translationY,
+ panel.getRight(), panel.getBottom());
+ mTmpPath.reset();
+ mTmpPath.addRoundRect(mTmpRectF, mBottomSheetCornerRadii, Direction.CW);
+ canvas.drawPath(mTmpPath, mHeaderPaint);
+ }
+
+ if (DEBUG_HEADER_PROTECTION) {
+ mHeaderPaint.setColor(Color.MAGENTA);
+ mHeaderPaint.setAlpha(255);
+ } else {
+ mHeaderPaint.setColor(mHeaderColor);
+ mHeaderPaint.setAlpha((int) (getAlpha() * Color.alpha(mHeaderColor)));
+ }
+ if (mHeaderPaint.getColor() == mScrimColor || mHeaderPaint.getColor() == 0) {
+ return;
+ }
+ final float offset = (getVisibleContainerView().getHeight() * (1 - scale) / 2);
+ final float bottom =
+ scale * (getHeaderBottom() + getVisibleContainerView().getPaddingTop()) + offset;
+ FloatingHeaderView headerView = getFloatingHeaderView();
+ if (isTablet) {
+ // Start adding header protection if search bar or tabs will attach to the top.
+ if (!FeatureFlags.ENABLE_FLOATING_SEARCH_BAR.get() || mUsingTabs) {
+ View panel = (View) mBottomSheetBackground;
+ float translationY = ((View) panel.getParent()).getTranslationY();
+ mTmpRectF.set(panel.getLeft(), panel.getTop() + translationY, panel.getRight(),
+ bottom);
+ mTmpPath.reset();
+ mTmpPath.addRoundRect(mTmpRectF, mBottomSheetCornerRadii, Direction.CW);
+ canvas.drawPath(mTmpPath, mHeaderPaint);
+ }
+ } else {
+ canvas.drawRect(0, 0, canvas.getWidth(), bottom, mHeaderPaint);
+ }
+ int tabsHeight = headerView.getPeripheralProtectionHeight();
+ if (mTabsProtectionAlpha > 0 && tabsHeight != 0) {
+ if (DEBUG_HEADER_PROTECTION) {
+ mHeaderPaint.setColor(Color.BLUE);
+ mHeaderPaint.setAlpha(255);
+ } else {
+ mHeaderPaint.setAlpha((int) (getAlpha() * mTabsProtectionAlpha));
+ }
+ int left = 0;
+ int right = canvas.getWidth();
+ if (isTablet) {
+ left = mBottomSheetBackground.getLeft();
+ right = mBottomSheetBackground.getRight();
+ }
+ canvas.drawRect(left, bottom, right, bottom + tabsHeight, mHeaderPaint);
+ }
+ }
+
+ /**
+ * redraws header protection
+ */
+ public void invalidateHeader() {
+ if (mScrimView != null) {
+ mScrimView.invalidate();
+ }
+ }
+
+ /** Returns the position of the bottom edge of the header */
+ public int getHeaderBottom() {
+ int bottom = (int) getTranslationY() + mHeader.getClipTop();
+ if (FeatureFlags.ENABLE_FLOATING_SEARCH_BAR.get()) {
+ if (mActivityContext.getDeviceProfile().isTablet) {
+ return bottom + mBottomSheetBackground.getTop();
+ }
+ return bottom;
+ }
+ return bottom + mHeader.getTop();
+ }
+
+ /**
+ * Returns a view that denotes the visible part of all apps container view.
+ */
+ public View getVisibleContainerView() {
+ return mActivityContext.getDeviceProfile().isTablet ? mBottomSheetBackground : this;
+ }
+
+ protected void onInitializeRecyclerView(RecyclerView rv) {
+ rv.addOnScrollListener(mScrollListener);
+ }
+
+ /** Holds a {@link BaseAllAppsAdapter} and related fields. */
+ public class AdapterHolder {
+ public static final int MAIN = 0;
+ public static final int WORK = 1;
+ public static final int SEARCH = 2;
+
+ private final int mType;
+ public final BaseAllAppsAdapter<T> mAdapter;
+ final RecyclerView.LayoutManager mLayoutManager;
+ final AlphabeticalAppsList<T> mAppsList;
+ final Rect mPadding = new Rect();
+ AllAppsRecyclerView mRecyclerView;
+
+ AdapterHolder(int type, AlphabeticalAppsList<T> appsList) {
+ mType = type;
+ mAppsList = appsList;
+ mAdapter = createAdapter(mAppsList);
+ mAppsList.setAdapter(mAdapter);
+ mLayoutManager = mAdapter.getLayoutManager();
+ }
+
+ void setup(@NonNull View rv, @Nullable Predicate<ItemInfo> matcher) {
+ mAppsList.updateItemFilter(matcher);
+ mRecyclerView = (AllAppsRecyclerView) rv;
+ mRecyclerView.setEdgeEffectFactory(createEdgeEffectFactory());
+ mRecyclerView.setApps(mAppsList);
+ mRecyclerView.setLayoutManager(mLayoutManager);
+ mRecyclerView.setAdapter(mAdapter);
+ mRecyclerView.setHasFixedSize(true);
+ // No animations will occur when changes occur to the items in this RecyclerView.
+ mRecyclerView.setItemAnimator(null);
+ onInitializeRecyclerView(mRecyclerView);
+ FocusedItemDecorator focusedItemDecorator = new FocusedItemDecorator(mRecyclerView);
+ mRecyclerView.addItemDecoration(focusedItemDecorator);
+ mAdapter.setIconFocusListener(focusedItemDecorator.getFocusListener());
+ applyPadding();
+ }
+
+ void applyPadding() {
+ if (mRecyclerView != null) {
+ int bottomOffset = 0;
+ if (isWork() && mWorkManager.getWorkModeSwitch() != null) {
+ bottomOffset = mInsets.bottom + mWorkManager.getWorkModeSwitch().getHeight();
+ }
+ mRecyclerView.setPadding(mPadding.left, mPadding.top, mPadding.right,
+ mPadding.bottom + bottomOffset);
+ }
+ }
+
+ private boolean isWork() {
+ return mType == WORK;
+ }
+
+ private boolean isSearch() {
+ return mType == SEARCH;
+ }
+ }
}
diff --git a/src/com/android/launcher3/allapps/AllAppsGridAdapter.java b/src/com/android/launcher3/allapps/AllAppsGridAdapter.java
index 112d47e..866932a 100644
--- a/src/com/android/launcher3/allapps/AllAppsGridAdapter.java
+++ b/src/com/android/launcher3/allapps/AllAppsGridAdapter.java
@@ -29,6 +29,7 @@
import androidx.recyclerview.widget.RecyclerView;
import androidx.recyclerview.widget.RecyclerView.Adapter;
+import com.android.launcher3.allapps.search.SearchAdapterProvider;
import com.android.launcher3.util.ScrollableLayoutManager;
import com.android.launcher3.views.ActivityContext;
@@ -73,8 +74,8 @@
public AllAppsGridAdapter(T activityContext, LayoutInflater inflater,
- AlphabeticalAppsList apps, BaseAdapterProvider[] adapterProviders) {
- super(activityContext, inflater, apps, adapterProviders);
+ AlphabeticalAppsList apps, SearchAdapterProvider<?> adapterProvider) {
+ super(activityContext, inflater, apps, adapterProvider);
mGridLayoutMgr = new AppsGridLayoutManager(mActivityContext);
mGridLayoutMgr.setSpanSizeLookup(new GridSpanSizer());
setAppsPerRow(activityContext.getDeviceProfile().numShownAllAppsColumns);
@@ -195,11 +196,9 @@
public void setAppsPerRow(int appsPerRow) {
mAppsPerRow = appsPerRow;
int totalSpans = mAppsPerRow;
- for (BaseAdapterProvider adapterProvider : mAdapterProviders) {
- for (int itemPerRow : adapterProvider.getSupportedItemsPerRowArray()) {
- if (totalSpans % itemPerRow != 0) {
- totalSpans *= itemPerRow;
- }
+ for (int itemPerRow : mAdapterProvider.getSupportedItemsPerRowArray()) {
+ if (totalSpans % itemPerRow != 0) {
+ totalSpans *= itemPerRow;
}
}
mGridLayoutMgr.setSpanCount(totalSpans);
@@ -226,9 +225,8 @@
if (isIconViewType(viewType)) {
return totalSpans / mAppsPerRow;
} else {
- BaseAdapterProvider adapterProvider = getAdapterProvider(viewType);
- if (adapterProvider != null) {
- return totalSpans / adapterProvider.getItemsPerRow(viewType, mAppsPerRow);
+ if (mAdapterProvider.isViewSupported(viewType)) {
+ return totalSpans / mAdapterProvider.getItemsPerRow(viewType, mAppsPerRow);
}
// Section breaks span the full width
diff --git a/src/com/android/launcher3/allapps/AllAppsRecyclerView.java b/src/com/android/launcher3/allapps/AllAppsRecyclerView.java
index 8cb31fa..7789191 100644
--- a/src/com/android/launcher3/allapps/AllAppsRecyclerView.java
+++ b/src/com/android/launcher3/allapps/AllAppsRecyclerView.java
@@ -299,7 +299,7 @@
return;
} else if (appsView.mViewPager != null) {
int currentPage = appsView.mViewPager.getCurrentPage();
- if (currentPage == BaseAllAppsContainerView.AdapterHolder.WORK) {
+ if (currentPage == ActivityAllAppsContainerView.AdapterHolder.WORK) {
// In work A-Z list
mgr.logger().withContainerInfo(containerInfo).log((mCumulativeVerticalScroll > 0)
? LAUNCHER_WORK_FAB_BUTTON_COLLAPSE
diff --git a/src/com/android/launcher3/allapps/BaseAdapterProvider.java b/src/com/android/launcher3/allapps/BaseAdapterProvider.java
deleted file mode 100644
index 308294c..0000000
--- a/src/com/android/launcher3/allapps/BaseAdapterProvider.java
+++ /dev/null
@@ -1,56 +0,0 @@
-/*
- * Copyright (C) 2021 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package com.android.launcher3.allapps;
-
-import android.view.LayoutInflater;
-import android.view.ViewGroup;
-
-/**
- * A UI expansion wrapper providing for providing dynamic recyclerview items
- */
-public abstract class BaseAdapterProvider {
-
- /**
- * Returns whether or not viewType can be handled by searchProvider
- */
- public abstract boolean isViewSupported(int viewType);
-
- /**
- * Called from RecyclerView.Adapter#onBindViewHolder
- */
- public abstract void onBindView(AllAppsGridAdapter.ViewHolder holder, int position);
-
- /**
- * Called from RecyclerView.Adapter#onCreateViewHolder
- */
- public abstract AllAppsGridAdapter.ViewHolder onCreateViewHolder(LayoutInflater layoutInflater,
- ViewGroup parent, int viewType);
-
- /**
- * Returns supported item per row combinations supported
- */
- public int[] getSupportedItemsPerRowArray() {
- return new int[]{};
- }
-
- /**
- * Returns how many cells a view should span
- */
- public int getItemsPerRow(int viewType, int appsPerRow) {
- return appsPerRow;
- }
-
-}
diff --git a/src/com/android/launcher3/allapps/BaseAllAppsAdapter.java b/src/com/android/launcher3/allapps/BaseAllAppsAdapter.java
index 42f8b0c..7040de5 100644
--- a/src/com/android/launcher3/allapps/BaseAllAppsAdapter.java
+++ b/src/com/android/launcher3/allapps/BaseAllAppsAdapter.java
@@ -27,18 +27,16 @@
import android.view.ViewGroup;
import android.widget.TextView;
-import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.recyclerview.widget.RecyclerView;
import com.android.launcher3.BubbleTextView;
import com.android.launcher3.R;
+import com.android.launcher3.allapps.search.SearchAdapterProvider;
import com.android.launcher3.config.FeatureFlags;
import com.android.launcher3.model.data.AppInfo;
import com.android.launcher3.views.ActivityContext;
-import java.util.Arrays;
-
/**
* Adapter for all the apps.
*
@@ -65,8 +63,7 @@
public static final int VIEW_TYPE_MASK_DIVIDER = VIEW_TYPE_ALL_APPS_DIVIDER;
public static final int VIEW_TYPE_MASK_ICON = VIEW_TYPE_ICON;
-
- protected final BaseAdapterProvider[] mAdapterProviders;
+ protected final SearchAdapterProvider<?> mAdapterProvider;
/**
* ViewHolder for each icon.
@@ -146,7 +143,7 @@
private final int mExtraHeight;
public BaseAllAppsAdapter(T activityContext, LayoutInflater inflater,
- AlphabeticalAppsList<T> apps, BaseAdapterProvider[] adapterProviders) {
+ AlphabeticalAppsList<T> apps, SearchAdapterProvider<?> adapterProvider) {
Resources res = activityContext.getResources();
mActivityContext = activityContext;
mApps = apps;
@@ -154,7 +151,7 @@
mOnIconClickListener = mActivityContext.getItemOnClickListener();
- mAdapterProviders = adapterProviders;
+ mAdapterProvider = adapterProvider;
mExtraHeight = res.getDimensionPixelSize(R.dimen.all_apps_height_extra);
}
@@ -216,9 +213,8 @@
return new ViewHolder(mLayoutInflater.inflate(
R.layout.work_apps_paused, parent, false));
default:
- BaseAdapterProvider adapterProvider = getAdapterProvider(viewType);
- if (adapterProvider != null) {
- return adapterProvider.onCreateViewHolder(mLayoutInflater, parent, viewType);
+ if (mAdapterProvider.isViewSupported(viewType)) {
+ return mAdapterProvider.onCreateViewHolder(mLayoutInflater, parent, viewType);
}
throw new RuntimeException("Unexpected view type" + viewType);
}
@@ -250,19 +246,13 @@
((WorkEduCard) holder.itemView).setPosition(position);
break;
default:
- BaseAdapterProvider adapterProvider = getAdapterProvider(holder.getItemViewType());
- if (adapterProvider != null) {
- adapterProvider.onBindView(holder, position);
+ if (mAdapterProvider.isViewSupported(holder.getItemViewType())) {
+ mAdapterProvider.onBindView(holder, position);
}
}
}
@Override
- public void onViewRecycled(@NonNull ViewHolder holder) {
- super.onViewRecycled(holder);
- }
-
- @Override
public boolean onFailedToRecycleView(ViewHolder holder) {
// Always recycle and we will reset the view when it is bound
return true;
@@ -283,10 +273,4 @@
return (viewType & viewTypeMask) != 0;
}
- @Nullable
- protected BaseAdapterProvider getAdapterProvider(int viewType) {
- return Arrays.stream(mAdapterProviders).filter(
- adapterProvider -> adapterProvider.isViewSupported(viewType)).findFirst().orElse(
- null);
- }
}
diff --git a/src/com/android/launcher3/allapps/BaseAllAppsContainerView.java b/src/com/android/launcher3/allapps/BaseAllAppsContainerView.java
deleted file mode 100644
index 9bb8250..0000000
--- a/src/com/android/launcher3/allapps/BaseAllAppsContainerView.java
+++ /dev/null
@@ -1,996 +0,0 @@
-/*
- * Copyright (C) 2015 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package com.android.launcher3.allapps;
-
-import static com.android.launcher3.logging.StatsLogManager.LauncherEvent.LAUNCHER_ALLAPPS_COUNT;
-import static com.android.launcher3.logging.StatsLogManager.LauncherEvent.LAUNCHER_ALLAPPS_TAP_ON_PERSONAL_TAB;
-import static com.android.launcher3.logging.StatsLogManager.LauncherEvent.LAUNCHER_ALLAPPS_TAP_ON_WORK_TAB;
-
-import android.animation.Animator;
-import android.animation.AnimatorListenerAdapter;
-import android.animation.ValueAnimator;
-import android.content.Context;
-import android.graphics.Canvas;
-import android.graphics.Color;
-import android.graphics.Paint;
-import android.graphics.Path;
-import android.graphics.Path.Direction;
-import android.graphics.Point;
-import android.graphics.Rect;
-import android.graphics.RectF;
-import android.os.Bundle;
-import android.os.Parcelable;
-import android.os.Process;
-import android.os.UserManager;
-import android.util.AttributeSet;
-import android.util.Log;
-import android.util.SparseArray;
-import android.util.TypedValue;
-import android.view.LayoutInflater;
-import android.view.MotionEvent;
-import android.view.View;
-import android.view.WindowInsets;
-import android.widget.Button;
-
-import androidx.annotation.NonNull;
-import androidx.annotation.Nullable;
-import androidx.annotation.VisibleForTesting;
-import androidx.core.graphics.ColorUtils;
-import androidx.recyclerview.widget.RecyclerView;
-
-import com.android.launcher3.DeviceProfile;
-import com.android.launcher3.DeviceProfile.OnDeviceProfileChangeListener;
-import com.android.launcher3.DragSource;
-import com.android.launcher3.DropTarget.DragObject;
-import com.android.launcher3.Insettable;
-import com.android.launcher3.InsettableFrameLayout;
-import com.android.launcher3.R;
-import com.android.launcher3.Utilities;
-import com.android.launcher3.allapps.search.DefaultSearchAdapterProvider;
-import com.android.launcher3.allapps.search.SearchAdapterProvider;
-import com.android.launcher3.config.FeatureFlags;
-import com.android.launcher3.keyboard.FocusedItemDecorator;
-import com.android.launcher3.model.StringCache;
-import com.android.launcher3.model.data.ItemInfo;
-import com.android.launcher3.util.ItemInfoMatcher;
-import com.android.launcher3.util.Themes;
-import com.android.launcher3.views.ActivityContext;
-import com.android.launcher3.views.BaseDragLayer;
-import com.android.launcher3.views.RecyclerViewFastScroller;
-import com.android.launcher3.views.ScrimView;
-import com.android.launcher3.views.SpringRelativeLayout;
-import com.android.launcher3.workprofile.PersonalWorkSlidingTabStrip.OnActivePageChangedListener;
-
-import java.util.Arrays;
-import java.util.List;
-import java.util.function.Predicate;
-import java.util.stream.Stream;
-
-/**
- * Base all apps view container.
- *
- * @param <T> Type of context inflating all apps.
- */
-public abstract class BaseAllAppsContainerView<T extends Context & ActivityContext>
- extends SpringRelativeLayout implements DragSource, Insettable,
- OnDeviceProfileChangeListener, OnActivePageChangedListener,
- ScrimView.ScrimDrawingController {
-
- protected static final String BUNDLE_KEY_CURRENT_PAGE = "launcher.allapps.current_page";
-
- public static final float PULL_MULTIPLIER = .02f;
- public static final float FLING_VELOCITY_MULTIPLIER = 1200f;
-
- // Render the header protection at all times to debug clipping issues.
- private static final boolean DEBUG_HEADER_PROTECTION = false;
-
- private final Paint mHeaderPaint = new Paint(Paint.ANTI_ALIAS_FLAG);
- private final Rect mInsets = new Rect();
-
- /** Context of an activity or window that is inflating this container. */
- protected final T mActivityContext;
- protected final List<AdapterHolder> mAH;
- protected final Predicate<ItemInfo> mPersonalMatcher = ItemInfoMatcher.ofUser(
- Process.myUserHandle());
- private final AllAppsStore mAllAppsStore = new AllAppsStore();
-
- private final RecyclerView.OnScrollListener mScrollListener =
- new RecyclerView.OnScrollListener() {
- @Override
- public void onScrolled(@NonNull RecyclerView recyclerView, int dx, int dy) {
- updateHeaderScroll(recyclerView.computeVerticalScrollOffset());
- }
- };
-
- protected final WorkProfileManager mWorkManager;
-
- private final Paint mNavBarScrimPaint;
- private int mNavBarScrimHeight = 0;
-
- protected AllAppsPagedView mViewPager;
- private SearchRecyclerView mSearchRecyclerView;
- private SearchAdapterProvider<?> mMainAdapterProvider;
-
- protected FloatingHeaderView mHeader;
- protected View mBottomSheetBackground;
- private View mBottomSheetHandleArea;
-
- /**
- * View that defines the search box. Result is rendered inside {@link #mSearchRecyclerView}.
- */
- protected View mSearchContainer;
- protected SearchUiManager mSearchUiManager;
-
- protected boolean mUsingTabs;
- private boolean mHasWorkApps;
-
- protected RecyclerViewFastScroller mTouchHandler;
- protected final Point mFastScrollerOffset = new Point();
-
- protected final int mScrimColor;
- private final int mHeaderProtectionColor;
- protected final float mHeaderThreshold;
- private final Path mTmpPath = new Path();
- private final RectF mTmpRectF = new RectF();
- private float[] mBottomSheetCornerRadii;
- private ScrimView mScrimView;
- private int mHeaderColor;
- private int mBottomSheetBackgroundColor;
- private int mTabsProtectionAlpha;
-
- protected BaseAllAppsContainerView(Context context, AttributeSet attrs, int defStyleAttr) {
- super(context, attrs, defStyleAttr);
- mActivityContext = ActivityContext.lookupContext(context);
-
- mScrimColor = Themes.getAttrColor(context, R.attr.allAppsScrimColor);
- mHeaderThreshold = getResources().getDimensionPixelSize(
- R.dimen.dynamic_grid_cell_border_spacing);
- mHeaderProtectionColor = Themes.getAttrColor(context, R.attr.allappsHeaderProtectionColor);
-
- mWorkManager = new WorkProfileManager(mActivityContext.getSystemService(UserManager.class),
- this, mActivityContext.getStatsLogManager());
- mAH = Arrays.asList(null, null, null);
- mNavBarScrimPaint = new Paint();
- mNavBarScrimPaint.setColor(Themes.getAttrColor(context, R.attr.allAppsNavBarScrimColor));
-
- mAllAppsStore.addUpdateListener(this::onAppsUpdated);
- mActivityContext.addOnDeviceProfileChangeListener(this);
-
- // This is a focus listener that proxies focus from a view into the list view. This is to
- // work around the search box from getting first focus and showing the cursor.
- setOnFocusChangeListener((v, hasFocus) -> {
- if (hasFocus && getActiveRecyclerView() != null) {
- getActiveRecyclerView().requestFocus();
- }
- });
- initContent();
- }
-
- /**
- * Initializes the view hierarchy and internal variables. Any initialization which actually uses
- * these members should be done in {@link #onFinishInflate()}.
- * In terms of subclass initialization, the following would be parallel order for activity:
- * initContent -> onPreCreate
- * constructor/init -> onCreate
- * onFinishInflate -> onPostCreate
- */
- protected void initContent() {
- mMainAdapterProvider = createMainAdapterProvider();
-
- mAH.set(AdapterHolder.MAIN, new AdapterHolder(AdapterHolder.MAIN));
- mAH.set(AdapterHolder.WORK, new AdapterHolder(AdapterHolder.WORK));
- mAH.set(AdapterHolder.SEARCH, new AdapterHolder(AdapterHolder.SEARCH));
-
- getLayoutInflater().inflate(R.layout.all_apps_content, this);
- mHeader = findViewById(R.id.all_apps_header);
- mBottomSheetBackground = findViewById(R.id.bottom_sheet_background);
- mBottomSheetHandleArea = findViewById(R.id.bottom_sheet_handle_area);
- mSearchRecyclerView = findViewById(R.id.search_results_list_view);
-
- // Add the search box next to the header
- mSearchContainer = inflateSearchBox();
- addView(mSearchContainer, indexOfChild(mHeader) + 1);
- mSearchUiManager = (SearchUiManager) mSearchContainer;
- }
-
- @Override
- protected void onFinishInflate() {
- super.onFinishInflate();
-
- mAH.get(AdapterHolder.SEARCH).setup(mSearchRecyclerView,
- /* Filter out A-Z apps */ itemInfo -> false);
- rebindAdapters(true /* force */);
- float cornerRadius = Themes.getDialogCornerRadius(getContext());
- mBottomSheetCornerRadii = new float[]{
- cornerRadius,
- cornerRadius, // Top left radius in px
- cornerRadius,
- cornerRadius, // Top right radius in px
- 0,
- 0, // Bottom right
- 0,
- 0 // Bottom left
- };
- final TypedValue value = new TypedValue();
- getContext().getTheme().resolveAttribute(android.R.attr.colorBackground, value, true);
- mBottomSheetBackgroundColor = value.data;
- updateBackground(mActivityContext.getDeviceProfile());
- }
-
- /**
- * Inflates the search box
- */
- protected View inflateSearchBox() {
- return getLayoutInflater().inflate(R.layout.search_container_all_apps, this, false);
- }
-
- /** Creates the adapter provider for the main section. */
- protected SearchAdapterProvider<?> createMainAdapterProvider() {
- return new DefaultSearchAdapterProvider(mActivityContext);
- }
-
- /** The adapter provider for the main section. */
- public final SearchAdapterProvider<?> getMainAdapterProvider() {
- return mMainAdapterProvider;
- }
-
- @Override
- protected void dispatchRestoreInstanceState(SparseArray<Parcelable> sparseArray) {
- try {
- // Many slice view id is not properly assigned, and hence throws null
- // pointer exception in the underneath method. Catching the exception
- // simply doesn't restore these slice views. This doesn't have any
- // user visible effect because because we query them again.
- super.dispatchRestoreInstanceState(sparseArray);
- } catch (Exception e) {
- Log.e("AllAppsContainerView", "restoreInstanceState viewId = 0", e);
- }
-
- Bundle state = (Bundle) sparseArray.get(R.id.work_tab_state_id, null);
- if (state != null) {
- int currentPage = state.getInt(BUNDLE_KEY_CURRENT_PAGE, 0);
- if (currentPage == AdapterHolder.WORK && mViewPager != null) {
- mViewPager.setCurrentPage(currentPage);
- rebindAdapters();
- } else {
- reset(true);
- }
- }
- }
-
- @Override
- protected void dispatchSaveInstanceState(SparseArray<Parcelable> container) {
- super.dispatchSaveInstanceState(container);
- Bundle state = new Bundle();
- state.putInt(BUNDLE_KEY_CURRENT_PAGE, getCurrentPage());
- container.put(R.id.work_tab_state_id, state);
- }
-
- /**
- * Sets the long click listener for icons
- */
- public void setOnIconLongClickListener(OnLongClickListener listener) {
- for (AdapterHolder holder : mAH) {
- holder.mAdapter.setOnIconLongClickListener(listener);
- }
- }
-
- public AllAppsStore getAppsStore() {
- return mAllAppsStore;
- }
-
- public WorkProfileManager getWorkManager() {
- return mWorkManager;
- }
-
- @Override
- public void onDeviceProfileChanged(DeviceProfile dp) {
- for (AdapterHolder holder : mAH) {
- holder.mAdapter.setAppsPerRow(dp.numShownAllAppsColumns);
- if (holder.mRecyclerView != null) {
- // Remove all views and clear the pool, while keeping the data same. After this
- // call, all the viewHolders will be recreated.
- holder.mRecyclerView.swapAdapter(holder.mRecyclerView.getAdapter(), true);
- holder.mRecyclerView.getRecycledViewPool().clear();
- }
- }
- updateBackground(dp);
- }
-
- protected void updateBackground(DeviceProfile deviceProfile) {
- mBottomSheetBackground.setVisibility(deviceProfile.isTablet ? View.VISIBLE : View.GONE);
- // Note: For tablets, the opaque background and header protection are added in drawOnScrim.
- // For the taskbar entrypoint, the scrim is drawn differently, so a static background is
- // added in TaskbarAllAppsContainerView and header protection is not yet supported.
- }
-
- private void onAppsUpdated() {
- mHasWorkApps = Stream.of(mAllAppsStore.getApps()).anyMatch(mWorkManager.getMatcher());
- if (!isSearching()) {
- rebindAdapters();
- if (mHasWorkApps) {
- mWorkManager.reset();
- }
- }
-
- mActivityContext.getStatsLogManager().logger()
- .withCardinality(mAllAppsStore.getApps().length)
- .log(LAUNCHER_ALLAPPS_COUNT);
- }
-
- /**
- * Returns whether the view itself will handle the touch event or not.
- */
- public boolean shouldContainerScroll(MotionEvent ev) {
- BaseDragLayer dragLayer = mActivityContext.getDragLayer();
- // Scroll if not within the container view (e.g. over large-screen scrim).
- if (!dragLayer.isEventOverView(getVisibleContainerView(), ev)) {
- return true;
- }
- if (dragLayer.isEventOverView(mBottomSheetHandleArea, ev)) {
- return true;
- }
- AllAppsRecyclerView rv = getActiveRecyclerView();
- if (rv == null) {
- return true;
- }
- if (rv.getScrollbar() != null
- && rv.getScrollbar().getThumbOffsetY() >= 0
- && dragLayer.isEventOverView(rv.getScrollbar(), ev)) {
- return false;
- }
- return rv.shouldContainerScroll(ev, dragLayer);
- }
-
- @Override
- public boolean onInterceptTouchEvent(MotionEvent ev) {
- // The AllAppsContainerView houses the QSB and is hence visible from the Workspace
- // Overview states. We shouldn't intercept for the scrubber in these cases.
- if (!isInAllApps()) {
- mTouchHandler = null;
- return false;
- }
-
- if (ev.getAction() == MotionEvent.ACTION_DOWN) {
- AllAppsRecyclerView rv = getActiveRecyclerView();
- if (rv != null && rv.getScrollbar() != null
- && rv.getScrollbar().isHitInParent(ev.getX(), ev.getY(), mFastScrollerOffset)) {
- mTouchHandler = rv.getScrollbar();
- } else {
- mTouchHandler = null;
- }
- }
- if (mTouchHandler != null) {
- return mTouchHandler.handleTouchEvent(ev, mFastScrollerOffset);
- }
- return false;
- }
-
- @Override
- public boolean onTouchEvent(MotionEvent ev) {
- if (!isInAllApps()) {
- return false;
- }
-
- if (ev.getAction() == MotionEvent.ACTION_DOWN) {
- AllAppsRecyclerView rv = getActiveRecyclerView();
- if (rv != null && rv.getScrollbar() != null
- && rv.getScrollbar().isHitInParent(ev.getX(), ev.getY(), mFastScrollerOffset)) {
- mTouchHandler = rv.getScrollbar();
- } else {
- mTouchHandler = null;
-
- }
- }
- if (mTouchHandler != null) {
- mTouchHandler.handleTouchEvent(ev, mFastScrollerOffset);
- return true;
- }
- if (isSearching()
- && mActivityContext.getDragLayer().isEventOverView(getVisibleContainerView(), ev)) {
- // if in search state, consume touch event.
- return true;
- }
- return false;
- }
-
- /** Description of the container view based on its current state. */
- public String getDescription() {
- StringCache cache = mActivityContext.getStringCache();
- if (mUsingTabs) {
- if (cache != null) {
- return isPersonalTab()
- ? cache.allAppsPersonalTabAccessibility
- : cache.allAppsWorkTabAccessibility;
- } else {
- return isPersonalTab()
- ? getContext().getString(R.string.all_apps_button_personal_label)
- : getContext().getString(R.string.all_apps_button_work_label);
- }
- }
- return getContext().getString(R.string.all_apps_button_label);
- }
-
- /** The current active recycler view (A-Z list from one of the profiles, or search results). */
- public AllAppsRecyclerView getActiveRecyclerView() {
- if (isSearching()) {
- return getSearchRecyclerView();
- }
- return getActiveAppsRecyclerView();
- }
-
- /** The current apps recycler view in the container. */
- private AllAppsRecyclerView getActiveAppsRecyclerView() {
- if (!mUsingTabs || isPersonalTab()) {
- return mAH.get(AdapterHolder.MAIN).mRecyclerView;
- } else {
- return mAH.get(AdapterHolder.WORK).mRecyclerView;
- }
- }
-
- /**
- * The container for A-Z apps (the ViewPager for main+work tabs, or main RV). This is currently
- * hidden while searching.
- **/
- protected View getAppsRecyclerViewContainer() {
- return mViewPager != null ? mViewPager : findViewById(R.id.apps_list_view);
- }
-
- /** The RV for search results, which is hidden while A-Z apps are visible. */
- public SearchRecyclerView getSearchRecyclerView() {
- return mSearchRecyclerView;
- }
-
- protected boolean isPersonalTab() {
- return mViewPager == null || mViewPager.getNextPage() == 0;
- }
-
- /**
- * Switches the current page to the provided {@code tab} if tabs are supported, otherwise does
- * nothing.
- */
- public void switchToTab(int tab) {
- if (mUsingTabs) {
- mViewPager.setCurrentPage(tab);
- }
- }
-
- public LayoutInflater getLayoutInflater() {
- return LayoutInflater.from(getContext());
- }
-
- /**
- * Resets the state of AllApps.
- */
- public void reset(boolean animate) {
- for (int i = 0; i < mAH.size(); i++) {
- if (mAH.get(i).mRecyclerView != null) {
- mAH.get(i).mRecyclerView.scrollToTop();
- }
- }
- if (isHeaderVisible()) {
- mHeader.reset(animate);
- }
- // Reset the base recycler view after transitioning home.
- updateHeaderScroll(0);
- }
-
- @Override
- public void onDropCompleted(View target, DragObject d, boolean success) {}
-
- @Override
- public void setInsets(Rect insets) {
- mInsets.set(insets);
- DeviceProfile grid = mActivityContext.getDeviceProfile();
-
- applyAdapterSideAndBottomPaddings(grid);
-
- MarginLayoutParams mlp = (MarginLayoutParams) getLayoutParams();
- mlp.leftMargin = insets.left;
- mlp.rightMargin = insets.right;
- setLayoutParams(mlp);
-
- if (grid.isVerticalBarLayout()) {
- setPadding(grid.workspacePadding.left, 0, grid.workspacePadding.right, 0);
- } else {
- int topPadding = grid.allAppsTopPadding;
- if (FeatureFlags.ENABLE_FLOATING_SEARCH_BAR.get() && !grid.isTablet) {
- topPadding += getResources().getDimensionPixelSize(
- R.dimen.all_apps_additional_top_padding_floating_search);
- }
- setPadding(grid.allAppsLeftRightMargin, topPadding, grid.allAppsLeftRightMargin, 0);
- }
-
- InsettableFrameLayout.dispatchInsets(this, insets);
- }
-
- /**
- * Returns a padding in case a scrim is shown on the bottom of the view and a padding is needed.
- */
- protected int computeNavBarScrimHeight(WindowInsets insets) {
- return 0;
- }
-
- /**
- * Returns the current height of nav bar scrim
- */
- public int getNavBarScrimHeight() {
- return mNavBarScrimHeight;
- }
-
- @Override
- public WindowInsets dispatchApplyWindowInsets(WindowInsets insets) {
- mNavBarScrimHeight = computeNavBarScrimHeight(insets);
- applyAdapterSideAndBottomPaddings(mActivityContext.getDeviceProfile());
- return super.dispatchApplyWindowInsets(insets);
- }
-
- @Override
- protected void dispatchDraw(Canvas canvas) {
- super.dispatchDraw(canvas);
-
- if (mNavBarScrimHeight > 0) {
- canvas.drawRect(0, getHeight() - mNavBarScrimHeight, getWidth(), getHeight(),
- mNavBarScrimPaint);
- }
- }
-
- protected void rebindAdapters() {
- rebindAdapters(false /* force */);
- }
-
- protected void rebindAdapters(boolean force) {
- updateSearchResultsVisibility();
-
- boolean showTabs = shouldShowTabs();
- if (showTabs == mUsingTabs && !force) {
- return;
- }
-
- if (isSearching()) {
- mUsingTabs = showTabs;
- mWorkManager.detachWorkModeSwitch();
- return;
- }
-
- // replaceAppsRVcontainer() needs to use both mUsingTabs value to remove the old view AND
- // showTabs value to create new view. Hence the mUsingTabs new value assignment MUST happen
- // after this call.
- replaceAppsRVContainer(showTabs);
- mUsingTabs = showTabs;
-
- mAllAppsStore.unregisterIconContainer(mAH.get(AdapterHolder.MAIN).mRecyclerView);
- mAllAppsStore.unregisterIconContainer(mAH.get(AdapterHolder.WORK).mRecyclerView);
- mAllAppsStore.unregisterIconContainer(mAH.get(AdapterHolder.SEARCH).mRecyclerView);
-
- if (mUsingTabs) {
- mAH.get(AdapterHolder.MAIN).setup(mViewPager.getChildAt(0), mPersonalMatcher);
- mAH.get(AdapterHolder.WORK).setup(mViewPager.getChildAt(1), mWorkManager.getMatcher());
- mAH.get(AdapterHolder.WORK).mRecyclerView.setId(R.id.apps_list_view_work);
- if (FeatureFlags.ENABLE_EXPANDING_PAUSE_WORK_BUTTON.get()) {
- mAH.get(AdapterHolder.WORK).mRecyclerView.addOnScrollListener(
- mWorkManager.newScrollListener());
- }
- mViewPager.getPageIndicator().setActiveMarker(AdapterHolder.MAIN);
- findViewById(R.id.tab_personal)
- .setOnClickListener((View view) -> {
- if (mViewPager.snapToPage(AdapterHolder.MAIN)) {
- mActivityContext.getStatsLogManager().logger()
- .log(LAUNCHER_ALLAPPS_TAP_ON_PERSONAL_TAB);
- }
- mActivityContext.hideKeyboard();
- });
- findViewById(R.id.tab_work)
- .setOnClickListener((View view) -> {
- if (mViewPager.snapToPage(AdapterHolder.WORK)) {
- mActivityContext.getStatsLogManager().logger()
- .log(LAUNCHER_ALLAPPS_TAP_ON_WORK_TAB);
- }
- mActivityContext.hideKeyboard();
- });
- setDeviceManagementResources();
- onActivePageChanged(mViewPager.getNextPage());
- } else {
- mAH.get(AdapterHolder.MAIN).setup(findViewById(R.id.apps_list_view), null);
- mAH.get(AdapterHolder.WORK).mRecyclerView = null;
- }
- setupHeader();
-
- mAllAppsStore.registerIconContainer(mAH.get(AdapterHolder.MAIN).mRecyclerView);
- mAllAppsStore.registerIconContainer(mAH.get(AdapterHolder.WORK).mRecyclerView);
- mAllAppsStore.registerIconContainer(mAH.get(AdapterHolder.SEARCH).mRecyclerView);
- }
-
- protected void updateSearchResultsVisibility() {
- if (isSearching()) {
- getSearchRecyclerView().setVisibility(VISIBLE);
- getAppsRecyclerViewContainer().setVisibility(GONE);
- mHeader.setVisibility(GONE);
- } else {
- getSearchRecyclerView().setVisibility(GONE);
- getAppsRecyclerViewContainer().setVisibility(VISIBLE);
- mHeader.setVisibility(VISIBLE);
- }
- if (mHeader.isSetUp()) {
- mHeader.setActiveRV(getCurrentPage());
- }
- }
-
- private void applyAdapterSideAndBottomPaddings(DeviceProfile grid) {
- int bottomPadding = Math.max(mInsets.bottom, mNavBarScrimHeight);
- mAH.forEach(adapterHolder -> {
- adapterHolder.mPadding.bottom = bottomPadding;
- adapterHolder.mPadding.left =
- adapterHolder.mPadding.right = grid.allAppsLeftRightPadding;
- adapterHolder.applyPadding();
- });
- }
-
- private void setDeviceManagementResources() {
- if (mActivityContext.getStringCache() != null) {
- Button personalTab = findViewById(R.id.tab_personal);
- personalTab.setText(mActivityContext.getStringCache().allAppsPersonalTab);
-
- Button workTab = findViewById(R.id.tab_work);
- workTab.setText(mActivityContext.getStringCache().allAppsWorkTab);
- }
- }
-
- protected boolean shouldShowTabs() {
- return mHasWorkApps;
- }
-
- protected boolean isSearching() {
- return false;
- }
-
- protected View replaceAppsRVContainer(boolean showTabs) {
- for (int i = AdapterHolder.MAIN; i <= AdapterHolder.WORK; i++) {
- AdapterHolder adapterHolder = mAH.get(i);
- if (adapterHolder.mRecyclerView != null) {
- adapterHolder.mRecyclerView.setLayoutManager(null);
- adapterHolder.mRecyclerView.setAdapter(null);
- }
- }
- View oldView = getAppsRecyclerViewContainer();
- int index = indexOfChild(oldView);
- removeView(oldView);
- int layout = showTabs ? R.layout.all_apps_tabs : R.layout.all_apps_rv_layout;
- View newView = getLayoutInflater().inflate(layout, this, false);
- addView(newView, index);
- if (showTabs) {
- mViewPager = (AllAppsPagedView) newView;
- mViewPager.initParentViews(this);
- mViewPager.getPageIndicator().setOnActivePageChangedListener(this);
-
- mWorkManager.reset();
- post(() -> mAH.get(AdapterHolder.WORK).applyPadding());
-
- } else {
- mWorkManager.detachWorkModeSwitch();
- mViewPager = null;
- }
- return newView;
- }
-
- @Override
- public void onActivePageChanged(int currentActivePage) {
- if (mAH.get(currentActivePage).mRecyclerView != null) {
- mAH.get(currentActivePage).mRecyclerView.bindFastScrollbar();
- }
- // Header keeps track of active recycler view to properly render header protection.
- mHeader.setActiveRV(currentActivePage);
- reset(true /* animate */);
-
- mWorkManager.onActivePageChanged(currentActivePage);
- }
-
- // Used by tests only
- private boolean isDescendantViewVisible(int viewId) {
- final View view = findViewById(viewId);
- if (view == null) return false;
-
- if (!view.isShown()) return false;
-
- return view.getGlobalVisibleRect(new Rect());
- }
-
- @VisibleForTesting
- public boolean isPersonalTabVisible() {
- return isDescendantViewVisible(R.id.tab_personal);
- }
-
- @VisibleForTesting
- public boolean isWorkTabVisible() {
- return isDescendantViewVisible(R.id.tab_work);
- }
-
- public AlphabeticalAppsList<T> getSearchResultList() {
- return mAH.get(AdapterHolder.SEARCH).mAppsList;
- }
-
- public FloatingHeaderView getFloatingHeaderView() {
- return mHeader;
- }
-
- @VisibleForTesting
- public View getContentView() {
- return isSearching() ? getSearchRecyclerView() : getAppsRecyclerViewContainer();
- }
-
- /** The current page visible in all apps. */
- public int getCurrentPage() {
- return isSearching()
- ? AdapterHolder.SEARCH
- : mViewPager == null ? AdapterHolder.MAIN : mViewPager.getNextPage();
- }
-
- /** The scroll bar for the active apps recycler view. */
- public RecyclerViewFastScroller getScrollBar() {
- AllAppsRecyclerView rv = getActiveAppsRecyclerView();
- return rv == null ? null : rv.getScrollbar();
- }
-
- void setupHeader() {
- mHeader.setVisibility(View.VISIBLE);
- boolean tabsHidden = !mUsingTabs;
- mHeader.setup(
- mAH.get(AdapterHolder.MAIN).mRecyclerView,
- mAH.get(AdapterHolder.WORK).mRecyclerView,
- (SearchRecyclerView) mAH.get(AdapterHolder.SEARCH).mRecyclerView,
- getCurrentPage(),
- tabsHidden);
-
- int padding = mHeader.getMaxTranslation();
- mAH.forEach(adapterHolder -> {
- adapterHolder.mPadding.top = padding;
- adapterHolder.applyPadding();
- if (adapterHolder.mRecyclerView != null) {
- adapterHolder.mRecyclerView.scrollToTop();
- }
- });
- }
-
- public boolean isHeaderVisible() {
- return mHeader != null && mHeader.getVisibility() == View.VISIBLE;
- }
-
- /**
- * Adds an update listener to animator that adds springs to the animation.
- */
- public void addSpringFromFlingUpdateListener(ValueAnimator animator,
- float velocity /* release velocity */,
- float progress /* portion of the distance to travel*/) {
- animator.addListener(new AnimatorListenerAdapter() {
- @Override
- public void onAnimationStart(Animator animator) {
- float distance = (1 - progress) * getHeight(); // px
- float settleVelocity = Math.min(0, distance
- / (AllAppsTransitionController.INTERP_COEFF * animator.getDuration())
- + velocity);
- absorbSwipeUpVelocity(Math.max(1000, Math.abs(
- Math.round(settleVelocity * FLING_VELOCITY_MULTIPLIER))));
- }
- });
- }
-
- /** Invoked when the container is pulled. */
- public void onPull(float deltaDistance, float displacement) {
- absorbPullDeltaDistance(PULL_MULTIPLIER * deltaDistance, PULL_MULTIPLIER * displacement);
- // Current motion spec is to actually push and not pull
- // on this surface. However, until EdgeEffect.onPush (b/190612804) is
- // implemented at view level, we will simply pull
- }
-
- @Override
- public void getDrawingRect(Rect outRect) {
- super.getDrawingRect(outRect);
- outRect.offset(0, (int) getTranslationY());
- }
-
- @Override
- public void setTranslationY(float translationY) {
- super.setTranslationY(translationY);
- invalidateHeader();
- }
-
- public void setScrimView(ScrimView scrimView) {
- mScrimView = scrimView;
- }
-
- @Override
- public void drawOnScrimWithScale(Canvas canvas, float scale) {
- boolean isTablet = mActivityContext.getDeviceProfile().isTablet;
-
- // Draw full background panel for tablets.
- if (isTablet) {
- mHeaderPaint.setColor(mBottomSheetBackgroundColor);
- View panel = (View) mBottomSheetBackground;
- float translationY = ((View) panel.getParent()).getTranslationY();
- mTmpRectF.set(panel.getLeft(), panel.getTop() + translationY,
- panel.getRight(), panel.getBottom());
- mTmpPath.reset();
- mTmpPath.addRoundRect(mTmpRectF, mBottomSheetCornerRadii, Direction.CW);
- canvas.drawPath(mTmpPath, mHeaderPaint);
- }
-
- if (DEBUG_HEADER_PROTECTION) {
- mHeaderPaint.setColor(Color.MAGENTA);
- mHeaderPaint.setAlpha(255);
- } else {
- mHeaderPaint.setColor(mHeaderColor);
- mHeaderPaint.setAlpha((int) (getAlpha() * Color.alpha(mHeaderColor)));
- }
- if (mHeaderPaint.getColor() == mScrimColor || mHeaderPaint.getColor() == 0) {
- return;
- }
- final float offset = (getVisibleContainerView().getHeight() * (1 - scale) / 2);
- final float bottom =
- scale * (getHeaderBottom() + getVisibleContainerView().getPaddingTop()) + offset;
- FloatingHeaderView headerView = getFloatingHeaderView();
- if (isTablet) {
- // Start adding header protection if search bar or tabs will attach to the top.
- if (!FeatureFlags.ENABLE_FLOATING_SEARCH_BAR.get() || mUsingTabs) {
- View panel = (View) mBottomSheetBackground;
- float translationY = ((View) panel.getParent()).getTranslationY();
- mTmpRectF.set(panel.getLeft(), panel.getTop() + translationY, panel.getRight(),
- bottom);
- mTmpPath.reset();
- mTmpPath.addRoundRect(mTmpRectF, mBottomSheetCornerRadii, Direction.CW);
- canvas.drawPath(mTmpPath, mHeaderPaint);
- }
- } else {
- canvas.drawRect(0, 0, canvas.getWidth(), bottom, mHeaderPaint);
- }
- int tabsHeight = headerView.getPeripheralProtectionHeight();
- if (mTabsProtectionAlpha > 0 && tabsHeight != 0) {
- if (DEBUG_HEADER_PROTECTION) {
- mHeaderPaint.setColor(Color.BLUE);
- mHeaderPaint.setAlpha(255);
- } else {
- mHeaderPaint.setAlpha((int) (getAlpha() * mTabsProtectionAlpha));
- }
- int left = 0;
- int right = canvas.getWidth();
- if (isTablet) {
- left = mBottomSheetBackground.getLeft();
- right = mBottomSheetBackground.getRight();
- }
- canvas.drawRect(left, bottom, right, bottom + tabsHeight, mHeaderPaint);
- }
- }
-
- /**
- * redraws header protection
- */
- public void invalidateHeader() {
- if (mScrimView != null) {
- mScrimView.invalidate();
- }
- }
-
- protected void updateHeaderScroll(int scrolledOffset) {
- float prog = Utilities.boundToRange((float) scrolledOffset / mHeaderThreshold, 0f, 1f);
- int headerColor = getHeaderColor(prog);
- int tabsAlpha = mHeader.getPeripheralProtectionHeight() == 0 ? 0
- : (int) (Utilities.boundToRange(
- (scrolledOffset + mHeader.mSnappedScrolledY) / mHeaderThreshold, 0f, 1f)
- * 255);
- if (headerColor != mHeaderColor || mTabsProtectionAlpha != tabsAlpha) {
- mHeaderColor = headerColor;
- mTabsProtectionAlpha = tabsAlpha;
- invalidateHeader();
- }
- }
-
- protected int getHeaderColor(float blendRatio) {
- return ColorUtils.blendARGB(mScrimColor, mHeaderProtectionColor, blendRatio);
- }
-
- protected abstract BaseAllAppsAdapter<T> createAdapter(AlphabeticalAppsList<T> mAppsList,
- BaseAdapterProvider[] adapterProviders);
-
- public int getHeaderBottom() {
- int bottom = (int) getTranslationY() + mHeader.getClipTop();
- if (FeatureFlags.ENABLE_FLOATING_SEARCH_BAR.get()) {
- if (mActivityContext.getDeviceProfile().isTablet) {
- return bottom + mBottomSheetBackground.getTop();
- }
- return bottom;
- }
- return bottom + mHeader.getTop();
- }
-
- /**
- * Returns a view that denotes the visible part of all apps container view.
- */
- public View getVisibleContainerView() {
- return mActivityContext.getDeviceProfile().isTablet ? mBottomSheetBackground : this;
- }
-
- protected void onInitializeRecyclerView(RecyclerView rv) {
- rv.addOnScrollListener(mScrollListener);
- }
-
- /**
- * Returns {@code true} the All Apps UI is currently being displayed on the target surface and
- * is interactive.
- */
- public abstract boolean isInAllApps();
-
- /** Holds a {@link BaseAllAppsAdapter} and related fields. */
- public class AdapterHolder {
- public static final int MAIN = 0;
- public static final int WORK = 1;
- public static final int SEARCH = 2;
-
- private final int mType;
- public final BaseAllAppsAdapter<T> mAdapter;
- final RecyclerView.LayoutManager mLayoutManager;
- final AlphabeticalAppsList<T> mAppsList;
- final Rect mPadding = new Rect();
- AllAppsRecyclerView mRecyclerView;
-
- AdapterHolder(int type) {
- mType = type;
- mAppsList = new AlphabeticalAppsList<>(mActivityContext,
- isSearch() ? null : mAllAppsStore,
- isWork() ? mWorkManager : null);
- BaseAdapterProvider[] adapterProviders =
- new BaseAdapterProvider[]{mMainAdapterProvider};
-
- mAdapter = createAdapter(mAppsList, adapterProviders);
- mAppsList.setAdapter(mAdapter);
- mLayoutManager = mAdapter.getLayoutManager();
- }
-
- void setup(@NonNull View rv, @Nullable Predicate<ItemInfo> matcher) {
- mAppsList.updateItemFilter(matcher);
- mRecyclerView = (AllAppsRecyclerView) rv;
- mRecyclerView.setEdgeEffectFactory(createEdgeEffectFactory());
- mRecyclerView.setApps(mAppsList);
- mRecyclerView.setLayoutManager(mLayoutManager);
- mRecyclerView.setAdapter(mAdapter);
- mRecyclerView.setHasFixedSize(true);
- // No animations will occur when changes occur to the items in this RecyclerView.
- mRecyclerView.setItemAnimator(null);
- onInitializeRecyclerView(mRecyclerView);
- FocusedItemDecorator focusedItemDecorator = new FocusedItemDecorator(mRecyclerView);
- mRecyclerView.addItemDecoration(focusedItemDecorator);
- mAdapter.setIconFocusListener(focusedItemDecorator.getFocusListener());
- applyPadding();
- }
-
- void applyPadding() {
- if (mRecyclerView != null) {
- int bottomOffset = 0;
- if (isWork() && mWorkManager.getWorkModeSwitch() != null) {
- bottomOffset = mInsets.bottom + mWorkManager.getWorkModeSwitch().getHeight();
- }
- mRecyclerView.setPadding(mPadding.left, mPadding.top, mPadding.right,
- mPadding.bottom + bottomOffset);
- }
- }
-
- private boolean isWork() {
- return mType == WORK;
- }
-
- private boolean isSearch() {
- return mType == SEARCH;
- }
- }
-}
diff --git a/src/com/android/launcher3/allapps/DiscoveryBounce.java b/src/com/android/launcher3/allapps/DiscoveryBounce.java
index be261f7..0188a47 100644
--- a/src/com/android/launcher3/allapps/DiscoveryBounce.java
+++ b/src/com/android/launcher3/allapps/DiscoveryBounce.java
@@ -81,10 +81,10 @@
}
@Override
- public boolean onBackPressed() {
- super.onBackPressed();
- // Go back to the previous state (from a user's perspective this floating view isn't
- // something to go back from).
+ public boolean canHandleBack() {
+ // Since DiscoveryBounce doesn't handle back, onBackInvoked() won't be called and we should
+ // close it without animation.
+ close(false);
return false;
}
diff --git a/src/com/android/launcher3/allapps/FloatingHeaderView.java b/src/com/android/launcher3/allapps/FloatingHeaderView.java
index c18f9e1..b3ea3ab 100644
--- a/src/com/android/launcher3/allapps/FloatingHeaderView.java
+++ b/src/com/android/launcher3/allapps/FloatingHeaderView.java
@@ -32,7 +32,7 @@
import com.android.launcher3.Insettable;
import com.android.launcher3.R;
-import com.android.launcher3.allapps.BaseAllAppsContainerView.AdapterHolder;
+import com.android.launcher3.allapps.ActivityAllAppsContainerView.AdapterHolder;
import com.android.launcher3.config.FeatureFlags;
import com.android.launcher3.uioverrides.plugins.PluginManagerWrapper;
import com.android.launcher3.views.ActivityContext;
@@ -72,8 +72,8 @@
moved(current);
applyVerticalMove();
if (headerCollapsed != mHeaderCollapsed) {
- BaseAllAppsContainerView<?> parent =
- (BaseAllAppsContainerView<?>) getParent();
+ ActivityAllAppsContainerView<?> parent =
+ (ActivityAllAppsContainerView<?>) getParent();
parent.invalidateHeader();
}
}
@@ -191,7 +191,7 @@
updateExpectedHeight();
if (mMaxTranslation != oldMaxHeight || mFloatingRowsCollapsed) {
- BaseAllAppsContainerView<?> parent = (BaseAllAppsContainerView<?>) getParent();
+ ActivityAllAppsContainerView parent = (ActivityAllAppsContainerView) getParent();
if (parent != null) {
parent.setupHeader();
}
diff --git a/src/com/android/launcher3/allapps/WorkProfileManager.java b/src/com/android/launcher3/allapps/WorkProfileManager.java
index fa03905..f66ea34 100644
--- a/src/com/android/launcher3/allapps/WorkProfileManager.java
+++ b/src/com/android/launcher3/allapps/WorkProfileManager.java
@@ -16,11 +16,11 @@
package com.android.launcher3.allapps;
import static com.android.launcher3.LauncherPrefs.WORK_EDU_STEP;
+import static com.android.launcher3.allapps.ActivityAllAppsContainerView.AdapterHolder.MAIN;
+import static com.android.launcher3.allapps.ActivityAllAppsContainerView.AdapterHolder.SEARCH;
+import static com.android.launcher3.allapps.ActivityAllAppsContainerView.AdapterHolder.WORK;
import static com.android.launcher3.allapps.BaseAllAppsAdapter.VIEW_TYPE_WORK_DISABLED_CARD;
import static com.android.launcher3.allapps.BaseAllAppsAdapter.VIEW_TYPE_WORK_EDU_CARD;
-import static com.android.launcher3.allapps.BaseAllAppsContainerView.AdapterHolder.MAIN;
-import static com.android.launcher3.allapps.BaseAllAppsContainerView.AdapterHolder.SEARCH;
-import static com.android.launcher3.allapps.BaseAllAppsContainerView.AdapterHolder.WORK;
import static com.android.launcher3.logging.StatsLogManager.LauncherEvent.LAUNCHER_TURN_OFF_WORK_APPS_TAP;
import static com.android.launcher3.model.BgDataModel.Callbacks.FLAG_HAS_SHORTCUT_PERMISSION;
import static com.android.launcher3.model.BgDataModel.Callbacks.FLAG_QUIET_MODE_CHANGE_PERMISSION;
@@ -54,7 +54,7 @@
import java.util.function.Predicate;
/**
- * Companion class for {@link BaseAllAppsContainerView} to manage work tab and personal tab
+ * Companion class for {@link ActivityAllAppsContainerView} to manage work tab and personal tab
* related
* logic based on {@link WorkProfileState}?
*/
@@ -79,7 +79,7 @@
public @interface WorkProfileState { }
private final UserManager mUserManager;
- private final BaseAllAppsContainerView<?> mAllApps;
+ private final ActivityAllAppsContainerView<?> mAllApps;
private final Predicate<ItemInfo> mMatcher;
private final StatsLogManager mStatsLogManager;
@@ -89,7 +89,7 @@
private int mCurrentState;
public WorkProfileManager(
- UserManager userManager, BaseAllAppsContainerView<?> allApps,
+ UserManager userManager, ActivityAllAppsContainerView allApps,
StatsLogManager statsLogManager) {
mUserManager = userManager;
mAllApps = allApps;
@@ -152,7 +152,7 @@
}
/**
- * Creates and attaches for profile toggle button to {@link BaseAllAppsContainerView}
+ * Creates and attaches for profile toggle button to {@link ActivityAllAppsContainerView}
*/
public boolean attachWorkModeSwitch() {
if (!mAllApps.getAppsStore().hasModelFlag(
@@ -177,7 +177,7 @@
return true;
}
/**
- * Removes work profile toggle button from {@link BaseAllAppsContainerView}
+ * Removes work profile toggle button from {@link ActivityAllAppsContainerView}
*/
public void detachWorkModeSwitch() {
if (mWorkModeSwitch != null && mWorkModeSwitch.getParent() == mAllApps) {
@@ -195,7 +195,7 @@
return mWorkModeSwitch;
}
- private BaseAllAppsContainerView<?>.AdapterHolder getAH() {
+ private ActivityAllAppsContainerView.AdapterHolder getAH() {
return mAllApps.mAH.get(WORK);
}
diff --git a/src/com/android/launcher3/allapps/search/DefaultSearchAdapterProvider.java b/src/com/android/launcher3/allapps/search/DefaultSearchAdapterProvider.java
index 20edf8a..714304b 100644
--- a/src/com/android/launcher3/allapps/search/DefaultSearchAdapterProvider.java
+++ b/src/com/android/launcher3/allapps/search/DefaultSearchAdapterProvider.java
@@ -15,12 +15,10 @@
*/
package com.android.launcher3.allapps.search;
-import android.graphics.Canvas;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
-import androidx.annotation.NonNull;
import androidx.recyclerview.widget.RecyclerView;
import com.android.launcher3.BubbleTextView;
@@ -38,13 +36,7 @@
public DefaultSearchAdapterProvider(ActivityContext launcher) {
super(launcher);
- mDecoration = new RecyclerView.ItemDecoration() {
- @Override
- public void onDraw(@NonNull Canvas c, @NonNull RecyclerView parent,
- @NonNull RecyclerView.State state) {
- super.onDraw(c, parent, state);
- }
- };
+ mDecoration = new RecyclerView.ItemDecoration() { };
}
@Override
diff --git a/src/com/android/launcher3/allapps/search/SearchAdapterProvider.java b/src/com/android/launcher3/allapps/search/SearchAdapterProvider.java
index 3890741..15756f5 100644
--- a/src/com/android/launcher3/allapps/search/SearchAdapterProvider.java
+++ b/src/com/android/launcher3/allapps/search/SearchAdapterProvider.java
@@ -16,12 +16,13 @@
package com.android.launcher3.allapps.search;
-import android.net.Uri;
+import android.view.LayoutInflater;
import android.view.View;
+import android.view.ViewGroup;
import androidx.recyclerview.widget.RecyclerView;
-import com.android.launcher3.allapps.BaseAdapterProvider;
+import com.android.launcher3.allapps.AllAppsGridAdapter;
import com.android.launcher3.views.ActivityContext;
/**
@@ -29,7 +30,7 @@
*
* @param <T> Context for this adapter provider.
*/
-public abstract class SearchAdapterProvider<T extends ActivityContext> extends BaseAdapterProvider {
+public abstract class SearchAdapterProvider<T extends ActivityContext> {
protected final T mLauncher;
@@ -38,12 +39,6 @@
}
/**
- * Called from LiveSearchManager to notify slice status updates.
- */
- public void onSliceStatusUpdate(Uri sliceUri) {
- }
-
- /**
* Handles selection event on search adapter item. Returns false if provider can not handle
* event
*/
@@ -63,4 +58,34 @@
* Clear the highlighted view.
*/
public abstract void clearHighlightedItem();
+
+ /**
+ * Returns whether or not viewType can be handled by searchProvider
+ */
+ public abstract boolean isViewSupported(int viewType);
+
+ /**
+ * Called from RecyclerView.Adapter#onBindViewHolder
+ */
+ public abstract void onBindView(AllAppsGridAdapter.ViewHolder holder, int position);
+
+ /**
+ * Called from RecyclerView.Adapter#onCreateViewHolder
+ */
+ public abstract AllAppsGridAdapter.ViewHolder onCreateViewHolder(LayoutInflater layoutInflater,
+ ViewGroup parent, int viewType);
+
+ /**
+ * Returns supported item per row combinations supported
+ */
+ public int[] getSupportedItemsPerRowArray() {
+ return new int[]{};
+ }
+
+ /**
+ * Returns how many cells a view should span
+ */
+ public int getItemsPerRow(int viewType, int appsPerRow) {
+ return appsPerRow;
+ }
}
diff --git a/src/com/android/launcher3/config/FeatureFlags.java b/src/com/android/launcher3/config/FeatureFlags.java
index c328554..c90c6bf 100644
--- a/src/com/android/launcher3/config/FeatureFlags.java
+++ b/src/com/android/launcher3/config/FeatureFlags.java
@@ -96,9 +96,6 @@
"ENABLE_EXPANDING_PAUSE_WORK_BUTTON", false,
"Expand and collapse pause work button while scrolling");
- public static final BooleanFlag ENABLE_HIDE_HEADER_STATIC = new DeviceFlag(
- "ENABLE_HIDE_HEADER_STATIC", false, "Hide keyboard suggestion strip");
-
public static final BooleanFlag COLLECT_SEARCH_HISTORY = new DeviceFlag(
"COLLECT_SEARCH_HISTORY", false, "Allow launcher to collect search history for log");
diff --git a/src/com/android/launcher3/folder/Folder.java b/src/com/android/launcher3/folder/Folder.java
index 94eea35..9a5d77e 100644
--- a/src/com/android/launcher3/folder/Folder.java
+++ b/src/com/android/launcher3/folder/Folder.java
@@ -1579,17 +1579,14 @@
return getOpenView(activityContext, TYPE_FOLDER);
}
- /**
- * Navigation bar back key or hardware input back key has been issued.
- */
+ /** Navigation bar back key or hardware input back key has been issued. */
@Override
- public boolean onBackPressed() {
+ public void onBackInvoked() {
if (isEditingName()) {
mFolderName.dispatchBackKey();
} else {
- super.onBackPressed();
+ super.onBackInvoked();
}
- return true;
}
@Override
diff --git a/src/com/android/launcher3/folder/FolderIcon.java b/src/com/android/launcher3/folder/FolderIcon.java
index 60442f4..e69f781 100644
--- a/src/com/android/launcher3/folder/FolderIcon.java
+++ b/src/com/android/launcher3/folder/FolderIcon.java
@@ -41,6 +41,7 @@
import android.widget.FrameLayout;
import androidx.annotation.NonNull;
+import androidx.annotation.Nullable;
import com.android.launcher3.Alarm;
import com.android.launcher3.BubbleTextView;
@@ -181,8 +182,11 @@
return icon;
}
- public static FolderIcon inflateIcon(int resId, ActivityContext activity, ViewGroup group,
- FolderInfo folderInfo) {
+ /**
+ * Builds a FolderIcon to be added to the Launcher
+ */
+ public static FolderIcon inflateIcon(int resId, ActivityContext activity,
+ @Nullable ViewGroup group, FolderInfo folderInfo) {
@SuppressWarnings("all") // suppress dead code warning
final boolean error = INITIAL_ITEM_ANIMATION_DURATION >= DROP_IN_ANIMATION_DURATION;
if (error) {
@@ -192,8 +196,10 @@
}
DeviceProfile grid = activity.getDeviceProfile();
- FolderIcon icon = (FolderIcon) LayoutInflater.from(group.getContext())
- .inflate(resId, group, false);
+ LayoutInflater inflater = (group != null)
+ ? LayoutInflater.from(group.getContext())
+ : activity.getLayoutInflater();
+ FolderIcon icon = (FolderIcon) inflater.inflate(resId, group, false);
icon.setClipToPadding(false);
icon.mFolderName = icon.findViewById(R.id.folder_icon_name);
diff --git a/src/com/android/launcher3/graphics/LauncherPreviewRenderer.java b/src/com/android/launcher3/graphics/LauncherPreviewRenderer.java
index e7b0446..4810b15 100644
--- a/src/com/android/launcher3/graphics/LauncherPreviewRenderer.java
+++ b/src/com/android/launcher3/graphics/LauncherPreviewRenderer.java
@@ -68,6 +68,7 @@
import com.android.launcher3.InsettableFrameLayout;
import com.android.launcher3.InvariantDeviceProfile;
import com.android.launcher3.LauncherAppState;
+import com.android.launcher3.LauncherPrefs;
import com.android.launcher3.LauncherSettings.Favorites;
import com.android.launcher3.R;
import com.android.launcher3.Utilities;
@@ -137,7 +138,7 @@
new ConcurrentLinkedQueue<>();
public PreviewContext(Context base, InvariantDeviceProfile idp) {
- super(base, UserCache.INSTANCE, InstallSessionHelper.INSTANCE,
+ super(base, UserCache.INSTANCE, InstallSessionHelper.INSTANCE, LauncherPrefs.INSTANCE,
LauncherAppState.INSTANCE, InvariantDeviceProfile.INSTANCE,
CustomWidgetManager.INSTANCE, PluginManagerWrapper.INSTANCE,
WindowManagerProxy.INSTANCE, DisplayController.INSTANCE);
diff --git a/src/com/android/launcher3/graphics/SysUiScrim.java b/src/com/android/launcher3/graphics/SysUiScrim.java
index 185b8d3..11e7dc8 100644
--- a/src/com/android/launcher3/graphics/SysUiScrim.java
+++ b/src/com/android/launcher3/graphics/SysUiScrim.java
@@ -16,17 +16,10 @@
package com.android.launcher3.graphics;
-import static android.content.Intent.ACTION_SCREEN_OFF;
-import static android.content.Intent.ACTION_USER_PRESENT;
-
import static com.android.launcher3.config.FeatureFlags.KEYGUARD_ANIMATION;
import static com.android.launcher3.icons.GraphicsUtils.setColorAlphaBound;
import android.animation.ObjectAnimator;
-import android.content.BroadcastReceiver;
-import android.content.Context;
-import android.content.Intent;
-import android.content.IntentFilter;
import android.graphics.Bitmap;
import android.graphics.Canvas;
import android.graphics.Color;
@@ -43,10 +36,12 @@
import com.android.launcher3.BaseDraggingActivity;
import com.android.launcher3.R;
-import com.android.launcher3.testing.shared.ResourceUtils;
import com.android.launcher3.Utilities;
import com.android.launcher3.config.FeatureFlags;
+import com.android.launcher3.testing.shared.ResourceUtils;
import com.android.launcher3.util.DynamicResource;
+import com.android.launcher3.util.ScreenOnTracker;
+import com.android.launcher3.util.ScreenOnTracker.ScreenOnListener;
import com.android.launcher3.util.Themes;
import com.android.systemui.plugins.ResourceProvider;
@@ -85,18 +80,20 @@
/**
* Receiver used to get a signal that the user unlocked their device.
*/
- private final BroadcastReceiver mReceiver = new BroadcastReceiver() {
+ private final ScreenOnListener mScreenOnListener = new ScreenOnListener() {
@Override
- public void onReceive(Context context, Intent intent) {
- final String action = intent.getAction();
- if (ACTION_SCREEN_OFF.equals(action)) {
+ public void onScreenOnChanged(boolean isOn) {
+ if (!isOn) {
mAnimateScrimOnNextDraw = true;
- } else if (ACTION_USER_PRESENT.equals(action)) {
- // ACTION_USER_PRESENT is sent after onStart/onResume. This covers the case where
- // the user unlocked and the Launcher is not in the foreground.
- mAnimateScrimOnNextDraw = false;
}
}
+
+ @Override
+ public void onUserPresent() {
+ // ACTION_USER_PRESENT is sent after onStart/onResume. This covers the case where
+ // the user unlocked and the Launcher is not in the foreground.
+ mAnimateScrimOnNextDraw = false;
+ }
};
private static final int MAX_HOTSEAT_SCRIM_ALPHA = 100;
@@ -208,16 +205,14 @@
@Override
public void onViewAttachedToWindow(View view) {
if (!KEYGUARD_ANIMATION.get() && mTopScrim != null) {
- IntentFilter filter = new IntentFilter(ACTION_SCREEN_OFF);
- filter.addAction(ACTION_USER_PRESENT); // When the device wakes up + keyguard is gone
- mRoot.getContext().registerReceiver(mReceiver, filter);
+ ScreenOnTracker.INSTANCE.get(mActivity).addListener(mScreenOnListener);
}
}
@Override
public void onViewDetachedFromWindow(View view) {
if (!KEYGUARD_ANIMATION.get() && mTopScrim != null) {
- mRoot.getContext().unregisterReceiver(mReceiver);
+ ScreenOnTracker.INSTANCE.get(mActivity).removeListener(mScreenOnListener);
}
}
diff --git a/src/com/android/launcher3/secondarydisplay/SecondaryDisplayLauncher.java b/src/com/android/launcher3/secondarydisplay/SecondaryDisplayLauncher.java
index a2353d8..56dffa9 100644
--- a/src/com/android/launcher3/secondarydisplay/SecondaryDisplayLauncher.java
+++ b/src/com/android/launcher3/secondarydisplay/SecondaryDisplayLauncher.java
@@ -175,8 +175,9 @@
// Note: There should be at most one log per method call. This is enforced implicitly
// by using if-else statements.
AbstractFloatingView topView = AbstractFloatingView.getTopOpenView(this);
- if (topView != null && topView.onBackPressed()) {
+ if (topView != null && topView.canHandleBack()) {
// Handled by the floating view.
+ topView.onBackInvoked();
} else {
showAppDrawer(false);
}
diff --git a/src/com/android/launcher3/settings/DeveloperOptionsFragment.java b/src/com/android/launcher3/settings/DeveloperOptionsFragment.java
index c81214e..40fc16e 100644
--- a/src/com/android/launcher3/settings/DeveloperOptionsFragment.java
+++ b/src/com/android/launcher3/settings/DeveloperOptionsFragment.java
@@ -15,6 +15,9 @@
*/
package com.android.launcher3.settings;
+import static android.content.Intent.ACTION_PACKAGE_ADDED;
+import static android.content.Intent.ACTION_PACKAGE_CHANGED;
+import static android.content.Intent.ACTION_PACKAGE_REMOVED;
import static android.content.pm.PackageManager.GET_RESOLVED_FILTER;
import static android.content.pm.PackageManager.MATCH_DISABLED_COMPONENTS;
import static android.view.View.GONE;
@@ -25,11 +28,9 @@
import static com.android.launcher3.uioverrides.plugins.PluginManagerWrapper.pluginEnabledKey;
import android.annotation.TargetApi;
-import android.content.BroadcastReceiver;
import android.content.ComponentName;
import android.content.Context;
import android.content.Intent;
-import android.content.IntentFilter;
import android.content.SharedPreferences;
import android.content.pm.PackageManager;
import android.content.pm.ResolveInfo;
@@ -66,6 +67,7 @@
import com.android.launcher3.secondarydisplay.SecondaryDisplayLauncher;
import com.android.launcher3.uioverrides.plugins.PluginManagerWrapper;
import com.android.launcher3.util.OnboardingPrefs;
+import com.android.launcher3.util.SimpleBroadcastReceiver;
import java.util.ArrayList;
import java.util.List;
@@ -83,12 +85,8 @@
private static final String ACTION_PLUGIN_SETTINGS = "com.android.systemui.action.PLUGIN_SETTINGS";
private static final String PLUGIN_PERMISSION = "com.android.systemui.permission.PLUGIN";
- private final BroadcastReceiver mPluginReceiver = new BroadcastReceiver() {
- @Override
- public void onReceive(Context context, Intent intent) {
- loadPluginPrefs();
- }
- };
+ private final SimpleBroadcastReceiver mPluginReceiver =
+ new SimpleBroadcastReceiver(i -> loadPluginPrefs());
private PreferenceScreen mPreferenceScreen;
@@ -97,13 +95,9 @@
@Override
public void onCreatePreferences(Bundle savedInstanceState, String rootKey) {
- IntentFilter filter = new IntentFilter(Intent.ACTION_PACKAGE_ADDED);
- filter.addAction(Intent.ACTION_PACKAGE_CHANGED);
- filter.addAction(Intent.ACTION_PACKAGE_REMOVED);
- filter.addDataScheme("package");
- getContext().registerReceiver(mPluginReceiver, filter);
- getContext().registerReceiver(mPluginReceiver,
- new IntentFilter(Intent.ACTION_USER_UNLOCKED));
+ mPluginReceiver.registerPkgActions(getContext(), null,
+ ACTION_PACKAGE_ADDED, ACTION_PACKAGE_CHANGED, ACTION_PACKAGE_REMOVED);
+ mPluginReceiver.register(getContext(), Intent.ACTION_USER_UNLOCKED);
mPreferenceScreen = getPreferenceManager().createPreferenceScreen(getContext());
setPreferenceScreen(mPreferenceScreen);
@@ -185,7 +179,7 @@
@Override
public void onDestroy() {
super.onDestroy();
- getContext().unregisterReceiver(mPluginReceiver);
+ mPluginReceiver.unregisterReceiverSafely(getContext());
}
private PreferenceCategory newCategory(String title) {
diff --git a/src/com/android/launcher3/settings/SettingsActivity.java b/src/com/android/launcher3/settings/SettingsActivity.java
index d2f82c2..8d6a5cb 100644
--- a/src/com/android/launcher3/settings/SettingsActivity.java
+++ b/src/com/android/launcher3/settings/SettingsActivity.java
@@ -226,9 +226,10 @@
getResources().getString(R.string.search_pref_screen_title))){
DeviceProfile mDeviceProfile = InvariantDeviceProfile.INSTANCE.get(
getContext()).getDeviceProfile(getContext());
- getPreferenceScreen().setTitle(mDeviceProfile.isTablet ?
- R.string.search_pref_screen_title_tablet
- : R.string.search_pref_screen_title);
+ getPreferenceScreen().setTitle(mDeviceProfile.isMultiDisplay
+ || mDeviceProfile.isPhone ?
+ R.string.search_pref_screen_title :
+ R.string.search_pref_screen_title_tablet);
}
getActivity().setTitle(getPreferenceScreen().getTitle());
}
diff --git a/src/com/android/launcher3/testing/TestInformationHandler.java b/src/com/android/launcher3/testing/TestInformationHandler.java
index acb7eb3..9a34478 100644
--- a/src/com/android/launcher3/testing/TestInformationHandler.java
+++ b/src/com/android/launcher3/testing/TestInformationHandler.java
@@ -201,6 +201,13 @@
});
}
+ case TestProtocol.REQUEST_WORKSPACE_COLUMNS_ROWS: {
+ return getLauncherUIProperty(Bundle::putParcelable, launcher -> new Point(
+ InvariantDeviceProfile.INSTANCE.get(mContext).numColumns,
+ InvariantDeviceProfile.INSTANCE.get(mContext).numRows)
+ );
+ }
+
case TestProtocol.REQUEST_HOTSEAT_CELL_CENTER: {
final HotseatCellCenterRequest request = extra.getParcelable(
TestProtocol.TEST_INFO_REQUEST_FIELD);
diff --git a/src/com/android/launcher3/testing/shared/TestProtocol.java b/src/com/android/launcher3/testing/shared/TestProtocol.java
index f5ee91b..9b2ce9a 100644
--- a/src/com/android/launcher3/testing/shared/TestProtocol.java
+++ b/src/com/android/launcher3/testing/shared/TestProtocol.java
@@ -123,6 +123,7 @@
public static final String REQUEST_WORKSPACE_CELL_LAYOUT_SIZE = "workspace-cell-layout-size";
public static final String REQUEST_WORKSPACE_CELL_CENTER = "workspace-cell-center";
+ public static final String REQUEST_WORKSPACE_COLUMNS_ROWS = "workspace-columns-rows";
public static final String REQUEST_HOTSEAT_CELL_CENTER = "hotseat-cell-center";
diff --git a/src/com/android/launcher3/testing/shared/WorkspaceCellCenterRequest.java b/src/com/android/launcher3/testing/shared/WorkspaceCellCenterRequest.java
index 80dbef8..e2cd8ea 100644
--- a/src/com/android/launcher3/testing/shared/WorkspaceCellCenterRequest.java
+++ b/src/com/android/launcher3/testing/shared/WorkspaceCellCenterRequest.java
@@ -124,7 +124,7 @@
* Set span Height in cells
*/
public WorkspaceCellCenterRequest.Builder setSpanY(int y) {
- this.mCellY = y;
+ this.mSpanY = y;
return this;
}
diff --git a/src/com/android/launcher3/util/DisplayController.java b/src/com/android/launcher3/util/DisplayController.java
index c52890f..9ed6700 100644
--- a/src/com/android/launcher3/util/DisplayController.java
+++ b/src/com/android/launcher3/util/DisplayController.java
@@ -23,7 +23,6 @@
import static com.android.launcher3.config.FeatureFlags.ENABLE_TRANSIENT_TASKBAR;
import static com.android.launcher3.config.FeatureFlags.FORCE_PERSISTENT_TASKBAR;
import static com.android.launcher3.util.Executors.MAIN_EXECUTOR;
-import static com.android.launcher3.util.PackageManagerHelper.getPackageFilter;
import static com.android.launcher3.util.window.WindowManagerProxy.MIN_TABLET_WIDTH;
import android.annotation.SuppressLint;
@@ -111,8 +110,7 @@
}
// Initialize navigation mode change listener
- mContext.registerReceiver(mReceiver,
- getPackageFilter(TARGET_OVERLAY_PACKAGE, ACTION_OVERLAY_CHANGED));
+ mReceiver.registerPkgActions(mContext, TARGET_OVERLAY_PACKAGE, ACTION_OVERLAY_CHANGED);
WindowManagerProxy wmProxy = WindowManagerProxy.INSTANCE.get(context);
Context displayInfoContext = getDisplayInfoContext(display);
diff --git a/src/com/android/launcher3/util/PackageManagerHelper.java b/src/com/android/launcher3/util/PackageManagerHelper.java
index 140440e..a6a2751 100644
--- a/src/com/android/launcher3/util/PackageManagerHelper.java
+++ b/src/com/android/launcher3/util/PackageManagerHelper.java
@@ -21,7 +21,6 @@
import android.content.ComponentName;
import android.content.Context;
import android.content.Intent;
-import android.content.IntentFilter;
import android.content.pm.ApplicationInfo;
import android.content.pm.LauncherActivityInfo;
import android.content.pm.LauncherApps;
@@ -33,7 +32,6 @@
import android.net.Uri;
import android.os.Build;
import android.os.Bundle;
-import android.os.PatternMatcher;
import android.os.UserHandle;
import android.text.TextUtils;
import android.util.Log;
@@ -249,19 +247,6 @@
}
}
- /**
- * Creates an intent filter to listen for actions with a specific package in the data field.
- */
- public static IntentFilter getPackageFilter(String pkg, String... actions) {
- IntentFilter packageFilter = new IntentFilter();
- for (String action : actions) {
- packageFilter.addAction(action);
- }
- packageFilter.addDataScheme("package");
- packageFilter.addDataSchemeSpecificPart(pkg, PatternMatcher.PATTERN_LITERAL);
- return packageFilter;
- }
-
public static boolean isSystemApp(@NonNull final Context context,
@NonNull final Intent intent) {
PackageManager pm = context.getPackageManager();
diff --git a/src/com/android/launcher3/util/ScreenOnTracker.java b/src/com/android/launcher3/util/ScreenOnTracker.java
new file mode 100644
index 0000000..67530a6
--- /dev/null
+++ b/src/com/android/launcher3/util/ScreenOnTracker.java
@@ -0,0 +1,93 @@
+/*
+ * 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.util;
+
+import static android.content.Intent.ACTION_SCREEN_OFF;
+import static android.content.Intent.ACTION_SCREEN_ON;
+import static android.content.Intent.ACTION_USER_PRESENT;
+
+import android.content.Context;
+import android.content.Intent;
+
+import java.util.concurrent.CopyOnWriteArrayList;
+
+/**
+ * Utility class for tracking if the screen is currently on or off
+ */
+public class ScreenOnTracker {
+
+ public static final MainThreadInitializedObject<ScreenOnTracker> INSTANCE =
+ new MainThreadInitializedObject<>(ScreenOnTracker::new);
+
+ private final SimpleBroadcastReceiver mReceiver = new SimpleBroadcastReceiver(this::onReceive);
+ private final CopyOnWriteArrayList<ScreenOnListener> mListeners = new CopyOnWriteArrayList<>();
+
+ private boolean mIsScreenOn;
+
+ private ScreenOnTracker(Context context) {
+ // Assume that the screen is on to begin with
+ mIsScreenOn = true;
+ mReceiver.register(context, ACTION_SCREEN_ON, ACTION_SCREEN_OFF, ACTION_USER_PRESENT);
+ }
+
+ private void onReceive(Intent intent) {
+ String action = intent.getAction();
+ if (ACTION_SCREEN_ON.equals(action)) {
+ mIsScreenOn = true;
+ dispatchScreenOnChanged();
+ } else if (ACTION_SCREEN_OFF.equals(action)) {
+ mIsScreenOn = false;
+ dispatchScreenOnChanged();
+ } else if (ACTION_USER_PRESENT.equals(action)) {
+ mListeners.forEach(ScreenOnListener::onUserPresent);
+ }
+ }
+
+ private void dispatchScreenOnChanged() {
+ mListeners.forEach(l -> l.onScreenOnChanged(mIsScreenOn));
+ }
+
+ /** Returns if the screen is on or not */
+ public boolean isScreenOn() {
+ return mIsScreenOn;
+ }
+
+ /** Adds a listener for screen on changes */
+ public void addListener(ScreenOnListener listener) {
+ mListeners.add(listener);
+ }
+
+ /** Removes a previously added listener */
+ public void removeListener(ScreenOnListener listener) {
+ mListeners.remove(listener);
+ }
+
+ /**
+ * Interface to listen for screen on changes
+ */
+ public interface ScreenOnListener {
+
+ /**
+ * Called when the screen turns on/off
+ */
+ void onScreenOnChanged(boolean isOn);
+
+ /**
+ * Called when the keyguard goes away
+ */
+ default void onUserPresent() { }
+ }
+}
diff --git a/src/com/android/launcher3/util/SimpleBroadcastReceiver.java b/src/com/android/launcher3/util/SimpleBroadcastReceiver.java
index 0a23506..064bcd0 100644
--- a/src/com/android/launcher3/util/SimpleBroadcastReceiver.java
+++ b/src/com/android/launcher3/util/SimpleBroadcastReceiver.java
@@ -19,6 +19,10 @@
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
+import android.os.PatternMatcher;
+import android.text.TextUtils;
+
+import androidx.annotation.Nullable;
import java.util.function.Consumer;
@@ -39,18 +43,34 @@
* Helper method to register multiple actions
*/
public void register(Context context, String... actions) {
- register(context, 0, actions);
+ context.registerReceiver(this, getFilter(actions));
}
/**
- * Helper method to register multiple actions with one or more {@code flags}.
+ * Helper method to register multiple actions associated with a paction
*/
- public void register(Context context, int flags, String... actions) {
+ public void registerPkgActions(Context context, @Nullable String pkg, String... actions) {
+ context.registerReceiver(this, getPackageFilter(pkg, actions));
+ }
+
+ /**
+ * Creates an intent filter to listen for actions with a specific package in the data field.
+ */
+ public static IntentFilter getPackageFilter(String pkg, String... actions) {
+ IntentFilter filter = getFilter(actions);
+ filter.addDataScheme("package");
+ if (!TextUtils.isEmpty(pkg)) {
+ filter.addDataSchemeSpecificPart(pkg, PatternMatcher.PATTERN_LITERAL);
+ }
+ return filter;
+ }
+
+ private static IntentFilter getFilter(String... actions) {
IntentFilter filter = new IntentFilter();
for (String action : actions) {
filter.addAction(action);
}
- context.registerReceiver(this, filter, flags);
+ return filter;
}
/**
diff --git a/src/com/android/launcher3/util/WallpaperOffsetInterpolator.java b/src/com/android/launcher3/util/WallpaperOffsetInterpolator.java
index 43e9820..4ac6bc4 100644
--- a/src/com/android/launcher3/util/WallpaperOffsetInterpolator.java
+++ b/src/com/android/launcher3/util/WallpaperOffsetInterpolator.java
@@ -1,12 +1,11 @@
package com.android.launcher3.util;
+import static android.content.Intent.ACTION_WALLPAPER_CHANGED;
+
import static com.android.launcher3.util.Executors.UI_HELPER_EXECUTOR;
import android.app.WallpaperManager;
-import android.content.BroadcastReceiver;
import android.content.Context;
-import android.content.Intent;
-import android.content.IntentFilter;
import android.os.Handler;
import android.os.IBinder;
import android.os.Message;
@@ -23,7 +22,7 @@
/**
* Utility class to handle wallpaper scrolling along with workspace.
*/
-public class WallpaperOffsetInterpolator extends BroadcastReceiver {
+public class WallpaperOffsetInterpolator {
private static final int[] sTempInt = new int[2];
private static final String TAG = "WPOffsetInterpolator";
@@ -32,6 +31,8 @@
// Don't use all the wallpaper for parallax until you have at least this many pages
private static final int MIN_PARALLAX_PAGE_SPAN = 4;
+ private final SimpleBroadcastReceiver mWallpaperChangeReceiver =
+ new SimpleBroadcastReceiver(i -> onWallpaperChanged());
private final Workspace<?> mWorkspace;
private final boolean mIsRtl;
private final Handler mHandler;
@@ -197,22 +198,20 @@
public void setWindowToken(IBinder token) {
mWindowToken = token;
if (mWindowToken == null && mRegistered) {
- mWorkspace.getContext().unregisterReceiver(this);
+ mWallpaperChangeReceiver.unregisterReceiverSafely(mWorkspace.getContext());
mRegistered = false;
} else if (mWindowToken != null && !mRegistered) {
- mWorkspace.getContext()
- .registerReceiver(this, new IntentFilter(Intent.ACTION_WALLPAPER_CHANGED));
- onReceive(mWorkspace.getContext(), null);
+ mWallpaperChangeReceiver.register(mWorkspace.getContext(), ACTION_WALLPAPER_CHANGED);
+ onWallpaperChanged();
mRegistered = true;
}
}
- @Override
- public void onReceive(Context context, Intent intent) {
+ private void onWallpaperChanged() {
UI_HELPER_EXECUTOR.execute(() -> {
// Updating the boolean on a background thread is fine as the assignments are atomic
- mWallpaperIsLiveWallpaper =
- WallpaperManager.getInstance(context).getWallpaperInfo() != null;
+ mWallpaperIsLiveWallpaper = WallpaperManager.getInstance(mWorkspace.getContext())
+ .getWallpaperInfo() != null;
updateOffset();
});
}
diff --git a/src/com/android/launcher3/widget/picker/WidgetsFullSheet.java b/src/com/android/launcher3/widget/picker/WidgetsFullSheet.java
index 38cdb4b..c78ecf5 100644
--- a/src/com/android/launcher3/widget/picker/WidgetsFullSheet.java
+++ b/src/com/android/launcher3/widget/picker/WidgetsFullSheet.java
@@ -17,7 +17,9 @@
import static android.view.View.MeasureSpec.makeMeasureSpec;
+import static com.android.launcher3.LauncherAnimUtils.SCALE_PROPERTY;
import static com.android.launcher3.LauncherAnimUtils.VIEW_TRANSLATE_Y;
+import static com.android.launcher3.allapps.AllAppsTransitionController.SWIPE_ALL_APPS_TO_HOME_MIN_SCALE;
import static com.android.launcher3.logging.StatsLogManager.LauncherEvent.LAUNCHER_WIDGETSTRAY_SEARCHED;
import static com.android.launcher3.testing.shared.TestProtocol.NORMAL_STATE_ORDINAL;
@@ -45,6 +47,7 @@
import android.widget.Button;
import android.widget.TextView;
+import androidx.annotation.FloatRange;
import androidx.annotation.Nullable;
import androidx.annotation.VisibleForTesting;
import androidx.recyclerview.widget.DefaultItemAnimator;
@@ -54,6 +57,7 @@
import com.android.launcher3.LauncherAppState;
import com.android.launcher3.R;
import com.android.launcher3.Utilities;
+import com.android.launcher3.anim.Interpolators;
import com.android.launcher3.anim.PendingAnimation;
import com.android.launcher3.compat.AccessibilityManagerCompat;
import com.android.launcher3.model.UserManagerState;
@@ -264,6 +268,15 @@
attachScrollbarToRecyclerView(currentRecyclerView);
}
+ @Override
+ public void onBackProgressed(@FloatRange(from = 0.0, to = 1.0) float progress) {
+ float deceleratedProgress =
+ Interpolators.PREDICTIVE_BACK_DECELERATED_EASE.getInterpolation(progress);
+ float scaleProgress = SWIPE_ALL_APPS_TO_HOME_MIN_SCALE
+ + (1 - SWIPE_ALL_APPS_TO_HOME_MIN_SCALE) * (1 - deceleratedProgress);
+ SCALE_PROPERTY.set(this, scaleProgress);
+ }
+
private void attachScrollbarToRecyclerView(WidgetsRecyclerView recyclerView) {
recyclerView.bindFastScrollbar();
if (mCurrentWidgetsRecyclerView != recyclerView) {
@@ -736,12 +749,12 @@
}
@Override
- public boolean onBackPressed() {
+ public void onBackInvoked() {
if (mIsInSearchMode) {
mSearchBar.reset();
- return true;
+ } else {
+ super.onBackInvoked();
}
- return super.onBackPressed();
}
@Override
diff --git a/tests/src/com/android/launcher3/DeviceProfileBaseTest.kt b/tests/src/com/android/launcher3/DeviceProfileBaseTest.kt
index 2da5eee..b7d0f28 100644
--- a/tests/src/com/android/launcher3/DeviceProfileBaseTest.kt
+++ b/tests/src/com/android/launcher3/DeviceProfileBaseTest.kt
@@ -112,7 +112,7 @@
numFolderRows = 3
numFolderColumns = 3
- folderStyle = R.style.FolderDefaultStyle
+ folderStyle = R.style.FolderStyleDefault
inlineNavButtonsEndSpacing = R.dimen.taskbar_button_margin_split
@@ -190,7 +190,7 @@
numFolderRows = 3
numFolderColumns = 3
- folderStyle = R.style.FolderDefaultStyle
+ folderStyle = R.style.FolderStyleDefault
inlineNavButtonsEndSpacing = R.dimen.taskbar_button_margin_6_5
@@ -269,7 +269,7 @@
numFolderRows = 3
numFolderColumns = 3
- folderStyle = R.style.FolderDefaultStyle
+ folderStyle = R.style.FolderStyleDefault
inlineNavButtonsEndSpacing = R.dimen.taskbar_button_margin_split
diff --git a/tests/src/com/android/launcher3/celllayout/CellLayoutBoard.java b/tests/src/com/android/launcher3/celllayout/CellLayoutBoard.java
index 469d79f..6d75180 100644
--- a/tests/src/com/android/launcher3/celllayout/CellLayoutBoard.java
+++ b/tests/src/com/android/launcher3/celllayout/CellLayoutBoard.java
@@ -29,7 +29,73 @@
import java.util.stream.Collectors;
-public class CellLayoutBoard {
+public class CellLayoutBoard implements Comparable<CellLayoutBoard> {
+
+ private boolean intersects(Rect r1, Rect r2) {
+ // If one rectangle is on left side of other
+ if (r1.left > r2.right || r2.left > r1.right) {
+ return false;
+ }
+
+ // If one rectangle is above other
+ if (r1.bottom > r2.top || r2.bottom > r1.top) {
+ return false;
+ }
+
+ return true;
+ }
+
+ private boolean overlapsWithIgnored(Set<Rect> ignoredRectangles, Rect rect) {
+ for (Rect ignoredRect : ignoredRectangles) {
+ // Using the built in intersects doesn't work because it doesn't account for area 0
+ if (intersects(ignoredRect, rect)) {
+ return true;
+ }
+ }
+ return false;
+ }
+
+ @Override
+ public int compareTo(CellLayoutBoard cellLayoutBoard) {
+ // to be equal they need to have the same number of widgets and the same dimensions
+ // their order can be different
+ Set<Rect> widgetsSet = new HashSet<>();
+ Set<Rect> ignoredRectangles = new HashSet<>();
+ for (WidgetRect rect : mWidgetsRects) {
+ if (rect.shouldIgnore()) {
+ ignoredRectangles.add(rect.mBounds);
+ } else {
+ widgetsSet.add(rect.mBounds);
+ }
+ }
+ for (WidgetRect rect : cellLayoutBoard.mWidgetsRects) {
+ // ignore rectangles overlapping with the area marked by x
+ if (overlapsWithIgnored(ignoredRectangles, rect.mBounds)) {
+ continue;
+ }
+ if (!widgetsSet.contains(rect.mBounds)) {
+ return -1;
+ }
+ widgetsSet.remove(rect.mBounds);
+ }
+ if (!widgetsSet.isEmpty()) {
+ return 1;
+ }
+
+ // to be equal they need to have the same number of icons their order can be different
+ Set<Point> iconsSet = new HashSet<>();
+ mIconPoints.forEach(icon -> iconsSet.add(icon.getCoord()));
+ for (IconPoint icon : cellLayoutBoard.mIconPoints) {
+ if (!iconsSet.contains(icon.getCoord())) {
+ return -1;
+ }
+ iconsSet.remove(icon.getCoord());
+ }
+ if (!iconsSet.isEmpty()) {
+ return 1;
+ }
+ return 0;
+ }
public static class CellType {
// The cells marked by this will be filled by 1x1 widgets and will be ignored when
@@ -115,7 +181,7 @@
List<IconPoint> mIconPoints = new ArrayList<>();
Map<Character, IconPoint> mIconsMap = new HashMap<>();
- Point mMain = new Point();
+ WidgetRect mMain = null;
CellLayoutBoard() {
for (int x = 0; x < mWidget.length; x++) {
@@ -133,7 +199,7 @@
return mIconPoints;
}
- public Point getMain() {
+ public WidgetRect getMain() {
return mMain;
}
@@ -273,6 +339,16 @@
return iconPoints;
}
+ public static WidgetRect getMainFromList(List<CellLayoutBoard> boards) {
+ for (CellLayoutBoard board : boards) {
+ WidgetRect main = board.getMain();
+ if (main != null) {
+ return main;
+ }
+ }
+ return null;
+ }
+
public static CellLayoutBoard boardFromString(String boardStr) {
String[] lines = boardStr.split("\n");
CellLayoutBoard board = new CellLayoutBoard();
@@ -281,17 +357,18 @@
String line = lines[y];
for (int x = 0; x < line.length(); x++) {
char c = line.charAt(x);
- if (c == CellType.MAIN_WIDGET) {
- board.mMain = new Point(x, y);
- }
if (c != CellType.EMPTY) {
board.mWidget[x][y] = line.charAt(x);
}
}
}
board.mWidgetsRects = getRects(board.mWidget);
- board.mWidgetsRects.forEach(
- widgetRect -> board.mWidgetsMap.put(widgetRect.mType, widgetRect));
+ board.mWidgetsRects.forEach(widgetRect -> {
+ if (widgetRect.mType == CellType.MAIN_WIDGET) {
+ board.mMain = widgetRect;
+ }
+ board.mWidgetsMap.put(widgetRect.mType, widgetRect);
+ });
board.mIconPoints = getIconPoints(board.mWidget);
return board;
}
@@ -308,4 +385,24 @@
}
return s.toString();
}
+
+ public static List<CellLayoutBoard> boardListFromString(String boardsStr) {
+ String[] lines = boardsStr.split("\n");
+ ArrayList<String> individualBoards = new ArrayList<>();
+ ArrayList<CellLayoutBoard> boards = new ArrayList<>();
+ for (String line : lines) {
+ String[] boardSegment = line.split("\\|");
+ for (int i = 0; i < boardSegment.length; i++) {
+ if (i >= individualBoards.size()) {
+ individualBoards.add(boardSegment[i]);
+ } else {
+ individualBoards.set(i, individualBoards.get(i) + "\n" + boardSegment[i]);
+ }
+ }
+ }
+ for (String board : individualBoards) {
+ boards.add(CellLayoutBoard.boardFromString(board));
+ }
+ return boards;
+ }
}
diff --git a/tests/src/com/android/launcher3/celllayout/MultipleCellLayoutsSimpleReorder.java b/tests/src/com/android/launcher3/celllayout/MultipleCellLayoutsSimpleReorder.java
new file mode 100644
index 0000000..9b52fe8
--- /dev/null
+++ b/tests/src/com/android/launcher3/celllayout/MultipleCellLayoutsSimpleReorder.java
@@ -0,0 +1,88 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.android.launcher3.celllayout.testcases;
+
+import android.graphics.Point;
+
+import java.util.Map;
+
+/**
+ * The grids represent the workspace to be build by TestWorkspaceBuilder, to see what each character
+ * in the board mean refer to {@code CellType}
+ */
+public class MultipleCellLayoutsSimpleReorder {
+
+ /** 5x5 Test
+ **/
+ private static final String START_BOARD_STR_5x5 = ""
+ + "xxxxx|-----\n"
+ + "--mm-|-----\n"
+ + "--mm-|-----\n"
+ + "-----|-----\n"
+ + "-----|-----";
+ private static final Point MOVE_TO_5x5 = new Point(8, 3);
+ private static final String END_BOARD_STR_5x5 = ""
+ + "xxxxx|-----\n"
+ + "-----|-----\n"
+ + "-----|-----\n"
+ + "-----|---mm\n"
+ + "-----|---mm";
+ private static final ReorderTestCase TEST_CASE_5x5 = new ReorderTestCase(START_BOARD_STR_5x5,
+ MOVE_TO_5x5,
+ END_BOARD_STR_5x5);
+
+ /** 4x4 Test
+ **/
+ private static final String START_BOARD_STR_4x4 = ""
+ + "xxxx|----\n"
+ + "--mm|----\n"
+ + "--mm|----\n"
+ + "----|----";
+ private static final Point MOVE_TO_4x4 = new Point(5, 3);
+ private static final String END_BOARD_STR_4x4 = ""
+ + "xxxx|----\n"
+ + "----|----\n"
+ + "----|-mm-\n"
+ + "----|-mm-";
+ private static final ReorderTestCase TEST_CASE_4x4 = new ReorderTestCase(START_BOARD_STR_4x4,
+ MOVE_TO_4x4,
+ END_BOARD_STR_4x4);
+
+
+ /** 6x5 Test
+ **/
+ private static final String START_BOARD_STR_6x5 = ""
+ + "xxxxxx|------\n"
+ + "--m---|------\n"
+ + "------|------\n"
+ + "------|------\n"
+ + "------|------";
+ private static final Point MOVE_TO_6x5 = new Point(10, 4);
+ private static final String END_BOARD_STR_6x5 = ""
+ + "xxxxxx|------\n"
+ + "------|------\n"
+ + "------|------\n"
+ + "------|------\n"
+ + "------|----m-";
+ private static final ReorderTestCase TEST_CASE_6x5 = new ReorderTestCase(START_BOARD_STR_6x5,
+ MOVE_TO_6x5,
+ END_BOARD_STR_6x5);
+
+ public static final Map<Point, ReorderTestCase> TEST_BY_GRID_SIZE =
+ Map.of(new Point(5, 5), TEST_CASE_5x5,
+ new Point(4, 4), TEST_CASE_4x4,
+ new Point(6, 5), TEST_CASE_6x5);
+}
diff --git a/tests/src/com/android/launcher3/celllayout/ReorderWidgets.java b/tests/src/com/android/launcher3/celllayout/ReorderWidgets.java
index 7b38ed6..35f6cbc 100644
--- a/tests/src/com/android/launcher3/celllayout/ReorderWidgets.java
+++ b/tests/src/com/android/launcher3/celllayout/ReorderWidgets.java
@@ -29,6 +29,7 @@
import com.android.launcher3.InvariantDeviceProfile;
import com.android.launcher3.celllayout.testcases.FullReorderCase;
import com.android.launcher3.celllayout.testcases.MoveOutReorderCase;
+import com.android.launcher3.celllayout.testcases.MultipleCellLayoutsSimpleReorder;
import com.android.launcher3.celllayout.testcases.PushReorderCase;
import com.android.launcher3.celllayout.testcases.ReorderTestCase;
import com.android.launcher3.celllayout.testcases.SimpleReorderCase;
@@ -38,7 +39,6 @@
import com.android.launcher3.ui.TaplTestsLauncher3;
import com.android.launcher3.util.rule.ShellCommandRule;
import com.android.launcher3.views.DoubleShadowBubbleTextView;
-import com.android.launcher3.widget.LauncherAppWidgetHostView;
import org.junit.Assume;
import org.junit.Before;
@@ -48,6 +48,7 @@
import org.junit.runner.RunWith;
import java.util.ArrayList;
+import java.util.List;
import java.util.Map;
import java.util.concurrent.ExecutionException;
@@ -62,20 +63,6 @@
TestWorkspaceBuilder mWorkspaceBuilder;
- private View getViewAt(int cellX, int cellY) {
- return getFromLauncher(l -> l.getWorkspace().getScreenWithId(
- l.getWorkspace().getScreenIdForPageIndex(0)).getChildAt(cellX, cellY));
- }
-
- private Point getCellDimensions() {
- return getFromLauncher(l -> {
- CellLayout cellLayout = l.getWorkspace().getScreenWithId(
- l.getWorkspace().getScreenIdForPageIndex(0));
- return new Point(cellLayout.getWidth() / cellLayout.getCountX(),
- cellLayout.getHeight() / cellLayout.getCountY());
- });
- }
-
@Before
public void setup() throws Throwable {
mWorkspaceBuilder = new TestWorkspaceBuilder(this, mTargetContext);
@@ -86,28 +73,26 @@
/**
* Validate if the given board represent the current CellLayout
**/
- private boolean validateBoard(CellLayoutBoard board) {
- boolean match = true;
- Point cellDimensions = getCellDimensions();
- for (CellLayoutBoard.WidgetRect widgetRect : board.getWidgets()) {
- if (widgetRect.shouldIgnore()) {
- continue;
+ private boolean validateBoard(List<CellLayoutBoard> testBoards) {
+ ArrayList<CellLayoutBoard> workspaceBoards = workspaceToBoards();
+ if (workspaceBoards.size() < testBoards.size()) {
+ return false;
+ }
+ for (int i = 0; i < testBoards.size(); i++) {
+ if (testBoards.get(i).compareTo(workspaceBoards.get(i)) != 0) {
+ return false;
}
- View widget = getViewAt(widgetRect.getCellX(), widgetRect.getCellY());
- assertTrue("The view selected at " + board + " is not a widget",
- widget instanceof LauncherAppWidgetHostView);
- match &= widgetRect.getSpanX()
- == Math.round(widget.getWidth() / (float) cellDimensions.x);
- match &= widgetRect.getSpanY()
- == Math.round(widget.getHeight() / (float) cellDimensions.y);
- if (!match) return match;
}
- for (CellLayoutBoard.IconPoint iconPoint : board.getIcons()) {
- View icon = getViewAt(iconPoint.getCoord().x, iconPoint.getCoord().y);
- assertTrue("The view selected at " + iconPoint.coord + " is not an Icon",
- icon instanceof DoubleShadowBubbleTextView);
+ return true;
+ }
+
+ private FavoriteItemsTransaction buildWorkspaceFromBoards(List<CellLayoutBoard> boards,
+ FavoriteItemsTransaction transaction) {
+ for (int i = 0; i < boards.size(); i++) {
+ CellLayoutBoard board = boards.get(i);
+ mWorkspaceBuilder.buildFromBoard(board, transaction, i);
}
- return match;
+ return transaction;
}
private void printCurrentWorkspace() {
@@ -148,22 +133,25 @@
private void runTestCase(ReorderTestCase testCase)
throws ExecutionException, InterruptedException {
- Point mainWidgetCellPos = testCase.mStart.getMain();
+ CellLayoutBoard.WidgetRect mainWidgetCellPos = CellLayoutBoard.getMainFromList(
+ testCase.mStart);
FavoriteItemsTransaction transaction =
new FavoriteItemsTransaction(mTargetContext, this);
- mWorkspaceBuilder.buildFromBoard(testCase.mStart, transaction).commit();
+ transaction = buildWorkspaceFromBoards(testCase.mStart, transaction);
+ transaction.commit();
waitForLauncherCondition("Workspace didn't finish loading", l -> !l.isWorkspaceLoading());
- Widget widget = mLauncher.getWorkspace().getWidgetAtCell(mainWidgetCellPos.x,
- mainWidgetCellPos.y);
+ Widget widget = mLauncher.getWorkspace().getWidgetAtCell(mainWidgetCellPos.getCellX(),
+ mainWidgetCellPos.getCellY());
assertNotNull(widget);
WidgetResizeFrame resizeFrame = widget.dragWidgetToWorkspace(testCase.moveMainTo.x,
- testCase.moveMainTo.y);
+ testCase.moveMainTo.y, mainWidgetCellPos.getSpanX(), mainWidgetCellPos.getSpanY());
resizeFrame.dismiss();
boolean isValid = false;
- for (CellLayoutBoard board : testCase.mEnd) {
- isValid |= validateBoard(board);
+ for (List<CellLayoutBoard> boards : testCase.mEnd) {
+ isValid |= validateBoard(boards);
+ if (isValid) break;
}
printCurrentWorkspace();
assertTrue("Non of the valid boards match with the current state", isValid);
@@ -207,4 +195,11 @@
runTestCaseMap(MoveOutReorderCase.TEST_BY_GRID_SIZE,
MoveOutReorderCase.class.getSimpleName());
}
+
+ @Test
+ public void multipleCellLayoutsSimpleReorder() throws ExecutionException, InterruptedException {
+ Assume.assumeTrue("Test doesn't support foldables", !mLauncher.isTwoPanels());
+ runTestCaseMap(MultipleCellLayoutsSimpleReorder.TEST_BY_GRID_SIZE,
+ MultipleCellLayoutsSimpleReorder.class.getSimpleName());
+ }
}
diff --git a/tests/src/com/android/launcher3/celllayout/TestWorkspaceBuilder.java b/tests/src/com/android/launcher3/celllayout/TestWorkspaceBuilder.java
index 7e3588b..5945605 100644
--- a/tests/src/com/android/launcher3/celllayout/TestWorkspaceBuilder.java
+++ b/tests/src/com/android/launcher3/celllayout/TestWorkspaceBuilder.java
@@ -15,7 +15,6 @@
*/
package com.android.launcher3.celllayout;
-import static com.android.launcher3.WorkspaceLayoutManager.FIRST_SCREEN_ID;
import static com.android.launcher3.util.WidgetUtils.createWidgetInfo;
import android.content.ComponentName;
@@ -62,7 +61,7 @@
* Fills the given rect in WidgetRect with 1x1 widgets. This is useful to equalize cases.
*/
private FavoriteItemsTransaction fillWithWidgets(CellLayoutBoard.WidgetRect widgetRect,
- FavoriteItemsTransaction transaction) {
+ FavoriteItemsTransaction transaction, int screenId) {
int initX = widgetRect.getCellX();
int initY = widgetRect.getCellY();
for (int x = initX; x < initX + widgetRect.getSpanX(); x++) {
@@ -71,8 +70,7 @@
// this widgets are filling, we don't care if we can't place them
ItemInfo item = createWidgetInCell(
new CellLayoutBoard.WidgetRect(CellLayoutBoard.CellType.IGNORE,
- new Rect(x, y, x, y))
- );
+ new Rect(x, y, x, y)), screenId);
transaction.addItem(item);
} catch (Exception e) {
Log.d(TAG, "Unable to place filling widget at " + x + "," + y);
@@ -94,11 +92,11 @@
}
private void addCorrespondingWidgetRect(CellLayoutBoard.WidgetRect widgetRect,
- FavoriteItemsTransaction transaction) {
+ FavoriteItemsTransaction transaction, int screenId) {
if (widgetRect.mType == 'x') {
- fillWithWidgets(widgetRect, transaction);
+ fillWithWidgets(widgetRect, transaction, screenId);
} else {
- transaction.addItem(createWidgetInCell(widgetRect));
+ transaction.addItem(createWidgetInCell(widgetRect, screenId));
}
}
@@ -106,11 +104,11 @@
* Builds the given board into the transaction
*/
public FavoriteItemsTransaction buildFromBoard(CellLayoutBoard board,
- FavoriteItemsTransaction transaction) {
+ FavoriteItemsTransaction transaction, final int screenId) {
board.getWidgets().forEach(
- (widgetRect) -> addCorrespondingWidgetRect(widgetRect, transaction));
+ (widgetRect) -> addCorrespondingWidgetRect(widgetRect, transaction, screenId));
board.getIcons().forEach((iconPoint) ->
- transaction.addItem(createIconInCell(iconPoint))
+ transaction.addItem(createIconInCell(iconPoint, screenId))
);
return transaction;
}
@@ -127,7 +125,7 @@
return transaction;
}
- private ItemInfo createWidgetInCell(CellLayoutBoard.WidgetRect widgetRect) {
+ private ItemInfo createWidgetInCell(CellLayoutBoard.WidgetRect widgetRect, int screenId) {
LauncherAppWidgetProviderInfo info = TestViewHelpers.findWidgetProvider(mTest, false);
LauncherAppWidgetInfo item = createWidgetInfo(info,
ApplicationProvider.getApplicationContext(), true);
@@ -136,14 +134,14 @@
item.cellY = widgetRect.getCellY();
item.spanX = widgetRect.getSpanX();
item.spanY = widgetRect.getSpanY();
- item.screenId = FIRST_SCREEN_ID;
+ item.screenId = screenId;
return item;
}
- private ItemInfo createIconInCell(CellLayoutBoard.IconPoint iconPoint) {
+ private ItemInfo createIconInCell(CellLayoutBoard.IconPoint iconPoint, int screenId) {
WorkspaceItemInfo item = new WorkspaceItemInfo(getApp());
item.id = getID();
- item.screenId = FIRST_SCREEN_ID;
+ item.screenId = screenId;
item.cellX = iconPoint.getCoord().x;
item.cellY = iconPoint.getCoord().y;
item.minSpanY = item.minSpanX = item.spanX = item.spanY = 1;
diff --git a/tests/src/com/android/launcher3/celllayout/testcases/ReorderTestCase.java b/tests/src/com/android/launcher3/celllayout/testcases/ReorderTestCase.java
index 0a28668..1689e47 100644
--- a/tests/src/com/android/launcher3/celllayout/testcases/ReorderTestCase.java
+++ b/tests/src/com/android/launcher3/celllayout/testcases/ReorderTestCase.java
@@ -24,23 +24,23 @@
import java.util.stream.Collectors;
public class ReorderTestCase {
- public CellLayoutBoard mStart;
+ public List<CellLayoutBoard> mStart;
public Point moveMainTo;
- public List<CellLayoutBoard> mEnd;
+ public List<List<CellLayoutBoard>> mEnd;
- ReorderTestCase(CellLayoutBoard start, Point moveMainTo, CellLayoutBoard ... end) {
+ ReorderTestCase(List<CellLayoutBoard> start, Point moveMainTo, List<CellLayoutBoard> ... end) {
mStart = start;
this.moveMainTo = moveMainTo;
mEnd = Arrays.asList(end);
}
ReorderTestCase(String start, Point moveMainTo, String ... end) {
- mStart = CellLayoutBoard.boardFromString(start);
+ mStart = CellLayoutBoard.boardListFromString(start);
this.moveMainTo = moveMainTo;
mEnd = Arrays
.asList(end)
.stream()
- .map(CellLayoutBoard::boardFromString)
+ .map(CellLayoutBoard::boardListFromString)
.collect(Collectors.toList());
}
}
diff --git a/tests/src/com/android/launcher3/celllayout/testcases/SimpleReorderCase.java b/tests/src/com/android/launcher3/celllayout/testcases/SimpleReorderCase.java
index 546c48b..c9f6849 100644
--- a/tests/src/com/android/launcher3/celllayout/testcases/SimpleReorderCase.java
+++ b/tests/src/com/android/launcher3/celllayout/testcases/SimpleReorderCase.java
@@ -33,13 +33,13 @@
+ "--mm-\n"
+ "-----\n"
+ "-----";
- private static final Point MOVE_TO_5x5 = new Point(4, 4);
+ private static final Point MOVE_TO_5x5 = new Point(0, 4);
private static final String END_BOARD_STR_5x5 = ""
+ "xxxxx\n"
+ "-----\n"
+ "-----\n"
- + "---mm\n"
- + "---mm";
+ + "mm---\n"
+ + "mm---";
private static final ReorderTestCase TEST_CASE_5x5 = new ReorderTestCase(START_BOARD_STR_5x5,
MOVE_TO_5x5,
END_BOARD_STR_5x5);
@@ -61,7 +61,27 @@
MOVE_TO_4x4,
END_BOARD_STR_4x4);
+ /** 6x5 Test
+ **/
+ private static final String START_BOARD_STR_6x5 = ""
+ + "xxxxxx\n"
+ + "-mm---\n"
+ + "-mm---\n"
+ + "------\n"
+ + "------";
+ private static final Point MOVE_TO_6x5 = new Point(4, 3);
+ private static final String END_BOARD_STR_6x5 = ""
+ + "xxxxxx\n"
+ + "------\n"
+ + "------\n"
+ + "----mm\n"
+ + "----mm";
+ private static final ReorderTestCase TEST_CASE_6x5 = new ReorderTestCase(START_BOARD_STR_6x5,
+ MOVE_TO_6x5,
+ END_BOARD_STR_6x5);
+
public static final Map<Point, ReorderTestCase> TEST_BY_GRID_SIZE =
Map.of(new Point(5, 5), TEST_CASE_5x5,
- new Point(4, 4), TEST_CASE_4x4);
+ new Point(4, 4), TEST_CASE_4x4,
+ new Point(6, 5), TEST_CASE_6x5);
}
diff --git a/tests/src/com/android/launcher3/ui/AbstractLauncherUiTest.java b/tests/src/com/android/launcher3/ui/AbstractLauncherUiTest.java
index cf21dd7..eae1868 100644
--- a/tests/src/com/android/launcher3/ui/AbstractLauncherUiTest.java
+++ b/tests/src/com/android/launcher3/ui/AbstractLauncherUiTest.java
@@ -63,7 +63,7 @@
import com.android.launcher3.testcomponent.TestCommandReceiver;
import com.android.launcher3.testing.shared.TestProtocol;
import com.android.launcher3.util.LooperExecutor;
-import com.android.launcher3.util.PackageManagerHelper;
+import com.android.launcher3.util.SimpleBroadcastReceiver;
import com.android.launcher3.util.Wait;
import com.android.launcher3.util.WidgetUtils;
import com.android.launcher3.util.rule.FailureWatcher;
@@ -196,15 +196,10 @@
protected void clearPackageData(String pkg) throws IOException, InterruptedException {
final CountDownLatch count = new CountDownLatch(2);
- final BroadcastReceiver broadcastReceiver = new BroadcastReceiver() {
- @Override
- public void onReceive(Context context, Intent intent) {
- count.countDown();
- }
- };
- mTargetContext.registerReceiver(broadcastReceiver,
- PackageManagerHelper.getPackageFilter(pkg,
- Intent.ACTION_PACKAGE_RESTARTED, Intent.ACTION_PACKAGE_DATA_CLEARED));
+ final SimpleBroadcastReceiver broadcastReceiver =
+ new SimpleBroadcastReceiver(i -> count.countDown());
+ broadcastReceiver.registerPkgActions(mTargetContext, pkg,
+ Intent.ACTION_PACKAGE_RESTARTED, Intent.ACTION_PACKAGE_DATA_CLEARED);
mDevice.executeShellCommand("pm clear " + pkg);
assertTrue(pkg + " didn't restart", count.await(10, TimeUnit.SECONDS));
diff --git a/tests/tapl/com/android/launcher3/tapl/AllAppsQsb.java b/tests/tapl/com/android/launcher3/tapl/AllAppsQsb.java
deleted file mode 100644
index 0931cd4..0000000
--- a/tests/tapl/com/android/launcher3/tapl/AllAppsQsb.java
+++ /dev/null
@@ -1,37 +0,0 @@
-/*
- * Copyright (C) 2022 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package com.android.launcher3.tapl;
-
-import androidx.test.uiautomator.UiObject2;
-
-/**
- * Operations on AllApp screen qsb.
- */
-class AllAppsQsb extends Qsb {
-
- private final UiObject2 mAllAppsContainer;
-
- AllAppsQsb(LauncherInstrumentation launcher, UiObject2 allAppsContainer) {
- super(launcher);
- mAllAppsContainer = allAppsContainer;
- waitForQsbObject();
- }
-
- @Override
- protected UiObject2 waitForQsbObject() {
- return mLauncher.waitForObjectInContainer(mAllAppsContainer, "search_container_all_apps");
- }
-}
diff --git a/tests/tapl/com/android/launcher3/tapl/HomeAllApps.java b/tests/tapl/com/android/launcher3/tapl/HomeAllApps.java
index 8ac1aef..50b03aa 100644
--- a/tests/tapl/com/android/launcher3/tapl/HomeAllApps.java
+++ b/tests/tapl/com/android/launcher3/tapl/HomeAllApps.java
@@ -115,13 +115,4 @@
}
}
}
-
- /**
- * Return the QSB UI object on the AllApps screen.
- * @return the QSB UI object.
- */
- @NonNull
- public Qsb getQsb() {
- return new AllAppsQsb(mLauncher, verifyActiveContainer());
- }
}
diff --git a/tests/tapl/com/android/launcher3/tapl/HomeQsb.java b/tests/tapl/com/android/launcher3/tapl/HomeQsb.java
index 20d09a1..c365708 100644
--- a/tests/tapl/com/android/launcher3/tapl/HomeQsb.java
+++ b/tests/tapl/com/android/launcher3/tapl/HomeQsb.java
@@ -15,23 +15,69 @@
*/
package com.android.launcher3.tapl;
+import androidx.annotation.NonNull;
+import androidx.test.uiautomator.By;
+import androidx.test.uiautomator.BySelector;
import androidx.test.uiautomator.UiObject2;
+import androidx.test.uiautomator.Until;
/**
- * Operations on Home screen qsb.
+ * Operations on home screen qsb.
*/
-class HomeQsb extends Qsb {
+public class HomeQsb {
- private final UiObject2 mHotSeat;
+ private final LauncherInstrumentation mLauncher;
+ private static final String ASSISTANT_APP_PACKAGE = "com.google.android.googlequicksearchbox";
+ private static final String ASSISTANT_ICON_RES_ID = "mic_icon";
- HomeQsb(LauncherInstrumentation launcher, UiObject2 hotseat) {
- super(launcher);
- mHotSeat = hotseat;
- waitForQsbObject();
+
+ HomeQsb(LauncherInstrumentation launcher) {
+ mLauncher = launcher;
+ mLauncher.waitForLauncherObject("search_container_hotseat");
}
- @Override
- protected UiObject2 waitForQsbObject() {
- return mLauncher.waitForObjectInContainer(mHotSeat, "search_container_hotseat");
+ /**
+ * Launch assistant app by tapping mic icon on qsb.
+ */
+ @NonNull
+ public LaunchedAppState launchAssistant() {
+ try (LauncherInstrumentation.Closable c = mLauncher.addContextLayer(
+ "want to click assistant mic icon button");
+ LauncherInstrumentation.Closable e = mLauncher.eventsCheck()) {
+ UiObject2 assistantIcon = mLauncher.waitForLauncherObject(ASSISTANT_ICON_RES_ID);
+
+ LauncherInstrumentation.log("HomeQsb.launchAssistant before click "
+ + assistantIcon.getVisibleCenter() + " in "
+ + mLauncher.getVisibleBounds(assistantIcon));
+
+ mLauncher.clickLauncherObject(assistantIcon);
+
+ try (LauncherInstrumentation.Closable c2 = mLauncher.addContextLayer("clicked")) {
+ // assert Assistant App Launched
+ BySelector selector = By.pkg(ASSISTANT_APP_PACKAGE);
+ mLauncher.assertTrue(
+ "assistant app didn't start: (" + selector + ")",
+ mLauncher.getDevice().wait(Until.hasObject(selector),
+ LauncherInstrumentation.WAIT_TIME_MS)
+ );
+ return new LaunchedAppState(mLauncher);
+ }
+ }
+ }
+
+ /**
+ * Show search result page from tapping qsb.
+ */
+ public SearchResultFromQsb showSearchResult() {
+ try (LauncherInstrumentation.Closable c = mLauncher.addContextLayer(
+ "want to open search result page");
+ LauncherInstrumentation.Closable e = mLauncher.eventsCheck()) {
+ mLauncher.clickLauncherObject(
+ mLauncher.waitForLauncherObject("search_container_hotseat"));
+ try (LauncherInstrumentation.Closable c2 = mLauncher.addContextLayer(
+ "clicked qsb to open search result page")) {
+ return new SearchResultFromQsb(mLauncher);
+ }
+ }
}
}
diff --git a/tests/tapl/com/android/launcher3/tapl/Qsb.java b/tests/tapl/com/android/launcher3/tapl/Qsb.java
deleted file mode 100644
index 6bc4f21..0000000
--- a/tests/tapl/com/android/launcher3/tapl/Qsb.java
+++ /dev/null
@@ -1,86 +0,0 @@
-/*
- * Copyright (C) 2022 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.launcher3.tapl;
-
-import androidx.annotation.NonNull;
-import androidx.test.uiautomator.By;
-import androidx.test.uiautomator.BySelector;
-import androidx.test.uiautomator.UiObject2;
-import androidx.test.uiautomator.Until;
-
-/**
- * Operations on qsb from either Home screen or AllApp screen.
- */
-public abstract class Qsb {
-
- private static final String ASSISTANT_APP_PACKAGE = "com.google.android.googlequicksearchbox";
- private static final String ASSISTANT_ICON_RES_ID = "mic_icon";
- protected final LauncherInstrumentation mLauncher;
-
- protected Qsb(LauncherInstrumentation launcher) {
- mLauncher = launcher;
- }
-
- // Waits for the quick search box.
- protected abstract UiObject2 waitForQsbObject();
- /**
- * Launch assistant app by tapping mic icon on qsb.
- */
-
- @NonNull
- public LaunchedAppState launchAssistant() {
- try (LauncherInstrumentation.Closable c = mLauncher.addContextLayer(
- "want to click assistant mic icon button");
- LauncherInstrumentation.Closable e = mLauncher.eventsCheck()) {
- UiObject2 assistantIcon = mLauncher.waitForLauncherObject(ASSISTANT_ICON_RES_ID);
-
- LauncherInstrumentation.log("Qsb.launchAssistant before click "
- + assistantIcon.getVisibleCenter() + " in "
- + mLauncher.getVisibleBounds(assistantIcon));
-
- mLauncher.clickLauncherObject(assistantIcon);
-
- try (LauncherInstrumentation.Closable c2 = mLauncher.addContextLayer("clicked")) {
- // assert Assistant App Launched
- BySelector selector = By.pkg(ASSISTANT_APP_PACKAGE);
- mLauncher.assertTrue(
- "assistant app didn't start: (" + selector + ")",
- mLauncher.getDevice().wait(Until.hasObject(selector),
- LauncherInstrumentation.WAIT_TIME_MS)
- );
- return new LaunchedAppState(mLauncher);
- }
- }
- }
-
- /**
- * Show search result page from tapping qsb.
- */
- public SearchResultFromQsb showSearchResult() {
- try (LauncherInstrumentation.Closable c = mLauncher.addContextLayer(
- "want to open search result page");
- LauncherInstrumentation.Closable e = mLauncher.eventsCheck()) {
- mLauncher.clickLauncherObject(waitForQsbObject());
- // wait for the result rendering to complete
- mLauncher.waitForIdle();
- try (LauncherInstrumentation.Closable c2 = mLauncher.addContextLayer(
- "clicked qsb to open search result page")) {
- return new SearchResultFromQsb(mLauncher);
- }
- }
- }
-}
diff --git a/tests/tapl/com/android/launcher3/tapl/SearchResultFromQsb.java b/tests/tapl/com/android/launcher3/tapl/SearchResultFromQsb.java
index 80176e9..80e4116 100644
--- a/tests/tapl/com/android/launcher3/tapl/SearchResultFromQsb.java
+++ b/tests/tapl/com/android/launcher3/tapl/SearchResultFromQsb.java
@@ -23,7 +23,7 @@
import java.util.ArrayList;
/**
- * Operations on search result page opened from qsb.
+ * Operations on search result page opened from home screen qsb.
*/
public class SearchResultFromQsb {
// The input resource id in the search box.
diff --git a/tests/tapl/com/android/launcher3/tapl/Widget.java b/tests/tapl/com/android/launcher3/tapl/Widget.java
index 046308b..d440903 100644
--- a/tests/tapl/com/android/launcher3/tapl/Widget.java
+++ b/tests/tapl/com/android/launcher3/tapl/Widget.java
@@ -71,7 +71,7 @@
public WidgetResizeFrame dragWidgetToWorkspace() {
try (LauncherInstrumentation.Closable e = mLauncher.eventsCheck()) {
return dragWidgetToWorkspace(/* configurable= */ false, /* acceptsConfig= */ false, -1,
- -1);
+ -1, 1, 1);
}
}
@@ -80,12 +80,12 @@
* cellY and returns the resize frame that is shown after the widget is added.
*/
@NonNull
- public WidgetResizeFrame dragWidgetToWorkspace(int cellX, int cellY) {
+ public WidgetResizeFrame dragWidgetToWorkspace(int cellX, int cellY, int spanX, int spanY) {
try (LauncherInstrumentation.Closable e = mLauncher.eventsCheck();
LauncherInstrumentation.Closable c = mLauncher.addContextLayer(
"Dragging widget to workspace cell " + cellX + "," + cellY)) {
return dragWidgetToWorkspace(/* configurable= */ false, /* acceptsConfig= */ false,
- cellX, cellY);
+ cellX, cellY, spanX, spanY);
}
}
@@ -98,7 +98,7 @@
public WidgetResizeFrame dragConfigWidgetToWorkspace(boolean acceptsConfig) {
// TODO(b/239438337, fransebas) add correct event checking for this case
//try (LauncherInstrumentation.Closable e = mLauncher.eventsCheck()) {
- return dragWidgetToWorkspace(/* configurable= */ true, acceptsConfig, -1, -1);
+ return dragWidgetToWorkspace(/* configurable= */ true, acceptsConfig, -1, -1, 1, 1);
//}
}
@@ -110,18 +110,17 @@
* @param cellX X position in the CellLayout
* @param cellY Y position in the CellLayout
*/
- private void dragToWorkspace(boolean startsActivity, boolean isWidgetShortcut, int cellX,
- int cellY) {
+ private void dragToWorkspaceCellPosition(boolean startsActivity, boolean isWidgetShortcut,
+ int cellX, int cellY, int spanX, int spanY) {
Launchable launchable = getLaunchable();
LauncherInstrumentation launcher = launchable.mLauncher;
- Workspace.dragIconToWorkspace(
+ Workspace.dragIconToWorkspaceCellPosition(
launcher,
launchable,
- () -> Workspace.getCellCenter(launchable.mLauncher, cellX, cellY),
+ cellX, cellY, spanX, spanY,
startsActivity,
isWidgetShortcut,
launchable::addExpectedEventsForLongClick);
-
}
/**
@@ -144,13 +143,13 @@
*/
@Nullable
private WidgetResizeFrame dragWidgetToWorkspace(boolean configurable, boolean acceptsConfig,
- int cellX, int cellY) {
+ int cellX, int cellY, int spanX, int spanY) {
if (cellX == -1 || cellY == -1) {
internalDragToWorkspace(/* startsActivity= */ configurable, /* isWidgetShortcut= */
false);
} else {
- dragToWorkspace(/* startsActivity= */ configurable, /* isWidgetShortcut= */ false,
- cellX, cellY);
+ dragToWorkspaceCellPosition(/* startsActivity= */ configurable, /* isWidgetShortcut= */
+ false, cellX, cellY, spanX, spanY);
}
if (configurable) {
diff --git a/tests/tapl/com/android/launcher3/tapl/Workspace.java b/tests/tapl/com/android/launcher3/tapl/Workspace.java
index 388955c..473cfb9 100644
--- a/tests/tapl/com/android/launcher3/tapl/Workspace.java
+++ b/tests/tapl/com/android/launcher3/tapl/Workspace.java
@@ -118,11 +118,10 @@
*
* The qsb must already be visible when calling this method.
*/
- @NonNull
- public Qsb getQsb() {
+ public HomeQsb getQsb() {
try (LauncherInstrumentation.Closable c = mLauncher.addContextLayer(
"want to get the home qsb")) {
- return new HomeQsb(mLauncher, mHotseat);
+ return new HomeQsb(mLauncher);
}
}
@@ -409,9 +408,15 @@
}
static Point getCellCenter(LauncherInstrumentation launcher, int cellX, int cellY) {
- return launcher.getTestInfo(WorkspaceCellCenterRequest.builder().setCellX(
- cellX).setCellY(cellY).build()).getParcelable(
- TestProtocol.TEST_INFO_RESPONSE_FIELD);
+ return launcher.getTestInfo(WorkspaceCellCenterRequest.builder().setCellX(cellX).setCellY(
+ cellY).build()).getParcelable(TestProtocol.TEST_INFO_RESPONSE_FIELD);
+ }
+
+ static Point getCellCenter(LauncherInstrumentation launcher, int cellX, int cellY, int spanX,
+ int spanY) {
+ return launcher.getTestInfo(WorkspaceCellCenterRequest.builder().setCellX(cellX)
+ .setCellY(cellY).setSpanX(spanX).setSpanY(spanY).build())
+ .getParcelable(TestProtocol.TEST_INFO_RESPONSE_FIELD);
}
static Point getHotseatCellCenter(LauncherInstrumentation launcher, int cellInd) {
@@ -419,6 +424,12 @@
.setCellInd(cellInd).build()).getParcelable(TestProtocol.TEST_INFO_RESPONSE_FIELD);
}
+ /** Returns the number of rows and columns in the workspace */
+ public Point getRowsAndCols() {
+ return mLauncher.getTestInfo(TestProtocol.REQUEST_WORKSPACE_COLUMNS_ROWS).getParcelable(
+ TestProtocol.TEST_INFO_RESPONSE_FIELD);
+ }
+
/**
* Finds folder icons in the current workspace.
*
@@ -457,6 +468,19 @@
launcher, launchable, dest, expectLongClickEvents, expectDropEvents);
}
+ static void dragIconToWorkspaceCellPosition(LauncherInstrumentation launcher,
+ Launchable launchable, int cellX, int cellY, int spanX, int spanY,
+ boolean startsActivity, boolean isWidgetShortcut, Runnable expectLongClickEvents) {
+ Runnable expectDropEvents = null;
+ if (startsActivity || isWidgetShortcut) {
+ expectDropEvents = () -> launcher.expectEvent(TestProtocol.SEQUENCE_MAIN,
+ LauncherInstrumentation.EVENT_START);
+ }
+ dragIconToWorkspaceCellPosition(
+ launcher, launchable, cellX, cellY, spanX, spanY, true, expectLongClickEvents,
+ expectDropEvents);
+ }
+
/**
* Drag icon in workspace to else where and drop it immediately.
* (There is no slow down time before drop event)
@@ -526,6 +550,51 @@
}
}
+ static void dragIconToWorkspaceCellPosition(
+ LauncherInstrumentation launcher,
+ Launchable launchable,
+ int cellX, int cellY, int spanX, int spanY,
+ boolean isDecelerating,
+ Runnable expectLongClickEvents,
+ @Nullable Runnable expectDropEvents) {
+ try (LauncherInstrumentation.Closable ignored = launcher.addContextLayer(
+ "want to drag icon to workspace")) {
+ Point rowsAndCols = launcher.getWorkspace().getRowsAndCols();
+ int destinationWorkspace = cellX / rowsAndCols.x;
+ cellX = cellX % rowsAndCols.x;
+
+ final long downTime = SystemClock.uptimeMillis();
+ Point dragStart = launchable.startDrag(
+ downTime,
+ expectLongClickEvents,
+ /* runToSpringLoadedState= */ true);
+ Point targetDest = getCellCenter(launcher, cellX, cellY, spanX, spanY);
+ int displayX = launcher.getRealDisplaySize().x;
+
+ // Since the destination can be on another page, we need to drag to the edge first
+ // until we reach the target page
+ for (int i = 0; i < destinationWorkspace; i++) {
+ // Don't drag all the way to the edge to prevent touch events from getting out of
+ //screen bounds.
+ Point screenEdge = new Point(displayX - 1, targetDest.y);
+ Point finalDragStart = dragStart;
+ executeAndWaitForPageScroll(launcher,
+ () -> launcher.movePointer(finalDragStart, screenEdge, DEFAULT_DRAG_STEPS,
+ true, downTime, downTime, true,
+ LauncherInstrumentation.GestureScope.INSIDE));
+ dragStart = screenEdge;
+ }
+
+ // targetDest.x is now between 0 and displayX so we found the target page,
+ // we just have to put move the icon to the destination and drop it
+ launcher.movePointer(dragStart, targetDest, DEFAULT_DRAG_STEPS, isDecelerating,
+ downTime, SystemClock.uptimeMillis(), false,
+ LauncherInstrumentation.GestureScope.INSIDE);
+ launcher.runCallbackIfActive(CALLBACK_HOLD_BEFORE_DROP);
+ dropDraggedIcon(launcher, targetDest, downTime, expectDropEvents);
+ }
+ }
+
private static void executeAndWaitForPageScroll(LauncherInstrumentation launcher,
Runnable command) {
launcher.executeAndWaitForEvent(command,