Merge "Cancel recents animation when touch home key(2/2)" into tm-dev
diff --git a/go/quickstep/res/values-or/strings.xml b/go/quickstep/res/values-or/strings.xml
index 36204a3..2e76e2d 100644
--- a/go/quickstep/res/values-or/strings.xml
+++ b/go/quickstep/res/values-or/strings.xml
@@ -7,13 +7,13 @@
<string name="action_search" msgid="6269564710943755464">"Lens"</string>
<string name="dialog_acknowledge" msgid="2804025517675853172">"ବୁଝିଗଲି"</string>
<string name="dialog_cancel" msgid="6464336969134856366">"ବାତିଲ୍ କରନ୍ତୁ"</string>
- <string name="dialog_settings" msgid="6564397136021186148">"ସେଟିଂସ୍"</string>
+ <string name="dialog_settings" msgid="6564397136021186148">"ସେଟିଂସ"</string>
<string name="niu_actions_confirmation_title" msgid="3863451714863526143">"ସ୍କିନରେ ଥିବା ଟେକ୍ସଟକୁ ଅନୁବାଦ କରନ୍ତୁ କିମ୍ବା ଶୁଣନ୍ତୁ"</string>
- <string name="niu_actions_confirmation_text" msgid="2105271481950866089">"ଆପଣଙ୍କ ସ୍କ୍ରିନରେ ଟେକ୍ସଟ୍, ୱେବ୍ ଠିକଣା ଏବଂ ସ୍କ୍ରିନସଟଗୁଡ଼ିକ ପରି ସୂଚନାକୁ Google ସହ ସେୟାର୍ କରାଯାଇପାରେ।\n\nଆପଣ କେଉଁ ସୂଚନା ସେୟାର୍ କରନ୍ତି ତାହା ପରିବର୍ତ୍ତନ କରିବାକୁ, "<b>"ସେଟିଂସ୍ > ଆପ୍ସ > ଡିଫଲ୍ଟ ଆପ୍ସ > ଡିଜିଟାଲ୍ ଆସିଷ୍ଟାଣ୍ଟ ଆପ"</b>"କୁ ଯାଆନ୍ତୁ।"</string>
+ <string name="niu_actions_confirmation_text" msgid="2105271481950866089">"ଆପଣଙ୍କ ସ୍କ୍ରିନରେ ଟେକ୍ସଟ, ୱେବ ଠିକଣା ଏବଂ ସ୍କ୍ରିନସଟଗୁଡ଼ିକ ପରି ସୂଚନାକୁ Google ସହ ସେୟାର କରାଯାଇପାରେ।\n\nଆପଣ କେଉଁ ସୂଚନାକୁ ସେୟାର କରନ୍ତି ତାହା ପରିବର୍ତ୍ତନ କରିବା ପାଇଁ, "<b>"ସେଟିଂସ > ଆପ୍ସ > ଡିଫଲ୍ଟ ଆପ୍ସ > Digital assistant ଆପ"</b>"କୁ ଯାଆନ୍ତୁ।"</string>
<string name="assistant_not_selected_title" msgid="5017072974603345228">"ଏହି ଫିଚର୍ ବ୍ୟବହାର କରିବାକୁ ଏକ ଆସିଷ୍ଟାଣ୍ଟ ବାଛନ୍ତୁ"</string>
- <string name="assistant_not_selected_text" msgid="3244613673884359276">"ଆପଣଙ୍କ ସ୍କ୍ରିନରେ ଥିବା ଟେକ୍ସଟକୁ ଶୁଣିବା ପାଇଁ କିମ୍ବା ଅନୁବାଦ କରିବାକୁ, ସେଟିଂସରେ ଏକ ଡିଜିଟାଲ୍ ଆସିଷ୍ଟାଣ୍ଟ ଆପ୍ ଚୟନ କରନ୍ତୁ"</string>
+ <string name="assistant_not_selected_text" msgid="3244613673884359276">"ଆପଣଙ୍କ ସ୍କ୍ରିନରେ ଥିବା ଟେକ୍ସଟକୁ ଶୁଣିବା କିମ୍ବା ଅନୁବାଦ କରିବା ପାଇଁ, ସେଟିଂସରେ ଏକ digital assistant ଆପ ବାଛନ୍ତୁ"</string>
<string name="assistant_not_supported_title" msgid="1675788067597484142">"ଏହି ଫିଚର୍ ବ୍ୟବହାର କରିବା ପାଇଁ ଆପଣଙ୍କ ଆସିଷ୍ଟାଣ୍ଟକୁ ବଦଳାନ୍ତୁ"</string>
- <string name="assistant_not_supported_text" msgid="1708031078549268884">"ଆପଣଙ୍କ ସ୍କ୍ରିନରେ ଥିବା ଟେକ୍ସଟକୁ ଶୁଣିବା ପାଇଁ କିମ୍ବା ଅନୁବାଦ କରିବାକୁ, ସେଟିଂସରେ ଆପଣଙ୍କ ଡିଜିଟାଲ୍ ଆସିଷ୍ଟାଣ୍ଟ ଆପକୁ ବଦଳାନ୍ତୁ"</string>
+ <string name="assistant_not_supported_text" msgid="1708031078549268884">"ଆପଣଙ୍କ ସ୍କ୍ରିନରେ ଥିବା ଟେକ୍ସଟକୁ ଶୁଣିବା କିମ୍ବା ଅନୁବାଦ କରିବା ପାଇଁ, ସେଟିଂସରେ ଆପଣଙ୍କ Digital assistant ଆପକୁ ବଦଳାନ୍ତୁ"</string>
<string name="tooltip_listen" msgid="7634466447860989102">"ଏହି ସ୍କ୍ରିନରେ ଥିବା ଟେକ୍ସଟକୁ ଶୁଣିବା ପାଇଁ ଏଠାରେ ଟାପ୍ କରନ୍ତୁ"</string>
<string name="tooltip_translate" msgid="4184845868901542567">"ଏହି ସ୍କ୍ରିନରେ ଥିବା ଟେକ୍ସଟକୁ ଅନୁବାଦ କରିବା ପାଇଁ ଏଠାରେ ଟାପ୍ କରନ୍ତୁ"</string>
<string name="toast_p2p_app_not_shareable" msgid="7229739094132131536">"ଏହି ଆପ ସେୟାର କରାଯାଇପାରିବ ନାହିଁ"</string>
diff --git a/protos/launcher_atom.proto b/protos/launcher_atom.proto
index c559988..84892f1 100644
--- a/protos/launcher_atom.proto
+++ b/protos/launcher_atom.proto
@@ -156,6 +156,12 @@
ALL_APPS_SEARCH_RESULT_LEGACY_SHORTCUT = 30;
ALL_APPS_SEARCH_RESULT_ASSISTANT_MEMORY = 31;
+ // Suggestion Type provided by AGA
+ ONE_SEARCH_WEB_QUERY = 32;
+ ONE_SEARCH_WEB_TRENDING = 33;
+ ONE_SEARCH_WEB_ENTITY = 34;
+ ONE_SEARCH_WEB_ANSWER = 35;
+
WIDGETS_BOTTOM_TRAY = 28;
WIDGETS_TRAY_PREDICTION = 29;
}
diff --git a/quickstep/res/layout/taskbar_all_apps.xml b/quickstep/res/layout/taskbar_all_apps.xml
index 11d75c7..7dc0cbe 100644
--- a/quickstep/res/layout/taskbar_all_apps.xml
+++ b/quickstep/res/layout/taskbar_all_apps.xml
@@ -14,12 +14,12 @@
See the License for the specific language governing permissions and
limitations under the License.
-->
-<com.android.launcher3.taskbar.TaskbarAllAppsSlideInView
+<com.android.launcher3.taskbar.allapps.TaskbarAllAppsSlideInView
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent">
- <com.android.launcher3.taskbar.TaskbarAllAppsContainerView
+ <com.android.launcher3.taskbar.allapps.TaskbarAllAppsContainerView
android:id="@+id/apps_view"
android:layout_width="match_parent"
android:layout_height="match_parent"
@@ -52,5 +52,5 @@
</com.android.launcher3.allapps.FloatingHeaderView>
<include layout="@layout/all_apps_fast_scroller" />
- </com.android.launcher3.taskbar.TaskbarAllAppsContainerView>
-</com.android.launcher3.taskbar.TaskbarAllAppsSlideInView>
+ </com.android.launcher3.taskbar.allapps.TaskbarAllAppsContainerView>
+</com.android.launcher3.taskbar.allapps.TaskbarAllAppsSlideInView>
diff --git a/quickstep/res/values-ar/strings.xml b/quickstep/res/values-ar/strings.xml
index 58b26d1..5deea3b 100644
--- a/quickstep/res/values-ar/strings.xml
+++ b/quickstep/res/values-ar/strings.xml
@@ -102,10 +102,8 @@
<string name="taskbar_button_back" msgid="8558862226461164514">"رجوع"</string>
<string name="taskbar_button_ime_switcher" msgid="1730244360907588541">"مفتاح التبديل إلى IME"</string>
<string name="taskbar_button_recents" msgid="7273376136216613134">"الأحدث"</string>
- <!-- no translation found for taskbar_button_notifications (7471740351507357318) -->
- <skip />
- <!-- no translation found for taskbar_button_quick_settings (227662894293189391) -->
- <skip />
+ <string name="taskbar_button_notifications" msgid="7471740351507357318">"الإشعارات"</string>
+ <string name="taskbar_button_quick_settings" msgid="227662894293189391">"إعدادات سريعة"</string>
<string name="move_drop_target_top_or_left" msgid="2988702185049595807">"الانتقال إلى يمين الشاشة أو أعلاها"</string>
<string name="move_drop_target_bottom_or_right" msgid="5431393418797620162">"الانتقال إلى يسار الشاشة أو أسفلها"</string>
</resources>
diff --git a/quickstep/res/values-as/strings.xml b/quickstep/res/values-as/strings.xml
index 38a506f..d48c2f1 100644
--- a/quickstep/res/values-as/strings.xml
+++ b/quickstep/res/values-as/strings.xml
@@ -102,10 +102,8 @@
<string name="taskbar_button_back" msgid="8558862226461164514">"উভতি যাওক"</string>
<string name="taskbar_button_ime_switcher" msgid="1730244360907588541">"IME ছুইচ্চাৰ"</string>
<string name="taskbar_button_recents" msgid="7273376136216613134">"শেহতীয়া"</string>
- <!-- no translation found for taskbar_button_notifications (7471740351507357318) -->
- <skip />
- <!-- no translation found for taskbar_button_quick_settings (227662894293189391) -->
- <skip />
+ <string name="taskbar_button_notifications" msgid="7471740351507357318">"জাননী"</string>
+ <string name="taskbar_button_quick_settings" msgid="227662894293189391">"ক্ষিপ্ৰ ছেটিং"</string>
<string name="move_drop_target_top_or_left" msgid="2988702185049595807">"ওপৰৰ বাঁওফাললৈ নিয়ক"</string>
<string name="move_drop_target_bottom_or_right" msgid="5431393418797620162">"তলৰ সোঁফাললৈ নিয়ক"</string>
</resources>
diff --git a/quickstep/res/values-az/strings.xml b/quickstep/res/values-az/strings.xml
index 74fcb63..9cea3c6 100644
--- a/quickstep/res/values-az/strings.xml
+++ b/quickstep/res/values-az/strings.xml
@@ -102,10 +102,8 @@
<string name="taskbar_button_back" msgid="8558862226461164514">"Geriyə"</string>
<string name="taskbar_button_ime_switcher" msgid="1730244360907588541">"IME keçiricisi"</string>
<string name="taskbar_button_recents" msgid="7273376136216613134">"Sonuncular"</string>
- <!-- no translation found for taskbar_button_notifications (7471740351507357318) -->
- <skip />
- <!-- no translation found for taskbar_button_quick_settings (227662894293189391) -->
- <skip />
+ <string name="taskbar_button_notifications" msgid="7471740351507357318">"Bildirişlər"</string>
+ <string name="taskbar_button_quick_settings" msgid="227662894293189391">"Sürətli Ayarlar"</string>
<string name="move_drop_target_top_or_left" msgid="2988702185049595807">"Yuxarı/sola köçürün"</string>
<string name="move_drop_target_bottom_or_right" msgid="5431393418797620162">"Aşağı/sağa köçürün"</string>
</resources>
diff --git a/quickstep/res/values-be/strings.xml b/quickstep/res/values-be/strings.xml
index 4872f7d..16aec9b 100644
--- a/quickstep/res/values-be/strings.xml
+++ b/quickstep/res/values-be/strings.xml
@@ -102,10 +102,8 @@
<string name="taskbar_button_back" msgid="8558862226461164514">"Назад"</string>
<string name="taskbar_button_ime_switcher" msgid="1730244360907588541">"Выключальнік IME"</string>
<string name="taskbar_button_recents" msgid="7273376136216613134">"Нядаўнія"</string>
- <!-- no translation found for taskbar_button_notifications (7471740351507357318) -->
- <skip />
- <!-- no translation found for taskbar_button_quick_settings (227662894293189391) -->
- <skip />
+ <string name="taskbar_button_notifications" msgid="7471740351507357318">"Апавяшчэнні"</string>
+ <string name="taskbar_button_quick_settings" msgid="227662894293189391">"Хуткія налады"</string>
<string name="move_drop_target_top_or_left" msgid="2988702185049595807">"Перамясціць уверх/улева"</string>
<string name="move_drop_target_bottom_or_right" msgid="5431393418797620162">"Перамясціць уніз/управа"</string>
</resources>
diff --git a/quickstep/res/values-bg/strings.xml b/quickstep/res/values-bg/strings.xml
index 3fea5ee..2d3dc60 100644
--- a/quickstep/res/values-bg/strings.xml
+++ b/quickstep/res/values-bg/strings.xml
@@ -102,10 +102,8 @@
<string name="taskbar_button_back" msgid="8558862226461164514">"Назад"</string>
<string name="taskbar_button_ime_switcher" msgid="1730244360907588541">"Редактор за метода на въвежд.: Превключвател"</string>
<string name="taskbar_button_recents" msgid="7273376136216613134">"Скорошни"</string>
- <!-- no translation found for taskbar_button_notifications (7471740351507357318) -->
- <skip />
- <!-- no translation found for taskbar_button_quick_settings (227662894293189391) -->
- <skip />
+ <string name="taskbar_button_notifications" msgid="7471740351507357318">"Известия"</string>
+ <string name="taskbar_button_quick_settings" msgid="227662894293189391">"Бързи настройки"</string>
<string name="move_drop_target_top_or_left" msgid="2988702185049595807">"Преместване горе/вляво"</string>
<string name="move_drop_target_bottom_or_right" msgid="5431393418797620162">"Преместване долу/вдясно"</string>
</resources>
diff --git a/quickstep/res/values-ca/strings.xml b/quickstep/res/values-ca/strings.xml
index 0f6c486..8a6d153 100644
--- a/quickstep/res/values-ca/strings.xml
+++ b/quickstep/res/values-ca/strings.xml
@@ -102,10 +102,8 @@
<string name="taskbar_button_back" msgid="8558862226461164514">"Enrere"</string>
<string name="taskbar_button_ime_switcher" msgid="1730244360907588541">"Selector d\'IME"</string>
<string name="taskbar_button_recents" msgid="7273376136216613134">"Recents"</string>
- <!-- no translation found for taskbar_button_notifications (7471740351507357318) -->
- <skip />
- <!-- no translation found for taskbar_button_quick_settings (227662894293189391) -->
- <skip />
+ <string name="taskbar_button_notifications" msgid="7471740351507357318">"Notificacions"</string>
+ <string name="taskbar_button_quick_settings" msgid="227662894293189391">"Config. ràpida"</string>
<string name="move_drop_target_top_or_left" msgid="2988702185049595807">"Mou a la part superior o a l\'esquerra"</string>
<string name="move_drop_target_bottom_or_right" msgid="5431393418797620162">"Mou a la part inferior o a la dreta"</string>
</resources>
diff --git a/quickstep/res/values-cs/strings.xml b/quickstep/res/values-cs/strings.xml
index 6aef1a4..c207103 100644
--- a/quickstep/res/values-cs/strings.xml
+++ b/quickstep/res/values-cs/strings.xml
@@ -102,10 +102,8 @@
<string name="taskbar_button_back" msgid="8558862226461164514">"Zpět"</string>
<string name="taskbar_button_ime_switcher" msgid="1730244360907588541">"Přepínač IME"</string>
<string name="taskbar_button_recents" msgid="7273376136216613134">"Poslední"</string>
- <!-- no translation found for taskbar_button_notifications (7471740351507357318) -->
- <skip />
- <!-- no translation found for taskbar_button_quick_settings (227662894293189391) -->
- <skip />
+ <string name="taskbar_button_notifications" msgid="7471740351507357318">"Oznámení"</string>
+ <string name="taskbar_button_quick_settings" msgid="227662894293189391">"Rychlé nastavení"</string>
<string name="move_drop_target_top_or_left" msgid="2988702185049595807">"Přesunout doleva nahoru"</string>
<string name="move_drop_target_bottom_or_right" msgid="5431393418797620162">"Přesunout doprava dolů"</string>
</resources>
diff --git a/quickstep/res/values-da/strings.xml b/quickstep/res/values-da/strings.xml
index c2e6681..e53dfb0 100644
--- a/quickstep/res/values-da/strings.xml
+++ b/quickstep/res/values-da/strings.xml
@@ -102,10 +102,8 @@
<string name="taskbar_button_back" msgid="8558862226461164514">"Tilbage"</string>
<string name="taskbar_button_ime_switcher" msgid="1730244360907588541">"IME-vælger"</string>
<string name="taskbar_button_recents" msgid="7273376136216613134">"Seneste"</string>
- <!-- no translation found for taskbar_button_notifications (7471740351507357318) -->
- <skip />
- <!-- no translation found for taskbar_button_quick_settings (227662894293189391) -->
- <skip />
+ <string name="taskbar_button_notifications" msgid="7471740351507357318">"Notifikationer"</string>
+ <string name="taskbar_button_quick_settings" msgid="227662894293189391">"Kvikmenu"</string>
<string name="move_drop_target_top_or_left" msgid="2988702185049595807">"Flyt til toppen eller venstre side"</string>
<string name="move_drop_target_bottom_or_right" msgid="5431393418797620162">"Flyt til bunden eller højre side"</string>
</resources>
diff --git a/quickstep/res/values-es/strings.xml b/quickstep/res/values-es/strings.xml
index b5dc6e6..0916fc2 100644
--- a/quickstep/res/values-es/strings.xml
+++ b/quickstep/res/values-es/strings.xml
@@ -102,10 +102,8 @@
<string name="taskbar_button_back" msgid="8558862226461164514">"Atrás"</string>
<string name="taskbar_button_ime_switcher" msgid="1730244360907588541">"Interruptor IME"</string>
<string name="taskbar_button_recents" msgid="7273376136216613134">"Recientes"</string>
- <!-- no translation found for taskbar_button_notifications (7471740351507357318) -->
- <skip />
- <!-- no translation found for taskbar_button_quick_settings (227662894293189391) -->
- <skip />
+ <string name="taskbar_button_notifications" msgid="7471740351507357318">"Notificaciones"</string>
+ <string name="taskbar_button_quick_settings" msgid="227662894293189391">"Ajustes rápidos"</string>
<string name="move_drop_target_top_or_left" msgid="2988702185049595807">"Mover arriba/a la izquierda"</string>
<string name="move_drop_target_bottom_or_right" msgid="5431393418797620162">"Mover abajo/a la derecha"</string>
</resources>
diff --git a/quickstep/res/values-et/strings.xml b/quickstep/res/values-et/strings.xml
index 950263f..5b4b1ce 100644
--- a/quickstep/res/values-et/strings.xml
+++ b/quickstep/res/values-et/strings.xml
@@ -102,10 +102,8 @@
<string name="taskbar_button_back" msgid="8558862226461164514">"Tagasi"</string>
<string name="taskbar_button_ime_switcher" msgid="1730244360907588541">"IME vahetaja"</string>
<string name="taskbar_button_recents" msgid="7273376136216613134">"Hiljutised"</string>
- <!-- no translation found for taskbar_button_notifications (7471740351507357318) -->
- <skip />
- <!-- no translation found for taskbar_button_quick_settings (227662894293189391) -->
- <skip />
+ <string name="taskbar_button_notifications" msgid="7471740351507357318">"Märguanded"</string>
+ <string name="taskbar_button_quick_settings" msgid="227662894293189391">"Kiirseaded"</string>
<string name="move_drop_target_top_or_left" msgid="2988702185049595807">"Teisalda üles/vasakule"</string>
<string name="move_drop_target_bottom_or_right" msgid="5431393418797620162">"Teisalda alla/paremale"</string>
</resources>
diff --git a/quickstep/res/values-fi/strings.xml b/quickstep/res/values-fi/strings.xml
index 9505039..4677eda 100644
--- a/quickstep/res/values-fi/strings.xml
+++ b/quickstep/res/values-fi/strings.xml
@@ -102,10 +102,8 @@
<string name="taskbar_button_back" msgid="8558862226461164514">"Takaisin"</string>
<string name="taskbar_button_ime_switcher" msgid="1730244360907588541">"IME-vaihtopalvelu"</string>
<string name="taskbar_button_recents" msgid="7273376136216613134">"Viimeaikaiset"</string>
- <!-- no translation found for taskbar_button_notifications (7471740351507357318) -->
- <skip />
- <!-- no translation found for taskbar_button_quick_settings (227662894293189391) -->
- <skip />
+ <string name="taskbar_button_notifications" msgid="7471740351507357318">"Ilmoitukset"</string>
+ <string name="taskbar_button_quick_settings" msgid="227662894293189391">"Pika-asetukset"</string>
<string name="move_drop_target_top_or_left" msgid="2988702185049595807">"Siirrä ylös tai vasemmalle"</string>
<string name="move_drop_target_bottom_or_right" msgid="5431393418797620162">"Siirrä alas tai oikealle"</string>
</resources>
diff --git a/quickstep/res/values-fr-rCA/strings.xml b/quickstep/res/values-fr-rCA/strings.xml
index e34cb5d..2a38ff8 100644
--- a/quickstep/res/values-fr-rCA/strings.xml
+++ b/quickstep/res/values-fr-rCA/strings.xml
@@ -102,10 +102,8 @@
<string name="taskbar_button_back" msgid="8558862226461164514">"Retour"</string>
<string name="taskbar_button_ime_switcher" msgid="1730244360907588541">"Sélecteur IME"</string>
<string name="taskbar_button_recents" msgid="7273376136216613134">"Récents"</string>
- <!-- no translation found for taskbar_button_notifications (7471740351507357318) -->
- <skip />
- <!-- no translation found for taskbar_button_quick_settings (227662894293189391) -->
- <skip />
+ <string name="taskbar_button_notifications" msgid="7471740351507357318">"Notifications"</string>
+ <string name="taskbar_button_quick_settings" msgid="227662894293189391">"Paramètres rapides"</string>
<string name="move_drop_target_top_or_left" msgid="2988702185049595807">"Déplacer vers le coin supérieur gauche de l\'écran"</string>
<string name="move_drop_target_bottom_or_right" msgid="5431393418797620162">"Déplacer vers le coin inférieur droit de l\'écran"</string>
</resources>
diff --git a/quickstep/res/values-fr/strings.xml b/quickstep/res/values-fr/strings.xml
index 3c28c46..c1dd76e 100644
--- a/quickstep/res/values-fr/strings.xml
+++ b/quickstep/res/values-fr/strings.xml
@@ -102,10 +102,8 @@
<string name="taskbar_button_back" msgid="8558862226461164514">"Retour"</string>
<string name="taskbar_button_ime_switcher" msgid="1730244360907588541">"Sélecteur IME"</string>
<string name="taskbar_button_recents" msgid="7273376136216613134">"Récents"</string>
- <!-- no translation found for taskbar_button_notifications (7471740351507357318) -->
- <skip />
- <!-- no translation found for taskbar_button_quick_settings (227662894293189391) -->
- <skip />
+ <string name="taskbar_button_notifications" msgid="7471740351507357318">"Notifications"</string>
+ <string name="taskbar_button_quick_settings" msgid="227662894293189391">"Réglages rapides"</string>
<string name="move_drop_target_top_or_left" msgid="2988702185049595807">"Déplacer en haut ou à gauche"</string>
<string name="move_drop_target_bottom_or_right" msgid="5431393418797620162">"Déplacer en bas ou à droite"</string>
</resources>
diff --git a/quickstep/res/values-gl/strings.xml b/quickstep/res/values-gl/strings.xml
index 4095f7d..8702947 100644
--- a/quickstep/res/values-gl/strings.xml
+++ b/quickstep/res/values-gl/strings.xml
@@ -102,10 +102,8 @@
<string name="taskbar_button_back" msgid="8558862226461164514">"Atrás"</string>
<string name="taskbar_button_ime_switcher" msgid="1730244360907588541">"Selector do IME"</string>
<string name="taskbar_button_recents" msgid="7273376136216613134">"Recentes"</string>
- <!-- no translation found for taskbar_button_notifications (7471740351507357318) -->
- <skip />
- <!-- no translation found for taskbar_button_quick_settings (227662894293189391) -->
- <skip />
+ <string name="taskbar_button_notifications" msgid="7471740351507357318">"Notificacións"</string>
+ <string name="taskbar_button_quick_settings" msgid="227662894293189391">"Configuración rápida"</string>
<string name="move_drop_target_top_or_left" msgid="2988702185049595807">"Mover á parte superior ou á esquerda"</string>
<string name="move_drop_target_bottom_or_right" msgid="5431393418797620162">"Mover á parte inferior ou á dereita"</string>
</resources>
diff --git a/quickstep/res/values-hu/strings.xml b/quickstep/res/values-hu/strings.xml
index 5b1aff9..a84dadd 100644
--- a/quickstep/res/values-hu/strings.xml
+++ b/quickstep/res/values-hu/strings.xml
@@ -102,10 +102,8 @@
<string name="taskbar_button_back" msgid="8558862226461164514">"Vissza"</string>
<string name="taskbar_button_ime_switcher" msgid="1730244360907588541">"IME-váltó"</string>
<string name="taskbar_button_recents" msgid="7273376136216613134">"Legutóbbiak"</string>
- <!-- no translation found for taskbar_button_notifications (7471740351507357318) -->
- <skip />
- <!-- no translation found for taskbar_button_quick_settings (227662894293189391) -->
- <skip />
+ <string name="taskbar_button_notifications" msgid="7471740351507357318">"Értesítések"</string>
+ <string name="taskbar_button_quick_settings" msgid="227662894293189391">"Gyorsbeállítások"</string>
<string name="move_drop_target_top_or_left" msgid="2988702185049595807">"Mozgatás felülre vagy a bal oldalra"</string>
<string name="move_drop_target_bottom_or_right" msgid="5431393418797620162">"Mozgatás alulra vagy a jobb oldalra"</string>
</resources>
diff --git a/quickstep/res/values-is/strings.xml b/quickstep/res/values-is/strings.xml
index 1327552..f888bea 100644
--- a/quickstep/res/values-is/strings.xml
+++ b/quickstep/res/values-is/strings.xml
@@ -102,10 +102,8 @@
<string name="taskbar_button_back" msgid="8558862226461164514">"Til baka"</string>
<string name="taskbar_button_ime_switcher" msgid="1730244360907588541">"Breyta innsláttaraðferð"</string>
<string name="taskbar_button_recents" msgid="7273376136216613134">"Nýlegt"</string>
- <!-- no translation found for taskbar_button_notifications (7471740351507357318) -->
- <skip />
- <!-- no translation found for taskbar_button_quick_settings (227662894293189391) -->
- <skip />
+ <string name="taskbar_button_notifications" msgid="7471740351507357318">"Tilkynningar"</string>
+ <string name="taskbar_button_quick_settings" msgid="227662894293189391">"Flýtistillingar"</string>
<string name="move_drop_target_top_or_left" msgid="2988702185049595807">"Færa efst/til vinstri"</string>
<string name="move_drop_target_bottom_or_right" msgid="5431393418797620162">"Færa neðst/til hægri"</string>
</resources>
diff --git a/quickstep/res/values-it/strings.xml b/quickstep/res/values-it/strings.xml
index a555636..344c2a1 100644
--- a/quickstep/res/values-it/strings.xml
+++ b/quickstep/res/values-it/strings.xml
@@ -102,10 +102,8 @@
<string name="taskbar_button_back" msgid="8558862226461164514">"Indietro"</string>
<string name="taskbar_button_ime_switcher" msgid="1730244360907588541">"Selettore IME"</string>
<string name="taskbar_button_recents" msgid="7273376136216613134">"Recenti"</string>
- <!-- no translation found for taskbar_button_notifications (7471740351507357318) -->
- <skip />
- <!-- no translation found for taskbar_button_quick_settings (227662894293189391) -->
- <skip />
+ <string name="taskbar_button_notifications" msgid="7471740351507357318">"Notifiche"</string>
+ <string name="taskbar_button_quick_settings" msgid="227662894293189391">"Impostazioni rapide"</string>
<string name="move_drop_target_top_or_left" msgid="2988702185049595807">"Sposta in alto/a sinistra"</string>
<string name="move_drop_target_bottom_or_right" msgid="5431393418797620162">"Sposta in basso/a destra"</string>
</resources>
diff --git a/quickstep/res/values-iw/strings.xml b/quickstep/res/values-iw/strings.xml
index cd97903..25d92cb 100644
--- a/quickstep/res/values-iw/strings.xml
+++ b/quickstep/res/values-iw/strings.xml
@@ -102,10 +102,8 @@
<string name="taskbar_button_back" msgid="8558862226461164514">"חזרה"</string>
<string name="taskbar_button_ime_switcher" msgid="1730244360907588541">"כלי להחלפת IME"</string>
<string name="taskbar_button_recents" msgid="7273376136216613134">"לאחרונה"</string>
- <!-- no translation found for taskbar_button_notifications (7471740351507357318) -->
- <skip />
- <!-- no translation found for taskbar_button_quick_settings (227662894293189391) -->
- <skip />
+ <string name="taskbar_button_notifications" msgid="7471740351507357318">"התראות"</string>
+ <string name="taskbar_button_quick_settings" msgid="227662894293189391">"הגדרות מהירות"</string>
<string name="move_drop_target_top_or_left" msgid="2988702185049595807">"העברה לפינה השמאלית/העליונה"</string>
<string name="move_drop_target_bottom_or_right" msgid="5431393418797620162">"העברה לפינה הימנית/התחתונה"</string>
</resources>
diff --git a/quickstep/res/values-km/strings.xml b/quickstep/res/values-km/strings.xml
index 3295a63..e006c6a 100644
--- a/quickstep/res/values-km/strings.xml
+++ b/quickstep/res/values-km/strings.xml
@@ -102,10 +102,8 @@
<string name="taskbar_button_back" msgid="8558862226461164514">"ថយក្រោយ"</string>
<string name="taskbar_button_ime_switcher" msgid="1730244360907588541">"ប៊ូតុងប្ដូរ IME"</string>
<string name="taskbar_button_recents" msgid="7273376136216613134">"ថ្មីៗ"</string>
- <!-- no translation found for taskbar_button_notifications (7471740351507357318) -->
- <skip />
- <!-- no translation found for taskbar_button_quick_settings (227662894293189391) -->
- <skip />
+ <string name="taskbar_button_notifications" msgid="7471740351507357318">"ការជូនដំណឹង"</string>
+ <string name="taskbar_button_quick_settings" msgid="227662894293189391">"ការកំណត់រហ័ស"</string>
<string name="move_drop_target_top_or_left" msgid="2988702185049595807">"ផ្លាស់ទីទៅខាងលើ/ឆ្វេង"</string>
<string name="move_drop_target_bottom_or_right" msgid="5431393418797620162">"ផ្លាស់ទីទៅខាងក្រោម/ស្ដាំ"</string>
</resources>
diff --git a/quickstep/res/values-ko/strings.xml b/quickstep/res/values-ko/strings.xml
index 08e5642..d9ff591 100644
--- a/quickstep/res/values-ko/strings.xml
+++ b/quickstep/res/values-ko/strings.xml
@@ -102,10 +102,8 @@
<string name="taskbar_button_back" msgid="8558862226461164514">"뒤로"</string>
<string name="taskbar_button_ime_switcher" msgid="1730244360907588541">"IME 전환기"</string>
<string name="taskbar_button_recents" msgid="7273376136216613134">"최근 항목"</string>
- <!-- no translation found for taskbar_button_notifications (7471740351507357318) -->
- <skip />
- <!-- no translation found for taskbar_button_quick_settings (227662894293189391) -->
- <skip />
+ <string name="taskbar_button_notifications" msgid="7471740351507357318">"알림"</string>
+ <string name="taskbar_button_quick_settings" msgid="227662894293189391">"빠른 설정"</string>
<string name="move_drop_target_top_or_left" msgid="2988702185049595807">"상단/왼쪽으로 이동"</string>
<string name="move_drop_target_bottom_or_right" msgid="5431393418797620162">"하단/오른쪽으로 이동"</string>
</resources>
diff --git a/quickstep/res/values-lo/strings.xml b/quickstep/res/values-lo/strings.xml
index 4c1791f..5c95b03 100644
--- a/quickstep/res/values-lo/strings.xml
+++ b/quickstep/res/values-lo/strings.xml
@@ -102,10 +102,8 @@
<string name="taskbar_button_back" msgid="8558862226461164514">"ກັບຄືນ"</string>
<string name="taskbar_button_ime_switcher" msgid="1730244360907588541">"ຕົວສະຫຼັບ IME"</string>
<string name="taskbar_button_recents" msgid="7273376136216613134">"ຫຼ້າສຸດ"</string>
- <!-- no translation found for taskbar_button_notifications (7471740351507357318) -->
- <skip />
- <!-- no translation found for taskbar_button_quick_settings (227662894293189391) -->
- <skip />
+ <string name="taskbar_button_notifications" msgid="7471740351507357318">"ການແຈ້ງເຕືອນ"</string>
+ <string name="taskbar_button_quick_settings" msgid="227662894293189391">"ການຕັ້ງຄ່າດ່ວນ"</string>
<string name="move_drop_target_top_or_left" msgid="2988702185049595807">"ຍ້າຍໄປຊ້າຍ/ເທິງ"</string>
<string name="move_drop_target_bottom_or_right" msgid="5431393418797620162">"ຍ້າຍໄປຂວາ/ລຸ່ມ"</string>
</resources>
diff --git a/quickstep/res/values-lt/strings.xml b/quickstep/res/values-lt/strings.xml
index 95a7e86..8b3d2ce 100644
--- a/quickstep/res/values-lt/strings.xml
+++ b/quickstep/res/values-lt/strings.xml
@@ -102,10 +102,8 @@
<string name="taskbar_button_back" msgid="8558862226461164514">"Atgal"</string>
<string name="taskbar_button_ime_switcher" msgid="1730244360907588541">"IMRP perjungiklis"</string>
<string name="taskbar_button_recents" msgid="7273376136216613134">"Naujausi"</string>
- <!-- no translation found for taskbar_button_notifications (7471740351507357318) -->
- <skip />
- <!-- no translation found for taskbar_button_quick_settings (227662894293189391) -->
- <skip />
+ <string name="taskbar_button_notifications" msgid="7471740351507357318">"Pranešimai"</string>
+ <string name="taskbar_button_quick_settings" msgid="227662894293189391">"Spartieji nustatymai"</string>
<string name="move_drop_target_top_or_left" msgid="2988702185049595807">"Perkelti aukštyn, kairėn"</string>
<string name="move_drop_target_bottom_or_right" msgid="5431393418797620162">"Perkelti žemyn, dešinėn"</string>
</resources>
diff --git a/quickstep/res/values-lv/strings.xml b/quickstep/res/values-lv/strings.xml
index f3de0b7..99a71fb 100644
--- a/quickstep/res/values-lv/strings.xml
+++ b/quickstep/res/values-lv/strings.xml
@@ -102,10 +102,8 @@
<string name="taskbar_button_back" msgid="8558862226461164514">"Atpakaļ"</string>
<string name="taskbar_button_ime_switcher" msgid="1730244360907588541">"IME pārslēdzējs"</string>
<string name="taskbar_button_recents" msgid="7273376136216613134">"Nesenie"</string>
- <!-- no translation found for taskbar_button_notifications (7471740351507357318) -->
- <skip />
- <!-- no translation found for taskbar_button_quick_settings (227662894293189391) -->
- <skip />
+ <string name="taskbar_button_notifications" msgid="7471740351507357318">"Paziņojumi"</string>
+ <string name="taskbar_button_quick_settings" msgid="227662894293189391">"Ātrie iestatīj."</string>
<string name="move_drop_target_top_or_left" msgid="2988702185049595807">"Pārvietot uz augšējo/kreiso stūri"</string>
<string name="move_drop_target_bottom_or_right" msgid="5431393418797620162">"Pārvietot uz apakšējo/labo stūri"</string>
</resources>
diff --git a/quickstep/res/values-my/strings.xml b/quickstep/res/values-my/strings.xml
index d09165a..ef6052e 100644
--- a/quickstep/res/values-my/strings.xml
+++ b/quickstep/res/values-my/strings.xml
@@ -102,10 +102,8 @@
<string name="taskbar_button_back" msgid="8558862226461164514">"နောက်သို့"</string>
<string name="taskbar_button_ime_switcher" msgid="1730244360907588541">"IME ပြောင်းစနစ်"</string>
<string name="taskbar_button_recents" msgid="7273376136216613134">"လတ်တလောများ"</string>
- <!-- no translation found for taskbar_button_notifications (7471740351507357318) -->
- <skip />
- <!-- no translation found for taskbar_button_quick_settings (227662894293189391) -->
- <skip />
+ <string name="taskbar_button_notifications" msgid="7471740351507357318">"အကြောင်းကြားချက်"</string>
+ <string name="taskbar_button_quick_settings" msgid="227662894293189391">"အမြန်ဆက်တင်များ"</string>
<string name="move_drop_target_top_or_left" msgid="2988702185049595807">"အပေါ်/ဘယ်ဘက်သို့ ရွှေ့ရန်"</string>
<string name="move_drop_target_bottom_or_right" msgid="5431393418797620162">"အောက်ခြေ/ညာဘက်သို့ ရွှေ့ရန်"</string>
</resources>
diff --git a/quickstep/res/values-nb/strings.xml b/quickstep/res/values-nb/strings.xml
index 6d143bd..a81c779 100644
--- a/quickstep/res/values-nb/strings.xml
+++ b/quickstep/res/values-nb/strings.xml
@@ -102,10 +102,8 @@
<string name="taskbar_button_back" msgid="8558862226461164514">"Tilbake"</string>
<string name="taskbar_button_ime_switcher" msgid="1730244360907588541">"IME-veksler"</string>
<string name="taskbar_button_recents" msgid="7273376136216613134">"Nylige"</string>
- <!-- no translation found for taskbar_button_notifications (7471740351507357318) -->
- <skip />
- <!-- no translation found for taskbar_button_quick_settings (227662894293189391) -->
- <skip />
+ <string name="taskbar_button_notifications" msgid="7471740351507357318">"Varsler"</string>
+ <string name="taskbar_button_quick_settings" msgid="227662894293189391">"Hurtiginnst."</string>
<string name="move_drop_target_top_or_left" msgid="2988702185049595807">"Flytt til øverst/venstre"</string>
<string name="move_drop_target_bottom_or_right" msgid="5431393418797620162">"Flytt til nederst/høyre"</string>
</resources>
diff --git a/quickstep/res/values-ne/strings.xml b/quickstep/res/values-ne/strings.xml
index cd3383b..3c5d64f 100644
--- a/quickstep/res/values-ne/strings.xml
+++ b/quickstep/res/values-ne/strings.xml
@@ -102,10 +102,8 @@
<string name="taskbar_button_back" msgid="8558862226461164514">"पछाडि जानुहोस्"</string>
<string name="taskbar_button_ime_switcher" msgid="1730244360907588541">"IME स्विचर"</string>
<string name="taskbar_button_recents" msgid="7273376136216613134">"हालसालैका बटनहरू"</string>
- <!-- no translation found for taskbar_button_notifications (7471740351507357318) -->
- <skip />
- <!-- no translation found for taskbar_button_quick_settings (227662894293189391) -->
- <skip />
+ <string name="taskbar_button_notifications" msgid="7471740351507357318">"सूचनाहरू"</string>
+ <string name="taskbar_button_quick_settings" msgid="227662894293189391">"द्रुत सेटिङ"</string>
<string name="move_drop_target_top_or_left" msgid="2988702185049595807">"सिरान/बायाँतिर सार्नुहोस्"</string>
<string name="move_drop_target_bottom_or_right" msgid="5431393418797620162">"फेद/दायाँतिर सार्नुहोस्"</string>
</resources>
diff --git a/quickstep/res/values-or/strings.xml b/quickstep/res/values-or/strings.xml
index 7740783..bb810f0 100644
--- a/quickstep/res/values-or/strings.xml
+++ b/quickstep/res/values-or/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>
@@ -38,7 +38,7 @@
<string name="hotseat_edu_message_migrate_alt" msgid="3042360119039646356">"ଆପଣଙ୍କର ସବୁଠାରୁ ଅଧିକ-ବ୍ୟବହୃତ ଆପଗୁଡ଼ିକୁ, ସିଧା ମୂଳ ସ୍କ୍ରିନରେ ସହଜରେ ଆକ୍ସେସ୍ କରନ୍ତୁ। ଆପଣଙ୍କ ରୁଟିନଗୁଡ଼ିକ ଆଧାରରେ ପରାମର୍ଶଗୁଡ଼ିକ ପରିବର୍ତ୍ତିତ ହେବ। ତଳ ଧାଡ଼ିରେ ଥିବା ଆପଗୁଡ଼ିକ ଏକ ନୂଆ ଫୋଲ୍ଡରକୁ ମୁଭ୍ କରିଯିବ।"</string>
<string name="hotseat_edu_accept" msgid="1611544083278999837">"ଆପ୍ ପରାମର୍ଶଗୁଡ଼ିକ ପାଆନ୍ତୁ"</string>
<string name="hotseat_edu_dismiss" msgid="2781161822780201689">"ନାହିଁ, ଥାଉ"</string>
- <string name="hotseat_prediction_settings" msgid="6246554993566070818">"ସେଟିଂସ୍"</string>
+ <string name="hotseat_prediction_settings" msgid="6246554993566070818">"ସେଟିଂସ"</string>
<string name="hotseat_auto_enrolled" msgid="522100018967146807">"ସବୁଠାରୁ ଅଧିକ-ବ୍ୟବହୃତ ଆପଗୁଡ଼ିକ ଏଠାରେ ଦେଖାଯାଏ ଏବଂ ରୁଟିନଗୁଡ଼ିକ ଆଧାରରେ ପରିବର୍ତ୍ତିତ ହୋଇଥାଏ"</string>
<string name="hotseat_tip_no_empty_slots" msgid="1325212677738179185">"ଆପ୍ ପରାମର୍ଶଗୁଡ଼ିକ ପାଇବାକୁ ଆପଗୁଡ଼ିକୁ ତଳ ଧାଡ଼ିରୁ ଟାଣି ଆଣନ୍ତୁ"</string>
<string name="hotseat_tip_gaps_filled" msgid="3035673010274223538">"ଆପ୍ ପରାମର୍ଶଗୁଡ଼ିକ ଖାଲି ସ୍ଥାନରେ ଯୋଗ କରାଯାଇଛି"</string>
@@ -69,14 +69,14 @@
<string name="overview_gesture_intro_subtitle" msgid="4968091015637850859">"ଆପଗୁଡ଼ିକ ମଧ୍ୟରେ ସ୍ୱିଚ୍ କରିବାକୁ, ସ୍କ୍ରିନର ତଳୁ ଉପରକୁ ସ୍ୱାଇପ୍ କରନ୍ତୁ, ଧରି ରଖନ୍ତୁ, ତା\'ପରେ ରିଲିଜ୍ କରନ୍ତୁ।"</string>
<string name="gesture_tutorial_confirm_title" msgid="6201516182040074092">"ସବୁ ପ୍ରସ୍ତୁତ"</string>
<string name="gesture_tutorial_action_button_label" msgid="6249846312991332122">"ହୋଇଗଲା"</string>
- <string name="gesture_tutorial_action_button_label_settings" msgid="2923621047916486604">"ସେଟିଂସ୍"</string>
+ <string name="gesture_tutorial_action_button_label_settings" msgid="2923621047916486604">"ସେଟିଂସ"</string>
<string name="gesture_tutorial_try_again" msgid="65962545858556697">"ପୁଣି ଚେଷ୍ଟା କରନ୍ତୁ"</string>
<string name="gesture_tutorial_nice" msgid="2936275692616928280">"ବଢ଼ିଆ!"</string>
<string name="gesture_tutorial_step" msgid="1279786122817620968">"ଟ୍ୟୁଟୋରିଆଲ୍ <xliff:g id="CURRENT">%1$d</xliff:g>/<xliff:g id="TOTAL">%2$d</xliff:g>"</string>
<string name="allset_title" msgid="5021126669778966707">"ସମ୍ପୂର୍ଣ୍ଣ ଭାବେ ପ୍ରସ୍ତୁତ!"</string>
<string name="allset_hint" msgid="2384632994739392447">"ମୂଳପୃଷ୍ଠାକୁ ଯିବା ପାଇଁ ଉପରକୁ ସ୍ୱାଇପ୍ କରନ୍ତୁ"</string>
<string name="allset_description" msgid="6350320429953234580">"ଆପଣ ଆପଣଙ୍କ ଫୋନ୍ ବ୍ୟବହାର କରିବା ପାଇଁ ପ୍ରସ୍ତୁତ ଅଛନ୍ତି"</string>
- <string name="allset_navigation_settings" msgid="4713404605961476027"><annotation id="link">"ସିଷ୍ଟମ୍ ନାଭିଗେସନ୍ ସେଟିଂସ୍"</annotation></string>
+ <string name="allset_navigation_settings" msgid="4713404605961476027"><annotation id="link">"ସିଷ୍ଟମ ନାଭିଗେସନ ସେଟିଂସ"</annotation></string>
<string name="action_share" msgid="2648470652637092375">"ସେୟାର୍ କରନ୍ତୁ"</string>
<string name="action_screenshot" msgid="8171125848358142917">"ସ୍କ୍ରିନସଟ୍"</string>
<string name="action_split" msgid="2098009717623550676">"ସ୍ପ୍ଲିଟ୍"</string>
@@ -102,10 +102,8 @@
<string name="taskbar_button_back" msgid="8558862226461164514">"ପଛକୁ ଫେରନ୍ତୁ"</string>
<string name="taskbar_button_ime_switcher" msgid="1730244360907588541">"IME ସ୍ୱିଚର"</string>
<string name="taskbar_button_recents" msgid="7273376136216613134">"ବର୍ତ୍ତମାନର"</string>
- <!-- no translation found for taskbar_button_notifications (7471740351507357318) -->
- <skip />
- <!-- no translation found for taskbar_button_quick_settings (227662894293189391) -->
- <skip />
+ <string name="taskbar_button_notifications" msgid="7471740351507357318">"ବିଜ୍ଞପ୍ତିଗୁଡ଼ିକ"</string>
+ <string name="taskbar_button_quick_settings" msgid="227662894293189391">"କ୍ୱିକ ସେଟିଂସ"</string>
<string name="move_drop_target_top_or_left" msgid="2988702185049595807">"ଶୀର୍ଷ/ବାମକୁ ମୁଭ କରନ୍ତୁ"</string>
<string name="move_drop_target_bottom_or_right" msgid="5431393418797620162">"ନିମ୍ନ/ଡାହାଣକୁ ମୁଭ କରନ୍ତୁ"</string>
</resources>
diff --git a/quickstep/res/values-si/strings.xml b/quickstep/res/values-si/strings.xml
index 990017e..3c15a85 100644
--- a/quickstep/res/values-si/strings.xml
+++ b/quickstep/res/values-si/strings.xml
@@ -102,10 +102,8 @@
<string name="taskbar_button_back" msgid="8558862226461164514">"ආපසු"</string>
<string name="taskbar_button_ime_switcher" msgid="1730244360907588541">"IME මාරුව"</string>
<string name="taskbar_button_recents" msgid="7273376136216613134">"මෑත"</string>
- <!-- no translation found for taskbar_button_notifications (7471740351507357318) -->
- <skip />
- <!-- no translation found for taskbar_button_quick_settings (227662894293189391) -->
- <skip />
+ <string name="taskbar_button_notifications" msgid="7471740351507357318">"දැනුම්දීම්"</string>
+ <string name="taskbar_button_quick_settings" msgid="227662894293189391">"ඉක්මන් සැකසීම්"</string>
<string name="move_drop_target_top_or_left" msgid="2988702185049595807">"ඉහළ/වම වෙත ගෙන යන්න"</string>
<string name="move_drop_target_bottom_or_right" msgid="5431393418797620162">"පහළ/දකුණ වෙත ගෙන යන්න"</string>
</resources>
diff --git a/quickstep/res/values-sk/strings.xml b/quickstep/res/values-sk/strings.xml
index a18f72c..155da05 100644
--- a/quickstep/res/values-sk/strings.xml
+++ b/quickstep/res/values-sk/strings.xml
@@ -102,10 +102,8 @@
<string name="taskbar_button_back" msgid="8558862226461164514">"Späť"</string>
<string name="taskbar_button_ime_switcher" msgid="1730244360907588541">"Prepínač IME"</string>
<string name="taskbar_button_recents" msgid="7273376136216613134">"Nedávne"</string>
- <!-- no translation found for taskbar_button_notifications (7471740351507357318) -->
- <skip />
- <!-- no translation found for taskbar_button_quick_settings (227662894293189391) -->
- <skip />
+ <string name="taskbar_button_notifications" msgid="7471740351507357318">"Upozornenia"</string>
+ <string name="taskbar_button_quick_settings" msgid="227662894293189391">"Rýchle nastavenia"</string>
<string name="move_drop_target_top_or_left" msgid="2988702185049595807">"Presunúť hore alebo doľava"</string>
<string name="move_drop_target_bottom_or_right" msgid="5431393418797620162">"Presunúť dole alebo doprava"</string>
</resources>
diff --git a/quickstep/res/values-sq/strings.xml b/quickstep/res/values-sq/strings.xml
index f2b2fa8..999768c 100644
--- a/quickstep/res/values-sq/strings.xml
+++ b/quickstep/res/values-sq/strings.xml
@@ -102,10 +102,8 @@
<string name="taskbar_button_back" msgid="8558862226461164514">"Pas"</string>
<string name="taskbar_button_ime_switcher" msgid="1730244360907588541">"Çelësi IME"</string>
<string name="taskbar_button_recents" msgid="7273376136216613134">"Të fundit"</string>
- <!-- no translation found for taskbar_button_notifications (7471740351507357318) -->
- <skip />
- <!-- no translation found for taskbar_button_quick_settings (227662894293189391) -->
- <skip />
+ <string name="taskbar_button_notifications" msgid="7471740351507357318">"Njoftimet"</string>
+ <string name="taskbar_button_quick_settings" msgid="227662894293189391">"Cilësimet shpejt"</string>
<string name="move_drop_target_top_or_left" msgid="2988702185049595807">"Lëviz në krye/majtas"</string>
<string name="move_drop_target_bottom_or_right" msgid="5431393418797620162">"Lëviz në fund/djathtas"</string>
</resources>
diff --git a/quickstep/res/values-sv/strings.xml b/quickstep/res/values-sv/strings.xml
index 2f1b75a..49f20c0 100644
--- a/quickstep/res/values-sv/strings.xml
+++ b/quickstep/res/values-sv/strings.xml
@@ -102,10 +102,8 @@
<string name="taskbar_button_back" msgid="8558862226461164514">"Tillbaka"</string>
<string name="taskbar_button_ime_switcher" msgid="1730244360907588541">"IME-väljare"</string>
<string name="taskbar_button_recents" msgid="7273376136216613134">"Senaste"</string>
- <!-- no translation found for taskbar_button_notifications (7471740351507357318) -->
- <skip />
- <!-- no translation found for taskbar_button_quick_settings (227662894293189391) -->
- <skip />
+ <string name="taskbar_button_notifications" msgid="7471740351507357318">"Aviseringar"</string>
+ <string name="taskbar_button_quick_settings" msgid="227662894293189391">"Snabbinställn."</string>
<string name="move_drop_target_top_or_left" msgid="2988702185049595807">"Flytta högst upp/till vänster"</string>
<string name="move_drop_target_bottom_or_right" msgid="5431393418797620162">"Flytta längst ned/till höger"</string>
</resources>
diff --git a/quickstep/res/values-tl/strings.xml b/quickstep/res/values-tl/strings.xml
index 3ecae96..71b01b6 100644
--- a/quickstep/res/values-tl/strings.xml
+++ b/quickstep/res/values-tl/strings.xml
@@ -102,10 +102,8 @@
<string name="taskbar_button_back" msgid="8558862226461164514">"Bumalik"</string>
<string name="taskbar_button_ime_switcher" msgid="1730244360907588541">"IME switcher"</string>
<string name="taskbar_button_recents" msgid="7273376136216613134">"Mga Kamakailan"</string>
- <!-- no translation found for taskbar_button_notifications (7471740351507357318) -->
- <skip />
- <!-- no translation found for taskbar_button_quick_settings (227662894293189391) -->
- <skip />
+ <string name="taskbar_button_notifications" msgid="7471740351507357318">"Mga Notification"</string>
+ <string name="taskbar_button_quick_settings" msgid="227662894293189391">"Quick Settings"</string>
<string name="move_drop_target_top_or_left" msgid="2988702185049595807">"Ilipat sa itaas/kaliwa"</string>
<string name="move_drop_target_bottom_or_right" msgid="5431393418797620162">"Ilipat sa ibaba/kanan"</string>
</resources>
diff --git a/quickstep/res/values-tr/strings.xml b/quickstep/res/values-tr/strings.xml
index 19ced47..5e9a84b 100644
--- a/quickstep/res/values-tr/strings.xml
+++ b/quickstep/res/values-tr/strings.xml
@@ -102,10 +102,8 @@
<string name="taskbar_button_back" msgid="8558862226461164514">"Geri"</string>
<string name="taskbar_button_ime_switcher" msgid="1730244360907588541">"IME değiştirici"</string>
<string name="taskbar_button_recents" msgid="7273376136216613134">"Son Kullanılanlar"</string>
- <!-- no translation found for taskbar_button_notifications (7471740351507357318) -->
- <skip />
- <!-- no translation found for taskbar_button_quick_settings (227662894293189391) -->
- <skip />
+ <string name="taskbar_button_notifications" msgid="7471740351507357318">"Bildirimler"</string>
+ <string name="taskbar_button_quick_settings" msgid="227662894293189391">"Hızlı Ayarlar"</string>
<string name="move_drop_target_top_or_left" msgid="2988702185049595807">"Sol üste taşı"</string>
<string name="move_drop_target_bottom_or_right" msgid="5431393418797620162">"Sağ alta taşı"</string>
</resources>
diff --git a/quickstep/res/values-uk/strings.xml b/quickstep/res/values-uk/strings.xml
index 231d128..2e0d3f7 100644
--- a/quickstep/res/values-uk/strings.xml
+++ b/quickstep/res/values-uk/strings.xml
@@ -102,10 +102,8 @@
<string name="taskbar_button_back" msgid="8558862226461164514">"Назад"</string>
<string name="taskbar_button_ime_switcher" msgid="1730244360907588541">"Перемикач IME"</string>
<string name="taskbar_button_recents" msgid="7273376136216613134">"Нещодавні"</string>
- <!-- no translation found for taskbar_button_notifications (7471740351507357318) -->
- <skip />
- <!-- no translation found for taskbar_button_quick_settings (227662894293189391) -->
- <skip />
+ <string name="taskbar_button_notifications" msgid="7471740351507357318">"Сповіщення"</string>
+ <string name="taskbar_button_quick_settings" msgid="227662894293189391">"Швидкі налаштув."</string>
<string name="move_drop_target_top_or_left" msgid="2988702185049595807">"Перемістити вгору або вліво"</string>
<string name="move_drop_target_bottom_or_right" msgid="5431393418797620162">"Перемістити вниз або вправо"</string>
</resources>
diff --git a/quickstep/res/values-vi/strings.xml b/quickstep/res/values-vi/strings.xml
index 1072c3a..e3c6698 100644
--- a/quickstep/res/values-vi/strings.xml
+++ b/quickstep/res/values-vi/strings.xml
@@ -102,10 +102,8 @@
<string name="taskbar_button_back" msgid="8558862226461164514">"Quay lại"</string>
<string name="taskbar_button_ime_switcher" msgid="1730244360907588541">"Trình chuyển đổi IME"</string>
<string name="taskbar_button_recents" msgid="7273376136216613134">"Gần đây"</string>
- <!-- no translation found for taskbar_button_notifications (7471740351507357318) -->
- <skip />
- <!-- no translation found for taskbar_button_quick_settings (227662894293189391) -->
- <skip />
+ <string name="taskbar_button_notifications" msgid="7471740351507357318">"Thông báo"</string>
+ <string name="taskbar_button_quick_settings" msgid="227662894293189391">"Cài đặt nhanh"</string>
<string name="move_drop_target_top_or_left" msgid="2988702185049595807">"Chuyển lên trên cùng/sang bên trái"</string>
<string name="move_drop_target_bottom_or_right" msgid="5431393418797620162">"Chuyển xuống dưới cùng/sang bên phải"</string>
</resources>
diff --git a/quickstep/res/values-zh-rCN/strings.xml b/quickstep/res/values-zh-rCN/strings.xml
index 4587d58..a42476c 100644
--- a/quickstep/res/values-zh-rCN/strings.xml
+++ b/quickstep/res/values-zh-rCN/strings.xml
@@ -102,10 +102,8 @@
<string name="taskbar_button_back" msgid="8558862226461164514">"返回"</string>
<string name="taskbar_button_ime_switcher" msgid="1730244360907588541">"IME 切换器"</string>
<string name="taskbar_button_recents" msgid="7273376136216613134">"最近用过"</string>
- <!-- no translation found for taskbar_button_notifications (7471740351507357318) -->
- <skip />
- <!-- no translation found for taskbar_button_quick_settings (227662894293189391) -->
- <skip />
+ <string name="taskbar_button_notifications" msgid="7471740351507357318">"通知"</string>
+ <string name="taskbar_button_quick_settings" msgid="227662894293189391">"快捷设置"</string>
<string name="move_drop_target_top_or_left" msgid="2988702185049595807">"移到顶部/左侧"</string>
<string name="move_drop_target_bottom_or_right" msgid="5431393418797620162">"移到底部/右侧"</string>
</resources>
diff --git a/quickstep/res/values-zh-rHK/strings.xml b/quickstep/res/values-zh-rHK/strings.xml
index 2810771..f2fd544 100644
--- a/quickstep/res/values-zh-rHK/strings.xml
+++ b/quickstep/res/values-zh-rHK/strings.xml
@@ -102,10 +102,8 @@
<string name="taskbar_button_back" msgid="8558862226461164514">"返回"</string>
<string name="taskbar_button_ime_switcher" msgid="1730244360907588541">"輸入法編輯器切換工具"</string>
<string name="taskbar_button_recents" msgid="7273376136216613134">"最近"</string>
- <!-- no translation found for taskbar_button_notifications (7471740351507357318) -->
- <skip />
- <!-- no translation found for taskbar_button_quick_settings (227662894293189391) -->
- <skip />
+ <string name="taskbar_button_notifications" msgid="7471740351507357318">"通知"</string>
+ <string name="taskbar_button_quick_settings" msgid="227662894293189391">"快速設定"</string>
<string name="move_drop_target_top_or_left" msgid="2988702185049595807">"移至上方/左側"</string>
<string name="move_drop_target_bottom_or_right" msgid="5431393418797620162">"移至底部/右側"</string>
</resources>
diff --git a/quickstep/res/values-zh-rTW/strings.xml b/quickstep/res/values-zh-rTW/strings.xml
index 847cb91..f1fe624 100644
--- a/quickstep/res/values-zh-rTW/strings.xml
+++ b/quickstep/res/values-zh-rTW/strings.xml
@@ -102,10 +102,8 @@
<string name="taskbar_button_back" msgid="8558862226461164514">"返回"</string>
<string name="taskbar_button_ime_switcher" msgid="1730244360907588541">"輸入法編輯器切換器"</string>
<string name="taskbar_button_recents" msgid="7273376136216613134">"最近使用"</string>
- <!-- no translation found for taskbar_button_notifications (7471740351507357318) -->
- <skip />
- <!-- no translation found for taskbar_button_quick_settings (227662894293189391) -->
- <skip />
+ <string name="taskbar_button_notifications" msgid="7471740351507357318">"通知"</string>
+ <string name="taskbar_button_quick_settings" msgid="227662894293189391">"快速設定"</string>
<string name="move_drop_target_top_or_left" msgid="2988702185049595807">"移到上方/左側"</string>
<string name="move_drop_target_bottom_or_right" msgid="5431393418797620162">"移到底部/右側"</string>
</resources>
diff --git a/quickstep/src/com/android/launcher3/BaseQuickstepLauncher.java b/quickstep/src/com/android/launcher3/BaseQuickstepLauncher.java
index af4f49d..cb6094b 100644
--- a/quickstep/src/com/android/launcher3/BaseQuickstepLauncher.java
+++ b/quickstep/src/com/android/launcher3/BaseQuickstepLauncher.java
@@ -41,6 +41,7 @@
import android.hardware.devicestate.DeviceStateManager;
import android.os.Bundle;
import android.os.CancellationSignal;
+import android.os.IBinder;
import android.view.Display;
import android.view.View;
import android.view.WindowInsets;
@@ -65,6 +66,7 @@
import com.android.launcher3.util.DisplayController;
import com.android.launcher3.util.IntSet;
import com.android.launcher3.util.ObjectWrapper;
+import com.android.launcher3.util.RunnableList;
import com.android.launcher3.util.SplitConfigurationOptions.SplitPositionOption;
import com.android.launcher3.util.UiThreadHelper;
import com.android.quickstep.OverviewCommandHelper;
@@ -497,6 +499,20 @@
}
@Override
+ public void onInitialBindComplete(IntSet boundPages, RunnableList pendingTasks) {
+ pendingTasks.add(() -> {
+ // This is added in pending task as we need to wait for views to be positioned
+ // correctly before registering them for the animation.
+ if (mLauncherUnfoldAnimationController != null) {
+ // This is needed in case items are rebound while the unfold animation is in
+ // progress.
+ mLauncherUnfoldAnimationController.updateRegisteredViewsIfNeeded();
+ }
+ });
+ super.onInitialBindComplete(boundPages, pendingTasks);
+ }
+
+ @Override
public Stream<SystemShortcut.Factory> getSupportedShortcuts() {
Stream<SystemShortcut.Factory> base = Stream.of(WellbeingModel.SHORTCUT_FACTORY);
if (ENABLE_SPLIT_FROM_WORKSPACE.get() && mDeviceProfile.isTablet) {
@@ -533,11 +549,26 @@
}
/**
- * Adds a new launch cookie for the activity launch of the given {@param info} if supported.
+ * Adds a new launch cookie for the activity launch if supported.
+ *
+ * @param info the item info for the launch
+ * @param opts the options to set the launchCookie on.
*/
public void addLaunchCookie(ItemInfo info, ActivityOptions opts) {
+ IBinder launchCookie = getLaunchCookie(info);
+ if (launchCookie != null) {
+ opts.setLaunchCookie(launchCookie);
+ }
+ }
+
+ /**
+ * Return a new launch cookie for the activity launch if supported.
+ *
+ * @param info the item info for the launch
+ */
+ public IBinder getLaunchCookie(ItemInfo info) {
if (info == null) {
- return;
+ return null;
}
switch (info.container) {
case LauncherSettings.Favorites.CONTAINER_DESKTOP:
@@ -551,8 +582,7 @@
break;
}
// Reset any existing launch cookies associated with the cookie
- opts.setLaunchCookie(ObjectWrapper.wrap(NO_MATCHING_ID));
- return;
+ return ObjectWrapper.wrap(NO_MATCHING_ID);
}
switch (info.itemType) {
case LauncherSettings.Favorites.ITEM_TYPE_APPLICATION:
@@ -563,10 +593,9 @@
break;
default:
// Reset any existing launch cookies associated with the cookie
- opts.setLaunchCookie(ObjectWrapper.wrap(NO_MATCHING_ID));
- return;
+ return ObjectWrapper.wrap(NO_MATCHING_ID);
}
- opts.setLaunchCookie(ObjectWrapper.wrap(new Integer(info.id)));
+ return ObjectWrapper.wrap(new Integer(info.id));
}
public void setHintUserWillBeActive() {
diff --git a/quickstep/src/com/android/launcher3/LauncherAnimationRunner.java b/quickstep/src/com/android/launcher3/LauncherAnimationRunner.java
index 661053a..62603e9 100644
--- a/quickstep/src/com/android/launcher3/LauncherAnimationRunner.java
+++ b/quickstep/src/com/android/launcher3/LauncherAnimationRunner.java
@@ -16,9 +16,9 @@
package com.android.launcher3;
import static com.android.launcher3.Utilities.postAsyncCallback;
-import static com.android.launcher3.util.DisplayController.getSingleFrameMs;
import static com.android.launcher3.util.Executors.MAIN_EXECUTOR;
import static com.android.launcher3.util.Executors.UI_HELPER_EXECUTOR;
+import static com.android.launcher3.util.window.RefreshRateTracker.getSingleFrameMs;
import static com.android.systemui.shared.recents.utilities.Utilities.postAtFrontOfQueueAsynchronously;
import android.animation.Animator;
diff --git a/quickstep/src/com/android/launcher3/QuickstepTransitionManager.java b/quickstep/src/com/android/launcher3/QuickstepTransitionManager.java
index 3eb1935e..c4a3fb5 100644
--- a/quickstep/src/com/android/launcher3/QuickstepTransitionManager.java
+++ b/quickstep/src/com/android/launcher3/QuickstepTransitionManager.java
@@ -44,7 +44,7 @@
import static com.android.launcher3.dragndrop.DragLayer.ALPHA_INDEX_TRANSITIONS;
import static com.android.launcher3.model.data.ItemInfo.NO_MATCHING_ID;
import static com.android.launcher3.statehandlers.DepthController.DEPTH;
-import static com.android.launcher3.util.DisplayController.getSingleFrameMs;
+import static com.android.launcher3.util.window.RefreshRateTracker.getSingleFrameMs;
import static com.android.launcher3.views.FloatingIconView.SHAPE_PROGRESS_DURATION;
import static com.android.launcher3.views.FloatingIconView.getFloatingIconView;
import static com.android.quickstep.TaskViewUtils.findTaskViewToLaunch;
diff --git a/quickstep/src/com/android/launcher3/statehandlers/DepthController.java b/quickstep/src/com/android/launcher3/statehandlers/DepthController.java
index d54b9e7..3b02599 100644
--- a/quickstep/src/com/android/launcher3/statehandlers/DepthController.java
+++ b/quickstep/src/com/android/launcher3/statehandlers/DepthController.java
@@ -23,6 +23,7 @@
import android.animation.Animator;
import android.animation.AnimatorListenerAdapter;
import android.animation.ObjectAnimator;
+import android.app.WallpaperManager;
import android.os.IBinder;
import android.os.SystemProperties;
import android.util.FloatProperty;
@@ -42,7 +43,6 @@
import com.android.launcher3.statemanager.StateManager.StateHandler;
import com.android.launcher3.states.StateAnimationConfig;
import com.android.systemui.shared.system.BlurUtils;
-import com.android.systemui.shared.system.WallpaperManagerCompat;
import java.io.PrintWriter;
import java.util.function.Consumer;
@@ -127,7 +127,7 @@
*/
private int mMaxBlurRadius;
private boolean mCrossWindowBlursEnabled;
- private WallpaperManagerCompat mWallpaperManager;
+ private WallpaperManager mWallpaperManager;
private SurfaceControl mSurface;
/**
* How visible the -1 overlay is, from 0 to 1.
@@ -168,7 +168,7 @@
private void ensureDependencies() {
if (mWallpaperManager == null) {
mMaxBlurRadius = mLauncher.getResources().getInteger(R.integer.max_depth_blur_radius);
- mWallpaperManager = new WallpaperManagerCompat(mLauncher);
+ mWallpaperManager = mLauncher.getSystemService(WallpaperManager.class);
}
if (mLauncher.getRootView() != null && mOnAttachListener == null) {
diff --git a/quickstep/src/com/android/launcher3/taskbar/BaseTaskbarContext.java b/quickstep/src/com/android/launcher3/taskbar/BaseTaskbarContext.java
new file mode 100644
index 0000000..27e89ba
--- /dev/null
+++ b/quickstep/src/com/android/launcher3/taskbar/BaseTaskbarContext.java
@@ -0,0 +1,72 @@
+/*
+ * 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.taskbar;
+
+import android.content.Context;
+import android.view.ContextThemeWrapper;
+import android.view.LayoutInflater;
+
+import com.android.launcher3.DeviceProfile;
+import com.android.launcher3.DeviceProfile.DeviceProfileListenable;
+import com.android.launcher3.DeviceProfile.OnDeviceProfileChangeListener;
+import com.android.launcher3.util.Themes;
+import com.android.launcher3.views.ActivityContext;
+
+import java.util.ArrayList;
+import java.util.List;
+
+// TODO(b/218912746): Share more behavior to avoid all apps context depending directly on taskbar.
+/** Base for common behavior between taskbar window contexts. */
+public abstract class BaseTaskbarContext extends ContextThemeWrapper implements ActivityContext,
+ DeviceProfileListenable {
+
+ protected final LayoutInflater mLayoutInflater;
+ private final List<OnDeviceProfileChangeListener> mDPChangeListeners = new ArrayList<>();
+
+ protected DeviceProfile mDeviceProfile;
+
+ public BaseTaskbarContext(Context windowContext) {
+ super(windowContext, Themes.getActivityThemeRes(windowContext));
+ mLayoutInflater = LayoutInflater.from(this).cloneInContext(this);
+ }
+
+ @Override
+ public final LayoutInflater getLayoutInflater() {
+ return mLayoutInflater;
+ }
+
+ @Override
+ public final DeviceProfile getDeviceProfile() {
+ return mDeviceProfile;
+ }
+
+ @Override
+ public final List<OnDeviceProfileChangeListener> getOnDeviceProfileChangeListeners() {
+ return mDPChangeListeners;
+ }
+
+ /** Updates the {@link DeviceProfile} instance to the latest representation of the screen. */
+ public abstract void updateDeviceProfile(DeviceProfile dp);
+
+ /** Callback invoked when a drag is initiated within this context. */
+ public abstract void onDragStart();
+
+ /** Callback invoked when a drag is finished within this context. */
+ public abstract void onDragEnd();
+
+ /** Callback invoked when a popup is shown or closed within this context. */
+ public abstract void onPopupVisibilityChanged(boolean isVisible);
+}
diff --git a/quickstep/src/com/android/launcher3/taskbar/LauncherTaskbarUIController.java b/quickstep/src/com/android/launcher3/taskbar/LauncherTaskbarUIController.java
index 0f91aa2..af53ae2 100644
--- a/quickstep/src/com/android/launcher3/taskbar/LauncherTaskbarUIController.java
+++ b/quickstep/src/com/android/launcher3/taskbar/LauncherTaskbarUIController.java
@@ -228,8 +228,7 @@
* Whether the taskbar education should be shown.
*/
public boolean shouldShowEdu() {
- return FeatureFlags.ENABLE_TASKBAR_EDU.get()
- && !Utilities.IS_RUNNING_IN_TEST_HARNESS
+ return !Utilities.IS_RUNNING_IN_TEST_HARNESS
&& !mLauncher.getOnboardingPrefs().getBoolean(OnboardingPrefs.TASKBAR_EDU_SEEN);
}
@@ -237,10 +236,6 @@
* Manually ends the taskbar education flow.
*/
public void hideEdu() {
- if (!FeatureFlags.ENABLE_TASKBAR_EDU.get()) {
- return;
- }
-
mControllers.taskbarEduController.hideEdu();
}
diff --git a/quickstep/src/com/android/launcher3/taskbar/TaskbarActivityContext.java b/quickstep/src/com/android/launcher3/taskbar/TaskbarActivityContext.java
index fe091ef..fa0a606 100644
--- a/quickstep/src/com/android/launcher3/taskbar/TaskbarActivityContext.java
+++ b/quickstep/src/com/android/launcher3/taskbar/TaskbarActivityContext.java
@@ -21,6 +21,7 @@
import static android.view.WindowManager.LayoutParams.LAYOUT_IN_DISPLAY_CUTOUT_MODE_ALWAYS;
import static android.view.WindowManager.LayoutParams.TYPE_NAVIGATION_BAR_PANEL;
+import static com.android.launcher3.AbstractFloatingView.TYPE_ALL;
import static com.android.launcher3.logging.StatsLogManager.LauncherEvent.LAUNCHER_FOLDER_OPEN;
import static com.android.systemui.shared.system.QuickStepContract.SYSUI_STATE_NOTIFICATION_PANEL_EXPANDED;
import static com.android.systemui.shared.system.QuickStepContract.SYSUI_STATE_QUICK_SETTINGS_EXPANDED;
@@ -42,10 +43,8 @@
import android.os.SystemProperties;
import android.provider.Settings;
import android.util.Log;
-import android.view.ContextThemeWrapper;
import android.view.Display;
import android.view.Gravity;
-import android.view.LayoutInflater;
import android.view.RoundedCorner;
import android.view.View;
import android.view.WindowManager;
@@ -58,11 +57,8 @@
import com.android.launcher3.AbstractFloatingView;
import com.android.launcher3.BubbleTextView;
import com.android.launcher3.DeviceProfile;
-import com.android.launcher3.DeviceProfile.DeviceProfileListenable;
-import com.android.launcher3.DeviceProfile.OnDeviceProfileChangeListener;
import com.android.launcher3.LauncherSettings.Favorites;
import com.android.launcher3.R;
-import com.android.launcher3.Utilities;
import com.android.launcher3.dot.DotInfo;
import com.android.launcher3.folder.Folder;
import com.android.launcher3.folder.FolderIcon;
@@ -72,11 +68,10 @@
import com.android.launcher3.model.data.ItemInfo;
import com.android.launcher3.model.data.WorkspaceItemInfo;
import com.android.launcher3.popup.PopupDataProvider;
+import com.android.launcher3.taskbar.allapps.TaskbarAllAppsController;
import com.android.launcher3.touch.ItemClickHandler;
-import com.android.launcher3.util.OnboardingPrefs;
import com.android.launcher3.util.PackageManagerHelper;
import com.android.launcher3.util.SettingsCache;
-import com.android.launcher3.util.Themes;
import com.android.launcher3.util.TraceHelper;
import com.android.launcher3.util.ViewCache;
import com.android.launcher3.views.ActivityContext;
@@ -89,16 +84,13 @@
import com.android.systemui.unfold.util.ScopedUnfoldTransitionProgressProvider;
import java.io.PrintWriter;
-import java.util.ArrayList;
-import java.util.List;
/**
* The {@link ActivityContext} with which we inflate Taskbar-related Views. This allows UI elements
* that are used by both Launcher and Taskbar (such as Folder) to reference a generic
* ActivityContext and BaseDragLayer instead of the Launcher activity and its DragLayer.
*/
-public class TaskbarActivityContext extends ContextThemeWrapper implements ActivityContext,
- DeviceProfileListenable {
+public class TaskbarActivityContext extends BaseTaskbarContext {
private static final boolean ENABLE_THREE_BUTTON_TASKBAR =
SystemProperties.getBoolean("persist.debug.taskbar_three_button", false);
@@ -106,13 +98,8 @@
private static final String WINDOW_TITLE = "Taskbar";
- private final LayoutInflater mLayoutInflater;
private final TaskbarDragLayer mDragLayer;
- private final TaskbarAllAppsContainerView mAppsView;
private final TaskbarControllers mControllers;
- private final List<OnDeviceProfileChangeListener> mDPChangeListeners = new ArrayList<>();
-
- private DeviceProfile mDeviceProfile;
private final WindowManager mWindowManager;
private final @Nullable RoundedCorner mLeftCorner, mRightCorner;
@@ -128,6 +115,7 @@
private final boolean mIsSafeModeEnabled;
private final boolean mIsUserSetupComplete;
+ private final boolean mIsNavBarForceVisible;
private final boolean mIsNavBarKidsMode;
private boolean mIsDestroyed = false;
// The flag to know if the window is excluded from magnification region computation.
@@ -135,14 +123,12 @@
private boolean mBindingItems = false;
private final TaskbarShortcutMenuAccessibilityDelegate mAccessibilityDelegate;
- private final OnboardingPrefs<TaskbarActivityContext> mOnboardingPrefs;
public TaskbarActivityContext(Context windowContext, DeviceProfile dp,
TaskbarNavButtonController buttonController, ScopedUnfoldTransitionProgressProvider
unfoldTransitionProgressProvider) {
- super(windowContext, Themes.getActivityThemeRes(windowContext));
+ super(windowContext);
mDeviceProfile = dp;
- mOnboardingPrefs = new OnboardingPrefs<>(this, Utilities.getPrefs(this));
mNavMode = SysUINavigationMode.getMode(windowContext);
mImeDrawsImeNavBar = SysUINavigationMode.getImeDrawsImeNavBar(windowContext);
@@ -150,6 +136,8 @@
() -> getPackageManager().isSafeMode());
mIsUserSetupComplete = SettingsCache.INSTANCE.get(this).getValue(
Settings.Secure.getUriFor(Settings.Secure.USER_SETUP_COMPLETE), 0);
+ mIsNavBarForceVisible = SettingsCache.INSTANCE.get(this).getValue(
+ Settings.Secure.getUriFor(Settings.Secure.NAV_BAR_FORCE_VISIBLE), 0);
mIsNavBarKidsMode = SettingsCache.INSTANCE.get(this).getValue(
Settings.Secure.getUriFor(Settings.Secure.NAV_BAR_KIDS_MODE), 0);
@@ -158,8 +146,6 @@
mTaskbarHeightForIme = resources.getDimensionPixelSize(R.dimen.taskbar_ime_size);
- mLayoutInflater = LayoutInflater.from(this).cloneInContext(this);
-
// Inflate views.
mDragLayer = (TaskbarDragLayer) mLayoutInflater.inflate(
R.layout.taskbar, null, false);
@@ -168,11 +154,6 @@
FrameLayout navButtonsView = mDragLayer.findViewById(R.id.navbuttons_view);
StashedHandleView stashedHandleView = mDragLayer.findViewById(R.id.stashed_handle);
- TaskbarAllAppsSlideInView appsSlideInView =
- (TaskbarAllAppsSlideInView) mLayoutInflater.inflate(R.layout.taskbar_all_apps,
- mDragLayer, false);
- mAppsView = appsSlideInView.getAppsView();
-
Display display = windowContext.getDisplay();
Context c = display.getDisplayId() == Display.DEFAULT_DISPLAY
? windowContext.getApplicationContext()
@@ -210,7 +191,7 @@
new TaskbarAutohideSuspendController(this),
new TaskbarPopupController(this),
new TaskbarForceVisibleImmersiveController(this),
- new TaskbarAllAppsViewController(this, appsSlideInView));
+ new TaskbarAllAppsController(this));
}
public void init(TaskbarSharedState sharedState) {
@@ -236,7 +217,7 @@
mWindowManager.addView(mDragLayer, mWindowLayoutParams);
}
- /** Updates the Device profile instance to the latest representation of the screen. */
+ @Override
public void updateDeviceProfile(DeviceProfile dp) {
mDeviceProfile = dp;
updateIconSize(getResources());
@@ -297,31 +278,11 @@
}
@Override
- public LayoutInflater getLayoutInflater() {
- return mLayoutInflater;
- }
-
- @Override
public TaskbarDragLayer getDragLayer() {
return mDragLayer;
}
@Override
- public TaskbarAllAppsContainerView getAppsView() {
- return mAppsView;
- }
-
- @Override
- public DeviceProfile getDeviceProfile() {
- return mDeviceProfile;
- }
-
- @Override
- public List<OnDeviceProfileChangeListener> getOnDeviceProfileChangeListeners() {
- return mDPChangeListeners;
- }
-
- @Override
public Rect getFolderBoundingBox() {
return mControllers.taskbarDragLayerController.getFolderBoundingBox();
}
@@ -412,11 +373,6 @@
}
@Override
- public OnboardingPrefs<TaskbarActivityContext> getOnboardingPrefs() {
- return mOnboardingPrefs;
- }
-
- @Override
public boolean isBindingItems() {
return mBindingItems;
}
@@ -425,6 +381,21 @@
mBindingItems = bindingItems;
}
+ @Override
+ public void onDragStart() {
+ setTaskbarWindowFullscreen(true);
+ }
+
+ @Override
+ public void onDragEnd() {
+ maybeSetTaskbarWindowNotFullscreen();
+ }
+
+ @Override
+ public void onPopupVisibilityChanged(boolean isVisible) {
+ setTaskbarWindowFocusable(isVisible);
+ }
+
/**
* Sets a new data-source for this taskbar instance
*/
@@ -523,6 +494,17 @@
setTaskbarWindowHeight(fullscreen ? MATCH_PARENT : mLastRequestedNonFullscreenHeight);
}
+ /**
+ * Reverts Taskbar window to its original size, if all floating views are closed and there is
+ * no system drag operation in progress.
+ */
+ void maybeSetTaskbarWindowNotFullscreen() {
+ if (AbstractFloatingView.getAnyView(this, TYPE_ALL) == null
+ && !mControllers.taskbarDragController.isSystemDragInProgress()) {
+ setTaskbarWindowFullscreen(false);
+ }
+ }
+
public boolean isTaskbarWindowFullscreen() {
return mIsFullscreen;
}
@@ -732,6 +714,10 @@
return mIsNavBarKidsMode && isThreeButtonNav();
}
+ protected boolean isNavBarForceVisible() {
+ return mIsNavBarForceVisible;
+ }
+
/**
* Called when we determine the touchable region.
*
diff --git a/quickstep/src/com/android/launcher3/taskbar/TaskbarAllAppsViewController.java b/quickstep/src/com/android/launcher3/taskbar/TaskbarAllAppsViewController.java
deleted file mode 100644
index 2670200..0000000
--- a/quickstep/src/com/android/launcher3/taskbar/TaskbarAllAppsViewController.java
+++ /dev/null
@@ -1,84 +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.taskbar;
-
-import static com.android.launcher3.util.OnboardingPrefs.ALL_APPS_VISITED_COUNT;
-
-import com.android.launcher3.appprediction.AppsDividerView;
-import com.android.launcher3.appprediction.PredictionRowView;
-import com.android.launcher3.config.FeatureFlags;
-import com.android.launcher3.model.data.AppInfo;
-import com.android.launcher3.model.data.ItemInfo;
-
-import java.util.List;
-
-/** Handles the {@link TaskbarAllAppsContainerView} initialization and updates. */
-public final class TaskbarAllAppsViewController {
-
- private final TaskbarActivityContext mContext;
- private final TaskbarAllAppsSlideInView mSlideInView;
- private final TaskbarAllAppsContainerView mAppsView;
-
- public TaskbarAllAppsViewController(
- TaskbarActivityContext context, TaskbarAllAppsSlideInView slideInView) {
- mContext = context;
- mSlideInView = slideInView;
- mAppsView = mSlideInView.getAppsView();
- }
-
- /** Initialize the controller. */
- public void init(TaskbarControllers controllers) {
- if (!FeatureFlags.ENABLE_ALL_APPS_IN_TASKBAR.get()) {
- return;
- }
-
- mAppsView.setOnIconLongClickListener(
- controllers.taskbarDragController::startDragOnLongClick);
- mAppsView.getFloatingHeaderView().findFixedRowByType(
- PredictionRowView.class).setOnIconLongClickListener(
- controllers.taskbarDragController::startDragOnLongClick);
- }
-
- /** Binds the current {@link AppInfo} instances to the {@link TaskbarAllAppsContainerView}. */
- public void setApps(AppInfo[] apps, int flags) {
- if (FeatureFlags.ENABLE_ALL_APPS_IN_TASKBAR.get()) {
- mAppsView.getAppsStore().setApps(apps, flags);
- }
- }
-
- /** Binds the current app predictions to all apps {@link PredictionRowView}. */
- public void setPredictedApps(List<ItemInfo> predictedApps) {
- if (FeatureFlags.ENABLE_ALL_APPS_IN_TASKBAR.get()) {
- PredictionRowView<?> predictionRowView =
- mAppsView.getFloatingHeaderView().findFixedRowByType(PredictionRowView.class);
- predictionRowView.setPredictedApps(predictedApps);
- }
- }
-
- /** Opens the {@link TaskbarAllAppsContainerView}. */
- public void show() {
- if (!FeatureFlags.ENABLE_ALL_APPS_IN_TASKBAR.get()) {
- return;
- }
-
- mAppsView.getFloatingHeaderView().findFixedRowByType(AppsDividerView.class)
- .setShowAllAppsLabel(
- !mContext.getOnboardingPrefs().hasReachedMaxCount(ALL_APPS_VISITED_COUNT));
- mContext.getOnboardingPrefs().incrementEventCount(ALL_APPS_VISITED_COUNT);
- mContext.setTaskbarWindowFullscreen(true);
- mSlideInView.show();
- }
-}
diff --git a/quickstep/src/com/android/launcher3/taskbar/TaskbarControllers.java b/quickstep/src/com/android/launcher3/taskbar/TaskbarControllers.java
index 21fbb3b..d2e24e5 100644
--- a/quickstep/src/com/android/launcher3/taskbar/TaskbarControllers.java
+++ b/quickstep/src/com/android/launcher3/taskbar/TaskbarControllers.java
@@ -20,6 +20,7 @@
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
+import com.android.launcher3.taskbar.allapps.TaskbarAllAppsController;
import com.android.systemui.shared.rotation.RotationButtonController;
import java.io.PrintWriter;
@@ -48,7 +49,7 @@
public final TaskbarAutohideSuspendController taskbarAutohideSuspendController;
public final TaskbarPopupController taskbarPopupController;
public final TaskbarForceVisibleImmersiveController taskbarForceVisibleImmersiveController;
- public final TaskbarAllAppsViewController taskbarAllAppsViewController;
+ public final TaskbarAllAppsController taskbarAllAppsController;
@Nullable private LoggableTaskbarController[] mControllersToLog = null;
@@ -74,7 +75,7 @@
TaskbarAutohideSuspendController taskbarAutoHideSuspendController,
TaskbarPopupController taskbarPopupController,
TaskbarForceVisibleImmersiveController taskbarForceVisibleImmersiveController,
- TaskbarAllAppsViewController taskbarAllAppsViewController) {
+ TaskbarAllAppsController taskbarAllAppsController) {
this.taskbarActivityContext = taskbarActivityContext;
this.taskbarDragController = taskbarDragController;
this.navButtonController = navButtonController;
@@ -91,7 +92,7 @@
this.taskbarAutohideSuspendController = taskbarAutoHideSuspendController;
this.taskbarPopupController = taskbarPopupController;
this.taskbarForceVisibleImmersiveController = taskbarForceVisibleImmersiveController;
- this.taskbarAllAppsViewController = taskbarAllAppsViewController;
+ this.taskbarAllAppsController = taskbarAllAppsController;
}
/**
@@ -115,7 +116,7 @@
taskbarEduController.init(this);
taskbarPopupController.init(this);
taskbarForceVisibleImmersiveController.init(this);
- taskbarAllAppsViewController.init(this);
+ taskbarAllAppsController.init(this);
mControllersToLog = new LoggableTaskbarController[] {
taskbarDragController, navButtonController, navbarButtonsViewController,
diff --git a/quickstep/src/com/android/launcher3/taskbar/TaskbarDragController.java b/quickstep/src/com/android/launcher3/taskbar/TaskbarDragController.java
index 6a2f622..24c5d0e 100644
--- a/quickstep/src/com/android/launcher3/taskbar/TaskbarDragController.java
+++ b/quickstep/src/com/android/launcher3/taskbar/TaskbarDragController.java
@@ -66,8 +66,6 @@
import com.android.launcher3.shortcuts.ShortcutDragPreviewProvider;
import com.android.launcher3.util.LauncherBindableItemsContainer;
import com.android.systemui.shared.recents.model.Task;
-import com.android.systemui.shared.system.ClipDescriptionCompat;
-import com.android.systemui.shared.system.LauncherAppsCompat;
import java.io.PrintWriter;
import java.util.Arrays;
@@ -75,7 +73,7 @@
/**
* Handles long click on Taskbar items to start a system drag and drop operation.
*/
-public class TaskbarDragController extends DragController<TaskbarActivityContext> implements
+public class TaskbarDragController extends DragController<BaseTaskbarContext> implements
TaskbarControllers.LoggableTaskbarController {
private static boolean DEBUG_DRAG_SHADOW_SURFACE = false;
@@ -95,7 +93,7 @@
// Animation for the drag shadow back into position after an unsuccessful drag
private ValueAnimator mReturnAnimator;
- public TaskbarDragController(TaskbarActivityContext activity) {
+ public TaskbarDragController(BaseTaskbarContext activity) {
super(activity);
Resources resources = mActivity.getResources();
mDragIconSize = resources.getDimensionPixelSize(R.dimen.taskbar_icon_drag_icon_size);
@@ -110,7 +108,7 @@
* generate the ClipDescription and Intent.
* @return Whether {@link View#startDragAndDrop} started successfully.
*/
- protected boolean startDragOnLongClick(View view) {
+ public boolean startDragOnLongClick(View view) {
return startDragOnLongClick(view, null, null);
}
@@ -131,8 +129,7 @@
}
BubbleTextView btv = (BubbleTextView) view;
-
- mActivity.setTaskbarWindowFullscreen(true);
+ mActivity.onDragStart();
btv.post(() -> {
DragView dragView = startInternalDrag(btv, dragPreviewProvider);
if (iconShift != null) {
@@ -185,7 +182,7 @@
}
};
if (FeatureFlags.ENABLE_TASKBAR_POPUP_MENU.get()) {
- PopupContainerWithArrow<TaskbarActivityContext> popupContainer =
+ PopupContainerWithArrow<BaseTaskbarContext> popupContainer =
mControllers.taskbarPopupController.showForIcon(btv);
if (popupContainer != null) {
dragOptions.preDragCondition = popupContainer.createPreDragCondition(false);
@@ -315,13 +312,13 @@
clipDescription = new ClipDescription(item.title,
new String[] {
item.itemType == LauncherSettings.Favorites.ITEM_TYPE_DEEP_SHORTCUT
- ? ClipDescriptionCompat.MIMETYPE_APPLICATION_SHORTCUT
- : ClipDescriptionCompat.MIMETYPE_APPLICATION_ACTIVITY
+ ? ClipDescription.MIMETYPE_APPLICATION_SHORTCUT
+ : ClipDescription.MIMETYPE_APPLICATION_ACTIVITY
});
intent = new Intent();
if (item.itemType == LauncherSettings.Favorites.ITEM_TYPE_DEEP_SHORTCUT) {
String deepShortcutId = ((WorkspaceItemInfo) item).getDeepShortcutId();
- intent.putExtra(ClipDescriptionCompat.EXTRA_PENDING_INTENT,
+ intent.putExtra(ClipDescription.EXTRA_PENDING_INTENT,
launcherApps.getShortcutIntent(
item.getIntent().getPackage(),
deepShortcutId,
@@ -330,19 +327,19 @@
intent.putExtra(Intent.EXTRA_PACKAGE_NAME, item.getIntent().getPackage());
intent.putExtra(Intent.EXTRA_SHORTCUT_ID, deepShortcutId);
} else {
- intent.putExtra(ClipDescriptionCompat.EXTRA_PENDING_INTENT,
- LauncherAppsCompat.getMainActivityLaunchIntent(launcherApps,
- item.getIntent().getComponent(), null, item.user));
+ intent.putExtra(ClipDescription.EXTRA_PENDING_INTENT,
+ launcherApps.getMainActivityLaunchIntent(item.getIntent().getComponent(),
+ null, item.user));
}
intent.putExtra(Intent.EXTRA_USER, item.user);
} else if (tag instanceof Task) {
Task task = (Task) tag;
clipDescription = new ClipDescription(task.titleDescription,
new String[] {
- ClipDescriptionCompat.MIMETYPE_APPLICATION_TASK
+ ClipDescription.MIMETYPE_APPLICATION_TASK
});
intent = new Intent();
- intent.putExtra(ClipDescriptionCompat.EXTRA_TASK_ID, task.key.id);
+ intent.putExtra(Intent.EXTRA_TASK_ID, task.key.id);
intent.putExtra(Intent.EXTRA_USER, UserHandle.of(task.key.userId));
}
@@ -394,11 +391,17 @@
return super.isDragging() || mIsSystemDragInProgress;
}
+ /** {@code true} if the system is currently handling the drag. */
+ public boolean isSystemDragInProgress() {
+ return mIsSystemDragInProgress;
+ }
+
private void maybeOnDragEnd() {
if (!isDragging()) {
((BubbleTextView) mDragObject.originalView).getIcon().setIsDisabled(false);
mControllers.taskbarAutohideSuspendController.updateFlag(
TaskbarAutohideSuspendController.FLAG_AUTOHIDE_SUSPEND_DRAGGING, false);
+ mActivity.onDragEnd();
}
}
diff --git a/quickstep/src/com/android/launcher3/taskbar/TaskbarDragLayerController.java b/quickstep/src/com/android/launcher3/taskbar/TaskbarDragLayerController.java
index 1bd76b9..cdac497 100644
--- a/quickstep/src/com/android/launcher3/taskbar/TaskbarDragLayerController.java
+++ b/quickstep/src/com/android/launcher3/taskbar/TaskbarDragLayerController.java
@@ -181,6 +181,9 @@
} else if (!mControllers.uiController.isTaskbarTouchable()) {
// Let touches pass through us.
insetsInfo.setTouchableInsets(TOUCHABLE_INSETS_REGION);
+ } else if (mControllers.taskbarDragController.isSystemDragInProgress()) {
+ // Let touches pass through us.
+ insetsInfo.setTouchableInsets(TOUCHABLE_INSETS_REGION);
} else if (mControllers.taskbarViewController.areIconsVisible()
|| AbstractFloatingView.getOpenView(mActivity, TYPE_ALL) != null
|| mActivity.isNavBarKidsModeActive()) {
@@ -208,9 +211,7 @@
* Called when a child is removed from TaskbarDragLayer.
*/
public void onDragLayerViewRemoved() {
- if (AbstractFloatingView.getAnyView(mActivity, TYPE_ALL) == null) {
- mActivity.setTaskbarWindowFullscreen(false);
- }
+ mActivity.maybeSetTaskbarWindowNotFullscreen();
}
/**
diff --git a/quickstep/src/com/android/launcher3/taskbar/TaskbarDragView.java b/quickstep/src/com/android/launcher3/taskbar/TaskbarDragView.java
index cf28eff..7a42432 100644
--- a/quickstep/src/com/android/launcher3/taskbar/TaskbarDragView.java
+++ b/quickstep/src/com/android/launcher3/taskbar/TaskbarDragView.java
@@ -25,8 +25,8 @@
* while the pre-drag is still in progress (i.e. when the long press popup is still open). After
* that ends, we switch to a system drag and drop view instead.
*/
-public class TaskbarDragView extends DragView<TaskbarActivityContext> {
- public TaskbarDragView(TaskbarActivityContext launcher, Drawable drawable, int registrationX,
+public class TaskbarDragView extends DragView<BaseTaskbarContext> {
+ public TaskbarDragView(BaseTaskbarContext launcher, Drawable drawable, int registrationX,
int registrationY, float initialScale, float scaleOnDrop, float finalScaleDps) {
super(launcher, drawable, registrationX, registrationY, initialScale, scaleOnDrop,
finalScaleDps);
diff --git a/quickstep/src/com/android/launcher3/taskbar/TaskbarForceVisibleImmersiveController.java b/quickstep/src/com/android/launcher3/taskbar/TaskbarForceVisibleImmersiveController.java
index 385090f..c99cebb 100644
--- a/quickstep/src/com/android/launcher3/taskbar/TaskbarForceVisibleImmersiveController.java
+++ b/quickstep/src/com/android/launcher3/taskbar/TaskbarForceVisibleImmersiveController.java
@@ -71,7 +71,7 @@
/** Update values tracked via sysui flags. */
public void updateSysuiFlags(int sysuiFlags) {
mIsImmersiveMode = (sysuiFlags & SYSUI_STATE_IMMERSIVE_MODE) != 0;
- if (mContext.isNavBarKidsModeActive()) {
+ if (mContext.isNavBarForceVisible()) {
if (mIsImmersiveMode) {
startIconDimming();
} else {
@@ -113,7 +113,7 @@
* Returns whether the taskbar is always visible in immersive mode.
*/
private boolean isNavbarShownInImmersiveMode() {
- return mIsImmersiveMode && mContext.isNavBarKidsModeActive();
+ return mIsImmersiveMode && mContext.isNavBarForceVisible();
}
private void updateIconDimmingAlpha() {
diff --git a/quickstep/src/com/android/launcher3/taskbar/TaskbarManager.java b/quickstep/src/com/android/launcher3/taskbar/TaskbarManager.java
index 50be430..0f7abda 100644
--- a/quickstep/src/com/android/launcher3/taskbar/TaskbarManager.java
+++ b/quickstep/src/com/android/launcher3/taskbar/TaskbarManager.java
@@ -236,8 +236,7 @@
DeviceProfile dp =
mUserUnlocked ? LauncherAppState.getIDP(mContext).getDeviceProfile(mContext) : null;
- boolean isTaskBarEnabled =
- FeatureFlags.ENABLE_TASKBAR.get() && dp != null && dp.isTaskbarPresent;
+ boolean isTaskBarEnabled = dp != null && dp.isTaskbarPresent;
if (!isTaskBarEnabled) {
SystemUiProxy.INSTANCE.get(mContext)
diff --git a/quickstep/src/com/android/launcher3/taskbar/TaskbarModelCallbacks.java b/quickstep/src/com/android/launcher3/taskbar/TaskbarModelCallbacks.java
index 2e18a40..62392ee 100644
--- a/quickstep/src/com/android/launcher3/taskbar/TaskbarModelCallbacks.java
+++ b/quickstep/src/com/android/launcher3/taskbar/TaskbarModelCallbacks.java
@@ -158,7 +158,7 @@
mPredictedItems = item.items;
commitItemsToUI();
} else if (item.containerId == Favorites.CONTAINER_PREDICTION) {
- mControllers.taskbarAllAppsViewController.setPredictedApps(item.items);
+ mControllers.taskbarAllAppsController.setPredictedApps(item.items);
}
}
@@ -201,7 +201,7 @@
@Override
public void bindAllApplications(AppInfo[] apps, int flags) {
- mControllers.taskbarAllAppsViewController.setApps(apps, flags);
+ mControllers.taskbarAllAppsController.setApps(apps, flags);
}
protected void dumpLogs(String prefix, PrintWriter pw) {
diff --git a/quickstep/src/com/android/launcher3/taskbar/TaskbarPopupController.java b/quickstep/src/com/android/launcher3/taskbar/TaskbarPopupController.java
index 68459ab..ea4fe34 100644
--- a/quickstep/src/com/android/launcher3/taskbar/TaskbarPopupController.java
+++ b/quickstep/src/com/android/launcher3/taskbar/TaskbarPopupController.java
@@ -52,7 +52,7 @@
*/
public class TaskbarPopupController implements TaskbarControllers.LoggableTaskbarController {
- private static final SystemShortcut.Factory<TaskbarActivityContext>
+ private static final SystemShortcut.Factory<BaseTaskbarContext>
APP_INFO = SystemShortcut.AppInfo::new;
private final TaskbarActivityContext mContext;
@@ -121,8 +121,8 @@
* Shows the notifications and deep shortcuts associated with a Taskbar {@param icon}.
* @return the container if shown or null.
*/
- public PopupContainerWithArrow<TaskbarActivityContext> showForIcon(BubbleTextView icon) {
- TaskbarActivityContext context = ActivityContext.lookupContext(icon.getContext());
+ public PopupContainerWithArrow<BaseTaskbarContext> showForIcon(BubbleTextView icon) {
+ BaseTaskbarContext context = ActivityContext.lookupContext(icon.getContext());
if (PopupContainerWithArrow.getOpen(context) != null) {
// There is already an items container open, so don't open this one.
icon.clearFocus();
@@ -133,11 +133,11 @@
return null;
}
- final PopupContainerWithArrow<TaskbarActivityContext> container =
- (PopupContainerWithArrow) context.getLayoutInflater().inflate(
+ final PopupContainerWithArrow<BaseTaskbarContext> container =
+ (PopupContainerWithArrow<BaseTaskbarContext>) context.getLayoutInflater().inflate(
R.layout.popup_container, context.getDragLayer(), false);
container.addOnAttachStateChangeListener(
- new PopupLiveUpdateHandler<TaskbarActivityContext>(mContext, container) {
+ new PopupLiveUpdateHandler<BaseTaskbarContext>(context, container) {
@Override
protected void showPopupContainerForIcon(BubbleTextView originalIcon) {
showForIcon(originalIcon);
@@ -157,10 +157,9 @@
container.requestFocus();
// Make focusable to receive back events
- mControllers.taskbarActivityContext.setTaskbarWindowFocusable(true);
+ context.onPopupVisibilityChanged(true);
container.setOnCloseCallback(() -> {
- mControllers.taskbarActivityContext.getDragLayer().post(
- () -> mControllers.taskbarActivityContext.setTaskbarWindowFocusable(false));
+ context.getDragLayer().post(() -> context.onPopupVisibilityChanged(false));
container.setOnCloseCallback(null);
});
@@ -207,7 +206,8 @@
iconShift.x = mIconLastTouchPos.x - sv.getIconCenter().x;
iconShift.y = mIconLastTouchPos.y - mContext.getDeviceProfile().iconSizePx;
- mControllers.taskbarDragController.startDragOnLongClick(sv, iconShift);
+ ((TaskbarDragController) ActivityContext.lookupContext(
+ v.getContext()).getDragController()).startDragOnLongClick(sv, iconShift);
return false;
}
diff --git a/quickstep/src/com/android/launcher3/taskbar/TaskbarShortcutMenuAccessibilityDelegate.java b/quickstep/src/com/android/launcher3/taskbar/TaskbarShortcutMenuAccessibilityDelegate.java
index 1589582..f131595 100644
--- a/quickstep/src/com/android/launcher3/taskbar/TaskbarShortcutMenuAccessibilityDelegate.java
+++ b/quickstep/src/com/android/launcher3/taskbar/TaskbarShortcutMenuAccessibilityDelegate.java
@@ -35,7 +35,6 @@
import com.android.launcher3.notification.NotificationListener;
import com.android.launcher3.util.ShortcutUtil;
import com.android.quickstep.SystemUiProxy;
-import com.android.systemui.shared.system.LauncherAppsCompat;
import java.util.List;
@@ -94,8 +93,7 @@
info.user);
} else {
SystemUiProxy.INSTANCE.get(mContext).startIntent(
- LauncherAppsCompat.getMainActivityLaunchIntent(
- mLauncherApps,
+ mLauncherApps.getMainActivityLaunchIntent(
item.getIntent().getComponent(),
/* startActivityOptions= */null,
item.user),
diff --git a/quickstep/src/com/android/launcher3/taskbar/TaskbarStashController.java b/quickstep/src/com/android/launcher3/taskbar/TaskbarStashController.java
index 335b637..6bc4c0a 100644
--- a/quickstep/src/com/android/launcher3/taskbar/TaskbarStashController.java
+++ b/quickstep/src/com/android/launcher3/taskbar/TaskbarStashController.java
@@ -29,10 +29,12 @@
import android.content.SharedPreferences;
import android.view.ViewConfiguration;
+import com.android.launcher3.DeviceProfile;
import com.android.launcher3.Utilities;
import com.android.launcher3.util.MultiValueAlpha.AlphaProperty;
import com.android.quickstep.AnimatedFloat;
import com.android.quickstep.SystemUiProxy;
+import com.android.systemui.shared.system.WindowManagerWrapper;
import java.io.PrintWriter;
import java.util.StringJoiner;
@@ -51,23 +53,25 @@
public static final int FLAG_STASHED_IN_APP_SETUP = 1 << 4; // setup wizard and AllSetActivity
public static final int FLAG_STASHED_IN_APP_IME = 1 << 5; // IME is visible
public static final int FLAG_IN_STASHED_LAUNCHER_STATE = 1 << 6;
+ public static final int FLAG_STASHED_IN_APP_ALL_APPS = 1 << 7; // All apps is visible.
// If we're in an app and any of these flags are enabled, taskbar should be stashed.
private static final int FLAGS_STASHED_IN_APP = FLAG_STASHED_IN_APP_MANUAL
| FLAG_STASHED_IN_APP_PINNED | FLAG_STASHED_IN_APP_EMPTY | FLAG_STASHED_IN_APP_SETUP
- | FLAG_STASHED_IN_APP_IME;
+ | FLAG_STASHED_IN_APP_IME | FLAG_STASHED_IN_APP_ALL_APPS;
// If any of these flags are enabled, inset apps by our stashed height instead of our unstashed
// height. This way the reported insets are consistent even during transitions out of the app.
- // Currently any flag that causes us to stash in an app is included, except for IME since that
- // covers the underlying app anyway and thus the app shouldn't change insets.
+ // Currently any flag that causes us to stash in an app is included, except for IME or All Apps
+ // since those cover the underlying app anyway and thus the app shouldn't change insets.
private static final int FLAGS_REPORT_STASHED_INSETS_TO_APP = FLAGS_STASHED_IN_APP
- & ~FLAG_STASHED_IN_APP_IME;
+ & ~FLAG_STASHED_IN_APP_IME & ~FLAG_STASHED_IN_APP_ALL_APPS;
/**
* How long to stash/unstash when manually invoked via long press.
*/
- public static final long TASKBAR_STASH_DURATION = 300;
+ public static final long TASKBAR_STASH_DURATION =
+ WindowManagerWrapper.ANIMATION_DURATION_RESIZE;
/**
* How long to stash/unstash when keyboard is appearing/disappearing.
@@ -186,7 +190,7 @@
* Returns whether the taskbar can visually stash into a handle based on the current device
* state.
*/
- private boolean supportsVisualStashing() {
+ public boolean supportsVisualStashing() {
return !mActivity.isThreeButtonNav();
}
@@ -253,7 +257,14 @@
* Returns the height that taskbar will inset when inside apps.
*/
public int getContentHeightToReportToApps() {
- if (hasAnyFlag(FLAGS_REPORT_STASHED_INSETS_TO_APP)) {
+ if (supportsVisualStashing() && hasAnyFlag(FLAGS_REPORT_STASHED_INSETS_TO_APP)) {
+ DeviceProfile dp = mActivity.getDeviceProfile();
+ if (hasAnyFlag(FLAG_STASHED_IN_APP_SETUP) && dp.isTaskbarPresent && !dp.isLandscape) {
+ // We always show the back button in SUW but in portrait the SUW layout may not
+ // be wide enough to support overlapping the nav bar with its content. For now,
+ // just inset by the bar height.
+ return mUnstashedHeight;
+ }
boolean isAnimating = mAnimator != null && mAnimator.isStarted();
return mControllers.stashedHandleViewController.isStashedHandleVisible() || isAnimating
? mStashedHeight : 0;
@@ -585,6 +596,7 @@
str.add((flags & FLAG_STASHED_IN_APP_IME) != 0 ? "FLAG_STASHED_IN_APP_IME" : "");
str.add((flags & FLAG_IN_STASHED_LAUNCHER_STATE) != 0
? "FLAG_IN_STASHED_LAUNCHER_STATE" : "");
+ str.add((flags & FLAG_STASHED_IN_APP_ALL_APPS) != 0 ? "FLAG_STASHED_IN_APP_ALL_APPS" : "");
return str.toString();
}
diff --git a/quickstep/src/com/android/launcher3/taskbar/TaskbarViewController.java b/quickstep/src/com/android/launcher3/taskbar/TaskbarViewController.java
index 8b6831b..153ed14 100644
--- a/quickstep/src/com/android/launcher3/taskbar/TaskbarViewController.java
+++ b/quickstep/src/com/android/launcher3/taskbar/TaskbarViewController.java
@@ -306,7 +306,7 @@
}
public View.OnClickListener getAllAppsButtonClickListener() {
- return v -> mControllers.taskbarAllAppsViewController.show();
+ return v -> mControllers.taskbarAllAppsController.show();
}
public View.OnLongClickListener getIconOnLongClickListener() {
diff --git a/quickstep/src/com/android/launcher3/taskbar/TaskbarAllAppsContainerView.java b/quickstep/src/com/android/launcher3/taskbar/allapps/TaskbarAllAppsContainerView.java
similarity index 83%
rename from quickstep/src/com/android/launcher3/taskbar/TaskbarAllAppsContainerView.java
rename to quickstep/src/com/android/launcher3/taskbar/allapps/TaskbarAllAppsContainerView.java
index d6eb716..b36b9f1 100644
--- a/quickstep/src/com/android/launcher3/taskbar/TaskbarAllAppsContainerView.java
+++ b/quickstep/src/com/android/launcher3/taskbar/allapps/TaskbarAllAppsContainerView.java
@@ -13,7 +13,7 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
-package com.android.launcher3.taskbar;
+package com.android.launcher3.taskbar.allapps;
import android.content.Context;
import android.util.AttributeSet;
@@ -29,10 +29,7 @@
import com.android.launcher3.allapps.search.SearchAdapterProvider;
/** All apps container accessible from taskbar. */
-public class TaskbarAllAppsContainerView extends BaseAllAppsContainerView<TaskbarActivityContext> {
- public TaskbarAllAppsContainerView(Context context) {
- this(context, null);
- }
+public class TaskbarAllAppsContainerView extends BaseAllAppsContainerView<TaskbarAllAppsContext> {
public TaskbarAllAppsContainerView(Context context, AttributeSet attrs) {
this(context, attrs, 0);
@@ -44,8 +41,8 @@
@Override
protected SearchAdapterProvider<?> createMainAdapterProvider() {
- // Task bar all apps does not yet support search, so this implementation is minimal.
- return new SearchAdapterProvider<TaskbarActivityContext>(mActivityContext) {
+ // Taskbar all apps does not yet support search, so this implementation is minimal.
+ return new SearchAdapterProvider<TaskbarAllAppsContext>(mActivityContext) {
@Override
public boolean launchHighlightedItem() {
return false;
@@ -79,8 +76,7 @@
@Override
public WindowInsets onApplyWindowInsets(WindowInsets insets) {
- // TODO(b/204696617): Switch to status bar insets once they work.
- setInsets(insets.getInsets(WindowInsets.Type.tappableElement()).toRect());
+ setInsets(insets.getInsets(WindowInsets.Type.systemBars()).toRect());
return super.onApplyWindowInsets(insets);
}
}
diff --git a/quickstep/src/com/android/launcher3/taskbar/allapps/TaskbarAllAppsContext.java b/quickstep/src/com/android/launcher3/taskbar/allapps/TaskbarAllAppsContext.java
new file mode 100644
index 0000000..a67ca70
--- /dev/null
+++ b/quickstep/src/com/android/launcher3/taskbar/allapps/TaskbarAllAppsContext.java
@@ -0,0 +1,234 @@
+/*
+ * 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.taskbar.allapps;
+
+import static android.view.KeyEvent.ACTION_UP;
+import static android.view.KeyEvent.KEYCODE_BACK;
+import static android.view.WindowManager.LayoutParams.TYPE_APPLICATION_OVERLAY;
+
+import static com.android.systemui.shared.system.ViewTreeObserverWrapper.InsetsInfo.TOUCHABLE_INSETS_REGION;
+
+import android.content.Context;
+import android.graphics.Insets;
+import android.view.KeyEvent;
+import android.view.View;
+import android.view.WindowInsets;
+
+import com.android.launcher3.AbstractFloatingView;
+import com.android.launcher3.DeviceProfile;
+import com.android.launcher3.R;
+import com.android.launcher3.Utilities;
+import com.android.launcher3.dot.DotInfo;
+import com.android.launcher3.model.data.ItemInfo;
+import com.android.launcher3.popup.PopupDataProvider;
+import com.android.launcher3.taskbar.BaseTaskbarContext;
+import com.android.launcher3.taskbar.TaskbarActivityContext;
+import com.android.launcher3.taskbar.TaskbarDragController;
+import com.android.launcher3.taskbar.TaskbarStashController;
+import com.android.launcher3.util.OnboardingPrefs;
+import com.android.launcher3.util.TouchController;
+import com.android.launcher3.views.BaseDragLayer;
+import com.android.systemui.shared.system.ViewTreeObserverWrapper;
+import com.android.systemui.shared.system.ViewTreeObserverWrapper.InsetsInfo;
+import com.android.systemui.shared.system.ViewTreeObserverWrapper.OnComputeInsetsListener;
+
+/**
+ * Window context for the taskbar all apps overlay.
+ * <p>
+ * All apps has its own window and needs a window context. Some properties are delegated to the
+ * {@link TaskbarActivityContext} such as {@link DeviceProfile} and {@link PopupDataProvider}.
+ */
+class TaskbarAllAppsContext extends BaseTaskbarContext {
+ private final TaskbarActivityContext mTaskbarContext;
+ private final OnboardingPrefs<TaskbarAllAppsContext> mOnboardingPrefs;
+
+ private final TaskbarAllAppsController mWindowController;
+ private final TaskbarAllAppsViewController mAllAppsViewController;
+ private final TaskbarDragController mDragController;
+ private final TaskbarAllAppsDragLayer mDragLayer;
+ private final TaskbarAllAppsContainerView mAppsView;
+
+ // We automatically stash taskbar when all apps is opened in gesture navigation mode.
+ private final boolean mWillTaskbarBeVisuallyStashed;
+ private final int mStashedTaskbarHeight;
+
+ TaskbarAllAppsContext(
+ TaskbarActivityContext taskbarContext,
+ TaskbarAllAppsController windowController,
+ TaskbarStashController taskbarStashController) {
+ super(taskbarContext.createWindowContext(TYPE_APPLICATION_OVERLAY, null));
+ mTaskbarContext = taskbarContext;
+ mDeviceProfile = taskbarContext.getDeviceProfile();
+ mDragController = new TaskbarDragController(this);
+ mOnboardingPrefs = new OnboardingPrefs<>(this, Utilities.getPrefs(this));
+
+ mDragLayer = new TaskbarAllAppsDragLayer(this);
+ TaskbarAllAppsSlideInView slideInView = (TaskbarAllAppsSlideInView) mLayoutInflater.inflate(
+ R.layout.taskbar_all_apps, mDragLayer, false);
+ mWindowController = windowController;
+ mAllAppsViewController = new TaskbarAllAppsViewController(
+ this,
+ slideInView,
+ windowController,
+ taskbarStashController);
+ mAppsView = slideInView.getAppsView();
+
+ mWillTaskbarBeVisuallyStashed = taskbarStashController.supportsVisualStashing();
+ mStashedTaskbarHeight = taskbarStashController.getStashedHeight();
+ }
+
+ TaskbarAllAppsViewController getAllAppsViewController() {
+ return mAllAppsViewController;
+ }
+
+ @Override
+ public TaskbarDragController getDragController() {
+ return mDragController;
+ }
+
+ @Override
+ public TaskbarAllAppsDragLayer getDragLayer() {
+ return mDragLayer;
+ }
+
+ @Override
+ public TaskbarAllAppsContainerView getAppsView() {
+ return mAppsView;
+ }
+
+ @Override
+ public OnboardingPrefs<TaskbarAllAppsContext> getOnboardingPrefs() {
+ return mOnboardingPrefs;
+ }
+
+ @Override
+ public boolean isBindingItems() {
+ return mTaskbarContext.isBindingItems();
+ }
+
+ @Override
+ public View.OnClickListener getItemOnClickListener() {
+ return mTaskbarContext.getItemOnClickListener();
+ }
+
+ @Override
+ public PopupDataProvider getPopupDataProvider() {
+ return mTaskbarContext.getPopupDataProvider();
+ }
+
+ @Override
+ public DotInfo getDotInfoForItem(ItemInfo info) {
+ return mTaskbarContext.getDotInfoForItem(info);
+ }
+
+ @Override
+ public void updateDeviceProfile(DeviceProfile dp) {
+ mDeviceProfile = dp;
+ dispatchDeviceProfileChanged();
+ }
+
+ @Override
+ public void onDragStart() {}
+
+ @Override
+ public void onDragEnd() {
+ mWindowController.maybeCloseWindow();
+ }
+
+ @Override
+ public void onPopupVisibilityChanged(boolean isVisible) {}
+
+ /** Root drag layer for this context. */
+ private static class TaskbarAllAppsDragLayer extends
+ BaseDragLayer<TaskbarAllAppsContext> implements OnComputeInsetsListener {
+
+ private TaskbarAllAppsDragLayer(Context context) {
+ super(context, null, 1);
+ setClipChildren(false);
+ recreateControllers();
+ }
+
+ @Override
+ protected void onAttachedToWindow() {
+ super.onAttachedToWindow();
+ ViewTreeObserverWrapper.addOnComputeInsetsListener(
+ getViewTreeObserver(), this);
+ mActivity.mAllAppsViewController.show();
+ }
+
+ @Override
+ protected void onDetachedFromWindow() {
+ super.onDetachedFromWindow();
+ ViewTreeObserverWrapper.removeOnComputeInsetsListener(this);
+ }
+
+ @Override
+ public void recreateControllers() {
+ mControllers = new TouchController[]{mActivity.mDragController};
+ }
+
+ @Override
+ public boolean dispatchKeyEvent(KeyEvent event) {
+ if (event.getAction() == ACTION_UP && event.getKeyCode() == KEYCODE_BACK) {
+ AbstractFloatingView topView = AbstractFloatingView.getTopOpenView(mActivity);
+ if (topView != null && topView.onBackPressed()) {
+ return true;
+ }
+ }
+ return super.dispatchKeyEvent(event);
+ }
+
+ @Override
+ public void onComputeInsets(InsetsInfo inoutInfo) {
+ if (mActivity.mDragController.isSystemDragInProgress()) {
+ inoutInfo.touchableRegion.setEmpty();
+ inoutInfo.setTouchableInsets(TOUCHABLE_INSETS_REGION);
+ }
+ }
+
+ @Override
+ public WindowInsets onApplyWindowInsets(WindowInsets insets) {
+ return updateInsetsDueToStashing(insets);
+ }
+
+ /**
+ * Taskbar automatically stashes when opening all apps, but we don't report the insets as
+ * changing to avoid moving the underlying app. But internally, the apps view should still
+ * layout according to the stashed insets rather than the unstashed insets. So this method
+ * does two things:
+ * 1) Sets navigationBars bottom inset to stashedHeight.
+ * 2) Sets tappableInsets bottom inset to 0.
+ */
+ private WindowInsets updateInsetsDueToStashing(WindowInsets oldInsets) {
+ if (!mActivity.mWillTaskbarBeVisuallyStashed) {
+ return oldInsets;
+ }
+ WindowInsets.Builder updatedInsetsBuilder = new WindowInsets.Builder(oldInsets);
+
+ Insets oldNavInsets = oldInsets.getInsets(WindowInsets.Type.navigationBars());
+ Insets newNavInsets = Insets.of(oldNavInsets.left, oldNavInsets.top, oldNavInsets.right,
+ mActivity.mStashedTaskbarHeight);
+ updatedInsetsBuilder.setInsets(WindowInsets.Type.navigationBars(), newNavInsets);
+
+ Insets oldTappableInsets = oldInsets.getInsets(WindowInsets.Type.tappableElement());
+ Insets newTappableInsets = Insets.of(oldTappableInsets.left, oldTappableInsets.top,
+ oldTappableInsets.right, 0);
+ updatedInsetsBuilder.setInsets(WindowInsets.Type.tappableElement(), newTappableInsets);
+
+ return updatedInsetsBuilder.build();
+ }
+ }
+}
diff --git a/quickstep/src/com/android/launcher3/taskbar/allapps/TaskbarAllAppsController.java b/quickstep/src/com/android/launcher3/taskbar/allapps/TaskbarAllAppsController.java
new file mode 100644
index 0000000..321ff79
--- /dev/null
+++ b/quickstep/src/com/android/launcher3/taskbar/allapps/TaskbarAllAppsController.java
@@ -0,0 +1,208 @@
+/*
+ * 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.taskbar.allapps;
+
+import static android.view.WindowManager.LayoutParams.LAYOUT_IN_DISPLAY_CUTOUT_MODE_ALWAYS;
+import static android.view.WindowManager.LayoutParams.TYPE_APPLICATION_OVERLAY;
+
+import static com.android.launcher3.AbstractFloatingView.TYPE_ALL;
+
+import android.content.Context;
+import android.graphics.PixelFormat;
+import android.view.Gravity;
+import android.view.MotionEvent;
+import android.view.WindowManager;
+import android.view.WindowManager.LayoutParams;
+
+import androidx.annotation.Nullable;
+
+import com.android.launcher3.AbstractFloatingView;
+import com.android.launcher3.DeviceProfile;
+import com.android.launcher3.DeviceProfile.OnDeviceProfileChangeListener;
+import com.android.launcher3.appprediction.PredictionRowView;
+import com.android.launcher3.config.FeatureFlags;
+import com.android.launcher3.model.data.AppInfo;
+import com.android.launcher3.model.data.ItemInfo;
+import com.android.launcher3.taskbar.TaskbarActivityContext;
+import com.android.launcher3.taskbar.TaskbarControllers;
+
+import java.util.List;
+import java.util.Optional;
+
+/**
+ * Handles the all apps overlay window initialization, updates, and its data.
+ * <p>
+ * All apps is in an application overlay window instead of taskbar's navigation bar panel window,
+ * because a navigation bar panel is higher than UI components that all apps should be below such as
+ * the notification tray.
+ * <p>
+ * The all apps window is created and destroyed upon opening and closing all apps, respectively.
+ * Application data may be bound while the window does not exist, so this controller will store
+ * the models for the next all apps session.
+ */
+public final class TaskbarAllAppsController implements OnDeviceProfileChangeListener {
+
+ private static final String WINDOW_TITLE = "Taskbar All Apps";
+
+ private final TaskbarActivityContext mTaskbarContext;
+ private final TaskbarAllAppsProxyView mProxyView;
+ private final LayoutParams mLayoutParams;
+
+ private TaskbarControllers mControllers;
+ /** Window context for all apps if it is open. */
+ private @Nullable TaskbarAllAppsContext mAllAppsContext;
+
+ // Application data models.
+ private AppInfo[] mApps;
+ private int mAppsModelFlags;
+ private List<ItemInfo> mPredictedApps;
+
+ public TaskbarAllAppsController(TaskbarActivityContext context) {
+ mTaskbarContext = context;
+ mProxyView = new TaskbarAllAppsProxyView(mTaskbarContext);
+ mLayoutParams = createLayoutParams();
+ }
+
+ /** Initialize the controller. */
+ public void init(TaskbarControllers controllers) {
+ if (FeatureFlags.ENABLE_ALL_APPS_IN_TASKBAR.get()) {
+ mControllers = controllers;
+ }
+ }
+
+ /** Updates the current {@link AppInfo} instances. */
+ public void setApps(AppInfo[] apps, int flags) {
+ if (!FeatureFlags.ENABLE_ALL_APPS_IN_TASKBAR.get()) {
+ return;
+ }
+
+ mApps = apps;
+ mAppsModelFlags = flags;
+ if (mAllAppsContext != null) {
+ mAllAppsContext.getAppsView().getAppsStore().setApps(mApps, mAppsModelFlags);
+ }
+ }
+
+ /** Updates the current predictions. */
+ public void setPredictedApps(List<ItemInfo> predictedApps) {
+ if (!FeatureFlags.ENABLE_ALL_APPS_IN_TASKBAR.get()) {
+ return;
+ }
+
+ mPredictedApps = predictedApps;
+ if (mAllAppsContext != null) {
+ mAllAppsContext.getAppsView().getFloatingHeaderView()
+ .findFixedRowByType(PredictionRowView.class)
+ .setPredictedApps(mPredictedApps);
+ }
+ }
+
+ /** Opens the {@link TaskbarAllAppsContainerView} in a new window. */
+ public void show() {
+ if (mProxyView.isOpen()) {
+ return;
+ }
+ mProxyView.show();
+
+ mAllAppsContext = new TaskbarAllAppsContext(mTaskbarContext,
+ this,
+ mControllers.taskbarStashController);
+ mAllAppsContext.getDragController().init(mControllers);
+ mTaskbarContext.addOnDeviceProfileChangeListener(this);
+ Optional.ofNullable(mAllAppsContext.getSystemService(WindowManager.class))
+ .ifPresent(m -> m.addView(mAllAppsContext.getDragLayer(), mLayoutParams));
+
+ mAllAppsContext.getAppsView().getAppsStore().setApps(mApps, mAppsModelFlags);
+ mAllAppsContext.getAppsView().getFloatingHeaderView()
+ .findFixedRowByType(PredictionRowView.class)
+ .setPredictedApps(mPredictedApps);
+ }
+
+ /**
+ * Removes the all apps window from the hierarchy, if all floating views are closed and there is
+ * no system drag operation in progress.
+ * <p>
+ * This method should be called after an exit animation finishes, if applicable.
+ */
+ void maybeCloseWindow() {
+ if (AbstractFloatingView.getOpenView(mAllAppsContext, TYPE_ALL) != null
+ || mAllAppsContext.getDragController().isSystemDragInProgress()) {
+ return;
+ }
+ mProxyView.close(false);
+ mTaskbarContext.removeOnDeviceProfileChangeListener(this);
+ Optional.ofNullable(mAllAppsContext)
+ .map(c -> c.getSystemService(WindowManager.class))
+ .ifPresent(m -> m.removeView(mAllAppsContext.getDragLayer()));
+ mAllAppsContext = null;
+ }
+
+ private LayoutParams createLayoutParams() {
+ LayoutParams layoutParams = new LayoutParams(
+ TYPE_APPLICATION_OVERLAY,
+ 0,
+ PixelFormat.TRANSLUCENT);
+ layoutParams.setTitle(WINDOW_TITLE);
+ layoutParams.gravity = Gravity.BOTTOM;
+ layoutParams.packageName = mTaskbarContext.getPackageName();
+ layoutParams.setFitInsetsTypes(0); // Handled by container view.
+ layoutParams.layoutInDisplayCutoutMode = LAYOUT_IN_DISPLAY_CUTOUT_MODE_ALWAYS;
+ layoutParams.setSystemApplicationOverlay(true);
+ return layoutParams;
+ }
+
+ @Override
+ public void onDeviceProfileChanged(DeviceProfile dp) {
+ Optional.ofNullable(mAllAppsContext).ifPresent(c -> c.updateDeviceProfile(dp));
+ }
+
+ /**
+ * Proxy view connecting taskbar drag layer to the all apps window.
+ * <p>
+ * The all apps view is in a separate window and has its own drag layer, but this proxy lets it
+ * behave as though its in the taskbar drag layer. For instance, when the taskbar closes all
+ * {@link AbstractFloatingView} instances, the all apps window will also close.
+ */
+ private class TaskbarAllAppsProxyView extends AbstractFloatingView {
+
+ private TaskbarAllAppsProxyView(Context context) {
+ super(context, null);
+ }
+
+ private void show() {
+ mIsOpen = true;
+ mTaskbarContext.getDragLayer().addView(this);
+ }
+
+ @Override
+ protected void handleClose(boolean animate) {
+ mTaskbarContext.getDragLayer().removeView(this);
+ Optional.ofNullable(mAllAppsContext)
+ .map(TaskbarAllAppsContext::getAllAppsViewController)
+ .ifPresent(v -> v.close(animate));
+ }
+
+ @Override
+ protected boolean isOfType(int type) {
+ return (type & TYPE_TASKBAR_ALL_APPS) != 0;
+ }
+
+ @Override
+ public boolean onControllerInterceptTouchEvent(MotionEvent ev) {
+ return false;
+ }
+ }
+}
diff --git a/quickstep/src/com/android/launcher3/taskbar/TaskbarAllAppsSlideInView.java b/quickstep/src/com/android/launcher3/taskbar/allapps/TaskbarAllAppsSlideInView.java
similarity index 61%
rename from quickstep/src/com/android/launcher3/taskbar/TaskbarAllAppsSlideInView.java
rename to quickstep/src/com/android/launcher3/taskbar/allapps/TaskbarAllAppsSlideInView.java
index 63690c4..02aa3f2 100644
--- a/quickstep/src/com/android/launcher3/taskbar/TaskbarAllAppsSlideInView.java
+++ b/quickstep/src/com/android/launcher3/taskbar/allapps/TaskbarAllAppsSlideInView.java
@@ -13,7 +13,7 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
-package com.android.launcher3.taskbar;
+package com.android.launcher3.taskbar.allapps;
import static com.android.launcher3.anim.Interpolators.AGGRESSIVE_EASE;
@@ -23,18 +23,22 @@
import android.util.AttributeSet;
import android.view.MotionEvent;
+import com.android.launcher3.DeviceProfile;
import com.android.launcher3.Insettable;
import com.android.launcher3.R;
import com.android.launcher3.views.AbstractSlideInView;
-/** Wrapper for taskbar all apps with slide-in behavior. */
-public class TaskbarAllAppsSlideInView extends
- AbstractSlideInView<TaskbarActivityContext> implements Insettable {
+import java.util.Optional;
- private static final int DEFAULT_OPEN_DURATION = 500;
- private static final int DEFAULT_CLOSE_DURATION = 200;
+/** Wrapper for taskbar all apps with slide-in behavior. */
+public class TaskbarAllAppsSlideInView extends AbstractSlideInView<TaskbarAllAppsContext>
+ implements Insettable, DeviceProfile.OnDeviceProfileChangeListener {
+ static final int DEFAULT_OPEN_DURATION = 500;
+ static final int DEFAULT_CLOSE_DURATION = 200;
private TaskbarAllAppsContainerView mAppsView;
+ private OnCloseListener mOnCloseBeginListener;
+ private float mShiftRange;
public TaskbarAllAppsSlideInView(Context context, AttributeSet attrs) {
this(context, attrs, 0);
@@ -46,7 +50,7 @@
}
/** Opens the all apps view. */
- public void show() {
+ void show() {
if (mIsOpen || mOpenCloseAnimator.isRunning()) {
return;
}
@@ -60,12 +64,18 @@
}
/** The apps container inside this view. */
- public TaskbarAllAppsContainerView getAppsView() {
+ TaskbarAllAppsContainerView getAppsView() {
return mAppsView;
}
+ /** Callback invoked when the view is beginning to close (e.g. close animation is started). */
+ void setOnCloseBeginListener(OnCloseListener onCloseBeginListener) {
+ mOnCloseBeginListener = onCloseBeginListener;
+ }
+
@Override
protected void handleClose(boolean animate) {
+ Optional.ofNullable(mOnCloseBeginListener).ifPresent(OnCloseListener::onSlideInViewClosed);
handleClose(animate, DEFAULT_CLOSE_DURATION);
}
@@ -79,6 +89,17 @@
super.onFinishInflate();
mAppsView = findViewById(R.id.apps_view);
mContent = mAppsView;
+
+ DeviceProfile dp = mActivityContext.getDeviceProfile();
+ setShiftRange(dp.allAppsShiftRange);
+
+ mActivityContext.addOnDeviceProfileChangeListener(this);
+ }
+
+ @Override
+ protected void onLayout(boolean changed, int l, int t, int r, int b) {
+ super.onLayout(changed, l, t, r, b);
+ setTranslationShift(mTranslationShift);
}
@Override
@@ -98,4 +119,24 @@
public void setInsets(Rect insets) {
mAppsView.setInsets(insets);
}
+
+ @Override
+ public void onDeviceProfileChanged(DeviceProfile dp) {
+ setShiftRange(dp.allAppsShiftRange);
+ setTranslationShift(TRANSLATION_SHIFT_OPENED);
+ }
+
+ private void setShiftRange(float shiftRange) {
+ mShiftRange = shiftRange;
+ }
+
+ @Override
+ protected float getShiftRange() {
+ return mShiftRange;
+ }
+
+ @Override
+ protected boolean isEventOverContent(MotionEvent ev) {
+ return getPopupContainer().isEventOverView(mAppsView.getVisibleContainerView(), ev);
+ }
}
diff --git a/quickstep/src/com/android/launcher3/taskbar/allapps/TaskbarAllAppsViewController.java b/quickstep/src/com/android/launcher3/taskbar/allapps/TaskbarAllAppsViewController.java
new file mode 100644
index 0000000..648c486
--- /dev/null
+++ b/quickstep/src/com/android/launcher3/taskbar/allapps/TaskbarAllAppsViewController.java
@@ -0,0 +1,91 @@
+/*
+ * 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.taskbar.allapps;
+
+import static com.android.launcher3.taskbar.TaskbarStashController.FLAG_STASHED_IN_APP_ALL_APPS;
+import static com.android.launcher3.taskbar.allapps.TaskbarAllAppsSlideInView.DEFAULT_CLOSE_DURATION;
+import static com.android.launcher3.taskbar.allapps.TaskbarAllAppsSlideInView.DEFAULT_OPEN_DURATION;
+import static com.android.launcher3.util.OnboardingPrefs.ALL_APPS_VISITED_COUNT;
+
+import com.android.launcher3.appprediction.AppsDividerView;
+import com.android.launcher3.appprediction.PredictionRowView;
+import com.android.launcher3.taskbar.TaskbarStashController;
+
+/**
+ * Handles the {@link TaskbarAllAppsContainerView} behavior and synchronizes its transitions with
+ * taskbar stashing.
+ */
+final class TaskbarAllAppsViewController {
+
+ private final TaskbarAllAppsContext mContext;
+ private final TaskbarAllAppsSlideInView mSlideInView;
+ private final TaskbarAllAppsContainerView mAppsView;
+ private final TaskbarStashController mTaskbarStashController;
+
+ TaskbarAllAppsViewController(
+ TaskbarAllAppsContext context,
+ TaskbarAllAppsSlideInView slideInView,
+ TaskbarAllAppsController windowController,
+ TaskbarStashController taskbarStashController) {
+
+ mContext = context;
+ mSlideInView = slideInView;
+ mAppsView = mSlideInView.getAppsView();
+ mTaskbarStashController = taskbarStashController;
+
+ setUpIconLongClick();
+ setUpAppDivider();
+ setUpTaskbarStashing();
+ mSlideInView.addOnCloseListener(windowController::maybeCloseWindow);
+ }
+
+ /** Starts the {@link TaskbarAllAppsSlideInView} enter transition. */
+ void show() {
+ mSlideInView.show();
+ }
+
+ /** Closes the {@link TaskbarAllAppsSlideInView}. */
+ void close(boolean animate) {
+ mSlideInView.close(animate);
+ }
+
+ private void setUpIconLongClick() {
+ mAppsView.setOnIconLongClickListener(
+ mContext.getDragController()::startDragOnLongClick);
+ mAppsView.getFloatingHeaderView()
+ .findFixedRowByType(PredictionRowView.class)
+ .setOnIconLongClickListener(
+ mContext.getDragController()::startDragOnLongClick);
+ }
+
+ private void setUpAppDivider() {
+ mAppsView.getFloatingHeaderView()
+ .findFixedRowByType(AppsDividerView.class)
+ .setShowAllAppsLabel(!mContext.getOnboardingPrefs().hasReachedMaxCount(
+ ALL_APPS_VISITED_COUNT));
+ mContext.getOnboardingPrefs().incrementEventCount(ALL_APPS_VISITED_COUNT);
+ }
+
+ private void setUpTaskbarStashing() {
+ mTaskbarStashController.updateStateForFlag(FLAG_STASHED_IN_APP_ALL_APPS, true);
+ mTaskbarStashController.applyState(DEFAULT_OPEN_DURATION);
+ mSlideInView.setOnCloseBeginListener(() -> {
+ mTaskbarStashController.updateStateForFlag(
+ FLAG_STASHED_IN_APP_ALL_APPS, false);
+ mTaskbarStashController.applyState(DEFAULT_CLOSE_DURATION);
+ });
+ }
+}
diff --git a/quickstep/src/com/android/launcher3/uioverrides/QuickstepInteractionHandler.java b/quickstep/src/com/android/launcher3/uioverrides/QuickstepInteractionHandler.java
index c058aa7..08d147f 100644
--- a/quickstep/src/com/android/launcher3/uioverrides/QuickstepInteractionHandler.java
+++ b/quickstep/src/com/android/launcher3/uioverrides/QuickstepInteractionHandler.java
@@ -21,6 +21,7 @@
import android.app.ActivityTaskManager;
import android.app.PendingIntent;
import android.content.Intent;
+import android.os.IBinder;
import android.os.RemoteException;
import android.util.Log;
import android.util.Pair;
@@ -58,6 +59,12 @@
Pair<Intent, ActivityOptions> options = remoteResponse.getLaunchOptions(view);
ActivityOptionsWrapper activityOptions = mLauncher.getAppTransitionManager()
.getActivityLaunchOptions(hostView);
+ Object itemInfo = hostView.getTag();
+ IBinder launchCookie = null;
+ if (itemInfo instanceof ItemInfo) {
+ launchCookie = mLauncher.getLaunchCookie((ItemInfo) itemInfo);
+ activityOptions.options.setLaunchCookie(launchCookie);
+ }
if (Utilities.ATLEAST_S && !pendingIntent.isActivity()) {
// In the event this pending intent eventually launches an activity, i.e. a trampoline,
// use the Quickstep transition animation.
@@ -65,17 +72,14 @@
ActivityTaskManager.getService()
.registerRemoteAnimationForNextActivityStart(
pendingIntent.getCreatorPackage(),
- activityOptions.options.getRemoteAnimationAdapter());
+ activityOptions.options.getRemoteAnimationAdapter(),
+ launchCookie);
} catch (RemoteException e) {
// Do nothing.
}
}
activityOptions.options.setPendingIntentLaunchFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
- activityOptions.options.setSplashScreenStyle(SplashScreen.SPLASH_SCREEN_STYLE_EMPTY);
- Object itemInfo = hostView.getTag();
- if (itemInfo instanceof ItemInfo) {
- mLauncher.addLaunchCookie((ItemInfo) itemInfo, activityOptions.options);
- }
+ activityOptions.options.setSplashScreenStyle(SplashScreen.SPLASH_SCREEN_STYLE_SOLID_COLOR);
options = Pair.create(options.first, activityOptions.options);
if (pendingIntent.isActivity()) {
logAppLaunch(itemInfo);
diff --git a/quickstep/src/com/android/launcher3/uioverrides/states/AllAppsState.java b/quickstep/src/com/android/launcher3/uioverrides/states/AllAppsState.java
index 26d8f30..cd14b3f 100644
--- a/quickstep/src/com/android/launcher3/uioverrides/states/AllAppsState.java
+++ b/quickstep/src/com/android/launcher3/uioverrides/states/AllAppsState.java
@@ -38,7 +38,7 @@
@Override
public int getTransitionDuration(Context context) {
- return 320;
+ return 150;
}
@Override
@@ -53,18 +53,20 @@
@Override
public ScaleAndTranslation getWorkspaceScaleAndTranslation(Launcher launcher) {
- ScaleAndTranslation scaleAndTranslation = LauncherState.OVERVIEW
- .getWorkspaceScaleAndTranslation(launcher);
- scaleAndTranslation.scale = 1;
+ ScaleAndTranslation scaleAndTranslation =
+ new ScaleAndTranslation(NO_SCALE, NO_OFFSET, NO_OFFSET);
+ if (launcher.getDeviceProfile().isTablet) {
+ scaleAndTranslation.scale = 0.97f;
+ } else {
+ ScaleAndTranslation overviewScaleAndTranslation = LauncherState.OVERVIEW
+ .getWorkspaceScaleAndTranslation(launcher);
+ scaleAndTranslation.translationX = overviewScaleAndTranslation.translationX;
+ scaleAndTranslation.translationY = overviewScaleAndTranslation.translationY;
+ }
return scaleAndTranslation;
}
@Override
- public boolean isTaskbarStashed(Launcher launcher) {
- return true;
- }
-
- @Override
protected float getDepthUnchecked(Context context) {
// The scrim fades in at approximately 50% of the swipe gesture.
// This means that the depth should be greater than 1, in order to fully zoom out.
@@ -86,7 +88,7 @@
@Override
public int getVisibleElements(Launcher launcher) {
- return ALL_APPS_CONTENT;
+ return ALL_APPS_CONTENT | HOTSEAT_ICONS;
}
@Override
diff --git a/quickstep/src/com/android/launcher3/uioverrides/touchcontrollers/NoButtonQuickSwitchTouchController.java b/quickstep/src/com/android/launcher3/uioverrides/touchcontrollers/NoButtonQuickSwitchTouchController.java
index f6148a7..d8f694e 100644
--- a/quickstep/src/com/android/launcher3/uioverrides/touchcontrollers/NoButtonQuickSwitchTouchController.java
+++ b/quickstep/src/com/android/launcher3/uioverrides/touchcontrollers/NoButtonQuickSwitchTouchController.java
@@ -40,7 +40,7 @@
import static com.android.launcher3.states.StateAnimationConfig.SKIP_SCRIM;
import static com.android.launcher3.touch.BothAxesSwipeDetector.DIRECTION_RIGHT;
import static com.android.launcher3.touch.BothAxesSwipeDetector.DIRECTION_UP;
-import static com.android.launcher3.util.DisplayController.getSingleFrameMs;
+import static com.android.launcher3.util.window.RefreshRateTracker.getSingleFrameMs;
import static com.android.quickstep.util.VibratorWrapper.OVERVIEW_HAPTIC;
import static com.android.quickstep.views.RecentsView.ADJACENT_PAGE_HORIZONTAL_OFFSET;
import static com.android.quickstep.views.RecentsView.CONTENT_ALPHA;
diff --git a/quickstep/src/com/android/launcher3/uioverrides/touchcontrollers/PortraitStatesTouchController.java b/quickstep/src/com/android/launcher3/uioverrides/touchcontrollers/PortraitStatesTouchController.java
index 099915a..f93917f 100644
--- a/quickstep/src/com/android/launcher3/uioverrides/touchcontrollers/PortraitStatesTouchController.java
+++ b/quickstep/src/com/android/launcher3/uioverrides/touchcontrollers/PortraitStatesTouchController.java
@@ -23,8 +23,13 @@
import static com.android.launcher3.LauncherState.OVERVIEW;
import static com.android.launcher3.anim.Interpolators.ACCEL;
import static com.android.launcher3.anim.Interpolators.DEACCEL;
+import static com.android.launcher3.anim.Interpolators.FINAL_FRAME;
+import static com.android.launcher3.anim.Interpolators.INSTANT;
+import static com.android.launcher3.anim.Interpolators.LINEAR;
+import static com.android.launcher3.anim.Interpolators.LINEAR_TELEPORT;
import static com.android.launcher3.states.StateAnimationConfig.ANIM_ALL_APPS_FADE;
import static com.android.launcher3.states.StateAnimationConfig.ANIM_SCRIM_FADE;
+import static com.android.launcher3.states.StateAnimationConfig.ANIM_VERTICAL_PROGRESS;
import android.view.MotionEvent;
@@ -126,23 +131,31 @@
private StateAnimationConfig getNormalToAllAppsAnimation() {
StateAnimationConfig builder = new StateAnimationConfig();
- builder.setInterpolator(ANIM_ALL_APPS_FADE, Interpolators.clampToProgress(ACCEL,
- ALL_APPS_CONTENT_FADE_MIN_CLAMPING_THRESHOLD,
- ALL_APPS_CONTENT_FADE_MAX_CLAMPING_THRESHOLD));
+ boolean isTablet = mLauncher.getDeviceProfile().isTablet;
+ builder.setInterpolator(ANIM_ALL_APPS_FADE, isTablet
+ ? INSTANT
+ : Interpolators.clampToProgress(ACCEL,
+ ALL_APPS_CONTENT_FADE_MIN_CLAMPING_THRESHOLD,
+ ALL_APPS_CONTENT_FADE_MAX_CLAMPING_THRESHOLD));
builder.setInterpolator(ANIM_SCRIM_FADE, Interpolators.clampToProgress(ACCEL,
ALL_APPS_SCRIM_VISIBLE_THRESHOLD,
ALL_APPS_SCRIM_OPAQUE_THRESHOLD));
+ builder.setInterpolator(ANIM_VERTICAL_PROGRESS, isTablet ? LINEAR_TELEPORT : LINEAR);
return builder;
}
private StateAnimationConfig getAllAppsToNormalAnimation() {
StateAnimationConfig builder = new StateAnimationConfig();
- builder.setInterpolator(ANIM_ALL_APPS_FADE, Interpolators.clampToProgress(DEACCEL,
- 1 - ALL_APPS_CONTENT_FADE_MAX_CLAMPING_THRESHOLD,
- 1 - ALL_APPS_CONTENT_FADE_MIN_CLAMPING_THRESHOLD));
+ boolean isTablet = mLauncher.getDeviceProfile().isTablet;
+ builder.setInterpolator(ANIM_ALL_APPS_FADE, isTablet
+ ? FINAL_FRAME
+ : Interpolators.clampToProgress(DEACCEL,
+ 1 - ALL_APPS_CONTENT_FADE_MAX_CLAMPING_THRESHOLD,
+ 1 - ALL_APPS_CONTENT_FADE_MIN_CLAMPING_THRESHOLD));
builder.setInterpolator(ANIM_SCRIM_FADE, Interpolators.clampToProgress(DEACCEL,
1 - ALL_APPS_SCRIM_OPAQUE_THRESHOLD,
1 - ALL_APPS_SCRIM_VISIBLE_THRESHOLD));
+ builder.setInterpolator(ANIM_VERTICAL_PROGRESS, isTablet ? LINEAR_TELEPORT : LINEAR);
return builder;
}
diff --git a/quickstep/src/com/android/quickstep/AbsSwipeUpHandler.java b/quickstep/src/com/android/quickstep/AbsSwipeUpHandler.java
index 2cb7100..2570e6c 100644
--- a/quickstep/src/com/android/quickstep/AbsSwipeUpHandler.java
+++ b/quickstep/src/com/android/quickstep/AbsSwipeUpHandler.java
@@ -32,10 +32,10 @@
import static com.android.launcher3.logging.StatsLogManager.LauncherEvent.LAUNCHER_OVERVIEW_GESTURE;
import static com.android.launcher3.logging.StatsLogManager.LauncherEvent.LAUNCHER_QUICKSWITCH_LEFT;
import static com.android.launcher3.logging.StatsLogManager.LauncherEvent.LAUNCHER_QUICKSWITCH_RIGHT;
-import static com.android.launcher3.util.DisplayController.getSingleFrameMs;
import static com.android.launcher3.util.Executors.MAIN_EXECUTOR;
import static com.android.launcher3.util.Executors.UI_HELPER_EXECUTOR;
import static com.android.launcher3.util.SystemUiController.UI_STATE_FULLSCREEN_TASK;
+import static com.android.launcher3.util.window.RefreshRateTracker.getSingleFrameMs;
import static com.android.quickstep.GestureState.GestureEndTarget.HOME;
import static com.android.quickstep.GestureState.GestureEndTarget.LAST_TASK;
import static com.android.quickstep.GestureState.GestureEndTarget.NEW_TASK;
@@ -833,12 +833,9 @@
// Notify when the animation starts
flushOnRecentsAnimationAndLauncherBound();
- // Start hiding the divider
- setDividerShown(false /* shown */, false /* immediate */);
-
// Only add the callback to enable the input consumer after we actually have the controller
mStateCallback.runOnceAtState(STATE_APP_CONTROLLER_RECEIVED | STATE_GESTURE_STARTED,
- mRecentsAnimationController::enableInputConsumer);
+ this::startInterceptingTouchesForGesture);
mStateCallback.setStateOnUiThread(STATE_APP_CONTROLLER_RECEIVED);
mPassedOverviewThreshold = false;
@@ -1457,6 +1454,17 @@
return swipePipToHomeAnimator;
}
+ private void startInterceptingTouchesForGesture() {
+ if (mRecentsAnimationController == null) {
+ return;
+ }
+
+ mRecentsAnimationController.enableInputConsumer();
+
+ // Start hiding the divider
+ setDividerShown(false /* shown */, true /* immediate */);
+ }
+
private void computeRecentsScrollIfInvisible() {
if (mRecentsView != null && mRecentsView.getVisibility() != View.VISIBLE) {
// Views typically don't compute scroll when invisible as an optimization,
diff --git a/quickstep/src/com/android/quickstep/QuickstepProcessInitializer.java b/quickstep/src/com/android/quickstep/QuickstepProcessInitializer.java
index 678372c..5521020 100644
--- a/quickstep/src/com/android/quickstep/QuickstepProcessInitializer.java
+++ b/quickstep/src/com/android/quickstep/QuickstepProcessInitializer.java
@@ -23,11 +23,11 @@
import android.os.RemoteException;
import android.os.UserManager;
import android.util.Log;
+import android.view.ThreadedRenderer;
import com.android.launcher3.BuildConfig;
import com.android.launcher3.MainProcessInitializer;
import com.android.systemui.shared.system.InteractionJankMonitorWrapper;
-import com.android.systemui.shared.system.ThreadedRendererCompat;
@SuppressWarnings("unused")
@TargetApi(Build.VERSION_CODES.R)
@@ -60,8 +60,8 @@
super.init(context);
// Elevate GPU priority for Quickstep and Remote animations.
- ThreadedRendererCompat.setContextPriority(
- ThreadedRendererCompat.EGL_CONTEXT_PRIORITY_HIGH_IMG);
+ ThreadedRenderer.setContextPriority(
+ ThreadedRenderer.EGL_CONTEXT_PRIORITY_HIGH_IMG);
// Enable binder tracing on system server for calls originating from Launcher
try {
diff --git a/quickstep/src/com/android/quickstep/RecentsAnimationController.java b/quickstep/src/com/android/quickstep/RecentsAnimationController.java
index f343485..c120b32 100644
--- a/quickstep/src/com/android/quickstep/RecentsAnimationController.java
+++ b/quickstep/src/com/android/quickstep/RecentsAnimationController.java
@@ -17,9 +17,13 @@
import static com.android.launcher3.util.Executors.MAIN_EXECUTOR;
import static com.android.launcher3.util.Executors.UI_HELPER_EXECUTOR;
+import static com.android.quickstep.TaskAnimationManager.ENABLE_SHELL_TRANSITIONS;
+import android.os.RemoteException;
+import android.util.Log;
import android.view.IRecentsAnimationController;
import android.view.SurfaceControl;
+import android.view.WindowManagerGlobal;
import android.window.PictureInPictureSurfaceTransaction;
import androidx.annotation.NonNull;
@@ -39,6 +43,7 @@
*/
public class RecentsAnimationController {
+ private static final String TAG = "RecentsAnimationController";
private final RecentsAnimationControllerCompat mController;
private final Consumer<RecentsAnimationController> mOnFinishedListener;
private final boolean mAllowMinimizeSplitScreen;
@@ -74,7 +79,16 @@
if (mUseLauncherSysBarFlags != useLauncherSysBarFlags) {
mUseLauncherSysBarFlags = useLauncherSysBarFlags;
UI_HELPER_EXECUTOR.execute(() -> {
- mController.setAnimationTargetsBehindSystemBars(!useLauncherSysBarFlags);
+ if (!ENABLE_SHELL_TRANSITIONS) {
+ mController.setAnimationTargetsBehindSystemBars(!useLauncherSysBarFlags);
+ } else {
+ try {
+ WindowManagerGlobal.getWindowManagerService().setRecentsAppBehindSystemBars(
+ useLauncherSysBarFlags);
+ } catch (RemoteException e) {
+ Log.e(TAG, "Unable to reach window manager", e);
+ }
+ }
});
}
}
diff --git a/quickstep/src/com/android/quickstep/RecentsAnimationDeviceState.java b/quickstep/src/com/android/quickstep/RecentsAnimationDeviceState.java
index f48a262..ad57683 100644
--- a/quickstep/src/com/android/quickstep/RecentsAnimationDeviceState.java
+++ b/quickstep/src/com/android/quickstep/RecentsAnimationDeviceState.java
@@ -550,15 +550,13 @@
/**
* @param ev An ACTION_DOWN motion event
- * @param task Info for the currently running task
* @return whether the given motion event can trigger the assistant over the current task.
*/
- public boolean canTriggerAssistantAction(MotionEvent ev, ActivityManager.RunningTaskInfo task) {
+ public boolean canTriggerAssistantAction(MotionEvent ev) {
return mAssistantAvailable
&& !QuickStepContract.isAssistantGestureDisabled(mSystemUiStateFlags)
&& mRotationTouchHelper.touchInAssistantRegion(ev)
- && !isLockToAppActive()
- && !isGestureBlockedActivity(task);
+ && !isLockToAppActive();
}
/**
diff --git a/quickstep/src/com/android/quickstep/SystemUiProxy.java b/quickstep/src/com/android/quickstep/SystemUiProxy.java
index d28796c..8b00f45 100644
--- a/quickstep/src/com/android/quickstep/SystemUiProxy.java
+++ b/quickstep/src/com/android/quickstep/SystemUiProxy.java
@@ -816,8 +816,12 @@
public ArrayList<GroupedRecentTaskInfo> getRecentTasks(int numTasks, int userId) {
if (mRecentTasks != null) {
try {
- return new ArrayList<>(Arrays.asList(mRecentTasks.getRecentTasks(numTasks,
- RECENT_IGNORE_UNAVAILABLE, userId)));
+ final GroupedRecentTaskInfo[] rawTasks = mRecentTasks.getRecentTasks(numTasks,
+ RECENT_IGNORE_UNAVAILABLE, userId);
+ if (rawTasks == null) {
+ return new ArrayList<>();
+ }
+ return new ArrayList<>(Arrays.asList(rawTasks));
} catch (RemoteException e) {
Log.w(TAG, "Failed call getRecentTasks", e);
}
diff --git a/quickstep/src/com/android/quickstep/TaskIconCache.java b/quickstep/src/com/android/quickstep/TaskIconCache.java
index 6c71da9..300f085 100644
--- a/quickstep/src/com/android/quickstep/TaskIconCache.java
+++ b/quickstep/src/com/android/quickstep/TaskIconCache.java
@@ -18,6 +18,7 @@
import static com.android.launcher3.uioverrides.QuickstepLauncher.GO_LOW_RAM_RECENTS_ENABLED;
import static com.android.launcher3.util.DisplayController.CHANGE_DENSITY;
+import android.app.ActivityManager;
import android.app.ActivityManager.TaskDescription;
import android.content.Context;
import android.content.pm.ActivityInfo;
@@ -48,7 +49,6 @@
import com.android.systemui.shared.recents.model.Task;
import com.android.systemui.shared.recents.model.Task.TaskKey;
import com.android.systemui.shared.system.PackageManagerWrapper;
-import com.android.systemui.shared.system.TaskDescriptionCompat;
import java.util.concurrent.Executor;
import java.util.function.Consumer;
@@ -154,7 +154,7 @@
// Load icon
// TODO: Load icon resource (b/143363444)
- Bitmap icon = TaskDescriptionCompat.getIcon(desc, key.userId);
+ Bitmap icon = getIcon(desc, key.userId);
if (icon != null) {
entry.icon = getBitmapInfo(
new BitmapDrawable(mContext.getResources(), icon),
@@ -193,6 +193,14 @@
return entry;
}
+ private Bitmap getIcon(ActivityManager.TaskDescription desc, int userId) {
+ if (desc.getInMemoryIcon() != null) {
+ return desc.getInMemoryIcon();
+ }
+ return ActivityManager.TaskDescription.loadTaskDescriptionIcon(
+ desc.getIconFilename(), userId);
+ }
+
private String getBadgedContentDescription(ActivityInfo info, int userId, TaskDescription td) {
PackageManager pm = mContext.getPackageManager();
String taskLabel = td == null ? null : Utilities.trim(td.getLabel());
diff --git a/quickstep/src/com/android/quickstep/TaskShortcutFactory.java b/quickstep/src/com/android/quickstep/TaskShortcutFactory.java
index ecb30e5..e731b79 100644
--- a/quickstep/src/com/android/quickstep/TaskShortcutFactory.java
+++ b/quickstep/src/com/android/quickstep/TaskShortcutFactory.java
@@ -258,9 +258,8 @@
@Override
protected ActivityOptions makeLaunchOptions(Activity activity) {
- final ActivityCompat act = new ActivityCompat(activity);
final int navBarPosition = WindowManagerWrapper.getInstance().getNavBarPosition(
- act.getDisplayId());
+ activity.getDisplayId());
if (navBarPosition == WindowManagerWrapper.NAV_BAR_POS_INVALID) {
return null;
}
diff --git a/quickstep/src/com/android/quickstep/TouchInteractionService.java b/quickstep/src/com/android/quickstep/TouchInteractionService.java
index 9627147..b224089 100644
--- a/quickstep/src/com/android/quickstep/TouchInteractionService.java
+++ b/quickstep/src/com/android/quickstep/TouchInteractionService.java
@@ -37,7 +37,6 @@
import static com.android.systemui.shared.system.QuickStepContract.SYSUI_STATE_TRACING_ENABLED;
import android.annotation.TargetApi;
-import android.app.ActivityManager;
import android.app.PendingIntent;
import android.app.RemoteAction;
import android.app.Service;
@@ -575,26 +574,14 @@
ActiveGestureLog.INSTANCE.addLog("setInputConsumer: " + mConsumer.getName());
mUncheckedConsumer = mConsumer;
- } else if (mDeviceState.isUserUnlocked() && mDeviceState.isFullyGesturalNavMode()) {
+ } else if (mDeviceState.isUserUnlocked() && mDeviceState.isFullyGesturalNavMode()
+ && mDeviceState.canTriggerAssistantAction(event)) {
mGestureState = createGestureState(mGestureState);
- ActivityManager.RunningTaskInfo runningTask = mGestureState.getRunningTask();
- if (mDeviceState.canTriggerAssistantAction(event, runningTask)) {
- // Do not change mConsumer as if there is an ongoing QuickSwitch gesture, we
- // should not interrupt it. QuickSwitch assumes that interruption can only
- // happen if the next gesture is also quick switch.
- mUncheckedConsumer = new AssistantInputConsumer(
- this,
- mGestureState,
- InputConsumer.NO_OP, mInputMonitorCompat,
- mDeviceState,
- event);
- } else if (mDeviceState.canTriggerOneHandedAction(event)) {
- // Consume gesture event for triggering one handed feature.
- mUncheckedConsumer = new OneHandedModeInputConsumer(this, mDeviceState,
- InputConsumer.NO_OP, mInputMonitorCompat);
- } else {
- mUncheckedConsumer = InputConsumer.NO_OP;
- }
+ // Do not change mConsumer as if there is an ongoing QuickSwitch gesture, we
+ // should not interrupt it. QuickSwitch assumes that interruption can only
+ // happen if the next gesture is also quick switch.
+ mUncheckedConsumer = tryCreateAssistantInputConsumer(
+ InputConsumer.NO_OP, mGestureState, event);
} else if (mDeviceState.canTriggerOneHandedAction(event)) {
// Consume gesture event for triggering one handed feature.
mUncheckedConsumer = new OneHandedModeInputConsumer(this, mDeviceState,
@@ -641,6 +628,14 @@
ProtoTracer.INSTANCE.get(this).scheduleFrameUpdate();
}
+ private InputConsumer tryCreateAssistantInputConsumer(InputConsumer base,
+ GestureState gestureState, MotionEvent motionEvent) {
+ return mDeviceState.isGestureBlockedActivity(gestureState.getRunningTask())
+ ? base
+ : new AssistantInputConsumer(this, gestureState, base, mInputMonitorCompat,
+ mDeviceState, motionEvent);
+ }
+
public GestureState createGestureState(GestureState previousGestureState) {
GestureState gestureState = new GestureState(mOverviewComponentObserver,
ActiveGestureLog.INSTANCE.generateAndSetLogId());
@@ -686,9 +681,8 @@
handleOrientationSetup(base);
}
if (mDeviceState.isFullyGesturalNavMode()) {
- if (mDeviceState.canTriggerAssistantAction(event, newGestureState.getRunningTask())) {
- base = new AssistantInputConsumer(this, newGestureState, base, mInputMonitorCompat,
- mDeviceState, event);
+ if (mDeviceState.canTriggerAssistantAction(event)) {
+ base = tryCreateAssistantInputConsumer(base, newGestureState, event);
}
// If Taskbar is present, we listen for long press to unstash it.
@@ -768,7 +762,10 @@
} else if (gestureState.getRunningTask() == null) {
return getDefaultInputConsumer();
} else if (previousGestureState.isRunningAnimationToLauncher()
- || gestureState.getActivityInterface().isResumed()
+ || (gestureState.getActivityInterface().isResumed()
+ // with shell-transitions, home is resumed during recents animation, so
+ // explicitly check against recents animation too.
+ && !previousGestureState.isRecentsAnimationRunning())
|| forceOverviewInputConsumer) {
return createOverviewInputConsumer(
previousGestureState, gestureState, event, forceOverviewInputConsumer);
@@ -965,6 +962,9 @@
pw.println("ProtoTrace:");
pw.println(" file=" + ProtoTracer.INSTANCE.get(this).getTraceFile());
mTaskbarManager.dumpLogs("", pw);
+ if (createdOverviewActivity != null) {
+ createdOverviewActivity.getDeviceProfile().dump("", pw);
+ }
}
}
diff --git a/quickstep/src/com/android/quickstep/ViewUtils.java b/quickstep/src/com/android/quickstep/ViewUtils.java
index e290be8..ab26d15 100644
--- a/quickstep/src/com/android/quickstep/ViewUtils.java
+++ b/quickstep/src/com/android/quickstep/ViewUtils.java
@@ -21,10 +21,8 @@
import android.view.ViewRootImpl;
import com.android.launcher3.Utilities;
-import com.android.systemui.shared.system.ViewRootImplCompat;
import java.util.function.BooleanSupplier;
-import java.util.function.LongConsumer;
/**
* Utility class for helpful methods related to {@link View} objects.
diff --git a/quickstep/src/com/android/quickstep/inputconsumers/SysUiOverlayInputConsumer.java b/quickstep/src/com/android/quickstep/inputconsumers/SysUiOverlayInputConsumer.java
index 3f833c0..878f132 100644
--- a/quickstep/src/com/android/quickstep/inputconsumers/SysUiOverlayInputConsumer.java
+++ b/quickstep/src/com/android/quickstep/inputconsumers/SysUiOverlayInputConsumer.java
@@ -15,9 +15,11 @@
*/
package com.android.quickstep.inputconsumers;
+import android.app.ActivityManager;
import android.content.Context;
-import android.content.Intent;
import android.graphics.PointF;
+import android.os.RemoteException;
+import android.util.Log;
import android.view.MotionEvent;
import com.android.launcher3.testing.TestLogging;
@@ -36,6 +38,10 @@
*/
public class SysUiOverlayInputConsumer implements InputConsumer,
TriggerSwipeUpTouchTracker.OnSwipeUpListener {
+ private static final String TAG = "SysUiOverlayInputConsumer";
+
+ // Should match the values in PhoneWindowManager
+ private static final String SYSTEM_DIALOG_REASON_GESTURE_NAV = "gestureNav";
private final Context mContext;
private final InputMonitorCompat mInputMonitor;
@@ -76,7 +82,11 @@
@Override
public void onSwipeUp(boolean wasFling, PointF finalVelocity) {
// Close system dialogs when a swipe up is detected.
- mContext.sendBroadcast(new Intent(Intent.ACTION_CLOSE_SYSTEM_DIALOGS));
+ try {
+ ActivityManager.getService().closeSystemDialogs(SYSTEM_DIALOG_REASON_GESTURE_NAV);
+ } catch (RemoteException e) {
+ Log.e(TAG, "Exception calling closeSystemDialogs " + e.getMessage());
+ }
}
@Override
diff --git a/quickstep/src/com/android/quickstep/interaction/SwipeUpGestureTutorialController.java b/quickstep/src/com/android/quickstep/interaction/SwipeUpGestureTutorialController.java
index 672687d..9a101b9 100644
--- a/quickstep/src/com/android/quickstep/interaction/SwipeUpGestureTutorialController.java
+++ b/quickstep/src/com/android/quickstep/interaction/SwipeUpGestureTutorialController.java
@@ -16,7 +16,7 @@
package com.android.quickstep.interaction;
import static com.android.launcher3.anim.Interpolators.ACCEL;
-import static com.android.launcher3.util.DisplayController.getSingleFrameMs;
+import static com.android.launcher3.util.window.RefreshRateTracker.getSingleFrameMs;
import static com.android.launcher3.views.FloatingIconView.SHAPE_PROGRESS_DURATION;
import static com.android.quickstep.AbsSwipeUpHandler.MAX_SWIPE_DURATION;
import static com.android.quickstep.interaction.TutorialController.TutorialType.HOME_NAVIGATION_COMPLETE;
diff --git a/quickstep/src/com/android/quickstep/logging/StatsLogCompatManager.java b/quickstep/src/com/android/quickstep/logging/StatsLogCompatManager.java
index 12a638a..04fc3ba 100644
--- a/quickstep/src/com/android/quickstep/logging/StatsLogCompatManager.java
+++ b/quickstep/src/com/android/quickstep/logging/StatsLogCompatManager.java
@@ -141,7 +141,9 @@
getCardinality(info) /* cardinality */,
info.getWidget().getSpanX(),
info.getWidget().getSpanY(),
- getFeatures(info));
+ getFeatures(info),
+ null /* attributes */
+ );
}
/**
@@ -170,7 +172,8 @@
info.getAttribute().getNumber(), // attribute_id = 15;
getCardinality(info), // cardinality = 16;
info.getWidget().getSpanX(), // span_x = 17 [default = 1];
- info.getWidget().getSpanY() // span_y = 18 [default = 1];
+ info.getWidget().getSpanY(), // span_y = 18 [default = 1];
+ null /* attributes */
);
}
@@ -413,7 +416,8 @@
atomInfo.getFolderIcon().getLabelInfo() /* edittext */,
getCardinality(atomInfo) /* cardinality */,
getFeatures(atomInfo) /* features */,
- getSearchAttributes(atomInfo) /* searchAttributes */
+ getSearchAttributes(atomInfo) /* searchAttributes */,
+ null /* attributes */
);
}
}
diff --git a/quickstep/src/com/android/quickstep/util/BaseUnfoldMoveFromCenterAnimator.java b/quickstep/src/com/android/quickstep/util/BaseUnfoldMoveFromCenterAnimator.java
index 861ff96..143042f 100644
--- a/quickstep/src/com/android/quickstep/util/BaseUnfoldMoveFromCenterAnimator.java
+++ b/quickstep/src/com/android/quickstep/util/BaseUnfoldMoveFromCenterAnimator.java
@@ -36,6 +36,8 @@
private final Map<ViewGroup, Boolean> mOriginalClipToPadding = new HashMap<>();
private final Map<ViewGroup, Boolean> mOriginalClipChildren = new HashMap<>();
+ private boolean mAnimationInProgress = false;
+
public BaseUnfoldMoveFromCenterAnimator(WindowManager windowManager) {
mMoveFromCenterAnimation = new UnfoldMoveFromCenterAnimator(windowManager,
new LauncherViewsMoveFromCenterTranslationApplier());
@@ -44,6 +46,7 @@
@CallSuper
@Override
public void onTransitionStarted() {
+ mAnimationInProgress = true;
mMoveFromCenterAnimation.updateDisplayProperties();
onPrepareViewsForAnimation();
onTransitionProgress(0f);
@@ -58,7 +61,23 @@
@CallSuper
@Override
public void onTransitionFinished() {
+ mAnimationInProgress = false;
mMoveFromCenterAnimation.onTransitionFinished();
+ clearRegisteredViews();
+ }
+
+ /**
+ * Re-prepares views for animation. This is useful in case views are re-bound while the
+ * animation is in progress.
+ */
+ public void updateRegisteredViewsIfNeeded() {
+ if (mAnimationInProgress) {
+ clearRegisteredViews();
+ onPrepareViewsForAnimation();
+ }
+ }
+
+ private void clearRegisteredViews() {
mMoveFromCenterAnimation.clearRegisteredViews();
mOriginalClipChildren.clear();
diff --git a/quickstep/src/com/android/quickstep/util/LauncherUnfoldAnimationController.java b/quickstep/src/com/android/quickstep/util/LauncherUnfoldAnimationController.java
index 3b58046..6f171f9 100644
--- a/quickstep/src/com/android/quickstep/util/LauncherUnfoldAnimationController.java
+++ b/quickstep/src/com/android/quickstep/util/LauncherUnfoldAnimationController.java
@@ -51,13 +51,14 @@
HOTSEAT_SCALE_PROPERTY_FACTORY.get(SCALE_INDEX_UNFOLD_ANIMATION);
private final Launcher mLauncher;
+ private final ScopedUnfoldTransitionProgressProvider mProgressProvider;
+ private final NaturalRotationUnfoldProgressProvider mNaturalOrientationProgressProvider;
+ private final UnfoldMoveFromCenterHotseatAnimator mUnfoldMoveFromCenterHotseatAnimator;
+ private final UnfoldMoveFromCenterWorkspaceAnimator mUnfoldMoveFromCenterWorkspaceAnimator;
@Nullable
private HorizontalInsettableView mQsbInsettable;
- private final ScopedUnfoldTransitionProgressProvider mProgressProvider;
- private final NaturalRotationUnfoldProgressProvider mNaturalOrientationProgressProvider;
-
public LauncherUnfoldAnimationController(
Launcher launcher,
WindowManager windowManager,
@@ -65,21 +66,21 @@
mLauncher = launcher;
mProgressProvider = new ScopedUnfoldTransitionProgressProvider(
unfoldTransitionProgressProvider);
+ mUnfoldMoveFromCenterHotseatAnimator = new UnfoldMoveFromCenterHotseatAnimator(launcher,
+ windowManager);
+ mUnfoldMoveFromCenterWorkspaceAnimator = new UnfoldMoveFromCenterWorkspaceAnimator(launcher,
+ windowManager);
mNaturalOrientationProgressProvider = new NaturalRotationUnfoldProgressProvider(launcher,
WindowManagerGlobal.getWindowManagerService(), mProgressProvider);
mNaturalOrientationProgressProvider.init();
// Animated in all orientations
- mProgressProvider.addCallback(new UnfoldMoveFromCenterWorkspaceAnimator(launcher,
- windowManager));
- mProgressProvider
- .addCallback(new LauncherScaleAnimationListener());
+ mProgressProvider.addCallback(mUnfoldMoveFromCenterWorkspaceAnimator);
+ mProgressProvider.addCallback(new LauncherScaleAnimationListener());
// Animated only in natural orientation
- mNaturalOrientationProgressProvider
- .addCallback(new QsbAnimationListener());
- mNaturalOrientationProgressProvider
- .addCallback(new UnfoldMoveFromCenterHotseatAnimator(launcher, windowManager));
+ mNaturalOrientationProgressProvider.addCallback(new QsbAnimationListener());
+ mNaturalOrientationProgressProvider.addCallback(mUnfoldMoveFromCenterHotseatAnimator);
}
/**
@@ -111,6 +112,12 @@
mNaturalOrientationProgressProvider.destroy();
}
+ /** Called when launcher finished binding its items. */
+ public void updateRegisteredViewsIfNeeded() {
+ mUnfoldMoveFromCenterHotseatAnimator.updateRegisteredViewsIfNeeded();
+ mUnfoldMoveFromCenterWorkspaceAnimator.updateRegisteredViewsIfNeeded();
+ }
+
private class QsbAnimationListener implements TransitionProgressListener {
@Override
@@ -137,6 +144,7 @@
@Override
public void onTransitionStarted() {
+ mLauncher.getWorkspace().setPivotToScaleWithSelf(mLauncher.getHotseat());
}
@Override
diff --git a/quickstep/src/com/android/quickstep/views/FloatingTaskThumbnailView.java b/quickstep/src/com/android/quickstep/views/FloatingTaskThumbnailView.java
new file mode 100644
index 0000000..cfb0056
--- /dev/null
+++ b/quickstep/src/com/android/quickstep/views/FloatingTaskThumbnailView.java
@@ -0,0 +1,86 @@
+/*
+ * Copyright 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.quickstep.views;
+
+import android.content.Context;
+import android.graphics.Bitmap;
+import android.graphics.BitmapShader;
+import android.graphics.Canvas;
+import android.graphics.Matrix;
+import android.graphics.Paint;
+import android.graphics.Shader;
+import android.util.AttributeSet;
+import android.view.View;
+
+import androidx.annotation.Nullable;
+
+/**
+ * A child view of {@link com.android.quickstep.views.FloatingTaskView} to draw the thumbnail in a
+ * rounded corner frame. While the purpose of this class sounds similar to
+ * {@link TaskThumbnailView}, it doesn't need a lot of complex logic in {@link TaskThumbnailView}
+ * in relation to moving with {@link RecentsView}.
+ */
+public class FloatingTaskThumbnailView extends View {
+
+ private final Paint mPaint = new Paint(Paint.ANTI_ALIAS_FLAG);
+ private final Matrix mMatrix = new Matrix();
+
+ private @Nullable BitmapShader mBitmapShader;
+ private @Nullable Bitmap mBitmap;
+
+ private FloatingTaskView.FullscreenDrawParams mFullscreenParams;
+
+ public FloatingTaskThumbnailView(Context context) {
+ this(context, null);
+ }
+
+ public FloatingTaskThumbnailView(Context context, AttributeSet attrs) {
+ this(context, attrs, 0);
+ }
+
+ public FloatingTaskThumbnailView(Context context, AttributeSet attrs, int defStyleAttr) {
+ super(context, attrs, defStyleAttr);
+ }
+
+ @Override
+ protected void onDraw(Canvas canvas) {
+ if (mFullscreenParams == null || mBitmap == null) {
+ return;
+ }
+
+ // Scale down the bitmap to fix x, and crop in y.
+ float scale = 1.0f * getMeasuredWidth() / mBitmap.getWidth();
+ mMatrix.postScale(scale, scale);
+ mBitmapShader.setLocalMatrix(mMatrix);
+
+ canvas.drawRoundRect(0, 0, getMeasuredWidth(), getMeasuredHeight(),
+ mFullscreenParams.mCurrentDrawnCornerRadius / mFullscreenParams.mScaleX,
+ mFullscreenParams.mCurrentDrawnCornerRadius / mFullscreenParams.mScaleY, mPaint);
+ }
+
+ public void setThumbnail(Bitmap bitmap) {
+ mBitmap = bitmap;
+ if (bitmap != null) {
+ mBitmapShader = new BitmapShader(bitmap, Shader.TileMode.CLAMP, Shader.TileMode.CLAMP);
+ mPaint.setShader(mBitmapShader);
+ }
+ }
+
+ public void setFullscreenParams(FloatingTaskView.FullscreenDrawParams fullscreenParams) {
+ mFullscreenParams = fullscreenParams;
+ }
+}
diff --git a/quickstep/src/com/android/quickstep/views/FloatingTaskView.java b/quickstep/src/com/android/quickstep/views/FloatingTaskView.java
index f2f1c3f..c59dc18 100644
--- a/quickstep/src/com/android/quickstep/views/FloatingTaskView.java
+++ b/quickstep/src/com/android/quickstep/views/FloatingTaskView.java
@@ -15,7 +15,6 @@
import android.view.View;
import android.view.ViewGroup;
import android.widget.FrameLayout;
-import android.widget.ImageView;
import androidx.annotation.Nullable;
@@ -29,6 +28,8 @@
import com.android.launcher3.touch.PagedOrientationHandler;
import com.android.launcher3.views.BaseDragLayer;
import com.android.quickstep.util.MultiValueUpdateListener;
+import com.android.quickstep.util.TaskCornerRadius;
+import com.android.systemui.shared.system.QuickStepContract;
import java.util.function.Consumer;
@@ -50,9 +51,9 @@
private RectF mStartingPosition;
private final StatefulActivity mActivity;
private final boolean mIsRtl;
- private final Rect mOutline = new Rect();
+ private final FullscreenDrawParams mCurrentFullscreenParams;
private PagedOrientationHandler mOrientationHandler;
- private ImageView mImageView;
+ private FloatingTaskThumbnailView mThumbnailView;
public FloatingTaskView(Context context) {
this(context, null);
@@ -66,16 +67,17 @@
super(context, attrs, defStyleAttr);
mActivity = BaseActivity.fromContext(context);
mIsRtl = Utilities.isRtl(getResources());
+ mCurrentFullscreenParams = new FullscreenDrawParams(context);
}
@Override
protected void onFinishInflate() {
super.onFinishInflate();
- mImageView = findViewById(R.id.thumbnail);
- mImageView.setScaleType(ImageView.ScaleType.CENTER_CROP);
- mImageView.setLayerType(LAYER_TYPE_HARDWARE, null);
+ mThumbnailView = findViewById(R.id.thumbnail);
+ mThumbnailView.setFullscreenParams(mCurrentFullscreenParams);
mSplitPlaceholderView = findViewById(R.id.split_placeholder);
mSplitPlaceholderView.setAlpha(0);
+ mSplitPlaceholderView.setFullscreenParams(mCurrentFullscreenParams);
}
private void init(StatefulActivity launcher, View originalView, @Nullable Bitmap thumbnail,
@@ -86,13 +88,11 @@
(InsettableFrameLayout.LayoutParams) getLayoutParams();
mSplitPlaceholderView.setLayoutParams(new FrameLayout.LayoutParams(lp.width, lp.height));
- positionOut.round(mOutline);
setPivotX(0);
setPivotY(0);
// Copy bounds of exiting thumbnail into ImageView
- mImageView.setImageBitmap(thumbnail);
- mImageView.setVisibility(VISIBLE);
+ mThumbnailView.setThumbnail(thumbnail);
RecentsView recentsView = launcher.getOverviewPanel();
mOrientationHandler = recentsView.getPagedOrientationHandler();
@@ -133,27 +133,24 @@
setLayoutParams(lp);
}
- // TODO(194414938) set correct corner radii
- public void update(RectF position, float progress, float windowRadius) {
+ public void update(RectF position, float progress) {
MarginLayoutParams lp = (MarginLayoutParams) getLayoutParams();
float dX = position.left - mStartingPosition.left;
float dY = position.top - lp.topMargin;
+ float scaleX = position.width() / lp.width;
+ float scaleY = position.height() / lp.height;
+
+ mCurrentFullscreenParams.updateParams(position, progress, scaleX, scaleY);
setTranslationX(dX);
setTranslationY(dY);
-
- float scaleX = position.width() / lp.width;
- float scaleY = position.height() / lp.height;
setScaleX(scaleX);
setScaleY(scaleY);
+ mSplitPlaceholderView.invalidate();
+
float childScaleX = 1f / scaleX;
float childScaleY = 1f / scaleY;
-
- invalidate();
- // TODO(194414938) seems like this scale value could be fine tuned, some stretchiness
- mImageView.setScaleX(1f / scaleX + scaleX * progress);
- mImageView.setScaleY(1f / scaleY + scaleY * progress);
mOrientationHandler.setPrimaryScale(mSplitPlaceholderView.getIconView(), childScaleX);
mOrientationHandler.setSecondaryScale(mSplitPlaceholderView.getIconView(), childScaleY);
}
@@ -181,7 +178,8 @@
}
public void addAnimation(PendingAnimation animation, RectF startingBounds, Rect endBounds,
- boolean fadeWithThumbnail) {
+ boolean fadeWithThumbnail, boolean isInitialSplit) {
+ mCurrentFullscreenParams.setIsInitialSplit(isInitialSplit);
final BaseDragLayer dragLayer = mActivity.getDragLayer();
int[] dragLayerBounds = new int[2];
dragLayer.getLocationOnScreen(dragLayerBounds);
@@ -191,22 +189,16 @@
ValueAnimator transitionAnimator = ValueAnimator.ofFloat(0, 1);
animation.add(transitionAnimator);
long animDuration = animation.getDuration();
- Rect crop = new Rect();
RectF floatingTaskViewBounds = new RectF();
- final float initialWindowRadius = supportsRoundedCornersOnWindows(getResources())
- ? Math.max(crop.width(), crop.height()) / 2f
- : 0f;
if (fadeWithThumbnail) {
animation.addFloat(mSplitPlaceholderView, SplitPlaceholderView.ALPHA_FLOAT,
0, 1, ACCEL);
- animation.addFloat(mImageView, LauncherAnimUtils.VIEW_ALPHA,
+ animation.addFloat(mThumbnailView, LauncherAnimUtils.VIEW_ALPHA,
1, 0, DEACCEL_3);
}
MultiValueUpdateListener listener = new MultiValueUpdateListener() {
- final FloatProp mWindowRadius = new FloatProp(initialWindowRadius,
- initialWindowRadius, 0, animDuration, LINEAR);
final FloatProp mDx = new FloatProp(0, prop.dX, 0, animDuration, LINEAR);
final FloatProp mDy = new FloatProp(0, prop.dY, 0, animDuration, LINEAR);
final FloatProp mTaskViewScaleX = new FloatProp(1f, prop.finalTaskViewScaleX, 0,
@@ -221,7 +213,7 @@
Utilities.scaleRectFAboutCenter(floatingTaskViewBounds, mTaskViewScaleX.value,
mTaskViewScaleY.value);
- update(floatingTaskViewBounds, percent, mWindowRadius.value * 1);
+ update(floatingTaskViewBounds, percent);
}
};
transitionAnimator.addUpdateListener(listener);
@@ -250,4 +242,36 @@
dY = centerY - startTaskViewBounds.centerY();
}
}
+
+ public static class FullscreenDrawParams {
+
+ private final float mCornerRadius;
+ private final float mWindowCornerRadius;
+
+ public boolean mIsInitialSplit = true;
+ public final RectF mFloatingTaskViewBounds = new RectF();
+ public float mCurrentDrawnCornerRadius;
+ public float mScaleX = 1;
+ public float mScaleY = 1;
+
+ public FullscreenDrawParams(Context context) {
+ mCornerRadius = TaskCornerRadius.get(context);
+ mWindowCornerRadius = QuickStepContract.getWindowCornerRadius(context);
+
+ mCurrentDrawnCornerRadius = mCornerRadius;
+ }
+
+ public void updateParams(RectF floatingTaskViewBounds, float progress, float scaleX,
+ float scaleY) {
+ mFloatingTaskViewBounds.set(floatingTaskViewBounds);
+ mScaleX = scaleX;
+ mScaleY = scaleY;
+ mCurrentDrawnCornerRadius = mIsInitialSplit ? 0 :
+ Utilities.mapRange(progress, mCornerRadius, mWindowCornerRadius);
+ }
+
+ public void setIsInitialSplit(boolean isInitialSplit) {
+ mIsInitialSplit = isInitialSplit;
+ }
+ }
}
diff --git a/quickstep/src/com/android/quickstep/views/RecentsView.java b/quickstep/src/com/android/quickstep/views/RecentsView.java
index cb7e08a..5e331e2 100644
--- a/quickstep/src/com/android/quickstep/views/RecentsView.java
+++ b/quickstep/src/com/android/quickstep/views/RecentsView.java
@@ -2732,7 +2732,7 @@
mSplitHiddenTaskView.getIconView().getDrawable(), startingTaskRect);
mFirstFloatingTaskView.setAlpha(1);
mFirstFloatingTaskView.addAnimation(anim, startingTaskRect,
- mTempRect, true /*fadeWithThumbnail*/);
+ mTempRect, true /* fadeWithThumbnail */, true /* isInitialSplit */);
} else {
mSplitSelectSource.view.setVisibility(INVISIBLE);
mFirstFloatingTaskView = FloatingTaskView.getFloatingTaskView(mActivity,
@@ -2740,7 +2740,7 @@
mSplitSelectSource.drawable, startingTaskRect);
mFirstFloatingTaskView.setAlpha(1);
mFirstFloatingTaskView.addAnimation(anim, startingTaskRect,
- mTempRect, true /*fadeWithThumbnail*/);
+ mTempRect, true /* fadeWithThumbnail */, true /* isInitialSplit */);
}
anim.addEndListener(success -> {
if (success) {
@@ -4030,14 +4030,14 @@
mFirstFloatingTaskView.getBoundsOnScreen(firstTaskStartingBounds);
mFirstFloatingTaskView.addAnimation(pendingAnimation,
new RectF(firstTaskStartingBounds), firstTaskEndingBounds,
- false /*fadeWithThumbnail*/);
+ false /* fadeWithThumbnail */, false /* isInitialSplit */);
mSecondFloatingTaskView = FloatingTaskView.getFloatingTaskView(mActivity,
thumbnailView, thumbnailView.getThumbnail(),
iconView.getDrawable(), secondTaskStartingBounds);
mSecondFloatingTaskView.setAlpha(1);
mSecondFloatingTaskView.addAnimation(pendingAnimation, secondTaskStartingBounds,
- secondTaskEndingBounds, true /* fadeWithThumbnail */);
+ secondTaskEndingBounds, true /* fadeWithThumbnail */, false /* isInitialSplit */);
pendingAnimation.addEndListener(aBoolean ->
mSplitSelectStateController.setSecondTaskId(task.key.id,
aBoolean1 -> RecentsView.this.resetFromSplitSelectionState()));
@@ -4110,7 +4110,7 @@
mTempRectF.set(mTempRect);
// TODO(194414938) set correct corner radius
mFirstFloatingTaskView.updateOrientationHandler(mOrientationHandler);
- mFirstFloatingTaskView.update(mTempRectF, /*progress=*/1f, /*windowRadius=*/0f);
+ mFirstFloatingTaskView.update(mTempRectF, /*progress=*/1f);
PagedOrientationHandler orientationHandler = getPagedOrientationHandler();
Pair<FloatProperty, FloatProperty> taskViewsFloat =
diff --git a/quickstep/src/com/android/quickstep/views/SplitPlaceholderView.java b/quickstep/src/com/android/quickstep/views/SplitPlaceholderView.java
index cfa482f..d37dfbf 100644
--- a/quickstep/src/com/android/quickstep/views/SplitPlaceholderView.java
+++ b/quickstep/src/com/android/quickstep/views/SplitPlaceholderView.java
@@ -17,9 +17,12 @@
package com.android.quickstep.views;
import android.content.Context;
+import android.graphics.Canvas;
+import android.graphics.Paint;
import android.graphics.drawable.Drawable;
import android.util.AttributeSet;
import android.util.FloatProperty;
+import android.util.TypedValue;
import android.view.Gravity;
import android.widget.FrameLayout;
@@ -27,6 +30,10 @@
public class SplitPlaceholderView extends FrameLayout {
+ private final Paint mPaint = new Paint(Paint.ANTI_ALIAS_FLAG);
+
+ private FloatingTaskView.FullscreenDrawParams mFullscreenParams;
+
public static final FloatProperty<SplitPlaceholderView> ALPHA_FLOAT =
new FloatProperty<SplitPlaceholderView>("SplitViewAlpha") {
@Override
@@ -46,6 +53,17 @@
public SplitPlaceholderView(Context context, AttributeSet attrs) {
super(context, attrs);
+
+ mPaint.setColor(getThemePrimaryColor(context));
+ setWillNotDraw(false);
+ }
+
+ @Override
+ protected void dispatchDraw(Canvas canvas) {
+ // Call this before super call to draw below the children.
+ drawBackground(canvas);
+
+ super.dispatchDraw(canvas);
}
@Nullable
@@ -53,6 +71,10 @@
return mIconView;
}
+ public void setFullscreenParams(FloatingTaskView.FullscreenDrawParams fullscreenParams) {
+ mFullscreenParams = fullscreenParams;
+ }
+
public void setIcon(Drawable drawable, int iconSize) {
if (mIconView == null) {
mIconView = new IconView(getContext());
@@ -64,4 +86,20 @@
params.gravity = Gravity.CENTER;
mIconView.setLayoutParams(params);
}
+
+ private void drawBackground(Canvas canvas) {
+ if (mFullscreenParams == null) {
+ return;
+ }
+
+ canvas.drawRoundRect(0, 0, getMeasuredWidth(), getMeasuredHeight(),
+ mFullscreenParams.mCurrentDrawnCornerRadius / mFullscreenParams.mScaleX,
+ mFullscreenParams.mCurrentDrawnCornerRadius / mFullscreenParams.mScaleY, mPaint);
+ }
+
+ private static int getThemePrimaryColor(Context context) {
+ final TypedValue value = new TypedValue();
+ context.getTheme().resolveAttribute(android.R.attr.colorPrimary, value, true);
+ return value.data;
+ }
}
diff --git a/quickstep/src/com/android/quickstep/views/TaskThumbnailView.java b/quickstep/src/com/android/quickstep/views/TaskThumbnailView.java
index 60b0d17..11f9ddd 100644
--- a/quickstep/src/com/android/quickstep/views/TaskThumbnailView.java
+++ b/quickstep/src/com/android/quickstep/views/TaskThumbnailView.java
@@ -50,6 +50,7 @@
import com.android.launcher3.BaseActivity;
import com.android.launcher3.DeviceProfile;
import com.android.launcher3.Utilities;
+import com.android.launcher3.icons.BitmapRenderer;
import com.android.launcher3.util.MainThreadInitializedObject;
import com.android.launcher3.util.SystemUiController;
import com.android.quickstep.TaskOverlayFactory.TaskOverlay;
@@ -161,6 +162,23 @@
setThumbnail(task, thumbnailData, true /* refreshNow */);
}
+ /**
+ * By combining the two in a single bitmap then we only have to do a single draw
+ * call in the onDraw function. Also, this fixes a bug where the background was
+ * visible in the corners because of anti-aliasing.
+ */
+ public Bitmap combineThumbnailAndBackground(Bitmap bm) {
+ return BitmapRenderer.createHardwareBitmap(bm.getWidth(), bm.getHeight(), c -> {
+ final boolean drawBackgroundOnly = mTask == null || mTask.isLocked;
+ if (drawBackgroundOnly) {
+ c.drawPaint(mBackgroundPaint);
+ } else {
+ c.drawPaint(mBackgroundPaint);
+ c.drawBitmap(bm, 0, 0, null);
+ }
+ });
+ }
+
/** Updates the shader, paint, matrix to redraw. */
public void refresh() {
refresh(false);
@@ -173,6 +191,7 @@
private void refresh(boolean shouldRefreshOverlay) {
if (mThumbnailData != null && mThumbnailData.thumbnail != null) {
Bitmap bm = mThumbnailData.thumbnail;
+ bm = combineThumbnailAndBackground(bm);
bm.prepareToDraw();
mBitmapShader = new BitmapShader(bm, Shader.TileMode.CLAMP, Shader.TileMode.CLAMP);
mPaint.setShader(mBitmapShader);
@@ -194,7 +213,6 @@
* <p>
* If dimAlpha is 0, no dimming is applied; if dimAlpha is 1, the thumbnail will be the
* extracted background color.
- *
*/
public void setDimAlpha(float dimAlpha) {
mDimAlpha = dimAlpha;
@@ -296,18 +314,6 @@
return;
}
}
-
- // Always draw the background since the snapshots might be translucent or partially empty
- // (For example, tasks been reparented out of dismissing split root when drag-to-dismiss
- // split screen).
- canvas.drawRoundRect(x, y, width, height, cornerRadius, cornerRadius, mBackgroundPaint);
-
- final boolean drawBackgroundOnly = mTask == null || mTask.isLocked || mBitmapShader == null
- || mThumbnailData == null;
- if (drawBackgroundOnly) {
- return;
- }
-
canvas.drawRoundRect(x, y, width, height, cornerRadius, cornerRadius, mPaint);
}
@@ -338,7 +344,6 @@
private void updateThumbnailPaintFilter() {
ColorFilter filter = getColorFilter(mDimAlpha);
- mBackgroundPaint.setColorFilter(filter);
int alpha = (int) (mDimAlpha * 255);
mDimmingPaintAfterClearing.setAlpha(alpha);
if (mBitmapShader != null) {
diff --git a/quickstep/src/com/android/quickstep/views/TaskView.java b/quickstep/src/com/android/quickstep/views/TaskView.java
index f716965..984b0ef 100644
--- a/quickstep/src/com/android/quickstep/views/TaskView.java
+++ b/quickstep/src/com/android/quickstep/views/TaskView.java
@@ -912,31 +912,31 @@
public void setOrientationState(RecentsOrientedState orientationState) {
PagedOrientationHandler orientationHandler = orientationState.getOrientationHandler();
boolean isRtl = getLayoutDirection() == LAYOUT_DIRECTION_RTL;
- LayoutParams snapshotParams = (LayoutParams) mSnapshotView.getLayoutParams();
DeviceProfile deviceProfile = mActivity.getDeviceProfile();
- snapshotParams.topMargin = deviceProfile.overviewTaskThumbnailTopMarginPx;
+
boolean isGridTask = isGridTask();
+ LayoutParams iconParams = (LayoutParams) mIconView.getLayoutParams();
+
+ int thumbnailTopMargin = deviceProfile.overviewTaskThumbnailTopMarginPx;
int taskIconHeight = deviceProfile.overviewTaskIconSizePx;
int taskMargin = isGridTask ? deviceProfile.overviewTaskMarginGridPx
: deviceProfile.overviewTaskMarginPx;
- int taskIconMargin = snapshotParams.topMargin - taskIconHeight - taskMargin;
- LayoutParams iconParams = (LayoutParams) mIconView.getLayoutParams();
- orientationHandler.setIconAndSnapshotParams(mIconView, taskIconMargin, taskIconHeight,
- snapshotParams, isRtl);
- updateDwbPlacement();
- mSnapshotView.setLayoutParams(snapshotParams);
+ int taskIconMargin = thumbnailTopMargin - taskIconHeight - taskMargin;
+ orientationHandler.setTaskIconParams(iconParams, taskIconMargin, taskIconHeight,
+ thumbnailTopMargin, isRtl);
iconParams.width = iconParams.height = taskIconHeight;
mIconView.setLayoutParams(iconParams);
+
mIconView.setRotation(orientationHandler.getDegreesRotated());
int iconDrawableSize = isGridTask ? deviceProfile.overviewTaskIconDrawableSizeGridPx
: deviceProfile.overviewTaskIconDrawableSizePx;
mIconView.setDrawableSize(iconDrawableSize, iconDrawableSize);
- snapshotParams.topMargin = deviceProfile.overviewTaskThumbnailTopMarginPx;
- mSnapshotView.setLayoutParams(snapshotParams);
- mSnapshotView.getTaskOverlay().updateOrientationState(orientationState);
- }
- private void updateDwbPlacement() {
+ LayoutParams snapshotParams = (LayoutParams) mSnapshotView.getLayoutParams();
+ snapshotParams.topMargin = thumbnailTopMargin;
+ mSnapshotView.setLayoutParams(snapshotParams);
+
+ mSnapshotView.getTaskOverlay().updateOrientationState(orientationState);
mDigitalWellBeingToast.initialize(mTask);
}
diff --git a/quickstep/tests/src/com/android/quickstep/FallbackRecentsTest.java b/quickstep/tests/src/com/android/quickstep/FallbackRecentsTest.java
index 4529217..9a39b34 100644
--- a/quickstep/tests/src/com/android/quickstep/FallbackRecentsTest.java
+++ b/quickstep/tests/src/com/android/quickstep/FallbackRecentsTest.java
@@ -42,6 +42,7 @@
import android.content.Intent;
import android.content.pm.ActivityInfo;
import android.os.RemoteException;
+import android.platform.test.rule.CrashDetector;
import androidx.test.filters.LargeTest;
import androidx.test.runner.AndroidJUnit4;
@@ -105,7 +106,8 @@
}
mOrderSensitiveRules = RuleChain
- .outerRule(new NavigationModeSwitchRule(mLauncher))
+ .outerRule(new CrashDetector("com.android.systemui"))
+ .around(new NavigationModeSwitchRule(mLauncher))
.around(new FailureWatcher(mDevice, mLauncher));
mOtherLauncherActivity = context.getPackageManager().queryIntentActivities(
diff --git a/res/color-night-v31/all_apps_button_color_2.xml b/res/color-night-v31/all_apps_button_color_2.xml
new file mode 100644
index 0000000..30b972f
--- /dev/null
+++ b/res/color-night-v31/all_apps_button_color_2.xml
@@ -0,0 +1,20 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- 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.
+-->
+<selector xmlns:android="http://schemas.android.com/apk/res/android" >
+ <item
+ android:color="@android:color/system_accent2_50"
+ android:lStar="98" />
+</selector>
diff --git a/res/color-v31/all_apps_button_bg_color.xml b/res/color-v31/all_apps_button_bg_color.xml
new file mode 100644
index 0000000..3ad38bc
--- /dev/null
+++ b/res/color-v31/all_apps_button_bg_color.xml
@@ -0,0 +1,20 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- 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.
+-->
+<selector xmlns:android="http://schemas.android.com/apk/res/android" >
+ <item
+ android:color="@android:color/system_neutral1_50"
+ android:lStar="98" />
+</selector>
diff --git a/res/color-v31/all_apps_button_color_1.xml b/res/color-v31/all_apps_button_color_1.xml
new file mode 100644
index 0000000..2d0895e
--- /dev/null
+++ b/res/color-v31/all_apps_button_color_1.xml
@@ -0,0 +1,20 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- 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.
+-->
+<selector xmlns:android="http://schemas.android.com/apk/res/android" >
+ <item
+ android:color="@android:color/system_accent1_50"
+ android:lStar="40" />
+</selector>
diff --git a/res/color-v31/all_apps_button_color_2.xml b/res/color-v31/all_apps_button_color_2.xml
new file mode 100644
index 0000000..7674b43
--- /dev/null
+++ b/res/color-v31/all_apps_button_color_2.xml
@@ -0,0 +1,20 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- 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.
+-->
+<selector xmlns:android="http://schemas.android.com/apk/res/android" >
+ <item
+ android:color="@android:color/system_accent2_50"
+ android:lStar="48" />
+</selector>
diff --git a/res/color-v31/all_apps_button_color_3.xml b/res/color-v31/all_apps_button_color_3.xml
new file mode 100644
index 0000000..17cb54f
--- /dev/null
+++ b/res/color-v31/all_apps_button_color_3.xml
@@ -0,0 +1,20 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- 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.
+-->
+<selector xmlns:android="http://schemas.android.com/apk/res/android" >
+ <item
+ android:color="@android:color/system_accent1_50"
+ android:lStar="35" />
+</selector>
diff --git a/res/color-v31/all_apps_button_color_4.xml b/res/color-v31/all_apps_button_color_4.xml
new file mode 100644
index 0000000..a6150f1
--- /dev/null
+++ b/res/color-v31/all_apps_button_color_4.xml
@@ -0,0 +1,20 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- 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.
+-->
+<selector xmlns:android="http://schemas.android.com/apk/res/android" >
+ <item
+ android:color="@android:color/system_accent3_50"
+ android:lStar="48" />
+</selector>
diff --git a/res/drawable/bg_all_apps_bottom_sheet.xml b/res/drawable/bg_all_apps_bottom_sheet.xml
deleted file mode 100644
index dba2fee..0000000
--- a/res/drawable/bg_all_apps_bottom_sheet.xml
+++ /dev/null
@@ -1,29 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
- 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.
--->
-<ripple android:color="?android:attr/colorControlHighlight"
- xmlns:android="http://schemas.android.com/apk/res/android"
- xmlns:androidprv="http://schemas.android.com/apk/prv/res/android">
- <item>
- <shape android:shape="rectangle"
- android:tint="?colorButtonNormal">
- <corners
- android:topLeftRadius="@dimen/dialogCornerRadius"
- android:topRightRadius="@dimen/dialogCornerRadius"/>
- <solid android:color="?attr/allAppsScrimColor" />
- </shape>
- </item>
-</ripple>
\ No newline at end of file
diff --git a/res/drawable/bg_rounded_corner_bottom_sheet.xml b/res/drawable/bg_rounded_corner_bottom_sheet.xml
index aa49bce..dfcd354 100644
--- a/res/drawable/bg_rounded_corner_bottom_sheet.xml
+++ b/res/drawable/bg_rounded_corner_bottom_sheet.xml
@@ -16,7 +16,7 @@
<shape xmlns:android="http://schemas.android.com/apk/res/android"
android:shape="rectangle" >
- <solid android:color="@color/surface" />
+ <solid android:color="?android:attr/colorBackground" />
<corners
android:topLeftRadius="@dimen/dialogCornerRadius"
android:topRightRadius="@dimen/dialogCornerRadius" />
diff --git a/res/drawable/bg_rounded_corner_bottom_sheet_handle.xml b/res/drawable/bg_rounded_corner_bottom_sheet_handle.xml
new file mode 100644
index 0000000..c502178
--- /dev/null
+++ b/res/drawable/bg_rounded_corner_bottom_sheet_handle.xml
@@ -0,0 +1,22 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- 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.
+-->
+
+<shape xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:androidprv="http://schemas.android.com/apk/prv/res/android"
+ android:shape="rectangle" >
+ <solid android:color="?androidprv:attr/colorSurfaceVariant"/>
+ <corners android:radius="@dimen/bottom_sheet_handle_corner_radius" />
+</shape>
diff --git a/res/drawable/ic_all_apps_button.xml b/res/drawable/ic_all_apps_button.xml
index 52b919b..5770d3c 100644
--- a/res/drawable/ic_all_apps_button.xml
+++ b/res/drawable/ic_all_apps_button.xml
@@ -18,26 +18,27 @@
android:width="80dp"
android:height="80dp"
android:viewportWidth="80"
- android:viewportHeight="80">
+ android:viewportHeight="80"
+ android:theme="@style/AllAppsTheme">
<path
android:pathData="M40,0.5L40,0.5c21.8,0 39.5,17.7 39.5,39.5l0,0c0,21.8 -17.7,39.5 -39.5,39.5l0,0C18.2,79.5 0.5,61.8 0.5,40l0,0C0.5,18.2 18.2,0.5 40,0.5z"
- android:fillColor="#F7F9FA"/>
+ android:fillColor="?attr/allAppsButtonBgColor"/>
<path
android:pathData="M26.8,32.1m-5.3,0a5.3,5.3 0,1 1,10.6 0a5.3,5.3 0,1 1,-10.6 0"
- android:fillColor="#00677E"/>
+ android:fillColor="?attr/allAppsButtonColor1"/>
<path
android:pathData="M26.8,47.9m-5.3,0a5.3,5.3 0,1 1,10.6 0a5.3,5.3 0,1 1,-10.6 0"
- android:fillColor="#5F757E"/>
+ android:fillColor="?attr/allAppsButtonColor2"/>
<path
android:pathData="M40,32.1m-5.3,0a5.3,5.3 0,1 1,10.6 0a5.3,5.3 0,1 1,-10.6 0"
- android:fillColor="#5F757E"/>
+ android:fillColor="?attr/allAppsButtonColor3"/>
<path
android:pathData="M40,47.9m-5.3,0a5.3,5.3 0,1 1,10.6 0a5.3,5.3 0,1 1,-10.6 0"
- android:fillColor="#6C6F93"/>
+ android:fillColor="?attr/allAppsButtonColor2"/>
<path
android:pathData="M53.2,32.1m-5.3,0a5.3,5.3 0,1 1,10.6 0a5.3,5.3 0,1 1,-10.6 0"
- android:fillColor="#005A6E"/>
+ android:fillColor="?attr/allAppsButtonColor4"/>
<path
android:pathData="M53.2,47.9m-5.3,0a5.3,5.3 0,1 1,10.6 0a5.3,5.3 0,1 1,-10.6 0"
- android:fillColor="#5F757E"/>
+ android:fillColor="?attr/allAppsButtonColor2"/>
</vector>
diff --git a/res/layout/all_apps_bottom_sheet_background.xml b/res/layout/all_apps_bottom_sheet_background.xml
index ad10d68..12b6b7b 100644
--- a/res/layout/all_apps_bottom_sheet_background.xml
+++ b/res/layout/all_apps_bottom_sheet_background.xml
@@ -17,19 +17,19 @@
android:id="@+id/bottom_sheet_background"
android:layout_width="match_parent"
android:layout_height="match_parent"
- android:background="@drawable/bg_all_apps_bottom_sheet">
+ android:background="@drawable/bg_rounded_corner_bottom_sheet">
<View
android:id="@+id/bottom_sheet_handle_area"
android:layout_width="match_parent"
- android:layout_height="34dp" />
+ android:layout_height="36dp" />
<View
android:id="@+id/bottom_sheet_handle"
- android:layout_width="48dp"
- android:layout_height="2dp"
+ android:layout_width="@dimen/bottom_sheet_handle_width"
+ android:layout_height="@dimen/bottom_sheet_handle_height"
android:layout_gravity="center_horizontal"
- android:layout_marginTop="16dp"
- android:layout_marginBottom="16dp"
- android:background="?android:attr/textColorSecondary" />
+ android:layout_marginTop="@dimen/bottom_sheet_handle_margin"
+ android:layout_marginBottom="@dimen/bottom_sheet_handle_margin"
+ android:background="@drawable/bg_rounded_corner_bottom_sheet_handle" />
</FrameLayout>
diff --git a/res/layout/floating_split_select_view.xml b/res/layout/floating_split_select_view.xml
index 8d47f4e..e4ca52e 100644
--- a/res/layout/floating_split_select_view.xml
+++ b/res/layout/floating_split_select_view.xml
@@ -4,7 +4,7 @@
android:layout_width="match_parent"
android:layout_height="match_parent">
- <ImageView
+ <com.android.quickstep.views.FloatingTaskThumbnailView
android:id="@+id/thumbnail"
android:layout_width="match_parent"
android:layout_height="match_parent"
@@ -14,7 +14,6 @@
android:id="@+id/split_placeholder"
android:layout_width="match_parent"
android:layout_height="@dimen/split_placeholder_size"
- android:background="?android:colorPrimary"
android:visibility="gone" />
</com.android.quickstep.views.FloatingTaskView>
\ No newline at end of file
diff --git a/res/layout/widgets_bottom_sheet_content.xml b/res/layout/widgets_bottom_sheet_content.xml
index 1a2cfc6..a5f72ef 100644
--- a/res/layout/widgets_bottom_sheet_content.xml
+++ b/res/layout/widgets_bottom_sheet_content.xml
@@ -19,16 +19,16 @@
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="@drawable/bg_rounded_corner_bottom_sheet"
- android:paddingTop="16dp"
+ android:paddingTop="@dimen/bottom_sheet_handle_margin"
android:orientation="vertical">
<View
android:id="@+id/collapse_handle"
- android:layout_width="48dp"
- android:layout_height="2dp"
+ android:layout_width="@dimen/bottom_sheet_handle_width"
+ android:layout_height="@dimen/bottom_sheet_handle_height"
android:layout_gravity="center_horizontal"
- android:layout_marginBottom="16dp"
+ android:layout_marginBottom="@dimen/bottom_sheet_handle_margin"
android:visibility="gone"
- android:background="?android:attr/textColorSecondary"/>
+ android:background="@drawable/bg_rounded_corner_bottom_sheet_handle"/>
<TextView
style="@style/TextHeadline"
android:id="@+id/title"
diff --git a/res/layout/widgets_full_sheet.xml b/res/layout/widgets_full_sheet.xml
index 309dc42..505ecb1 100644
--- a/res/layout/widgets_full_sheet.xml
+++ b/res/layout/widgets_full_sheet.xml
@@ -31,11 +31,11 @@
<View
android:id="@+id/collapse_handle"
- android:layout_width="48dp"
- android:layout_height="2dp"
- android:layout_marginTop="16dp"
+ android:layout_width="@dimen/bottom_sheet_handle_width"
+ android:layout_height="@dimen/bottom_sheet_handle_height"
+ android:layout_marginTop="@dimen/bottom_sheet_handle_margin"
android:layout_centerHorizontal="true"
- android:background="?android:attr/textColorSecondary"/>
+ android:background="@drawable/bg_rounded_corner_bottom_sheet_handle"/>
<TextView
android:id="@+id/no_widgets_text"
diff --git a/res/values-de/strings.xml b/res/values-de/strings.xml
index a0c784f..1ddd652 100644
--- a/res/values-de/strings.xml
+++ b/res/values-de/strings.xml
@@ -103,7 +103,7 @@
<string name="folder_name_format_overflow" msgid="4270108890534995199">"Ordner: <xliff:g id="NAME">%1$s</xliff:g>, <xliff:g id="SIZE">%2$d</xliff:g> oder mehr Elemente"</string>
<string name="wallpaper_button_text" msgid="8404103075899945851">"Hintergründe"</string>
<string name="styles_wallpaper_button_text" msgid="8216961355289236794">"Hintergrund & Stil"</string>
- <string name="settings_button_text" msgid="8873672322605444408">"Startbildschirm-Einstellungen"</string>
+ <string name="settings_button_text" msgid="8873672322605444408">"Einstellungen"</string>
<string name="msg_disabled_by_admin" msgid="6898038085516271325">"Von deinem Administrator deaktiviert"</string>
<string name="allow_rotation_title" msgid="7728578836261442095">"Drehen des Startbildschirms zulassen"</string>
<string name="allow_rotation_desc" msgid="8662546029078692509">"Beim Drehen des Smartphones"</string>
diff --git a/res/values-night-v31/colors.xml b/res/values-night-v31/colors.xml
index 2c1bc90..eefe8c5 100644
--- a/res/values-night-v31/colors.xml
+++ b/res/values-night-v31/colors.xml
@@ -24,4 +24,9 @@
<color name="home_settings_thumb_off_color">@android:color/system_neutral2_300</color>
<color name="home_settings_track_on_color">@android:color/system_accent2_700</color>
<color name="home_settings_track_off_color">@android:color/system_neutral1_700</color>
+
+ <color name="all_apps_button_bg_color">@android:color/system_neutral1_800</color>
+ <color name="all_apps_button_color_1">@android:color/system_accent1_300</color>
+ <color name="all_apps_button_color_3">@android:color/system_accent1_100</color>
+ <color name="all_apps_button_color_4">@android:color/system_accent2_100</color>
</resources>
\ No newline at end of file
diff --git a/res/values-night/colors.xml b/res/values-night/colors.xml
new file mode 100644
index 0000000..ce272ce
--- /dev/null
+++ b/res/values-night/colors.xml
@@ -0,0 +1,25 @@
+<?xml version="1.0" encoding="utf-8"?><!--
+/*
+* 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.
+*/
+-->
+
+<resources>
+ <color name="all_apps_button_bg_color">#2E3132</color>
+ <color name="all_apps_button_color_1">#33B9DB</color>
+ <color name="all_apps_button_color_2">#EFFBFF</color>
+ <color name="all_apps_button_color_3">#B1EBFF</color>
+ <color name="all_apps_button_color_4">#DEE0FF</color>
+</resources>
\ No newline at end of file
diff --git a/res/values-or/strings.xml b/res/values-or/strings.xml
index 1149e02..5612191 100644
--- a/res/values-or/strings.xml
+++ b/res/values-or/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="745542879510751525">"ଆପଗୁଡ଼ିକୁ ନଖୋଲି ସୂଚନା ପାଇବା ପାଇଁ, ଆପଣ ଆପଣଙ୍କ ମୂଳସ୍କ୍ରିନରେ ୱିଜେଟଗୁଡ଼ିକୁ ଯୋଗ କରିପାରିବେ"</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>
@@ -79,10 +79,10 @@
<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="1941457408239617576">"ହୋମ୍ ସେଟିଙ୍ଗ ଏବଂ ଶର୍ଟକଟ୍ ପଢ଼ନ୍ତୁ"</string>
- <string name="permdesc_read_settings" msgid="5833423719057558387">"ହୋମରେ ସେଟିଙ୍ଗ ପଢ଼ିବାକୁ ଆପ ଏବଂ ଶର୍ଟକଟକୁ ଅନୁମତି ଦିଏ।"</string>
- <string name="permlab_write_settings" msgid="3574213698004620587">"ହୋମ୍ ସେଟିଙ୍ଗ ଏବଂ ଶର୍ଟକଟ୍ ଲେଖନ୍ତୁ"</string>
- <string name="permdesc_write_settings" msgid="5440712911516509985">"ହୋମରେ ସେଟିଙ୍ଗ ଏବଂ ଶର୍ଟକଟ୍ ପରିବର୍ତ୍ତନ କରିବାକୁ ଆପକୁ ଅନୁମତି ଦିଏ।"</string>
+ <string name="permlab_read_settings" msgid="1941457408239617576">"ହୋମ ସେଟିଂସ ଏବଂ ସର୍ଟକଟ ପଢ଼ନ୍ତୁ"</string>
+ <string name="permdesc_read_settings" msgid="5833423719057558387">"ହୋମରେ ସେଟିଂସ ଏବଂ ସର୍ଟକଟକୁ ପଢ଼ିବା ପାଇଁ ଆପକୁ ଅନୁମତି ଦିଏ।"</string>
+ <string name="permlab_write_settings" msgid="3574213698004620587">"ହୋମ ସେଟିଂସ ଏବଂ ସର୍ଟକଟ ଲେଖନ୍ତୁ"</string>
+ <string name="permdesc_write_settings" msgid="5440712911516509985">"ହୋମରେ ସେଟିଂସ ଏବଂ ସର୍ଟକଟକୁ ପରିବର୍ତ୍ତନ କରିବା ପାଇଁ ଆପକୁ ଅନୁମତି ଦିଏ।"</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>
@@ -103,7 +103,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="7728578836261442095">"ହୋମ୍ ସ୍କ୍ରିନ୍ ବୁଲାଇବାକୁ ଅନୁମତି ଦିଅନ୍ତୁ"</string>
<string name="allow_rotation_desc" msgid="8662546029078692509">"ଯେତେବେଳେ ଫୋନକୁ ବୁଲାଯାଇଥାଏ"</string>
@@ -112,7 +112,7 @@
<string name="notification_dots_desc_off" msgid="1760796511504341095">"ବନ୍ଦ କରନ୍ତୁ"</string>
<string name="title_missing_notification_access" msgid="7503287056163941064">"ବିଜ୍ଞପ୍ତି ଆକ୍ସେସ୍ ଆବଶ୍ୟକ ଅଟେ"</string>
<string name="msg_missing_notification_access" msgid="281113995110910548">"ବିଜ୍ଞପ୍ତି ବିନ୍ଦୁ ଦେଖାଇବାକୁ, <xliff:g id="NAME">%1$s</xliff:g> ପାଇଁ ଆପ୍ ବିଜ୍ଞପ୍ତି ଅନ୍ କରନ୍ତୁ"</string>
- <string name="title_change_settings" msgid="1376365968844349552">"ସେଟିଂସ୍ ପରିବର୍ତ୍ତନ କରନ୍ତୁ"</string>
+ <string name="title_change_settings" msgid="1376365968844349552">"ସେଟିଂସ ପରିବର୍ତ୍ତନ କରନ୍ତୁ"</string>
<string name="notification_dots_service_title" msgid="4284221181793592871">"ବିଜ୍ଞପ୍ତି ଡଟ୍ଗୁଡ଼ିକୁ ଦେଖାନ୍ତୁ"</string>
<string name="auto_add_shortcuts_label" msgid="3698776050751790653">"ହୋମ୍ ସ୍କ୍ରିନରେ ଆପ୍ ଆଇକନଗୁଡ଼ିକୁ ଯୋଗ କରନ୍ତୁ"</string>
<string name="auto_add_shortcuts_description" msgid="7117251166066978730">"ନୂଆ ଆପ୍ ପାଇଁ"</string>
diff --git a/res/values-sw600dp/dimens.xml b/res/values-sw600dp/dimens.xml
index 3dde3f6..92f806e 100644
--- a/res/values-sw600dp/dimens.xml
+++ b/res/values-sw600dp/dimens.xml
@@ -22,7 +22,8 @@
<dimen name="widget_list_horizontal_margin">32dp</dimen>
<!-- AllApps -->
- <dimen name="all_apps_bottom_sheet_horizontal_padding">32dp</dimen>
+ <dimen name="all_apps_search_bar_content_overlap">0dp</dimen>
+ <dimen name="all_apps_bottom_sheet_horizontal_padding">46dp</dimen>
<!-- Fast scroll -->
<dimen name="fastscroll_popup_width">75dp</dimen>
diff --git a/res/values-sw720dp-land/dimens.xml b/res/values-sw720dp-land/dimens.xml
new file mode 100644
index 0000000..a9e0fb8
--- /dev/null
+++ b/res/values-sw720dp-land/dimens.xml
@@ -0,0 +1,20 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- 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.
+-->
+
+<resources>
+<!-- AllApps -->
+ <dimen name="all_apps_top_padding">0dp</dimen>
+</resources>
diff --git a/res/values-sw720dp/dimens.xml b/res/values-sw720dp/dimens.xml
index 9d7941f..5c314d5 100644
--- a/res/values-sw720dp/dimens.xml
+++ b/res/values-sw720dp/dimens.xml
@@ -16,5 +16,6 @@
<resources>
<!-- AllApps -->
- <dimen name="all_apps_bottom_sheet_horizontal_padding">41dp</dimen>
+ <dimen name="all_apps_top_padding">300dp</dimen>
+ <dimen name="all_apps_bottom_sheet_horizontal_padding">65dp</dimen>
</resources>
diff --git a/res/values/attrs.xml b/res/values/attrs.xml
index 0b04b86..99a337e 100644
--- a/res/values/attrs.xml
+++ b/res/values/attrs.xml
@@ -54,6 +54,12 @@
<attr name="workspaceAccentColor" format="color" />
<attr name="dropTargetHoverTextColor" format="color" />
+ <attr name="allAppsButtonBgColor" format="color" />
+ <attr name="allAppsButtonColor1" format="color" />
+ <attr name="allAppsButtonColor2" format="color" />
+ <attr name="allAppsButtonColor3" format="color" />
+ <attr name="allAppsButtonColor4" format="color" />
+
<!-- BubbleTextView specific attributes. -->
<declare-styleable name="BubbleTextView">
<attr name="layoutHorizontal" format="boolean" />
diff --git a/res/values/colors.xml b/res/values/colors.xml
index 0b1b451..2bc9239 100644
--- a/res/values/colors.xml
+++ b/res/values/colors.xml
@@ -79,4 +79,10 @@
<color name="workspace_accent_color_light">#ff8df5e3</color>
<color name="workspace_accent_color_dark">#ff3d665f</color>
+
+ <color name="all_apps_button_bg_color">#F7F9FA</color>
+ <color name="all_apps_button_color_1">#00677E</color>
+ <color name="all_apps_button_color_2">#00677E</color>
+ <color name="all_apps_button_color_3">#5F757E</color>
+ <color name="all_apps_button_color_4">#005A6E</color>
</resources>
diff --git a/res/values/dimens.xml b/res/values/dimens.xml
index ddc7d10..3e666fc 100644
--- a/res/values/dimens.xml
+++ b/res/values/dimens.xml
@@ -93,8 +93,11 @@
<dimen name="fastscroll_end_margin">-26dp</dimen>
<!-- All Apps -->
- <dimen name="all_apps_open_vertical_translate">320dp</dimen>
+ <dimen name="all_apps_starting_vertical_translate">320dp</dimen>
+ <dimen name="all_apps_top_padding">0dp</dimen>
<dimen name="all_apps_search_bar_field_height">48dp</dimen>
+ <!-- all_apps_search_bar_field_height / 2 -->
+ <dimen name="all_apps_search_bar_content_overlap">24dp</dimen>
<dimen name="all_apps_search_bar_bottom_padding">30dp</dimen>
<dimen name="all_apps_empty_search_message_top_offset">40dp</dimen>
<dimen name="all_apps_empty_search_bg_top_offset">144dp</dimen>
@@ -363,4 +366,9 @@
<dimen name="search_row_small_icon_size">32dp</dimen>
<dimen name="padded_rounded_button_padding">8dp</dimen>
+<!-- Bottom sheet related parameters -->
+ <dimen name="bottom_sheet_handle_width">32dp</dimen>
+ <dimen name="bottom_sheet_handle_height">4dp</dimen>
+ <dimen name="bottom_sheet_handle_margin">16dp</dimen>
+ <dimen name="bottom_sheet_handle_corner_radius">2dp</dimen>
</resources>
diff --git a/res/values/styles.xml b/res/values/styles.xml
index 818a032..864bb58 100644
--- a/res/values/styles.xml
+++ b/res/values/styles.xml
@@ -203,6 +203,14 @@
<item name="android:importantForAccessibility">no</item>
</style>
+ <style name="AllAppsButtonTheme">
+ <item name="allAppsButtonBgColor">@color/all_apps_button_bg_color</item>
+ <item name="allAppsButtonColor1">@color/all_apps_button_color_1</item>
+ <item name="allAppsButtonColor2">@color/all_apps_button_color_2</item>
+ <item name="allAppsButtonColor3">@color/all_apps_button_color_3</item>
+ <item name="allAppsButtonColor4">@color/all_apps_button_color_4</item>
+ </style>
+
<style name="AllAppsTheme">
<item name="disabledIconAlpha">.54</item>
</style>
diff --git a/src/com/android/launcher3/CellLayout.java b/src/com/android/launcher3/CellLayout.java
index 11f58e7..ad4cae4 100644
--- a/src/com/android/launcher3/CellLayout.java
+++ b/src/com/android/launcher3/CellLayout.java
@@ -1169,9 +1169,7 @@
// Apply local extracted color if the DragView is an AppWidgetHostViewDrawable.
View view = dragObject.dragView.getContentView();
if (view instanceof LauncherAppWidgetHostView) {
- Launcher launcher = Launcher.getLauncher(getContext());
- Workspace workspace = launcher.getWorkspace();
- int screenId = workspace.getIdForScreen(this);
+ int screenId = getWorkspace().getIdForScreen(this);
cellToRect(targetCell[0], targetCell[1], spanX, spanY, mTempRect);
((LauncherAppWidgetHostView) view).handleDrag(mTempRect, this, screenId);
@@ -1184,11 +1182,24 @@
return getContext().getString(R.string.move_to_hotseat_position,
Math.max(cellX, cellY) + 1);
} else {
- return getContext().getString(R.string.move_to_empty_cell,
- cellY + 1, cellX + 1);
+ Workspace workspace = getWorkspace();
+ int row = cellY + 1;
+ int col = workspace.mIsRtl ? mCountX - cellX : cellX + 1;
+ int panelCount = workspace.getPanelCount();
+ if (panelCount > 1) {
+ // Increment the column if the target is on the right side of a two panel home
+ int screenId = workspace.getIdForScreen(this);
+ int pageIndex = workspace.getPageIndexForScreenId(screenId);
+ col += (pageIndex % panelCount) * mCountX;
+ }
+ return getContext().getString(R.string.move_to_empty_cell, row, col);
}
}
+ private Workspace getWorkspace() {
+ return Launcher.cast(mActivity).getWorkspace();
+ }
+
public void clearDragOutlines() {
final int oldIndex = mDragOutlineCurrent;
mDragOutlineAnims[oldIndex].animateOut();
@@ -2243,7 +2254,7 @@
private void commitTempPlacement(View dragView) {
mTmpOccupied.copyTo(mOccupied);
- int screenId = Launcher.cast(mActivity).getWorkspace().getIdForScreen(this);
+ int screenId = getWorkspace().getIdForScreen(this);
int container = Favorites.CONTAINER_DESKTOP;
if (mContainerType == HOTSEAT) {
diff --git a/src/com/android/launcher3/DeviceProfile.java b/src/com/android/launcher3/DeviceProfile.java
index 62703ad..97c0f38 100644
--- a/src/com/android/launcher3/DeviceProfile.java
+++ b/src/com/android/launcher3/DeviceProfile.java
@@ -171,7 +171,8 @@
// All apps
public Point allAppsBorderSpacePx;
- public int allAppsOpenVerticalTranslate;
+ public int allAppsShiftRange;
+ public int allAppsTopPadding;
public int allAppsCellHeightPx;
public int allAppsCellWidthPx;
public int allAppsIconSizePx;
@@ -244,8 +245,7 @@
isTablet = info.isTablet(windowBounds);
isPhone = !isTablet;
isTwoPanels = isTablet && useTwoPanels;
- isTaskbarPresent = isTablet && ApiWrapper.TASKBAR_DRAWN_IN_PROCESS
- && FeatureFlags.ENABLE_TASKBAR.get();
+ isTaskbarPresent = isTablet && ApiWrapper.TASKBAR_DRAWN_IN_PROCESS;
// Some more constants.
context = getContext(context, info, isVerticalBarLayout() || (isTablet && isLandscape)
@@ -288,8 +288,11 @@
desiredWorkspaceHorizontalMarginPx = getHorizontalMarginPx(inv, res);
desiredWorkspaceHorizontalMarginOriginalPx = desiredWorkspaceHorizontalMarginPx;
- allAppsOpenVerticalTranslate = res.getDimensionPixelSize(
- R.dimen.all_apps_open_vertical_translate);
+ allAppsTopPadding = res.getDimensionPixelSize(R.dimen.all_apps_top_padding)
+ + (isTablet ? heightPx - availableHeightPx : 0);
+ allAppsShiftRange = isTablet
+ ? heightPx - allAppsTopPadding
+ : res.getDimensionPixelSize(R.dimen.all_apps_starting_vertical_translate);
folderLabelTextScale = res.getFloat(R.dimen.folder_label_text_scale);
folderContentPaddingLeftRight =
diff --git a/src/com/android/launcher3/FirstFrameAnimatorHelper.java b/src/com/android/launcher3/FirstFrameAnimatorHelper.java
index a199a57..fdf0101 100644
--- a/src/com/android/launcher3/FirstFrameAnimatorHelper.java
+++ b/src/com/android/launcher3/FirstFrameAnimatorHelper.java
@@ -15,7 +15,7 @@
*/
package com.android.launcher3;
-import static com.android.launcher3.util.DisplayController.getSingleFrameMs;
+import static com.android.launcher3.util.window.RefreshRateTracker.getSingleFrameMs;
import android.animation.ValueAnimator;
import android.animation.ValueAnimator.AnimatorUpdateListener;
diff --git a/src/com/android/launcher3/Hotseat.java b/src/com/android/launcher3/Hotseat.java
index cb0cc11..e1680fc 100644
--- a/src/com/android/launcher3/Hotseat.java
+++ b/src/com/android/launcher3/Hotseat.java
@@ -173,9 +173,15 @@
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
super.onMeasure(widthMeasureSpec, heightMeasureSpec);
- int width = mActivity.getDeviceProfile().isQsbInline
- ? mActivity.getDeviceProfile().qsbWidth
- : getShortcutsAndWidgets().getMeasuredWidth();
+ int width;
+ if (mActivity.getDeviceProfile().isQsbInline) {
+ width = mActivity.getDeviceProfile().qsbWidth;
+ } else {
+ MarginLayoutParams qsbParams = (MarginLayoutParams) mQsb.getLayoutParams();
+ width = getShortcutsAndWidgets().getMeasuredWidth()
+ - qsbParams.getMarginStart()
+ - qsbParams.getMarginEnd();
+ }
mQsb.measure(MeasureSpec.makeMeasureSpec(width, MeasureSpec.EXACTLY),
MeasureSpec.makeMeasureSpec(mQsbHeight, MeasureSpec.EXACTLY));
diff --git a/src/com/android/launcher3/Workspace.java b/src/com/android/launcher3/Workspace.java
index 16fecde..df97d2f 100644
--- a/src/com/android/launcher3/Workspace.java
+++ b/src/com/android/launcher3/Workspace.java
@@ -2484,21 +2484,27 @@
}
}
+ // Note, centerX represents the center of the object that is being dragged, visually. d.x
+ // represents the location of the finger within the dragged item.
+ float touchX;
+ float touchY = d.y;
+
+ // Go through the pages and check if the dragged item is inside one of them. This block
+ // is responsible for determining whether we need to snap to a different screen.
int nextPage = getNextPage();
- IntSet pageIndexesToVerify = IntSet.wrap(nextPage - 1, nextPage + 1);
- if (isTwoPanelEnabled()) {
- // If two panel is enabled, users can also drag items to nextPage + 2
- pageIndexesToVerify.add(nextPage + 2);
- }
-
- int touchX = (int) Math.min(centerX, d.x);
- int touchY = d.y;
-
- // Go through the pages and check if the dragged item is inside one of them
+ IntSet pageIndexesToVerify = IntSet.wrap(nextPage - 1, nextPage
+ + (isTwoPanelEnabled() ? 2 : 1));
for (int pageIndex : pageIndexesToVerify) {
if (layout != null || isPageInTransition()) {
break;
}
+
+ // When deciding whether to perform a page switch, we need to consider the most extreme
+ // X coordinate between the finger location and the center of the object being dragged.
+ // This is either the max or the min of the two depending on whether dragging to the
+ // left / right, respectively.
+ touchX = ((((pageIndex < nextPage) && !mIsRtl) || pageIndex > nextPage && mIsRtl)
+ ? Math.min(d.x, centerX) : Math.max(d.x, centerX));
layout = verifyInsidePage(pageIndex, touchX, touchY);
}
@@ -2507,12 +2513,16 @@
// on one panel just choose the current page.
if (layout == null && nextPage >= 0 && nextPage < getPageCount()) {
if (isTwoPanelEnabled()) {
+ // When determining which panel to use within a single screen, we always use
+ // the centroid of the object rather than the finger.
+ touchX = centerX;
nextPage = getScreenCenter(getScrollX()) > touchX
? (mIsRtl ? nextPage + 1 : nextPage) // left side
: (mIsRtl ? nextPage : nextPage + 1); // right side
}
layout = (CellLayout) getChildAt(nextPage);
}
+
if (layout != mDragTargetLayout) {
setCurrentDropLayout(layout);
setCurrentDragOverlappingLayout(layout);
@@ -3398,7 +3408,10 @@
// When the workspace is not loaded, we do not know how many screen will be bound.
return getContext().getString(R.string.home_screen);
}
- return getContext().getString(R.string.workspace_scroll_format, page + 1, nScreens);
+ int panelCount = getPanelCount();
+ int currentPage = (page / panelCount) + 1;
+ int totalPages = nScreens / panelCount + nScreens % panelCount;
+ return getContext().getString(R.string.workspace_scroll_format, currentPage, totalPages);
}
/**
diff --git a/src/com/android/launcher3/allapps/AllAppsTransitionController.java b/src/com/android/launcher3/allapps/AllAppsTransitionController.java
index b6a2459..cdc313f 100644
--- a/src/com/android/launcher3/allapps/AllAppsTransitionController.java
+++ b/src/com/android/launcher3/allapps/AllAppsTransitionController.java
@@ -89,15 +89,15 @@
private float mShiftRange; // changes depending on the orientation
private float mProgress; // [0, 1], mShiftRange * mProgress = shiftCurrent
- private float mScrollRangeDelta = 0;
private ScrimView mScrimView;
public AllAppsTransitionController(Launcher l) {
mLauncher = l;
- mShiftRange = mLauncher.getDeviceProfile().heightPx;
+ DeviceProfile dp = mLauncher.getDeviceProfile();
+ setShiftRange(dp.allAppsShiftRange);
mProgress = 1f;
- mIsVerticalLayout = mLauncher.getDeviceProfile().isVerticalBarLayout();
+ mIsVerticalLayout = dp.isVerticalBarLayout();
mLauncher.addOnDeviceProfileChangeListener(this);
}
@@ -108,7 +108,7 @@
@Override
public void onDeviceProfileChanged(DeviceProfile dp) {
mIsVerticalLayout = dp.isVerticalBarLayout();
- setScrollRangeDelta(mScrollRangeDelta);
+ setShiftRange(dp.allAppsShiftRange);
if (mIsVerticalLayout) {
mLauncher.getHotseat().setTranslationY(0);
@@ -160,12 +160,14 @@
}
// need to decide depending on the release velocity
- Interpolator interpolator = (config.userControlled ? LINEAR : DEACCEL_1_7);
-
+ Interpolator verticalProgressInterpolator = config.getInterpolator(ANIM_VERTICAL_PROGRESS,
+ config.userControlled ? LINEAR : DEACCEL_1_7);
Animator anim = createSpringAnimation(mProgress, targetProgress);
- anim.setInterpolator(config.getInterpolator(ANIM_VERTICAL_PROGRESS, interpolator));
+ anim.setInterpolator(verticalProgressInterpolator);
anim.addListener(getProgressAnimatorListener());
builder.add(anim);
+ // Use ANIM_VERTICAL_PROGRESS's interpolator to determine state transition threshold.
+ builder.setInterpolator(verticalProgressInterpolator);
setAlphas(toState, config, builder);
@@ -215,9 +217,8 @@
/**
* Updates the total scroll range but does not update the UI.
*/
- public void setScrollRangeDelta(float delta) {
- mScrollRangeDelta = delta;
- mShiftRange = mLauncher.getDeviceProfile().heightPx - mScrollRangeDelta;
+ public void setShiftRange(float shiftRange) {
+ mShiftRange = shiftRange;
}
/**
diff --git a/src/com/android/launcher3/allapps/BaseAllAppsContainerView.java b/src/com/android/launcher3/allapps/BaseAllAppsContainerView.java
index 59e21c0..bfc7515 100644
--- a/src/com/android/launcher3/allapps/BaseAllAppsContainerView.java
+++ b/src/com/android/launcher3/allapps/BaseAllAppsContainerView.java
@@ -408,7 +408,7 @@
if (grid.isVerticalBarLayout()) {
setPadding(grid.workspacePadding.left, 0, grid.workspacePadding.right, 0);
} else {
- setPadding(0, grid.isTablet ? insets.top : 0, 0, 0);
+ setPadding(0, grid.allAppsTopPadding, 0, 0);
}
InsettableFrameLayout.dispatchInsets(this, insets);
@@ -765,4 +765,11 @@
&& mVerticalFadingEdge);
}
}
+
+ /**
+ * Returns a view that denotes the visible part of all apps container view.
+ */
+ public View getVisibleContainerView() {
+ return mActivityContext.getDeviceProfile().isTablet ? mBottomSheetBackground : this;
+ }
}
diff --git a/src/com/android/launcher3/allapps/LauncherAllAppsContainerView.java b/src/com/android/launcher3/allapps/LauncherAllAppsContainerView.java
index 30d33f9..8601819 100644
--- a/src/com/android/launcher3/allapps/LauncherAllAppsContainerView.java
+++ b/src/com/android/launcher3/allapps/LauncherAllAppsContainerView.java
@@ -16,7 +16,6 @@
package com.android.launcher3.allapps;
import android.content.Context;
-import android.graphics.Rect;
import android.util.AttributeSet;
import android.view.MotionEvent;
@@ -59,12 +58,4 @@
}
return super.onTouchEvent(ev);
}
-
- @Override
- public void setInsets(Rect insets) {
- super.setInsets(insets);
- int allAppsStartingPositionY = mActivityContext.getDeviceProfile().availableHeightPx
- - mActivityContext.getDeviceProfile().allAppsOpenVerticalTranslate;
- mActivityContext.getAllAppsController().setScrollRangeDelta(allAppsStartingPositionY);
- }
}
diff --git a/src/com/android/launcher3/allapps/search/AppsSearchContainerLayout.java b/src/com/android/launcher3/allapps/search/AppsSearchContainerLayout.java
index ffc049b..4a886a4 100644
--- a/src/com/android/launcher3/allapps/search/AppsSearchContainerLayout.java
+++ b/src/com/android/launcher3/allapps/search/AppsSearchContainerLayout.java
@@ -82,7 +82,7 @@
setHint(prefixTextWithIcon(getContext(), R.drawable.ic_allapps_search, getHint()));
mContentOverlap =
- getResources().getDimensionPixelSize(R.dimen.all_apps_search_bar_field_height) / 2;
+ getResources().getDimensionPixelSize(R.dimen.all_apps_search_bar_content_overlap);
}
@Override
diff --git a/src/com/android/launcher3/anim/AnimatorPlaybackController.java b/src/com/android/launcher3/anim/AnimatorPlaybackController.java
index 85ca280..1cc0c21 100644
--- a/src/com/android/launcher3/anim/AnimatorPlaybackController.java
+++ b/src/com/android/launcher3/anim/AnimatorPlaybackController.java
@@ -19,7 +19,7 @@
import static com.android.launcher3.anim.Interpolators.LINEAR;
import static com.android.launcher3.anim.Interpolators.clampToProgress;
import static com.android.launcher3.anim.Interpolators.scrollInterpolatorForVelocity;
-import static com.android.launcher3.util.DisplayController.getSingleFrameMs;
+import static com.android.launcher3.util.window.RefreshRateTracker.getSingleFrameMs;
import android.animation.Animator;
import android.animation.Animator.AnimatorListener;
diff --git a/src/com/android/launcher3/anim/Interpolators.java b/src/com/android/launcher3/anim/Interpolators.java
index 1e7b224..9c12abd 100644
--- a/src/com/android/launcher3/anim/Interpolators.java
+++ b/src/com/android/launcher3/anim/Interpolators.java
@@ -130,6 +130,23 @@
}
};
+ public static final Interpolator LINEAR_TELEPORT = t -> {
+ float startTeleport = 0.2f;
+ float endTeleport = 0.4f;
+ float teleportProgress = 0.5f;
+ float v;
+ if (t < startTeleport) {
+ v = LINEAR.getInterpolation(t);
+ } else if (t < endTeleport) {
+ v = Utilities.mapToRange(t, startTeleport, endTeleport, startTeleport,
+ endTeleport + teleportProgress, ACCEL_DEACCEL);
+ } else {
+ v = LINEAR.getInterpolation(t) + teleportProgress;
+ }
+ v = Utilities.boundToRange(v, 0f, 1f);
+ return v;
+ };
+
private static final float FAST_FLING_PX_MS = 10;
public static Interpolator scrollInterpolatorForVelocity(float velocity) {
diff --git a/src/com/android/launcher3/anim/PendingAnimation.java b/src/com/android/launcher3/anim/PendingAnimation.java
index 3ab893b..1300ce7 100644
--- a/src/com/android/launcher3/anim/PendingAnimation.java
+++ b/src/com/android/launcher3/anim/PendingAnimation.java
@@ -77,6 +77,13 @@
addAnimationHoldersRecur(a, mDuration, springProperty, mAnimHolders);
}
+ /**
+ * Configures interpolator of the underlying AnimatorSet.
+ */
+ public void setInterpolator(TimeInterpolator interpolator) {
+ mAnim.setInterpolator(interpolator);
+ }
+
@Override
public void setViewAlpha(View view, float alpha, TimeInterpolator interpolator) {
if (view == null || view.getAlpha() == alpha) {
diff --git a/src/com/android/launcher3/anim/SpringAnimationBuilder.java b/src/com/android/launcher3/anim/SpringAnimationBuilder.java
index bd52158..40fa0cf 100644
--- a/src/com/android/launcher3/anim/SpringAnimationBuilder.java
+++ b/src/com/android/launcher3/anim/SpringAnimationBuilder.java
@@ -25,7 +25,7 @@
import androidx.annotation.FloatRange;
import androidx.dynamicanimation.animation.SpringForce;
-import com.android.launcher3.util.DisplayController;
+import com.android.launcher3.util.window.RefreshRateTracker;
/**
* Utility class to build an object animator which follows the same path as a spring animation for
@@ -134,7 +134,7 @@
}
public SpringAnimationBuilder computeParams() {
- int singleFrameMs = DisplayController.getSingleFrameMs(mContext);
+ int singleFrameMs = RefreshRateTracker.getSingleFrameMs(mContext);
double naturalFreq = Math.sqrt(mStiffness);
double dampedFreq = naturalFreq * Math.sqrt(1 - mDampingRatio * mDampingRatio);
diff --git a/src/com/android/launcher3/config/FeatureFlags.java b/src/com/android/launcher3/config/FeatureFlags.java
index a949e11..3458ed1 100644
--- a/src/com/android/launcher3/config/FeatureFlags.java
+++ b/src/com/android/launcher3/config/FeatureFlags.java
@@ -96,6 +96,13 @@
getDebugFlag("ENABLE_FLOATING_SEARCH_BAR", false,
"Keep All Apps search bar at the bottom (but above keyboard if open)");
+ public static final BooleanFlag INJECT_WEB_TOP = new DeviceFlag("INJECT_WEB_TOP", false,
+ "Show web suggestions on top of the search results");
+
+ public static final BooleanFlag USE_FALLBACK_APP_SEARCH = new DeviceFlag(
+ "USE_FALLBACK_APP_SEARCH", false,
+ "Use fallback launcher app search results instead of AiAi app results");
+
public static final BooleanFlag COLLECT_SEARCH_HISTORY = new DeviceFlag(
"COLLECT_SEARCH_HISTORY", false, "Allow launcher to collect search history for log");
@@ -197,12 +204,6 @@
"ENABLE_APP_PREDICTIONS_WHILE_VISIBLE", true, "Allows app "
+ "predictions to be updated while they are visible to the user.");
- public static final BooleanFlag ENABLE_TASKBAR = getDebugFlag(
- "ENABLE_TASKBAR", true, "Allows a system Taskbar to be shown on larger devices.");
-
- public static final BooleanFlag ENABLE_TASKBAR_EDU = getDebugFlag("ENABLE_TASKBAR_EDU", true,
- "Enables showing taskbar education the first time an app is opened.");
-
public static final BooleanFlag ENABLE_TASKBAR_POPUP_MENU = getDebugFlag(
"ENABLE_TASKBAR_POPUP_MENU", true, "Enables long pressing taskbar icons to show the"
+ " popup menu.");
@@ -252,10 +253,18 @@
"ENABLE_ALL_APPS_IN_TASKBAR", true,
"Enables accessing All Apps from the system Taskbar.");
+ public static final BooleanFlag ENABLE_ALL_APPS_ONE_SEARCH_IN_TASKBAR = getDebugFlag(
+ "ENABLE_ALL_APPS_ONE_SEARCH_IN_TASKBAR", false,
+ "Enables One Search box in Taskbar All Apps.");
+
public static final BooleanFlag ENABLE_SPLIT_FROM_WORKSPACE = getDebugFlag(
"ENABLE_SPLIT_FROM_WORKSPACE", true,
"Enable initiating split screen from workspace.");
+ public static final BooleanFlag ENABLE_NEW_MIGRATION_LOGIC = getDebugFlag(
+ "ENABLE_NEW_MIGRATION_LOGIC", true,
+ "Enable the new grid migration logic, keeping pages when src < dest");
+
public static void initialize(Context context) {
synchronized (sDebugFlags) {
for (DebugFlag flag : sDebugFlags) {
diff --git a/src/com/android/launcher3/folder/Folder.java b/src/com/android/launcher3/folder/Folder.java
index 1e6342c..8916519 100644
--- a/src/com/android/launcher3/folder/Folder.java
+++ b/src/com/android/launcher3/folder/Folder.java
@@ -24,7 +24,7 @@
import static com.android.launcher3.config.FeatureFlags.ALWAYS_USE_HARDWARE_OPTIMIZATION_FOR_FOLDER_ANIMATIONS;
import static com.android.launcher3.logging.StatsLogManager.LauncherEvent.LAUNCHER_FOLDER_LABEL_UPDATED;
import static com.android.launcher3.logging.StatsLogManager.LauncherEvent.LAUNCHER_ITEM_DROP_COMPLETED;
-import static com.android.launcher3.util.DisplayController.getSingleFrameMs;
+import static com.android.launcher3.util.window.RefreshRateTracker.getSingleFrameMs;
import android.animation.Animator;
import android.animation.AnimatorListenerAdapter;
diff --git a/src/com/android/launcher3/model/DeviceGridState.java b/src/com/android/launcher3/model/DeviceGridState.java
index 08c3149..3e49d79 100644
--- a/src/com/android/launcher3/model/DeviceGridState.java
+++ b/src/com/android/launcher3/model/DeviceGridState.java
@@ -38,7 +38,7 @@
/**
* Utility class representing persisted grid properties.
*/
-public class DeviceGridState {
+public class DeviceGridState implements Comparable<DeviceGridState> {
public static final String KEY_WORKSPACE_SIZE = "migration_src_workspace_size";
public static final String KEY_HOTSEAT_COUNT = "migration_src_hotseat_count";
@@ -84,16 +84,16 @@
*/
public LauncherEvent getWorkspaceSizeEvent() {
if (!TextUtils.isEmpty(mGridSizeString)) {
- switch (mGridSizeString.charAt(0)) {
- case '6':
+ switch (getColumns()) {
+ case 6:
return LAUNCHER_GRID_SIZE_6;
- case '5':
+ case 5:
return LAUNCHER_GRID_SIZE_5;
- case '4':
+ case 4:
return LAUNCHER_GRID_SIZE_4;
- case '3':
+ case 3:
return LAUNCHER_GRID_SIZE_3;
- case '2':
+ case 2:
return LAUNCHER_GRID_SIZE_2;
}
}
@@ -119,4 +119,21 @@
return mNumHotseat == other.mNumHotseat
&& Objects.equals(mGridSizeString, other.mGridSizeString);
}
+
+ public Integer getColumns() {
+ return Integer.parseInt(String.valueOf(mGridSizeString.charAt(0)));
+ }
+
+ public Integer getRows() {
+ return Integer.parseInt(String.valueOf(mGridSizeString.charAt(2)));
+ }
+
+ @Override
+ public int compareTo(DeviceGridState other) {
+ Integer size = getColumns() * getRows();
+ Integer otherSize = other.getColumns() * other.getRows();
+
+ return size.compareTo(otherSize);
+ }
+
}
diff --git a/src/com/android/launcher3/model/GridSizeMigrationTaskV2.java b/src/com/android/launcher3/model/GridSizeMigrationTaskV2.java
index ca680b7..74b0a6f 100644
--- a/src/com/android/launcher3/model/GridSizeMigrationTaskV2.java
+++ b/src/com/android/launcher3/model/GridSizeMigrationTaskV2.java
@@ -38,6 +38,7 @@
import com.android.launcher3.LauncherAppState;
import com.android.launcher3.LauncherSettings;
import com.android.launcher3.Utilities;
+import com.android.launcher3.config.FeatureFlags;
import com.android.launcher3.graphics.LauncherPreviewRenderer;
import com.android.launcher3.model.data.ItemInfo;
import com.android.launcher3.pm.InstallSessionHelper;
@@ -225,13 +226,21 @@
screens.add(screenId);
}
+ boolean preservePages = false;
+ if (screens.isEmpty() && FeatureFlags.ENABLE_NEW_MIGRATION_LOGIC.get()) {
+ DeviceGridState srcDeviceState = new DeviceGridState(mContext);
+ DeviceGridState destDeviceState = new DeviceGridState(idp);
+ preservePages = destDeviceState.compareTo(srcDeviceState) >= 0
+ && destDeviceState.getColumns() - srcDeviceState.getColumns() <= 2;
+ }
+
// Then we place the items on the screens
for (int screenId : screens) {
if (DEBUG) {
Log.d(TAG, "Migrating " + screenId);
}
GridPlacementSolution workspaceSolution = new GridPlacementSolution(mDb, mSrcReader,
- mDestReader, mContext, screenId, mTrgX, mTrgY, mWorkspaceDiff);
+ mDestReader, mContext, screenId, mTrgX, mTrgY, mWorkspaceDiff, false);
workspaceSolution.find();
if (mWorkspaceDiff.isEmpty()) {
break;
@@ -243,10 +252,12 @@
int screenId = mDestReader.mLastScreenId + 1;
while (!mWorkspaceDiff.isEmpty()) {
GridPlacementSolution workspaceSolution = new GridPlacementSolution(mDb, mSrcReader,
- mDestReader, mContext, screenId, mTrgX, mTrgY, mWorkspaceDiff);
+ mDestReader, mContext, screenId, mTrgX, mTrgY, mWorkspaceDiff,
+ preservePages);
workspaceSolution.find();
screenId++;
}
+
return true;
}
@@ -363,13 +374,15 @@
private final int mScreenId;
private final int mTrgX;
private final int mTrgY;
- private final List<DbEntry> mItemsToPlace;
+ private final List<DbEntry> mSortedItemsToPlace;
+ private final boolean mMatchingScreenIdOnly;
private int mNextStartX;
private int mNextStartY;
GridPlacementSolution(SQLiteDatabase db, DbReader srcReader, DbReader destReader,
- Context context, int screenId, int trgX, int trgY, List<DbEntry> itemsToPlace) {
+ Context context, int screenId, int trgX, int trgY, List<DbEntry> sortedItemsToPlace,
+ boolean matchingScreenIdOnly) {
mDb = db;
mSrcReader = srcReader;
mDestReader = destReader;
@@ -386,13 +399,16 @@
mOccupied.markCells(entry, true);
}
}
- mItemsToPlace = itemsToPlace;
+ mSortedItemsToPlace = sortedItemsToPlace;
+ mMatchingScreenIdOnly = matchingScreenIdOnly;
}
public void find() {
- Iterator<DbEntry> iterator = mItemsToPlace.iterator();
+ Iterator<DbEntry> iterator = mSortedItemsToPlace.iterator();
while (iterator.hasNext()) {
final DbEntry entry = iterator.next();
+ if (mMatchingScreenIdOnly && entry.screenId < mScreenId) continue;
+ if (mMatchingScreenIdOnly && entry.screenId > mScreenId) break;
if (entry.minSpanX > mTrgX || entry.minSpanY > mTrgY) {
iterator.remove();
continue;
@@ -494,7 +510,7 @@
private final SQLiteDatabase mDb;
private final String mTableName;
private final Context mContext;
- private final HashSet<String> mValidPackages;
+ private final Set<String> mValidPackages;
private int mLastScreenId = -1;
private final ArrayList<DbEntry> mHotseatEntries = new ArrayList<>();
@@ -503,7 +519,7 @@
new ArrayMap<>();
DbReader(SQLiteDatabase db, String tableName, Context context,
- HashSet<String> validPackages) {
+ Set<String> validPackages) {
mDb = db;
mTableName = tableName;
mContext = context;
diff --git a/src/com/android/launcher3/popup/PopupContainerWithArrow.java b/src/com/android/launcher3/popup/PopupContainerWithArrow.java
index 05d6fc6..2fa7945 100644
--- a/src/com/android/launcher3/popup/PopupContainerWithArrow.java
+++ b/src/com/android/launcher3/popup/PopupContainerWithArrow.java
@@ -508,7 +508,9 @@
@Override
protected void closeComplete() {
super.closeComplete();
- mActivityContext.getDragController().removeDragListener(this);
+ if (mActivityContext.getDragController() != null) {
+ mActivityContext.getDragController().removeDragListener(this);
+ }
PopupContainerWithArrow openPopup = getOpen(mActivityContext);
if (openPopup == null || openPopup.mOriginalIcon != mOriginalIcon) {
mOriginalIcon.setTextVisibility(mOriginalIcon.shouldTextBeVisible());
diff --git a/src/com/android/launcher3/touch/AbstractStateChangeTouchController.java b/src/com/android/launcher3/touch/AbstractStateChangeTouchController.java
index 61d488c..c00e174 100644
--- a/src/com/android/launcher3/touch/AbstractStateChangeTouchController.java
+++ b/src/com/android/launcher3/touch/AbstractStateChangeTouchController.java
@@ -26,7 +26,7 @@
import static com.android.launcher3.logging.StatsLogManager.LAUNCHER_STATE_OVERVIEW;
import static com.android.launcher3.logging.StatsLogManager.LauncherEvent.LAUNCHER_UNKNOWN_SWIPEDOWN;
import static com.android.launcher3.logging.StatsLogManager.LauncherEvent.LAUNCHER_UNKNOWN_SWIPEUP;
-import static com.android.launcher3.util.DisplayController.getSingleFrameMs;
+import static com.android.launcher3.util.window.RefreshRateTracker.getSingleFrameMs;
import android.animation.Animator.AnimatorListener;
import android.animation.ValueAnimator;
diff --git a/src/com/android/launcher3/touch/AllAppsSwipeController.java b/src/com/android/launcher3/touch/AllAppsSwipeController.java
index 989a9e4..f7d3492 100644
--- a/src/com/android/launcher3/touch/AllAppsSwipeController.java
+++ b/src/com/android/launcher3/touch/AllAppsSwipeController.java
@@ -17,9 +17,13 @@
import static com.android.launcher3.LauncherState.ALL_APPS;
import static com.android.launcher3.LauncherState.NORMAL;
+import static com.android.launcher3.anim.Interpolators.FINAL_FRAME;
+import static com.android.launcher3.anim.Interpolators.INSTANT;
import static com.android.launcher3.anim.Interpolators.LINEAR;
+import static com.android.launcher3.anim.Interpolators.LINEAR_TELEPORT;
import static com.android.launcher3.states.StateAnimationConfig.ANIM_ALL_APPS_FADE;
import static com.android.launcher3.states.StateAnimationConfig.ANIM_SCRIM_FADE;
+import static com.android.launcher3.states.StateAnimationConfig.ANIM_VERTICAL_PROGRESS;
import android.view.MotionEvent;
import android.view.animation.Interpolator;
@@ -94,9 +98,9 @@
LauncherState toState) {
StateAnimationConfig config = super.getConfigForStates(fromState, toState);
if (fromState == NORMAL && toState == ALL_APPS) {
- applyNormalToAllAppsAnimConfig(config);
+ applyNormalToAllAppsAnimConfig(mLauncher, config);
} else if (fromState == ALL_APPS && toState == NORMAL) {
- applyAllAppsToNormalConfig(config);
+ applyAllAppsToNormalConfig(mLauncher, config);
}
return config;
}
@@ -104,17 +108,24 @@
/**
* Applies Animation config values for transition from all apps to home
*/
- public static void applyAllAppsToNormalConfig(StateAnimationConfig config) {
+ public static void applyAllAppsToNormalConfig(Launcher launcher, StateAnimationConfig config) {
+ boolean isTablet = launcher.getDeviceProfile().isTablet;
config.setInterpolator(ANIM_SCRIM_FADE, ALLAPPS_STAGGERED_FADE_LATE_RESPONDER);
- config.setInterpolator(ANIM_ALL_APPS_FADE, ALLAPPS_STAGGERED_FADE_EARLY_RESPONDER);
+ config.setInterpolator(ANIM_ALL_APPS_FADE, isTablet
+ ? FINAL_FRAME : ALLAPPS_STAGGERED_FADE_EARLY_RESPONDER);
+ config.setInterpolator(ANIM_VERTICAL_PROGRESS, isTablet ? LINEAR_TELEPORT : LINEAR);
}
/**
* Applies Animation config values for transition from home to all apps
*/
- public static void applyNormalToAllAppsAnimConfig(StateAnimationConfig config) {
+ public static void applyNormalToAllAppsAnimConfig(Launcher launcher,
+ StateAnimationConfig config) {
+ boolean isTablet = launcher.getDeviceProfile().isTablet;
config.setInterpolator(ANIM_SCRIM_FADE, ALLAPPS_STAGGERED_FADE_EARLY_RESPONDER);
- config.setInterpolator(ANIM_ALL_APPS_FADE, ALLAPPS_STAGGERED_FADE_LATE_RESPONDER);
+ config.setInterpolator(ANIM_ALL_APPS_FADE, isTablet
+ ? INSTANT : ALLAPPS_STAGGERED_FADE_LATE_RESPONDER);
+ config.setInterpolator(ANIM_VERTICAL_PROGRESS, isTablet ? LINEAR_TELEPORT : LINEAR);
}
diff --git a/src/com/android/launcher3/touch/LandscapePagedViewHandler.java b/src/com/android/launcher3/touch/LandscapePagedViewHandler.java
index 4a55d2e..2609e54 100644
--- a/src/com/android/launcher3/touch/LandscapePagedViewHandler.java
+++ b/src/com/android/launcher3/touch/LandscapePagedViewHandler.java
@@ -178,18 +178,6 @@
}
@Override
- public int getSplitTaskViewDismissDirection(@StagePosition int stagePosition,
- DeviceProfile dp) {
- // Don't use device profile here because we know we're in fake landscape, only split option
- // available is top/left
- if (stagePosition == STAGE_POSITION_TOP_OR_LEFT) {
- // Top (visually left) side
- return SPLIT_TRANSLATE_PRIMARY_NEGATIVE;
- }
- throw new IllegalStateException("Invalid split stage position: " + stagePosition);
- }
-
- @Override
public int getPrimaryScroll(View view) {
return view.getScrollY();
}
@@ -469,14 +457,12 @@
}
@Override
- public void setIconAndSnapshotParams(View iconView, int taskIconMargin, int taskIconHeight,
- FrameLayout.LayoutParams snapshotParams, boolean isRtl) {
- FrameLayout.LayoutParams iconParams =
- (FrameLayout.LayoutParams) iconView.getLayoutParams();
+ public void setTaskIconParams(FrameLayout.LayoutParams iconParams, int taskIconMargin,
+ int taskIconHeight, int thumbnailTopMargin, boolean isRtl) {
iconParams.gravity = (isRtl ? START : END) | CENTER_VERTICAL;
iconParams.rightMargin = -taskIconHeight - taskIconMargin / 2;
iconParams.leftMargin = 0;
- iconParams.topMargin = snapshotParams.topMargin / 2;
+ iconParams.topMargin = thumbnailTopMargin / 2;
}
@Override
diff --git a/src/com/android/launcher3/touch/PagedOrientationHandler.java b/src/com/android/launcher3/touch/PagedOrientationHandler.java
index 923dcc6..6e594e9 100644
--- a/src/com/android/launcher3/touch/PagedOrientationHandler.java
+++ b/src/com/android/launcher3/touch/PagedOrientationHandler.java
@@ -47,10 +47,6 @@
*/
public interface PagedOrientationHandler {
- int SPLIT_TRANSLATE_PRIMARY_POSITIVE = 0;
- int SPLIT_TRANSLATE_PRIMARY_NEGATIVE = 1;
- int SPLIT_TRANSLATE_SECONDARY_NEGATIVE = 2;
-
PagedOrientationHandler PORTRAIT = new PortraitPagedViewHandler();
PagedOrientationHandler LANDSCAPE = new LandscapePagedViewHandler();
PagedOrientationHandler SEASCAPE = new SeascapePagedViewHandler();
@@ -82,12 +78,6 @@
FloatProperty<View> getPrimaryViewTranslate();
FloatProperty<View> getSecondaryViewTranslate();
- /**
- * @param stagePosition The position where the view to be split will go
- * @return {@link #SPLIT_TRANSLATE_*} constants to indicate which direction the
- * dismissal should happen
- */
- int getSplitTaskViewDismissDirection(@StagePosition int stagePosition, DeviceProfile dp);
int getPrimaryScroll(View view);
float getPrimaryScale(View view);
int getChildStart(View view);
@@ -152,8 +142,8 @@
StagedSplitBounds splitBoundsConfig, DeviceProfile dp);
// Overview TaskMenuView methods
- void setIconAndSnapshotParams(View iconView, int taskIconMargin, int taskIconHeight,
- FrameLayout.LayoutParams snapshotParams, boolean isRtl);
+ void setTaskIconParams(FrameLayout.LayoutParams iconParams,
+ int taskIconMargin, int taskIconHeight, int thumbnailTopMargin, boolean isRtl);
void setSplitIconParams(View primaryIconView, View secondaryIconView,
int taskIconHeight, int primarySnapshotWidth, int primarySnapshotHeight,
boolean isRtl, DeviceProfile deviceProfile, StagedSplitBounds splitConfig);
diff --git a/src/com/android/launcher3/touch/PortraitPagedViewHandler.java b/src/com/android/launcher3/touch/PortraitPagedViewHandler.java
index 0d92e25..2c9afd6 100644
--- a/src/com/android/launcher3/touch/PortraitPagedViewHandler.java
+++ b/src/com/android/launcher3/touch/PortraitPagedViewHandler.java
@@ -180,24 +180,6 @@
}
@Override
- public int getSplitTaskViewDismissDirection(@StagePosition int stagePosition,
- DeviceProfile dp) {
- if (stagePosition == STAGE_POSITION_TOP_OR_LEFT) {
- if (dp.isLandscape) {
- // Left side
- return SPLIT_TRANSLATE_PRIMARY_NEGATIVE;
- } else {
- // Top side
- return SPLIT_TRANSLATE_SECONDARY_NEGATIVE;
- }
- } else if (stagePosition == STAGE_POSITION_BOTTOM_OR_RIGHT) {
- // We don't have a bottom option, so should be right
- return SPLIT_TRANSLATE_PRIMARY_POSITIVE;
- }
- throw new IllegalStateException("Invalid split stage position: " + stagePosition);
- }
-
- @Override
public int getPrimaryScroll(View view) {
return view.getScrollX();
}
@@ -567,10 +549,8 @@
}
@Override
- public void setIconAndSnapshotParams(View iconView, int taskIconMargin, int taskIconHeight,
- FrameLayout.LayoutParams snapshotParams, boolean isRtl) {
- FrameLayout.LayoutParams iconParams =
- (FrameLayout.LayoutParams) iconView.getLayoutParams();
+ public void setTaskIconParams(FrameLayout.LayoutParams iconParams, int taskIconMargin,
+ int taskIconHeight, int thumbnailTopMargin, boolean isRtl) {
iconParams.gravity = TOP | CENTER_HORIZONTAL;
iconParams.leftMargin = iconParams.rightMargin = 0;
iconParams.topMargin = taskIconMargin;
diff --git a/src/com/android/launcher3/touch/SeascapePagedViewHandler.java b/src/com/android/launcher3/touch/SeascapePagedViewHandler.java
index 69e19f4..9151796 100644
--- a/src/com/android/launcher3/touch/SeascapePagedViewHandler.java
+++ b/src/com/android/launcher3/touch/SeascapePagedViewHandler.java
@@ -23,7 +23,6 @@
import static com.android.launcher3.touch.SingleAxisSwipeDetector.HORIZONTAL;
import static com.android.launcher3.util.SplitConfigurationOptions.STAGE_POSITION_BOTTOM_OR_RIGHT;
-import static com.android.launcher3.util.SplitConfigurationOptions.STAGE_POSITION_TOP_OR_LEFT;
import static com.android.launcher3.util.SplitConfigurationOptions.STAGE_TYPE_MAIN;
import android.content.res.Resources;
@@ -168,14 +167,12 @@
}
@Override
- public void setIconAndSnapshotParams(View mIconView, int taskIconMargin, int taskIconHeight,
- FrameLayout.LayoutParams snapshotParams, boolean isRtl) {
- FrameLayout.LayoutParams iconParams =
- (FrameLayout.LayoutParams) mIconView.getLayoutParams();
+ public void setTaskIconParams(FrameLayout.LayoutParams iconParams,
+ int taskIconMargin, int taskIconHeight, int thumbnailTopMargin, boolean isRtl) {
iconParams.gravity = (isRtl ? END : START) | CENTER_VERTICAL;
iconParams.leftMargin = -taskIconHeight - taskIconMargin / 2;
iconParams.rightMargin = 0;
- iconParams.topMargin = snapshotParams.topMargin / 2;
+ iconParams.topMargin = thumbnailTopMargin / 2;
}
@Override
diff --git a/src/com/android/launcher3/touch/WorkspaceTouchListener.java b/src/com/android/launcher3/touch/WorkspaceTouchListener.java
index e8941e6..fe0bf6d 100644
--- a/src/com/android/launcher3/touch/WorkspaceTouchListener.java
+++ b/src/com/android/launcher3/touch/WorkspaceTouchListener.java
@@ -121,6 +121,9 @@
mLongPressState = STATE_COMPLETED;
}
+ boolean isInAllAppsBottomSheet = mLauncher.isInState(ALL_APPS)
+ && mLauncher.getDeviceProfile().isTablet;
+
final boolean result;
if (mLongPressState == STATE_COMPLETED) {
// We have handled the touch, so workspace does not need to know anything anymore.
@@ -136,8 +139,9 @@
result = true;
} else {
- // We don't want to handle touch, let workspace handle it as usual.
- result = false;
+ // We don't want to handle touch unless we're in AllApps bottom sheet, let workspace
+ // handle it as usual.
+ result = isInAllAppsBottomSheet;
}
if (action == ACTION_UP || action == ACTION_POINTER_UP) {
@@ -153,9 +157,7 @@
if (action == ACTION_UP || action == ACTION_CANCEL) {
cancelLongPress();
}
- if (action == ACTION_UP
- && mLauncher.isInState(ALL_APPS)
- && mLauncher.getDeviceProfile().isTablet) {
+ if (action == ACTION_UP && isInAllAppsBottomSheet) {
mLauncher.getStateManager().goToState(NORMAL);
mLauncher.getStatsLogManager().logger()
.withSrcState(ALL_APPS.statsLogOrdinal)
diff --git a/src/com/android/launcher3/util/DisplayController.java b/src/com/android/launcher3/util/DisplayController.java
index ba925f5..7963401 100644
--- a/src/com/android/launcher3/util/DisplayController.java
+++ b/src/com/android/launcher3/util/DisplayController.java
@@ -20,7 +20,6 @@
import static com.android.launcher3.Utilities.dpiFromPx;
import static com.android.launcher3.util.Executors.MAIN_EXECUTOR;
-import static com.android.launcher3.util.Executors.UI_HELPER_EXECUTOR;
import static com.android.launcher3.util.WindowManagerCompat.MIN_TABLET_WIDTH;
import static java.util.Collections.emptyMap;
@@ -34,7 +33,6 @@
import android.content.res.Configuration;
import android.graphics.Point;
import android.hardware.display.DisplayManager;
-import android.hardware.display.DisplayManager.DisplayListener;
import android.os.Build;
import android.text.TextUtils;
import android.util.ArrayMap;
@@ -44,7 +42,6 @@
import androidx.annotation.AnyThread;
import androidx.annotation.UiThread;
-import androidx.annotation.WorkerThread;
import com.android.launcher3.Utilities;
import com.android.launcher3.uioverrides.ApiWrapper;
@@ -58,7 +55,7 @@
* Utility class to cache properties of default display to avoid a system RPC on every call.
*/
@SuppressLint("NewApi")
-public class DisplayController implements DisplayListener, ComponentCallbacks, SafeCloseable {
+public class DisplayController implements ComponentCallbacks, SafeCloseable {
private static final String TAG = "DisplayController";
@@ -102,7 +99,6 @@
}
mInfo = new Info(getDisplayInfoContext(display), display,
getInternalDisplays(mDM), emptyMap());
- mDM.registerDisplayListener(this, UI_HELPER_EXECUTOR.getHandler());
}
private static ArrayMap<String, PortraitSize> getInternalDisplays(
@@ -128,35 +124,6 @@
} else {
// TODO: unregister broadcast receiver
}
- mDM.unregisterDisplayListener(this);
- }
-
- @Override
- public final void onDisplayAdded(int displayId) { }
-
- @Override
- public final void onDisplayRemoved(int displayId) { }
-
- @WorkerThread
- @Override
- public final void onDisplayChanged(int displayId) {
- if (displayId != DEFAULT_DISPLAY) {
- return;
- }
- Display display = mDM.getDisplay(DEFAULT_DISPLAY);
- if (display == null) {
- return;
- }
- if (Utilities.ATLEAST_S) {
- // Only update refresh rate. Everything else comes from component callbacks
- mInfo.mSingleFrameMs = getSingleFrameMs(display);
- return;
- }
- handleInfoChange(display);
- }
-
- public static int getSingleFrameMs(Context context) {
- return INSTANCE.get(context).getInfo().mSingleFrameMs;
}
/**
@@ -287,8 +254,6 @@
public static class Info {
- private int mSingleFrameMs;
-
// Configuration properties
public final int rotation;
public final float fontScale;
@@ -318,7 +283,6 @@
densityDpi = config.densityDpi;
mScreenSizeDp = new PortraitSize(config.screenHeightDp, config.screenWidthDp);
- mSingleFrameMs = getSingleFrameMs(display);
currentSize = new Point();
display.getRealSize(currentSize);
@@ -400,9 +364,4 @@
return Objects.hash(width, height);
}
}
-
- private static int getSingleFrameMs(Display display) {
- float refreshRate = display.getRefreshRate();
- return refreshRate > 0 ? (int) (1000 / refreshRate) : 16;
- }
}
diff --git a/src/com/android/launcher3/util/window/RefreshRateTracker.java b/src/com/android/launcher3/util/window/RefreshRateTracker.java
new file mode 100644
index 0000000..7814617
--- /dev/null
+++ b/src/com/android/launcher3/util/window/RefreshRateTracker.java
@@ -0,0 +1,83 @@
+/*
+ * 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.util.window;
+
+import static android.view.Display.DEFAULT_DISPLAY;
+
+import static com.android.launcher3.util.Executors.UI_HELPER_EXECUTOR;
+
+import android.content.Context;
+import android.hardware.display.DisplayManager;
+import android.hardware.display.DisplayManager.DisplayListener;
+import android.view.Display;
+
+import androidx.annotation.WorkerThread;
+
+import com.android.launcher3.util.MainThreadInitializedObject;
+import com.android.launcher3.util.SafeCloseable;
+
+/**
+ * Utility class to track refresh rate of the current device
+ */
+public class RefreshRateTracker implements DisplayListener, SafeCloseable {
+
+ private static final MainThreadInitializedObject<RefreshRateTracker> INSTANCE =
+ new MainThreadInitializedObject<>(RefreshRateTracker::new);
+
+ private int mSingleFrameMs = 1;
+
+ private final DisplayManager mDM;
+
+ private RefreshRateTracker(Context context) {
+ mDM = context.getSystemService(DisplayManager.class);
+ updateSingleFrameMs();
+ mDM.registerDisplayListener(this, UI_HELPER_EXECUTOR.getHandler());
+ }
+
+ /**
+ * Returns the single frame time in ms
+ */
+ public static int getSingleFrameMs(Context context) {
+ return INSTANCE.get(context).mSingleFrameMs;
+ }
+
+ @Override
+ public final void onDisplayAdded(int displayId) { }
+
+ @Override
+ public final void onDisplayRemoved(int displayId) { }
+
+ @WorkerThread
+ @Override
+ public final void onDisplayChanged(int displayId) {
+ if (displayId == DEFAULT_DISPLAY) {
+ updateSingleFrameMs();
+ }
+ }
+
+ private void updateSingleFrameMs() {
+ Display display = mDM.getDisplay(DEFAULT_DISPLAY);
+ if (display != null) {
+ float refreshRate = display.getRefreshRate();
+ mSingleFrameMs = refreshRate > 0 ? (int) (1000 / refreshRate) : 16;
+ }
+ }
+
+ @Override
+ public void close() {
+ mDM.unregisterDisplayListener(this);
+ }
+}
diff --git a/src/com/android/launcher3/views/AbstractSlideInView.java b/src/com/android/launcher3/views/AbstractSlideInView.java
index c22d60d..5d88884 100644
--- a/src/com/android/launcher3/views/AbstractSlideInView.java
+++ b/src/com/android/launcher3/views/AbstractSlideInView.java
@@ -113,9 +113,16 @@
return -1;
}
+ /**
+ * Returns the range in height that the slide in view can be dragged.
+ */
+ protected float getShiftRange() {
+ return mContent.getHeight();
+ }
+
protected void setTranslationShift(float translationShift) {
mTranslationShift = translationShift;
- mContent.setTranslationY(mTranslationShift * mContent.getHeight());
+ mContent.setTranslationY(mTranslationShift * getShiftRange());
if (mColorScrim != null) {
mColorScrim.setAlpha(1 - mTranslationShift);
}
@@ -132,8 +139,7 @@
mSwipeDetector.setDetectableScrollConditions(
directionsToDetectScroll, false);
mSwipeDetector.onTouchEvent(ev);
- return mSwipeDetector.isDraggingOrSettling()
- || !getPopupContainer().isEventOverView(mContent, ev);
+ return mSwipeDetector.isDraggingOrSettling() || !isEventOverContent(ev);
}
@Override
@@ -142,13 +148,23 @@
if (ev.getAction() == MotionEvent.ACTION_UP && mSwipeDetector.isIdleState()
&& !isOpeningAnimationRunning()) {
// If we got ACTION_UP without ever starting swipe, close the panel.
- if (!getPopupContainer().isEventOverView(mContent, ev)) {
+ if (!isEventOverContent(ev)) {
close(true);
}
}
return true;
}
+ /**
+ * Returns {@code true} if the touch event is over the visible area of the bottom sheet.
+ *
+ * By default will check if the touch event is over {@code mContent}, subclasses should override
+ * this method if the visible area of the bottom sheet is different from {@code mContent}.
+ */
+ protected boolean isEventOverContent(MotionEvent ev) {
+ return getPopupContainer().isEventOverView(mContent, ev);
+ }
+
private boolean isOpeningAnimationRunning() {
return mIsOpen && mOpenCloseAnimator.isRunning();
}
@@ -160,7 +176,7 @@
@Override
public boolean onDrag(float displacement) {
- float range = mContent.getHeight();
+ float range = getShiftRange();
displacement = Utilities.boundToRange(displacement, 0, range);
setTranslationShift(displacement / range);
return true;
diff --git a/src/com/android/launcher3/views/AllAppsButton.java b/src/com/android/launcher3/views/AllAppsButton.java
index f502d46..b1e69c7 100644
--- a/src/com/android/launcher3/views/AllAppsButton.java
+++ b/src/com/android/launcher3/views/AllAppsButton.java
@@ -18,6 +18,7 @@
import android.content.Context;
import android.graphics.Bitmap;
import android.util.AttributeSet;
+import android.view.ContextThemeWrapper;
import com.android.launcher3.BubbleTextView;
import com.android.launcher3.LauncherAppState;
@@ -40,8 +41,9 @@
public AllAppsButton(Context context, AttributeSet attrs, int defStyle) {
super(context, attrs, defStyle);
+ Context theme = new ContextThemeWrapper(context, R.style.AllAppsButtonTheme);
Bitmap bitmap = LauncherAppState.getInstance(context).getIconCache().getIconFactory()
- .createScaledBitmapWithShadow(context.getDrawable(R.drawable.ic_all_apps_button));
+ .createScaledBitmapWithShadow(theme.getDrawable(R.drawable.ic_all_apps_button));
setIcon(new FastBitmapDrawable(bitmap));
}
}
diff --git a/src/com/android/launcher3/views/BaseDragLayer.java b/src/com/android/launcher3/views/BaseDragLayer.java
index 76dfb3c..f71aa13 100644
--- a/src/com/android/launcher3/views/BaseDragLayer.java
+++ b/src/com/android/launcher3/views/BaseDragLayer.java
@@ -20,7 +20,7 @@
import static android.view.MotionEvent.ACTION_DOWN;
import static android.view.MotionEvent.ACTION_UP;
-import static com.android.launcher3.util.DisplayController.getSingleFrameMs;
+import static com.android.launcher3.util.window.RefreshRateTracker.getSingleFrameMs;
import android.annotation.TargetApi;
import android.app.WallpaperManager;
diff --git a/src/com/android/launcher3/views/FloatingSurfaceView.java b/src/com/android/launcher3/views/FloatingSurfaceView.java
index e7cb3b3..7f54d6d 100644
--- a/src/com/android/launcher3/views/FloatingSurfaceView.java
+++ b/src/com/android/launcher3/views/FloatingSurfaceView.java
@@ -40,8 +40,8 @@
import com.android.launcher3.Insettable;
import com.android.launcher3.Launcher;
import com.android.launcher3.R;
-import com.android.launcher3.util.DisplayController;
import com.android.launcher3.util.Executors;
+import com.android.launcher3.util.window.RefreshRateTracker;
/**
* Similar to {@link FloatingIconView} but displays a surface with the targetIcon. It then passes
@@ -97,7 +97,7 @@
// Remove after some time, to avoid flickering
Executors.MAIN_EXECUTOR.getHandler().postDelayed(mRemoveViewRunnable,
- DisplayController.getSingleFrameMs(mLauncher));
+ RefreshRateTracker.getSingleFrameMs(mLauncher));
}
private void removeViewFromParent() {
diff --git a/src_ui_overrides/com/android/launcher3/uioverrides/states/AllAppsState.java b/src_ui_overrides/com/android/launcher3/uioverrides/states/AllAppsState.java
index 5543cc2..8a435c9 100644
--- a/src_ui_overrides/com/android/launcher3/uioverrides/states/AllAppsState.java
+++ b/src_ui_overrides/com/android/launcher3/uioverrides/states/AllAppsState.java
@@ -55,8 +55,15 @@
@Override
public ScaleAndTranslation getWorkspaceScaleAndTranslation(Launcher launcher) {
- return new ScaleAndTranslation(1f, 0,
- -launcher.getAllAppsController().getShiftRange() * PARALLAX_COEFFICIENT);
+ ScaleAndTranslation scaleAndTranslation =
+ new ScaleAndTranslation(NO_SCALE, NO_OFFSET, NO_OFFSET);
+ if (launcher.getDeviceProfile().isTablet) {
+ scaleAndTranslation.scale = 0.97f;
+ } else {
+ scaleAndTranslation.translationY =
+ -launcher.getAllAppsController().getShiftRange() * PARALLAX_COEFFICIENT;
+ }
+ return scaleAndTranslation;
}
@Override
diff --git a/tests/Android.bp b/tests/Android.bp
index c2c545b..7542d04 100644
--- a/tests/Android.bp
+++ b/tests/Android.bp
@@ -67,7 +67,8 @@
"androidx.test.uiautomator_uiautomator",
"mockito-target-inline-minus-junit4",
"launcher_log_protos_lite",
- "truth-prebuilt"
+ "truth-prebuilt",
+ "platform-test-rules",
],
manifest: "AndroidManifest-common.xml",
platform_apis: true,
diff --git a/tests/AndroidManifest-common.xml b/tests/AndroidManifest-common.xml
index e44c172..b4cd773 100644
--- a/tests/AndroidManifest-common.xml
+++ b/tests/AndroidManifest-common.xml
@@ -267,6 +267,15 @@
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity-alias>
+ <activity-alias android:name="Activity15" android:exported="true"
+ android:label="ThemeIconTestActivity"
+ android:icon="@drawable/test_theme_icon"
+ android:targetActivity="com.android.launcher3.testcomponent.OtherBaseTestingActivity">
+ <intent-filter>
+ <action android:name="android.intent.action.MAIN" />
+ <category android:name="android.intent.category.LAUNCHER" />
+ </intent-filter>
+ </activity-alias>
<!-- [b/197780098] Disable eager initialization of Jetpack libraries. -->
<provider
diff --git a/tests/res/drawable/test_theme_icon.xml b/tests/res/drawable/test_theme_icon.xml
new file mode 100644
index 0000000..be5c4d9
--- /dev/null
+++ b/tests/res/drawable/test_theme_icon.xml
@@ -0,0 +1,29 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+Copyright (C) 2021 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+<adaptive-icon xmlns:android="http://schemas.android.com/apk/res/android">
+ <background android:drawable="@android:color/white"/>
+ <foreground>
+ <color android:color="#FFFF0000" />
+ </foreground>
+ <monochrome>
+ <vector android:width="48dp" android:height="48dp" android:viewportWidth="48.0" android:viewportHeight="48.0">
+ <path
+ android:fillColor="#FF000000"
+ android:pathData="M0,24L48,24 48,48, 0,48 Z"/>
+ </vector>
+ </monochrome>
+</adaptive-icon>
diff --git a/tests/src/com/android/launcher3/compat/PromiseIconUiTest.java b/tests/src/com/android/launcher3/compat/PromiseIconUiTest.java
index f34a29e..92e3e64 100644
--- a/tests/src/com/android/launcher3/compat/PromiseIconUiTest.java
+++ b/tests/src/com/android/launcher3/compat/PromiseIconUiTest.java
@@ -34,6 +34,7 @@
import org.junit.runner.RunWith;
import java.util.UUID;
+import java.util.concurrent.TimeUnit;
/**
@@ -44,6 +45,8 @@
public class PromiseIconUiTest extends AbstractLauncherUiTest {
private int mSessionId = -1;
+ // TODO(b/202985412): Revert to default timeout when PackageManager bug is fixed.
+ private static final long PROMISE_ICON_TIMEOUT = TimeUnit.SECONDS.toMillis(60);
@Override
public void setUp() throws Exception {
@@ -85,7 +88,8 @@
// Verify promise icon is added
waitForLauncherCondition("Test Promise App not found on workspace", launcher ->
- launcher.getWorkspace().getFirstMatch(findPromiseApp) != null);
+ launcher.getWorkspace().getFirstMatch(findPromiseApp) != null,
+ PROMISE_ICON_TIMEOUT);
// Remove session
mTargetContext.getPackageManager().getPackageInstaller().abandonSession(mSessionId);
@@ -93,7 +97,8 @@
// Verify promise icon is removed
waitForLauncherCondition("Test Promise App not removed from workspace", launcher ->
- launcher.getWorkspace().getFirstMatch(findPromiseApp) == null);
+ launcher.getWorkspace().getFirstMatch(findPromiseApp) == null,
+ PROMISE_ICON_TIMEOUT);
}
@Test
@@ -111,6 +116,7 @@
// Verify promise icon is not added
waitForLauncherCondition("Test Promise App not found on workspace", launcher ->
- launcher.getWorkspace().getFirstMatch(findPromiseApp) == null);
+ launcher.getWorkspace().getFirstMatch(findPromiseApp) == null,
+ PROMISE_ICON_TIMEOUT);
}
}
diff --git a/tests/src/com/android/launcher3/model/GridSizeMigrationTaskV2Test.java b/tests/src/com/android/launcher3/model/GridSizeMigrationTaskV2Test.java
deleted file mode 100644
index 005389e..0000000
--- a/tests/src/com/android/launcher3/model/GridSizeMigrationTaskV2Test.java
+++ /dev/null
@@ -1,278 +0,0 @@
-/*
- * Copyright (C) 2020 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.launcher3.model;
-
-import static com.android.launcher3.LauncherSettings.Favorites.CONTAINER_DESKTOP;
-import static com.android.launcher3.LauncherSettings.Favorites.CONTAINER_HOTSEAT;
-import static com.android.launcher3.LauncherSettings.Favorites.TMP_CONTENT_URI;
-import static com.android.launcher3.provider.LauncherDbUtils.dropTable;
-import static com.android.launcher3.util.LauncherModelHelper.APP_ICON;
-import static com.android.launcher3.util.LauncherModelHelper.DESKTOP;
-import static com.android.launcher3.util.LauncherModelHelper.HOTSEAT;
-import static com.android.launcher3.util.LauncherModelHelper.SHORTCUT;
-import static com.android.launcher3.util.LauncherModelHelper.TEST_PACKAGE;
-
-import static org.junit.Assert.assertEquals;
-import static org.junit.Assert.assertTrue;
-
-import android.content.Context;
-import android.content.Intent;
-import android.database.Cursor;
-import android.database.sqlite.SQLiteDatabase;
-import android.graphics.Point;
-import android.os.Process;
-
-import androidx.test.ext.junit.runners.AndroidJUnit4;
-import androidx.test.filters.SmallTest;
-
-import com.android.launcher3.InvariantDeviceProfile;
-import com.android.launcher3.LauncherSettings;
-import com.android.launcher3.pm.UserCache;
-import com.android.launcher3.util.LauncherModelHelper;
-
-import org.junit.After;
-import org.junit.Before;
-import org.junit.Test;
-import org.junit.runner.RunWith;
-
-import java.util.HashMap;
-import java.util.HashSet;
-
-/** Unit tests for {@link GridSizeMigrationTaskV2} */
-@SmallTest
-@RunWith(AndroidJUnit4.class)
-public class GridSizeMigrationTaskV2Test {
-
- private LauncherModelHelper mModelHelper;
- private Context mContext;
- private SQLiteDatabase mDb;
-
- private HashSet<String> mValidPackages;
- private InvariantDeviceProfile mIdp;
-
- private final String testPackage1 = "com.android.launcher3.validpackage1";
- private final String testPackage2 = "com.android.launcher3.validpackage2";
- private final String testPackage3 = "com.android.launcher3.validpackage3";
- private final String testPackage4 = "com.android.launcher3.validpackage4";
- private final String testPackage5 = "com.android.launcher3.validpackage5";
- private final String testPackage6 = "com.android.launcher3.validpackage6";
- private final String testPackage7 = "com.android.launcher3.validpackage7";
- private final String testPackage8 = "com.android.launcher3.validpackage8";
- private final String testPackage9 = "com.android.launcher3.validpackage9";
- private final String testPackage10 = "com.android.launcher3.validpackage10";
-
- @Before
- public void setUp() {
- mModelHelper = new LauncherModelHelper();
- mContext = mModelHelper.sandboxContext;
- mDb = mModelHelper.provider.getDb();
-
- mValidPackages = new HashSet<>();
- mValidPackages.add(TEST_PACKAGE);
- mValidPackages.add(testPackage1);
- mValidPackages.add(testPackage2);
- mValidPackages.add(testPackage3);
- mValidPackages.add(testPackage4);
- mValidPackages.add(testPackage5);
- mValidPackages.add(testPackage6);
- mValidPackages.add(testPackage7);
- mValidPackages.add(testPackage8);
- mValidPackages.add(testPackage9);
- mValidPackages.add(testPackage10);
-
- mIdp = InvariantDeviceProfile.INSTANCE.get(mContext);
-
- long userSerial = UserCache.INSTANCE.get(mContext).getSerialNumberForUser(
- Process.myUserHandle());
- dropTable(mDb, LauncherSettings.Favorites.TMP_TABLE);
- LauncherSettings.Favorites.addTableToDb(mDb, userSerial, false,
- LauncherSettings.Favorites.TMP_TABLE);
- }
-
- @After
- public void tearDown() {
- mModelHelper.destroy();
- }
-
- @Test
- public void testMigration() throws Exception {
- int[] srcHotseatItems = {
- mModelHelper.addItem(APP_ICON, 0, HOTSEAT, 0, 0, testPackage1, 1, TMP_CONTENT_URI),
- mModelHelper.addItem(SHORTCUT, 1, HOTSEAT, 0, 0, testPackage2, 2, TMP_CONTENT_URI),
- -1,
- mModelHelper.addItem(SHORTCUT, 3, HOTSEAT, 0, 0, testPackage3, 3, TMP_CONTENT_URI),
- mModelHelper.addItem(APP_ICON, 4, HOTSEAT, 0, 0, testPackage4, 4, TMP_CONTENT_URI),
- };
- mModelHelper.addItem(APP_ICON, 0, DESKTOP, 2, 2, testPackage5, 5, TMP_CONTENT_URI);
- mModelHelper.addItem(APP_ICON, 0, DESKTOP, 2, 3, testPackage6, 6, TMP_CONTENT_URI);
- mModelHelper.addItem(APP_ICON, 0, DESKTOP, 4, 1, testPackage8, 8, TMP_CONTENT_URI);
- mModelHelper.addItem(APP_ICON, 0, DESKTOP, 4, 2, testPackage9, 9, TMP_CONTENT_URI);
- mModelHelper.addItem(APP_ICON, 0, DESKTOP, 4, 3, testPackage10, 10, TMP_CONTENT_URI);
-
- int[] destHotseatItems = {
- -1,
- mModelHelper.addItem(SHORTCUT, 1, HOTSEAT, 0, 0, testPackage2),
- -1,
- };
- mModelHelper.addItem(APP_ICON, 0, DESKTOP, 2, 2, testPackage7);
-
- mIdp.numDatabaseHotseatIcons = 4;
- mIdp.numColumns = 4;
- mIdp.numRows = 4;
- GridSizeMigrationTaskV2.DbReader srcReader = new GridSizeMigrationTaskV2.DbReader(mDb,
- LauncherSettings.Favorites.TMP_TABLE, mContext, mValidPackages);
- GridSizeMigrationTaskV2.DbReader destReader = new GridSizeMigrationTaskV2.DbReader(mDb,
- LauncherSettings.Favorites.TABLE_NAME, mContext, mValidPackages);
- GridSizeMigrationTaskV2 task = new GridSizeMigrationTaskV2(mContext, mDb, srcReader,
- destReader, mIdp.numDatabaseHotseatIcons, new Point(mIdp.numColumns, mIdp.numRows));
- task.migrate(mIdp);
-
- // Check hotseat items
- Cursor c = mContext.getContentResolver().query(LauncherSettings.Favorites.CONTENT_URI,
- new String[]{LauncherSettings.Favorites.SCREEN, LauncherSettings.Favorites.INTENT},
- "container=" + CONTAINER_HOTSEAT, null, LauncherSettings.Favorites.SCREEN, null);
- assertEquals(c.getCount(), mIdp.numDatabaseHotseatIcons);
- int screenIndex = c.getColumnIndex(LauncherSettings.Favorites.SCREEN);
- int intentIndex = c.getColumnIndex(LauncherSettings.Favorites.INTENT);
- c.moveToNext();
- assertEquals(c.getInt(screenIndex), 0);
- assertTrue(c.getString(intentIndex).contains(testPackage1));
- c.moveToNext();
- assertEquals(c.getInt(screenIndex), 1);
- assertTrue(c.getString(intentIndex).contains(testPackage2));
- c.moveToNext();
- assertEquals(c.getInt(screenIndex), 2);
- assertTrue(c.getString(intentIndex).contains(testPackage3));
- c.moveToNext();
- assertEquals(c.getInt(screenIndex), 3);
- assertTrue(c.getString(intentIndex).contains(testPackage4));
- c.close();
-
- // Check workspace items
- c = mContext.getContentResolver().query(LauncherSettings.Favorites.CONTENT_URI,
- new String[]{LauncherSettings.Favorites.CELLX, LauncherSettings.Favorites.CELLY,
- LauncherSettings.Favorites.INTENT},
- "container=" + CONTAINER_DESKTOP, null, null, null);
- intentIndex = c.getColumnIndex(LauncherSettings.Favorites.INTENT);
- int cellXIndex = c.getColumnIndex(LauncherSettings.Favorites.CELLX);
- int cellYIndex = c.getColumnIndex(LauncherSettings.Favorites.CELLY);
-
- HashMap<String, Point> locMap = new HashMap<>();
- while (c.moveToNext()) {
- locMap.put(
- Intent.parseUri(c.getString(intentIndex), 0).getPackage(),
- new Point(c.getInt(cellXIndex), c.getInt(cellYIndex)));
- }
- c.close();
-
- assertEquals(locMap.size(), 6);
- assertEquals(new Point(0, 2), locMap.get(testPackage8));
- assertEquals(new Point(0, 3), locMap.get(testPackage6));
- assertEquals(new Point(1, 3), locMap.get(testPackage10));
- assertEquals(new Point(2, 3), locMap.get(testPackage5));
- assertEquals(new Point(3, 3), locMap.get(testPackage9));
- }
-
- @Test
- public void migrateToLargerHotseat() {
- int[] srcHotseatItems = {
- mModelHelper.addItem(APP_ICON, 0, HOTSEAT, 0, 0, testPackage1, 1, TMP_CONTENT_URI),
- mModelHelper.addItem(SHORTCUT, 1, HOTSEAT, 0, 0, testPackage2, 2, TMP_CONTENT_URI),
- mModelHelper.addItem(APP_ICON, 2, HOTSEAT, 0, 0, testPackage3, 3, TMP_CONTENT_URI),
- mModelHelper.addItem(SHORTCUT, 3, HOTSEAT, 0, 0, testPackage4, 4, TMP_CONTENT_URI),
- };
-
- int numSrcDatabaseHotseatIcons = srcHotseatItems.length;
- mIdp.numDatabaseHotseatIcons = 6;
- mIdp.numColumns = 4;
- mIdp.numRows = 4;
- GridSizeMigrationTaskV2.DbReader srcReader = new GridSizeMigrationTaskV2.DbReader(mDb,
- LauncherSettings.Favorites.TMP_TABLE, mContext, mValidPackages);
- GridSizeMigrationTaskV2.DbReader destReader = new GridSizeMigrationTaskV2.DbReader(mDb,
- LauncherSettings.Favorites.TABLE_NAME, mContext, mValidPackages);
- GridSizeMigrationTaskV2 task = new GridSizeMigrationTaskV2(mContext, mDb, srcReader,
- destReader, mIdp.numDatabaseHotseatIcons, new Point(mIdp.numColumns, mIdp.numRows));
- task.migrate(mIdp);
-
- // Check hotseat items
- Cursor c = mContext.getContentResolver().query(LauncherSettings.Favorites.CONTENT_URI,
- new String[]{LauncherSettings.Favorites.SCREEN, LauncherSettings.Favorites.INTENT},
- "container=" + CONTAINER_HOTSEAT, null, LauncherSettings.Favorites.SCREEN, null);
- assertEquals(c.getCount(), numSrcDatabaseHotseatIcons);
- int screenIndex = c.getColumnIndex(LauncherSettings.Favorites.SCREEN);
- int intentIndex = c.getColumnIndex(LauncherSettings.Favorites.INTENT);
- c.moveToNext();
- assertEquals(c.getInt(screenIndex), 0);
- assertTrue(c.getString(intentIndex).contains(testPackage1));
- c.moveToNext();
- assertEquals(c.getInt(screenIndex), 1);
- assertTrue(c.getString(intentIndex).contains(testPackage2));
- c.moveToNext();
- assertEquals(c.getInt(screenIndex), 2);
- assertTrue(c.getString(intentIndex).contains(testPackage3));
- c.moveToNext();
- assertEquals(c.getInt(screenIndex), 3);
- assertTrue(c.getString(intentIndex).contains(testPackage4));
-
- c.close();
- }
-
- @Test
- public void migrateFromLargerHotseat() {
- int[] srcHotseatItems = {
- mModelHelper.addItem(APP_ICON, 0, HOTSEAT, 0, 0, testPackage1, 1, TMP_CONTENT_URI),
- -1,
- mModelHelper.addItem(SHORTCUT, 2, HOTSEAT, 0, 0, testPackage2, 2, TMP_CONTENT_URI),
- mModelHelper.addItem(APP_ICON, 3, HOTSEAT, 0, 0, testPackage3, 3, TMP_CONTENT_URI),
- mModelHelper.addItem(SHORTCUT, 4, HOTSEAT, 0, 0, testPackage4, 4, TMP_CONTENT_URI),
- mModelHelper.addItem(APP_ICON, 5, HOTSEAT, 0, 0, testPackage5, 5, TMP_CONTENT_URI),
- };
-
- mIdp.numDatabaseHotseatIcons = 4;
- mIdp.numColumns = 4;
- mIdp.numRows = 4;
- GridSizeMigrationTaskV2.DbReader srcReader = new GridSizeMigrationTaskV2.DbReader(mDb,
- LauncherSettings.Favorites.TMP_TABLE, mContext, mValidPackages);
- GridSizeMigrationTaskV2.DbReader destReader = new GridSizeMigrationTaskV2.DbReader(mDb,
- LauncherSettings.Favorites.TABLE_NAME, mContext, mValidPackages);
- GridSizeMigrationTaskV2 task = new GridSizeMigrationTaskV2(mContext, mDb, srcReader,
- destReader, mIdp.numDatabaseHotseatIcons, new Point(mIdp.numColumns, mIdp.numRows));
- task.migrate(mIdp);
-
- // Check hotseat items
- Cursor c = mContext.getContentResolver().query(LauncherSettings.Favorites.CONTENT_URI,
- new String[]{LauncherSettings.Favorites.SCREEN, LauncherSettings.Favorites.INTENT},
- "container=" + CONTAINER_HOTSEAT, null, LauncherSettings.Favorites.SCREEN, null);
- assertEquals(c.getCount(), mIdp.numDatabaseHotseatIcons);
- int screenIndex = c.getColumnIndex(LauncherSettings.Favorites.SCREEN);
- int intentIndex = c.getColumnIndex(LauncherSettings.Favorites.INTENT);
- c.moveToNext();
- assertEquals(c.getInt(screenIndex), 0);
- assertTrue(c.getString(intentIndex).contains(testPackage1));
- c.moveToNext();
- assertEquals(c.getInt(screenIndex), 1);
- assertTrue(c.getString(intentIndex).contains(testPackage2));
- c.moveToNext();
- assertEquals(c.getInt(screenIndex), 2);
- assertTrue(c.getString(intentIndex).contains(testPackage3));
- c.moveToNext();
- assertEquals(c.getInt(screenIndex), 3);
- assertTrue(c.getString(intentIndex).contains(testPackage4));
-
- c.close();
- }
-}
diff --git a/tests/src/com/android/launcher3/model/GridSizeMigrationTaskV2Test.kt b/tests/src/com/android/launcher3/model/GridSizeMigrationTaskV2Test.kt
new file mode 100644
index 0000000..239e092
--- /dev/null
+++ b/tests/src/com/android/launcher3/model/GridSizeMigrationTaskV2Test.kt
@@ -0,0 +1,500 @@
+/*
+ * 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.model
+
+import android.content.Context
+import android.content.Intent
+import android.database.sqlite.SQLiteDatabase
+import android.graphics.Point
+import android.os.Process
+import androidx.test.ext.junit.runners.AndroidJUnit4
+import androidx.test.filters.SmallTest
+import com.android.launcher3.InvariantDeviceProfile
+import com.android.launcher3.LauncherFiles
+import com.android.launcher3.LauncherSettings.Favorites.*
+import com.android.launcher3.config.FeatureFlags
+import com.android.launcher3.model.GridSizeMigrationTaskV2.DbReader
+import com.android.launcher3.pm.UserCache
+import com.android.launcher3.provider.LauncherDbUtils
+import com.android.launcher3.util.LauncherModelHelper
+import com.android.launcher3.util.LauncherModelHelper.*
+import com.google.common.truth.Truth.assertThat
+import org.junit.After
+import org.junit.Before
+import org.junit.Test
+import org.junit.runner.RunWith
+
+/** Unit tests for [GridSizeMigrationTaskV2] */
+@SmallTest
+@RunWith(AndroidJUnit4::class)
+class GridSizeMigrationTaskV2Test {
+ private lateinit var modelHelper: LauncherModelHelper
+ private lateinit var context: Context
+ private lateinit var db: SQLiteDatabase
+ private lateinit var validPackages: Set<String>
+ private lateinit var idp: InvariantDeviceProfile
+ private val testPackage1 = "com.android.launcher3.validpackage1"
+ private val testPackage2 = "com.android.launcher3.validpackage2"
+ private val testPackage3 = "com.android.launcher3.validpackage3"
+ private val testPackage4 = "com.android.launcher3.validpackage4"
+ private val testPackage5 = "com.android.launcher3.validpackage5"
+ private val testPackage6 = "com.android.launcher3.validpackage6"
+ private val testPackage7 = "com.android.launcher3.validpackage7"
+ private val testPackage8 = "com.android.launcher3.validpackage8"
+ private val testPackage9 = "com.android.launcher3.validpackage9"
+ private val testPackage10 = "com.android.launcher3.validpackage10"
+
+ @Before
+ fun setUp() {
+ modelHelper = LauncherModelHelper()
+ context = modelHelper.sandboxContext
+ db = modelHelper.provider.db
+
+ validPackages = setOf(
+ TEST_PACKAGE,
+ testPackage1,
+ testPackage2,
+ testPackage3,
+ testPackage4,
+ testPackage5,
+ testPackage6,
+ testPackage7,
+ testPackage8,
+ testPackage9,
+ testPackage10
+ )
+
+ idp = InvariantDeviceProfile.INSTANCE[context]
+ val userSerial = UserCache.INSTANCE[context].getSerialNumberForUser(Process.myUserHandle())
+ LauncherDbUtils.dropTable(db, TMP_TABLE)
+ addTableToDb(db, userSerial, false, TMP_TABLE)
+ }
+
+ @After
+ fun tearDown() {
+ modelHelper.destroy()
+ }
+
+ /**
+ * Old migration logic, should be modified once [FeatureFlags.ENABLE_NEW_MIGRATION_LOGIC] is
+ * not needed anymore
+ */
+ @Test
+ @Throws(Exception::class)
+ fun testMigration() {
+ // Src Hotseat icons
+ modelHelper.addItem(APP_ICON, 0, HOTSEAT, 0, 0, testPackage1, 1, TMP_CONTENT_URI)
+ modelHelper.addItem(SHORTCUT, 1, HOTSEAT, 0, 0, testPackage2, 2, TMP_CONTENT_URI)
+ modelHelper.addItem(SHORTCUT, 3, HOTSEAT, 0, 0, testPackage3, 3, TMP_CONTENT_URI)
+ modelHelper.addItem(APP_ICON, 4, HOTSEAT, 0, 0, testPackage4, 4, TMP_CONTENT_URI)
+ // Src grid icons
+ modelHelper.addItem(APP_ICON, 0, DESKTOP, 2, 2, testPackage5, 5, TMP_CONTENT_URI)
+ modelHelper.addItem(APP_ICON, 0, DESKTOP, 2, 3, testPackage6, 6, TMP_CONTENT_URI)
+ modelHelper.addItem(APP_ICON, 0, DESKTOP, 4, 1, testPackage8, 8, TMP_CONTENT_URI)
+ modelHelper.addItem(APP_ICON, 0, DESKTOP, 4, 2, testPackage9, 9, TMP_CONTENT_URI)
+ modelHelper.addItem(APP_ICON, 0, DESKTOP, 4, 3, testPackage10, 10, TMP_CONTENT_URI)
+
+ // Dest hotseat icons
+ modelHelper.addItem(SHORTCUT, 1, HOTSEAT, 0, 0, testPackage2)
+ // Dest grid icons
+ modelHelper.addItem(APP_ICON, 0, DESKTOP, 2, 2, testPackage7)
+
+ idp.numDatabaseHotseatIcons = 4
+ idp.numColumns = 4
+ idp.numRows = 4
+ val srcReader = DbReader(db, TMP_TABLE, context, validPackages)
+ val destReader = DbReader(db, TABLE_NAME, context, validPackages)
+ val task = GridSizeMigrationTaskV2(
+ context,
+ db,
+ srcReader,
+ destReader,
+ idp.numDatabaseHotseatIcons,
+ Point(idp.numColumns, idp.numRows)
+ )
+ task.migrate(idp)
+
+ // Check hotseat items
+ var c = context.contentResolver.query(
+ CONTENT_URI,
+ arrayOf(SCREEN, INTENT),
+ "container=$CONTAINER_HOTSEAT",
+ null,
+ SCREEN,
+ null
+ ) ?: throw IllegalStateException()
+
+ assertThat(c.count).isEqualTo(idp.numDatabaseHotseatIcons)
+
+ val screenIndex = c.getColumnIndex(SCREEN)
+ var intentIndex = c.getColumnIndex(INTENT)
+ c.moveToNext()
+ assertThat(c.getInt(screenIndex).toLong()).isEqualTo(0)
+ assertThat(c.getString(intentIndex)).contains(testPackage1)
+ c.moveToNext()
+ assertThat(c.getInt(screenIndex).toLong()).isEqualTo(1)
+ assertThat(c.getString(intentIndex)).contains(testPackage2)
+ c.moveToNext()
+ assertThat(c.getInt(screenIndex).toLong()).isEqualTo(2)
+ assertThat(c.getString(intentIndex)).contains(testPackage3)
+ c.moveToNext()
+ assertThat(c.getInt(screenIndex).toLong()).isEqualTo(3)
+ assertThat(c.getString(intentIndex)).contains(testPackage4)
+ c.close()
+
+ // Check workspace items
+ c = context.contentResolver.query(
+ CONTENT_URI,
+ arrayOf(CELLX, CELLY, INTENT),
+ "container=$CONTAINER_DESKTOP",
+ null,
+ null,
+ null
+ ) ?: throw IllegalStateException()
+
+ intentIndex = c.getColumnIndex(INTENT)
+ val cellXIndex = c.getColumnIndex(CELLX)
+ val cellYIndex = c.getColumnIndex(CELLY)
+ val locMap = HashMap<String, Point>()
+ while (c.moveToNext()) {
+ locMap[Intent.parseUri(c.getString(intentIndex), 0).getPackage()] =
+ Point(c.getInt(cellXIndex), c.getInt(cellYIndex))
+ }
+ c.close()
+ assertThat(locMap.size.toLong()).isEqualTo(6)
+ assertThat(locMap[testPackage8]).isEqualTo(Point(0, 2))
+ assertThat(locMap[testPackage6]).isEqualTo(Point(0, 3))
+ assertThat(locMap[testPackage10]).isEqualTo(Point(1, 3))
+ assertThat(locMap[testPackage7]).isEqualTo(Point(2, 2))
+ assertThat(locMap[testPackage5]).isEqualTo(Point(2, 3))
+ assertThat(locMap[testPackage9]).isEqualTo(Point(3, 3))
+ }
+
+ @Test
+ fun migrateToLargerHotseat() {
+ val srcHotseatItems = intArrayOf(
+ modelHelper.addItem(APP_ICON, 0, HOTSEAT, 0, 0, testPackage1, 1, TMP_CONTENT_URI),
+ modelHelper.addItem(SHORTCUT, 1, HOTSEAT, 0, 0, testPackage2, 2, TMP_CONTENT_URI),
+ modelHelper.addItem(APP_ICON, 2, HOTSEAT, 0, 0, testPackage3, 3, TMP_CONTENT_URI),
+ modelHelper.addItem(SHORTCUT, 3, HOTSEAT, 0, 0, testPackage4, 4, TMP_CONTENT_URI)
+ )
+ val numSrcDatabaseHotseatIcons = srcHotseatItems.size
+ idp.numDatabaseHotseatIcons = 6
+ idp.numColumns = 4
+ idp.numRows = 4
+ val srcReader = DbReader(db, TMP_TABLE, context, validPackages)
+ val destReader = DbReader(db, TABLE_NAME, context, validPackages)
+ val task = GridSizeMigrationTaskV2(
+ context,
+ db,
+ srcReader,
+ destReader,
+ idp.numDatabaseHotseatIcons,
+ Point(idp.numColumns, idp.numRows)
+ )
+ task.migrate(idp)
+
+ // Check hotseat items
+ val c = context.contentResolver.query(
+ CONTENT_URI,
+ arrayOf(SCREEN, INTENT),
+ "container=$CONTAINER_HOTSEAT",
+ null,
+ SCREEN,
+ null
+ ) ?: throw IllegalStateException()
+
+ assertThat(c.count.toLong()).isEqualTo(numSrcDatabaseHotseatIcons.toLong())
+ val screenIndex = c.getColumnIndex(SCREEN)
+ val intentIndex = c.getColumnIndex(INTENT)
+ c.moveToNext()
+ assertThat(c.getInt(screenIndex)).isEqualTo(0)
+ assertThat(c.getString(intentIndex)).contains(testPackage1)
+
+ c.moveToNext()
+ assertThat(c.getInt(screenIndex)).isEqualTo(1)
+ assertThat(c.getString(intentIndex)).contains(testPackage2)
+
+ c.moveToNext()
+ assertThat(c.getInt(screenIndex)).isEqualTo(2)
+ assertThat(c.getString(intentIndex)).contains(testPackage3)
+
+ c.moveToNext()
+ assertThat(c.getInt(screenIndex)).isEqualTo(3)
+ assertThat(c.getString(intentIndex)).contains(testPackage4)
+
+ c.close()
+ }
+
+ @Test
+ fun migrateFromLargerHotseat() {
+ modelHelper.addItem(APP_ICON, 0, HOTSEAT, 0, 0, testPackage1, 1, TMP_CONTENT_URI)
+ modelHelper.addItem(SHORTCUT, 2, HOTSEAT, 0, 0, testPackage2, 2, TMP_CONTENT_URI)
+ modelHelper.addItem(APP_ICON, 3, HOTSEAT, 0, 0, testPackage3, 3, TMP_CONTENT_URI)
+ modelHelper.addItem(SHORTCUT, 4, HOTSEAT, 0, 0, testPackage4, 4, TMP_CONTENT_URI)
+ modelHelper.addItem(APP_ICON, 5, HOTSEAT, 0, 0, testPackage5, 5, TMP_CONTENT_URI)
+
+ idp.numDatabaseHotseatIcons = 4
+ idp.numColumns = 4
+ idp.numRows = 4
+ val srcReader = DbReader(db, TMP_TABLE, context, validPackages)
+ val destReader = DbReader(db, TABLE_NAME, context, validPackages)
+ val task = GridSizeMigrationTaskV2(
+ context,
+ db,
+ srcReader,
+ destReader,
+ idp.numDatabaseHotseatIcons,
+ Point(idp.numColumns, idp.numRows)
+ )
+ task.migrate(idp)
+
+ // Check hotseat items
+ val c = context.contentResolver.query(
+ CONTENT_URI,
+ arrayOf(SCREEN, INTENT),
+ "container=$CONTAINER_HOTSEAT",
+ null,
+ SCREEN,
+ null
+ ) ?: throw IllegalStateException()
+
+ assertThat(c.count.toLong()).isEqualTo(idp.numDatabaseHotseatIcons.toLong())
+ val screenIndex = c.getColumnIndex(SCREEN)
+ val intentIndex = c.getColumnIndex(INTENT)
+
+ c.moveToNext()
+ assertThat(c.getInt(screenIndex)).isEqualTo(0)
+ assertThat(c.getString(intentIndex)).contains(testPackage1)
+
+ c.moveToNext()
+ assertThat(c.getInt(screenIndex)).isEqualTo(1)
+ assertThat(c.getString(intentIndex)).contains(testPackage2)
+
+ c.moveToNext()
+ assertThat(c.getInt(screenIndex)).isEqualTo(2)
+ assertThat(c.getString(intentIndex)).contains(testPackage3)
+
+ c.moveToNext()
+ assertThat(c.getInt(screenIndex)).isEqualTo(3)
+ assertThat(c.getString(intentIndex)).contains(testPackage4)
+
+ c.close()
+ }
+
+ /**
+ * Migrating from a smaller grid to a large one should keep the pages
+ * if the column difference is less than 2
+ */
+ @Test
+ @Throws(Exception::class)
+ fun migrateFromSmallerGridSmallDifference() {
+ enableNewMigrationLogic("4,4")
+
+ // Setup src grid
+ modelHelper.addItem(APP_ICON, 0, DESKTOP, 2, 2, testPackage1, 5, TMP_CONTENT_URI)
+ modelHelper.addItem(APP_ICON, 0, DESKTOP, 2, 3, testPackage2, 6, TMP_CONTENT_URI)
+ modelHelper.addItem(APP_ICON, 1, DESKTOP, 3, 1, testPackage3, 7, TMP_CONTENT_URI)
+ modelHelper.addItem(APP_ICON, 1, DESKTOP, 3, 2, testPackage4, 8, TMP_CONTENT_URI)
+ modelHelper.addItem(APP_ICON, 2, DESKTOP, 3, 3, testPackage5, 9, TMP_CONTENT_URI)
+
+ idp.numDatabaseHotseatIcons = 4
+ idp.numColumns = 6
+ idp.numRows = 5
+
+ val srcReader = DbReader(db, TMP_TABLE, context, validPackages)
+ val destReader = DbReader(db, TABLE_NAME, context, validPackages)
+ val task = GridSizeMigrationTaskV2(
+ context,
+ db,
+ srcReader,
+ destReader,
+ idp.numDatabaseHotseatIcons,
+ Point(idp.numColumns, idp.numRows)
+ )
+ task.migrate(idp)
+
+ // Get workspace items
+ val c = context.contentResolver.query(
+ CONTENT_URI,
+ arrayOf(INTENT, SCREEN),
+ "container=$CONTAINER_DESKTOP",
+ null,
+ null,
+ null
+ ) ?: throw IllegalStateException()
+ val intentIndex = c.getColumnIndex(INTENT)
+ val screenIndex = c.getColumnIndex(SCREEN)
+
+ // Get in which screen the icon is
+ val locMap = HashMap<String, Int>()
+ while (c.moveToNext()) {
+ locMap[Intent.parseUri(c.getString(intentIndex), 0).getPackage()] =
+ c.getInt(screenIndex)
+ }
+ c.close()
+ assertThat(locMap.size).isEqualTo(5)
+ assertThat(locMap[testPackage1]).isEqualTo(0)
+ assertThat(locMap[testPackage2]).isEqualTo(0)
+ assertThat(locMap[testPackage3]).isEqualTo(1)
+ assertThat(locMap[testPackage4]).isEqualTo(1)
+ assertThat(locMap[testPackage5]).isEqualTo(2)
+
+ disableNewMigrationLogic()
+ }
+
+ /**
+ * Migrating from a smaller grid to a large one should reflow the pages
+ * if the column difference is more than 2
+ */
+ @Test
+ @Throws(Exception::class)
+ fun migrateFromSmallerGridBigDifference() {
+ enableNewMigrationLogic("2,2")
+
+ // Setup src grid
+ modelHelper.addItem(APP_ICON, 0, DESKTOP, 0, 1, testPackage1, 5, TMP_CONTENT_URI)
+ modelHelper.addItem(APP_ICON, 0, DESKTOP, 1, 1, testPackage2, 6, TMP_CONTENT_URI)
+ modelHelper.addItem(APP_ICON, 1, DESKTOP, 0, 0, testPackage3, 7, TMP_CONTENT_URI)
+ modelHelper.addItem(APP_ICON, 1, DESKTOP, 1, 0, testPackage4, 8, TMP_CONTENT_URI)
+ modelHelper.addItem(APP_ICON, 2, DESKTOP, 0, 0, testPackage5, 9, TMP_CONTENT_URI)
+
+ idp.numDatabaseHotseatIcons = 4
+ idp.numColumns = 5
+ idp.numRows = 5
+ val srcReader = DbReader(db, TMP_TABLE, context, validPackages)
+ val destReader = DbReader(db, TABLE_NAME, context, validPackages)
+ val task = GridSizeMigrationTaskV2(
+ context,
+ db,
+ srcReader,
+ destReader,
+ idp.numDatabaseHotseatIcons,
+ Point(idp.numColumns, idp.numRows)
+ )
+ task.migrate(idp)
+
+ // Get workspace items
+ val c = context.contentResolver.query(
+ CONTENT_URI,
+ arrayOf(INTENT, SCREEN),
+ "container=$CONTAINER_DESKTOP",
+ null,
+ null,
+ null
+ ) ?: throw IllegalStateException()
+
+ val intentIndex = c.getColumnIndex(INTENT)
+ val screenIndex = c.getColumnIndex(SCREEN)
+
+ // Get in which screen the icon is
+ val locMap = HashMap<String, Int>()
+ while (c.moveToNext()) {
+ locMap[Intent.parseUri(c.getString(intentIndex), 0).getPackage()] =
+ c.getInt(screenIndex)
+ }
+ c.close()
+
+ // All icons fit the first screen
+ assertThat(locMap.size).isEqualTo(5)
+ assertThat(locMap[testPackage1]).isEqualTo(0)
+ assertThat(locMap[testPackage2]).isEqualTo(0)
+ assertThat(locMap[testPackage3]).isEqualTo(0)
+ assertThat(locMap[testPackage4]).isEqualTo(0)
+ assertThat(locMap[testPackage5]).isEqualTo(0)
+ disableNewMigrationLogic()
+ }
+
+ /**
+ * Migrating from a larger grid to a smaller, we reflow from page 0
+ */
+ @Test
+ @Throws(Exception::class)
+ fun migrateFromLargerGrid() {
+ enableNewMigrationLogic("5,5")
+
+ // Setup src grid
+ modelHelper.addItem(APP_ICON, 0, DESKTOP, 0, 1, testPackage1, 5, TMP_CONTENT_URI)
+ modelHelper.addItem(APP_ICON, 0, DESKTOP, 1, 1, testPackage2, 6, TMP_CONTENT_URI)
+ modelHelper.addItem(APP_ICON, 1, DESKTOP, 0, 0, testPackage3, 7, TMP_CONTENT_URI)
+ modelHelper.addItem(APP_ICON, 1, DESKTOP, 1, 0, testPackage4, 8, TMP_CONTENT_URI)
+ modelHelper.addItem(APP_ICON, 2, DESKTOP, 0, 0, testPackage5, 9, TMP_CONTENT_URI)
+
+ idp.numDatabaseHotseatIcons = 4
+ idp.numColumns = 4
+ idp.numRows = 4
+ val srcReader = DbReader(db, TMP_TABLE, context, validPackages)
+ val destReader = DbReader(db, TABLE_NAME, context, validPackages)
+ val task = GridSizeMigrationTaskV2(
+ context,
+ db,
+ srcReader,
+ destReader,
+ idp.numDatabaseHotseatIcons,
+ Point(idp.numColumns, idp.numRows)
+ )
+ task.migrate(idp)
+
+ // Get workspace items
+ val c = context.contentResolver.query(
+ CONTENT_URI,
+ arrayOf(INTENT, SCREEN),
+ "container=$CONTAINER_DESKTOP",
+ null,
+ null,
+ null
+ ) ?: throw IllegalStateException()
+ val intentIndex = c.getColumnIndex(INTENT)
+ val screenIndex = c.getColumnIndex(SCREEN)
+
+ // Get in which screen the icon is
+ val locMap = HashMap<String, Int>()
+ while (c.moveToNext()) {
+ locMap[Intent.parseUri(c.getString(intentIndex), 0).getPackage()] =
+ c.getInt(screenIndex)
+ }
+ c.close()
+
+ // All icons fit the first screen
+ assertThat(locMap.size).isEqualTo(5)
+ assertThat(locMap[testPackage1]).isEqualTo(0)
+ assertThat(locMap[testPackage2]).isEqualTo(0)
+ assertThat(locMap[testPackage3]).isEqualTo(0)
+ assertThat(locMap[testPackage4]).isEqualTo(0)
+ assertThat(locMap[testPackage5]).isEqualTo(0)
+
+ disableNewMigrationLogic()
+ }
+
+ private fun enableNewMigrationLogic(srcGridSize: String) {
+ context.getSharedPreferences(FeatureFlags.FLAGS_PREF_NAME, Context.MODE_PRIVATE)
+ .edit()
+ .putBoolean(FeatureFlags.ENABLE_NEW_MIGRATION_LOGIC.key, true)
+ .commit()
+ context.getSharedPreferences(LauncherFiles.SHARED_PREFERENCES_KEY, Context.MODE_PRIVATE)
+ .edit()
+ .putString(DeviceGridState.KEY_WORKSPACE_SIZE, srcGridSize)
+ .commit()
+ FeatureFlags.initialize(context)
+ }
+
+ private fun disableNewMigrationLogic() {
+ context.getSharedPreferences(FeatureFlags.FLAGS_PREF_NAME, Context.MODE_PRIVATE)
+ .edit()
+ .putBoolean(FeatureFlags.ENABLE_NEW_MIGRATION_LOGIC.key, false)
+ .commit()
+ }
+}
\ No newline at end of file
diff --git a/tests/src/com/android/launcher3/ui/AbstractLauncherUiTest.java b/tests/src/com/android/launcher3/ui/AbstractLauncherUiTest.java
index 79a4673..5abdcd3 100644
--- a/tests/src/com/android/launcher3/ui/AbstractLauncherUiTest.java
+++ b/tests/src/com/android/launcher3/ui/AbstractLauncherUiTest.java
@@ -38,6 +38,7 @@
import android.os.RemoteException;
import android.os.UserHandle;
import android.os.UserManager;
+import android.platform.test.rule.CrashDetector;
import android.system.OsConstants;
import android.util.Log;
@@ -225,6 +226,7 @@
@Rule
public TestRule mOrderSensitiveRules = RuleChain
.outerRule(new TestStabilityRule())
+ .around(new CrashDetector("com.android.systemui"))
.around(mActivityMonitor)
.around(getRulesInsideActivityMonitor());
diff --git a/tests/src/com/android/launcher3/ui/workspace/ThemeIconsTest.java b/tests/src/com/android/launcher3/ui/workspace/ThemeIconsTest.java
new file mode 100644
index 0000000..e66810c
--- /dev/null
+++ b/tests/src/com/android/launcher3/ui/workspace/ThemeIconsTest.java
@@ -0,0 +1,128 @@
+/*
+ * 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.ui.workspace;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.assertTrue;
+
+import android.content.ContentProviderClient;
+import android.content.ContentResolver;
+import android.content.ContentValues;
+import android.net.Uri;
+import android.view.View;
+import android.view.ViewGroup;
+
+import androidx.test.filters.LargeTest;
+
+import com.android.launcher3.BubbleTextView;
+import com.android.launcher3.icons.ThemedIconDrawable;
+import com.android.launcher3.tapl.HomeAllApps;
+import com.android.launcher3.tapl.HomeAppIcon;
+import com.android.launcher3.ui.AbstractLauncherUiTest;
+import com.android.launcher3.ui.TaplTestsLauncher3;
+
+import org.junit.Test;
+
+import java.util.ArrayDeque;
+import java.util.Queue;
+
+/**
+ * Tests for theme icon support in Launcher
+ *
+ * Note running these tests will clear the workspace on the device.
+ */
+@LargeTest
+public class ThemeIconsTest extends AbstractLauncherUiTest {
+
+ private static final String APP_NAME = "ThemeIconTestActivity";
+
+ @Test
+ public void testIconWithoutTheme() throws Exception {
+ setThemeEnabled(false);
+ TaplTestsLauncher3.initialize(this);
+
+ HomeAllApps allApps = mLauncher.getWorkspace().switchToAllApps();
+ allApps.freeze();
+
+ try {
+ HomeAppIcon icon = allApps.getAppIcon(APP_NAME);
+ executeOnLauncher(l -> verifyIconTheme(l.getAppsView(), false));
+ icon.dragToWorkspace(false, false);
+ executeOnLauncher(l -> verifyIconTheme(l.getWorkspace(), false));
+ } finally {
+ allApps.unfreeze();
+ }
+ }
+
+ @Test
+ public void testIconWithTheme() throws Exception {
+ setThemeEnabled(true);
+ TaplTestsLauncher3.initialize(this);
+
+ HomeAllApps allApps = mLauncher.getWorkspace().switchToAllApps();
+ allApps.freeze();
+
+ try {
+ HomeAppIcon icon = allApps.getAppIcon(APP_NAME);
+ executeOnLauncher(l -> verifyIconTheme(l.getAppsView(), false));
+ icon.dragToWorkspace(false, false);
+ executeOnLauncher(l -> verifyIconTheme(l.getWorkspace(), true));
+ } finally {
+ allApps.unfreeze();
+ }
+ }
+
+ private void verifyIconTheme(ViewGroup parent, boolean isThemed) {
+ // Find the app icon
+ Queue<View> viewQueue = new ArrayDeque<>();
+ viewQueue.add(parent);
+ BubbleTextView icon = null;
+ while (!viewQueue.isEmpty()) {
+ View view = viewQueue.poll();
+ if (view instanceof ViewGroup) {
+ parent = (ViewGroup) view;
+ for (int i = parent.getChildCount() - 1; i >= 0; i--) {
+ viewQueue.add(parent.getChildAt(i));
+ }
+ } else if (view instanceof BubbleTextView) {
+ BubbleTextView btv = (BubbleTextView) view;
+ if (APP_NAME.equals(btv.getText())) {
+ icon = btv;
+ break;
+ }
+ }
+ }
+
+ assertNotNull(icon.getIcon());
+ assertEquals(isThemed, icon.getIcon() instanceof ThemedIconDrawable);
+ }
+
+ private void setThemeEnabled(boolean isEnabled) throws Exception {
+ Uri uri = new Uri.Builder()
+ .scheme(ContentResolver.SCHEME_CONTENT)
+ .authority(mTargetPackage + ".grid_control")
+ .appendPath("set_icon_themed")
+ .build();
+ ContentValues values = new ContentValues();
+ values.put("boolean_value", isEnabled);
+ try (ContentProviderClient client = mTargetContext.getContentResolver()
+ .acquireContentProviderClient(uri)) {
+ int result = client.update(uri, values, null);
+ assertTrue(result > 0);
+ }
+ }
+}