From 2321e1a323c027d74b04f1429d4364e455136972 Mon Sep 17 00:00:00 2001 From: Bill Yi Date: Thu, 26 Sep 2024 19:15:19 -0700 Subject: [PATCH 1/7] Import translations. DO NOT MERGE ANYWHERE Auto-generated-cl: translation import Change-Id: I5a631a9968edafb4f7cdc83a9b0a21cd7bb65b12 --- quickstep/res/values-am/strings.xml | 3 +-- quickstep/res/values-b+sr+Latn/strings.xml | 3 +-- quickstep/res/values-be/strings.xml | 3 +-- quickstep/res/values-bs/strings.xml | 3 +-- quickstep/res/values-es/strings.xml | 3 +-- quickstep/res/values-hr/strings.xml | 3 +-- quickstep/res/values-is/strings.xml | 3 +-- quickstep/res/values-ja/strings.xml | 3 +-- quickstep/res/values-ka/strings.xml | 3 +-- quickstep/res/values-kk/strings.xml | 3 +-- quickstep/res/values-km/strings.xml | 3 +-- quickstep/res/values-ky/strings.xml | 3 +-- quickstep/res/values-lt/strings.xml | 3 +-- quickstep/res/values-ml/strings.xml | 3 +-- quickstep/res/values-ms/strings.xml | 3 +-- quickstep/res/values-ne/strings.xml | 3 +-- quickstep/res/values-pt-rPT/strings.xml | 3 +-- quickstep/res/values-pt/strings.xml | 3 +-- quickstep/res/values-ru/strings.xml | 3 +-- quickstep/res/values-si/strings.xml | 3 +-- quickstep/res/values-sl/strings.xml | 3 +-- quickstep/res/values-sr/strings.xml | 3 +-- quickstep/res/values-sv/strings.xml | 3 +-- quickstep/res/values-te/strings.xml | 3 +-- 24 files changed, 24 insertions(+), 48 deletions(-) diff --git a/quickstep/res/values-am/strings.xml b/quickstep/res/values-am/strings.xml index 28bd69a8cb..0848ddd48e 100644 --- a/quickstep/res/values-am/strings.xml +++ b/quickstep/res/values-am/strings.xml @@ -139,8 +139,7 @@ "ሁልጊዜ የተግባር አሞሌ ያሳዩ" "የአሰሳ ሁነታን ይለውጡ" "የተግባር አሞሌ አካፋይ" - - + "የተግባር አሞሌ ትርፍ ፍሰት" "ወደ ላይ/ግራ ይውሰዱ" "ወደ ታች/ቀኝ ይውሰዱ" "{count,plural, =1{ተጨማሪ መተግበሪያ}one{ተጨማሪ መተግበሪያ}other{ተጨማሪ መተግበሪያዎች}}" diff --git a/quickstep/res/values-b+sr+Latn/strings.xml b/quickstep/res/values-b+sr+Latn/strings.xml index f08cf835b5..aa16f3c353 100644 --- a/quickstep/res/values-b+sr+Latn/strings.xml +++ b/quickstep/res/values-b+sr+Latn/strings.xml @@ -139,8 +139,7 @@ "Uvek prikazuj traku zadataka" "Promeni režim navigacije" "Razdelnik trake zadataka" - - + "Preklopna traka zadataka" "Premesti gore levo" "Premesti dole desno" "{count,plural, =1{dodatna aplikacija}one{dodatna aplikacija}few{dodatne aplikacije}other{dodatnih aplikacija}}" diff --git a/quickstep/res/values-be/strings.xml b/quickstep/res/values-be/strings.xml index fb5b55698d..4dcfe62c1c 100644 --- a/quickstep/res/values-be/strings.xml +++ b/quickstep/res/values-be/strings.xml @@ -139,8 +139,7 @@ "Заўсёды паказваць панэль задач" "Змяніць рэжым навігацыі" "Раздзяляльнік панэлі задач" - - + "Меню з пашырэннем панэлі задач" "Перамясціць уверх/улева" "Перамясціць уніз/управа" "{count,plural, =1{даступная праграма}one{даступная праграма}few{даступныя праграмы}many{даступных праграм}other{даступнай праграмы}}" diff --git a/quickstep/res/values-bs/strings.xml b/quickstep/res/values-bs/strings.xml index 6588dd060c..3357a6e7eb 100644 --- a/quickstep/res/values-bs/strings.xml +++ b/quickstep/res/values-bs/strings.xml @@ -139,8 +139,7 @@ "Uvijek prikaži traku zadataka" "Promijeni način navigacije" "Razdjelnik trake zadataka" - - + "Dodatni izbornik trake sa zadacima" "Premjesti gore lijevo" "Premjesti dolje desno" "{count,plural, =1{dodatna aplikacija}one{dodatna aplikacija}few{dodatne aplikacije}other{dodatnih aplikacija}}" diff --git a/quickstep/res/values-es/strings.xml b/quickstep/res/values-es/strings.xml index 527bdc30d3..d8bbc55815 100644 --- a/quickstep/res/values-es/strings.xml +++ b/quickstep/res/values-es/strings.xml @@ -139,8 +139,7 @@ "Barra de tareas visible" "Cambiar el modo de navegación" "Divisor de Barra de Tareas" - - + "Barra de tareas ampliada" "Mover arriba/a la izquierda" "Mover abajo/a la derecha" "{count,plural, =1{aplicación más}other{aplicaciones más}}" diff --git a/quickstep/res/values-hr/strings.xml b/quickstep/res/values-hr/strings.xml index a2bf69159f..2514aa157f 100644 --- a/quickstep/res/values-hr/strings.xml +++ b/quickstep/res/values-hr/strings.xml @@ -139,8 +139,7 @@ "Uvijek prikaži traku zadataka" "Promijeni način navigacije" "Razdjelnik trake sa zadacima" - - + "Dodatni izbornik trake sa zadacima" "Premjesti gore/lijevo" "Premjesti dolje/desno" "{count,plural, =1{dodatna aplikacija}one{dodatna aplikacija}few{dodatne aplikacije}other{dodatnih aplikacija}}" diff --git a/quickstep/res/values-is/strings.xml b/quickstep/res/values-is/strings.xml index 274e1da362..3aec0ceb32 100644 --- a/quickstep/res/values-is/strings.xml +++ b/quickstep/res/values-is/strings.xml @@ -139,8 +139,7 @@ "Alltaf sýna forritastiku" "Breyta leiðsagnarstillingu" "Skipting forritastiku" - - + "Yfirflæði á forritastiku" "Færa efst/til vinstri" "Færa neðst/til hægri" "{count,plural, =1{forrit til viðbótar}one{forrit til viðbótar}other{forrit til viðbótar}}" diff --git a/quickstep/res/values-ja/strings.xml b/quickstep/res/values-ja/strings.xml index 0cff4c1f53..28b7746b43 100644 --- a/quickstep/res/values-ja/strings.xml +++ b/quickstep/res/values-ja/strings.xml @@ -139,8 +139,7 @@ "常にタスクバーを表示する" "ナビゲーション モードを変更" "タスクバーの区切り" - - + "タスクバーのオーバフロー" "上 / 左に移動" "下 / 右に移動" "{count,plural, =1{個のその他のアプリ}other{個のその他のアプリ}}" diff --git a/quickstep/res/values-ka/strings.xml b/quickstep/res/values-ka/strings.xml index efff980290..d84d53e576 100644 --- a/quickstep/res/values-ka/strings.xml +++ b/quickstep/res/values-ka/strings.xml @@ -139,8 +139,7 @@ "ამოცანათა ზოლის მუდამ ჩვენება" "შეცვალეთ ნავიგაციის რეჟიმი" "ამოცანათა ზოლის გამყოფი" - - + "ამოცანათა ზოლის გადავსება" "ზემოთ/მარცხნივ გადატანა" "ქვემოთ/მარჯვნივ გადატანა" "{count,plural, =1{სხვა აპი}other{სხვა აპი}}" diff --git a/quickstep/res/values-kk/strings.xml b/quickstep/res/values-kk/strings.xml index 193b606307..4cdbfc4d94 100644 --- a/quickstep/res/values-kk/strings.xml +++ b/quickstep/res/values-kk/strings.xml @@ -139,8 +139,7 @@ "Тапсырма жолағын үнемі көрсету" "Навигация режимін өзгерту" "Тапсырмалар жолағын бөлгіш" - - + "\"Тапсырмалар жолағы\" қосымша мәзірі" "Жоғары/солға жылжыту" "Төмен/оңға жылжыту" "{count,plural, =1{қосымша қолданба}other{қосымша қолданба}}" diff --git a/quickstep/res/values-km/strings.xml b/quickstep/res/values-km/strings.xml index aadfd673cd..5cf1b92737 100644 --- a/quickstep/res/values-km/strings.xml +++ b/quickstep/res/values-km/strings.xml @@ -139,8 +139,7 @@ "បង្ហាញរបារកិច្ចការជានិច្ច" "ប្ដូរ​មុខងាររុករក" "បន្ទាត់​ខណ្ឌចែករបារកិច្ចការ" - - + "ម៉ឺនុយបន្ថែមរបារកិច្ចការ" "ផ្លាស់ទីទៅខាងលើ/ឆ្វេង" "ផ្លាស់ទីទៅខាងក្រោម/ស្ដាំ" "{count,plural, =1{កម្មវិធីច្រើនទៀត}other{កម្មវិធីច្រើនទៀត}}" diff --git a/quickstep/res/values-ky/strings.xml b/quickstep/res/values-ky/strings.xml index 8eba2a5215..faf5675762 100644 --- a/quickstep/res/values-ky/strings.xml +++ b/quickstep/res/values-ky/strings.xml @@ -139,8 +139,7 @@ "Такта ар дайым көрүнсүн" "Өтүү режимин өзгөртүү" "Тапшырмалар панелин бөлгүч" - - + "\"Тапшырмалар панели\" кошумча менюсу" "Жогорку/сол бурчка жылдыруу" "Төмөнкү/оң бурчка жылдыруу" "{count,plural, =1{колдонмо бар}other{колдонмо бар}}" diff --git a/quickstep/res/values-lt/strings.xml b/quickstep/res/values-lt/strings.xml index 1c20015f7e..a95249b508 100644 --- a/quickstep/res/values-lt/strings.xml +++ b/quickstep/res/values-lt/strings.xml @@ -139,8 +139,7 @@ "Visada rodyti užduočių juostą" "Keisti naršymo režimą" "Užduočių juostos daliklis" - - + "Užduočių juostos perpildymas" "Perkelti aukštyn, kairėn" "Perkelti žemyn, dešinėn" "{count,plural, =1{papildoma programa}one{papildoma programa}few{papildomos programos}many{papildomos programos}other{papildomų programų}}" diff --git a/quickstep/res/values-ml/strings.xml b/quickstep/res/values-ml/strings.xml index bb5c01480a..c15a241bdb 100644 --- a/quickstep/res/values-ml/strings.xml +++ b/quickstep/res/values-ml/strings.xml @@ -139,8 +139,7 @@ "ടാസ്‌ക്ബാർ എപ്പോഴും കാണിക്കൂ" "നാവിഗേഷൻ മോഡ് മാറ്റുക" "ടാസ്‌ക്ബാർ ഡിവൈഡർ" - - + "ടാസ്‌ക്ബാർ ഓവർഫ്ലോ" "മുകളിലേക്കോ ഇടത്തേക്കോ നീക്കുക" "താഴേക്കോ വലത്തേക്കോ നീക്കുക" "{count,plural, =1{കൂടുതൽ ആപ്പ്}other{കൂടുതൽ ആപ്പുകൾ}}" diff --git a/quickstep/res/values-ms/strings.xml b/quickstep/res/values-ms/strings.xml index 9bdc9734a5..a1f19a95a4 100644 --- a/quickstep/res/values-ms/strings.xml +++ b/quickstep/res/values-ms/strings.xml @@ -139,8 +139,7 @@ "Papar Bar Tugas selalu" "Tukar mod navigasi" "Pembahagi Bar Tugas" - - + "Limpahan Bar Tugas" "Alihkan ke atas/kiri" "Alihkan ke bawah/kanan" "{count,plural, =1{apl lagi}other{apl lagi}}" diff --git a/quickstep/res/values-ne/strings.xml b/quickstep/res/values-ne/strings.xml index 4c9747f351..a2d4d325b3 100644 --- a/quickstep/res/values-ne/strings.xml +++ b/quickstep/res/values-ne/strings.xml @@ -139,8 +139,7 @@ "टास्कबार सधैँ देखाउनुहोस्" "नेभिगेसन मोड बदल्नुहोस्" "टास्कबार डिभाइडर" - - + "टास्कबार ओभरफ्लो" "सिरान/बायाँतिर सार्नुहोस्" "फेद/दायाँतिर सार्नुहोस्" "{count,plural, =1{थप एप}other{थप एपहरू}}" diff --git a/quickstep/res/values-pt-rPT/strings.xml b/quickstep/res/values-pt-rPT/strings.xml index 5ad32afaf1..2167875719 100644 --- a/quickstep/res/values-pt-rPT/strings.xml +++ b/quickstep/res/values-pt-rPT/strings.xml @@ -139,8 +139,7 @@ "Ver sempre Barra de tarefas" "Alterar modo de navegação" "Divisor da Barra de tarefas" - - + "Menu adicional da Barra de tarefas" "Mover para a parte superior esquerda" "Mover para a part superior direita" "{count,plural, =1{outra app}other{outras apps}}" diff --git a/quickstep/res/values-pt/strings.xml b/quickstep/res/values-pt/strings.xml index 28b3414715..9309810cdf 100644 --- a/quickstep/res/values-pt/strings.xml +++ b/quickstep/res/values-pt/strings.xml @@ -139,8 +139,7 @@ "Sempre mostrar a Barra de tarefas" "Mudar o modo de navegação" "Separador da Barra de tarefas" - - + "Barra de tarefas flutuante" "Mover para cima/para a esquerda" "Mover para baixo/para a direita" "{count,plural, =1{outro app}one{outro app}other{outros apps}}" diff --git a/quickstep/res/values-ru/strings.xml b/quickstep/res/values-ru/strings.xml index 20f579dbd5..76c4e1f646 100644 --- a/quickstep/res/values-ru/strings.xml +++ b/quickstep/res/values-ru/strings.xml @@ -139,8 +139,7 @@ "Всегда показывать панель задач" "Изменить режим навигации" "Разделитель панели задач" - - + "Дополнительное меню панели задач" "Переместить вверх или влево" "Переместить вниз или вправо" "{count,plural, =1{дополнительное приложение}one{дополнительное приложение}few{дополнительных приложения}many{дополнительных приложений}other{дополнительного приложения}}" diff --git a/quickstep/res/values-si/strings.xml b/quickstep/res/values-si/strings.xml index dd9739c11d..0953b38bd1 100644 --- a/quickstep/res/values-si/strings.xml +++ b/quickstep/res/values-si/strings.xml @@ -139,8 +139,7 @@ "සෑම විටම කාර්ය තීරුව පෙන්වන්න" "සංචාලන ප්‍රකාරය වෙනස් කරන්න" "කාර්ය තීරු බෙදනය" - - + "කාර්ය තීරුව පිටාර යාම" "ඉහළ/වම වෙත ගෙන යන්න" "පහළ/දකුණ වෙත ගෙන යන්න" "{count,plural, =1{තව යෙදුම}one{තවත් යෙදුම්}other{තවත් යෙදුම්}}" diff --git a/quickstep/res/values-sl/strings.xml b/quickstep/res/values-sl/strings.xml index 9394a5a34c..94de1e0567 100644 --- a/quickstep/res/values-sl/strings.xml +++ b/quickstep/res/values-sl/strings.xml @@ -139,8 +139,7 @@ "Stalen prikaz oprav. vrstice" "Spreminjanje načina navigacije" "Razdelilnik opravilne vrstice" - - + "Oblaček opravilne vrstice z dodatnimi elementi" "Premakni na vrh/levo" "Premakni na dno/desno" "{count,plural, =1{dodatna aplikacija}one{dodatna aplikacija}two{dodatni aplikaciji}few{dodatne aplikacije}other{dodatnih aplikacij}}" diff --git a/quickstep/res/values-sr/strings.xml b/quickstep/res/values-sr/strings.xml index a7760b9735..d6e5d03cee 100644 --- a/quickstep/res/values-sr/strings.xml +++ b/quickstep/res/values-sr/strings.xml @@ -139,8 +139,7 @@ "Увек приказуј траку задатака" "Промени режим навигације" "Разделник траке задатака" - - + "Преклопна трака задатака" "Премести горе лево" "Премести доле десно" "{count,plural, =1{додатна апликација}one{додатна апликација}few{додатне апликације}other{додатних апликација}}" diff --git a/quickstep/res/values-sv/strings.xml b/quickstep/res/values-sv/strings.xml index d4c3a695c0..bba98c6fb6 100644 --- a/quickstep/res/values-sv/strings.xml +++ b/quickstep/res/values-sv/strings.xml @@ -139,8 +139,7 @@ "Visa alltid aktivitetsfältet" "Ändra navigeringsläge" "Avdelare för aktivitetsfältet" - - + "Fler alternativ för aktivitetsfältet" "Flytta högst upp/till vänster" "Flytta längst ned/till höger" "{count,plural, =1{app till}other{appar till}}" diff --git a/quickstep/res/values-te/strings.xml b/quickstep/res/values-te/strings.xml index 86161b4900..91ef8463a9 100644 --- a/quickstep/res/values-te/strings.xml +++ b/quickstep/res/values-te/strings.xml @@ -139,8 +139,7 @@ "టాస్క్‌బార్‌ను నిరంతరం చూపండి" "నావిగేషన్ మోడ్‌ను మార్చండి" "టాస్క్‌బార్ డివైడర్" - - + "టాస్క్‌బార్ ఓవర్‌ఫ్లో" "ఎగువ/ఎడమ వైపునకు తరలించండి" "దిగువ/కుడి వైపునకు తరలించండి" "{count,plural, =1{మరో యాప్‌}other{మరిన్ని యాప్‌లు}}" From dfbe78fc0796bae5734c9e825a4e8b3ed4ecd010 Mon Sep 17 00:00:00 2001 From: Bill Yi Date: Thu, 26 Sep 2024 19:16:07 -0700 Subject: [PATCH 2/7] Import translations. DO NOT MERGE ANYWHERE Auto-generated-cl: translation import Change-Id: Iece37a3f71514301080854e669827f80721f103a --- res/values-am/strings.xml | 3 +-- res/values-b+sr+Latn/strings.xml | 3 +-- res/values-be/strings.xml | 3 +-- res/values-bs/strings.xml | 3 +-- res/values-es/strings.xml | 3 +-- res/values-fa/strings.xml | 2 +- res/values-hr/strings.xml | 3 +-- res/values-is/strings.xml | 3 +-- res/values-ja/strings.xml | 3 +-- res/values-ka/strings.xml | 3 +-- res/values-kk/strings.xml | 3 +-- res/values-km/strings.xml | 3 +-- res/values-ky/strings.xml | 3 +-- res/values-lt/strings.xml | 3 +-- res/values-ml/strings.xml | 3 +-- res/values-ms/strings.xml | 3 +-- res/values-ne/strings.xml | 3 +-- res/values-pt-rPT/strings.xml | 3 +-- res/values-pt/strings.xml | 3 +-- res/values-ru/strings.xml | 3 +-- res/values-si/strings.xml | 3 +-- res/values-sl/strings.xml | 3 +-- res/values-sr/strings.xml | 3 +-- res/values-sv/strings.xml | 3 +-- res/values-te/strings.xml | 3 +-- 25 files changed, 25 insertions(+), 49 deletions(-) diff --git a/res/values-am/strings.xml b/res/values-am/strings.xml index be91c0b738..53dc4bae3d 100644 --- a/res/values-am/strings.xml +++ b/res/values-am/strings.xml @@ -31,8 +31,7 @@ "የተከፈለ ማያ ገፅ" "የመተግበሪያ መረጃ ለ%1$s" "የ%1$s የአጠቃቀም ቅንብሮች" - - + "አዲስ መስኮት" "የመተግበሪያ ጥምረትን ያስቀምጡ" "%1$s | %2$s" "ይህ የመተግበሪያ ጥምረት በዚህ መሣሪያ ላይ አይደገፍም" diff --git a/res/values-b+sr+Latn/strings.xml b/res/values-b+sr+Latn/strings.xml index 35ba18357d..002c800a04 100644 --- a/res/values-b+sr+Latn/strings.xml +++ b/res/values-b+sr+Latn/strings.xml @@ -31,8 +31,7 @@ "Podeljeni ekran" "Informacije o aplikaciji za: %1$s" "Podešavanja potrošnje za %1$s" - - + "Novi prozor" "Sačuvaj par aplikacija" "%1$s | %2$s" "Ovaj par aplikacija nije podržan na ovom uređaju" diff --git a/res/values-be/strings.xml b/res/values-be/strings.xml index 1a2bcc13f7..0984f3216f 100644 --- a/res/values-be/strings.xml +++ b/res/values-be/strings.xml @@ -31,8 +31,7 @@ "Падзелены экран" "Інфармацыя пра праграму для: %1$s" "%1$s: налады выкарыстання" - - + "Новае акно" "Захаваць спалучэнне праграм" "%1$s | %2$s" "Дадзенае спалучэнне праграм не падтрымліваецца на гэтай прыладзе" diff --git a/res/values-bs/strings.xml b/res/values-bs/strings.xml index e4bbd30f52..2b168f60d1 100644 --- a/res/values-bs/strings.xml +++ b/res/values-bs/strings.xml @@ -31,8 +31,7 @@ "Podijeljeni ekran" "Informacije o aplikaciji %1$s" "Postavke korištenja za: %1$s" - - + "Novi prozor" "Sačuvaj par aplikacija" "%1$s | %2$s" "Par aplikacija nije podržan na uređaju" diff --git a/res/values-es/strings.xml b/res/values-es/strings.xml index 169afe52c2..ddcee65306 100644 --- a/res/values-es/strings.xml +++ b/res/values-es/strings.xml @@ -31,8 +31,7 @@ "Pantalla dividida" "Información de la aplicación %1$s" "Ajustes de uso para %1$s" - - + "Ventana nueva" "Guardar apps emparejadas" "%1$s | %2$s" "El dispositivo no admite esta aplicación emparejada" diff --git a/res/values-fa/strings.xml b/res/values-fa/strings.xml index d8417703f2..c0a6fe3f65 100644 --- a/res/values-fa/strings.xml +++ b/res/values-fa/strings.xml @@ -132,7 +132,7 @@ "برای نمایش «نقطه‌های اعلان»، اعلان‌های برنامه را برای %1$s روشن کنید" "تغییر تنظیمات" "نمایش نقطه‌های اعلان" - "گزینه‌های برنامه‌نویس" + "گزینه‌های توسعه‌دهندگان" "افزودن نماد برنامه‌ها به صفحه اصلی" "برای برنامه‌های جدید" "نامشخص" diff --git a/res/values-hr/strings.xml b/res/values-hr/strings.xml index 3d5380a66b..a9fd14e2f3 100644 --- a/res/values-hr/strings.xml +++ b/res/values-hr/strings.xml @@ -31,8 +31,7 @@ "Podijeljeni zaslon" "Informacije o aplikaciji %1$s" "Postavke upotrebe za %1$s" - - + "Novi prozor" "Spremi par aplikacija" "%1$s | %2$s" "Taj par aplikacija nije podržan na ovom uređaju" diff --git a/res/values-is/strings.xml b/res/values-is/strings.xml index 7a87b2665d..001431797f 100644 --- a/res/values-is/strings.xml +++ b/res/values-is/strings.xml @@ -31,8 +31,7 @@ "Skipta skjá" "Upplýsingar um forrit fyrir %1$s" "Notkunarstillingar fyrir %1$s" - - + "Nýr gluggi" "Vista forritapar" "%1$s | %2$s" "Þetta forritapar er ekki stutt í þessu tæki" diff --git a/res/values-ja/strings.xml b/res/values-ja/strings.xml index cea0a08a27..fc89041cdd 100644 --- a/res/values-ja/strings.xml +++ b/res/values-ja/strings.xml @@ -31,8 +31,7 @@ "分割画面" "%1$s のアプリ情報" "%1$s の使用設定" - - + "新しいウィンドウ" "アプリのペア設定を保存" "%1$s | %2$s" "このデバイスは、このアプリのペア設定に対応していません" diff --git a/res/values-ka/strings.xml b/res/values-ka/strings.xml index 2211a7d11e..f099bcde78 100644 --- a/res/values-ka/strings.xml +++ b/res/values-ka/strings.xml @@ -31,8 +31,7 @@ "ეკრანის გაყოფა" "%1$s-ის აპის ინფო" "გამოყენების პარამეტრები %1$s-ისთვის" - - + "ახალი ფანჯარა" "აპთა წყვილის შენახვა" "%1$s | %2$s" "ამ მოწყობილობაზე აღნიშნული აპთა წყვილი არ არის მხარდაჭერილი" diff --git a/res/values-kk/strings.xml b/res/values-kk/strings.xml index ca26ea4515..ebaacc9e65 100644 --- a/res/values-kk/strings.xml +++ b/res/values-kk/strings.xml @@ -31,8 +31,7 @@ "Экранды бөлу" "%1$s қолданбасы туралы ақпарат" "%1$s пайдалану параметрлері" - - + "Жаңа терезе" "Қолданбаларды жұптау әрекетін сақтау" "%1$s | %2$s" "Бұл құрылғы қолданбаларды жұптау функциясын қолдамайды." diff --git a/res/values-km/strings.xml b/res/values-km/strings.xml index dc4fd80d24..b05eeb05cc 100644 --- a/res/values-km/strings.xml +++ b/res/values-km/strings.xml @@ -31,8 +31,7 @@ "មុខងារ​បំបែកអេក្រង់" "ព័ត៌មានកម្មវិធី​សម្រាប់ %1$s" "ការកំណត់ការប្រើប្រាស់សម្រាប់ %1$s" - - + "វិនដូ​ថ្មី" "រក្សាទុកគូកម្មវិធី" "%1$s | %2$s" "មិនអាចប្រើគូកម្មវិធីនេះនៅលើឧបករណ៍នេះបានទេ" diff --git a/res/values-ky/strings.xml b/res/values-ky/strings.xml index b32618154e..753d2dd26b 100644 --- a/res/values-ky/strings.xml +++ b/res/values-ky/strings.xml @@ -31,8 +31,7 @@ "Экранды бөлүү" "%1$s колдонмосу жөнүндө маалымат" "%1$s колдонмосун пайдалануу параметрлери" - - + "Жаңы терезе" "Колдонмолорду сактап коюу" "%1$s | %2$s" "Бул эки колдонмону бул түзмөктө бир маалда пайдаланууга болбойт" diff --git a/res/values-lt/strings.xml b/res/values-lt/strings.xml index a613cb1cbf..6879862fd4 100644 --- a/res/values-lt/strings.xml +++ b/res/values-lt/strings.xml @@ -31,8 +31,7 @@ "Išskaidyto ekrano režimas" "Programos „%1$s“ informacija" "„%1$s“ naudojimo nustatymai" - - + "Naujas langas" "Išsaugoti programų porą" "%1$s | %2$s" "Ši programų pora šiame įrenginyje nepalaikoma" diff --git a/res/values-ml/strings.xml b/res/values-ml/strings.xml index 2eb1b2b947..b9e68e05de 100644 --- a/res/values-ml/strings.xml +++ b/res/values-ml/strings.xml @@ -31,8 +31,7 @@ "സ്‌ക്രീൻ വിഭജന മോഡ്" "%1$s എന്നതിന്റെ ആപ്പ് വിവരങ്ങൾ" "%1$s എന്നതിനുള്ള ഉപയോഗ ക്രമീകരണം" - - + "പുതിയ വിന്‍ഡോ" "ആപ്പ് ജോടി സംരക്ഷിക്കുക" "%1$s | %2$s" "ഈ ഉപകരണത്തിൽ ഈ ആപ്പ് ജോടിക്ക് പിന്തുണയില്ല" diff --git a/res/values-ms/strings.xml b/res/values-ms/strings.xml index b548e67810..5ddf8a2075 100644 --- a/res/values-ms/strings.xml +++ b/res/values-ms/strings.xml @@ -31,8 +31,7 @@ "Skrin pisah" "Maklumat apl untuk %1$s" "Tetapan penggunaan sebanyak %1$s" - - + "Tetingkap Baharu" "Simpan gandingan apl" "%1$s | %2$s" "Gandingan apl ini tidak disokong pada peranti ini" diff --git a/res/values-ne/strings.xml b/res/values-ne/strings.xml index 93c4339af5..4fae68beb8 100644 --- a/res/values-ne/strings.xml +++ b/res/values-ne/strings.xml @@ -31,8 +31,7 @@ "स्प्लिट स्क्रिन" "%1$s का हकमा एपसम्बन्धी जानकारी" "%1$s को प्रयोगसम्बन्धी सेटिङ" - - + "नयाँ विन्डो" "एपको पेयर सेभ गर्नुहोस्" "%1$s | %2$s" "यस डिभाइसमा यो एप पेयर प्रयोग गर्न मिल्दैन" diff --git a/res/values-pt-rPT/strings.xml b/res/values-pt-rPT/strings.xml index c86c58d22c..d2b214e225 100644 --- a/res/values-pt-rPT/strings.xml +++ b/res/values-pt-rPT/strings.xml @@ -31,8 +31,7 @@ "Ecrã dividido" "Informações da app para %1$s" "Definições de utilização para %1$s" - - + "Nova janela" "Guardar par de apps" "%1$s | %2$s" "Este par de apps não é suportado neste dispositivo" diff --git a/res/values-pt/strings.xml b/res/values-pt/strings.xml index f10b93af94..f864b3e7c7 100644 --- a/res/values-pt/strings.xml +++ b/res/values-pt/strings.xml @@ -31,8 +31,7 @@ "Tela dividida" "Informações do app %1$s" "Configurações de uso de %1$s" - - + "Nova janela" "Salvar par de apps" "%1$s | %2$s" "Este Par de apps não está disponível no dispositivo" diff --git a/res/values-ru/strings.xml b/res/values-ru/strings.xml index aea3d2b985..126e3ad893 100644 --- a/res/values-ru/strings.xml +++ b/res/values-ru/strings.xml @@ -31,8 +31,7 @@ "Разделить экран" "Сведения о приложении \"%1$s\"" "Настройки использования приложения \"%1$s\"" - - + "Новое окно" "Сохранить приложения" "%1$s | %2$s" "Одновременно использовать эти два приложения на устройстве нельзя." diff --git a/res/values-si/strings.xml b/res/values-si/strings.xml index a3b9a710f8..328f2f5b33 100644 --- a/res/values-si/strings.xml +++ b/res/values-si/strings.xml @@ -31,8 +31,7 @@ "බෙදුම් තිරය" "%1$s සඳහා යෙදුම් තතු" "%1$s සඳහා භාවිත සැකසීම්" - - + "නව කවුළුව" "යෙදුම් යුගල සුරකින්න" "%1$s | %2$s" "මෙම යෙදුම් යුගලය මෙම උපාංගයෙහි සහාය නොදක්වයි" diff --git a/res/values-sl/strings.xml b/res/values-sl/strings.xml index 51b0c7ba1f..37a02e4256 100644 --- a/res/values-sl/strings.xml +++ b/res/values-sl/strings.xml @@ -31,8 +31,7 @@ "Razdeljen zaslon" "Podatki o aplikaciji za: %1$s" "Nastavitve uporabe za »%1$s«" - - + "Novo okno" "Shrani par aplikacij" "%1$s | %2$s" "Ta par aplikacij ni podprt v tej napravi" diff --git a/res/values-sr/strings.xml b/res/values-sr/strings.xml index c93519f7aa..afaeb61e0e 100644 --- a/res/values-sr/strings.xml +++ b/res/values-sr/strings.xml @@ -31,8 +31,7 @@ "Подељени екран" "Информације о апликацији за: %1$s" "Подешавања потрошње за %1$s" - - + "Нови прозор" "Сачувај пар апликација" "%1$s | %2$s" "Овај пар апликација није подржан на овом уређају" diff --git a/res/values-sv/strings.xml b/res/values-sv/strings.xml index c92d6f0fa2..547f60ef9a 100644 --- a/res/values-sv/strings.xml +++ b/res/values-sv/strings.xml @@ -31,8 +31,7 @@ "Delad skärm" "Appinformation för %1$s" "Användningsinställningar för %1$s" - - + "Nytt fönster" "Spara app-par" "%1$s | %2$s" "De här apparna som ska användas tillsammans stöds inte på den här enheten" diff --git a/res/values-te/strings.xml b/res/values-te/strings.xml index 5348a222ab..75dc7f0b60 100644 --- a/res/values-te/strings.xml +++ b/res/values-te/strings.xml @@ -31,8 +31,7 @@ "స్ప్లిట్ స్క్రీన్" "%1$s కోసం యాప్ సమాచారం" "%1$sకు సంబంధించిన వినియోగ సెట్టింగ్‌లు" - - + "కొత్త విండో" "యాప్ పెయిర్‌ను సేవ్ చేయండి" "%1$s | %2$s" "ఈ పరికరంలో ఈ యాప్ పెయిర్ సపోర్ట్ చేయదు" From 2831d1eaf7dfaeb3ed1901480a9e36579e6718e1 Mon Sep 17 00:00:00 2001 From: Luca Zuccarini Date: Wed, 18 Sep 2024 11:08:56 +0000 Subject: [PATCH 3/7] Make workspace and hotseat scale animations interruptible. This affects app launches and returns to home. When launching immediately after returning to home (before the return animation is complete), the two animations could overlap, causing the two property setters to conflict. Bug: 367591368 Flag: com.android.launcher3.coordinate_workspace_scale Test: tested with flag off and on, see before and after in the bug Change-Id: Ie1483fa0bf589caee315ae298e9e68ca361709d8 --- aconfig/launcher.aconfig | 11 ++++ .../launcher3/QuickstepTransitionManager.java | 38 ++++++++++++-- .../util/ScalingWorkspaceRevealAnim.kt | 51 +++++++++++++++---- 3 files changed, 85 insertions(+), 15 deletions(-) diff --git a/aconfig/launcher.aconfig b/aconfig/launcher.aconfig index 38af57260f..9fb5b7b061 100644 --- a/aconfig/launcher.aconfig +++ b/aconfig/launcher.aconfig @@ -433,3 +433,14 @@ flag { description: "Enables tracking active gesture logs in ProtoLog" bug: "293182501" } + + +flag { + name: "coordinate_workspace_scale" + namespace: "launcher" + description: "Ensure that the workspace and hotseat scale doesn't conflict and transitions smoothly between launching and closing apps" + bug: "366403487" + metadata { + purpose: PURPOSE_BUGFIX + } +} diff --git a/quickstep/src/com/android/launcher3/QuickstepTransitionManager.java b/quickstep/src/com/android/launcher3/QuickstepTransitionManager.java index a64936d287..acf74cdede 100644 --- a/quickstep/src/com/android/launcher3/QuickstepTransitionManager.java +++ b/quickstep/src/com/android/launcher3/QuickstepTransitionManager.java @@ -116,6 +116,7 @@ import androidx.annotation.NonNull; import androidx.annotation.Nullable; import androidx.core.graphics.ColorUtils; +import com.android.app.animation.Animations; import com.android.internal.jank.Cuj; import com.android.launcher3.DeviceProfile.OnDeviceProfileChangeListener; import com.android.launcher3.LauncherAnimationRunner.RemoteAnimationFactory; @@ -574,23 +575,45 @@ public class QuickstepTransitionManager implements OnDeviceProfileChangeListener } else { List viewsToAnimate = new ArrayList<>(); Workspace workspace = mLauncher.getWorkspace(); - workspace.forEachVisiblePage( - view -> viewsToAnimate.add(((CellLayout) view).getShortcutsAndWidgets())); + if (Flags.coordinateWorkspaceScale()) { + viewsToAnimate.add(workspace); + } else { + workspace.forEachVisiblePage( + view -> viewsToAnimate.add(((CellLayout) view).getShortcutsAndWidgets())); + } + Hotseat hotseat = mLauncher.getHotseat(); // Do not scale hotseat as a whole when taskbar is present, and scale QSB only if it's // not inline. if (mDeviceProfile.isTaskbarPresent) { if (!mDeviceProfile.isQsbInline) { - viewsToAnimate.add(mLauncher.getHotseat().getQsb()); + viewsToAnimate.add(hotseat.getQsb()); } } else { - viewsToAnimate.add(mLauncher.getHotseat()); + viewsToAnimate.add(hotseat); } viewsToAnimate.forEach(view -> { view.setLayerType(View.LAYER_TYPE_HARDWARE, null); - ObjectAnimator scaleAnim = ObjectAnimator.ofFloat(view, SCALE_PROPERTY, scales) + float[] scale = scales; + if (Flags.coordinateWorkspaceScale()) { + // Start the animation from the current value, instead of assuming the views are + // in their resting state, so interrupted animations merge seamlessly. + // TODO(b/367591368): ideally these animations would be refactored to be + // controlled centrally so each instances doesn't need to care about this + // coordination. + scale = new float[]{view.getScaleX(), scales[1]}; + + // Cancel any ongoing animations. This is necessary to avoid a conflict between + // e.g. the unfinished animation triggered when closing an app back to Home and + // this animation caused by a launch. + Animations.Companion.cancelOngoingAnimation(view); + // Make sure to cache the current animation, so it can be properly interrupted. + Animations.Companion.setOngoingAnimation(view, launcherAnimator); + } + + ObjectAnimator scaleAnim = ObjectAnimator.ofFloat(view, SCALE_PROPERTY, scale) .setDuration(CONTENT_SCALE_DURATION); scaleAnim.setInterpolator(DECELERATE_1_5); launcherAnimator.play(scaleAnim); @@ -600,6 +623,11 @@ public class QuickstepTransitionManager implements OnDeviceProfileChangeListener viewsToAnimate.forEach(view -> { SCALE_PROPERTY.set(view, 1f); view.setLayerType(View.LAYER_TYPE_NONE, null); + + if (Flags.coordinateWorkspaceScale()) { + // Reset the cached animation. + Animations.Companion.setOngoingAnimation(view, null /* animation */); + } }); mLauncher.resumeExpensiveViewUpdates(); }; diff --git a/quickstep/src/com/android/quickstep/util/ScalingWorkspaceRevealAnim.kt b/quickstep/src/com/android/quickstep/util/ScalingWorkspaceRevealAnim.kt index f547a7fba1..a94d023076 100644 --- a/quickstep/src/com/android/quickstep/util/ScalingWorkspaceRevealAnim.kt +++ b/quickstep/src/com/android/quickstep/util/ScalingWorkspaceRevealAnim.kt @@ -23,8 +23,10 @@ import android.graphics.RectF import android.view.View import android.view.animation.PathInterpolator import androidx.core.graphics.transform +import com.android.app.animation.Animations import com.android.app.animation.Interpolators import com.android.app.animation.Interpolators.LINEAR +import com.android.launcher3.Flags import com.android.launcher3.LauncherAnimUtils.HOTSEAT_SCALE_PROPERTY_FACTORY import com.android.launcher3.LauncherAnimUtils.SCALE_INDEX_WORKSPACE_STATE import com.android.launcher3.LauncherAnimUtils.WORKSPACE_SCALE_PROPERTY_FACTORY @@ -44,9 +46,9 @@ import com.android.quickstep.views.RecentsView * the screen outwards radially. This is used in conjunction with the swipe up to home animation. */ class ScalingWorkspaceRevealAnim( - launcher: QuickstepLauncher, + private val launcher: QuickstepLauncher, siblingAnimation: RectFSpringAnim?, - windowTargetRect: RectF? + windowTargetRect: RectF?, ) { companion object { private const val FADE_DURATION_MS = 200L @@ -86,25 +88,40 @@ class ScalingWorkspaceRevealAnim( launcher.workspace.stateTransitionAnimation.setScrim( PropertySetter.NO_ANIM_PROPERTY_SETTER, LauncherState.BACKGROUND_APP, - setupConfig + setupConfig, ) val workspace = launcher.workspace val hotseat = launcher.hotseat + var fromSize = + if (Flags.coordinateWorkspaceScale()) { + // Interrupt the current animation, if any. + Animations.cancelOngoingAnimation(workspace) + Animations.cancelOngoingAnimation(hotseat) + + if (workspace.scaleX != MAX_SIZE) { + workspace.scaleX + } else { + MIN_SIZE + } + } else { + MIN_SIZE + } + // Scale the Workspace and Hotseat around the same pivot. workspace.setPivotToScaleWithSelf(hotseat) animation.addFloat( workspace, WORKSPACE_SCALE_PROPERTY_FACTORY[SCALE_INDEX_WORKSPACE_STATE], - MIN_SIZE, + fromSize, MAX_SIZE, SCALE_INTERPOLATOR, ) animation.addFloat( hotseat, HOTSEAT_SCALE_PROPERTY_FACTORY[SCALE_INDEX_WORKSPACE_STATE], - MIN_SIZE, + fromSize, MAX_SIZE, SCALE_INTERPOLATOR, ) @@ -116,13 +133,13 @@ class ScalingWorkspaceRevealAnim( animation.setViewAlpha( workspace, MAX_ALPHA, - Interpolators.clampToProgress(LINEAR, 0f, fadeClamp) + Interpolators.clampToProgress(LINEAR, 0f, fadeClamp), ) hotseat.alpha = MIN_ALPHA animation.setViewAlpha( hotseat, MAX_ALPHA, - Interpolators.clampToProgress(LINEAR, 0f, fadeClamp) + Interpolators.clampToProgress(LINEAR, 0f, fadeClamp), ) val transitionConfig = StateAnimationConfig() @@ -137,7 +154,7 @@ class ScalingWorkspaceRevealAnim( launcher.workspace.stateTransitionAnimation.setScrim( animation, LauncherState.NORMAL, - transitionConfig + transitionConfig, ) // To avoid awkward jumps in icon position, we want the sibling animation to always be @@ -164,7 +181,7 @@ class ScalingWorkspaceRevealAnim( 1 / workspace.scaleX, 1 / workspace.scaleY, transformed.centerX(), - transformed.centerY() + transformed.centerY(), ) } ) @@ -183,6 +200,12 @@ class ScalingWorkspaceRevealAnim( Runnable { workspace.setLayerType(View.LAYER_TYPE_NONE, null) hotseat.setLayerType(View.LAYER_TYPE_NONE, null) + + if (Flags.coordinateWorkspaceScale()) { + // Reset the cached animations. + Animations.setOngoingAnimation(workspace, animation = null) + Animations.setOngoingAnimation(hotseat, animation = null) + } } ) ) @@ -193,6 +216,14 @@ class ScalingWorkspaceRevealAnim( } fun start() { - getAnimators().start() + val animators = getAnimators() + if (Flags.coordinateWorkspaceScale()) { + // Make sure to cache the current animation, so it can be properly interrupted. + // TODO(b/367591368): ideally these animations would be refactored to be controlled + // centrally so each instances doesn't need to care about this coordination. + Animations.setOngoingAnimation(launcher.workspace, animators) + Animations.setOngoingAnimation(launcher.hotseat, animators) + } + animators.start() } } From b140ccec4932e4f4f33bb3be59f2f8a903f212e4 Mon Sep 17 00:00:00 2001 From: Liran Binyamin Date: Fri, 27 Sep 2024 13:00:18 +0000 Subject: [PATCH 4/7] Increase frame limit for bubble bar screen test This test is flaky because the animation sometimes doesn't finish before the screenshot is taken. Increasing the frame limit should help to ensure that the animation has time to finish. ABTD 100x runs (passed): https://android-build.corp.google.com/abtd/run/L84400030006722716 Change-Id: I410fb74a947d805551ce1b2303f0dc4c8d616de9 Flag: com.android.wm.shell.enable_bubble_bar Fixes: 366544536 Test: ABTD above --- .../launcher3/taskbar/bubbles/BubbleBarViewScreenshotTest.kt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/quickstep/tests/multivalentScreenshotTests/src/com/android/launcher3/taskbar/bubbles/BubbleBarViewScreenshotTest.kt b/quickstep/tests/multivalentScreenshotTests/src/com/android/launcher3/taskbar/bubbles/BubbleBarViewScreenshotTest.kt index 82a76250c2..b5a418b04d 100644 --- a/quickstep/tests/multivalentScreenshotTests/src/com/android/launcher3/taskbar/bubbles/BubbleBarViewScreenshotTest.kt +++ b/quickstep/tests/multivalentScreenshotTests/src/com/android/launcher3/taskbar/bubbles/BubbleBarViewScreenshotTest.kt @@ -98,7 +98,7 @@ class BubbleBarViewScreenshotTest(emulationSpec: DeviceEmulationSpec) { // if we're still expanding, wait with taking a screenshot val shouldWait: (ComponentActivity, View) -> Boolean = { _, _ -> bubbleBarView.isExpanding } // increase the frame limit to allow the animation to end before taking the screenshot - screenshotRule.frameLimit = 50 + screenshotRule.frameLimit = 500 screenshotRule.screenshotTest( "bubbleBarView_expanded_threeBubbles", checkView = shouldWait, From 5c34cf2741251ca1cd2b1ef0a630cf255f3e51c4 Mon Sep 17 00:00:00 2001 From: Liran Binyamin Date: Fri, 27 Sep 2024 10:33:28 -0400 Subject: [PATCH 5/7] Update flyout content during animation This change translates the content of the flyout according to the progress of the animation. Adding an outline provider allows clipping the content to the bounds of the animating background. Also animate the color of the background. Demo: on left - http://recall/-/bJtug1HhvXkkeA4MQvIaiP/cH2EK0FiD92dykhLkLeyh1 on right - http://recall/-/bJtug1HhvXkkeA4MQvIaiP/btpcter79rAlcavd4xxHu7 Flag: com.android.wm.shell.enable_bubble_bar Bug: 277815200 Test: atest BubbleBarFlyoutViewScreenshotTest Test: atest BubbleBarFlyoutControllerTest Change-Id: Id142af2041410c0570759a360146d5e084411cc1 --- .../flyout/BubbleBarFlyoutPositioner.kt | 3 + .../bubbles/flyout/BubbleBarFlyoutView.kt | 114 ++++++++++++++++-- .../BubbleBarFlyoutViewScreenshotTest.kt | 96 ++++++++++++++- .../flyout/BubbleBarFlyoutControllerTest.kt | 2 + 4 files changed, 199 insertions(+), 16 deletions(-) diff --git a/quickstep/src/com/android/launcher3/taskbar/bubbles/flyout/BubbleBarFlyoutPositioner.kt b/quickstep/src/com/android/launcher3/taskbar/bubbles/flyout/BubbleBarFlyoutPositioner.kt index 2b77dec462..b8c1c7f1d7 100644 --- a/quickstep/src/com/android/launcher3/taskbar/bubbles/flyout/BubbleBarFlyoutPositioner.kt +++ b/quickstep/src/com/android/launcher3/taskbar/bubbles/flyout/BubbleBarFlyoutPositioner.kt @@ -36,4 +36,7 @@ interface BubbleBarFlyoutPositioner { /** The size of the flyout when collapsed. */ val collapsedSize: Float + + /** The color of the flyout when collapsed. */ + val collapsedColor: Int } diff --git a/quickstep/src/com/android/launcher3/taskbar/bubbles/flyout/BubbleBarFlyoutView.kt b/quickstep/src/com/android/launcher3/taskbar/bubbles/flyout/BubbleBarFlyoutView.kt index 8884b646b7..6723f57dd5 100644 --- a/quickstep/src/com/android/launcher3/taskbar/bubbles/flyout/BubbleBarFlyoutView.kt +++ b/quickstep/src/com/android/launcher3/taskbar/bubbles/flyout/BubbleBarFlyoutView.kt @@ -20,13 +20,18 @@ import android.content.Context import android.content.res.Configuration import android.graphics.Canvas import android.graphics.Color +import android.graphics.Outline import android.graphics.Paint import android.graphics.Path import android.graphics.PointF +import android.graphics.RectF import android.view.LayoutInflater +import android.view.View +import android.view.ViewOutlineProvider import android.widget.ImageView import android.widget.TextView import androidx.constraintlayout.widget.ConstraintLayout +import androidx.core.animation.ArgbEvaluator import com.android.launcher3.R import com.android.launcher3.popup.RoundedArrowDrawable @@ -37,6 +42,8 @@ class BubbleBarFlyoutView(context: Context, private val positioner: BubbleBarFly private companion object { // the minimum progress of the expansion animation before the triangle is made visible. const val MIN_EXPANSION_PROGRESS_FOR_TRIANGLE = 0.1f + // the minimum progress of the expansion animation before the content starts fading in. + const val MIN_EXPANSION_PROGRESS_FOR_CONTENT_ALPHA = 0.75f } private val sender: TextView by @@ -85,8 +92,11 @@ class BubbleBarFlyoutView(context: Context, private val positioner: BubbleBarFly context.resources.getDimensionPixelSize(R.dimen.bubblebar_flyout_max_width) } + /** The bounds of the background rect. */ + private val backgroundRect = RectF() private val cornerRadius: Float private val triangle: Path = Path() + private val triangleOutline = Outline() private var backgroundColor = Color.BLACK /** Represents the progress of the expansion animation. 0 when collapsed. 1 when expanded. */ private var expansionProgress = 0f @@ -96,6 +106,20 @@ class BubbleBarFlyoutView(context: Context, private val positioner: BubbleBarFly private var collapsedSize = 0f /** The corner radius of the flyout when it's collapsed. */ private var collapsedCornerRadius = 0f + /** The color of the flyout when collapsed. */ + private var collapsedColor = 0 + + /** The corner radius of the background according to the progress of the animation. */ + private val currentCornerRadius + get() = collapsedCornerRadius + (cornerRadius - collapsedCornerRadius) * expansionProgress + + /** Translation X of the background. */ + private val backgroundRectTx + get() = translationToCollapsedPosition.x * (1 - expansionProgress) + + /** Translation Y of the background. */ + private val backgroundRectTy + get() = translationToCollapsedPosition.y * (1 - expansionProgress) /** * The paint used to draw the background, whose color changes as the flyout transitions to the @@ -111,7 +135,7 @@ class BubbleBarFlyoutView(context: Context, private val positioner: BubbleBarFly ta.recycle() setWillNotDraw(false) - clipChildren = false + clipChildren = true clipToPadding = false val padding = context.resources.getDimensionPixelSize(R.dimen.bubblebar_flyout_padding) @@ -126,12 +150,24 @@ class BubbleBarFlyoutView(context: Context, private val positioner: BubbleBarFly triangleRadius.toFloat(), triangle, ) + triangleOutline.setPath(triangle) + + outlineProvider = + object : ViewOutlineProvider() { + override fun getOutline(view: View, outline: Outline) { + this@BubbleBarFlyoutView.getOutline(outline) + } + } + clipToOutline = true applyConfigurationColors(resources.configuration) } /** Sets the data for the flyout and starts playing the expand animation. */ fun showFromCollapsed(flyoutMessage: BubbleBarFlyoutMessage, expandAnimation: () -> Unit) { + avatar.alpha = 0f + sender.alpha = 0f + message.alpha = 0f setData(flyoutMessage) val txToCollapsedPosition = if (positioner.isOnLeft) { @@ -145,6 +181,7 @@ class BubbleBarFlyoutView(context: Context, private val positioner: BubbleBarFly collapsedSize = positioner.collapsedSize collapsedCornerRadius = collapsedSize / 2 + collapsedColor = positioner.collapsedColor // post the request to start the expand animation to the looper so the view can measure // itself @@ -189,42 +226,64 @@ class BubbleBarFlyoutView(context: Context, private val positioner: BubbleBarFly /** Updates the flyout view with the progress of the animation. */ fun updateExpansionProgress(fraction: Float) { expansionProgress = fraction + + updateTranslationForAnimation(message) + updateTranslationForAnimation(sender) + updateTranslationForAnimation(avatar) + + // start fading in the content only after we're past the threshold + val alpha = + ((expansionProgress - MIN_EXPANSION_PROGRESS_FOR_CONTENT_ALPHA) / + (1f - MIN_EXPANSION_PROGRESS_FOR_CONTENT_ALPHA)) + .coerceIn(0f, 1f) + sender.alpha = alpha + message.alpha = alpha + avatar.alpha = alpha + invalidate() } override fun onDraw(canvas: Canvas) { // interpolate the width, height, corner radius and translation based on the progress of the - // animation + // animation. + // the background is drawn from the bottom left corner to the top right corner if we're + // positioned on the left, and from the bottom right corner to the top left if we're + // positioned on the right. + // the current width of the background rect according to the progress of the animation val currentWidth = collapsedSize + (width - collapsedSize) * expansionProgress val rectBottom = height - triangleHeight + triangleOverlap val currentHeight = collapsedSize + (rectBottom - collapsedSize) * expansionProgress - val currentCornerRadius = - collapsedCornerRadius + (cornerRadius - collapsedCornerRadius) * expansionProgress - val tx = translationToCollapsedPosition.x * (1 - expansionProgress) - val ty = translationToCollapsedPosition.y * (1 - expansionProgress) - canvas.save() - canvas.translate(tx, ty) - // draw the background starting from the bottom left if we're positioned left, or the bottom - // right if we're positioned right. - canvas.drawRoundRect( + backgroundRect.set( if (positioner.isOnLeft) 0f else width.toFloat() - currentWidth, height.toFloat() - triangleHeight + triangleOverlap - currentHeight, if (positioner.isOnLeft) currentWidth else width.toFloat(), height.toFloat() - triangleHeight + triangleOverlap, + ) + + backgroundPaint.color = + ArgbEvaluator.getInstance().evaluate(expansionProgress, collapsedColor, backgroundColor) + + canvas.save() + canvas.translate(backgroundRectTx, backgroundRectTy) + // draw the background starting from the bottom left if we're positioned left, or the bottom + // right if we're positioned right. + canvas.drawRoundRect( + backgroundRect, currentCornerRadius, currentCornerRadius, backgroundPaint, ) if (expansionProgress >= MIN_EXPANSION_PROGRESS_FOR_TRIANGLE) { - drawTriangle(canvas, currentCornerRadius) + drawTriangle(canvas) } canvas.restore() + invalidateOutline() super.onDraw(canvas) } - private fun drawTriangle(canvas: Canvas, currentCornerRadius: Float) { + private fun drawTriangle(canvas: Canvas) { canvas.save() val triangleX = if (positioner.isOnLeft) { @@ -237,9 +296,38 @@ class BubbleBarFlyoutView(context: Context, private val positioner: BubbleBarFly val triangleY = height - triangleHeight - 0.5f * triangleHeight * (1 - expansionProgress) canvas.translate(triangleX, triangleY) canvas.drawPath(triangle, backgroundPaint) + triangleOutline.setPath(triangle) + triangleOutline.offset(triangleX.toInt(), triangleY.toInt()) canvas.restore() } + private fun getOutline(outline: Outline) { + val path = Path() + path.addRoundRect( + backgroundRect, + currentCornerRadius, + currentCornerRadius, + Path.Direction.CW, + ) + if (expansionProgress >= MIN_EXPANSION_PROGRESS_FOR_TRIANGLE) { + path.addPath(triangleOutline.mPath) + } + outline.setPath(path) + outline.offset(backgroundRectTx.toInt(), backgroundRectTy.toInt()) + } + + private fun updateTranslationForAnimation(view: View) { + val tx = + if (positioner.isOnLeft) { + translationToCollapsedPosition.x - view.left + } else { + width - view.left - translationToCollapsedPosition.x + } + val ty = height - view.top + translationToCollapsedPosition.y + view.translationX = tx * (1f - expansionProgress) + view.translationY = ty * (1f - expansionProgress) + } + private fun applyConfigurationColors(configuration: Configuration) { val nightModeFlags = configuration.uiMode and Configuration.UI_MODE_NIGHT_MASK val isNightModeOn = nightModeFlags == Configuration.UI_MODE_NIGHT_YES diff --git a/quickstep/tests/multivalentScreenshotTests/src/com/android/launcher3/taskbar/bubbles/flyout/BubbleBarFlyoutViewScreenshotTest.kt b/quickstep/tests/multivalentScreenshotTests/src/com/android/launcher3/taskbar/bubbles/flyout/BubbleBarFlyoutViewScreenshotTest.kt index 467a9cb968..50e2dcf7b4 100644 --- a/quickstep/tests/multivalentScreenshotTests/src/com/android/launcher3/taskbar/bubbles/flyout/BubbleBarFlyoutViewScreenshotTest.kt +++ b/quickstep/tests/multivalentScreenshotTests/src/com/android/launcher3/taskbar/bubbles/flyout/BubbleBarFlyoutViewScreenshotTest.kt @@ -170,10 +170,100 @@ class BubbleBarFlyoutViewScreenshotTest(emulationSpec: DeviceEmulationSpec) { } } - private class FakeBubbleBarFlyoutPositioner(override val isOnLeft: Boolean) : - BubbleBarFlyoutPositioner { + @Test + fun bubbleBarFlyoutView_collapsed_onLeft() { + screenshotRule.screenshotTest("bubbleBarFlyoutView_collapsed_onLeft") { activity -> + activity.actionBar?.hide() + val flyout = + BubbleBarFlyoutView(context, FakeBubbleBarFlyoutPositioner(isOnLeft = true)) + flyout.showFromCollapsed( + BubbleBarFlyoutMessage( + senderAvatar = ColorDrawable(Color.RED), + senderName = "sender", + message = "collapsed on left", + isGroupChat = true, + ) + ) {} + flyout.updateExpansionProgress(0f) + flyout + } + } + + @Test + fun bubbleBarFlyoutView_collapsed_onRight() { + screenshotRule.screenshotTest("bubbleBarFlyoutView_collapsed_onRight") { activity -> + activity.actionBar?.hide() + val flyout = + BubbleBarFlyoutView(context, FakeBubbleBarFlyoutPositioner(isOnLeft = false)) + flyout.showFromCollapsed( + BubbleBarFlyoutMessage( + senderAvatar = ColorDrawable(Color.RED), + senderName = "sender", + message = "collapsed on right", + isGroupChat = true, + ) + ) {} + flyout.updateExpansionProgress(0f) + flyout + } + } + + @Test + fun bubbleBarFlyoutView_90p_onLeft() { + screenshotRule.screenshotTest("bubbleBarFlyoutView_90p_onLeft") { activity -> + activity.actionBar?.hide() + val flyout = + BubbleBarFlyoutView( + context, + FakeBubbleBarFlyoutPositioner( + isOnLeft = true, + distanceToCollapsedPosition = PointF(100f, 100f), + ), + ) + flyout.showFromCollapsed( + BubbleBarFlyoutMessage( + senderAvatar = ColorDrawable(Color.RED), + senderName = "sender", + message = "collapsed 90% on left", + isGroupChat = true, + ) + ) {} + flyout.updateExpansionProgress(0.9f) + flyout + } + } + + @Test + fun bubbleBarFlyoutView_80p_onRight() { + screenshotRule.screenshotTest("bubbleBarFlyoutView_80p_onRight") { activity -> + activity.actionBar?.hide() + val flyout = + BubbleBarFlyoutView( + context, + FakeBubbleBarFlyoutPositioner( + isOnLeft = false, + distanceToCollapsedPosition = PointF(200f, 100f), + ), + ) + flyout.showFromCollapsed( + BubbleBarFlyoutMessage( + senderAvatar = ColorDrawable(Color.RED), + senderName = "sender", + message = "collapsed 80% on right", + isGroupChat = true, + ) + ) {} + flyout.updateExpansionProgress(0.8f) + flyout + } + } + + private class FakeBubbleBarFlyoutPositioner( + override val isOnLeft: Boolean, + override val distanceToCollapsedPosition: PointF = PointF(0f, 0f), + ) : BubbleBarFlyoutPositioner { override val targetTy = 0f - override val distanceToCollapsedPosition = PointF(0f, 0f) override val collapsedSize = 30f + override val collapsedColor = Color.BLUE } } diff --git a/quickstep/tests/multivalentTests/src/com/android/launcher3/taskbar/bubbles/flyout/BubbleBarFlyoutControllerTest.kt b/quickstep/tests/multivalentTests/src/com/android/launcher3/taskbar/bubbles/flyout/BubbleBarFlyoutControllerTest.kt index fb12ac9a59..0f02444b30 100644 --- a/quickstep/tests/multivalentTests/src/com/android/launcher3/taskbar/bubbles/flyout/BubbleBarFlyoutControllerTest.kt +++ b/quickstep/tests/multivalentTests/src/com/android/launcher3/taskbar/bubbles/flyout/BubbleBarFlyoutControllerTest.kt @@ -17,6 +17,7 @@ package com.android.launcher3.taskbar.bubbles.flyout import android.content.Context +import android.graphics.Color import android.graphics.PointF import android.view.Gravity import android.widget.FrameLayout @@ -53,6 +54,7 @@ class BubbleBarFlyoutControllerTest { override val targetTy = 50f override val distanceToCollapsedPosition = PointF(100f, 200f) override val collapsedSize = 30f + override val collapsedColor = Color.BLUE } flyoutController = BubbleBarFlyoutController(flyoutContainer, positioner) } From 396441545fdd0b241fe9af23d279ef2326707591 Mon Sep 17 00:00:00 2001 From: Alex Chau Date: Fri, 27 Sep 2024 19:26:05 +0100 Subject: [PATCH 6/7] Animated fullscreen and desktop carousel attaching together desktopCarouselDetachProgress: - Controls whether desktop and fullscreen carousel is attached (RecentsView..DESKTOP_CAROUSEL_DETACH_PROGRESS) - When fully detached (progress==1), hide the carousel (RecentsView.applyAttachAlpha) - As the detach progress increase, we animate the other carousel away by using `getMaxHorizontalOffsetSize`, with additional maxOverscroll to make sure the other carousel won't be seen even if user overscroll RecentsView (RecentsView.updatePageOffsets) min/max scroll changes - When desktop and fullscreen carousel detaches, disallow scrolling to the detached carousel. This avoids quickswitching or scroll to the other carousel (RecentsView.getFirstViewIndex and RecentsView.getLastViewIndex) State machine changes: - On Overview states, desktop and fullscreen carousel is attached. Otherwise, they're detached, including in quick switch and home. (BaseState, RecentsState, OverviewState, BackgroundAppState) - StateController set/animate desktopCarouselDetachProgress between the above states (BaseRecentsViewStateController, FallbackRecentsStateController) - On swipe up gesture release and going to Overview, animate attaching back the 2 carousels (RecentsView.onPrepareGestureEndAnimation) Bug: 353948100 Test: quick switch; swipe from home/app; scroll in Overview; with normal/3p launcher Flag: com.android.launcher3.enable_large_desktop_windowing_tile Change-Id: Ic4217efb07db079825a3210afd306d9ef627c873 --- .../BaseRecentsViewStateController.java | 12 ++ .../states/BackgroundAppState.java | 5 + .../uioverrides/states/OverviewState.java | 5 + .../FallbackRecentsStateController.java | 7 ++ .../quickstep/fallback/RecentsState.java | 10 +- .../quickstep/util/RecentsViewUtils.kt | 39 +++--- .../android/quickstep/views/RecentsView.java | 112 ++++++++++++------ .../launcher3/statemanager/BaseState.java | 7 ++ 8 files changed, 142 insertions(+), 55 deletions(-) diff --git a/quickstep/src/com/android/launcher3/uioverrides/BaseRecentsViewStateController.java b/quickstep/src/com/android/launcher3/uioverrides/BaseRecentsViewStateController.java index bcad478eae..721c831a42 100644 --- a/quickstep/src/com/android/launcher3/uioverrides/BaseRecentsViewStateController.java +++ b/quickstep/src/com/android/launcher3/uioverrides/BaseRecentsViewStateController.java @@ -21,6 +21,7 @@ import static com.android.app.animation.Interpolators.AGGRESSIVE_EASE_IN_OUT; import static com.android.app.animation.Interpolators.FINAL_FRAME; import static com.android.app.animation.Interpolators.INSTANT; import static com.android.app.animation.Interpolators.LINEAR; +import static com.android.launcher3.Flags.enableLargeDesktopWindowingTile; import static com.android.launcher3.LauncherState.QUICK_SWITCH_FROM_HOME; import static com.android.launcher3.logging.StatsLogManager.LauncherEvent.LAUNCHER_SPLIT_SELECTION_EXIT_HOME; import static com.android.launcher3.states.StateAnimationConfig.ANIM_OVERVIEW_FADE; @@ -31,6 +32,7 @@ import static com.android.launcher3.states.StateAnimationConfig.ANIM_OVERVIEW_TR import static com.android.launcher3.states.StateAnimationConfig.ANIM_OVERVIEW_TRANSLATE_Y; import static com.android.launcher3.states.StateAnimationConfig.SKIP_OVERVIEW; import static com.android.quickstep.views.RecentsView.ADJACENT_PAGE_HORIZONTAL_OFFSET; +import static com.android.quickstep.views.RecentsView.DESKTOP_CAROUSEL_DETACH_PROGRESS; import static com.android.quickstep.views.RecentsView.RECENTS_GRID_PROGRESS; import static com.android.quickstep.views.RecentsView.RECENTS_SCALE_PROPERTY; import static com.android.quickstep.views.RecentsView.TASK_SECONDARY_TRANSLATION; @@ -76,6 +78,10 @@ public abstract class BaseRecentsViewStateController RECENTS_GRID_PROGRESS.set(mRecentsView, state.displayOverviewTasksAsGrid(mLauncher.getDeviceProfile()) ? 1f : 0f); TASK_THUMBNAIL_SPLASH_ALPHA.set(mRecentsView, state.showTaskThumbnailSplash() ? 1f : 0f); + if (enableLargeDesktopWindowingTile()) { + DESKTOP_CAROUSEL_DETACH_PROGRESS.set(mRecentsView, + state.detachDesktopCarousel() ? 1f : 0f); + } } @Override @@ -142,6 +148,12 @@ public abstract class BaseRecentsViewStateController setter.setFloat(mRecentsView, RECENTS_GRID_PROGRESS, toState.displayOverviewTasksAsGrid(mLauncher.getDeviceProfile()) ? 1f : 0f, getOverviewInterpolator(fromState, toState)); + + if (enableLargeDesktopWindowingTile()) { + setter.setFloat(mRecentsView, DESKTOP_CAROUSEL_DETACH_PROGRESS, + toState.detachDesktopCarousel() ? 1f : 0f, + getOverviewInterpolator(fromState, toState)); + } } private Interpolator getOverviewInterpolator(LauncherState fromState, LauncherState toState) { diff --git a/quickstep/src/com/android/launcher3/uioverrides/states/BackgroundAppState.java b/quickstep/src/com/android/launcher3/uioverrides/states/BackgroundAppState.java index 18d717f096..e87ac2fec6 100644 --- a/quickstep/src/com/android/launcher3/uioverrides/states/BackgroundAppState.java +++ b/quickstep/src/com/android/launcher3/uioverrides/states/BackgroundAppState.java @@ -89,6 +89,11 @@ public class BackgroundAppState extends OverviewState { return true; } + @Override + public boolean detachDesktopCarousel() { + return true; + } + @Override protected float getDepthUnchecked(Context context) { if (Launcher.getLauncher(context).areDesktopTasksVisible()) { diff --git a/quickstep/src/com/android/launcher3/uioverrides/states/OverviewState.java b/quickstep/src/com/android/launcher3/uioverrides/states/OverviewState.java index b165cddfb2..c48ba4f11b 100644 --- a/quickstep/src/com/android/launcher3/uioverrides/states/OverviewState.java +++ b/quickstep/src/com/android/launcher3/uioverrides/states/OverviewState.java @@ -165,6 +165,11 @@ public class OverviewState extends LauncherState { return deviceProfile.isTablet; } + @Override + public boolean detachDesktopCarousel() { + return false; + } + @Override public boolean disallowTaskbarGlobalDrag() { // Disable global drag in overview diff --git a/quickstep/src/com/android/quickstep/fallback/FallbackRecentsStateController.java b/quickstep/src/com/android/quickstep/fallback/FallbackRecentsStateController.java index 83794fbd6c..daac9fb013 100644 --- a/quickstep/src/com/android/quickstep/fallback/FallbackRecentsStateController.java +++ b/quickstep/src/com/android/quickstep/fallback/FallbackRecentsStateController.java @@ -18,6 +18,7 @@ package com.android.quickstep.fallback; import static com.android.app.animation.Interpolators.FINAL_FRAME; import static com.android.app.animation.Interpolators.INSTANT; import static com.android.app.animation.Interpolators.LINEAR; +import static com.android.launcher3.Flags.enableLargeDesktopWindowingTile; import static com.android.launcher3.states.StateAnimationConfig.ANIM_OVERVIEW_MODAL; import static com.android.launcher3.states.StateAnimationConfig.ANIM_OVERVIEW_SCALE; import static com.android.launcher3.states.StateAnimationConfig.ANIM_OVERVIEW_TRANSLATE_X; @@ -26,6 +27,7 @@ import static com.android.launcher3.states.StateAnimationConfig.ANIM_SCRIM_FADE; import static com.android.launcher3.states.StateAnimationConfig.SKIP_OVERVIEW; import static com.android.quickstep.fallback.RecentsState.OVERVIEW_SPLIT_SELECT; import static com.android.quickstep.views.RecentsView.ADJACENT_PAGE_HORIZONTAL_OFFSET; +import static com.android.quickstep.views.RecentsView.DESKTOP_CAROUSEL_DETACH_PROGRESS; import static com.android.quickstep.views.RecentsView.FULLSCREEN_PROGRESS; import static com.android.quickstep.views.RecentsView.RECENTS_GRID_PROGRESS; import static com.android.quickstep.views.RecentsView.RECENTS_SCALE_PROPERTY; @@ -116,6 +118,11 @@ public class FallbackRecentsStateController implements StateHandler { private static final int FLAG_LIVE_TILE = BaseState.getFlag(6); private static final int FLAG_RECENTS_VIEW_VISIBLE = BaseState.getFlag(7); private static final int FLAG_TASK_THUMBNAIL_SPLASH = BaseState.getFlag(8); + private static final int FLAG_DETACH_DESKTOP_CAROUSEL = BaseState.getFlag(9); public static final RecentsState DEFAULT = new RecentsState(0, FLAG_DISABLE_RESTORE | FLAG_CLEAR_ALL_BUTTON | FLAG_OVERVIEW_ACTIONS | FLAG_SHOW_AS_GRID @@ -51,8 +52,8 @@ public class RecentsState implements BaseState { | FLAG_SHOW_AS_GRID | FLAG_SCRIM | FLAG_LIVE_TILE | FLAG_RECENTS_VIEW_VISIBLE); public static final RecentsState BACKGROUND_APP = new BackgroundAppState(2, FLAG_DISABLE_RESTORE | FLAG_NON_INTERACTIVE | FLAG_FULL_SCREEN - | FLAG_RECENTS_VIEW_VISIBLE - | FLAG_TASK_THUMBNAIL_SPLASH); + | FLAG_RECENTS_VIEW_VISIBLE | FLAG_TASK_THUMBNAIL_SPLASH + | FLAG_DETACH_DESKTOP_CAROUSEL); public static final RecentsState HOME = new RecentsState(3, 0); public static final RecentsState BG_LAUNCHER = new LauncherState(4, 0); public static final RecentsState OVERVIEW_SPLIT_SELECT = new RecentsState(5, @@ -149,6 +150,11 @@ public class RecentsState implements BaseState { return hasFlag(FLAG_TASK_THUMBNAIL_SPLASH); } + @Override + public boolean detachDesktopCarousel() { + return hasFlag(FLAG_DETACH_DESKTOP_CAROUSEL); + } + /** * True if the state has overview panel visible. */ diff --git a/quickstep/src/com/android/quickstep/util/RecentsViewUtils.kt b/quickstep/src/com/android/quickstep/util/RecentsViewUtils.kt index e70372fb79..aa0fd88573 100644 --- a/quickstep/src/com/android/quickstep/util/RecentsViewUtils.kt +++ b/quickstep/src/com/android/quickstep/util/RecentsViewUtils.kt @@ -83,22 +83,22 @@ class RecentsViewUtils { /** Returns the first [TaskView], with some tasks possibly hidden in the carousel. */ fun getFirstTaskViewInCarousel( - nonRunningTaskCategoryHidden: Boolean, + nonRunningTaskCarouselHidden: Boolean, taskViews: Iterable, runningTaskView: TaskView?, ): TaskView? = taskViews.firstOrNull { - it.isVisibleInCarousel(runningTaskView, nonRunningTaskCategoryHidden) + it.isVisibleInCarousel(runningTaskView, nonRunningTaskCarouselHidden) } /** Returns the last [TaskView], with some tasks possibly hidden in the carousel. */ fun getLastTaskViewInCarousel( - nonRunningTaskCategoryHidden: Boolean, + nonRunningTaskCarouselHidden: Boolean, taskViews: Iterable, runningTaskView: TaskView?, ): TaskView? = taskViews.lastOrNull { - it.isVisibleInCarousel(runningTaskView, nonRunningTaskCategoryHidden) + it.isVisibleInCarousel(runningTaskView, nonRunningTaskCarouselHidden) } /** Returns the current list of [TaskView] children. */ @@ -109,28 +109,33 @@ class RecentsViewUtils { fun applyAttachAlpha( taskViews: Iterable, runningTaskView: TaskView?, - runningTaskTileHidden: Boolean, - nonRunningTaskCategoryHidden: Boolean, + runningTaskAttachAlpha: Float, + nonRunningTaskCarouselHidden: Boolean, ) { taskViews.forEach { taskView -> - val isVisible = - if (taskView == runningTaskView) !runningTaskTileHidden - else taskView.isVisibleInCarousel(runningTaskView, nonRunningTaskCategoryHidden) - taskView.attachAlpha = if (isVisible) 1f else 0f + taskView.attachAlpha = + if (taskView == runningTaskView) { + runningTaskAttachAlpha + } else { + if (taskView.isVisibleInCarousel(runningTaskView, nonRunningTaskCarouselHidden)) + 1f + else 0f + } } } - private fun TaskView.isVisibleInCarousel( + fun TaskView.isVisibleInCarousel( runningTaskView: TaskView?, - nonRunningTaskCategoryHidden: Boolean, + nonRunningTaskCarouselHidden: Boolean, ): Boolean = - if (!nonRunningTaskCategoryHidden) true - else if (runningTaskView == null) true else getCategory() == runningTaskView.getCategory() + if (!nonRunningTaskCarouselHidden) true + else getCarouselType() == runningTaskView.getCarouselType() - private fun TaskView.getCategory(): TaskViewCategory = - if (this is DesktopTaskView) TaskViewCategory.DESKTOP else TaskViewCategory.FULL_SCREEN + /** Returns the carousel type of the TaskView, and default to fullscreen if it's null. */ + private fun TaskView?.getCarouselType(): TaskViewCarousel = + if (this is DesktopTaskView) TaskViewCarousel.DESKTOP else TaskViewCarousel.FULL_SCREEN - private enum class TaskViewCategory { + private enum class TaskViewCarousel { FULL_SCREEN, DESKTOP, } diff --git a/quickstep/src/com/android/quickstep/views/RecentsView.java b/quickstep/src/com/android/quickstep/views/RecentsView.java index 8b2c95de5c..89844ad11b 100644 --- a/quickstep/src/com/android/quickstep/views/RecentsView.java +++ b/quickstep/src/com/android/quickstep/views/RecentsView.java @@ -235,6 +235,8 @@ import com.android.wm.shell.common.pip.IPipAnimationListener; import com.android.wm.shell.shared.desktopmode.DesktopModeStatus; import com.android.wm.shell.shared.desktopmode.DesktopModeTransitionSource; +import kotlin.Unit; + import java.util.ArrayList; import java.util.Arrays; import java.util.Collections; @@ -248,8 +250,6 @@ import java.util.Set; import java.util.function.Consumer; import java.util.stream.Collectors; -import kotlin.Unit; - /** * A list of recent tasks. * @@ -324,20 +324,13 @@ public abstract class RecentsView< new FloatProperty("runningTaskAttachAlpha") { @Override public void setValue(RecentsView recentsView, float v) { - TaskView runningTask = recentsView.getRunningTaskView(); - if (runningTask == null) { - return; - } - runningTask.setAttachAlpha(v); + recentsView.mRunningTaskAttachAlpha = v; + recentsView.applyAttachAlpha(); } @Override public Float get(RecentsView recentsView) { - TaskView runningTask = recentsView.getRunningTaskView(); - if (runningTask == null) { - return null; - } - return runningTask.getAttachAlpha(); + return recentsView.mRunningTaskAttachAlpha; } }; @@ -463,6 +456,21 @@ public abstract class RecentsView< } }; + public static final FloatProperty DESKTOP_CAROUSEL_DETACH_PROGRESS = + new FloatProperty<>("desktopCarouselDetachProgress") { + @Override + public void setValue(RecentsView view, float offset) { + view.mDesktopCarouselDetachProgress = offset; + view.applyAttachAlpha(); + view.updatePageOffsets(); + } + + @Override + public Float get(RecentsView view) { + return view.mDesktopCarouselDetachProgress; + } + }; + /** * Alpha of the task thumbnail splash, where being in BackgroundAppState has a value of 1, and * being in any other state has a value of 0. @@ -574,6 +582,7 @@ public abstract class RecentsView< private int mClampedScrollOffsetBound; private float mAdjacentPageHorizontalOffset = 0; + private float mDesktopCarouselDetachProgress = 0; protected float mTaskViewsSecondaryTranslation = 0; protected float mTaskViewsPrimarySplitTranslation = 0; protected float mTaskViewsSecondarySplitTranslation = 0; @@ -680,13 +689,13 @@ public abstract class RecentsView< protected int mRunningTaskViewId = -1; private int mTaskViewIdCount; protected boolean mRunningTaskTileHidden; - private boolean mNonRunningTaskCategoryHidden; @Nullable private Task[] mTmpRunningTasks; protected int mFocusedTaskViewId = INVALID_TASK_ID; private boolean mTaskIconScaledDown = false; private boolean mRunningTaskShowScreenshot = false; + private float mRunningTaskAttachAlpha; private boolean mOverviewStateEnabled; private boolean mHandleTaskStackChanges; @@ -2741,9 +2750,6 @@ public abstract class RecentsView< setEnableFreeScroll(false); setEnableDrawingLiveTile(false); setRunningTaskHidden(true); - if (enableLargeDesktopWindowingTile()) { - setNonRunningTaskCategoryHidden(true); - } setTaskIconScaledDown(true); } @@ -2867,6 +2873,14 @@ public abstract class RecentsView< animatorSet.play( ObjectAnimator.ofFloat(this, TASK_THUMBNAIL_SPLASH_ALPHA, splashAlpha)); } + if (enableLargeDesktopWindowingTile()) { + if (animatorSet != null) { + animatorSet.play( + ObjectAnimator.ofFloat(this, DESKTOP_CAROUSEL_DETACH_PROGRESS, 0f)); + } else { + DESKTOP_CAROUSEL_DETACH_PROGRESS.set(this, 0f); + } + } } /** @@ -2882,9 +2896,6 @@ public abstract class RecentsView< setEnableDrawingLiveTile(mCurrentGestureEndTarget == GestureState.GestureEndTarget.RECENTS); Log.d(TAG, "onGestureAnimationEnd - mEnableDrawingLiveTile: " + mEnableDrawingLiveTile); setRunningTaskHidden(false); - if (enableLargeDesktopWindowingTile()) { - setNonRunningTaskCategoryHidden(false); - } animateUpTaskIconScale(); animateActionsViewIn(); @@ -3036,6 +3047,9 @@ public abstract class RecentsView< */ public void setRunningTaskHidden(boolean isHidden) { mRunningTaskTileHidden = isHidden; + // mRunningTaskAttachAlpha can be changed by RUNNING_TASK_ATTACH_ALPHA animation without + // changing mRunningTaskTileHidden. + mRunningTaskAttachAlpha = isHidden ? 0f : 1f; TaskView runningTask = getRunningTaskView(); if (runningTask == null) { return; @@ -3047,18 +3061,11 @@ public abstract class RecentsView< } } - /** - * Hides the tasks that has a different category (Fullscreen/Desktop) from the running task. - */ - public void setNonRunningTaskCategoryHidden(boolean isHidden) { - mNonRunningTaskCategoryHidden = isHidden; - updateMinAndMaxScrollX(); - applyAttachAlpha(); - } - private void applyAttachAlpha() { - mUtils.applyAttachAlpha(getTaskViews(), getRunningTaskView(), mRunningTaskTileHidden, - mNonRunningTaskCategoryHidden); + // Only hide non running task carousel when it's fully off screen, otherwise it needs to + // be visible to move to on screen. + mUtils.applyAttachAlpha(getTaskViews(), getRunningTaskView(), mRunningTaskAttachAlpha, + /*nonRunningTaskCarouselHidden=*/mDesktopCarouselDetachProgress == 1f); } private void setRunningTaskViewShowScreenshot(boolean showScreenshot) { @@ -4679,6 +4686,10 @@ public abstract class RecentsView< ? (runningTask == null ? INVALID_PAGE : indexOfChild(runningTask)) : mOffsetMidpointIndexOverride; int modalMidpoint = getCurrentPage(); + TaskView carouselHiddenMidpointTask = runningTask != null ? runningTask + : mUtils.getFirstTaskViewInCarousel(/*nonRunningTaskCarouselHidden=*/true, + getTaskViews(), null); + int carouselHiddenMidpoint = indexOfChild(carouselHiddenMidpointTask); boolean shouldCalculateOffsetForAllTasks = showAsGrid && (enableGridOnlyOverview() || enableLargeDesktopWindowingTile()) && mTaskModalness > 0; @@ -4698,6 +4709,7 @@ public abstract class RecentsView< float modalLeftOffsetSize = 0; float modalRightOffsetSize = 0; float gridOffsetSize = 0; + float carouselHiddenOffsetSize = 0; if (showAsGrid) { // In grid, we only focus the task on the side. The reference index used for offset @@ -4715,7 +4727,10 @@ public abstract class RecentsView< : 0; } + int primarySize = getPagedOrientationHandler().getPrimaryValue(getWidth(), getHeight()); + float maxOverscroll = primarySize * OverScroll.OVERSCROLL_DAMP_FACTOR; for (int i = 0; i < count; i++) { + View child = getChildAt(i); float translation = i == midpoint ? midpointOffsetSize : i < midpoint @@ -4725,16 +4740,31 @@ public abstract class RecentsView< gridOffsetSize = getHorizontalOffsetSize(i, modalMidpoint, modalOffset); gridOffsetSize = Math.abs(gridOffsetSize) * (i <= modalMidpoint ? 1 : -1); } + if (enableLargeDesktopWindowingTile()) { + if (child instanceof TaskView + && !mUtils.isVisibleInCarousel((TaskView) child, + runningTask, /*nonRunningTaskCarouselHidden=*/true)) { + // Increment carouselHiddenOffsetSize by maxOverscroll so it won't be on screen + // even when user overscroll. + carouselHiddenOffsetSize = (Math.abs(getMaxHorizontalOffsetSize(i, + carouselHiddenMidpoint)) + maxOverscroll) + * mDesktopCarouselDetachProgress; + carouselHiddenOffsetSize = carouselHiddenOffsetSize * ( + i <= carouselHiddenMidpoint ? 1 : -1); + } else { + carouselHiddenOffsetSize = 0; + } + } float modalTranslation = i == modalMidpoint ? modalMidpointOffsetSize : showAsGrid ? gridOffsetSize : i < modalMidpoint ? modalLeftOffsetSize : modalRightOffsetSize; - View child = getChildAt(i); boolean skipTranslationOffset = enableDesktopTaskAlphaAnimation() && i == getRunningTaskIndex() && child instanceof DesktopTaskView; - float totalTranslationX = (skipTranslationOffset ? 0f : translation) + modalTranslation; + float totalTranslationX = (skipTranslationOffset ? 0f : translation) + modalTranslation + + carouselHiddenOffsetSize; FloatProperty translationPropertyX = child instanceof TaskView ? ((TaskView) child).getPrimaryTaskOffsetTranslationProperty() : getPagedOrientationHandler().getPrimaryViewTranslate(); @@ -4791,6 +4821,14 @@ public abstract class RecentsView< return 0; } + return getMaxHorizontalOffsetSize(childIndex, midpointIndex) * offsetProgress; + } + + /** + * Computes the distance to offset the given child such that it is completely offscreen when + * translating away from the given midpoint. + */ + private float getMaxHorizontalOffsetSize(int childIndex, int midpointIndex) { // First, get the position of the task relative to the midpoint. If there is no midpoint // then we just use the normal (centered) task position. RectF taskPosition = mTempRectF; @@ -4850,7 +4888,7 @@ public abstract class RecentsView< } distanceToOffscreen -= mLastComputedTaskEndPushOutDistance; } - return distanceToOffscreen * offsetProgress; + return distanceToOffscreen; } /** @@ -5812,7 +5850,7 @@ public abstract class RecentsView< private int getFirstViewIndex() { final TaskView firstView; if (mShowAsGridLastOnLayout) { - // For grid Overivew, it always start if a large tile (focused task or desktop task) if + // For grid Overview, it always start if a large tile (focused task or desktop task) if // they exist, otherwise it start with the first task. TaskView firstLargeTaskView = mUtils.getFirstLargeTaskView(getTaskViews()); if (firstLargeTaskView != null) { @@ -5821,7 +5859,8 @@ public abstract class RecentsView< firstView = getTaskViewAt(0); } } else { - firstView = mUtils.getFirstTaskViewInCarousel(mNonRunningTaskCategoryHidden, + firstView = mUtils.getFirstTaskViewInCarousel( + /*nonRunningTaskCarouselHidden=*/mDesktopCarouselDetachProgress > 0, getTaskViews(), getRunningTaskView()); } return indexOfChild(firstView); @@ -5842,7 +5881,8 @@ public abstract class RecentsView< lastView = mUtils.getLastLargeTaskView(getTaskViews()); } } else { - lastView = mUtils.getLastTaskViewInCarousel(mNonRunningTaskCategoryHidden, + lastView = mUtils.getLastTaskViewInCarousel( + /*nonRunningTaskCarouselHidden=*/mDesktopCarouselDetachProgress > 0, getTaskViews(), getRunningTaskView()); } return indexOfChild(lastView); diff --git a/src/com/android/launcher3/statemanager/BaseState.java b/src/com/android/launcher3/statemanager/BaseState.java index b81729a712..f6b610c9bf 100644 --- a/src/com/android/launcher3/statemanager/BaseState.java +++ b/src/com/android/launcher3/statemanager/BaseState.java @@ -71,6 +71,13 @@ public interface BaseState { return false; } + /** + * For this state, whether fullscreen and desktop quickswitch carousel are detached. + */ + default boolean detachDesktopCarousel() { + return true; + } + /** * For this state, whether member variables and other forms of data state should be preserved * or wiped when the state is reapplied. (See {@link StateManager#reapplyState()}) From 52afe8b7945e49390492d18bf33cc26bf52f101c Mon Sep 17 00:00:00 2001 From: Alex Chau Date: Mon, 30 Sep 2024 13:01:33 +0100 Subject: [PATCH 7/7] Pass correct scrollDiff to translateTaskWhenDismissed - This is a follow-up of refactoring CL ag/29580515, which passed wrong parameter to a function Bug: 353948182 Test: manual Flag: EXEMPT REFACTOR Change-Id: I544f4142b1007c034f8e7364e48c32e6500e03f8 --- quickstep/src/com/android/quickstep/views/RecentsView.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/quickstep/src/com/android/quickstep/views/RecentsView.java b/quickstep/src/com/android/quickstep/views/RecentsView.java index a94f047764..3ae9bc823b 100644 --- a/quickstep/src/com/android/quickstep/views/RecentsView.java +++ b/quickstep/src/com/android/quickstep/views/RecentsView.java @@ -3800,7 +3800,7 @@ public abstract class RecentsView< translateTaskWhenDismissed( child, Math.abs(i - dismissedIndex), - mIsRtl ? -scrollDiff : scrollDiff, + scrollDiff, anim, splitTimings); needsCurveUpdates = true;