From 1d016ed10ded3b55edb6c84e7cb181954b146fa1 Mon Sep 17 00:00:00 2001 From: Bill Yi Date: Thu, 13 Jun 2019 08:59:49 -0700 Subject: [PATCH 001/108] Import translations. DO NOT MERGE Auto-generated-cl: translation import Bug: 64712476 Change-Id: Id8c281d336d4108a120004a58b53153a888c24e1 --- quickstep/res/values-ar/strings.xml | 2 +- quickstep/res/values-as/strings.xml | 3 +++ quickstep/res/values-de/strings.xml | 2 +- quickstep/res/values-gl/strings.xml | 2 +- quickstep/res/values-or/strings.xml | 5 ++++- res/values-ar/strings.xml | 4 ++-- res/values-b+sr+Latn/strings.xml | 2 +- res/values-bn/strings.xml | 4 ++-- res/values-bs/strings.xml | 4 ++-- res/values-ca/strings.xml | 4 ++-- res/values-da/strings.xml | 8 ++++---- res/values-de/strings.xml | 8 ++++---- res/values-en-rAU/strings.xml | 2 +- res/values-en-rGB/strings.xml | 2 +- res/values-en-rIN/strings.xml | 2 +- res/values-es/strings.xml | 8 ++++---- res/values-et/strings.xml | 20 ++++++++++---------- res/values-eu/strings.xml | 10 +++++----- res/values-fa/strings.xml | 2 +- res/values-fr-rCA/strings.xml | 2 +- res/values-fr/strings.xml | 2 +- res/values-gl/strings.xml | 8 ++++---- res/values-hi/strings.xml | 14 +++++++------- res/values-in/strings.xml | 6 +++--- res/values-iw/strings.xml | 4 ++-- res/values-kk/strings.xml | 2 +- res/values-km/strings.xml | 4 ++-- res/values-kn/strings.xml | 2 +- res/values-ky/strings.xml | 4 ++-- res/values-ml/strings.xml | 2 +- res/values-mn/strings.xml | 2 +- res/values-mr/strings.xml | 2 +- res/values-my/strings.xml | 4 ++-- res/values-nl/strings.xml | 4 ++-- res/values-pl/strings.xml | 2 +- res/values-pt-rPT/strings.xml | 2 +- res/values-pt/strings.xml | 4 ++-- res/values-ro/strings.xml | 6 +++--- res/values-ru/strings.xml | 4 ++-- res/values-si/strings.xml | 4 ++-- res/values-sk/strings.xml | 2 +- res/values-sr/strings.xml | 2 +- res/values-sw/strings.xml | 2 +- res/values-ta/strings.xml | 24 ++++++++++++------------ res/values-te/strings.xml | 2 +- res/values-tl/strings.xml | 2 +- res/values-uk/strings.xml | 6 +++--- res/values-ur/strings.xml | 2 +- res/values-uz/strings.xml | 14 +++++++------- res/values-vi/strings.xml | 4 ++-- res/values-zh-rCN/strings.xml | 2 +- res/values-zh-rHK/strings.xml | 2 +- res/values-zh-rTW/strings.xml | 4 ++-- 53 files changed, 126 insertions(+), 120 deletions(-) diff --git a/quickstep/res/values-ar/strings.xml b/quickstep/res/values-ar/strings.xml index 73c7c5c033..b036bc1ebd 100644 --- a/quickstep/res/values-ar/strings.xml +++ b/quickstep/res/values-ar/strings.xml @@ -27,7 +27,7 @@ "إغلاق" "إعدادات استخدام التطبيق" "محو الكل" - "التطبيقات التي تمّ استخدامها مؤخرًا" + "التطبيقات المستخدمة مؤخرًا" "%1$s، %2$s" "أقل من دقيقة" "يتبقى اليوم %1$s." diff --git a/quickstep/res/values-as/strings.xml b/quickstep/res/values-as/strings.xml index a33973b218..c188493e59 100644 --- a/quickstep/res/values-as/strings.xml +++ b/quickstep/res/values-as/strings.xml @@ -31,4 +31,7 @@ "%1$s, %2$s" "< ১ মিনিট" "আজি %1$s বাকী আছ" + "এপৰ পৰামৰ্শসমূহ" + "সকলো এপ্" + "আপোনাৰ অনুমানিক এপ্" diff --git a/quickstep/res/values-de/strings.xml b/quickstep/res/values-de/strings.xml index 7f4e56d260..449cc8c11d 100644 --- a/quickstep/res/values-de/strings.xml +++ b/quickstep/res/values-de/strings.xml @@ -20,7 +20,7 @@ "Splitscreen" - "Fixieren" + "Anpinnen" "Freeform-Modus" "Übersicht" "Keine kürzlich verwendeten Elemente" diff --git a/quickstep/res/values-gl/strings.xml b/quickstep/res/values-gl/strings.xml index c6698bb480..356d10d5da 100644 --- a/quickstep/res/values-gl/strings.xml +++ b/quickstep/res/values-gl/strings.xml @@ -27,7 +27,7 @@ "Pecha a aplicación" "Configuración do uso de aplicacións" "Borrar todo" - "Aplicacións recentes" + "Apps recentes" "%1$s (%2$s)" "<1 min" "Tempo restante hoxe %1$s" diff --git a/quickstep/res/values-or/strings.xml b/quickstep/res/values-or/strings.xml index bd88671938..2ebec4e7c7 100644 --- a/quickstep/res/values-or/strings.xml +++ b/quickstep/res/values-or/strings.xml @@ -27,8 +27,11 @@ "ବନ୍ଦ କରନ୍ତୁ" "ଆପ୍‍ ବ୍ୟବହାର ସେଟିଂସ୍‍" "ସବୁ ଖାଲି କରନ୍ତୁ" - "ସାମ୍ପ୍ରତିକ ଆପ୍‌" + "ବର୍ତ୍ତମାନର ଆପ୍‌" "%1$s %2$s" "< 1 ମିନିଟ୍" "ଆଜି %1$s ବାକି ଅଛି" + "ଆପ୍ ପରାମର୍ଶଗୁଡ଼ିକ" + "ସମସ୍ତ ଆପ୍ସ" + "ଆପଣ ପୂର୍ବାନୁମାନ କରିଥିବା ଆପ୍ସ" diff --git a/res/values-ar/strings.xml b/res/values-ar/strings.xml index bf00e9541d..a80ecb0b14 100644 --- a/res/values-ar/strings.xml +++ b/res/values-ar/strings.xml @@ -85,7 +85,7 @@ "الأدوات" "الخلفيات" "الأنماط والخلفيات" - "إعدادات الصفحة الرئيسية" + "إعدادات الشاشة الرئيسية" "أوقف المشرف هذه الميزة" "السماح بتدوير الشاشة الرئيسية" "عند تدوير الهاتف" @@ -108,7 +108,7 @@ "أدوات %1$s" "قائمة الأدوات" "تم إغلاق قائمة الأدوات." - "إضافة إلى الشاشة الرئيسية" + "الإضافة إلى الشاشة الرئيسية" "نقل العنصر إلى هنا" "تمت إضافة العنصر إلى الشاشة الرئيسية" "تم حذف العنصر" diff --git a/res/values-b+sr+Latn/strings.xml b/res/values-b+sr+Latn/strings.xml index 5158a78164..883003c5c0 100644 --- a/res/values-b+sr+Latn/strings.xml +++ b/res/values-b+sr+Latn/strings.xml @@ -105,7 +105,7 @@ "Vidžeti za %1$s" "Lista vidžeta" "Lista vidžeta je zatvorena" - "Dodaj na početni ekran" + "Dodajte na početni ekran" "Premesti stavku ovde" "Stavka je dodata na početni ekran" "Stavka je uklonjena" diff --git a/res/values-bn/strings.xml b/res/values-bn/strings.xml index 6d80329988..775885caac 100644 --- a/res/values-bn/strings.xml +++ b/res/values-bn/strings.xml @@ -83,7 +83,7 @@ "স্টাইল এবং ওয়ালপেপার" "হোম সেটিংস" "আপনার প্রশাসক দ্বারা অক্ষম করা হয়েছে" - "হোমস্ক্রীন ঘোরানোর অনুমতি দিন" + "হোম স্ক্রিন ঘোরানোর অনুমতি দিন" "যখন ফোনটি ঘোরানো হয়" "বিজ্ঞপ্তি ডট" "চালু" @@ -104,7 +104,7 @@ "%1$s উইজেট" "উইজেটের তালিকা" "উইজেটের তালিকা বন্ধ করা হয়েছে" - "হোম স্ক্রীনে যোগ করুন" + "হোম স্ক্রিনে যোগ করুন" "এখানে আইটেম সরান" "হোম স্ক্রীনে আইটেম যোগ করা হয়েছে" "আইটেম সরানো হয়েছে" diff --git a/res/values-bs/strings.xml b/res/values-bs/strings.xml index 53bdeb2d7b..5650457071 100644 --- a/res/values-bs/strings.xml +++ b/res/values-bs/strings.xml @@ -79,7 +79,7 @@ "Folder je zatvoren" "Ime foldera je promijenjeno u %1$s" "Folder: %1$s" - "Dodaci" + "Vidžeti" "Pozadinske slike" "Stilovi i pozadinske slike" "Postavke početnog ekrana" @@ -90,7 +90,7 @@ "Uključeno" "Isključeno" "Potreban je pristup obavještenjima" - "Za prikaz tačaka obavještenja, uključite obavještenja za aplikacije za aplikaciju %1$s" + "Za prikaz tačaka za obavještenja, uključite obavještenja za aplikacije za aplikaciju %1$s" "Promijeni postavke" "Prikaži tačke za obavještenja" "Dodaj ikonu na početni ekran" diff --git a/res/values-ca/strings.xml b/res/values-ca/strings.xml index 19f537ffbd..c0859d3b4d 100644 --- a/res/values-ca/strings.xml +++ b/res/values-ca/strings.xml @@ -81,7 +81,7 @@ "Widgets" "Fons de pantalla" "Estils i fons de pantalla" - "Configuració de pantalla d\'inici" + "Config. pantalla d\'inici" "Desactivada per l\'administrador" "Permet la rotació de la pantalla d\'inici" "En girar el telèfon" @@ -92,7 +92,7 @@ "Per veure els punts de notificació, activa les notificacions de l\'aplicació %1$s" "Canvia la configuració" "Mostra els punts de notificació" - "Afegeix la icona a la pantalla d\'inici" + "Afegeix icona a la pantalla d\'inici" "Per a les aplicacions noves" "Desconegut" "Suprimeix" diff --git a/res/values-da/strings.xml b/res/values-da/strings.xml index 008910dc93..dc17516bce 100644 --- a/res/values-da/strings.xml +++ b/res/values-da/strings.xml @@ -33,7 +33,7 @@ "Tryk to gange, og hold fingeren nede for at vælge en widget eller bruge tilpassede handlinger." "%1$d × %2$d" "%1$d i bredden og %2$d i højden" - "Tryk og hold nede for at placere manuelt" + "Tryk og hold for at placere manuelt" "Tilføj automatisk" "Søg efter apps" "Indlæser apps…" @@ -48,7 +48,7 @@ "Liste med apps" "Liste over personlige apps" "Liste over apps til arbejdet" - "Startskærm" + "Hjem" "Fjern" "Afinstaller" "Appinfo" @@ -80,8 +80,8 @@ "Mappe: %1$s" "Widgets" "Baggrunde" - "Stilarter og baggrunde" - "Indstillinger for startskærmen" + "Stil og baggrunde" + "Startskærmindstillinger" "Deaktiveret af din administrator" "Tillad rotation af startskærmen" "Når telefonen roteres" diff --git a/res/values-de/strings.xml b/res/values-de/strings.xml index 1b7cd22c31..a345babd5c 100644 --- a/res/values-de/strings.xml +++ b/res/values-de/strings.xml @@ -80,11 +80,11 @@ "Ordner: %1$s" "Widgets" "Hintergründe" - "Stile und Hintergründe" - "Einstellungen für den Startbildschirm" + "Designs und Hintergründe" + "Startbildschirm-Einstellungen" "Von deinem Administrator deaktiviert" "Drehung des Startbildschirms zulassen" - "Bei Drehung des Smartphones" + "Beim Drehen des Smartphones" "App-Benachrichtigungspunkte" "An" "Aus" @@ -93,7 +93,7 @@ "Einstellungen ändern" "App-Benachrichtigungspunkte anzeigen" "Symbol zum Startbildschirm hinzufügen" - "Für neue Apps" + "Bei neuen Apps" "Unbekannt" "Entfernen" "Suchen" diff --git a/res/values-en-rAU/strings.xml b/res/values-en-rAU/strings.xml index 6692370896..0c48b5d2cb 100644 --- a/res/values-en-rAU/strings.xml +++ b/res/values-en-rAU/strings.xml @@ -83,7 +83,7 @@ "Styles & wallpapers" "Home settings" "Disabled by your admin" - "Allow Homescreen rotation" + "Allow Home screen rotation" "When phone is rotated" "Notification dots" "On" diff --git a/res/values-en-rGB/strings.xml b/res/values-en-rGB/strings.xml index 6692370896..0c48b5d2cb 100644 --- a/res/values-en-rGB/strings.xml +++ b/res/values-en-rGB/strings.xml @@ -83,7 +83,7 @@ "Styles & wallpapers" "Home settings" "Disabled by your admin" - "Allow Homescreen rotation" + "Allow Home screen rotation" "When phone is rotated" "Notification dots" "On" diff --git a/res/values-en-rIN/strings.xml b/res/values-en-rIN/strings.xml index 6692370896..0c48b5d2cb 100644 --- a/res/values-en-rIN/strings.xml +++ b/res/values-en-rIN/strings.xml @@ -83,7 +83,7 @@ "Styles & wallpapers" "Home settings" "Disabled by your admin" - "Allow Homescreen rotation" + "Allow Home screen rotation" "When phone is rotated" "Notification dots" "On" diff --git a/res/values-es/strings.xml b/res/values-es/strings.xml index ac6ffaa35f..09b1239972 100644 --- a/res/values-es/strings.xml +++ b/res/values-es/strings.xml @@ -85,13 +85,13 @@ "Inhabilitado por el administrador" "Permitir rotación de la pantalla de inicio" "Al girar el teléfono" - "Burbujas de notificación" - "Activadas" + "Puntos de notificación" + "Activados" "Desactivadas" "Se necesita acceso a las notificaciones" - "Para mostrar burbujas de notificación, activa las notificaciones de %1$s" + "Para mostrar puntos de notificación, activa las notificaciones de %1$s" "Cambiar ajustes" - "Mostrar burbujas de notificación" + "Mostrar puntos de notificación" "Añadir icono a la pantalla de inicio" "Para aplicaciones nuevas" "Desconocido" diff --git a/res/values-et/strings.xml b/res/values-et/strings.xml index cea321da27..1e470e15a7 100644 --- a/res/values-et/strings.xml +++ b/res/values-et/strings.xml @@ -27,7 +27,7 @@ "Allalaetud rakendus on turvarežiimis keelatud" "Turvarežiimis on vidinad keelatud" "Otsetee pole saadaval" - "Avaekraan" + "Avakuva" "Kohandatud toimingud" "Vidina valimiseks vajutage ja hoidke seda all." "Topeltpuudutage ja hoidke vidina valimiseks või kohandatud toimingute kasutamiseks." @@ -48,16 +48,16 @@ "Rakenduste loend" "Isiklike rakenduste loend" "Töörakenduste loend" - "Avaekraan" + "Avakuva" "Eemalda" "Desinstalli" "Rakenduse teave" "Installimine" "installi otseteed" "Võimaldab rakendusel lisada otseteid kasutaja sekkumiseta." - "loe avaekraani seadeid ja otseteid" + "avakuva seadete ja otseteede lugemine" "Võimaldab rakendusel lugeda avaekraanil seadeid ja otseteid." - "kirjuta avaekraani seaded ja otseteed" + "avakuva seadete ja otseteede kirjutamine" "Võimaldab rakendusel muuta avaekraanil seadeid ja otseteid." "Rakendusel %1$s pole lubatud helistada" "Probleem vidina laadimisel" @@ -70,8 +70,8 @@ %1$s, %2$d märguanne "Leht %1$d/%2$d" - "Avaekraan %1$d/%2$d" - "Uus avaekraan" + "Avakuva %1$d/%2$d" + "Uus avakuva leht" "Kaust on avatud, %1$d x %2$d" "Puudutage kausta sulgemiseks" "Puudutage ümbernimetamise salvestamiseks" @@ -81,9 +81,9 @@ "Vidinad" "Taustapildid" "Stiilid ja taustapildid" - "Avaekraani seaded" + "Avakuva seaded" "Keelas administraator" - "Luba avaekraani pööramine" + "Luba avakuva pööramine" "Kui telefoni pööratakse" "Märguandetäpid" "Sees" @@ -92,7 +92,7 @@ "Märguandetäppide kuvamiseks lülitage sisse rakenduse %1$s märguanded" "Seadete muutmine" "Kuva märguandetäpid" - "Lisa ikoon avaekraanile" + "Lisa ikoon avakuvasse" "Uute rakenduste puhul" "Teadmata" "Eemalda" @@ -104,7 +104,7 @@ "Teenuse %1$s vidinad" "Vidinate loend" "Vidinate loend on suletud" - "Lisa avaekraanile" + "Lisa avakuvasse" "Teisalda üksus siia" "Üksus lisati avaekraanile" "Üksus eemaldati" diff --git a/res/values-eu/strings.xml b/res/values-eu/strings.xml index 18af2fb0fc..9ba46c171d 100644 --- a/res/values-eu/strings.xml +++ b/res/values-eu/strings.xml @@ -54,11 +54,11 @@ "Aplikazioaren datuak" "Instalatu" "Instalatu lasterbideak" - "Erabiltzaileak ezer egin gabe lasterbideak gehitzea baimentzen die aplikazioei." + "Erabiltzaileak ezer egin gabe lasterbideak gehitzeko baimena ematen die aplikazioei." "Irakurri hasierako ezarpenak eta lasterbideak" - "Hasierako pantailako ezarpenak eta lasterbideak irakurtzea baimentzen die aplikazioei." + "Hasierako pantailako ezarpenak eta lasterbideak irakurtzeko baimena ematen die aplikazioei." "Idatzi hasierako ezarpenak eta lasterbideak" - "Hasierako pantailako ezarpenak eta lasterbideak aldatzea baimentzen die aplikazioei." + "Hasierako pantailako ezarpenak eta lasterbideak aldatzeko baimena ematen die aplikazioei." "%1$s aplikazioak ez du telefono-deiak egiteko baimenik" "Arazo bat izan da widgeta kargatzean" "Konfigurazioa" @@ -83,7 +83,7 @@ "Estiloak eta horma-paperak" "Hasierako pantailaren ezarpenak" "Administratzaileak desgaitu du" - "Baimendu hasierako pantaila biratzea" + "Eman hasierako pantaila biratzeko baimena" "Telefonoa biratzen denean" "Jakinarazpen-biribiltxoak" "Aktibatuta" @@ -93,7 +93,7 @@ "Aldatu ezarpenak" "Erakutsi jakinarazpen-biribiltxoak" "Gehitu ikonoa hasierako pantailan" - "Aplikazio berrietan" + "Aplikazio berrien kasuan" "Ezezaguna" "Kendu" "Bilatu" diff --git a/res/values-fa/strings.xml b/res/values-fa/strings.xml index 7e3cbdc810..926cdb9b1c 100644 --- a/res/values-fa/strings.xml +++ b/res/values-fa/strings.xml @@ -33,7 +33,7 @@ "برای انتخاب یک ابزارک، دو ضربه سریع بزنید و نگه‌دارید یا از کنش‌های سفارشی استفاده کنید." "%1$d × %2$d" "‏%1$d عرض در %2$d طول" - "برای قرار دادن به‌صورت دستی لمس کنید و بکشید" + "آن را لمس کنید و بکشید تا به‌صورت دستی اضافه شود" "افزودن خودکار" "جستجوی برنامه‌ها" "درحال بارگیری برنامه‌‌ها…" diff --git a/res/values-fr-rCA/strings.xml b/res/values-fr-rCA/strings.xml index 9d0e3a0b0c..5ac514d448 100644 --- a/res/values-fr-rCA/strings.xml +++ b/res/values-fr-rCA/strings.xml @@ -51,7 +51,7 @@ "Accueil" "Supprimer" "Désinstaller" - "Détails de l\'appli" + "Détails de l\'application" "Installer" "installer des raccourcis" "Permet à une application d\'ajouter des raccourcis sans l\'intervention de l\'utilisateur." diff --git a/res/values-fr/strings.xml b/res/values-fr/strings.xml index 585139c758..7b4bcb1d82 100644 --- a/res/values-fr/strings.xml +++ b/res/values-fr/strings.xml @@ -81,7 +81,7 @@ "Widgets" "Fonds d\'écran" "Styles et fonds d\'écran" - "Paramètres accueil" + "Paramètres d\'écran d\'accueil" "Désactivé par votre administrateur" "Autoriser la rotation de l\'écran d\'accueil" "Lorsque vous faites pivoter le téléphone" diff --git a/res/values-gl/strings.xml b/res/values-gl/strings.xml index 769586e78a..e115a72624 100644 --- a/res/values-gl/strings.xml +++ b/res/values-gl/strings.xml @@ -80,14 +80,14 @@ "Cartafol: %1$s" "Widgets" "Fondos de pantalla" - "Estilos e fondos de pantalla" - "Configuración da pantalla de Inicio" + "Estilos/fondos de pantalla" + "Axustes de Inicio" "Función desactivada polo administrador" "Permitir xirar a pantalla de inicio" "Ao xirar o teléfono" "Puntos de notificacións" - "Opción activada" - "Opción desactivada" + "Activados" + "Desactivados" "Necesítase acceso ás notificacións" "Para que se mostren os puntos de notificacións, activa as notificacións da aplicación %1$s" "Cambiar configuración" diff --git a/res/values-hi/strings.xml b/res/values-hi/strings.xml index 5f24b05210..b796140e5e 100644 --- a/res/values-hi/strings.xml +++ b/res/values-hi/strings.xml @@ -22,9 +22,9 @@ "Launcher3" "कार्यस्‍थल" - "एप्‍लिकेशन इंस्‍टॉल नहीं है." - "ऐप्स उपलब्ध नहीं है" - "डाउनलोड किए गए ऐप्स सुरक्षित मोड में अक्षम है" + "ऐप्‍लिकेशन इंस्‍टॉल नहीं है." + "ऐप्लिकेशन उपलब्ध नहीं है" + "डाउनलोड किए गए ऐप्लिकेशन सुरक्षित मोड में अक्षम है" "विजेट सुरक्षित मोड में अक्षम हैं" "शॉर्टकट उपलब्ध नहीं है" "होम स्क्रीन" @@ -78,7 +78,7 @@ "फ़ोल्डर बंद किया गया" "फ़ोल्डर का नाम बदलकर %1$s किया गया" "फ़ोल्डर: %1$s" - "शॉर्टकट" + "विजेट" "वॉलपेपर" "स्टाइल और वॉलपेपर" "होम पेज की सेटिंग" @@ -97,9 +97,9 @@ "अज्ञात" "निकालें" "सर्च करें" - "यह ऐप्स इंस्टॉल नहीं है" + "यह ऐप्लिकेशन इंस्टॉल नहीं है" "इस आइकॉन का ऐप इंस्टॉल नहीं है. आप उसे निकाल सकते हैं या ऐप को खोज कर उसे मैन्युअल रूप से इंस्टॉल कर सकते हैं." - "%1$s डाउनलोड हो रहा है, %2$s पूर्ण" + "%1$s डाउनलोड हो रहा है, %2$s पूरी हुई" "%1$s के इंस्टॉल होने की प्रतीक्षा की जा रही है" "%1$s विजेट" "विजेट की सूची" @@ -132,7 +132,7 @@ "सूचना को खारिज किया गया" "निजी ऐप" "काम से जुड़े ऐप" - "कार्य प्रोफ़ाइल" + "वर्क प्रोफ़ाइल" "काम से जुड़े सभी ऐप्लिकेशन यहां पाएं" "काम से जुड़े हर ऐप्लिकेशन पर एक बैज (निशान) होता है और इन ऐप्लिकेशन की सुरक्षा आपका संगठन करता है. आसानी से इस्तेमाल करने के लिए ऐप्लिकेशन को अपनी होम स्क्रीन पर ले जाएं." "आपका संगठन प्रबंधित कर रहा है" diff --git a/res/values-in/strings.xml b/res/values-in/strings.xml index 0841be0fd1..3054214b5e 100644 --- a/res/values-in/strings.xml +++ b/res/values-in/strings.xml @@ -33,7 +33,7 @@ "Tap dua kalip & tahan untuk mengambil widget atau menggunakan tindakan khusus." "%1$d × %2$d" "lebar %1$d x tinggi %2$d" - "Sentuh & tahan untuk menempatkan secara manual" + "Tap lama untuk menempatkan secara manual" "Tambahkan otomatis" "Telusuri aplikasi" "Memuat aplikasi…" @@ -81,9 +81,9 @@ "Widget" "Wallpaper" "Gaya & wallpaper" - "Setelan layar Utama" + "Setelan layar utama" "Dinonaktifkan oleh admin" - "Izinkan layar Utama diputar" + "Izinkan Layar utama diputar" "Saat ponsel diputar" "Titik notifikasi" "Aktif" diff --git a/res/values-iw/strings.xml b/res/values-iw/strings.xml index 6f5a4009ee..c25e8795f7 100644 --- a/res/values-iw/strings.xml +++ b/res/values-iw/strings.xml @@ -50,7 +50,7 @@ "רשימת אפליקציות עבודה" "דף הבית" "הסר" - "הסר התקנה" + "להסרת התקנה" "פרטי אפליקציה" "התקנה" "התקן קיצורי דרך" @@ -61,7 +61,7 @@ "מאפשר לאפליקציה לשנות את ההגדרות וקיצורי הדרך בדף הבית." "%1$s אינו רשאי להתקשר" "בעיה בטעינת ווידג\'ט" - "הגדר" + "הגדרה" "זוהי אפליקציית מערכת ולא ניתן להסיר את התקנתה." "תיקיה ללא שם" "%1$s מושבתת" diff --git a/res/values-kk/strings.xml b/res/values-kk/strings.xml index 2e953a6cdd..1cd9045b76 100644 --- a/res/values-kk/strings.xml +++ b/res/values-kk/strings.xml @@ -34,7 +34,7 @@ "%1$d × %2$d" "Ені: %1$d, биіктігі: %2$d" "Қолмен қою үшін басып тұрыңыз" - "Автоматты енгізу" + "Автоматты қосу" "Қолданбаларды іздеу" "Қолданбалар жүктелуде…" "\"%1$s\" сұрауына сәйкес келетін қолданбалар жоқ" diff --git a/res/values-km/strings.xml b/res/values-km/strings.xml index b953ea337b..f4a328df14 100644 --- a/res/values-km/strings.xml +++ b/res/values-km/strings.xml @@ -84,7 +84,7 @@ "ការកំណត់​ទំព័រដើម" "បានបិទដំណើរការដោយអ្នកគ្រប់គ្រងរបស់អ្នក" "អនុញ្ញាតការបងិ្វលអេក្រង់ដើម" - "នៅពេលដែលបង្វិលទូរស័ព្ទរបស់អ្នក" + "នៅពេលដែលបង្វិលទូរសព្ទ" "ស្លាកជូនដំណឹង" "បើក" "បិទ" @@ -104,7 +104,7 @@ "ធាតុ​ក្រាហ្វិក %1$s" "បញ្ជីធាតុ​ក្រាហ្វិក" "បាន​បិទ​បញ្ជីធាតុ​ក្រាហ្វិក" - "បន្ថែមទៅអេក្រង់ដើម" + "បញ្ចូលទៅអេក្រង់ដើម" "ផ្លាស់ធាតុមកទីនេះ" "ធាតុដែលត្រូវបានបន្ថែមទៅអេក្រង់ដើម" "ធាតុដែលបានដកចេញ" diff --git a/res/values-kn/strings.xml b/res/values-kn/strings.xml index 2e96a7ce19..14c830064b 100644 --- a/res/values-kn/strings.xml +++ b/res/values-kn/strings.xml @@ -104,7 +104,7 @@ "%1$s ವಿಜೆಟ್‌ಗಳು" "ವಿಜೆಟ್ ಪಟ್ಟಿ" "ವಿಜೆಟ್ ಪಟ್ಟಿಯನ್ನು ಮುಚ್ಚಲಾಗಿದೆ" - "ಮುಖಪುಟಕ್ಕೆ ಸೇರಿಸು" + "ಮುಖಪುಟಕ್ಕೆ ಸೇರಿಸಿ" "ಐಟಂ ಇಲ್ಲಿಗೆ ಸರಿಸಿ" "ಮುಖಪುಟ ಪರದೆಗೆ ಐಟಂ ಸೇರಿಸಲಾಗಿದೆ" "ಐಟಂ ತೆಗೆದುಹಾಕಲಾಗಿದೆ" diff --git a/res/values-ky/strings.xml b/res/values-ky/strings.xml index 36b63851c5..046a66253e 100644 --- a/res/values-ky/strings.xml +++ b/res/values-ky/strings.xml @@ -33,7 +33,7 @@ "Виджет тандоо үчүн эки жолу таптап, кармап туруңуз же ыңгайлаштырылган аракеттерди колдонуңуз." "%1$d × %2$d" "Туурасы: %1$d, бийиктиги: %2$d" - "Кол менен жайгаштыруу үчүн басып туруп, таштаңыз" + "Кол менен кошуу үчүн кое бербей басып туруңуз" "Автоматтык түрдө кошуу" "Колдонмолорду издөө" "Колдонмолор жүктөлүүдө…" @@ -81,7 +81,7 @@ "Виджеттер" "Тушкагаздар" "Стилдер жана тушкагаздар" - "Башкы беттин жөндөөлөрү" + "Башкы бет жөндөөлөрү" "Администраторуңуз өчүрүп койгон" "Башкы экранды айлантууга уруксат берүү" "Телефон айланганда" diff --git a/res/values-ml/strings.xml b/res/values-ml/strings.xml index e03340bdb1..4362e7cca5 100644 --- a/res/values-ml/strings.xml +++ b/res/values-ml/strings.xml @@ -78,7 +78,7 @@ "ഫോൾഡർ അടച്ചു" "ഫോൾഡറിന്റെ പേര് %1$s എന്നായി മാറ്റി" "ഫോൾഡർ: %1$s" - "വിജറ്റുകൾ" + "വിഡ്ജെറ്റുകൾ" "വാൾപേപ്പർ" "സ്‌റ്റൈലുകളും വാൾപേപ്പറുകളും" "ഹോം ക്രമീകരണം" diff --git a/res/values-mn/strings.xml b/res/values-mn/strings.xml index f52f46171c..ab02ac655c 100644 --- a/res/values-mn/strings.xml +++ b/res/values-mn/strings.xml @@ -104,7 +104,7 @@ "%1$s жижиг хэрэгсэл" "Жижиг хэрэгслийн жагсаалт" "Жижиг хэрэгслийн жагсаалтыг хаасан" - "Нүүр дэлгэц нэмэх" + "Нүүр дэлгэцэд нэмэх" "Энд байршуулах" "Нүүр дэлгэцэнд нэмсэн зүйл" "Арилгасан зүйл" diff --git a/res/values-mr/strings.xml b/res/values-mr/strings.xml index f6eac53997..19c06976b0 100644 --- a/res/values-mr/strings.xml +++ b/res/values-mr/strings.xml @@ -66,8 +66,8 @@ "अनामित फोल्डर" "%1$s अक्षम केला आहे" - %1$sसाठी%2$dसूचना आहेत %1$sसाठी %2$d सूचना आहेत + %1$sसाठी%2$dसूचना आहे "%2$d पैकी %1$d पृष्ठ" "%2$d पैकी %1$d मुख्य स्क्रीन" diff --git a/res/values-my/strings.xml b/res/values-my/strings.xml index 7ae4446d5f..fd1f7d9535 100644 --- a/res/values-my/strings.xml +++ b/res/values-my/strings.xml @@ -50,7 +50,7 @@ "အလုပ်သုံး အက်ပ်စာရင်း" "ပင်မစာမျက်နှာ" "ဖယ်ရှားမည်" - "ဖယ်ထုတ်မည်" + "ဖြုတ်ရန်" "အက်ပ်အချက်အလက်များ" "ထည့်သွင်းရန်" "အတိုကောက်မှတ်သားမှုများအား ထည့်သွင်းခြင်း" @@ -94,7 +94,7 @@ "သတိပေးချက် အစက်များ ပြရန်" "ပင်မစာမျက်နှာသို့ သင်္ကေတပုံ ထည့်ရန်" "အက်ပ်အသစ်များအတွက်" - "မသိရ" + "မသိ" "ဖယ်ရှားရန်" "ရှာဖွေရန်" "အက်ပ်မတပ်ဆင်ရသေးပါ" diff --git a/res/values-nl/strings.xml b/res/values-nl/strings.xml index bc1b45036c..ec30d8c6b2 100644 --- a/res/values-nl/strings.xml +++ b/res/values-nl/strings.xml @@ -33,7 +33,7 @@ "Dubbeltik en blijf aanraken om een widget toe te voegen of aangepaste acties te gebruiken." "%1$d × %2$d" "%1$d breed en %2$d hoog" - "Tik op een item en houd dit vast om het handmatig te plaatsen" + "Tik en houd vast om handmatig te plaatsen" "Automatisch toevoegen" "Apps zoeken" "Apps laden…" @@ -80,7 +80,7 @@ "Map: %1$s" "Widgets" "Achtergrond" - "Stijlen en achtergronden" + "Stijl en achtergrond" "Instellingen startscherm" "Uitgeschakeld door je beheerder" "Draaien van startscherm toestaan" diff --git a/res/values-pl/strings.xml b/res/values-pl/strings.xml index e33ef7da70..68859605fb 100644 --- a/res/values-pl/strings.xml +++ b/res/values-pl/strings.xml @@ -106,7 +106,7 @@ "%1$s – widżety" "Lista widgetów" "Lista widgetów zamknięta" - "Dodaj do strony głównej" + "Dodaj do ekranu głównego" "Przenieś element tutaj" "Element został dodany do ekranu głównego" "Element został usunięty" diff --git a/res/values-pt-rPT/strings.xml b/res/values-pt-rPT/strings.xml index 68a08a9eb5..071b71e38f 100644 --- a/res/values-pt-rPT/strings.xml +++ b/res/values-pt-rPT/strings.xml @@ -81,7 +81,7 @@ "Widgets" "Imagens de fundo" "Estilos e imagens de fundo" - "Definições da página inicial" + "Definições de início" "Desativada pelo gestor" "Permitir rotação do ecrã principal" "Quando o telemóvel é rodado" diff --git a/res/values-pt/strings.xml b/res/values-pt/strings.xml index 1744fa16cc..e88ff18b42 100644 --- a/res/values-pt/strings.xml +++ b/res/values-pt/strings.xml @@ -33,7 +33,7 @@ "Toque duas vezes e segure para selecionar um widget ou usar ações personalizadas." "%1$d × %2$d" "%1$d de largura por %2$d de altura" - "Toque e mantenha pressionado para posicionar manualmente" + "Toque e mantenha pressionado para mover manualmente" "Adicionar automaticamente" "Apps de pesquisa" "Carregando apps…" @@ -81,7 +81,7 @@ "Widgets" "Planos de fundo" "Estilos e planos de fundo" - "Configurações da tela inicial" + "Config. tela inicial" "Desativado pelo administrador" "Permitir rotação da tela inicial" "Quando o smartphone for girado" diff --git a/res/values-ro/strings.xml b/res/values-ro/strings.xml index a7e8f05844..1251d7e3f8 100644 --- a/res/values-ro/strings.xml +++ b/res/values-ro/strings.xml @@ -51,7 +51,7 @@ "Ecran de pornire" "Eliminați" "Dezinstalați" - "Informații aplicație" + "Informații despre aplicații" "Instalați" "instalează comenzi rapide" "Permite unei aplicații să adauge comenzi rapide fără intervenția utilizatorului." @@ -82,9 +82,9 @@ "Widgeturi" "Imagini de fundal" "Stiluri și imagini de fundal" - "Setări pentru ecranul de pornire" + "Setări ecran de pornire" "Dezactivată de administrator" - "Permiteți rotirea ecranului de pornire" + "Permite rotirea ecranului de pornire" "Când telefonul este rotit" "Puncte de notificare" "Activate" diff --git a/res/values-ru/strings.xml b/res/values-ru/strings.xml index 9030a75eed..34e267da9b 100644 --- a/res/values-ru/strings.xml +++ b/res/values-ru/strings.xml @@ -82,8 +82,8 @@ "Папка: %1$s" "Виджеты" "Обои" - "Темы и обои" - "Настройки главного экрана" + "Стили и обои" + "Главный экран" "Функция отключена администратором" "Разрешить поворачивать главный экран" "Когда телефон повернут" diff --git a/res/values-si/strings.xml b/res/values-si/strings.xml index 574d3ede01..ef99a59e4e 100644 --- a/res/values-si/strings.xml +++ b/res/values-si/strings.xml @@ -80,8 +80,8 @@ "ෆෝල්ඩරය: %1$s" "විජට්" "වෝල්පේපර" - "විලාස සහ බිතුපත්" - "Home සැකසීම්" + "විලාස සහ වෝල්පේපර" + "නිවසේ සැකසීම්" "ඔබගේ පරිපාලක විසින් අබල කරන ලදී" "මුල් පිටු තිරය කරකැවීමට ඉඩ දෙන්න" "දුරකථනය කරකවන විට" diff --git a/res/values-sk/strings.xml b/res/values-sk/strings.xml index 77eeab25ec..340a128d2b 100644 --- a/res/values-sk/strings.xml +++ b/res/values-sk/strings.xml @@ -83,7 +83,7 @@ "Miniaplikácie" "Tapety" "Štýly a tapety" - "Nastavenia Home" + "Nastavenia plochy" "Zakázané vaším správcom" "Povoliť otáčanie plochy" "Pri otočení telefónu" diff --git a/res/values-sr/strings.xml b/res/values-sr/strings.xml index f74fde2eb8..4e52592687 100644 --- a/res/values-sr/strings.xml +++ b/res/values-sr/strings.xml @@ -105,7 +105,7 @@ "Виџети за %1$s" "Листа виџета" "Листа виџета је затворена" - "Додај на почетни екран" + "Додајте на почетни екран" "Премести ставку овде" "Ставка је додата на почетни екран" "Ставка је уклоњена" diff --git a/res/values-sw/strings.xml b/res/values-sw/strings.xml index 7b84ed3c1d..6f33c4f046 100644 --- a/res/values-sw/strings.xml +++ b/res/values-sw/strings.xml @@ -106,7 +106,7 @@ "Wijeti za %1$s" "Orodha ya wijeti" "Orodha ya wijeti imefungwa" - "Ongeza kwenye skrini ya Kwanza" + "Ongeza kwenye Skrini ya Kwanza" "Hamishia kipengee hapa" "Kipengee kimeongezwa kwenye skrini ya kwanza" "Kipengee kimeondolewa" diff --git a/res/values-ta/strings.xml b/res/values-ta/strings.xml index 47b25816fb..672665e430 100644 --- a/res/values-ta/strings.xml +++ b/res/values-ta/strings.xml @@ -22,9 +22,9 @@ "Launcher3" "பணியிடம்" - "பயன்பாடு நிறுவப்படவில்லை." - "பயன்பாடு இல்லை" - "இறக்கிய பயன்பாடு பாதுகாப்பு முறையில் முடக்கப்பட்டது" + "ஆப்ஸ் நிறுவப்படவில்லை." + "ஆப்ஸ் இல்லை" + "இறக்கிய ஆப்ஸ் பாதுகாப்பு முறையில் முடக்கப்பட்டது" "பாதுகாப்புப் பயன்முறையில் விட்ஜெட்கள் முடக்கப்பட்டுள்ளன" "ஷார்ட்கட் இல்லை" "முகப்புத் திரை" @@ -51,18 +51,18 @@ "முகப்பு" "அகற்று" "நிறுவல் நீக்கு" - "பயன்பாட்டுத் தகவல்" + "ஆப்ஸ் தகவல்" "நிறுவு" "குறுக்குவழிகளை நிறுவுதல்" - "பயனரின் அனுமதி இல்லாமல் குறுக்குவழிகளைச் சேர்க்கப் பயன்பாட்டை அனுமதிக்கிறது." + "பயனரின் அனுமதி இல்லாமல் குறுக்குவழிகளைச் சேர்க்கப் ஆப்ஸை அனுமதிக்கிறது." "முகப்பின் அமைப்பு மற்றும் குறுக்குவழிகளைப் படித்தல்" - "முகப்பில் உள்ள அமைப்பு மற்றும் குறுக்குவழிகளைப் படிக்க பயன்பாட்டை அனுமதிக்கிறது." + "முகப்பில் உள்ள அமைப்பு மற்றும் குறுக்குவழிகளைப் படிக்க ஆப்ஸை அனுமதிக்கிறது." "முகப்பின் அமைப்பு மற்றும் குறுக்குவழிகளை எழுதுதல்" - "முகப்பில் உள்ள அமைப்பு மற்றும் குறுக்குவழிகளை மாற்ற பயன்பாட்டை அனுமதிக்கிறது." + "முகப்பில் உள்ள அமைப்பு மற்றும் குறுக்குவழிகளை மாற்ற ஆப்ஸை அனுமதிக்கிறது." "ஃபோன் அழைப்புகள் செய்ய, %1$s அனுமதிக்கப்படவில்லை" "விட்ஜெட்டை ஏற்றுவதில் சிக்கல்" "அமைவு" - "இது அமைப்பு பயன்பாடு என்பதால் நிறுவல் நீக்கம் செய்ய முடியாது." + "இது அமைப்பு ஆப்ஸ் என்பதால் நிறுவல் நீக்கம் செய்ய முடியாது." "பெயரிடப்படாத கோப்புறை" "%1$s முடக்கப்பட்டது" @@ -78,7 +78,7 @@ "கோப்புறை மூடப்பட்டது" "கோப்புறை %1$s என மறுபெயரிடப்பட்டது" "கோப்புறை: %1$s" - "ஷார்ட்கட்ஸ்" + "விட்ஜெட்கள்" "வால்பேப்பர்கள்" "ஸ்டைல்கள் & வால்பேப்பர்கள்" "முகப்பு அமைப்புகள்" @@ -93,12 +93,12 @@ "அமைப்புகளை மாற்று" "அறிவிப்புப் புள்ளிகளைக் காட்டு" "முகப்புத் திரையில் ஐகானைச் சேர்" - "புதிய பயன்பாடுகளுக்கு" + "புதிய ஆப்ஸை நிறுவும்போது" "தெரியாதது" "அகற்று" "தேடு" - "பயன்பாடு நிறுவப்படவில்லை" - "ஐகானுக்கான பயன்பாடு நிறுவப்படவில்லை. இதை அகற்றலாம் அல்லது பயன்பாட்டைத் தேடி கைமுறையாக நிறுவலாம்." + "ஆப்ஸ் நிறுவப்படவில்லை" + "ஐகானுக்கான ஆப்ஸ் நிறுவப்படவில்லை. இதை அகற்றலாம் அல்லது பயன்பாட்டைத் தேடி கைமுறையாக நிறுவலாம்." "%1$sஐப் பதிவிறக்குகிறது, %2$s முடிந்தது" "%1$sஐ நிறுவுவதற்காகக் காத்திருக்கிறது" "%1$s விட்ஜெட்டுகள்" diff --git a/res/values-te/strings.xml b/res/values-te/strings.xml index 528ce481bd..c8f70fe058 100644 --- a/res/values-te/strings.xml +++ b/res/values-te/strings.xml @@ -80,7 +80,7 @@ "ఫోల్డర్: %1$s" "విడ్జెట్‌లు" "వాల్‌పేపర్‌లు" - "శైలులు & వాల్‌పేపర్‌లు" + "స్ట‌యిల్స్‌ & వాల్‌పేపర్‌లు" "హోమ్ సెట్టింగ్‌లు" "మీ నిర్వాహకులు నిలిపివేసారు" "హోమ్ స్క్రీన్ భ్రమణాన్ని అనుమతించండి" diff --git a/res/values-tl/strings.xml b/res/values-tl/strings.xml index f0c241e9e8..0df94c7104 100644 --- a/res/values-tl/strings.xml +++ b/res/values-tl/strings.xml @@ -98,7 +98,7 @@ "Alisin" "Maghanap" "Hindi naka-install ang app na ito" - "Hindi naka-install ang app para sa icon na ito. Maaari mo itong alisin, o maaari mong hanapin ang app at i-install ito nang manu-mano." + "Hindi naka-install ang app para sa icon na ito. Puwede mo itong alisin, o maaari mong hanapin ang app at i-install ito nang manual." "Dina-download na ang %1$s, tapos na ang %2$s" "Hinihintay nang mag-install ang %1$s" "Mga widget ng %1$s" diff --git a/res/values-uk/strings.xml b/res/values-uk/strings.xml index ad51464a32..13ba701815 100644 --- a/res/values-uk/strings.xml +++ b/res/values-uk/strings.xml @@ -82,8 +82,8 @@ "Папка %1$s" "Віджети" "Фонові малюнки" - "Стилі й фонові малюнки" - "Налаштування Home" + "Стиль і фон" + "Налаштування головного екрана" "Вимкнув адміністратор" "Дозволити обертання головного екрана" "Коли телефон обертається" @@ -94,7 +94,7 @@ "Щоб показувати значки сповіщень, увімкніть сповіщення в додатку %1$s" "Змінити налаштування" "Показувати значки сповіщень" - "Додати значок на головний екран" + "Додавати значок на головний екран" "Для нових додатків" "Невідомо" "Прибрати" diff --git a/res/values-ur/strings.xml b/res/values-ur/strings.xml index 5d7218d37e..4f776701e5 100644 --- a/res/values-ur/strings.xml +++ b/res/values-ur/strings.xml @@ -33,7 +33,7 @@ "کوئی ویجٹ منتخب کرنے یا حسب ضرورت کاروائیاں استعمال کرنے کیلئے دو بار تھپتھپائیں اور پکڑے رکھیں۔" "%1$d × %2$d" "‏%1$d چوڑا اور ‎%2$d اونچا" - "‏دستی طور پر رکھنے کیلئے ‎& ٹچ کرکے ہولڈ کریں" + "‏دستی طور پر رکھنے کیلئے ‎ٹچ کر کے دبائے رکھیں" "خود کار طور پر شامل کریں" "ایپس تلاش کریں" "ایپس لوڈ کی جا رہی ہیں…" diff --git a/res/values-uz/strings.xml b/res/values-uz/strings.xml index d34a64f93a..69084d7041 100644 --- a/res/values-uz/strings.xml +++ b/res/values-uz/strings.xml @@ -33,7 +33,7 @@ "Ikki marta bosib va bosib turgan holatda vidjetni tanlang yoki maxsus amaldan foydalaning." "%1$d × %2$d" "Eni %1$d, bo‘yi %2$d" - "Qo‘lda joylashtirish uchun bosib turing" + "Joylash uchun bosib turing" "Avtomatik chiqarish" "Ilovalarni qidirish" "Ilovalar yuklanmoqda…" @@ -83,7 +83,7 @@ "Mavzu va fon rasmlari" "Bosh ekran sozlamalari" "Administrator tomonidan o‘chirilgan" - "Asosiy ekranni aylantirishga ruxsat berish" + "Bosh ekranni burishga ruxsat" "Telefon burilganda" "Bildirishnoma belgilari" "Yoniq" @@ -95,7 +95,7 @@ "Bosh ekranga ikonka chiqarish" "Yangi o‘rnatilgan ilovalar ikonkasini bosh ekranga chiqarish" "Noma’lum" - "O‘chirish" + "Olib tashlash" "Qidirish" "Ushbu ilova o‘rnatilmagan" "Ilova o‘rnatilmagan. Belgini o‘chirib tashlashingiz yoki ilovani topib, uni qo‘lda o‘rnatishingiz mumkin." @@ -104,15 +104,15 @@ "%1$s vidjetlari" "Vidjetlar ro‘yxati" "Vidjetlar ro‘yxati yopildi" - "Bosh ekranga qo‘shish" + "Bosh ekranga chiqarish" "Obyektni bu yerga ko‘chirish" "Obyekt bosh ekranga qo‘shildi" "Obyekt o‘chirib tashlandi" "Qaytarish" "Obyektni ko‘chirib o‘tkazish" - "%1$s %2$s katakka ko‘chirib o‘tkazish" - "%1$s-joyga ko‘chirib o‘tkazish" - "Sevimlilarga (%1$s) ko‘chirib o‘tkazish" + "%1$s %2$s katakka olish" + "%1$s-joyga olish" + "Sevimlilarga olish (%1$s)" "Element ko‘chirib o‘tkazildi" "%1$s jildiga qo‘shish" "%1$s ilovasi bor jildga qo‘shish" diff --git a/res/values-vi/strings.xml b/res/values-vi/strings.xml index 174ec7fe95..71decfca68 100644 --- a/res/values-vi/strings.xml +++ b/res/values-vi/strings.xml @@ -33,7 +33,7 @@ "Nhấn đúp và giữ để chọn tiện ích hoặc sử dụng tác vụ tùy chỉnh." "%1$d × %2$d" "Rộng %1$d x cao %2$d" - "Chạm và giữ để đặt theo cách thủ công" + "Chạm và giữ để thêm theo cách thủ công" "Tự động thêm" "Tìm kiếm ứng dụng" "Đang tải ứng dụng…" @@ -78,7 +78,7 @@ "Đã đóng thư mục" "Đã đổi tên thư mục thành %1$s" "Thư mục: %1$s" - "Tiện ích con" + "Tiện ích" "Hình nền" "Kiểu và hình nền" "Cài đặt màn hình chính" diff --git a/res/values-zh-rCN/strings.xml b/res/values-zh-rCN/strings.xml index fd31875a98..9804af1e89 100644 --- a/res/values-zh-rCN/strings.xml +++ b/res/values-zh-rCN/strings.xml @@ -33,7 +33,7 @@ "点按两次并按住微件即可选择微件,您也可以使用自定义操作。" "%1$d × %2$d" "宽 %1$d,高 %2$d" - "触摸并按住即可手动放置" + "轻触并按住即可手动放置" "自动添加" "搜索应用" "正在加载应用…" diff --git a/res/values-zh-rHK/strings.xml b/res/values-zh-rHK/strings.xml index de0fa89a0c..e7377440c1 100644 --- a/res/values-zh-rHK/strings.xml +++ b/res/values-zh-rHK/strings.xml @@ -81,7 +81,7 @@ "小工具" "桌布" "樣式和桌布" - "主螢幕設定" + "主畫面設定" "已由您的管理員停用" "允許主畫面旋轉" "當手機旋轉時" diff --git a/res/values-zh-rTW/strings.xml b/res/values-zh-rTW/strings.xml index 4d37d721f7..e971b69f1f 100644 --- a/res/values-zh-rTW/strings.xml +++ b/res/values-zh-rTW/strings.xml @@ -33,7 +33,7 @@ "輕觸兩下並按住小工具即可選取,你也可以使用自訂動作。" "%1$d × %2$d" "寬度為 %1$d,高度為 %2$d" - "按住即可手動放置" + "按住圖示即可手動新增" "自動新增" "搜尋應用程式" "正在載入應用程式…" @@ -81,7 +81,7 @@ "小工具" "桌布" "樣式和桌布" - "Home 設定" + "主螢幕設定" "已由你的管理員停用" "允許旋轉主螢幕" "當手機旋轉時" From 725e35f73c349093fbc6344db8afb68d970436ad Mon Sep 17 00:00:00 2001 From: Hyunyoung Song Date: Fri, 21 Jun 2019 23:24:02 -0700 Subject: [PATCH 002/108] Enable FLAG_SLIPPERY window flag when swipe down on workspace Bug: 131356741 Test: manual Change-Id: Ibe0e3a03e7406d5d882a1c63265d6e4e0253983e --- .../StatusBarTouchController.java | 68 +++-- .../launcher3/touch/TouchEventTranslator.java | 283 ------------------ 2 files changed, 51 insertions(+), 300 deletions(-) delete mode 100644 src/com/android/launcher3/touch/TouchEventTranslator.java diff --git a/quickstep/src/com/android/launcher3/uioverrides/touchcontrollers/StatusBarTouchController.java b/quickstep/src/com/android/launcher3/uioverrides/touchcontrollers/StatusBarTouchController.java index fee18204ea..f5ba3725df 100644 --- a/quickstep/src/com/android/launcher3/uioverrides/touchcontrollers/StatusBarTouchController.java +++ b/quickstep/src/com/android/launcher3/uioverrides/touchcontrollers/StatusBarTouchController.java @@ -17,17 +17,22 @@ package com.android.launcher3.uioverrides.touchcontrollers; import static android.view.MotionEvent.ACTION_DOWN; import static android.view.MotionEvent.ACTION_MOVE; +import static android.view.MotionEvent.ACTION_UP; +import static android.view.MotionEvent.ACTION_CANCEL; +import android.graphics.PointF; import android.os.RemoteException; import android.util.Log; +import android.util.SparseArray; import android.view.MotionEvent; import android.view.ViewConfiguration; +import android.view.Window; +import android.view.WindowManager; import com.android.launcher3.AbstractFloatingView; import com.android.launcher3.DeviceProfile; import com.android.launcher3.Launcher; import com.android.launcher3.LauncherState; -import com.android.launcher3.touch.TouchEventTranslator; import com.android.launcher3.util.TouchController; import com.android.quickstep.RecentsModel; import com.android.systemui.shared.recents.ISystemUiProxy; @@ -36,18 +41,29 @@ import java.io.PrintWriter; /** * TouchController for handling touch events that get sent to the StatusBar. Once the - * Once the event delta y passes the touch slop, the events start getting forwarded. + * Once the event delta mDownY passes the touch slop, the events start getting forwarded. * All events are offset by initial Y value of the pointer. */ public class StatusBarTouchController implements TouchController { private static final String TAG = "StatusBarController"; + /** + * Window flag: Enable touches to slide out of a window into neighboring + * windows in mid-gesture instead of being captured for the duration of + * the gesture. + * + * This flag changes the behavior of touch focus for this window only. + * Touches can slide out of the window but they cannot necessarily slide + * back in (unless the other window with touch focus permits it). + */ + private static final int FLAG_SLIPPERY = 0x20000000; + protected final Launcher mLauncher; - protected final TouchEventTranslator mTranslator; private final float mTouchSlop; private ISystemUiProxy mSysUiProxy; private int mLastAction; + private final SparseArray mDownEvents; /* If {@code false}, this controller should not handle the input {@link MotionEvent}.*/ private boolean mCanIntercept; @@ -56,7 +72,7 @@ public class StatusBarTouchController implements TouchController { mLauncher = l; // Guard against TAPs by increasing the touch slop. mTouchSlop = 2 * ViewConfiguration.get(l).getScaledTouchSlop(); - mTranslator = new TouchEventTranslator((MotionEvent ev)-> dispatchTouchEvent(ev)); + mDownEvents = new SparseArray<>(); } @Override @@ -64,7 +80,6 @@ public class StatusBarTouchController implements TouchController { writer.println(prefix + "mCanIntercept:" + mCanIntercept); writer.println(prefix + "mLastAction:" + MotionEvent.actionToString(mLastAction)); writer.println(prefix + "mSysUiProxy available:" + (mSysUiProxy != null)); - } private void dispatchTouchEvent(MotionEvent ev) { @@ -81,26 +96,31 @@ public class StatusBarTouchController implements TouchController { @Override public final boolean onControllerInterceptTouchEvent(MotionEvent ev) { int action = ev.getActionMasked(); + int idx = ev.getActionIndex(); + int pid = ev.getPointerId(idx); if (action == ACTION_DOWN) { mCanIntercept = canInterceptTouch(ev); if (!mCanIntercept) { return false; } - mTranslator.reset(); - mTranslator.setDownParameters(0, ev); + mDownEvents.put(pid, new PointF(ev.getX(), ev.getY())); } else if (ev.getActionMasked() == MotionEvent.ACTION_POINTER_DOWN) { - // Check!! should only set it only when threshold is not entered. - mTranslator.setDownParameters(ev.getActionIndex(), ev); + // Check!! should only set it only when threshold is not entered. + mDownEvents.put(pid, new PointF(ev.getX(idx), ev.getY(idx))); } if (!mCanIntercept) { return false; } if (action == ACTION_MOVE) { - float dy = ev.getY() - mTranslator.getDownY(); - float dx = ev.getX() - mTranslator.getDownX(); - if (dy > mTouchSlop && dy > Math.abs(dx)) { - mTranslator.dispatchDownEvents(ev); - mTranslator.processMotionEvent(ev); + float dy = ev.getY(idx) - mDownEvents.get(pid).y; + float dx = ev.getX(idx) - mDownEvents.get(pid).x; + // Currently input dispatcher will not do touch transfer if there are more than + // one touch pointer. Hence, even if slope passed, only set the slippery flag + // when there is single touch event. (context: InputDispatcher.cpp line 1445) + if (dy > mTouchSlop && dy > Math.abs(dx) && ev.getPointerCount() == 1) { + ev.setAction(ACTION_DOWN); + dispatchTouchEvent(ev); + setWindowSlippery(true); return true; } if (Math.abs(dx) > mTouchSlop) { @@ -110,13 +130,27 @@ public class StatusBarTouchController implements TouchController { return false; } - @Override public final boolean onControllerTouchEvent(MotionEvent ev) { - mTranslator.processMotionEvent(ev); + if (ev.getAction() == ACTION_UP || ev.getAction() == ACTION_CANCEL) { + dispatchTouchEvent(ev); + setWindowSlippery(false); + return true; + } return true; } + private void setWindowSlippery(boolean enable) { + Window w = mLauncher.getWindow(); + WindowManager.LayoutParams wlp = w.getAttributes(); + if (enable) { + wlp.flags |= FLAG_SLIPPERY; + } else { + wlp.flags &= ~FLAG_SLIPPERY; + } + w.setAttributes(wlp); + } + private boolean canInterceptTouch(MotionEvent ev) { if (!mLauncher.isInState(LauncherState.NORMAL) || AbstractFloatingView.getTopOpenViewWithType(mLauncher, @@ -132,4 +166,4 @@ public class StatusBarTouchController implements TouchController { mSysUiProxy = RecentsModel.INSTANCE.get(mLauncher).getSystemUiProxy(); return mSysUiProxy != null; } -} +} \ No newline at end of file diff --git a/src/com/android/launcher3/touch/TouchEventTranslator.java b/src/com/android/launcher3/touch/TouchEventTranslator.java deleted file mode 100644 index 3fcda90848..0000000000 --- a/src/com/android/launcher3/touch/TouchEventTranslator.java +++ /dev/null @@ -1,283 +0,0 @@ -/* - * Copyright (C) 2018 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package com.android.launcher3.touch; - -import android.graphics.PointF; -import android.util.Log; -import android.util.Pair; -import android.util.SparseArray; -import android.view.MotionEvent; -import android.view.MotionEvent.PointerCoords; -import android.view.MotionEvent.PointerProperties; - -import java.util.function.Consumer; - -/** - * To minimize the size of the MotionEvent, historic events are not copied and passed via the - * listener. - */ -public class TouchEventTranslator { - - private static final String TAG = "TouchEventTranslator"; - private static final boolean DEBUG = false; - - private class DownState { - long timeStamp; - float downX; - float downY; - public DownState(long timeStamp, float downX, float downY) { - this.timeStamp = timeStamp; - this.downX = downX; - this.downY = downY; - } - }; - private final DownState ZERO = new DownState(0, 0f, 0f); - - private final Consumer mListener; - - private final SparseArray mDownEvents; - private final SparseArray mFingers; - - private final SparseArray> mCache; - - public TouchEventTranslator(Consumer listener) { - mDownEvents = new SparseArray<>(); - mFingers = new SparseArray<>(); - mCache = new SparseArray<>(); - - mListener = listener; - } - - public void reset() { - mDownEvents.clear(); - mFingers.clear(); - } - - public float getDownX() { - return mDownEvents.get(0).downX; - } - - public float getDownY() { - return mDownEvents.get(0).downY; - } - - public void setDownParameters(int idx, MotionEvent e) { - DownState ev = new DownState(e.getEventTime(), e.getX(idx), e.getY(idx)); - mDownEvents.append(idx, ev); - } - - public void dispatchDownEvents(MotionEvent ev) { - for(int i = 0; i < ev.getPointerCount() && i < mDownEvents.size(); i++) { - int pid = ev.getPointerId(i); - put(pid, i, ev.getX(i), 0, mDownEvents.get(i).timeStamp, ev); - } - } - - public void processMotionEvent(MotionEvent ev) { - if (DEBUG) { - printSamples(TAG + " processMotionEvent", ev); - } - int index = ev.getActionIndex(); - float x = ev.getX(index); - float y = ev.getY(index) - mDownEvents.get(index, ZERO).downY; - switch (ev.getActionMasked()) { - case MotionEvent.ACTION_POINTER_DOWN: - int pid = ev.getPointerId(index); - if(mFingers.get(pid, null) != null) { - for(int i=0; i < ev.getPointerCount(); i++) { - pid = ev.getPointerId(i); - position(pid, x, y); - } - generateEvent(ev.getAction(), ev); - } else { - put(pid, index, x, y, ev); - } - break; - case MotionEvent.ACTION_MOVE: - for(int i=0; i < ev.getPointerCount(); i++) { - pid = ev.getPointerId(i); - position(pid, x, y); - } - generateEvent(ev.getAction(), ev); - break; - case MotionEvent.ACTION_POINTER_UP: - case MotionEvent.ACTION_UP: - pid = ev.getPointerId(index); - lift(pid, index, x, y, ev); - break; - case MotionEvent.ACTION_CANCEL: - cancel(ev); - break; - default: - Log.v(TAG, "Didn't process "); - printSamples(TAG, ev); - - } - } - - private TouchEventTranslator put(int id, int index, float x, float y, MotionEvent ev) { - return put(id, index, x, y, ev.getEventTime(), ev); - } - - private TouchEventTranslator put(int id, int index, float x, float y, long ms, MotionEvent ev) { - checkFingerExistence(id, false); - boolean isInitialDown = (mFingers.size() == 0); - - mFingers.put(id, new PointF(x, y)); - int n = mFingers.size(); - - if (mCache.get(n) == null) { - PointerProperties[] properties = new PointerProperties[n]; - PointerCoords[] coords = new PointerCoords[n]; - for (int i = 0; i < n; i++) { - properties[i] = new PointerProperties(); - coords[i] = new PointerCoords(); - } - mCache.put(n, new Pair(properties, coords)); - } - - int action; - if (isInitialDown) { - action = MotionEvent.ACTION_DOWN; - } else { - action = MotionEvent.ACTION_POINTER_DOWN; - // Set the id of the changed pointer. - action |= index << MotionEvent.ACTION_POINTER_INDEX_SHIFT; - } - generateEvent(action, ms, ev); - return this; - } - - public TouchEventTranslator position(int id, float x, float y) { - checkFingerExistence(id, true); - mFingers.get(id).set(x, y); - return this; - } - - private TouchEventTranslator lift(int id, int index, MotionEvent ev) { - checkFingerExistence(id, true); - boolean isFinalUp = (mFingers.size() == 1); - int action; - if (isFinalUp) { - action = MotionEvent.ACTION_UP; - } else { - action = MotionEvent.ACTION_POINTER_UP; - // Set the id of the changed pointer. - action |= index << MotionEvent.ACTION_POINTER_INDEX_SHIFT; - } - generateEvent(action, ev); - mFingers.remove(id); - return this; - } - - private TouchEventTranslator lift(int id, int index, float x, float y, MotionEvent ev) { - checkFingerExistence(id, true); - mFingers.get(id).set(x, y); - return lift(id, index, ev); - } - - public TouchEventTranslator cancel(MotionEvent ev) { - generateEvent(MotionEvent.ACTION_CANCEL, ev); - mFingers.clear(); - return this; - } - - private void checkFingerExistence(int id, boolean shouldExist) { - if (shouldExist != (mFingers.get(id, null) != null)) { - throw new IllegalArgumentException( - shouldExist ? "Finger does not exist" : "Finger already exists"); - } - } - - - /** - * Used to debug MotionEvents being sent/received. - */ - public void printSamples(String msg, MotionEvent ev) { - System.out.printf("%s %s", msg, MotionEvent.actionToString(ev.getActionMasked())); - final int pointerCount = ev.getPointerCount(); - System.out.printf("#%d/%d", ev.getActionIndex(), pointerCount); - System.out.printf(" t=%d:", ev.getEventTime()); - for (int p = 0; p < pointerCount; p++) { - System.out.printf(" id=%d: (%f,%f)", - ev.getPointerId(p), ev.getX(p), ev.getY(p)); - } - System.out.println(); - } - - private void generateEvent(int action, MotionEvent ev) { - generateEvent(action, ev.getEventTime(), ev); - } - - private void generateEvent(int action, long ms, MotionEvent ev) { - Pair state = getFingerState(); - MotionEvent event = MotionEvent.obtain( - mDownEvents.get(0).timeStamp, - ms, - action, - state.first.length, - state.first, - state.second, - ev.getMetaState(), - ev.getButtonState() /* buttonState */, - ev.getXPrecision() /* xPrecision */, - ev.getYPrecision() /* yPrecision */, - ev.getDeviceId(), - ev.getEdgeFlags(), - ev.getSource(), - ev.getFlags() /* flags */); - if (DEBUG) { - printSamples(TAG + " generateEvent", event); - } - if (event.getPointerId(event.getActionIndex()) < 0) { - printSamples(TAG + "generateEvent", event); - throw new IllegalStateException(event.getActionIndex() + " not found in MotionEvent"); - } - mListener.accept(event); - event.recycle(); - } - - /** - * Returns the description of the fingers' state expected by MotionEvent. - */ - private Pair getFingerState() { - int nFingers = mFingers.size(); - - Pair result = mCache.get(nFingers); - PointerProperties[] properties = result.first; - PointerCoords[] coordinates = result.second; - - int index = 0; - for (int i = 0; i < mFingers.size(); i++) { - int id = mFingers.keyAt(i); - PointF location = mFingers.get(id); - - PointerProperties property = properties[i]; - property.id = id; - property.toolType = MotionEvent.TOOL_TYPE_FINGER; - properties[index] = property; - - PointerCoords coordinate = coordinates[i]; - coordinate.x = location.x; - coordinate.y = location.y; - coordinate.pressure = 1.0f; - coordinates[index] = coordinate; - - index++; - } - return mCache.get(nFingers); - } -} From 0b20a11d66b36980dd8e99bf9168f3e56cdc4aea Mon Sep 17 00:00:00 2001 From: vadimt Date: Wed, 26 Jun 2019 13:40:42 -0700 Subject: [PATCH 003/108] Converting even more tests to TAPL Bug: 131116002 Bug: 115582915 Change-Id: Id36fca232b5aff5f6692142ce4a0c937d0531f4e --- .../launcher3/ui/AbstractLauncherUiTest.java | 31 ----- .../launcher3/ui/TaplTestsLauncher3.java | 19 +-- .../android/launcher3/ui/TestViewHelpers.java | 114 ------------------ .../ui/widget/AddConfigWidgetTest.java | 16 +-- .../launcher3/ui/widget/AddWidgetTest.java | 32 ++--- .../android/launcher3/tapl/Launchable.java | 6 +- .../tapl/LauncherInstrumentation.java | 4 +- .../com/android/launcher3/tapl/Widget.java | 13 +- .../com/android/launcher3/tapl/Widgets.java | 29 +++++ 9 files changed, 62 insertions(+), 202 deletions(-) diff --git a/tests/src/com/android/launcher3/ui/AbstractLauncherUiTest.java b/tests/src/com/android/launcher3/ui/AbstractLauncherUiTest.java index 4a0ca5c245..abaad20b2a 100644 --- a/tests/src/com/android/launcher3/ui/AbstractLauncherUiTest.java +++ b/tests/src/com/android/launcher3/ui/AbstractLauncherUiTest.java @@ -20,7 +20,6 @@ import static androidx.test.InstrumentationRegistry.getInstrumentation; import static com.android.launcher3.ui.TaplTestsLauncher3.getAppPackageName; import static org.junit.Assert.assertTrue; -import static org.junit.Assert.fail; import static java.lang.System.exit; @@ -38,10 +37,7 @@ import android.util.Log; import androidx.test.InstrumentationRegistry; import androidx.test.uiautomator.By; -import androidx.test.uiautomator.BySelector; -import androidx.test.uiautomator.Direction; import androidx.test.uiautomator.UiDevice; -import androidx.test.uiautomator.UiObject2; import androidx.test.uiautomator.Until; import com.android.launcher3.Launcher; @@ -50,7 +46,6 @@ import com.android.launcher3.LauncherModel; import com.android.launcher3.LauncherSettings; import com.android.launcher3.LauncherState; import com.android.launcher3.MainThreadExecutor; -import com.android.launcher3.ResourceUtils; import com.android.launcher3.Utilities; import com.android.launcher3.compat.LauncherAppsCompat; import com.android.launcher3.model.AppLaunchTracker; @@ -86,7 +81,6 @@ public abstract class AbstractLauncherUiTest { public static final long DEFAULT_ACTIVITY_TIMEOUT = TimeUnit.SECONDS.toMillis(10); public static final long DEFAULT_BROADCAST_TIMEOUT_SECS = 5; - public static final long SHORT_UI_TIMEOUT = 300; public static final long DEFAULT_UI_TIMEOUT = 10000; private static final String TAG = "AbstractLauncherUiTest"; @@ -180,31 +174,6 @@ public abstract class AbstractLauncherUiTest { } } - /** - * Scrolls the {@param container} until it finds an object matching {@param condition}. - * - * @return the matching object. - */ - protected UiObject2 scrollAndFind(UiObject2 container, BySelector condition) { - final int margin = ResourceUtils.getNavbarSize( - ResourceUtils.NAVBAR_BOTTOM_GESTURE_SIZE, mLauncher.getResources()) + 1; - container.setGestureMargins(0, 0, 0, margin); - - int i = 0; - for (; ; ) { - // findObject can only execute after spring settles. - mDevice.wait(Until.findObject(condition), SHORT_UI_TIMEOUT); - UiObject2 widget = container.findObject(condition); - if (widget != null && widget.getVisibleBounds().intersects( - 0, 0, mDevice.getDisplayWidth(), - mDevice.getDisplayHeight() - margin)) { - return widget; - } - if (++i > 40) fail("Too many attempts"); - container.scroll(Direction.DOWN, 1f); - } - } - /** * Removes all icons from homescreen and hotseat. */ diff --git a/tests/src/com/android/launcher3/ui/TaplTestsLauncher3.java b/tests/src/com/android/launcher3/ui/TaplTestsLauncher3.java index c3168f812e..4dab44fadd 100644 --- a/tests/src/com/android/launcher3/ui/TaplTestsLauncher3.java +++ b/tests/src/com/android/launcher3/ui/TaplTestsLauncher3.java @@ -216,7 +216,8 @@ public class TaplTestsLauncher3 extends AbstractLauncherUiTest { final AppIcon app = allApps.getAppIcon("TestActivity7"); assertNotNull("AppIcon.launch returned null", app.launch(getAppPackageName())); test.executeOnLauncher(launcher -> assertTrue( - "Launcher activity is the top activity; expecting another activity to be the top " + "Launcher activity is the top activity; expecting another activity to be the " + + "top " + "one", test.isInBackground(launcher))); } finally { @@ -304,11 +305,8 @@ public class TaplTestsLauncher3 extends AbstractLauncherUiTest { switchToAllApps(); allApps.freeze(); try { - allApps. - getAppIcon(APP_NAME). - dragToWorkspace(). - getWorkspaceAppIcon(APP_NAME). - launch(getAppPackageName()); + allApps.getAppIcon(APP_NAME).dragToWorkspace(); + mLauncher.getWorkspace().getWorkspaceAppIcon(APP_NAME).launch(getAppPackageName()); } finally { allApps.unfreeze(); } @@ -335,13 +333,8 @@ public class TaplTestsLauncher3 extends AbstractLauncherUiTest { getMenuItem(0); final String shortcutName = menuItem.getText(); - // 4. Drag the first shortcut to the home screen. - // 5. Verify that the shortcut works on home screen - // (the app opens and has the same text as the shortcut). - menuItem. - dragToWorkspace(). - getWorkspaceAppIcon(shortcutName). - launch(getAppPackageName()); + menuItem.dragToWorkspace(); + mLauncher.getWorkspace().getWorkspaceAppIcon(shortcutName).launch(getAppPackageName()); } finally { allApps.unfreeze(); } diff --git a/tests/src/com/android/launcher3/ui/TestViewHelpers.java b/tests/src/com/android/launcher3/ui/TestViewHelpers.java index d13d319525..d0df66485e 100644 --- a/tests/src/com/android/launcher3/ui/TestViewHelpers.java +++ b/tests/src/com/android/launcher3/ui/TestViewHelpers.java @@ -18,28 +18,15 @@ package com.android.launcher3.ui; import static androidx.test.InstrumentationRegistry.getInstrumentation; import static androidx.test.InstrumentationRegistry.getTargetContext; -import static org.junit.Assert.assertNotNull; -import static org.junit.Assert.assertNull; - import android.content.ComponentName; -import android.content.Context; -import android.graphics.Point; import android.os.Process; -import android.os.SystemClock; import android.util.Log; -import android.view.KeyEvent; -import android.view.MotionEvent; import android.view.View; import android.view.ViewGroup; -import androidx.test.uiautomator.By; -import androidx.test.uiautomator.BySelector; import androidx.test.uiautomator.UiDevice; -import androidx.test.uiautomator.UiObject2; -import androidx.test.uiautomator.Until; import com.android.launcher3.LauncherAppWidgetProviderInfo; -import com.android.launcher3.R; import com.android.launcher3.compat.AppWidgetManagerCompat; import com.android.launcher3.testcomponent.AppWidgetNoConfig; import com.android.launcher3.testcomponent.AppWidgetWithConfig; @@ -50,21 +37,6 @@ import java.util.function.Function; public class TestViewHelpers { private static final String TAG = "TestViewHelpers"; - private static UiDevice getDevice() { - return UiDevice.getInstance(getInstrumentation()); - } - - public static UiObject2 findViewById(int id) { - return getDevice().wait(Until.findObject(getSelectorForId(id)), - AbstractLauncherUiTest.DEFAULT_UI_TIMEOUT); - } - - public static BySelector getSelectorForId(int id) { - final Context targetContext = getTargetContext(); - String name = targetContext.getResources().getResourceEntryName(id); - return By.res(targetContext.getPackageName(), name); - } - /** * Finds a widget provider which can fit on the home screen. * @@ -91,92 +63,6 @@ public class TestViewHelpers { return info; } - /** - * Drags an icon to the center of homescreen. - * - * @param icon object that is either app icon or shortcut icon - */ - public static void dragToWorkspace(UiObject2 icon, boolean expectedToShowShortcuts) { - Point center = icon.getVisibleCenter(); - - // Action Down - final long downTime = SystemClock.uptimeMillis(); - sendPointer(downTime, MotionEvent.ACTION_DOWN, center); - - UiObject2 dragLayer = findViewById(R.id.drag_layer); - - if (expectedToShowShortcuts) { - // Make sure shortcuts show up, and then move a bit to hide them. - assertNotNull(findViewById(R.id.deep_shortcuts_container)); - - Point moveLocation = new Point(center); - int distanceToMove = - getTargetContext().getResources().getDimensionPixelSize( - R.dimen.deep_shortcuts_start_drag_threshold) + 50; - if (moveLocation.y - distanceToMove >= dragLayer.getVisibleBounds().top) { - moveLocation.y -= distanceToMove; - } else { - moveLocation.y += distanceToMove; - } - movePointer(downTime, center, moveLocation); - - assertNull(findViewById(R.id.deep_shortcuts_container)); - } - - // Wait until Remove/Delete target is visible - assertNotNull(findViewById(R.id.delete_target_text)); - - Point moveLocation = dragLayer.getVisibleCenter(); - - // Move to center - movePointer(downTime, center, moveLocation); - sendPointer(downTime, MotionEvent.ACTION_UP, moveLocation); - - // Wait until remove target is gone. - getDevice().wait(Until.gone(getSelectorForId(R.id.delete_target_text)), - AbstractLauncherUiTest.DEFAULT_UI_TIMEOUT); - } - - private static void movePointer(long downTime, Point from, Point to) { - while (!from.equals(to)) { - try { - Thread.sleep(20); - } catch (InterruptedException e) { - e.printStackTrace(); - } - from.x = getNextMoveValue(to.x, from.x); - from.y = getNextMoveValue(to.y, from.y); - sendPointer(downTime, MotionEvent.ACTION_MOVE, from); - } - } - - private static int getNextMoveValue(int targetValue, int oldValue) { - if (targetValue - oldValue > 10) { - return oldValue + 10; - } else if (targetValue - oldValue < -10) { - return oldValue - 10; - } else { - return targetValue; - } - } - - public static void sendPointer(long downTime, int action, Point point) { - MotionEvent event = MotionEvent.obtain(downTime, - SystemClock.uptimeMillis(), action, point.x, point.y, 0); - getInstrumentation().sendPointerSync(event); - event.recycle(); - } - - /** - * Opens widget tray and returns the recycler view. - */ - public static UiObject2 openWidgetsTray() { - final UiDevice device = getDevice(); - device.pressKeyCode(KeyEvent.KEYCODE_W, KeyEvent.META_CTRL_ON); - device.waitForIdle(); - return findViewById(R.id.widgets_list_view); - } - public static View findChildView(ViewGroup parent, Function condition) { for (int i = 0; i < parent.getChildCount(); ++i) { final View child = parent.getChildAt(i); diff --git a/tests/src/com/android/launcher3/ui/widget/AddConfigWidgetTest.java b/tests/src/com/android/launcher3/ui/widget/AddConfigWidgetTest.java index 5eb5f19928..dc72bda9a3 100644 --- a/tests/src/com/android/launcher3/ui/widget/AddConfigWidgetTest.java +++ b/tests/src/com/android/launcher3/ui/widget/AddConfigWidgetTest.java @@ -27,20 +27,18 @@ import android.view.View; import androidx.test.filters.LargeTest; import androidx.test.runner.AndroidJUnit4; -import androidx.test.uiautomator.By; -import androidx.test.uiautomator.UiObject2; import com.android.launcher3.ItemInfo; import com.android.launcher3.LauncherAppWidgetInfo; import com.android.launcher3.LauncherAppWidgetProviderInfo; import com.android.launcher3.Workspace; +import com.android.launcher3.tapl.Widgets; import com.android.launcher3.testcomponent.WidgetConfigActivity; import com.android.launcher3.ui.AbstractLauncherUiTest; import com.android.launcher3.ui.TestViewHelpers; import com.android.launcher3.util.Condition; import com.android.launcher3.util.Wait; import com.android.launcher3.util.rule.ShellCommandRule; -import com.android.launcher3.widget.WidgetCell; import org.junit.Before; import org.junit.Ignore; @@ -71,7 +69,6 @@ public class AddConfigWidgetTest extends AbstractLauncherUiTest { } @Test - // Convert test to TAPL b/131116002 public void testWidgetConfig() throws Throwable { runTest(false, true); } @@ -83,7 +80,6 @@ public class AddConfigWidgetTest extends AbstractLauncherUiTest { } @Test - // Convert test to TAPL b/131116002 public void testConfigCancelled() throws Throwable { runTest(false, false); } @@ -104,15 +100,13 @@ public class AddConfigWidgetTest extends AbstractLauncherUiTest { clearHomescreen(); mActivityMonitor.startLauncher(); - // Open widget tray and wait for load complete. - final UiObject2 widgetContainer = TestViewHelpers.openWidgetsTray(); - Wait.atMost(null, Condition.minChildCount(widgetContainer, 2), DEFAULT_UI_TIMEOUT); + final Widgets widgets = mLauncher.getWorkspace().openAllWidgets(); // Drag widget to homescreen WidgetConfigStartupMonitor monitor = new WidgetConfigStartupMonitor(); - UiObject2 widget = scrollAndFind(widgetContainer, By.clazz(WidgetCell.class) - .hasDescendant(By.text(mWidgetInfo.getLabel(mTargetContext.getPackageManager())))); - TestViewHelpers.dragToWorkspace(widget, false); + widgets. + getWidget(mWidgetInfo.getLabel(mTargetContext.getPackageManager())). + dragToWorkspace(); // Widget id for which the config activity was opened mWidgetId = monitor.getWidgetId(); diff --git a/tests/src/com/android/launcher3/ui/widget/AddWidgetTest.java b/tests/src/com/android/launcher3/ui/widget/AddWidgetTest.java index 0061568cce..4529a80d1d 100644 --- a/tests/src/com/android/launcher3/ui/widget/AddWidgetTest.java +++ b/tests/src/com/android/launcher3/ui/widget/AddWidgetTest.java @@ -19,20 +19,12 @@ import static org.junit.Assert.assertTrue; import androidx.test.filters.LargeTest; import androidx.test.runner.AndroidJUnit4; -import androidx.test.uiautomator.By; -import androidx.test.uiautomator.UiObject2; -import android.view.View; -import com.android.launcher3.ItemInfo; import com.android.launcher3.LauncherAppWidgetInfo; import com.android.launcher3.LauncherAppWidgetProviderInfo; -import com.android.launcher3.Workspace.ItemOperator; import com.android.launcher3.ui.AbstractLauncherUiTest; import com.android.launcher3.ui.TestViewHelpers; -import com.android.launcher3.util.Condition; -import com.android.launcher3.util.Wait; import com.android.launcher3.util.rule.ShellCommandRule; -import com.android.launcher3.widget.WidgetCell; import org.junit.Ignore; import org.junit.Rule; @@ -61,7 +53,6 @@ public class AddWidgetTest extends AbstractLauncherUiTest { performTest(); } - // Convert to TAPL b/131116002 private void performTest() throws Throwable { clearHomescreen(); mActivityMonitor.startLauncher(); @@ -69,22 +60,15 @@ public class AddWidgetTest extends AbstractLauncherUiTest { final LauncherAppWidgetProviderInfo widgetInfo = TestViewHelpers.findWidgetProvider(this, false /* hasConfigureScreen */); - // Open widget tray and wait for load complete. - final UiObject2 widgetContainer = TestViewHelpers.openWidgetsTray(); - Wait.atMost(null, Condition.minChildCount(widgetContainer, 2), DEFAULT_UI_TIMEOUT); + mLauncher. + getWorkspace(). + openAllWidgets(). + getWidget(widgetInfo.getLabel(mTargetContext.getPackageManager())). + dragToWorkspace(); - // Drag widget to homescreen - UiObject2 widget = scrollAndFind(widgetContainer, By.clazz(WidgetCell.class) - .hasDescendant(By.text(widgetInfo.getLabel(mTargetContext.getPackageManager())))); - TestViewHelpers.dragToWorkspace(widget, false); - - assertTrue(mActivityMonitor.itemExists(new ItemOperator() { - @Override - public boolean evaluate(ItemInfo info, View view) { - return info instanceof LauncherAppWidgetInfo && + assertTrue(mActivityMonitor.itemExists( + (info, view) -> info instanceof LauncherAppWidgetInfo && ((LauncherAppWidgetInfo) info).providerName.getClassName().equals( - widgetInfo.provider.getClassName()); - } - }).call()); + widgetInfo.provider.getClassName())).call()); } } diff --git a/tests/tapl/com/android/launcher3/tapl/Launchable.java b/tests/tapl/com/android/launcher3/tapl/Launchable.java index d4bdafa764..04b8019450 100644 --- a/tests/tapl/com/android/launcher3/tapl/Launchable.java +++ b/tests/tapl/com/android/launcher3/tapl/Launchable.java @@ -68,7 +68,7 @@ abstract class Launchable { /** * Drags an object to the center of homescreen. */ - public Workspace dragToWorkspace() { + public void dragToWorkspace() { final Point launchableCenter = getObject().getVisibleCenter(); final Point displaySize = mLauncher.getRealDisplaySize(); final int width = displaySize.x / 2; @@ -80,10 +80,6 @@ abstract class Launchable { launchableCenter.x - width / 2 : launchableCenter.x + width / 2, displaySize.y / 2), getLongPressIndicator()); - try (LauncherInstrumentation.Closable c = mLauncher.addContextLayer( - "dragged launchable to workspace")) { - return new Workspace(mLauncher); - } } protected abstract String getLongPressIndicator(); diff --git a/tests/tapl/com/android/launcher3/tapl/LauncherInstrumentation.java b/tests/tapl/com/android/launcher3/tapl/LauncherInstrumentation.java index a7e6336199..1641d702d3 100644 --- a/tests/tapl/com/android/launcher3/tapl/LauncherInstrumentation.java +++ b/tests/tapl/com/android/launcher3/tapl/LauncherInstrumentation.java @@ -614,12 +614,12 @@ public final class LauncherInstrumentation { @NonNull UiObject2 waitForLauncherObject(BySelector selector) { - return waitForObjectBySelector(selector.pkg(getLauncherPackageName())); + return waitForObjectBySelector(By.copy(selector).pkg(getLauncherPackageName())); } @NonNull UiObject2 tryWaitForLauncherObject(BySelector selector, long timeout) { - return tryWaitForObjectBySelector(selector.pkg(getLauncherPackageName()), timeout); + return tryWaitForObjectBySelector(By.copy(selector).pkg(getLauncherPackageName()), timeout); } @NonNull diff --git a/tests/tapl/com/android/launcher3/tapl/Widget.java b/tests/tapl/com/android/launcher3/tapl/Widget.java index 128789dbc1..1b6d8c4a6e 100644 --- a/tests/tapl/com/android/launcher3/tapl/Widget.java +++ b/tests/tapl/com/android/launcher3/tapl/Widget.java @@ -18,7 +18,16 @@ package com.android.launcher3.tapl; import androidx.test.uiautomator.UiObject2; -public class Widget { - Widget(LauncherInstrumentation launcher, UiObject2 widget) { +/** + * Widget in workspace or a widget list. + */ +public final class Widget extends Launchable { + Widget(LauncherInstrumentation launcher, UiObject2 icon) { + super(launcher, icon); + } + + @Override + protected String getLongPressIndicator() { + return "drop_target_bar"; } } diff --git a/tests/tapl/com/android/launcher3/tapl/Widgets.java b/tests/tapl/com/android/launcher3/tapl/Widgets.java index 94003be919..2495933ac6 100644 --- a/tests/tapl/com/android/launcher3/tapl/Widgets.java +++ b/tests/tapl/com/android/launcher3/tapl/Widgets.java @@ -16,6 +16,12 @@ package com.android.launcher3.tapl; +import static org.junit.Assert.fail; + +import android.graphics.Point; + +import androidx.test.uiautomator.By; +import androidx.test.uiautomator.BySelector; import androidx.test.uiautomator.Direction; import androidx.test.uiautomator.UiObject2; @@ -75,4 +81,27 @@ public final class Widgets extends LauncherInstrumentation.VisibleContainer { protected LauncherInstrumentation.ContainerType getContainerType() { return LauncherInstrumentation.ContainerType.WIDGETS; } + + public Widget getWidget(String label) { + final int margin = ResourceUtils.getNavbarSize( + ResourceUtils.NAVBAR_BOTTOM_GESTURE_SIZE, mLauncher.getResources()) + 1; + final UiObject2 widgetsContainer = verifyActiveContainer(); + widgetsContainer.setGestureMargins(0, 0, 0, margin); + + final Point displaySize = mLauncher.getRealDisplaySize(); + + int i = 0; + final BySelector selector = By. + clazz("com.android.launcher3.widget.WidgetCell"). + hasDescendant(By.text(label)); + + for (; ; ) { + final UiObject2 widget = mLauncher.tryWaitForLauncherObject(selector, 300); + if (widget != null && widget.getVisibleBounds().bottom <= displaySize.y - margin) { + return new Widget(mLauncher, widget); + } + if (++i > 40) fail("Too many attempts"); + widgetsContainer.scroll(Direction.DOWN, 1f); + } + } } From e8a72681163c9eca77608f030a14b1711e469b9d Mon Sep 17 00:00:00 2001 From: vadimt Date: Thu, 27 Jun 2019 11:57:30 -0700 Subject: [PATCH 004/108] Tapl: diagnosing anomalies Bug: 133891845 Change-Id: I7e5afbdec580c6659917aa3e9586930d5f55ea51 --- .../tapl/LauncherInstrumentation.java | 20 +++++++++++++++++-- 1 file changed, 18 insertions(+), 2 deletions(-) diff --git a/tests/tapl/com/android/launcher3/tapl/LauncherInstrumentation.java b/tests/tapl/com/android/launcher3/tapl/LauncherInstrumentation.java index a7e6336199..40ab90a47e 100644 --- a/tests/tapl/com/android/launcher3/tapl/LauncherInstrumentation.java +++ b/tests/tapl/com/android/launcher3/tapl/LauncherInstrumentation.java @@ -263,10 +263,26 @@ public final class LauncherInstrumentation { } } + private String getAnomalyMessage() { + final UiObject2 object = mDevice.findObject(By.res("android", "alertTitle")); + if (object != null) { + return "System alert popup is visible: " + object.getText(); + } + + if (!mDevice.hasObject(By.textStartsWith(""))) return "Screen is empty"; + + return null; + } + private void fail(String message) { - log("Hierarchy dump for: " + getContextDescription() + message); + message = "http://go/tapl : " + getContextDescription() + message; + + final String anomaly = getAnomalyMessage(); + if (anomaly != null) message = anomaly + ", which causes:\n" + message; + + log("Hierarchy dump for: " + message); dumpViewHierarchy(); - Assert.fail("http://go/tapl : " + getContextDescription() + message); + Assert.fail(message); } private String getContextDescription() { From bd31868ea7d73d85584b3505b8416410a2c28325 Mon Sep 17 00:00:00 2001 From: vadimt Date: Thu, 27 Jun 2019 14:52:41 -0700 Subject: [PATCH 005/108] Adding system health diags for OOP tests Bug: 133891845 Change-Id: I24aa2b1408b3ffe4105cd4a7892c8b5fec8740e1 --- tests/tapl/AndroidManifest.xml | 2 + .../tapl/LauncherInstrumentation.java | 83 +++++++++++++++++++ 2 files changed, 85 insertions(+) diff --git a/tests/tapl/AndroidManifest.xml b/tests/tapl/AndroidManifest.xml index 0207e2be6f..1065446827 100644 --- a/tests/tapl/AndroidManifest.xml +++ b/tests/tapl/AndroidManifest.xml @@ -23,4 +23,6 @@ > + + diff --git a/tests/tapl/com/android/launcher3/tapl/LauncherInstrumentation.java b/tests/tapl/com/android/launcher3/tapl/LauncherInstrumentation.java index c613ed5f33..55ccb1c07e 100644 --- a/tests/tapl/com/android/launcher3/tapl/LauncherInstrumentation.java +++ b/tests/tapl/com/android/launcher3/tapl/LauncherInstrumentation.java @@ -39,6 +39,7 @@ import android.graphics.Rect; import android.net.Uri; import android.os.Build; import android.os.Bundle; +import android.os.DropBoxManager; import android.os.Parcelable; import android.os.SystemClock; import android.text.TextUtils; @@ -274,14 +275,96 @@ public final class LauncherInstrumentation { return null; } + private static String truncateCrash(String text, int maxLines) { + String[] lines = text.split("\\r?\\n"); + StringBuilder ret = new StringBuilder(); + for (int i = 0; i < maxLines && i < lines.length; i++) { + ret.append(lines[i]); + ret.append('\n'); + } + if (lines.length > maxLines) { + ret.append("... "); + ret.append(lines.length - maxLines); + ret.append(" more lines truncated ...\n"); + } + return ret.toString(); + } + + private String checkCrash(String label) { + DropBoxManager dropbox = (DropBoxManager) getContext().getSystemService( + Context.DROPBOX_SERVICE); + Assert.assertNotNull("Unable access the DropBoxManager service", dropbox); + + long timestamp = 0; + DropBoxManager.Entry entry; + int crashCount = 0; + StringBuilder errorDetails = new StringBuilder(); + while (null != (entry = dropbox.getNextEntry(label, timestamp))) { + String dropboxSnippet; + try { + dropboxSnippet = entry.getText(4096); + } finally { + entry.close(); + } + + crashCount++; + errorDetails.append(label); + errorDetails.append(": "); + errorDetails.append(truncateCrash(dropboxSnippet, 40)); + errorDetails.append(" ...\n"); + + timestamp = entry.getTimeMillis(); + } + Assert.assertEquals(errorDetails.toString(), 0, crashCount); + return crashCount > 0 ? errorDetails.toString() : null; + } + + private String getSystemHealthMessage() { + try { + StringBuilder errors = new StringBuilder(); + + final String testPackage = getContext().getPackageName(); + try { + mDevice.executeShellCommand("pm grant " + testPackage + + " android.permission.READ_LOGS"); + mDevice.executeShellCommand("pm grant " + testPackage + + " android.permission.PACKAGE_USAGE_STATS"); + } catch (IOException e) { + e.printStackTrace(); + } + + final String[] labels = { + "system_server_crash", + "system_server_native_crash", + "system_server_anr", + }; + + for (String label : labels) { + final String crash = checkCrash(label); + if (crash != null) errors.append(crash); + } + + return errors.length() != 0 ? errors.toString() : null; + } catch (Exception e) { + return null; + } + } + private void fail(String message) { message = "http://go/tapl : " + getContextDescription() + message; final String anomaly = getAnomalyMessage(); if (anomaly != null) message = anomaly + ", which causes:\n" + message; + final String systemHealth = getSystemHealthMessage(); + if (systemHealth != null) { + message = message + ", which might be a consequence of system health problems:\n<<<\n" + + systemHealth + "\n>>>"; + } + log("Hierarchy dump for: " + message); dumpViewHierarchy(); + Assert.fail(message); } From 73ed3e432ce74912828b5444ed469b49260ef6ca Mon Sep 17 00:00:00 2001 From: vadimt Date: Thu, 27 Jun 2019 19:03:33 -0700 Subject: [PATCH 006/108] Adding tracing for a bug about missing input events Bug: 136215685 Change-Id: I1e735c1e787710ae37b7c7d1a6a06498edd7c525 --- .../src/com/android/quickstep/TouchInteractionService.java | 4 ++++ .../quickstep/inputconsumers/OverviewInputConsumer.java | 5 +++++ src/com/android/launcher3/testing/TestProtocol.java | 1 + src/com/android/launcher3/views/BaseDragLayer.java | 6 ++++++ 4 files changed, 16 insertions(+) diff --git a/quickstep/recents_ui_overrides/src/com/android/quickstep/TouchInteractionService.java b/quickstep/recents_ui_overrides/src/com/android/quickstep/TouchInteractionService.java index 53da0f92dd..9353c04b58 100644 --- a/quickstep/recents_ui_overrides/src/com/android/quickstep/TouchInteractionService.java +++ b/quickstep/recents_ui_overrides/src/com/android/quickstep/TouchInteractionService.java @@ -74,6 +74,7 @@ import com.android.launcher3.Utilities; import com.android.launcher3.compat.UserManagerCompat; import com.android.launcher3.logging.EventLogArray; import com.android.launcher3.logging.UserEventDispatcher; +import com.android.launcher3.testing.TestProtocol; import com.android.launcher3.util.LooperExecutor; import com.android.launcher3.util.UiThreadHelper; import com.android.quickstep.SysUINavigationMode.Mode; @@ -502,6 +503,9 @@ public class TouchInteractionService extends Service implements } private void onInputEvent(InputEvent ev) { + if (TestProtocol.sDebugTracing) { + Log.d(TestProtocol.EVENTS_TO_OVERVIEW_MISSING_TAG, "onInputEvent " + ev); + } if (!(ev instanceof MotionEvent)) { Log.e(TAG, "Unknown event " + ev); return; diff --git a/quickstep/recents_ui_overrides/src/com/android/quickstep/inputconsumers/OverviewInputConsumer.java b/quickstep/recents_ui_overrides/src/com/android/quickstep/inputconsumers/OverviewInputConsumer.java index 56db2095fe..f2e53bb18c 100644 --- a/quickstep/recents_ui_overrides/src/com/android/quickstep/inputconsumers/OverviewInputConsumer.java +++ b/quickstep/recents_ui_overrides/src/com/android/quickstep/inputconsumers/OverviewInputConsumer.java @@ -19,6 +19,7 @@ import static com.android.launcher3.config.FeatureFlags.ENABLE_QUICKSTEP_LIVE_TI import static com.android.quickstep.TouchInteractionService.TOUCH_INTERACTION_LOG; import static com.android.systemui.shared.system.ActivityManagerWrapper.CLOSE_SYSTEM_WINDOWS_REASON_RECENTS; +import android.util.Log; import android.view.KeyEvent; import android.view.MotionEvent; @@ -26,6 +27,7 @@ import androidx.annotation.Nullable; import com.android.launcher3.BaseDraggingActivity; import com.android.launcher3.Utilities; +import com.android.launcher3.testing.TestProtocol; import com.android.launcher3.views.BaseDragLayer; import com.android.quickstep.OverviewCallbacks; import com.android.systemui.shared.system.ActivityManagerWrapper; @@ -80,6 +82,9 @@ public class OverviewInputConsumer @Override public void onMotionEvent(MotionEvent ev) { + if (TestProtocol.sDebugTracing) { + Log.d(TestProtocol.EVENTS_TO_OVERVIEW_MISSING_TAG, "onMotionEvent " + ev); + } if (!mProxyTouch) { return; } diff --git a/src/com/android/launcher3/testing/TestProtocol.java b/src/com/android/launcher3/testing/TestProtocol.java index 6ffc2d9cd1..3774042c93 100644 --- a/src/com/android/launcher3/testing/TestProtocol.java +++ b/src/com/android/launcher3/testing/TestProtocol.java @@ -78,4 +78,5 @@ public final class TestProtocol { public static final String NO_START_TAG = "b/132900132"; public static final String NO_START_TASK_TAG = "b/133765434"; public static final String NO_OVERVIEW_EVENT_TAG = "b/134532571"; + public static final String EVENTS_TO_OVERVIEW_MISSING_TAG = "b/133867119"; } diff --git a/src/com/android/launcher3/views/BaseDragLayer.java b/src/com/android/launcher3/views/BaseDragLayer.java index c1ba780503..53686cae48 100644 --- a/src/com/android/launcher3/views/BaseDragLayer.java +++ b/src/com/android/launcher3/views/BaseDragLayer.java @@ -152,6 +152,9 @@ public abstract class BaseDragLayer } private TouchController findControllerToHandleTouch(MotionEvent ev) { + if (TestProtocol.sDebugTracing) { + Log.d(TestProtocol.EVENTS_TO_OVERVIEW_MISSING_TAG, "findControllerToHandleTouch " + ev); + } if (shouldDisableGestures(ev)) return null; AbstractFloatingView topView = AbstractFloatingView.getTopOpenView(mActivity); @@ -314,6 +317,9 @@ public abstract class BaseDragLayer * Proxies the touch events to the gesture handlers */ public boolean proxyTouchEvent(MotionEvent ev) { + if (TestProtocol.sDebugTracing) { + Log.d(TestProtocol.EVENTS_TO_OVERVIEW_MISSING_TAG, "proxyTouchEvent " + ev); + } boolean handled; if (mProxyTouchController != null) { handled = mProxyTouchController.onControllerTouchEvent(ev); From 83d5eef5a545f386bae0ed4541f27bec4d2bf4eb Mon Sep 17 00:00:00 2001 From: vadimt Date: Fri, 28 Jun 2019 13:12:58 -0700 Subject: [PATCH 007/108] Temporary workarounds to make tests pass on a virtual device Bug: 136278866 Change-Id: I198cb4cdf94c2b1151b4b7249ae10dbcaa99a4fd --- .../android/quickstep/DigitalWellBeingToastTest.java | 2 +- .../quickstep/StartLauncherViaGestureTests.java | 5 +++++ .../android/launcher3/ui/AbstractLauncherUiTest.java | 2 +- .../launcher3/tapl/LauncherInstrumentation.java | 11 +++++++++++ 4 files changed, 18 insertions(+), 2 deletions(-) diff --git a/quickstep/tests/src/com/android/quickstep/DigitalWellBeingToastTest.java b/quickstep/tests/src/com/android/quickstep/DigitalWellBeingToastTest.java index 0c5a6f5b6e..ec3d49afad 100644 --- a/quickstep/tests/src/com/android/quickstep/DigitalWellBeingToastTest.java +++ b/quickstep/tests/src/com/android/quickstep/DigitalWellBeingToastTest.java @@ -51,7 +51,7 @@ public class DigitalWellBeingToastTest extends AbstractQuickStepTest { mLauncher.pressHome(); final DigitalWellBeingToast toast = getToast(); - assertTrue("Toast is not visible", toast.hasLimit()); + waitForLauncherCondition("Toast is not visible", launcher -> toast.hasLimit()); assertEquals("Toast text: ", "5 minutes left today", toast.getText()); // Unset time limit for app. diff --git a/quickstep/tests/src/com/android/quickstep/StartLauncherViaGestureTests.java b/quickstep/tests/src/com/android/quickstep/StartLauncherViaGestureTests.java index 2111e2ca27..c5b560c3fc 100644 --- a/quickstep/tests/src/com/android/quickstep/StartLauncherViaGestureTests.java +++ b/quickstep/tests/src/com/android/quickstep/StartLauncherViaGestureTests.java @@ -25,6 +25,7 @@ import androidx.test.filters.LargeTest; import androidx.test.runner.AndroidJUnit4; import com.android.launcher3.Launcher; +import com.android.launcher3.tapl.LauncherInstrumentation; import com.android.launcher3.util.RaceConditionReproducer; import com.android.quickstep.NavigationModeSwitchRule.Mode; import com.android.quickstep.NavigationModeSwitchRule.NavigationModeSwitch; @@ -79,6 +80,8 @@ public class StartLauncherViaGestureTests extends AbstractQuickStepTest { @Test @NavigationModeSwitch public void testStressPressHome() { + if (LauncherInstrumentation.isAvd()) return; // b/136278866 + for (int i = 0; i < STRESS_REPEAT_COUNT; ++i) { // Destroy Launcher activity. closeLauncherActivity(); @@ -91,6 +94,8 @@ public class StartLauncherViaGestureTests extends AbstractQuickStepTest { @Test @NavigationModeSwitch public void testStressSwipeToOverview() { + if (LauncherInstrumentation.isAvd()) return; // b/136278866 + for (int i = 0; i < STRESS_REPEAT_COUNT; ++i) { // Destroy Launcher activity. closeLauncherActivity(); diff --git a/tests/src/com/android/launcher3/ui/AbstractLauncherUiTest.java b/tests/src/com/android/launcher3/ui/AbstractLauncherUiTest.java index abaad20b2a..c03c182b4c 100644 --- a/tests/src/com/android/launcher3/ui/AbstractLauncherUiTest.java +++ b/tests/src/com/android/launcher3/ui/AbstractLauncherUiTest.java @@ -81,7 +81,7 @@ public abstract class AbstractLauncherUiTest { public static final long DEFAULT_ACTIVITY_TIMEOUT = TimeUnit.SECONDS.toMillis(10); public static final long DEFAULT_BROADCAST_TIMEOUT_SECS = 5; - public static final long DEFAULT_UI_TIMEOUT = 10000; + public static final long DEFAULT_UI_TIMEOUT = 60000; // b/136278866 private static final String TAG = "AbstractLauncherUiTest"; protected MainThreadExecutor mMainThreadExecutor = new MainThreadExecutor(); diff --git a/tests/tapl/com/android/launcher3/tapl/LauncherInstrumentation.java b/tests/tapl/com/android/launcher3/tapl/LauncherInstrumentation.java index 55ccb1c07e..2cda7b7664 100644 --- a/tests/tapl/com/android/launcher3/tapl/LauncherInstrumentation.java +++ b/tests/tapl/com/android/launcher3/tapl/LauncherInstrumentation.java @@ -432,6 +432,17 @@ public final class LauncherInstrumentation { private UiObject2 verifyContainerType(ContainerType containerType) { assertEquals("Unexpected display rotation", mExpectedRotation, mDevice.getDisplayRotation()); + + // b/136278866 + for (int i = 0; i != 100; ++i) { + if (getNavigationModeMismatchError() == null) break; + try { + Thread.sleep(100); + } catch (InterruptedException e) { + e.printStackTrace(); + } + } + final String error = getNavigationModeMismatchError(); assertTrue(error, error == null); log("verifyContainerType: " + containerType); From 615b823c942121ad7601cdbf78311ec5f6f5415b Mon Sep 17 00:00:00 2001 From: vadimt Date: Fri, 28 Jun 2019 13:57:12 -0700 Subject: [PATCH 008/108] Enable debug tracing for AllApps.flingBackward Bug: 136280872 Change-Id: I128ee7b0f9c131fd102fce9d81d29fdcb4e8727d --- tests/tapl/com/android/launcher3/tapl/AllApps.java | 2 ++ 1 file changed, 2 insertions(+) diff --git a/tests/tapl/com/android/launcher3/tapl/AllApps.java b/tests/tapl/com/android/launcher3/tapl/AllApps.java index 9ff354a7eb..0ac5e9f887 100644 --- a/tests/tapl/com/android/launcher3/tapl/AllApps.java +++ b/tests/tapl/com/android/launcher3/tapl/AllApps.java @@ -181,6 +181,7 @@ public class AllApps extends LauncherInstrumentation.VisibleContainer { * Flings backward (up) and waits the fling's end. */ public void flingBackward() { + mLauncher.getTestInfo(TestProtocol.REQUEST_ENABLE_DEBUG_TRACING); try (LauncherInstrumentation.Closable c = mLauncher.addContextLayer("want to fling backward in all apps")) { final UiObject2 allAppsContainer = verifyActiveContainer(); @@ -189,6 +190,7 @@ public class AllApps extends LauncherInstrumentation.VisibleContainer { allAppsContainer, Direction.UP, 1, new Rect(0, mHeight / 2, 0, 0), 10); verifyActiveContainer(); } + mLauncher.getTestInfo(TestProtocol.REQUEST_DISABLE_DEBUG_TRACING); } /** From 881a31560d79c1fa963c8c9d129cc89f1456cd60 Mon Sep 17 00:00:00 2001 From: vadimt Date: Fri, 28 Jun 2019 14:19:22 -0700 Subject: [PATCH 009/108] Diagnosing launcher visible state in TAPL Bug: 133891845 Change-Id: Ibdd959f50668fd6eeb5e48dacc370a054057b7fc --- .../launcher3/tapl/LauncherInstrumentation.java | 16 +++++++++++++++- 1 file changed, 15 insertions(+), 1 deletion(-) diff --git a/tests/tapl/com/android/launcher3/tapl/LauncherInstrumentation.java b/tests/tapl/com/android/launcher3/tapl/LauncherInstrumentation.java index 55ccb1c07e..22be594851 100644 --- a/tests/tapl/com/android/launcher3/tapl/LauncherInstrumentation.java +++ b/tests/tapl/com/android/launcher3/tapl/LauncherInstrumentation.java @@ -270,11 +270,21 @@ public final class LauncherInstrumentation { return "System alert popup is visible: " + object.getText(); } + if (hasSystemUiObject("keyguard_status_view")) return "Phone is locked"; + if (!mDevice.hasObject(By.textStartsWith(""))) return "Screen is empty"; return null; } + private String getVisibleStateMessage() { + if (hasLauncherObject(WIDGETS_RES_ID)) return "Widgets"; + if (hasLauncherObject(OVERVIEW_RES_ID)) return "Overview"; + if (hasLauncherObject(WORKSPACE_RES_ID)) return "Workspace"; + if (hasLauncherObject(APPS_RES_ID)) return "AllApps"; + return "Background"; + } + private static String truncateCrash(String text, int maxLines) { String[] lines = text.split("\\r?\\n"); StringBuilder ret = new StringBuilder(); @@ -354,7 +364,11 @@ public final class LauncherInstrumentation { message = "http://go/tapl : " + getContextDescription() + message; final String anomaly = getAnomalyMessage(); - if (anomaly != null) message = anomaly + ", which causes:\n" + message; + if (anomaly != null) { + message = anomaly + ", which causes:\n" + message; + } else { + message = message + " (visible state: " + getVisibleStateMessage() + ")"; + } final String systemHealth = getSystemHealthMessage(); if (systemHealth != null) { From 4770e241c997557e1051bc77dd4727d474d900de Mon Sep 17 00:00:00 2001 From: Hyunyoung Song Date: Fri, 28 Jun 2019 16:09:26 -0700 Subject: [PATCH 010/108] Enable swipe down to open shade for non userdebug population Bug: 131356741 Change-Id: I74c682d39c70f785777b5a0804b31a0cc2369759 --- .../src/com/android/launcher3/uioverrides/RecentsUiFactory.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/quickstep/recents_ui_overrides/src/com/android/launcher3/uioverrides/RecentsUiFactory.java b/quickstep/recents_ui_overrides/src/com/android/launcher3/uioverrides/RecentsUiFactory.java index 8d5ac50942..8aecaf04e2 100644 --- a/quickstep/recents_ui_overrides/src/com/android/launcher3/uioverrides/RecentsUiFactory.java +++ b/quickstep/recents_ui_overrides/src/com/android/launcher3/uioverrides/RecentsUiFactory.java @@ -163,7 +163,7 @@ public abstract class RecentsUiFactory { } } - if (FeatureFlags.PULL_DOWN_STATUS_BAR && Utilities.IS_DEBUG_DEVICE + if (FeatureFlags.PULL_DOWN_STATUS_BAR && !launcher.getDeviceProfile().isMultiWindowMode && !launcher.getDeviceProfile().isVerticalBarLayout()) { list.add(new StatusBarTouchController(launcher)); From e7a786ee969e6b4a5822087841fbaf73f66aa9c3 Mon Sep 17 00:00:00 2001 From: vadimt Date: Fri, 28 Jun 2019 12:04:36 -0700 Subject: [PATCH 011/108] Tests: Waiting for package-restart events when restarting Launcher Bug: 136215685 Change-Id: Ia947994399220544c90bfc077437fc639e635a33 --- .../launcher3/ui/AbstractLauncherUiTest.java | 22 +++++++++++++++++-- 1 file changed, 20 insertions(+), 2 deletions(-) diff --git a/tests/src/com/android/launcher3/ui/AbstractLauncherUiTest.java b/tests/src/com/android/launcher3/ui/AbstractLauncherUiTest.java index c03c182b4c..e39fc76a0b 100644 --- a/tests/src/com/android/launcher3/ui/AbstractLauncherUiTest.java +++ b/tests/src/com/android/launcher3/ui/AbstractLauncherUiTest.java @@ -51,6 +51,7 @@ import com.android.launcher3.compat.LauncherAppsCompat; import com.android.launcher3.model.AppLaunchTracker; import com.android.launcher3.tapl.LauncherInstrumentation; import com.android.launcher3.tapl.TestHelpers; +import com.android.launcher3.util.PackageManagerHelper; import com.android.launcher3.util.Wait; import com.android.launcher3.util.rule.FailureWatcher; import com.android.launcher3.util.rule.LauncherActivityRule; @@ -110,6 +111,23 @@ public abstract class AbstractLauncherUiTest { public ShellCommandRule mDisableHeadsUpNotification = ShellCommandRule.disableHeadsUpNotification(); + protected void clearPackageData(String pkg) throws IOException, InterruptedException { + final CountDownLatch count = new CountDownLatch(2); + final BroadcastReceiver broadcastReceiver = new BroadcastReceiver() { + @Override + public void onReceive(Context context, Intent intent) { + count.countDown(); + } + }; + mTargetContext.registerReceiver(broadcastReceiver, + PackageManagerHelper.getPackageFilter(pkg, + Intent.ACTION_PACKAGE_RESTARTED, Intent.ACTION_PACKAGE_DATA_CLEARED)); + + mDevice.executeShellCommand("pm clear " + pkg); + assertTrue(pkg + " didn't restart", count.await(10, TimeUnit.SECONDS)); + mTargetContext.unregisterReceiver(broadcastReceiver); + } + // Annotation for tests that need to be run in portrait and landscape modes. @Retention(RetentionPolicy.RUNTIME) @Target(ElementType.METHOD) @@ -164,13 +182,13 @@ public abstract class AbstractLauncherUiTest { } } - protected void clearLauncherData() throws IOException { + protected void clearLauncherData() throws IOException, InterruptedException { if (TestHelpers.isInLauncherProcess()) { LauncherSettings.Settings.call(mTargetContext.getContentResolver(), LauncherSettings.Settings.METHOD_CREATE_EMPTY_DB); resetLoaderState(); } else { - mDevice.executeShellCommand("pm clear " + mDevice.getLauncherPackageName()); + clearPackageData(mDevice.getLauncherPackageName()); } } From f5e81122a0ce8bb438a7bed199beac5ce16d9d43 Mon Sep 17 00:00:00 2001 From: Winson Chung Date: Fri, 28 Jun 2019 23:31:24 +0000 Subject: [PATCH 012/108] Revert "Revert "Enable FLAG_SLIPPERY window flag when swipe down on workspace"" This reverts commit c4c8b3c69597ac5fdd0c29124cb1e5fb70873a55. Reason for revert: Re-enabling for R1 Change-Id: Id6706c548dcc9debbfaf2069164636bc22aa9b5e --- .../StatusBarTouchController.java | 68 +++-- .../launcher3/touch/TouchEventTranslator.java | 283 ------------------ 2 files changed, 51 insertions(+), 300 deletions(-) delete mode 100644 src/com/android/launcher3/touch/TouchEventTranslator.java diff --git a/quickstep/src/com/android/launcher3/uioverrides/touchcontrollers/StatusBarTouchController.java b/quickstep/src/com/android/launcher3/uioverrides/touchcontrollers/StatusBarTouchController.java index fee18204ea..f5ba3725df 100644 --- a/quickstep/src/com/android/launcher3/uioverrides/touchcontrollers/StatusBarTouchController.java +++ b/quickstep/src/com/android/launcher3/uioverrides/touchcontrollers/StatusBarTouchController.java @@ -17,17 +17,22 @@ package com.android.launcher3.uioverrides.touchcontrollers; import static android.view.MotionEvent.ACTION_DOWN; import static android.view.MotionEvent.ACTION_MOVE; +import static android.view.MotionEvent.ACTION_UP; +import static android.view.MotionEvent.ACTION_CANCEL; +import android.graphics.PointF; import android.os.RemoteException; import android.util.Log; +import android.util.SparseArray; import android.view.MotionEvent; import android.view.ViewConfiguration; +import android.view.Window; +import android.view.WindowManager; import com.android.launcher3.AbstractFloatingView; import com.android.launcher3.DeviceProfile; import com.android.launcher3.Launcher; import com.android.launcher3.LauncherState; -import com.android.launcher3.touch.TouchEventTranslator; import com.android.launcher3.util.TouchController; import com.android.quickstep.RecentsModel; import com.android.systemui.shared.recents.ISystemUiProxy; @@ -36,18 +41,29 @@ import java.io.PrintWriter; /** * TouchController for handling touch events that get sent to the StatusBar. Once the - * Once the event delta y passes the touch slop, the events start getting forwarded. + * Once the event delta mDownY passes the touch slop, the events start getting forwarded. * All events are offset by initial Y value of the pointer. */ public class StatusBarTouchController implements TouchController { private static final String TAG = "StatusBarController"; + /** + * Window flag: Enable touches to slide out of a window into neighboring + * windows in mid-gesture instead of being captured for the duration of + * the gesture. + * + * This flag changes the behavior of touch focus for this window only. + * Touches can slide out of the window but they cannot necessarily slide + * back in (unless the other window with touch focus permits it). + */ + private static final int FLAG_SLIPPERY = 0x20000000; + protected final Launcher mLauncher; - protected final TouchEventTranslator mTranslator; private final float mTouchSlop; private ISystemUiProxy mSysUiProxy; private int mLastAction; + private final SparseArray mDownEvents; /* If {@code false}, this controller should not handle the input {@link MotionEvent}.*/ private boolean mCanIntercept; @@ -56,7 +72,7 @@ public class StatusBarTouchController implements TouchController { mLauncher = l; // Guard against TAPs by increasing the touch slop. mTouchSlop = 2 * ViewConfiguration.get(l).getScaledTouchSlop(); - mTranslator = new TouchEventTranslator((MotionEvent ev)-> dispatchTouchEvent(ev)); + mDownEvents = new SparseArray<>(); } @Override @@ -64,7 +80,6 @@ public class StatusBarTouchController implements TouchController { writer.println(prefix + "mCanIntercept:" + mCanIntercept); writer.println(prefix + "mLastAction:" + MotionEvent.actionToString(mLastAction)); writer.println(prefix + "mSysUiProxy available:" + (mSysUiProxy != null)); - } private void dispatchTouchEvent(MotionEvent ev) { @@ -81,26 +96,31 @@ public class StatusBarTouchController implements TouchController { @Override public final boolean onControllerInterceptTouchEvent(MotionEvent ev) { int action = ev.getActionMasked(); + int idx = ev.getActionIndex(); + int pid = ev.getPointerId(idx); if (action == ACTION_DOWN) { mCanIntercept = canInterceptTouch(ev); if (!mCanIntercept) { return false; } - mTranslator.reset(); - mTranslator.setDownParameters(0, ev); + mDownEvents.put(pid, new PointF(ev.getX(), ev.getY())); } else if (ev.getActionMasked() == MotionEvent.ACTION_POINTER_DOWN) { - // Check!! should only set it only when threshold is not entered. - mTranslator.setDownParameters(ev.getActionIndex(), ev); + // Check!! should only set it only when threshold is not entered. + mDownEvents.put(pid, new PointF(ev.getX(idx), ev.getY(idx))); } if (!mCanIntercept) { return false; } if (action == ACTION_MOVE) { - float dy = ev.getY() - mTranslator.getDownY(); - float dx = ev.getX() - mTranslator.getDownX(); - if (dy > mTouchSlop && dy > Math.abs(dx)) { - mTranslator.dispatchDownEvents(ev); - mTranslator.processMotionEvent(ev); + float dy = ev.getY(idx) - mDownEvents.get(pid).y; + float dx = ev.getX(idx) - mDownEvents.get(pid).x; + // Currently input dispatcher will not do touch transfer if there are more than + // one touch pointer. Hence, even if slope passed, only set the slippery flag + // when there is single touch event. (context: InputDispatcher.cpp line 1445) + if (dy > mTouchSlop && dy > Math.abs(dx) && ev.getPointerCount() == 1) { + ev.setAction(ACTION_DOWN); + dispatchTouchEvent(ev); + setWindowSlippery(true); return true; } if (Math.abs(dx) > mTouchSlop) { @@ -110,13 +130,27 @@ public class StatusBarTouchController implements TouchController { return false; } - @Override public final boolean onControllerTouchEvent(MotionEvent ev) { - mTranslator.processMotionEvent(ev); + if (ev.getAction() == ACTION_UP || ev.getAction() == ACTION_CANCEL) { + dispatchTouchEvent(ev); + setWindowSlippery(false); + return true; + } return true; } + private void setWindowSlippery(boolean enable) { + Window w = mLauncher.getWindow(); + WindowManager.LayoutParams wlp = w.getAttributes(); + if (enable) { + wlp.flags |= FLAG_SLIPPERY; + } else { + wlp.flags &= ~FLAG_SLIPPERY; + } + w.setAttributes(wlp); + } + private boolean canInterceptTouch(MotionEvent ev) { if (!mLauncher.isInState(LauncherState.NORMAL) || AbstractFloatingView.getTopOpenViewWithType(mLauncher, @@ -132,4 +166,4 @@ public class StatusBarTouchController implements TouchController { mSysUiProxy = RecentsModel.INSTANCE.get(mLauncher).getSystemUiProxy(); return mSysUiProxy != null; } -} +} \ No newline at end of file diff --git a/src/com/android/launcher3/touch/TouchEventTranslator.java b/src/com/android/launcher3/touch/TouchEventTranslator.java deleted file mode 100644 index 3fcda90848..0000000000 --- a/src/com/android/launcher3/touch/TouchEventTranslator.java +++ /dev/null @@ -1,283 +0,0 @@ -/* - * Copyright (C) 2018 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package com.android.launcher3.touch; - -import android.graphics.PointF; -import android.util.Log; -import android.util.Pair; -import android.util.SparseArray; -import android.view.MotionEvent; -import android.view.MotionEvent.PointerCoords; -import android.view.MotionEvent.PointerProperties; - -import java.util.function.Consumer; - -/** - * To minimize the size of the MotionEvent, historic events are not copied and passed via the - * listener. - */ -public class TouchEventTranslator { - - private static final String TAG = "TouchEventTranslator"; - private static final boolean DEBUG = false; - - private class DownState { - long timeStamp; - float downX; - float downY; - public DownState(long timeStamp, float downX, float downY) { - this.timeStamp = timeStamp; - this.downX = downX; - this.downY = downY; - } - }; - private final DownState ZERO = new DownState(0, 0f, 0f); - - private final Consumer mListener; - - private final SparseArray mDownEvents; - private final SparseArray mFingers; - - private final SparseArray> mCache; - - public TouchEventTranslator(Consumer listener) { - mDownEvents = new SparseArray<>(); - mFingers = new SparseArray<>(); - mCache = new SparseArray<>(); - - mListener = listener; - } - - public void reset() { - mDownEvents.clear(); - mFingers.clear(); - } - - public float getDownX() { - return mDownEvents.get(0).downX; - } - - public float getDownY() { - return mDownEvents.get(0).downY; - } - - public void setDownParameters(int idx, MotionEvent e) { - DownState ev = new DownState(e.getEventTime(), e.getX(idx), e.getY(idx)); - mDownEvents.append(idx, ev); - } - - public void dispatchDownEvents(MotionEvent ev) { - for(int i = 0; i < ev.getPointerCount() && i < mDownEvents.size(); i++) { - int pid = ev.getPointerId(i); - put(pid, i, ev.getX(i), 0, mDownEvents.get(i).timeStamp, ev); - } - } - - public void processMotionEvent(MotionEvent ev) { - if (DEBUG) { - printSamples(TAG + " processMotionEvent", ev); - } - int index = ev.getActionIndex(); - float x = ev.getX(index); - float y = ev.getY(index) - mDownEvents.get(index, ZERO).downY; - switch (ev.getActionMasked()) { - case MotionEvent.ACTION_POINTER_DOWN: - int pid = ev.getPointerId(index); - if(mFingers.get(pid, null) != null) { - for(int i=0; i < ev.getPointerCount(); i++) { - pid = ev.getPointerId(i); - position(pid, x, y); - } - generateEvent(ev.getAction(), ev); - } else { - put(pid, index, x, y, ev); - } - break; - case MotionEvent.ACTION_MOVE: - for(int i=0; i < ev.getPointerCount(); i++) { - pid = ev.getPointerId(i); - position(pid, x, y); - } - generateEvent(ev.getAction(), ev); - break; - case MotionEvent.ACTION_POINTER_UP: - case MotionEvent.ACTION_UP: - pid = ev.getPointerId(index); - lift(pid, index, x, y, ev); - break; - case MotionEvent.ACTION_CANCEL: - cancel(ev); - break; - default: - Log.v(TAG, "Didn't process "); - printSamples(TAG, ev); - - } - } - - private TouchEventTranslator put(int id, int index, float x, float y, MotionEvent ev) { - return put(id, index, x, y, ev.getEventTime(), ev); - } - - private TouchEventTranslator put(int id, int index, float x, float y, long ms, MotionEvent ev) { - checkFingerExistence(id, false); - boolean isInitialDown = (mFingers.size() == 0); - - mFingers.put(id, new PointF(x, y)); - int n = mFingers.size(); - - if (mCache.get(n) == null) { - PointerProperties[] properties = new PointerProperties[n]; - PointerCoords[] coords = new PointerCoords[n]; - for (int i = 0; i < n; i++) { - properties[i] = new PointerProperties(); - coords[i] = new PointerCoords(); - } - mCache.put(n, new Pair(properties, coords)); - } - - int action; - if (isInitialDown) { - action = MotionEvent.ACTION_DOWN; - } else { - action = MotionEvent.ACTION_POINTER_DOWN; - // Set the id of the changed pointer. - action |= index << MotionEvent.ACTION_POINTER_INDEX_SHIFT; - } - generateEvent(action, ms, ev); - return this; - } - - public TouchEventTranslator position(int id, float x, float y) { - checkFingerExistence(id, true); - mFingers.get(id).set(x, y); - return this; - } - - private TouchEventTranslator lift(int id, int index, MotionEvent ev) { - checkFingerExistence(id, true); - boolean isFinalUp = (mFingers.size() == 1); - int action; - if (isFinalUp) { - action = MotionEvent.ACTION_UP; - } else { - action = MotionEvent.ACTION_POINTER_UP; - // Set the id of the changed pointer. - action |= index << MotionEvent.ACTION_POINTER_INDEX_SHIFT; - } - generateEvent(action, ev); - mFingers.remove(id); - return this; - } - - private TouchEventTranslator lift(int id, int index, float x, float y, MotionEvent ev) { - checkFingerExistence(id, true); - mFingers.get(id).set(x, y); - return lift(id, index, ev); - } - - public TouchEventTranslator cancel(MotionEvent ev) { - generateEvent(MotionEvent.ACTION_CANCEL, ev); - mFingers.clear(); - return this; - } - - private void checkFingerExistence(int id, boolean shouldExist) { - if (shouldExist != (mFingers.get(id, null) != null)) { - throw new IllegalArgumentException( - shouldExist ? "Finger does not exist" : "Finger already exists"); - } - } - - - /** - * Used to debug MotionEvents being sent/received. - */ - public void printSamples(String msg, MotionEvent ev) { - System.out.printf("%s %s", msg, MotionEvent.actionToString(ev.getActionMasked())); - final int pointerCount = ev.getPointerCount(); - System.out.printf("#%d/%d", ev.getActionIndex(), pointerCount); - System.out.printf(" t=%d:", ev.getEventTime()); - for (int p = 0; p < pointerCount; p++) { - System.out.printf(" id=%d: (%f,%f)", - ev.getPointerId(p), ev.getX(p), ev.getY(p)); - } - System.out.println(); - } - - private void generateEvent(int action, MotionEvent ev) { - generateEvent(action, ev.getEventTime(), ev); - } - - private void generateEvent(int action, long ms, MotionEvent ev) { - Pair state = getFingerState(); - MotionEvent event = MotionEvent.obtain( - mDownEvents.get(0).timeStamp, - ms, - action, - state.first.length, - state.first, - state.second, - ev.getMetaState(), - ev.getButtonState() /* buttonState */, - ev.getXPrecision() /* xPrecision */, - ev.getYPrecision() /* yPrecision */, - ev.getDeviceId(), - ev.getEdgeFlags(), - ev.getSource(), - ev.getFlags() /* flags */); - if (DEBUG) { - printSamples(TAG + " generateEvent", event); - } - if (event.getPointerId(event.getActionIndex()) < 0) { - printSamples(TAG + "generateEvent", event); - throw new IllegalStateException(event.getActionIndex() + " not found in MotionEvent"); - } - mListener.accept(event); - event.recycle(); - } - - /** - * Returns the description of the fingers' state expected by MotionEvent. - */ - private Pair getFingerState() { - int nFingers = mFingers.size(); - - Pair result = mCache.get(nFingers); - PointerProperties[] properties = result.first; - PointerCoords[] coordinates = result.second; - - int index = 0; - for (int i = 0; i < mFingers.size(); i++) { - int id = mFingers.keyAt(i); - PointF location = mFingers.get(id); - - PointerProperties property = properties[i]; - property.id = id; - property.toolType = MotionEvent.TOOL_TYPE_FINGER; - properties[index] = property; - - PointerCoords coordinate = coordinates[i]; - coordinate.x = location.x; - coordinate.y = location.y; - coordinate.pressure = 1.0f; - coordinates[index] = coordinate; - - index++; - } - return mCache.get(nFingers); - } -} From 70697e48a8e0c16a9d7c4231767a213cbaa9df47 Mon Sep 17 00:00:00 2001 From: Riddle Hsu Date: Thu, 27 Jun 2019 00:37:38 -0600 Subject: [PATCH 013/108] Preload overview activity in background To reduce the jank when swiping-up the overview which is not ready yet, we restart the overview activity if the process was died and update its configuration if there is change. Bug: 127350205 Test: manual - Enable 2-button or gesture navigation. Swipe-up overview after: Case 1: Other app is in foreground and kill the process of launcher. Case 2: Change configuration, e.g. font size, language. Change-Id: Ia6e365cc0faf3765781484d040bdddd4e10a2650 --- .../quickstep/TouchInteractionService.java | 53 +++++++++++ .../quickstep/OverviewComponentObserver.java | 91 +++++++++++++------ 2 files changed, 116 insertions(+), 28 deletions(-) diff --git a/quickstep/recents_ui_overrides/src/com/android/quickstep/TouchInteractionService.java b/quickstep/recents_ui_overrides/src/com/android/quickstep/TouchInteractionService.java index 9353c04b58..bf9d531061 100644 --- a/quickstep/recents_ui_overrides/src/com/android/quickstep/TouchInteractionService.java +++ b/quickstep/recents_ui_overrides/src/com/android/quickstep/TouchInteractionService.java @@ -43,6 +43,8 @@ import android.content.ComponentName; import android.content.Context; import android.content.Intent; import android.content.IntentFilter; +import android.content.pm.ActivityInfo; +import android.content.res.Configuration; import android.graphics.Point; import android.graphics.RectF; import android.graphics.Region; @@ -74,6 +76,7 @@ import com.android.launcher3.Utilities; import com.android.launcher3.compat.UserManagerCompat; import com.android.launcher3.logging.EventLogArray; import com.android.launcher3.logging.UserEventDispatcher; +import com.android.launcher3.model.AppLaunchTracker; import com.android.launcher3.testing.TestProtocol; import com.android.launcher3.util.LooperExecutor; import com.android.launcher3.util.UiThreadHelper; @@ -92,6 +95,7 @@ import com.android.quickstep.inputconsumers.ScreenPinnedInputConsumer; import com.android.systemui.shared.recents.IOverviewProxy; import com.android.systemui.shared.recents.ISystemUiProxy; import com.android.systemui.shared.system.ActivityManagerWrapper; +import com.android.systemui.shared.system.BackgroundExecutor; import com.android.systemui.shared.system.InputChannelCompat.InputEventReceiver; import com.android.systemui.shared.system.InputConsumerController; import com.android.systemui.shared.system.InputMonitorCompat; @@ -153,6 +157,7 @@ public class TouchInteractionService extends Service implements .asInterface(bundle.getBinder(KEY_EXTRA_SYSUI_PROXY)); MAIN_THREAD_EXECUTOR.execute(TouchInteractionService.this::initInputMonitor); MAIN_THREAD_EXECUTOR.execute(TouchInteractionService.this::onSystemUiProxySet); + MAIN_THREAD_EXECUTOR.execute(() -> preloadOverview(true /* fromInit */)); } @Override @@ -688,6 +693,54 @@ public class TouchInteractionService extends Service implements } } + private void preloadOverview(boolean fromInit) { + if (!mIsUserUnlocked) { + return; + } + + final ActivityControlHelper activityControl = + mOverviewComponentObserver.getActivityControlHelper(); + if (activityControl.getCreatedActivity() == null) { + // Make sure that UI states will be initialized. + activityControl.createActivityInitListener((activity, wasVisible) -> { + AppLaunchTracker.INSTANCE.get(activity); + return false; + }).register(); + } else if (fromInit) { + // The activity has been created before the initialization of overview service. It is + // usually happens when booting or launcher is the top activity, so we should already + // have the latest state. + return; + } + + // Pass null animation handler to indicate this start is preload. + BackgroundExecutor.get().submit( + () -> ActivityManagerWrapper.getInstance().startRecentsActivity( + mOverviewComponentObserver.getOverviewIntentIgnoreSysUiState(), + null /* assistDataReceiver */, null /* animationHandler */, + null /* resultCallback */, null /* resultCallbackHandler */)); + } + + @Override + public void onConfigurationChanged(Configuration newConfig) { + if (!mIsUserUnlocked) { + return; + } + final ActivityControlHelper activityControl = + mOverviewComponentObserver.getActivityControlHelper(); + final BaseDraggingActivity activity = activityControl.getCreatedActivity(); + if (activity == null || activity.isStarted()) { + // We only care about the existing background activity. + return; + } + if (mOverviewComponentObserver.canHandleConfigChanges(activity.getComponentName(), + activity.getResources().getConfiguration().diff(newConfig))) { + return; + } + + preloadOverview(false /* fromInit */); + } + @Override protected void dump(FileDescriptor fd, PrintWriter pw, String[] rawArgs) { if (rawArgs.length > 0 && Utilities.IS_DEBUG_DEVICE) { diff --git a/quickstep/src/com/android/quickstep/OverviewComponentObserver.java b/quickstep/src/com/android/quickstep/OverviewComponentObserver.java index 0738affa93..4a2ed3a3d1 100644 --- a/quickstep/src/com/android/quickstep/OverviewComponentObserver.java +++ b/quickstep/src/com/android/quickstep/OverviewComponentObserver.java @@ -29,11 +29,15 @@ import android.content.ComponentName; import android.content.Context; import android.content.Intent; import android.content.IntentFilter; +import android.content.pm.ActivityInfo; +import android.content.pm.PackageManager; import android.content.pm.ResolveInfo; +import android.util.SparseIntArray; import com.android.systemui.shared.system.PackageManagerWrapper; import java.util.ArrayList; +import java.util.Objects; /** * Class to keep track of the current overview component based off user preferences and app updates @@ -53,22 +57,41 @@ public final class OverviewComponentObserver { } }; private final Context mContext; - private final ComponentName mMyHomeComponent; + private final Intent mCurrentHomeIntent; + private final Intent mMyHomeIntent; + private final Intent mFallbackIntent; + private final SparseIntArray mConfigChangesMap = new SparseIntArray(); private String mUpdateRegisteredPackage; private ActivityControlHelper mActivityControlHelper; private Intent mOverviewIntent; - private Intent mHomeIntent; private int mSystemUiStateFlags; private boolean mIsHomeAndOverviewSame; + private boolean mIsDefaultHome; public OverviewComponentObserver(Context context) { mContext = context; - Intent myHomeIntent = new Intent(Intent.ACTION_MAIN) + mCurrentHomeIntent = new Intent(Intent.ACTION_MAIN) .addCategory(Intent.CATEGORY_HOME) - .setPackage(mContext.getPackageName()); - ResolveInfo info = context.getPackageManager().resolveActivity(myHomeIntent, 0); - mMyHomeComponent = new ComponentName(context.getPackageName(), info.activityInfo.name); + .setFlags(Intent.FLAG_ACTIVITY_NEW_TASK); + mMyHomeIntent = new Intent(mCurrentHomeIntent).setPackage(mContext.getPackageName()); + ResolveInfo info = context.getPackageManager().resolveActivity(mMyHomeIntent, 0); + ComponentName myHomeComponent = + new ComponentName(context.getPackageName(), info.activityInfo.name); + mMyHomeIntent.setComponent(myHomeComponent); + mConfigChangesMap.append(myHomeComponent.hashCode(), info.activityInfo.configChanges); + + ComponentName fallbackComponent = new ComponentName(mContext, RecentsActivity.class); + mFallbackIntent = new Intent(Intent.ACTION_MAIN) + .addCategory(Intent.CATEGORY_DEFAULT) + .setComponent(fallbackComponent) + .setFlags(Intent.FLAG_ACTIVITY_NEW_TASK); + + try { + ActivityInfo fallbackInfo = context.getPackageManager().getActivityInfo( + mFallbackIntent.getComponent(), 0 /* flags */); + mConfigChangesMap.append(fallbackComponent.hashCode(), fallbackInfo.configChanges); + } catch (PackageManager.NameNotFoundException ignored) { /* Impossible */ } mContext.registerReceiver(mUserPreferenceChangeReceiver, new IntentFilter(ACTION_PREFERRED_ACTIVITY_CHANGED)); @@ -92,17 +115,14 @@ public final class OverviewComponentObserver { ComponentName defaultHome = PackageManagerWrapper.getInstance() .getHomeActivities(new ArrayList<>()); - final String overviewIntentCategory; - ComponentName overviewComponent; - mHomeIntent = null; - - if ((mSystemUiStateFlags & SYSUI_STATE_HOME_DISABLED) == 0 && - (defaultHome == null || mMyHomeComponent.equals(defaultHome))) { + mIsDefaultHome = Objects.equals(mMyHomeIntent.getComponent(), defaultHome); + if ((mSystemUiStateFlags & SYSUI_STATE_HOME_DISABLED) == 0 + && (defaultHome == null || mIsDefaultHome)) { // User default home is same as out home app. Use Overview integrated in Launcher. - overviewComponent = mMyHomeComponent; mActivityControlHelper = new LauncherActivityControllerHelper(); mIsHomeAndOverviewSame = true; - overviewIntentCategory = Intent.CATEGORY_HOME; + mOverviewIntent = mMyHomeIntent; + mCurrentHomeIntent.setComponent(mMyHomeIntent.getComponent()); if (mUpdateRegisteredPackage != null) { // Remove any update listener as we don't care about other packages. @@ -111,14 +131,11 @@ public final class OverviewComponentObserver { } } else { // The default home app is a different launcher. Use the fallback Overview instead. - overviewComponent = new ComponentName(mContext, RecentsActivity.class); mActivityControlHelper = new FallbackActivityControllerHelper(); mIsHomeAndOverviewSame = false; - overviewIntentCategory = Intent.CATEGORY_DEFAULT; + mOverviewIntent = mFallbackIntent; + mCurrentHomeIntent.setComponent(defaultHome); - mHomeIntent = new Intent(Intent.ACTION_MAIN) - .addCategory(Intent.CATEGORY_HOME) - .setComponent(defaultHome); // User's default home app can change as a result of package updates of this app (such // as uninstalling the app or removing the "Launcher" feature in an update). // Listen for package updates of this app (and remove any previously attached @@ -138,14 +155,6 @@ public final class OverviewComponentObserver { ACTION_PACKAGE_REMOVED)); } } - - mOverviewIntent = new Intent(Intent.ACTION_MAIN) - .addCategory(overviewIntentCategory) - .setComponent(overviewComponent) - .setFlags(Intent.FLAG_ACTIVITY_NEW_TASK); - if (mHomeIntent == null) { - mHomeIntent = mOverviewIntent; - } } /** @@ -160,6 +169,32 @@ public final class OverviewComponentObserver { } } + /** + * @return {@code true} if the overview component is able to handle the configuration changes. + */ + boolean canHandleConfigChanges(ComponentName component, int changes) { + final int orientationChange = + ActivityInfo.CONFIG_ORIENTATION | ActivityInfo.CONFIG_SCREEN_SIZE; + if ((changes & orientationChange) == orientationChange) { + // This is just an approximate guess for simple orientation change because the changes + // may contain non-public bits (e.g. window configuration). + return true; + } + + int configMask = mConfigChangesMap.get(component.hashCode()); + return configMask != 0 && (~configMask & changes) == 0; + } + + /** + * Get the intent for overview activity. It is used when lockscreen is shown and home was died + * in background, we still want to restart the one that will be used after unlock. + * + * @return the overview intent + */ + Intent getOverviewIntentIgnoreSysUiState() { + return mIsDefaultHome ? mMyHomeIntent : mOverviewIntent; + } + /** * Get the current intent for going to the overview activity. * @@ -173,7 +208,7 @@ public final class OverviewComponentObserver { * Get the current intent for going to the home activity. */ public Intent getHomeIntent() { - return mHomeIntent; + return mCurrentHomeIntent; } /** From 4bfcf04ae9228f912ac151009800a9f3cd205550 Mon Sep 17 00:00:00 2001 From: Hyunyoung Song Date: Mon, 1 Jul 2019 14:39:40 -0700 Subject: [PATCH 014/108] [DO NOT MERGE] Disable swipe down to pull noti shade for Q Bug: 136293958 Change-Id: Iac169d91a784b5f2d05410a06cd358f85b533562 --- .../com/android/launcher3/uioverrides/RecentsUiFactory.java | 6 ------ 1 file changed, 6 deletions(-) diff --git a/quickstep/recents_ui_overrides/src/com/android/launcher3/uioverrides/RecentsUiFactory.java b/quickstep/recents_ui_overrides/src/com/android/launcher3/uioverrides/RecentsUiFactory.java index 6ecf1c11bd..a3c2e3cc81 100644 --- a/quickstep/recents_ui_overrides/src/com/android/launcher3/uioverrides/RecentsUiFactory.java +++ b/quickstep/recents_ui_overrides/src/com/android/launcher3/uioverrides/RecentsUiFactory.java @@ -164,12 +164,6 @@ public abstract class RecentsUiFactory { } } - if (FeatureFlags.PULL_DOWN_STATUS_BAR && Utilities.IS_DEBUG_DEVICE - && !launcher.getDeviceProfile().isMultiWindowMode - && !launcher.getDeviceProfile().isVerticalBarLayout()) { - list.add(new StatusBarTouchController(launcher)); - } - list.add(new LauncherTaskViewController(launcher)); return list.toArray(new TouchController[list.size()]); } From 826cdcd32fa91afe932c8c07be1a4e92a6f73301 Mon Sep 17 00:00:00 2001 From: Jon Miranda Date: Tue, 2 Jul 2019 14:35:11 -0700 Subject: [PATCH 015/108] Fix bug where icon is no present during app close animation. * WindowTransformSwipeHandler closes all AbstractFloatingViews, including ListenerView, which results in FloatingIconView getting removed. * In IconLoadResult.onIconLoaded, we remove the check for isIconLoaded since its not needed. This was also causing a race condition since isIconLoaded is not set to true until after we tell onIconLoaded to run. * In BaseDragLayer, we have a delay before checking if the view is open and then closing the floating view if true. This caused issues since we reycle the view. Now we check if the view is open before running the delay to call close. Bug: 136044361 Change-Id: I7442a589a62c3cdf90b70d146e0ecf3e4300ddf7 --- .../android/quickstep/WindowTransformSwipeHandler.java | 3 ++- src/com/android/launcher3/views/BaseDragLayer.java | 10 ++++------ src/com/android/launcher3/views/FloatingIconView.java | 10 +++++----- 3 files changed, 11 insertions(+), 12 deletions(-) diff --git a/quickstep/recents_ui_overrides/src/com/android/quickstep/WindowTransformSwipeHandler.java b/quickstep/recents_ui_overrides/src/com/android/quickstep/WindowTransformSwipeHandler.java index f1d1141bcd..ac7ba3fc3d 100644 --- a/quickstep/recents_ui_overrides/src/com/android/quickstep/WindowTransformSwipeHandler.java +++ b/quickstep/recents_ui_overrides/src/com/android/quickstep/WindowTransformSwipeHandler.java @@ -505,7 +505,8 @@ public class WindowTransformSwipeHandler initAnimFactory.run(); } } - AbstractFloatingView.closeAllOpenViews(activity, mWasLauncherAlreadyVisible); + AbstractFloatingView.closeAllOpenViewsExcept(activity, mWasLauncherAlreadyVisible, + AbstractFloatingView.TYPE_LISTENER); if (mWasLauncherAlreadyVisible) { mStateCallback.setState(STATE_LAUNCHER_DRAWN); diff --git a/src/com/android/launcher3/views/BaseDragLayer.java b/src/com/android/launcher3/views/BaseDragLayer.java index 53686cae48..1e70c7f812 100644 --- a/src/com/android/launcher3/views/BaseDragLayer.java +++ b/src/com/android/launcher3/views/BaseDragLayer.java @@ -224,12 +224,10 @@ public abstract class BaseDragLayer if (child instanceof AbstractFloatingView) { // Handles the case where the view is removed without being properly closed. // This can happen if something goes wrong during a state change/transition. - postDelayed(() -> { - AbstractFloatingView floatingView = (AbstractFloatingView) child; - if (floatingView.isOpen()) { - floatingView.close(false); - } - }, SINGLE_FRAME_MS); + AbstractFloatingView floatingView = (AbstractFloatingView) child; + if (floatingView.isOpen()) { + postDelayed(() -> floatingView.close(false), SINGLE_FRAME_MS); + } } } diff --git a/src/com/android/launcher3/views/FloatingIconView.java b/src/com/android/launcher3/views/FloatingIconView.java index b6c4fedac9..ab4b576bf9 100644 --- a/src/com/android/launcher3/views/FloatingIconView.java +++ b/src/com/android/launcher3/views/FloatingIconView.java @@ -574,17 +574,17 @@ public class FloatingIconView extends View implements if (cancellationSignal.isCanceled()) { return; } - if (mIconLoadResult.isIconLoaded) { - setIcon(originalView, mIconLoadResult.drawable, mIconLoadResult.badge, - mIconLoadResult.iconOffset); - } + + setIcon(originalView, mIconLoadResult.drawable, mIconLoadResult.badge, + mIconLoadResult.iconOffset); + // Delay swapping views until the icon is loaded to prevent a flash. setVisibility(VISIBLE); originalView.setVisibility(INVISIBLE); }; + mLoadIconSignal = cancellationSignal; } } - mLoadIconSignal = cancellationSignal; } private void setBackgroundDrawableBounds(float scale) { From ab6be31746aafae1cd75a755eab1592ccef5065a Mon Sep 17 00:00:00 2001 From: Adam Cohen Date: Sat, 6 Jul 2019 13:24:59 +0900 Subject: [PATCH 016/108] Fix issue where can't interact with Workspace while App => Home is running => Regression from recent CL ag/8074890 => Fix which scopes the change down to the RecentsView, but not all PagedViews Bug 136733573 Change-Id: I0abaa61b2b132d8086dc3b2cb3e3e9c1f181b5f5 --- .../src/com/android/quickstep/views/RecentsView.java | 5 +++++ src/com/android/launcher3/PagedView.java | 9 ++++++--- 2 files changed, 11 insertions(+), 3 deletions(-) diff --git a/quickstep/recents_ui_overrides/src/com/android/quickstep/views/RecentsView.java b/quickstep/recents_ui_overrides/src/com/android/quickstep/views/RecentsView.java index a98df0fa1f..30a8a3a23f 100644 --- a/quickstep/recents_ui_overrides/src/com/android/quickstep/views/RecentsView.java +++ b/quickstep/recents_ui_overrides/src/com/android/quickstep/views/RecentsView.java @@ -472,6 +472,11 @@ public abstract class RecentsView extends PagedView impl } } + @Override + protected boolean shouldBlockGestures(MotionEvent ev) { + return Utilities.shouldDisableGestures(ev); + } + @Override public boolean onTouchEvent(MotionEvent ev) { super.onTouchEvent(ev); diff --git a/src/com/android/launcher3/PagedView.java b/src/com/android/launcher3/PagedView.java index 2eeb132bbf..f8e4c9dfc7 100644 --- a/src/com/android/launcher3/PagedView.java +++ b/src/com/android/launcher3/PagedView.java @@ -16,7 +16,6 @@ package com.android.launcher3; -import static com.android.launcher3.Utilities.shouldDisableGestures; import static com.android.launcher3.compat.AccessibilityManagerCompat.isAccessibilityEnabled; import static com.android.launcher3.compat.AccessibilityManagerCompat.isObservedEventType; import static com.android.launcher3.config.FeatureFlags.QUICKSTEP_SPRINGS; @@ -847,7 +846,7 @@ public abstract class PagedView extends ViewGrou */ // Skip touch handling if there are no pages to swipe - if (getChildCount() <= 0 || shouldDisableGestures(ev)) return false; + if (getChildCount() <= 0 || shouldBlockGestures(ev)) return false; acquireVelocityTrackerAndAddMovement(ev); @@ -1092,10 +1091,14 @@ public abstract class PagedView extends ViewGrou mAllowOverScroll = enable; } + protected boolean shouldBlockGestures(MotionEvent ev) { + return false; + } + @Override public boolean onTouchEvent(MotionEvent ev) { // Skip touch handling if there are no pages to swipe - if (getChildCount() <= 0 || shouldDisableGestures(ev)) return false; + if (getChildCount() <= 0 || shouldBlockGestures(ev)) return false; acquireVelocityTrackerAndAddMovement(ev); From 98de773474fd0622d1c95f436e4553daca51f589 Mon Sep 17 00:00:00 2001 From: Winson Chung Date: Mon, 8 Jul 2019 20:30:53 +0000 Subject: [PATCH 017/108] Revert "Trigger heap dump when heap exceeds a limit" This reverts commit e069291ecdbcaa1fdd4fa7201f97992cfe3bc6e8. Reason for revert: Blocked on FW change Change-Id: Iabf6dee687e499544be5bf895563e57157b0f9e1 --- .../quickstep/QuickstepProcessInitializer.java | 13 ------------- 1 file changed, 13 deletions(-) diff --git a/quickstep/src/com/android/quickstep/QuickstepProcessInitializer.java b/quickstep/src/com/android/quickstep/QuickstepProcessInitializer.java index 7bfa9a0f99..befeee0db9 100644 --- a/quickstep/src/com/android/quickstep/QuickstepProcessInitializer.java +++ b/quickstep/src/com/android/quickstep/QuickstepProcessInitializer.java @@ -15,7 +15,6 @@ */ package com.android.quickstep; -import android.app.ActivityManager; import android.content.Context; import android.content.pm.PackageManager; import android.os.UserManager; @@ -23,29 +22,17 @@ import android.util.Log; import com.android.launcher3.BuildConfig; import com.android.launcher3.MainProcessInitializer; -import com.android.launcher3.Utilities; import com.android.systemui.shared.system.ThreadedRendererCompat; @SuppressWarnings("unused") public class QuickstepProcessInitializer extends MainProcessInitializer { private static final String TAG = "QuickstepProcessInitializer"; - private static final int HEAP_LIMIT_MB = 250; public QuickstepProcessInitializer(Context context) { } @Override protected void init(Context context) { - if (Utilities.IS_DEBUG_DEVICE) { - try { - // Trigger a heap dump if the PSS reaches beyond the target heap limit - final ActivityManager am = context.getSystemService(ActivityManager.class); - am.setWatchHeapLimit(HEAP_LIMIT_MB * 1024 * 1024); - } catch (SecurityException e) { - // Do nothing - } - } - // Workaround for b/120550382, an external app can cause the launcher process to start for // a work profile user which we do not support. Disable the application immediately when we // detect this to be the case. From 4abfbd067073cc24622c80a3e3519cca37e8f206 Mon Sep 17 00:00:00 2001 From: Hyunyoung Song Date: Tue, 9 Jul 2019 10:35:27 -0700 Subject: [PATCH 018/108] Reset the UI_STATE_OVERVIEW statusbar/navbar flag when RecentsView resets Bug: 135383592 TL;DR;; this reset is called when for instance OMS call happens Change-Id: I57bb6c1c8833aff00e3be572dd19744afbb81eb5 --- .../src/com/android/quickstep/views/RecentsView.java | 1 + 1 file changed, 1 insertion(+) diff --git a/quickstep/recents_ui_overrides/src/com/android/quickstep/views/RecentsView.java b/quickstep/recents_ui_overrides/src/com/android/quickstep/views/RecentsView.java index a8987a3d42..c465798fc5 100644 --- a/quickstep/recents_ui_overrides/src/com/android/quickstep/views/RecentsView.java +++ b/quickstep/recents_ui_overrides/src/com/android/quickstep/views/RecentsView.java @@ -784,6 +784,7 @@ public abstract class RecentsView extends PagedView impl unloadVisibleTaskData(); setCurrentPage(0); mDwbToastShown = false; + mActivity.getSystemUiController().updateUiState(UI_STATE_OVERVIEW, 0); } public @Nullable TaskView getRunningTaskView() { From 940b0ac0157945a40d8b3b44d976da53aaeff81f Mon Sep 17 00:00:00 2001 From: Winson Chung Date: Tue, 9 Jul 2019 11:33:50 -0700 Subject: [PATCH 019/108] Copy resume callbacks list prior to making callbacks - Starting a deferred activity can trigger a new callback to be added to the list while we are iterating it Bug: 136613192 Change-Id: I6690ab0695bb73f11bf343fb41e9fc86b4afec1b --- src/com/android/launcher3/Launcher.java | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/src/com/android/launcher3/Launcher.java b/src/com/android/launcher3/Launcher.java index d9af4da8e8..bc3aa7ef40 100644 --- a/src/com/android/launcher3/Launcher.java +++ b/src/com/android/launcher3/Launcher.java @@ -952,10 +952,14 @@ public class Launcher extends BaseDraggingActivity implements LauncherExterns, mHandler.removeCallbacks(mHandleDeferredResume); Utilities.postAsyncCallback(mHandler, mHandleDeferredResume); - for (OnResumeCallback cb : mOnResumeCallbacks) { - cb.onLauncherResume(); + if (!mOnResumeCallbacks.isEmpty()) { + final ArrayList resumeCallbacks = new ArrayList<>(mOnResumeCallbacks); + mOnResumeCallbacks.clear(); + for (int i = resumeCallbacks.size() - 1; i >= 0; i--) { + resumeCallbacks.get(i).onLauncherResume(); + } + resumeCallbacks.clear(); } - mOnResumeCallbacks.clear(); if (mLauncherCallbacks != null) { mLauncherCallbacks.onResume(); From 857b3fbb7e1cc7603139d03d46cb1d08c737a338 Mon Sep 17 00:00:00 2001 From: Jon Miranda Date: Wed, 10 Jul 2019 11:04:40 -0700 Subject: [PATCH 020/108] Fix bug where app icons are clipped when transitioning from app to home. Bug: 135636137 Change-Id: Icaba06ed27b3196371730a5a4c5d3382cedc7000 --- .../util/StaggeredWorkspaceAnim.java | 40 +++++++++++++++++-- .../launcher3/anim/SpringObjectAnimator.java | 5 ++- 2 files changed, 41 insertions(+), 4 deletions(-) diff --git a/quickstep/recents_ui_overrides/src/com/android/quickstep/util/StaggeredWorkspaceAnim.java b/quickstep/recents_ui_overrides/src/com/android/quickstep/util/StaggeredWorkspaceAnim.java index 07e96869ed..45d12fd77e 100644 --- a/quickstep/recents_ui_overrides/src/com/android/quickstep/util/StaggeredWorkspaceAnim.java +++ b/quickstep/recents_ui_overrides/src/com/android/quickstep/util/StaggeredWorkspaceAnim.java @@ -16,6 +16,8 @@ package com.android.quickstep.util; import android.animation.Animator; +import android.animation.Animator.AnimatorListener; +import android.animation.AnimatorListenerAdapter; import android.animation.ObjectAnimator; import android.view.View; import android.view.ViewGroup; @@ -29,6 +31,7 @@ import com.android.launcher3.LauncherState; import com.android.launcher3.LauncherStateManager.AnimationConfig; import com.android.launcher3.R; import com.android.launcher3.ShortcutAndWidgetContainer; +import com.android.launcher3.Workspace; import com.android.launcher3.anim.AnimatorSetBuilder; import com.android.launcher3.anim.PropertySetter; import com.android.launcher3.anim.SpringObjectAnimator; @@ -79,9 +82,19 @@ public class StaggeredWorkspaceAnim { .getDimensionPixelSize(R.dimen.swipe_up_max_workspace_trans_y); DeviceProfile grid = launcher.getDeviceProfile(); - ShortcutAndWidgetContainer currentPage = ((CellLayout) launcher.getWorkspace() - .getChildAt(launcher.getWorkspace().getCurrentPage())) - .getShortcutsAndWidgets(); + Workspace workspace = launcher.getWorkspace(); + CellLayout cellLayout = (CellLayout) workspace.getChildAt(workspace.getCurrentPage()); + ShortcutAndWidgetContainer currentPage = cellLayout.getShortcutsAndWidgets(); + + boolean workspaceClipChildren = workspace.getClipChildren(); + boolean workspaceClipToPadding = workspace.getClipToPadding(); + boolean cellLayoutClipChildren = cellLayout.getClipChildren(); + boolean cellLayoutClipToPadding = cellLayout.getClipToPadding(); + + workspace.setClipChildren(false); + workspace.setClipToPadding(false); + cellLayout.setClipChildren(false); + cellLayout.setClipToPadding(false); // Hotseat and QSB takes up two additional rows. int totalRows = grid.inv.numRows + (grid.isVerticalBarLayout() ? 0 : 2); @@ -111,6 +124,27 @@ public class StaggeredWorkspaceAnim { addWorkspaceScrimAnimationForState(launcher, BACKGROUND_APP, 0); addWorkspaceScrimAnimationForState(launcher, NORMAL, ALPHA_DURATION_MS); + + AnimatorListener resetClipListener = new AnimatorListenerAdapter() { + int numAnimations = mAnimators.size(); + + @Override + public void onAnimationEnd(Animator animation) { + numAnimations--; + if (numAnimations > 0) { + return; + } + + workspace.setClipChildren(workspaceClipChildren); + workspace.setClipToPadding(workspaceClipToPadding); + cellLayout.setClipChildren(cellLayoutClipChildren); + cellLayout.setClipToPadding(cellLayoutClipToPadding); + } + }; + + for (Animator a : mAnimators) { + a.addListener(resetClipListener); + } } /** diff --git a/src/com/android/launcher3/anim/SpringObjectAnimator.java b/src/com/android/launcher3/anim/SpringObjectAnimator.java index 395fed259a..91a31069c1 100644 --- a/src/com/android/launcher3/anim/SpringObjectAnimator.java +++ b/src/com/android/launcher3/anim/SpringObjectAnimator.java @@ -96,7 +96,10 @@ public class SpringObjectAnimator extends ValueAnimator { } }); - mSpring.addUpdateListener((animation, value, velocity) -> mSpringEnded = false); + mSpring.addUpdateListener((animation, value, velocity) -> { + mSpringEnded = false; + mEnded = false; + }); mSpring.addEndListener((animation, canceled, value, velocity) -> { mSpringEnded = true; tryEnding(); From cabbaf986cacfc7eeb40eaae549658e9e594368e Mon Sep 17 00:00:00 2001 From: Jon Miranda Date: Wed, 10 Jul 2019 14:14:23 -0700 Subject: [PATCH 021/108] Fix bug where floating icon and workspace icon visible at the same time. - Add a signal for the animation to be "cancelled" - Allow the workspace view to be attached to a spring during the animatoin (but kept hidden) to prevent any jumpy movement Bug: 137215697 Change-Id: Ie6868a7f45fefaee5366c8d30bb323fe042e9156 --- .../WindowTransformSwipeHandler.java | 82 +++++++++++++------ .../quickstep/util/RectFSpringAnim.java | 11 +++ .../util/StaggeredWorkspaceAnim.java | 8 +- .../launcher3/views/FloatingIconView.java | 5 +- 4 files changed, 76 insertions(+), 30 deletions(-) diff --git a/quickstep/recents_ui_overrides/src/com/android/quickstep/WindowTransformSwipeHandler.java b/quickstep/recents_ui_overrides/src/com/android/quickstep/WindowTransformSwipeHandler.java index ac7ba3fc3d..f8e0c245e9 100644 --- a/quickstep/recents_ui_overrides/src/com/android/quickstep/WindowTransformSwipeHandler.java +++ b/quickstep/recents_ui_overrides/src/com/android/quickstep/WindowTransformSwipeHandler.java @@ -871,7 +871,7 @@ public class WindowTransformSwipeHandler @UiThread private InputConsumer createNewInputProxyHandler() { - endRunningWindowAnim(); + endRunningWindowAnim(true /* cancel */); endLauncherTransitionController(); if (!ENABLE_QUICKSTEP_LIVE_TILE.get()) { // Hide the task view, if not already hidden @@ -883,9 +883,13 @@ public class WindowTransformSwipeHandler ? InputConsumer.NO_OP : new OverviewInputConsumer(activity, null, true); } - private void endRunningWindowAnim() { + private void endRunningWindowAnim(boolean cancel) { if (mRunningWindowAnim != null) { - mRunningWindowAnim.end(); + if (cancel) { + mRunningWindowAnim.cancel(); + } else { + mRunningWindowAnim.end(); + } } } @@ -1177,27 +1181,37 @@ public class WindowTransformSwipeHandler // We want the window alpha to be 0 once this threshold is met, so that the // FolderIconView can be seen morphing into the icon shape. final float windowAlphaThreshold = isFloatingIconView ? 1f - SHAPE_PROGRESS_DURATION : 1f; - anim.addOnUpdateListener((currentRect, progress) -> { - homeAnim.setPlayFraction(progress); + anim.addOnUpdateListener(new RectFSpringAnim.OnUpdateListener() { + @Override + public void onUpdate(RectF currentRect, float progress) { + homeAnim.setPlayFraction(progress); - float alphaProgress = ACCEL_1_5.getInterpolation(progress); - float windowAlpha = Utilities.boundToRange(Utilities.mapToRange(alphaProgress, 0, - windowAlphaThreshold, 1.5f, 0f, Interpolators.LINEAR), 0, 1); - mTransformParams.setProgress(progress) - .setCurrentRectAndTargetAlpha(currentRect, windowAlpha); - if (isFloatingIconView) { - mTransformParams.setCornerRadius(endRadius * progress + startRadius - * (1f - progress)); - } - mClipAnimationHelper.applyTransform(targetSet, mTransformParams, - false /* launcherOnTop */); + float alphaProgress = ACCEL_1_5.getInterpolation(progress); + float windowAlpha = Utilities.boundToRange(Utilities.mapToRange(alphaProgress, 0, + windowAlphaThreshold, 1.5f, 0f, Interpolators.LINEAR), 0, 1); + mTransformParams.setProgress(progress) + .setCurrentRectAndTargetAlpha(currentRect, windowAlpha); + if (isFloatingIconView) { + mTransformParams.setCornerRadius(endRadius * progress + startRadius + * (1f - progress)); + } + mClipAnimationHelper.applyTransform(targetSet, mTransformParams, + false /* launcherOnTop */); - if (isFloatingIconView) { - ((FloatingIconView) floatingView).update(currentRect, 1f, progress, - windowAlphaThreshold, mClipAnimationHelper.getCurrentCornerRadius(), false); + if (isFloatingIconView) { + ((FloatingIconView) floatingView).update(currentRect, 1f, progress, + windowAlphaThreshold, mClipAnimationHelper.getCurrentCornerRadius(), false); + } + + updateSysUiFlags(Math.max(progress, mCurrentShift.value)); } - updateSysUiFlags(Math.max(progress, mCurrentShift.value)); + @Override + public void onCancel() { + if (isFloatingIconView) { + ((FloatingIconView) floatingView).fastFinish(); + } + } }); anim.addAnimatorListener(new AnimationSuccessListener() { @Override @@ -1306,7 +1320,7 @@ public class WindowTransformSwipeHandler } private void invalidateHandler() { - endRunningWindowAnim(); + endRunningWindowAnim(false /* cancel */); if (mGestureEndCallback != null) { mGestureEndCallback.run(); @@ -1471,12 +1485,34 @@ public class WindowTransformSwipeHandler private interface RunningWindowAnim { void end(); + void cancel(); + static RunningWindowAnim wrap(Animator animator) { - return animator::end; + return new RunningWindowAnim() { + @Override + public void end() { + animator.end(); + } + + @Override + public void cancel() { + animator.cancel(); + } + }; } static RunningWindowAnim wrap(RectFSpringAnim rectFSpringAnim) { - return rectFSpringAnim::end; + return new RunningWindowAnim() { + @Override + public void end() { + rectFSpringAnim.end(); + } + + @Override + public void cancel() { + rectFSpringAnim.cancel(); + } + }; } } } diff --git a/quickstep/recents_ui_overrides/src/com/android/quickstep/util/RectFSpringAnim.java b/quickstep/recents_ui_overrides/src/com/android/quickstep/util/RectFSpringAnim.java index 77dc6f32e7..9c5cf2042b 100644 --- a/quickstep/recents_ui_overrides/src/com/android/quickstep/util/RectFSpringAnim.java +++ b/quickstep/recents_ui_overrides/src/com/android/quickstep/util/RectFSpringAnim.java @@ -225,7 +225,18 @@ public class RectFSpringAnim { } } + public void cancel() { + if (mAnimsStarted) { + for (OnUpdateListener onUpdateListener : mOnUpdateListeners) { + onUpdateListener.onCancel(); + } + } + end(); + } + public interface OnUpdateListener { void onUpdate(RectF currentRect, float progress); + + void onCancel(); } } diff --git a/quickstep/recents_ui_overrides/src/com/android/quickstep/util/StaggeredWorkspaceAnim.java b/quickstep/recents_ui_overrides/src/com/android/quickstep/util/StaggeredWorkspaceAnim.java index 07e96869ed..bb6892ade7 100644 --- a/quickstep/recents_ui_overrides/src/com/android/quickstep/util/StaggeredWorkspaceAnim.java +++ b/quickstep/recents_ui_overrides/src/com/android/quickstep/util/StaggeredWorkspaceAnim.java @@ -134,10 +134,6 @@ public class StaggeredWorkspaceAnim { * @param totalRows Total number of rows. */ private void addStaggeredAnimationForView(View v, int row, int totalRows) { - if (v == mViewToIgnore) { - return; - } - // Invert the rows, because we stagger starting from the bottom of the screen. int invertedRow = totalRows - row; // Add 1 to the inverted row so that the bottom most row has a start delay. @@ -149,6 +145,10 @@ public class StaggeredWorkspaceAnim { springTransY.setStartDelay(startDelay); mAnimators.add(springTransY); + if (v == mViewToIgnore) { + return; + } + v.setAlpha(0); ObjectAnimator alpha = ObjectAnimator.ofFloat(v, View.ALPHA, 0f, 1f); alpha.setInterpolator(LINEAR); diff --git a/src/com/android/launcher3/views/FloatingIconView.java b/src/com/android/launcher3/views/FloatingIconView.java index ab4b576bf9..4fdd83b657 100644 --- a/src/com/android/launcher3/views/FloatingIconView.java +++ b/src/com/android/launcher3/views/FloatingIconView.java @@ -656,8 +656,7 @@ public class FloatingIconView extends View implements canvas.restoreToCount(count); } - public void onListenerViewClosed() { - // Fast finish here. + public void fastFinish() { if (mEndRunnable != null) { mEndRunnable.run(); mEndRunnable = null; @@ -757,7 +756,7 @@ public class FloatingIconView extends View implements view.setVisibility(INVISIBLE); parent.addView(view); dragLayer.addView(view.mListenerView); - view.mListenerView.setListener(view::onListenerViewClosed); + view.mListenerView.setListener(view::fastFinish); view.mEndRunnable = () -> { view.mEndRunnable = null; From 3739fbccdc7cb727d6e3d340194338652aaa42fd Mon Sep 17 00:00:00 2001 From: Hyunyoung Song Date: Mon, 1 Jul 2019 14:39:40 -0700 Subject: [PATCH 022/108] [DO NOT MERGE] Disable swipe down to pull noti shade for Q Merged-In: I74c682d39c70f785777b5a0804b31a0cc2369759 Bug: 136293958 Change-Id: Iac169d91a784b5f2d05410a06cd358f85b533562 (cherry picked from commit 4bfcf04ae9228f912ac151009800a9f3cd205550) --- .../com/android/launcher3/uioverrides/RecentsUiFactory.java | 6 ------ 1 file changed, 6 deletions(-) diff --git a/quickstep/recents_ui_overrides/src/com/android/launcher3/uioverrides/RecentsUiFactory.java b/quickstep/recents_ui_overrides/src/com/android/launcher3/uioverrides/RecentsUiFactory.java index 6ecf1c11bd..a3c2e3cc81 100644 --- a/quickstep/recents_ui_overrides/src/com/android/launcher3/uioverrides/RecentsUiFactory.java +++ b/quickstep/recents_ui_overrides/src/com/android/launcher3/uioverrides/RecentsUiFactory.java @@ -164,12 +164,6 @@ public abstract class RecentsUiFactory { } } - if (FeatureFlags.PULL_DOWN_STATUS_BAR && Utilities.IS_DEBUG_DEVICE - && !launcher.getDeviceProfile().isMultiWindowMode - && !launcher.getDeviceProfile().isVerticalBarLayout()) { - list.add(new StatusBarTouchController(launcher)); - } - list.add(new LauncherTaskViewController(launcher)); return list.toArray(new TouchController[list.size()]); } From 4d93df51a348125f2f85d310bb555e39d35be7b2 Mon Sep 17 00:00:00 2001 From: vadimt Date: Wed, 10 Jul 2019 17:32:58 -0700 Subject: [PATCH 023/108] Switching flinging gestures injection to model time This is a right thing to do in any case. Change-Id: I34eeecac6d9eb13130eb1015f9a9a5e2a32974ec --- src/com/android/launcher3/PagedView.java | 2 ++ .../com/android/launcher3/tapl/BaseOverview.java | 12 ++++++------ .../launcher3/tapl/LauncherInstrumentation.java | 16 ++++++++++++++++ 3 files changed, 24 insertions(+), 6 deletions(-) diff --git a/src/com/android/launcher3/PagedView.java b/src/com/android/launcher3/PagedView.java index f8e4c9dfc7..bd52ffe4b2 100644 --- a/src/com/android/launcher3/PagedView.java +++ b/src/com/android/launcher3/PagedView.java @@ -47,6 +47,7 @@ import android.view.animation.Interpolator; import android.widget.ScrollView; import com.android.launcher3.anim.Interpolators; +import com.android.launcher3.compat.AccessibilityManagerCompat; import com.android.launcher3.config.FeatureFlags; import com.android.launcher3.pageindicators.PageIndicator; import com.android.launcher3.touch.OverScroll; @@ -367,6 +368,7 @@ public abstract class PagedView extends ViewGrou */ protected void onPageEndTransition() { mWasInOverscroll = false; + AccessibilityManagerCompat.sendScrollFinishedEventToTest(getContext()); } protected int getUnboundedScrollX() { diff --git a/tests/tapl/com/android/launcher3/tapl/BaseOverview.java b/tests/tapl/com/android/launcher3/tapl/BaseOverview.java index ace49e9cea..ae93867191 100644 --- a/tests/tapl/com/android/launcher3/tapl/BaseOverview.java +++ b/tests/tapl/com/android/launcher3/tapl/BaseOverview.java @@ -16,6 +16,8 @@ package com.android.launcher3.tapl; +import android.graphics.Rect; + import androidx.annotation.NonNull; import androidx.test.uiautomator.BySelector; import androidx.test.uiautomator.Direction; @@ -49,9 +51,8 @@ public class BaseOverview extends LauncherInstrumentation.VisibleContainer { mLauncher.addContextLayer("want to fling forward in overview")) { LauncherInstrumentation.log("Overview.flingForward before fling"); final UiObject2 overview = verifyActiveContainer(); - overview.setGestureMargins(mLauncher.getEdgeSensitivityWidth(), 0, 0, 0); - overview.fling(Direction.LEFT, (int) (FLING_SPEED * mLauncher.getDisplayDensity())); - mLauncher.waitForIdle(); + mLauncher.scroll(overview, Direction.LEFT, 1, + new Rect(mLauncher.getEdgeSensitivityWidth(), 0, 0, 0), 20); verifyActiveContainer(); } } @@ -86,9 +87,8 @@ public class BaseOverview extends LauncherInstrumentation.VisibleContainer { mLauncher.addContextLayer("want to fling backward in overview")) { LauncherInstrumentation.log("Overview.flingBackward before fling"); final UiObject2 overview = verifyActiveContainer(); - overview.setGestureMargins(0, 0, mLauncher.getEdgeSensitivityWidth(), 0); - overview.fling(Direction.RIGHT, (int) (FLING_SPEED * mLauncher.getDisplayDensity())); - mLauncher.waitForIdle(); + mLauncher.scroll(overview, Direction.RIGHT, 1, + new Rect(0, 0, mLauncher.getEdgeSensitivityWidth(), 0), 20); verifyActiveContainer(); } } diff --git a/tests/tapl/com/android/launcher3/tapl/LauncherInstrumentation.java b/tests/tapl/com/android/launcher3/tapl/LauncherInstrumentation.java index 11b0665d95..72fc31903c 100644 --- a/tests/tapl/com/android/launcher3/tapl/LauncherInstrumentation.java +++ b/tests/tapl/com/android/launcher3/tapl/LauncherInstrumentation.java @@ -820,6 +820,22 @@ public final class LauncherInstrumentation { endY = (int) (vertCenter - halfGestureHeight); } break; + case LEFT: { + startY = endY = rect.centerY(); + final int horizCenter = rect.centerX(); + final float halfGestureWidth = rect.width() * percent / 2.0f; + startX = (int) (horizCenter - halfGestureWidth); + endX = (int) (horizCenter + halfGestureWidth); + } + break; + case RIGHT: { + startY = endY = rect.centerY(); + final int horizCenter = rect.centerX(); + final float halfGestureWidth = rect.width() * percent / 2.0f; + startX = (int) (horizCenter + halfGestureWidth); + endX = (int) (horizCenter - halfGestureWidth); + } + break; default: fail("Unsupported direction"); return; From f11dd8e1077ca229e228afd6a39e7b22d12105f7 Mon Sep 17 00:00:00 2001 From: Sunny Goyal Date: Wed, 10 Jul 2019 14:05:58 -0700 Subject: [PATCH 024/108] Using a higher priority executor than BackgroundExecutor for various recents tasks BackgroundExecutor is also using thread pool executor where the order is perserved Change-Id: Ieef8825599f35fe22da3e9adb1270c5525449d62 --- .../quickstep/TouchInteractionService.java | 5 +++++ .../quickstep/TouchInteractionService.java | 18 +++++++----------- .../DeviceLockedInputConsumer.java | 7 ++----- .../FallbackNoButtonInputConsumer.java | 6 ++---- .../OtherActivityInputConsumer.java | 6 ++---- .../android/quickstep/views/RecentsView.java | 4 ++-- .../com/android/quickstep/RecentTasksList.java | 9 ++++----- 7 files changed, 24 insertions(+), 31 deletions(-) diff --git a/go/quickstep/src/com/android/quickstep/TouchInteractionService.java b/go/quickstep/src/com/android/quickstep/TouchInteractionService.java index 900b94e186..c902826ed8 100644 --- a/go/quickstep/src/com/android/quickstep/TouchInteractionService.java +++ b/go/quickstep/src/com/android/quickstep/TouchInteractionService.java @@ -34,6 +34,8 @@ import android.view.MotionEvent; import com.android.launcher3.Utilities; import com.android.launcher3.compat.UserManagerCompat; +import com.android.launcher3.util.LooperExecutor; +import com.android.launcher3.util.UiThreadHelper; import com.android.systemui.shared.recents.IOverviewProxy; import com.android.systemui.shared.recents.ISystemUiProxy; @@ -137,6 +139,9 @@ public class TouchInteractionService extends Service { return sConnected; } + public static final LooperExecutor BACKGROUND_EXECUTOR = + new LooperExecutor(UiThreadHelper.getBackgroundLooper()); + private RecentsModel mRecentsModel; private OverviewComponentObserver mOverviewComponentObserver; private OverviewCommandHelper mOverviewCommandHelper; diff --git a/quickstep/recents_ui_overrides/src/com/android/quickstep/TouchInteractionService.java b/quickstep/recents_ui_overrides/src/com/android/quickstep/TouchInteractionService.java index bf9d531061..0ef2f5c5ad 100644 --- a/quickstep/recents_ui_overrides/src/com/android/quickstep/TouchInteractionService.java +++ b/quickstep/recents_ui_overrides/src/com/android/quickstep/TouchInteractionService.java @@ -43,7 +43,6 @@ import android.content.ComponentName; import android.content.Context; import android.content.Intent; import android.content.IntentFilter; -import android.content.pm.ActivityInfo; import android.content.res.Configuration; import android.graphics.Point; import android.graphics.RectF; @@ -95,12 +94,12 @@ import com.android.quickstep.inputconsumers.ScreenPinnedInputConsumer; import com.android.systemui.shared.recents.IOverviewProxy; import com.android.systemui.shared.recents.ISystemUiProxy; import com.android.systemui.shared.system.ActivityManagerWrapper; -import com.android.systemui.shared.system.BackgroundExecutor; import com.android.systemui.shared.system.InputChannelCompat.InputEventReceiver; import com.android.systemui.shared.system.InputConsumerController; import com.android.systemui.shared.system.InputMonitorCompat; import com.android.systemui.shared.system.QuickStepContract; import com.android.systemui.shared.system.QuickStepContract.SystemUiStateFlags; +import com.android.systemui.shared.system.RecentsAnimationListener; import com.android.systemui.shared.system.SystemGestureExclusionListenerCompat; import java.io.FileDescriptor; @@ -124,10 +123,6 @@ class ArgList extends LinkedList { public String nextArg() { return pollFirst().toLowerCase(); } - - public String nextArgExact() { - return pollFirst(); - } } /** @@ -714,11 +709,7 @@ public class TouchInteractionService extends Service implements } // Pass null animation handler to indicate this start is preload. - BackgroundExecutor.get().submit( - () -> ActivityManagerWrapper.getInstance().startRecentsActivity( - mOverviewComponentObserver.getOverviewIntentIgnoreSysUiState(), - null /* assistDataReceiver */, null /* animationHandler */, - null /* resultCallback */, null /* resultCallbackHandler */)); + startRecentsActivityAsync(mOverviewComponentObserver.getOverviewIntentIgnoreSysUiState(), null); } @Override @@ -796,4 +787,9 @@ public class TouchInteractionService extends Service implements break; } } + + public static void startRecentsActivityAsync(Intent intent, RecentsAnimationListener listener) { + BACKGROUND_EXECUTOR.execute(() -> ActivityManagerWrapper.getInstance() + .startRecentsActivity(intent, null, listener, null, null)); + } } diff --git a/quickstep/recents_ui_overrides/src/com/android/quickstep/inputconsumers/DeviceLockedInputConsumer.java b/quickstep/recents_ui_overrides/src/com/android/quickstep/inputconsumers/DeviceLockedInputConsumer.java index db2af59aca..3d763ab52c 100644 --- a/quickstep/recents_ui_overrides/src/com/android/quickstep/inputconsumers/DeviceLockedInputConsumer.java +++ b/quickstep/recents_ui_overrides/src/com/android/quickstep/inputconsumers/DeviceLockedInputConsumer.java @@ -23,6 +23,7 @@ import static com.android.launcher3.Utilities.squaredHypot; import static com.android.launcher3.Utilities.squaredTouchSlop; import static com.android.quickstep.MultiStateCallback.DEBUG_STATES; import static com.android.quickstep.WindowTransformSwipeHandler.MIN_PROGRESS_FOR_OVERVIEW; +import static com.android.quickstep.TouchInteractionService.startRecentsActivityAsync; import android.content.ComponentName; import android.content.Context; @@ -44,8 +45,6 @@ import com.android.quickstep.SwipeSharedState; import com.android.quickstep.util.ClipAnimationHelper; import com.android.quickstep.util.RecentsAnimationListenerSet; import com.android.quickstep.util.SwipeAnimationTargetSet; -import com.android.systemui.shared.system.ActivityManagerWrapper; -import com.android.systemui.shared.system.BackgroundExecutor; import com.android.systemui.shared.system.InputMonitorCompat; import com.android.systemui.shared.system.RemoteAnimationTargetCompat; @@ -209,9 +208,7 @@ public class DeviceLockedInputConsumer implements InputConsumer, .setFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_CLEAR_TASK); mInputMonitorCompat.pilferPointers(); - BackgroundExecutor.get().submit( - () -> ActivityManagerWrapper.getInstance().startRecentsActivity( - intent, null, newListenerSet, null, null)); + startRecentsActivityAsync(intent, newListenerSet); } @Override diff --git a/quickstep/recents_ui_overrides/src/com/android/quickstep/inputconsumers/FallbackNoButtonInputConsumer.java b/quickstep/recents_ui_overrides/src/com/android/quickstep/inputconsumers/FallbackNoButtonInputConsumer.java index d05ca2a161..d17bba49b5 100644 --- a/quickstep/recents_ui_overrides/src/com/android/quickstep/inputconsumers/FallbackNoButtonInputConsumer.java +++ b/quickstep/recents_ui_overrides/src/com/android/quickstep/inputconsumers/FallbackNoButtonInputConsumer.java @@ -27,6 +27,7 @@ import static com.android.quickstep.WindowTransformSwipeHandler.MAX_SWIPE_DURATI import static com.android.quickstep.WindowTransformSwipeHandler.MIN_PROGRESS_FOR_OVERVIEW; import static com.android.quickstep.WindowTransformSwipeHandler.MIN_SWIPE_DURATION; import static com.android.quickstep.inputconsumers.OtherActivityInputConsumer.QUICKSTEP_TOUCH_SLOP_RATIO; +import static com.android.quickstep.TouchInteractionService.startRecentsActivityAsync; import static com.android.systemui.shared.system.ActivityManagerWrapper.CLOSE_SYSTEM_WINDOWS_REASON_RECENTS; import android.animation.Animator; @@ -56,7 +57,6 @@ import com.android.quickstep.util.RecentsAnimationListenerSet; import com.android.quickstep.util.SwipeAnimationTargetSet; import com.android.quickstep.util.SwipeAnimationTargetSet.SwipeAnimationListener; import com.android.systemui.shared.system.ActivityManagerWrapper; -import com.android.systemui.shared.system.BackgroundExecutor; import com.android.systemui.shared.system.InputMonitorCompat; import com.android.systemui.shared.system.RemoteAnimationTargetCompat; @@ -222,9 +222,7 @@ public class FallbackNoButtonInputConsumer implements InputConsumer, SwipeAnimat mSwipeSharedState.newRecentsAnimationListenerSet(); listenerSet.addListener(this); Intent homeIntent = mOverviewComponentObserver.getHomeIntent(); - BackgroundExecutor.get().submit( - () -> ActivityManagerWrapper.getInstance().startRecentsActivity( - homeIntent, null, listenerSet, null, null)); + startRecentsActivityAsync(homeIntent, listenerSet); ActivityManagerWrapper.getInstance().closeSystemWindows( CLOSE_SYSTEM_WINDOWS_REASON_RECENTS); diff --git a/quickstep/recents_ui_overrides/src/com/android/quickstep/inputconsumers/OtherActivityInputConsumer.java b/quickstep/recents_ui_overrides/src/com/android/quickstep/inputconsumers/OtherActivityInputConsumer.java index 4c137d3bf9..a4d2f39d29 100644 --- a/quickstep/recents_ui_overrides/src/com/android/quickstep/inputconsumers/OtherActivityInputConsumer.java +++ b/quickstep/recents_ui_overrides/src/com/android/quickstep/inputconsumers/OtherActivityInputConsumer.java @@ -28,6 +28,7 @@ import static com.android.launcher3.Utilities.squaredHypot; import static com.android.launcher3.util.RaceConditionTracker.ENTER; import static com.android.launcher3.util.RaceConditionTracker.EXIT; import static com.android.quickstep.TouchInteractionService.TOUCH_INTERACTION_LOG; +import static com.android.quickstep.TouchInteractionService.startRecentsActivityAsync; import static com.android.systemui.shared.system.ActivityManagerWrapper.CLOSE_SYSTEM_WINDOWS_REASON_RECENTS; import android.annotation.TargetApi; @@ -61,7 +62,6 @@ import com.android.quickstep.util.MotionPauseDetector; import com.android.quickstep.util.NavBarPosition; import com.android.quickstep.util.RecentsAnimationListenerSet; import com.android.systemui.shared.system.ActivityManagerWrapper; -import com.android.systemui.shared.system.BackgroundExecutor; import com.android.systemui.shared.system.InputConsumerController; import com.android.systemui.shared.system.InputMonitorCompat; @@ -352,9 +352,7 @@ public class OtherActivityInputConsumer extends ContextWrapper implements InputC RecentsAnimationListenerSet newListenerSet = mSwipeSharedState.newRecentsAnimationListenerSet(); newListenerSet.addListener(handler); - BackgroundExecutor.get().submit( - () -> ActivityManagerWrapper.getInstance().startRecentsActivity( - mHomeIntent, null, newListenerSet, null, null)); + startRecentsActivityAsync(mHomeIntent, newListenerSet); } } diff --git a/quickstep/recents_ui_overrides/src/com/android/quickstep/views/RecentsView.java b/quickstep/recents_ui_overrides/src/com/android/quickstep/views/RecentsView.java index 6a9abd5455..432f8a1355 100644 --- a/quickstep/recents_ui_overrides/src/com/android/quickstep/views/RecentsView.java +++ b/quickstep/recents_ui_overrides/src/com/android/quickstep/views/RecentsView.java @@ -37,6 +37,7 @@ import static com.android.launcher3.userevent.nano.LauncherLogProto.Action.Touch import static com.android.launcher3.userevent.nano.LauncherLogProto.ControlType.CLEAR_ALL_BUTTON; import static com.android.launcher3.util.SystemUiController.UI_STATE_OVERVIEW; import static com.android.quickstep.TaskUtils.checkCurrentOrManagedUserId; +import static com.android.quickstep.TouchInteractionService.BACKGROUND_EXECUTOR; import android.animation.Animator; import android.animation.AnimatorSet; @@ -108,7 +109,6 @@ import com.android.quickstep.util.ClipAnimationHelper; import com.android.systemui.shared.recents.model.Task; import com.android.systemui.shared.recents.model.ThumbnailData; import com.android.systemui.shared.system.ActivityManagerWrapper; -import com.android.systemui.shared.system.BackgroundExecutor; import com.android.systemui.shared.system.LauncherEventUtil; import com.android.systemui.shared.system.PackageManagerWrapper; import com.android.systemui.shared.system.SyncRtSurfaceTransactionApplierCompat; @@ -226,7 +226,7 @@ public abstract class RecentsView extends PagedView impl return; } - BackgroundExecutor.get().submit(() -> { + BACKGROUND_EXECUTOR.execute(() -> { TaskView taskView = getTaskView(taskId); if (taskView == null) { return; diff --git a/quickstep/src/com/android/quickstep/RecentTasksList.java b/quickstep/src/com/android/quickstep/RecentTasksList.java index f27ba85388..7a1d0e83f6 100644 --- a/quickstep/src/com/android/quickstep/RecentTasksList.java +++ b/quickstep/src/com/android/quickstep/RecentTasksList.java @@ -16,6 +16,8 @@ package com.android.quickstep; +import static com.android.quickstep.TouchInteractionService.BACKGROUND_EXECUTOR; + import android.annotation.TargetApi; import android.app.ActivityManager; import android.content.Context; @@ -25,7 +27,6 @@ import android.util.SparseBooleanArray; import com.android.launcher3.MainThreadExecutor; import com.android.systemui.shared.recents.model.Task; import com.android.systemui.shared.system.ActivityManagerWrapper; -import com.android.systemui.shared.system.BackgroundExecutor; import com.android.systemui.shared.system.KeyguardManagerCompat; import com.android.systemui.shared.system.RecentTaskInfoCompat; import com.android.systemui.shared.system.TaskDescriptionCompat; @@ -43,7 +44,6 @@ public class RecentTasksList extends TaskStackChangeListener { private final KeyguardManagerCompat mKeyguardManager; private final MainThreadExecutor mMainThreadExecutor; - private final BackgroundExecutor mBgThreadExecutor; // The list change id, increments as the task list changes in the system private int mChangeId; @@ -56,7 +56,6 @@ public class RecentTasksList extends TaskStackChangeListener { public RecentTasksList(Context context) { mMainThreadExecutor = new MainThreadExecutor(); - mBgThreadExecutor = BackgroundExecutor.get(); mKeyguardManager = new KeyguardManagerCompat(context); mChangeId = 1; ActivityManagerWrapper.getInstance().registerTaskStackListener(this); @@ -67,7 +66,7 @@ public class RecentTasksList extends TaskStackChangeListener { */ public void getTaskKeys(int numTasks, Consumer> callback) { // Kick off task loading in the background - mBgThreadExecutor.submit(() -> { + BACKGROUND_EXECUTOR.execute(() -> { ArrayList tasks = loadTasksInBackground(numTasks, true /* loadKeysOnly */); mMainThreadExecutor.execute(() -> callback.accept(tasks)); }); @@ -93,7 +92,7 @@ public class RecentTasksList extends TaskStackChangeListener { } // Kick off task loading in the background - mBgThreadExecutor.submit(() -> { + BACKGROUND_EXECUTOR.execute(() -> { ArrayList tasks = loadTasksInBackground(Integer.MAX_VALUE, loadKeysOnly); mMainThreadExecutor.execute(() -> { From 6b0eb38461ac061bd9a3281c205a45d8f3faa9f2 Mon Sep 17 00:00:00 2001 From: Sunny Goyal Date: Tue, 9 Jul 2019 17:30:22 -0700 Subject: [PATCH 025/108] Swipe-up support for 3P Launcher On swipe up, we start a rencets transition to the current launcher app. At the end of the transition, if the user is going to recents, we start overview activity. Bug: 137197916 Change-Id: Ie5ed848879ad965dcab2780a05d649e3be066568 --- quickstep/AndroidManifest.xml | 1 + .../android/quickstep/BaseSwipeUpHandler.java | 101 +++++++++ .../android/quickstep/RecentsActivity.java | 21 ++ .../WindowTransformSwipeHandler.java | 69 +----- .../FallbackNoButtonInputConsumer.java | 199 ++++++++++++------ .../quickstep/util/ClipAnimationHelper.java | 28 ++- .../android/quickstep/util/ObjectWrapper.java | 41 ++++ 7 files changed, 325 insertions(+), 135 deletions(-) create mode 100644 quickstep/recents_ui_overrides/src/com/android/quickstep/BaseSwipeUpHandler.java create mode 100644 quickstep/recents_ui_overrides/src/com/android/quickstep/util/ObjectWrapper.java diff --git a/quickstep/AndroidManifest.xml b/quickstep/AndroidManifest.xml index 332e0fa360..546548036e 100644 --- a/quickstep/AndroidManifest.xml +++ b/quickstep/AndroidManifest.xml @@ -23,6 +23,7 @@ package="com.android.launcher3" > + mVibrator.vibrate(effect)); + } + + protected float getShiftForDisplacement(float displacement) { + // We are moving in the negative x/y direction + displacement = -displacement; + if (displacement > mTransitionDragLength * mDragLengthFactor && mTransitionDragLength > 0) { + return mDragLengthFactor; + } else { + float translation = Math.max(displacement, 0); + float shift = mTransitionDragLength == 0 ? 0 : translation / mTransitionDragLength; + if (shift > DRAG_LENGTH_FACTOR_START_PULLBACK) { + float pullbackProgress = Utilities.getProgress(shift, + DRAG_LENGTH_FACTOR_START_PULLBACK, mDragLengthFactor); + pullbackProgress = PULLBACK_INTERPOLATOR.getInterpolation(pullbackProgress); + shift = DRAG_LENGTH_FACTOR_START_PULLBACK + pullbackProgress + * (DRAG_LENGTH_FACTOR_MAX_PULLBACK - DRAG_LENGTH_FACTOR_START_PULLBACK); + } + return shift; + } + } +} diff --git a/quickstep/recents_ui_overrides/src/com/android/quickstep/RecentsActivity.java b/quickstep/recents_ui_overrides/src/com/android/quickstep/RecentsActivity.java index fc29a5663b..52e8ba26d0 100644 --- a/quickstep/recents_ui_overrides/src/com/android/quickstep/RecentsActivity.java +++ b/quickstep/recents_ui_overrides/src/com/android/quickstep/RecentsActivity.java @@ -28,8 +28,10 @@ import android.animation.Animator; import android.animation.AnimatorListenerAdapter; import android.animation.AnimatorSet; import android.app.ActivityOptions; +import android.content.Intent; import android.content.res.Configuration; import android.os.Handler; +import android.os.IBinder; import android.os.Looper; import android.view.View; @@ -42,7 +44,9 @@ import com.android.launcher3.views.BaseDragLayer; import com.android.quickstep.fallback.FallbackRecentsView; import com.android.quickstep.fallback.RecentsRootView; import com.android.quickstep.util.ClipAnimationHelper; +import com.android.quickstep.util.ObjectWrapper; import com.android.quickstep.views.TaskView; +import com.android.systemui.shared.recents.model.ThumbnailData; import com.android.systemui.shared.system.ActivityOptionsCompat; import com.android.systemui.shared.system.RemoteAnimationAdapterCompat; import com.android.systemui.shared.system.RemoteAnimationRunnerCompat; @@ -54,6 +58,9 @@ import com.android.systemui.shared.system.RemoteAnimationTargetCompat; */ public final class RecentsActivity extends BaseRecentsActivity { + public static final String EXTRA_THUMBNAIL = "thumbnailData"; + public static final String EXTRA_TASK_ID = "taskID"; + private Handler mUiHandler = new Handler(Looper.getMainLooper()); private RecentsRootView mRecentsRootView; private FallbackRecentsView mFallbackRecentsView; @@ -78,6 +85,20 @@ public final class RecentsActivity extends BaseRecentsActivity { } } + @Override + protected void onNewIntent(Intent intent) { + int taskID = intent.getIntExtra(EXTRA_TASK_ID, 0); + IBinder thumbnail = intent.getExtras().getBinder(EXTRA_THUMBNAIL); + if (taskID != 0 && thumbnail instanceof ObjectWrapper) { + ThumbnailData thumbnailData = ((ObjectWrapper) thumbnail).get(); + mFallbackRecentsView.showCurrentTask(taskID); + mFallbackRecentsView.updateThumbnail(taskID, thumbnailData); + } + intent.removeExtra(EXTRA_TASK_ID); + intent.removeExtra(EXTRA_THUMBNAIL); + super.onNewIntent(intent); + } + @Override protected void onHandleConfigChanged() { super.onHandleConfigChanged(); diff --git a/quickstep/recents_ui_overrides/src/com/android/quickstep/WindowTransformSwipeHandler.java b/quickstep/recents_ui_overrides/src/com/android/quickstep/WindowTransformSwipeHandler.java index ac7ba3fc3d..da9c6cb5fe 100644 --- a/quickstep/recents_ui_overrides/src/com/android/quickstep/WindowTransformSwipeHandler.java +++ b/quickstep/recents_ui_overrides/src/com/android/quickstep/WindowTransformSwipeHandler.java @@ -43,7 +43,6 @@ import static com.android.systemui.shared.system.QuickStepContract.SYSUI_STATE_O import android.animation.Animator; import android.animation.AnimatorSet; -import android.animation.ObjectAnimator; import android.animation.TimeInterpolator; import android.animation.ValueAnimator; import android.annotation.TargetApi; @@ -59,7 +58,6 @@ import android.os.Handler; import android.os.Looper; import android.os.SystemClock; import android.util.Log; -import android.view.HapticFeedbackConstants; import android.view.MotionEvent; import android.view.View; import android.view.View.OnApplyWindowInsetsListener; @@ -97,7 +95,7 @@ import com.android.quickstep.ActivityControlHelper.HomeAnimationFactory; import com.android.quickstep.SysUINavigationMode.Mode; import com.android.quickstep.inputconsumers.InputConsumer; import com.android.quickstep.inputconsumers.OverviewInputConsumer; -import com.android.quickstep.util.ClipAnimationHelper; +import com.android.quickstep.util.ClipAnimationHelper.TargetAlphaProvider; import com.android.quickstep.util.RectFSpringAnim; import com.android.quickstep.util.RemoteAnimationTargetSet; import com.android.quickstep.util.SwipeAnimationTargetSet; @@ -112,11 +110,10 @@ import com.android.systemui.shared.system.RemoteAnimationTargetCompat; import com.android.systemui.shared.system.SyncRtSurfaceTransactionApplierCompat; import com.android.systemui.shared.system.WindowCallbacksCompat; -import java.util.function.BiFunction; import java.util.function.Consumer; @TargetApi(Build.VERSION_CODES.O) -public class WindowTransformSwipeHandler +public class WindowTransformSwipeHandler extends BaseSwipeUpHandler implements SwipeAnimationListener, OnApplyWindowInsetsListener { private static final String TAG = WindowTransformSwipeHandler.class.getSimpleName(); @@ -220,30 +217,17 @@ public class WindowTransformSwipeHandler private static final long SHELF_ANIM_DURATION = 240; public static final long RECENTS_ATTACH_DURATION = 300; - // Start resisting when swiping past this factor of mTransitionDragLength. - private static final float DRAG_LENGTH_FACTOR_START_PULLBACK = 1.4f; - // This is how far down we can scale down, where 0f is full screen and 1f is recents. - private static final float DRAG_LENGTH_FACTOR_MAX_PULLBACK = 1.8f; - private static final Interpolator PULLBACK_INTERPOLATOR = DEACCEL; - /** * Used as the page index for logging when we return to the last task at the end of the gesture. */ private static final int LOG_NO_OP_PAGE_INDEX = -1; - private final ClipAnimationHelper mClipAnimationHelper; - private final ClipAnimationHelper.TransformParams mTransformParams; - private Runnable mGestureEndCallback; private GestureEndTarget mGestureEndTarget; // Either RectFSpringAnim (if animating home) or ObjectAnimator (from mCurrentShift) otherwise private RunningWindowAnim mRunningWindowAnim; private boolean mIsShelfPeeking; private DeviceProfile mDp; - // The distance needed to drag to reach the task size in recents. - private int mTransitionDragLength; - // How much further we can drag past recents, as a factor of mTransitionDragLength. - private float mDragLengthFactor = 1; // Shift in the range of [0, 1]. // 0 => preview snapShot is completely visible, and hotseat is completely translated down @@ -256,7 +240,6 @@ public class WindowTransformSwipeHandler private final Handler mMainThreadHandler = MAIN_THREAD_EXECUTOR.getHandler(); - private final Context mContext; private final ActivityControlHelper mActivityControlHelper; private final ActivityInitListener mActivityInitListener; @@ -294,7 +277,7 @@ public class WindowTransformSwipeHandler public WindowTransformSwipeHandler(RunningTaskInfo runningTaskInfo, Context context, long touchTimeMs, ActivityControlHelper controller, boolean continuingLastGesture, InputConsumerController inputConsumer) { - mContext = context; + super(context); mRunningTaskId = runningTaskInfo.id; mTouchTimeMs = touchTimeMs; mActivityControlHelper = controller; @@ -303,8 +286,6 @@ public class WindowTransformSwipeHandler mContinuingLastGesture = continuingLastGesture; mRecentsAnimationWrapper = new RecentsAnimationWrapper(inputConsumer, this::createNewInputProxyHandler); - mClipAnimationHelper = new ClipAnimationHelper(context); - mTransformParams = new ClipAnimationHelper.TransformParams(); mMode = SysUINavigationMode.getMode(context); initStateCallbacks(); @@ -394,18 +375,6 @@ public class WindowTransformSwipeHandler } } - private long getFadeInDuration() { - if (mCurrentShift.getCurrentAnimation() != null) { - ObjectAnimator anim = mCurrentShift.getCurrentAnimation(); - long theirDuration = anim.getDuration() - anim.getCurrentPlayTime(); - - // TODO: Find a better heuristic - return Math.min(MAX_SWIPE_DURATION, Math.max(theirDuration, MIN_SWIPE_DURATION)); - } else { - return MAX_SWIPE_DURATION; - } - } - public void initWhenReady() { mActivityInitListener.register(); } @@ -583,22 +552,7 @@ public class WindowTransformSwipeHandler @UiThread public void updateDisplacement(float displacement) { - // We are moving in the negative x/y direction - displacement = -displacement; - if (displacement > mTransitionDragLength * mDragLengthFactor && mTransitionDragLength > 0) { - mCurrentShift.updateValue(mDragLengthFactor); - } else { - float translation = Math.max(displacement, 0); - float shift = mTransitionDragLength == 0 ? 0 : translation / mTransitionDragLength; - if (shift > DRAG_LENGTH_FACTOR_START_PULLBACK) { - float pullbackProgress = Utilities.getProgress(shift, - DRAG_LENGTH_FACTOR_START_PULLBACK, mDragLengthFactor); - pullbackProgress = PULLBACK_INTERPOLATOR.getInterpolation(pullbackProgress); - shift = DRAG_LENGTH_FACTOR_START_PULLBACK + pullbackProgress - * (DRAG_LENGTH_FACTOR_MAX_PULLBACK - DRAG_LENGTH_FACTOR_START_PULLBACK); - } - mCurrentShift.updateValue(shift); - } + mCurrentShift.updateValue(getShiftForDisplacement(displacement)); } public void onMotionPauseChanged(boolean isPaused) { @@ -666,9 +620,8 @@ public class WindowTransformSwipeHandler if (mIsShelfPeeking != wasShelfPeeking) { maybeUpdateRecentsAttachedState(); } - if (mRecentsView != null && shelfState.shouldPreformHaptic) { - mRecentsView.performHapticFeedback(HapticFeedbackConstants.VIRTUAL_KEY, - HapticFeedbackConstants.FLAG_IGNORE_VIEW_SETTING); + if (shelfState.shouldPreformHaptic) { + performHapticFeedback(); } } @@ -722,9 +675,8 @@ public class WindowTransformSwipeHandler final boolean passed = mCurrentShift.value >= MIN_PROGRESS_FOR_OVERVIEW; if (passed != mPassedOverviewThreshold) { mPassedOverviewThreshold = passed; - if (mRecentsView != null && mMode != Mode.NO_BUTTON) { - mRecentsView.performHapticFeedback(HapticFeedbackConstants.VIRTUAL_KEY, - HapticFeedbackConstants.FLAG_IGNORE_VIEW_SETTING); + if (mMode != Mode.NO_BUTTON) { + performHapticFeedback(); } } @@ -1450,13 +1402,12 @@ public class WindowTransformSwipeHandler mGestureEndCallback = gestureEndCallback; } - private void setTargetAlphaProvider( - BiFunction provider) { + private void setTargetAlphaProvider(TargetAlphaProvider provider) { mClipAnimationHelper.setTaskAlphaCallback(provider); updateFinalShift(); } - public static float getHiddenTargetAlpha(RemoteAnimationTargetCompat app, Float expectedAlpha) { + public static float getHiddenTargetAlpha(RemoteAnimationTargetCompat app, float expectedAlpha) { if (!isNotInRecents(app)) { return 0; } diff --git a/quickstep/recents_ui_overrides/src/com/android/quickstep/inputconsumers/FallbackNoButtonInputConsumer.java b/quickstep/recents_ui_overrides/src/com/android/quickstep/inputconsumers/FallbackNoButtonInputConsumer.java index d17bba49b5..cdd91b78f4 100644 --- a/quickstep/recents_ui_overrides/src/com/android/quickstep/inputconsumers/FallbackNoButtonInputConsumer.java +++ b/quickstep/recents_ui_overrides/src/com/android/quickstep/inputconsumers/FallbackNoButtonInputConsumer.java @@ -23,22 +23,27 @@ import static android.view.MotionEvent.ACTION_POINTER_UP; import static android.view.MotionEvent.ACTION_UP; import static android.view.MotionEvent.INVALID_POINTER_ID; -import static com.android.quickstep.WindowTransformSwipeHandler.MAX_SWIPE_DURATION; +import static com.android.quickstep.RecentsActivity.EXTRA_TASK_ID; +import static com.android.quickstep.RecentsActivity.EXTRA_THUMBNAIL; import static com.android.quickstep.WindowTransformSwipeHandler.MIN_PROGRESS_FOR_OVERVIEW; -import static com.android.quickstep.WindowTransformSwipeHandler.MIN_SWIPE_DURATION; +import static com.android.quickstep.inputconsumers.FallbackNoButtonInputConsumer.GestureEndTarget.HOME; +import static com.android.quickstep.inputconsumers.FallbackNoButtonInputConsumer.GestureEndTarget.LAST_TASK; +import static com.android.quickstep.inputconsumers.FallbackNoButtonInputConsumer.GestureEndTarget.RECENTS; import static com.android.quickstep.inputconsumers.OtherActivityInputConsumer.QUICKSTEP_TOUCH_SLOP_RATIO; import static com.android.quickstep.TouchInteractionService.startRecentsActivityAsync; import static com.android.systemui.shared.system.ActivityManagerWrapper.CLOSE_SYSTEM_WINDOWS_REASON_RECENTS; import android.animation.Animator; import android.animation.AnimatorListenerAdapter; -import android.animation.ValueAnimator; +import android.animation.AnimatorSet; import android.app.ActivityManager.RunningTaskInfo; +import android.app.ActivityOptions; import android.content.Context; import android.content.Intent; import android.graphics.PointF; import android.graphics.Rect; import android.graphics.RectF; +import android.os.Bundle; import android.view.MotionEvent; import android.view.VelocityTracker; import android.view.ViewConfiguration; @@ -48,38 +53,50 @@ import com.android.launcher3.DeviceProfile; import com.android.launcher3.InvariantDeviceProfile; import com.android.launcher3.R; import com.android.quickstep.ActivityControlHelper; +import com.android.quickstep.AnimatedFloat; +import com.android.quickstep.BaseSwipeUpHandler; import com.android.quickstep.OverviewComponentObserver; import com.android.quickstep.SwipeSharedState; -import com.android.quickstep.util.ClipAnimationHelper; -import com.android.quickstep.util.ClipAnimationHelper.TransformParams; +import com.android.quickstep.util.MotionPauseDetector; import com.android.quickstep.util.NavBarPosition; +import com.android.quickstep.util.ObjectWrapper; import com.android.quickstep.util.RecentsAnimationListenerSet; import com.android.quickstep.util.SwipeAnimationTargetSet; import com.android.quickstep.util.SwipeAnimationTargetSet.SwipeAnimationListener; +import com.android.systemui.shared.recents.model.ThumbnailData; import com.android.systemui.shared.system.ActivityManagerWrapper; import com.android.systemui.shared.system.InputMonitorCompat; import com.android.systemui.shared.system.RemoteAnimationTargetCompat; -public class FallbackNoButtonInputConsumer implements InputConsumer, SwipeAnimationListener { +public class FallbackNoButtonInputConsumer extends BaseSwipeUpHandler + implements InputConsumer, SwipeAnimationListener { - private static final int STATE_NOT_FINISHED = 0; - private static final int STATE_FINISHED_TO_HOME = 1; - private static final int STATE_FINISHED_TO_APP = 2; + public enum GestureEndTarget { + HOME(3, 100, 1), + RECENTS(1, 300, 0), + LAST_TASK(0, 150, 1); - private static final float PROGRESS_TO_END_GESTURE = -2; + private final float mEndProgress; + private final long mDurationMultiplier; + private final float mLauncherAlpha; + GestureEndTarget(float endProgress, long durationMultiplier, float launcherAlpha) { + mEndProgress = endProgress; + mDurationMultiplier = durationMultiplier; + mLauncherAlpha = launcherAlpha; + } + } private final ActivityControlHelper mActivityControlHelper; private final InputMonitorCompat mInputMonitor; - private final Context mContext; private final NavBarPosition mNavBarPosition; private final SwipeSharedState mSwipeSharedState; private final OverviewComponentObserver mOverviewComponentObserver; private final int mRunningTaskId; - private final ClipAnimationHelper mClipAnimationHelper; - private final TransformParams mTransformParams = new TransformParams(); - private final float mTransitionDragLength; private final DeviceProfile mDP; + private final MotionPauseDetector mMotionPauseDetector; + private final float mMotionPauseMinDisplacement; + private final Rect mTargetRect = new Rect(); private final RectF mSwipeTouchRegion; private final boolean mDisableHorizontalSwipe; @@ -87,6 +104,9 @@ public class FallbackNoButtonInputConsumer implements InputConsumer, SwipeAnimat private final PointF mDownPos = new PointF(); private final PointF mLastPos = new PointF(); + private final AnimatedFloat mLauncherAlpha = new AnimatedFloat(this::onLauncherAlphaChanged); + private final AnimatedFloat mProgress = new AnimatedFloat(this::onProgressChanged); + private int mActivePointerId = -1; // Slop used to determine when we say that the gesture has started. private boolean mPassedPilferInputSlop; @@ -99,21 +119,26 @@ public class FallbackNoButtonInputConsumer implements InputConsumer, SwipeAnimat // Might be displacement in X or Y, depending on the direction we are swiping from the nav bar. private float mStartDisplacement; private SwipeAnimationTargetSet mSwipeAnimationTargetSet; - private float mProgress; - private int mState = STATE_NOT_FINISHED; + private boolean mIsMotionPaused = false; + private GestureEndTarget mEndTarget; public FallbackNoButtonInputConsumer(Context context, ActivityControlHelper activityControlHelper, InputMonitorCompat inputMonitor, SwipeSharedState swipeSharedState, RectF swipeTouchRegion, OverviewComponentObserver overviewComponentObserver, boolean disableHorizontalSwipe, RunningTaskInfo runningTaskInfo) { - mContext = context; + super(context); mActivityControlHelper = activityControlHelper; mInputMonitor = inputMonitor; mOverviewComponentObserver = overviewComponentObserver; mRunningTaskId = runningTaskInfo.id; + mMotionPauseDetector = new MotionPauseDetector(context); + mMotionPauseMinDisplacement = context.getResources().getDimension( + R.dimen.motion_pause_detector_min_displacement_from_app); + mMotionPauseDetector.setOnMotionPauseListener(this::onMotionPauseChanged); + mSwipeSharedState = swipeSharedState; mSwipeTouchRegion = swipeTouchRegion; mDisableHorizontalSwipe = disableHorizontalSwipe; @@ -124,13 +149,11 @@ public class FallbackNoButtonInputConsumer implements InputConsumer, SwipeAnimat mTouchSlop = QUICKSTEP_TOUCH_SLOP_RATIO * ViewConfiguration.get(context).getScaledTouchSlop(); - mClipAnimationHelper = new ClipAnimationHelper(context); - mDP = InvariantDeviceProfile.INSTANCE.get(context).getDeviceProfile(context).copy(context); - Rect tempRect = new Rect(); - mTransitionDragLength = mActivityControlHelper.getSwipeUpDestinationAndLength( - mDP, context, tempRect); - mClipAnimationHelper.updateTargetRect(tempRect); + mLauncherAlpha.value = 1; + + mClipAnimationHelper.setBaseAlphaCallback((t, a) -> mLauncherAlpha.value); + initTransitionTarget(); } @Override @@ -138,6 +161,19 @@ public class FallbackNoButtonInputConsumer implements InputConsumer, SwipeAnimat return TYPE_FALLBACK_NO_BUTTON; } + private void onLauncherAlphaChanged() { + if (mSwipeAnimationTargetSet != null && mEndTarget == null) { + mClipAnimationHelper.applyTransform(mSwipeAnimationTargetSet, mTransformParams); + } + } + + private void onMotionPauseChanged(boolean isPaused) { + mIsMotionPaused = isPaused; + mLauncherAlpha.animateToValue(mLauncherAlpha.value, isPaused ? 0 : 1) + .setDuration(150).start(); + performHapticFeedback(); + } + @Override public void onMotionEvent(MotionEvent ev) { if (mVelocityTracker == null) { @@ -147,6 +183,7 @@ public class FallbackNoButtonInputConsumer implements InputConsumer, SwipeAnimat mVelocityTracker.addMovement(ev); if (ev.getActionMasked() == ACTION_POINTER_UP) { mVelocityTracker.clear(); + mMotionPauseDetector.clear(); } switch (ev.getActionMasked()) { @@ -204,6 +241,9 @@ public class FallbackNoButtonInputConsumer implements InputConsumer, SwipeAnimat } } else { updateDisplacement(displacement - mStartDisplacement); + mMotionPauseDetector.setDisallowPause( + -displacement < mMotionPauseMinDisplacement); + mMotionPauseDetector.addPosition(displacement, ev.getEventTime()); } break; } @@ -230,9 +270,11 @@ public class FallbackNoButtonInputConsumer implements InputConsumer, SwipeAnimat } private void updateDisplacement(float displacement) { - mProgress = displacement / mTransitionDragLength; - mTransformParams.setProgress(mProgress); + mProgress.updateValue(getShiftForDisplacement(displacement)); + } + private void onProgressChanged() { + mTransformParams.setProgress(mProgress.value); if (mSwipeAnimationTargetSet != null) { mClipAnimationHelper.applyTransform(mSwipeAnimationTargetSet, mTransformParams); } @@ -251,7 +293,7 @@ public class FallbackNoButtonInputConsumer implements InputConsumer, SwipeAnimat */ private void finishTouchTracking(MotionEvent ev) { if (ev.getAction() == ACTION_CANCEL) { - mState = STATE_FINISHED_TO_APP; + mEndTarget = LAST_TASK; } else { mVelocityTracker.computeCurrentVelocity(1000, ViewConfiguration.get(mContext).getScaledMaximumFlingVelocity()); @@ -264,53 +306,68 @@ public class FallbackNoButtonInputConsumer implements InputConsumer, SwipeAnimat .getDimension(R.dimen.quickstep_fling_threshold_velocity); boolean isFling = Math.abs(velocity) > flingThreshold; - boolean goingHome; - if (!isFling) { - goingHome = -mProgress >= MIN_PROGRESS_FOR_OVERVIEW; + if (isFling) { + mEndTarget = velocity < 0 ? HOME : LAST_TASK; + } else if (mIsMotionPaused) { + mEndTarget = RECENTS; } else { - goingHome = velocity < 0; - } - - if (goingHome) { - mState = STATE_FINISHED_TO_HOME; - } else { - mState = STATE_FINISHED_TO_APP; + mEndTarget = mProgress.value >= MIN_PROGRESS_FOR_OVERVIEW ? HOME : LAST_TASK; } } if (mSwipeAnimationTargetSet != null) { finishAnimationTargetSet(); } + mMotionPauseDetector.clear(); + } + + private void finishAnimationTargetSetAnimationComplete() { + switch (mEndTarget) { + case HOME: + mSwipeAnimationTargetSet.finishController(true, null, true); + break; + case LAST_TASK: + mSwipeAnimationTargetSet.finishController(false, null, false); + break; + case RECENTS: { + ThumbnailData thumbnail = + mSwipeAnimationTargetSet.controller.screenshotTask(mRunningTaskId); + mSwipeAnimationTargetSet.controller.setCancelWithDeferredScreenshot(true); + + ActivityOptions options = ActivityOptions.makeCustomAnimation(mContext, 0, 0); + Bundle extras = new Bundle(); + extras.putBinder(EXTRA_THUMBNAIL, new ObjectWrapper<>(thumbnail)); + extras.putInt(EXTRA_TASK_ID, mRunningTaskId); + + Intent intent = new Intent(mOverviewComponentObserver.getOverviewIntent()) + .putExtras(extras); + mContext.startActivity(intent, options.toBundle()); + mSwipeAnimationTargetSet.controller.cleanupScreenshot(); + break; + } + } } private void finishAnimationTargetSet() { - if (mState == STATE_FINISHED_TO_APP) { - mSwipeAnimationTargetSet.finishController(false, null, false); - } else { - if (mProgress < PROGRESS_TO_END_GESTURE) { - mSwipeAnimationTargetSet.finishController(true, null, true); - } else { - long duration = (long) (Math.min(mProgress - PROGRESS_TO_END_GESTURE, 1) - * MAX_SWIPE_DURATION / Math.abs(PROGRESS_TO_END_GESTURE)); - if (duration < 0) { - duration = MIN_SWIPE_DURATION; - } + float endProgress = mEndTarget.mEndProgress; - ValueAnimator anim = ValueAnimator.ofFloat(mProgress, PROGRESS_TO_END_GESTURE); - anim.addUpdateListener(a -> { - float p = (Float) anim.getAnimatedValue(); - mTransformParams.setProgress(p); - mClipAnimationHelper.applyTransform(mSwipeAnimationTargetSet, mTransformParams); - }); - anim.setDuration(duration); - anim.addListener(new AnimatorListenerAdapter() { - @Override - public void onAnimationEnd(Animator animation) { - mSwipeAnimationTargetSet.finishController(true, null, true); - } - }); - anim.start(); - } + if (mProgress.value != endProgress) { + AnimatorSet anim = new AnimatorSet(); + anim.play(mLauncherAlpha.animateToValue( + mLauncherAlpha.value, mEndTarget.mLauncherAlpha)); + anim.play(mProgress.animateToValue(mProgress.value, endProgress)); + + anim.setDuration((long) (mEndTarget.mDurationMultiplier * + Math.abs(endProgress - mProgress.value))); + anim.addListener(new AnimatorListenerAdapter() { + @Override + public void onAnimationEnd(Animator animation) { + finishAnimationTargetSetAnimationComplete(); + } + }); + anim.start(); + } else { + finishAnimationTargetSetAnimationComplete(); } } @@ -321,21 +378,29 @@ public class FallbackNoButtonInputConsumer implements InputConsumer, SwipeAnimat RemoteAnimationTargetCompat runningTaskTarget = targetSet.findTask(mRunningTaskId); mDP.updateIsSeascape(mContext.getSystemService(WindowManager.class)); + if (targetSet.homeContentInsets != null) { + mDP.updateInsets(targetSet.homeContentInsets); + } + if (runningTaskTarget != null) { mClipAnimationHelper.updateSource(overviewStackBounds, runningTaskTarget); } mClipAnimationHelper.prepareAnimation(mDP, false /* isOpening */); - - overviewStackBounds - .inset(-overviewStackBounds.width() / 5, -overviewStackBounds.height() / 5); - mClipAnimationHelper.updateTargetRect(overviewStackBounds); + initTransitionTarget(); mClipAnimationHelper.applyTransform(mSwipeAnimationTargetSet, mTransformParams); - if (mState != STATE_NOT_FINISHED) { + if (mEndTarget != null) { finishAnimationTargetSet(); } } + private void initTransitionTarget() { + mTransitionDragLength = mActivityControlHelper.getSwipeUpDestinationAndLength( + mDP, mContext, mTargetRect); + mDragLengthFactor = (float) mDP.heightPx / mTransitionDragLength; + mClipAnimationHelper.updateTargetRect(mTargetRect); + } + @Override public void onRecentsAnimationCanceled() { } diff --git a/quickstep/recents_ui_overrides/src/com/android/quickstep/util/ClipAnimationHelper.java b/quickstep/recents_ui_overrides/src/com/android/quickstep/util/ClipAnimationHelper.java index de671e04aa..f0a290333c 100644 --- a/quickstep/recents_ui_overrides/src/com/android/quickstep/util/ClipAnimationHelper.java +++ b/quickstep/recents_ui_overrides/src/com/android/quickstep/util/ClipAnimationHelper.java @@ -99,8 +99,8 @@ public class ClipAnimationHelper { // Whether to boost the opening animation target layers, or the closing private int mBoostModeTargetLayers = -1; - private BiFunction mTaskAlphaCallback = - (t, a1) -> a1; + private TargetAlphaProvider mTaskAlphaCallback = (t, a) -> a; + private TargetAlphaProvider mBaseAlphaCallback = (t, a) -> 1; public ClipAnimationHelper(Context context) { mWindowCornerRadius = getWindowCornerRadius(context.getResources()); @@ -187,12 +187,12 @@ public class ClipAnimationHelper { Rect crop = mTmpRect; crop.set(app.sourceContainerBounds); crop.offsetTo(0, 0); - float alpha = 1f; + float alpha; int layer = RemoteAnimationProvider.getLayer(app, mBoostModeTargetLayers); float cornerRadius = 0f; float scale = Math.max(params.currentRect.width(), mTargetRect.width()) / crop.width(); if (app.mode == targetSet.targetMode) { - alpha = mTaskAlphaCallback.apply(app, params.targetAlpha); + alpha = mTaskAlphaCallback.getAlpha(app, params.targetAlpha); if (app.activityType != RemoteAnimationTargetCompat.ACTIVITY_TYPE_HOME) { mTmpMatrix.setRectToRect(mSourceRect, params.currentRect, ScaleToFit.FILL); mTmpMatrix.postTranslate(app.position.x, app.position.y); @@ -214,9 +214,12 @@ public class ClipAnimationHelper { // home target. alpha = 1 - (progress * params.targetAlpha); } - } else if (ENABLE_QUICKSTEP_LIVE_TILE.get() && launcherOnTop) { - crop = null; - layer = Integer.MAX_VALUE; + } else { + alpha = mBaseAlphaCallback.getAlpha(app, progress); + if (ENABLE_QUICKSTEP_LIVE_TILE.get() && launcherOnTop) { + crop = null; + layer = Integer.MAX_VALUE; + } } // Since radius is in Surface space, but we draw the rounded corners in screen space, we @@ -247,11 +250,14 @@ public class ClipAnimationHelper { } } - public void setTaskAlphaCallback( - BiFunction callback) { + public void setTaskAlphaCallback(TargetAlphaProvider callback) { mTaskAlphaCallback = callback; } + public void setBaseAlphaCallback(TargetAlphaProvider callback) { + mBaseAlphaCallback = callback; + } + public void fromTaskThumbnailView(TaskThumbnailView ttv, RecentsView rv) { fromTaskThumbnailView(ttv, rv, null); } @@ -357,6 +363,10 @@ public class ClipAnimationHelper { return mCurrentCornerRadius; } + public interface TargetAlphaProvider { + float getAlpha(RemoteAnimationTargetCompat target, float expectedAlpha); + } + public static class TransformParams { float progress; public float offsetX; diff --git a/quickstep/recents_ui_overrides/src/com/android/quickstep/util/ObjectWrapper.java b/quickstep/recents_ui_overrides/src/com/android/quickstep/util/ObjectWrapper.java new file mode 100644 index 0000000000..abfe3adbff --- /dev/null +++ b/quickstep/recents_ui_overrides/src/com/android/quickstep/util/ObjectWrapper.java @@ -0,0 +1,41 @@ +/* + * Copyright (C) 2019 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * 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.util; + +import android.os.Binder; +import android.os.IBinder; + +/** + * Utility class to pass non-parcealable objects within same process using parcealable payload. + * + * It wraps the object in a binder as binders are singleton within a process + */ +public class ObjectWrapper extends Binder { + + private final T mObject; + + public ObjectWrapper(T object) { + mObject = object; + } + + public T get() { + return mObject; + } + + public static IBinder wrap(Object obj) { + return new ObjectWrapper<>(obj); + } +} From c127dff1812fd5059ba16cf92de608c6f79de196 Mon Sep 17 00:00:00 2001 From: Sunny Goyal Date: Wed, 10 Jul 2019 13:16:43 -0700 Subject: [PATCH 026/108] Unifying FallbackNoButton input consumer with OtherActivityInputConsumer using a different handler This will allow us to use common logic for handling horizontal swipe Bug: 137197916 Change-Id: I6f9cba6e8728dd0669482906c4bf34270af2bc82 --- .../android/quickstep/BaseSwipeUpHandler.java | 73 ++++- .../android/quickstep/RecentsActivity.java | 6 + .../quickstep/TouchInteractionService.java | 49 +++- .../WindowTransformSwipeHandler.java | 73 +++-- .../FallbackNoButtonInputConsumer.java | 254 +++--------------- .../inputconsumers/InputConsumer.java | 2 - .../OtherActivityInputConsumer.java | 61 ++--- 7 files changed, 193 insertions(+), 325 deletions(-) diff --git a/quickstep/recents_ui_overrides/src/com/android/quickstep/BaseSwipeUpHandler.java b/quickstep/recents_ui_overrides/src/com/android/quickstep/BaseSwipeUpHandler.java index 6e4a40843f..d34b604a76 100644 --- a/quickstep/recents_ui_overrides/src/com/android/quickstep/BaseSwipeUpHandler.java +++ b/quickstep/recents_ui_overrides/src/com/android/quickstep/BaseSwipeUpHandler.java @@ -22,22 +22,32 @@ import static com.android.launcher3.anim.Interpolators.DEACCEL; import static com.android.quickstep.TouchInteractionService.BACKGROUND_EXECUTOR; import android.annotation.TargetApi; +import android.app.ActivityManager.RunningTaskInfo; import android.content.Context; +import android.graphics.PointF; import android.os.Build; import android.os.VibrationEffect; import android.os.Vibrator; import android.provider.Settings; +import android.view.MotionEvent; import android.view.animation.Interpolator; import com.android.launcher3.Utilities; +import com.android.launcher3.graphics.RotationMode; import com.android.quickstep.util.ClipAnimationHelper; import com.android.quickstep.util.ClipAnimationHelper.TransformParams; +import com.android.quickstep.util.SwipeAnimationTargetSet.SwipeAnimationListener; +import com.android.quickstep.views.RecentsView; + +import java.util.function.Consumer; + +import androidx.annotation.UiThread; /** * Base class for swipe up handler with some utility methods */ @TargetApi(Build.VERSION_CODES.Q) -public abstract class BaseSwipeUpHandler { +public abstract class BaseSwipeUpHandler implements SwipeAnimationListener { // Start resisting when swiping past this factor of mTransitionDragLength. private static final float DRAG_LENGTH_FACTOR_START_PULLBACK = 1.4f; @@ -57,6 +67,16 @@ public abstract class BaseSwipeUpHandler { private final Vibrator mVibrator; + // Shift in the range of [0, 1]. + // 0 => preview snapShot is completely visible, and hotseat is completely translated down + // 1 => preview snapShot is completely aligned with the recents view and hotseat is completely + // visible. + protected final AnimatedFloat mCurrentShift = new AnimatedFloat(this::updateFinalShift); + + protected RecentsView mRecentsView; + + protected Runnable mGestureEndCallback; + protected BaseSwipeUpHandler(Context context) { mContext = context; mClipAnimationHelper = new ClipAnimationHelper(context); @@ -80,14 +100,20 @@ public abstract class BaseSwipeUpHandler { BACKGROUND_EXECUTOR.execute(() -> mVibrator.vibrate(effect)); } - protected float getShiftForDisplacement(float displacement) { + public Consumer getRecentsViewDispatcher(RotationMode rotationMode) { + return mRecentsView != null ? mRecentsView.getEventDispatcher(rotationMode) : null; + } + + @UiThread + public void updateDisplacement(float displacement) { // We are moving in the negative x/y direction displacement = -displacement; + float shift; if (displacement > mTransitionDragLength * mDragLengthFactor && mTransitionDragLength > 0) { - return mDragLengthFactor; + shift = mDragLengthFactor; } else { float translation = Math.max(displacement, 0); - float shift = mTransitionDragLength == 0 ? 0 : translation / mTransitionDragLength; + shift = mTransitionDragLength == 0 ? 0 : translation / mTransitionDragLength; if (shift > DRAG_LENGTH_FACTOR_START_PULLBACK) { float pullbackProgress = Utilities.getProgress(shift, DRAG_LENGTH_FACTOR_START_PULLBACK, mDragLengthFactor); @@ -95,7 +121,44 @@ public abstract class BaseSwipeUpHandler { shift = DRAG_LENGTH_FACTOR_START_PULLBACK + pullbackProgress * (DRAG_LENGTH_FACTOR_MAX_PULLBACK - DRAG_LENGTH_FACTOR_START_PULLBACK); } - return shift; } + + mCurrentShift.updateValue(shift); + } + + public void setGestureEndCallback(Runnable gestureEndCallback) { + mGestureEndCallback = gestureEndCallback; + } + + /** + * Called when the value of {@link #mCurrentShift} changes + */ + public abstract void updateFinalShift(); + + + /** + * Called when motion pause is detected + */ + public abstract void onMotionPauseChanged(boolean isPaused); + + @UiThread + public void onGestureStarted() { } + + @UiThread + public abstract void onGestureCancelled(); + + @UiThread + public abstract void onGestureEnded(float endVelocity, PointF velocity, PointF downPos); + + public void onConsumerAboutToBeSwitched(SwipeSharedState sharedState) { } + + public void setIsLikelyToStartNewTask(boolean isLikelyToStartNewTask) { } + + public void initWhenReady() { } + + public interface Factory { + + BaseSwipeUpHandler newHandler(RunningTaskInfo runningTask, + long touchTimeMs, boolean continuingLastGesture); } } diff --git a/quickstep/recents_ui_overrides/src/com/android/quickstep/RecentsActivity.java b/quickstep/recents_ui_overrides/src/com/android/quickstep/RecentsActivity.java index 52e8ba26d0..61767e5f74 100644 --- a/quickstep/recents_ui_overrides/src/com/android/quickstep/RecentsActivity.java +++ b/quickstep/recents_ui_overrides/src/com/android/quickstep/RecentsActivity.java @@ -199,6 +199,12 @@ public final class RecentsActivity extends BaseRecentsActivity { mFallbackRecentsView.resetTaskVisuals(); } + @Override + protected void onStop() { + super.onStop(); + mFallbackRecentsView.reset(); + } + public void onTaskLaunched() { mFallbackRecentsView.resetTaskVisuals(); } diff --git a/quickstep/recents_ui_overrides/src/com/android/quickstep/TouchInteractionService.java b/quickstep/recents_ui_overrides/src/com/android/quickstep/TouchInteractionService.java index 0ef2f5c5ad..fafa4d34ca 100644 --- a/quickstep/recents_ui_overrides/src/com/android/quickstep/TouchInteractionService.java +++ b/quickstep/recents_ui_overrides/src/com/android/quickstep/TouchInteractionService.java @@ -239,6 +239,11 @@ public class TouchInteractionService extends Service implements private final InputConsumer mResetGestureInputConsumer = new ResetGestureInputConsumer(sSwipeSharedState); + private final BaseSwipeUpHandler.Factory mWindowTreansformFactory = + this::createWindowTransformSwipeHandler; + private final BaseSwipeUpHandler.Factory mFallbackNoButtonFactory = + this::createFallbackNoButtonSwipeHandler; + private ActivityManagerWrapper mAM; private RecentsModel mRecentsModel; private ISystemUiProxy mISystemUiProxy; @@ -623,10 +628,6 @@ public class TouchInteractionService extends Service implements } else if (mGestureBlockingActivity != null && runningTaskInfo != null && mGestureBlockingActivity.equals(runningTaskInfo.topActivity)) { return mResetGestureInputConsumer; - } else if (mMode == Mode.NO_BUTTON && !mOverviewComponentObserver.isHomeAndOverviewSame()) { - return new FallbackNoButtonInputConsumer(this, activityControl, - mInputMonitorCompat, sSwipeSharedState, mSwipeTouchRegion, - mOverviewComponentObserver, disableHorizontalSwipe(event), runningTaskInfo); } else { return createOtherActivityInputConsumer(event, runningTaskInfo); } @@ -639,17 +640,28 @@ public class TouchInteractionService extends Service implements && exclusionRegion.contains((int) event.getX(), (int) event.getY()); } - private OtherActivityInputConsumer createOtherActivityInputConsumer(MotionEvent event, + private InputConsumer createOtherActivityInputConsumer(MotionEvent event, RunningTaskInfo runningTaskInfo) { - final ActivityControlHelper activityControl = - mOverviewComponentObserver.getActivityControlHelper(); - boolean shouldDefer = activityControl.deferStartingActivity(mActiveNavBarRegion, event); - return new OtherActivityInputConsumer(this, runningTaskInfo, mRecentsModel, - mOverviewComponentObserver.getOverviewIntent(), activityControl, - shouldDefer, mOverviewCallbacks, mInputConsumer, this::onConsumerInactive, + final boolean shouldDefer; + final BaseSwipeUpHandler.Factory factory; + final Intent homeIntent; + + if (mMode == Mode.NO_BUTTON && !mOverviewComponentObserver.isHomeAndOverviewSame()) { + shouldDefer = true; + factory = mFallbackNoButtonFactory; + homeIntent = mOverviewComponentObserver.getHomeIntent(); + } else { + shouldDefer = mOverviewComponentObserver.getActivityControlHelper() + .deferStartingActivity(mActiveNavBarRegion, event); + factory = mWindowTreansformFactory; + homeIntent = mOverviewComponentObserver.getOverviewIntent(); + } + + return new OtherActivityInputConsumer(this, runningTaskInfo, homeIntent, + shouldDefer, mOverviewCallbacks, this::onConsumerInactive, sSwipeSharedState, mInputMonitorCompat, mSwipeTouchRegion, - disableHorizontalSwipe(event)); + disableHorizontalSwipe(event), factory); } private InputConsumer createDeviceLockedInputConsumer(RunningTaskInfo taskInfo) { @@ -788,6 +800,19 @@ public class TouchInteractionService extends Service implements } } + private BaseSwipeUpHandler createWindowTransformSwipeHandler(RunningTaskInfo runningTask, + long touchTimeMs, boolean continuingLastGesture) { + return new WindowTransformSwipeHandler( + runningTask, this, touchTimeMs, + mOverviewComponentObserver.getActivityControlHelper(), + continuingLastGesture, mInputConsumer, mRecentsModel); + } + + private BaseSwipeUpHandler createFallbackNoButtonSwipeHandler(RunningTaskInfo runningTask, + long touchTimeMs, boolean continuingLastGesture) { + return new FallbackNoButtonInputConsumer(this, mOverviewComponentObserver, runningTask); + } + public static void startRecentsActivityAsync(Intent intent, RecentsAnimationListener listener) { BACKGROUND_EXECUTOR.execute(() -> ActivityManagerWrapper.getInstance() .startRecentsActivity(intent, null, listener, null, null)); diff --git a/quickstep/recents_ui_overrides/src/com/android/quickstep/WindowTransformSwipeHandler.java b/quickstep/recents_ui_overrides/src/com/android/quickstep/WindowTransformSwipeHandler.java index da9c6cb5fe..9684eeca2f 100644 --- a/quickstep/recents_ui_overrides/src/com/android/quickstep/WindowTransformSwipeHandler.java +++ b/quickstep/recents_ui_overrides/src/com/android/quickstep/WindowTransformSwipeHandler.java @@ -58,7 +58,6 @@ import android.os.Handler; import android.os.Looper; import android.os.SystemClock; import android.util.Log; -import android.view.MotionEvent; import android.view.View; import android.view.View.OnApplyWindowInsetsListener; import android.view.ViewTreeObserver.OnDrawListener; @@ -66,10 +65,6 @@ import android.view.WindowInsets; import android.view.WindowManager; import android.view.animation.Interpolator; -import androidx.annotation.NonNull; -import androidx.annotation.Nullable; -import androidx.annotation.UiThread; - import com.android.launcher3.AbstractFloatingView; import com.android.launcher3.BaseDraggingActivity; import com.android.launcher3.DeviceProfile; @@ -79,7 +74,6 @@ import com.android.launcher3.Utilities; import com.android.launcher3.anim.AnimationSuccessListener; import com.android.launcher3.anim.AnimatorPlaybackController; import com.android.launcher3.anim.Interpolators; -import com.android.launcher3.graphics.RotationMode; import com.android.launcher3.logging.UserEventDispatcher; import com.android.launcher3.testing.TestProtocol; import com.android.launcher3.userevent.nano.LauncherLogProto.Action.Direction; @@ -99,9 +93,7 @@ import com.android.quickstep.util.ClipAnimationHelper.TargetAlphaProvider; import com.android.quickstep.util.RectFSpringAnim; import com.android.quickstep.util.RemoteAnimationTargetSet; import com.android.quickstep.util.SwipeAnimationTargetSet; -import com.android.quickstep.util.SwipeAnimationTargetSet.SwipeAnimationListener; import com.android.quickstep.views.LiveTileOverlay; -import com.android.quickstep.views.RecentsView; import com.android.quickstep.views.TaskView; import com.android.systemui.shared.recents.model.ThumbnailData; import com.android.systemui.shared.system.InputConsumerController; @@ -110,11 +102,12 @@ import com.android.systemui.shared.system.RemoteAnimationTargetCompat; import com.android.systemui.shared.system.SyncRtSurfaceTransactionApplierCompat; import com.android.systemui.shared.system.WindowCallbacksCompat; -import java.util.function.Consumer; +import androidx.annotation.NonNull; +import androidx.annotation.UiThread; @TargetApi(Build.VERSION_CODES.O) public class WindowTransformSwipeHandler extends BaseSwipeUpHandler - implements SwipeAnimationListener, OnApplyWindowInsetsListener { + implements OnApplyWindowInsetsListener { private static final String TAG = WindowTransformSwipeHandler.class.getSimpleName(); private static final Rect TEMP_RECT = new Rect(); @@ -222,18 +215,12 @@ public class WindowTransformSwipeHandler extends */ private static final int LOG_NO_OP_PAGE_INDEX = -1; - private Runnable mGestureEndCallback; private GestureEndTarget mGestureEndTarget; // Either RectFSpringAnim (if animating home) or ObjectAnimator (from mCurrentShift) otherwise private RunningWindowAnim mRunningWindowAnim; private boolean mIsShelfPeeking; private DeviceProfile mDp; - // Shift in the range of [0, 1]. - // 0 => preview snapShot is completely visible, and hotseat is completely translated down - // 1 => preview snapShot is completely aligned with the recents view and hotseat is completely - // visible. - private final AnimatedFloat mCurrentShift = new AnimatedFloat(this::updateFinalShift); private boolean mContinuingLastGesture; // To avoid UI jump when gesture is started, we offset the animation by the threshold. private float mShiftAtGestureStart = 0; @@ -242,6 +229,7 @@ public class WindowTransformSwipeHandler extends private final ActivityControlHelper mActivityControlHelper; private final ActivityInitListener mActivityInitListener; + private final RecentsModel mRecentsModel; private final SysUINavigationMode.Mode mMode; @@ -254,7 +242,6 @@ public class WindowTransformSwipeHandler extends private boolean mHasLauncherTransitionControllerStarted; private T mActivity; - private RecentsView mRecentsView; private AnimationFactory mAnimationFactory = (t) -> { }; private LiveTileOverlay mLiveTileOverlay = new LiveTileOverlay(); @@ -276,11 +263,12 @@ public class WindowTransformSwipeHandler extends public WindowTransformSwipeHandler(RunningTaskInfo runningTaskInfo, Context context, long touchTimeMs, ActivityControlHelper controller, boolean continuingLastGesture, - InputConsumerController inputConsumer) { + InputConsumerController inputConsumer, RecentsModel recentsModel) { super(context); mRunningTaskId = runningTaskInfo.id; mTouchTimeMs = touchTimeMs; mActivityControlHelper = controller; + mRecentsModel = recentsModel; mActivityInitListener = mActivityControlHelper .createActivityInitListener(this::onActivityInit); mContinuingLastGesture = continuingLastGesture; @@ -375,7 +363,11 @@ public class WindowTransformSwipeHandler extends } } + @Override public void initWhenReady() { + // Preload the plan + mRecentsModel.getTasks(null); + mActivityInitListener.register(); } @@ -546,15 +538,7 @@ public class WindowTransformSwipeHandler extends return TaskView.getCurveScaleForInterpolation(interpolation); } - public Consumer getRecentsViewDispatcher(RotationMode rotationMode) { - return mRecentsView != null ? mRecentsView.getEventDispatcher(rotationMode) : null; - } - - @UiThread - public void updateDisplacement(float displacement) { - mCurrentShift.updateValue(getShiftForDisplacement(displacement)); - } - + @Override public void onMotionPauseChanged(boolean isPaused) { setShelfState(isPaused ? PEEK : HIDE, OVERSHOOT_1_2, SHELF_ANIM_DURATION); } @@ -605,6 +589,7 @@ public class WindowTransformSwipeHandler extends mAnimationFactory.setRecentsAttachedToAppWindow(recentsAttachedToAppWindow, animate); } + @Override public void setIsLikelyToStartNewTask(boolean isLikelyToStartNewTask) { if (mIsLikelyToStartNewTask != isLikelyToStartNewTask) { mIsLikelyToStartNewTask = isLikelyToStartNewTask; @@ -651,7 +636,8 @@ public class WindowTransformSwipeHandler extends } @UiThread - private void updateFinalShift() { + @Override + public void updateFinalShift() { float shift = mCurrentShift.value; SwipeAnimationTargetSet controller = mRecentsAnimationWrapper.getController(); @@ -766,7 +752,7 @@ public class WindowTransformSwipeHandler extends TOUCH_INTERACTION_LOG.addLog("cancelRecentsAnimation"); } - @UiThread + @Override public void onGestureStarted() { notifyGestureStartedAsync(); mShiftAtGestureStart = mCurrentShift.value; @@ -790,7 +776,7 @@ public class WindowTransformSwipeHandler extends /** * Called as a result on ACTION_CANCEL to return the UI to the start state. */ - @UiThread + @Override public void onGestureCancelled() { updateDisplacement(0); setStateOnUiThread(STATE_GESTURE_COMPLETED); @@ -803,7 +789,7 @@ public class WindowTransformSwipeHandler extends * @param velocity The x and y components of the velocity when the gesture ends. * @param downPos The x and y value of where the gesture started. */ - @UiThread + @Override public void onGestureEnded(float endVelocity, PointF velocity, PointF downPos) { float flingThreshold = mContext.getResources() .getDimension(R.dimen.quickstep_fling_threshold_velocity); @@ -1174,11 +1160,18 @@ public class WindowTransformSwipeHandler extends return anim; } - /** - * @return The GestureEndTarget if the gesture has ended, else null. - */ - public @Nullable GestureEndTarget getGestureEndTarget() { - return mGestureEndTarget; + @Override + public void onConsumerAboutToBeSwitched(SwipeSharedState sharedState) { + if (mGestureEndTarget != null) { + sharedState.canGestureBeContinued = mGestureEndTarget.canBeContinued; + sharedState.goingToLauncher = mGestureEndTarget.isLauncher; + } + + if (sharedState.canGestureBeContinued) { + cancelCurrentAnimation(sharedState); + } else { + reset(); + } } @UiThread @@ -1227,7 +1220,7 @@ public class WindowTransformSwipeHandler extends TOUCH_INTERACTION_LOG.addLog("finishRecentsAnimation", true); } - public void reset() { + private void reset() { setStateOnUiThread(STATE_HANDLER_INVALIDATED); } @@ -1235,7 +1228,7 @@ public class WindowTransformSwipeHandler extends * Cancels any running animation so that the active target can be overriden by a new swipe * handle (in case of quick switch). */ - public void cancelCurrentAnimation(SwipeSharedState sharedState) { + private void cancelCurrentAnimation(SwipeSharedState sharedState) { mCanceled = true; mCurrentShift.cancelAnimation(); if (mLauncherTransitionController != null && mLauncherTransitionController @@ -1398,10 +1391,6 @@ public class WindowTransformSwipeHandler extends reset(); } - public void setGestureEndCallback(Runnable gestureEndCallback) { - mGestureEndCallback = gestureEndCallback; - } - private void setTargetAlphaProvider(TargetAlphaProvider provider) { mClipAnimationHelper.setTaskAlphaCallback(provider); updateFinalShift(); diff --git a/quickstep/recents_ui_overrides/src/com/android/quickstep/inputconsumers/FallbackNoButtonInputConsumer.java b/quickstep/recents_ui_overrides/src/com/android/quickstep/inputconsumers/FallbackNoButtonInputConsumer.java index cdd91b78f4..a5a8f388f4 100644 --- a/quickstep/recents_ui_overrides/src/com/android/quickstep/inputconsumers/FallbackNoButtonInputConsumer.java +++ b/quickstep/recents_ui_overrides/src/com/android/quickstep/inputconsumers/FallbackNoButtonInputConsumer.java @@ -15,23 +15,12 @@ */ package com.android.quickstep.inputconsumers; -import static android.view.MotionEvent.ACTION_CANCEL; -import static android.view.MotionEvent.ACTION_DOWN; -import static android.view.MotionEvent.ACTION_MOVE; -import static android.view.MotionEvent.ACTION_POINTER_DOWN; -import static android.view.MotionEvent.ACTION_POINTER_UP; -import static android.view.MotionEvent.ACTION_UP; -import static android.view.MotionEvent.INVALID_POINTER_ID; - import static com.android.quickstep.RecentsActivity.EXTRA_TASK_ID; import static com.android.quickstep.RecentsActivity.EXTRA_THUMBNAIL; import static com.android.quickstep.WindowTransformSwipeHandler.MIN_PROGRESS_FOR_OVERVIEW; import static com.android.quickstep.inputconsumers.FallbackNoButtonInputConsumer.GestureEndTarget.HOME; import static com.android.quickstep.inputconsumers.FallbackNoButtonInputConsumer.GestureEndTarget.LAST_TASK; import static com.android.quickstep.inputconsumers.FallbackNoButtonInputConsumer.GestureEndTarget.RECENTS; -import static com.android.quickstep.inputconsumers.OtherActivityInputConsumer.QUICKSTEP_TOUCH_SLOP_RATIO; -import static com.android.quickstep.TouchInteractionService.startRecentsActivityAsync; -import static com.android.systemui.shared.system.ActivityManagerWrapper.CLOSE_SYSTEM_WINDOWS_REASON_RECENTS; import android.animation.Animator; import android.animation.AnimatorListenerAdapter; @@ -42,11 +31,7 @@ import android.content.Context; import android.content.Intent; import android.graphics.PointF; import android.graphics.Rect; -import android.graphics.RectF; import android.os.Bundle; -import android.view.MotionEvent; -import android.view.VelocityTracker; -import android.view.ViewConfiguration; import android.view.WindowManager; import com.android.launcher3.DeviceProfile; @@ -56,20 +41,12 @@ import com.android.quickstep.ActivityControlHelper; import com.android.quickstep.AnimatedFloat; import com.android.quickstep.BaseSwipeUpHandler; import com.android.quickstep.OverviewComponentObserver; -import com.android.quickstep.SwipeSharedState; -import com.android.quickstep.util.MotionPauseDetector; -import com.android.quickstep.util.NavBarPosition; import com.android.quickstep.util.ObjectWrapper; -import com.android.quickstep.util.RecentsAnimationListenerSet; import com.android.quickstep.util.SwipeAnimationTargetSet; -import com.android.quickstep.util.SwipeAnimationTargetSet.SwipeAnimationListener; import com.android.systemui.shared.recents.model.ThumbnailData; -import com.android.systemui.shared.system.ActivityManagerWrapper; -import com.android.systemui.shared.system.InputMonitorCompat; import com.android.systemui.shared.system.RemoteAnimationTargetCompat; -public class FallbackNoButtonInputConsumer extends BaseSwipeUpHandler - implements InputConsumer, SwipeAnimationListener { +public class FallbackNoButtonInputConsumer extends BaseSwipeUpHandler { public enum GestureEndTarget { HOME(3, 100, 1), @@ -79,6 +56,7 @@ public class FallbackNoButtonInputConsumer extends BaseSwipeUpHandler private final float mEndProgress; private final long mDurationMultiplier; private final float mLauncherAlpha; + GestureEndTarget(float endProgress, long durationMultiplier, float launcherAlpha) { mEndProgress = endProgress; mDurationMultiplier = durationMultiplier; @@ -87,68 +65,26 @@ public class FallbackNoButtonInputConsumer extends BaseSwipeUpHandler } private final ActivityControlHelper mActivityControlHelper; - private final InputMonitorCompat mInputMonitor; - private final NavBarPosition mNavBarPosition; - private final SwipeSharedState mSwipeSharedState; private final OverviewComponentObserver mOverviewComponentObserver; private final int mRunningTaskId; private final DeviceProfile mDP; - private final MotionPauseDetector mMotionPauseDetector; - private final float mMotionPauseMinDisplacement; private final Rect mTargetRect = new Rect(); - private final RectF mSwipeTouchRegion; - private final boolean mDisableHorizontalSwipe; - - private final PointF mDownPos = new PointF(); - private final PointF mLastPos = new PointF(); - private final AnimatedFloat mLauncherAlpha = new AnimatedFloat(this::onLauncherAlphaChanged); - private final AnimatedFloat mProgress = new AnimatedFloat(this::onProgressChanged); - private int mActivePointerId = -1; - // Slop used to determine when we say that the gesture has started. - private boolean mPassedPilferInputSlop; - - private VelocityTracker mVelocityTracker; - - // Distance after which we start dragging the window. - private final float mTouchSlop; - - // Might be displacement in X or Y, depending on the direction we are swiping from the nav bar. - private float mStartDisplacement; private SwipeAnimationTargetSet mSwipeAnimationTargetSet; private boolean mIsMotionPaused = false; private GestureEndTarget mEndTarget; public FallbackNoButtonInputConsumer(Context context, - ActivityControlHelper activityControlHelper, InputMonitorCompat inputMonitor, - SwipeSharedState swipeSharedState, RectF swipeTouchRegion, OverviewComponentObserver overviewComponentObserver, - boolean disableHorizontalSwipe, RunningTaskInfo runningTaskInfo) { + RunningTaskInfo runningTaskInfo) { super(context); - mActivityControlHelper = activityControlHelper; - mInputMonitor = inputMonitor; mOverviewComponentObserver = overviewComponentObserver; + mActivityControlHelper = overviewComponentObserver.getActivityControlHelper(); mRunningTaskId = runningTaskInfo.id; - - mMotionPauseDetector = new MotionPauseDetector(context); - mMotionPauseMinDisplacement = context.getResources().getDimension( - R.dimen.motion_pause_detector_min_displacement_from_app); - mMotionPauseDetector.setOnMotionPauseListener(this::onMotionPauseChanged); - - mSwipeSharedState = swipeSharedState; - mSwipeTouchRegion = swipeTouchRegion; - mDisableHorizontalSwipe = disableHorizontalSwipe; - - mNavBarPosition = new NavBarPosition(context); - mVelocityTracker = VelocityTracker.obtain(); - - mTouchSlop = QUICKSTEP_TOUCH_SLOP_RATIO - * ViewConfiguration.get(context).getScaledTouchSlop(); - mDP = InvariantDeviceProfile.INSTANCE.get(context).getDeviceProfile(context).copy(context); mLauncherAlpha.value = 1; @@ -156,18 +92,14 @@ public class FallbackNoButtonInputConsumer extends BaseSwipeUpHandler initTransitionTarget(); } - @Override - public int getType() { - return TYPE_FALLBACK_NO_BUTTON; - } - private void onLauncherAlphaChanged() { if (mSwipeAnimationTargetSet != null && mEndTarget == null) { mClipAnimationHelper.applyTransform(mSwipeAnimationTargetSet, mTransformParams); } } - private void onMotionPauseChanged(boolean isPaused) { + @Override + public void onMotionPauseChanged(boolean isPaused) { mIsMotionPaused = isPaused; mLauncherAlpha.animateToValue(mLauncherAlpha.value, isPaused ? 0 : 1) .setDuration(150).start(); @@ -175,150 +107,36 @@ public class FallbackNoButtonInputConsumer extends BaseSwipeUpHandler } @Override - public void onMotionEvent(MotionEvent ev) { - if (mVelocityTracker == null) { - return; - } - - mVelocityTracker.addMovement(ev); - if (ev.getActionMasked() == ACTION_POINTER_UP) { - mVelocityTracker.clear(); - mMotionPauseDetector.clear(); - } - - switch (ev.getActionMasked()) { - case ACTION_DOWN: { - mActivePointerId = ev.getPointerId(0); - mDownPos.set(ev.getX(), ev.getY()); - mLastPos.set(mDownPos); - break; - } - case ACTION_POINTER_DOWN: { - if (!mPassedPilferInputSlop) { - // Cancel interaction in case of multi-touch interaction - int ptrIdx = ev.getActionIndex(); - if (!mSwipeTouchRegion.contains(ev.getX(ptrIdx), ev.getY(ptrIdx))) { - forceCancelGesture(ev); - } - } - break; - } - case ACTION_POINTER_UP: { - int ptrIdx = ev.getActionIndex(); - int ptrId = ev.getPointerId(ptrIdx); - if (ptrId == mActivePointerId) { - final int newPointerIdx = ptrIdx == 0 ? 1 : 0; - mDownPos.set( - ev.getX(newPointerIdx) - (mLastPos.x - mDownPos.x), - ev.getY(newPointerIdx) - (mLastPos.y - mDownPos.y)); - mLastPos.set(ev.getX(newPointerIdx), ev.getY(newPointerIdx)); - mActivePointerId = ev.getPointerId(newPointerIdx); - } - break; - } - case ACTION_MOVE: { - int pointerIndex = ev.findPointerIndex(mActivePointerId); - if (pointerIndex == INVALID_POINTER_ID) { - break; - } - mLastPos.set(ev.getX(pointerIndex), ev.getY(pointerIndex)); - float displacement = getDisplacement(ev); - - if (!mPassedPilferInputSlop) { - if (mDisableHorizontalSwipe && Math.abs(mLastPos.x - mDownPos.x) - > Math.abs(mLastPos.y - mDownPos.y)) { - // Horizontal gesture is not allowed in this region - forceCancelGesture(ev); - break; - } - - if (Math.abs(displacement) >= mTouchSlop) { - mPassedPilferInputSlop = true; - - // Deferred gesture, start the animation and gesture tracking once - // we pass the actual touch slop - startTouchTrackingForWindowAnimation(displacement); - } - } else { - updateDisplacement(displacement - mStartDisplacement); - mMotionPauseDetector.setDisallowPause( - -displacement < mMotionPauseMinDisplacement); - mMotionPauseDetector.addPosition(displacement, ev.getEventTime()); - } - break; - } - case ACTION_CANCEL: - case ACTION_UP: { - finishTouchTracking(ev); - break; - } - } - } - - private void startTouchTrackingForWindowAnimation(float displacement) { - mStartDisplacement = Math.min(displacement, -mTouchSlop); - - RecentsAnimationListenerSet listenerSet = - mSwipeSharedState.newRecentsAnimationListenerSet(); - listenerSet.addListener(this); - Intent homeIntent = mOverviewComponentObserver.getHomeIntent(); - startRecentsActivityAsync(homeIntent, listenerSet); - - ActivityManagerWrapper.getInstance().closeSystemWindows( - CLOSE_SYSTEM_WINDOWS_REASON_RECENTS); - mInputMonitor.pilferPointers(); - } - - private void updateDisplacement(float displacement) { - mProgress.updateValue(getShiftForDisplacement(displacement)); - } - - private void onProgressChanged() { - mTransformParams.setProgress(mProgress.value); + public void updateFinalShift() { + mTransformParams.setProgress(mCurrentShift.value); if (mSwipeAnimationTargetSet != null) { mClipAnimationHelper.applyTransform(mSwipeAnimationTargetSet, mTransformParams); } } - private void forceCancelGesture(MotionEvent ev) { - int action = ev.getAction(); - ev.setAction(ACTION_CANCEL); - finishTouchTracking(ev); - ev.setAction(action); + @Override + public void onGestureCancelled() { + updateDisplacement(0); + mEndTarget = LAST_TASK; + finishAnimationTargetSetAnimationComplete(); } - /** - * Called when the gesture has ended. Does not correlate to the completion of the interaction as - * the animation can still be running. - */ - private void finishTouchTracking(MotionEvent ev) { - if (ev.getAction() == ACTION_CANCEL) { - mEndTarget = LAST_TASK; + @Override + public void onGestureEnded(float endVelocity, PointF velocity, PointF downPos) { + float flingThreshold = mContext.getResources() + .getDimension(R.dimen.quickstep_fling_threshold_velocity); + boolean isFling = Math.abs(endVelocity) > flingThreshold; + + if (isFling) { + mEndTarget = endVelocity < 0 ? HOME : LAST_TASK; + } else if (mIsMotionPaused) { + mEndTarget = RECENTS; } else { - mVelocityTracker.computeCurrentVelocity(1000, - ViewConfiguration.get(mContext).getScaledMaximumFlingVelocity()); - float velocityX = mVelocityTracker.getXVelocity(mActivePointerId); - float velocityY = mVelocityTracker.getYVelocity(mActivePointerId); - float velocity = mNavBarPosition.isRightEdge() ? velocityX - : mNavBarPosition.isLeftEdge() ? -velocityX - : velocityY; - float flingThreshold = mContext.getResources() - .getDimension(R.dimen.quickstep_fling_threshold_velocity); - boolean isFling = Math.abs(velocity) > flingThreshold; - - if (isFling) { - mEndTarget = velocity < 0 ? HOME : LAST_TASK; - } else if (mIsMotionPaused) { - mEndTarget = RECENTS; - } else { - mEndTarget = mProgress.value >= MIN_PROGRESS_FOR_OVERVIEW ? HOME : LAST_TASK; - } + mEndTarget = mCurrentShift.value >= MIN_PROGRESS_FOR_OVERVIEW ? HOME : LAST_TASK; } - if (mSwipeAnimationTargetSet != null) { finishAnimationTargetSet(); } - mMotionPauseDetector.clear(); } private void finishAnimationTargetSetAnimationComplete() { @@ -346,19 +164,22 @@ public class FallbackNoButtonInputConsumer extends BaseSwipeUpHandler break; } } + if (mGestureEndCallback != null) { + mGestureEndCallback.run(); + } } private void finishAnimationTargetSet() { float endProgress = mEndTarget.mEndProgress; - if (mProgress.value != endProgress) { + if (mCurrentShift.value != endProgress) { AnimatorSet anim = new AnimatorSet(); anim.play(mLauncherAlpha.animateToValue( mLauncherAlpha.value, mEndTarget.mLauncherAlpha)); - anim.play(mProgress.animateToValue(mProgress.value, endProgress)); + anim.play(mCurrentShift.animateToValue(mCurrentShift.value, endProgress)); anim.setDuration((long) (mEndTarget.mDurationMultiplier * - Math.abs(endProgress - mProgress.value))); + Math.abs(endProgress - mCurrentShift.value))); anim.addListener(new AnimatorListenerAdapter() { @Override public void onAnimationEnd(Animator animation) { @@ -403,19 +224,4 @@ public class FallbackNoButtonInputConsumer extends BaseSwipeUpHandler @Override public void onRecentsAnimationCanceled() { } - - private float getDisplacement(MotionEvent ev) { - if (mNavBarPosition.isRightEdge()) { - return ev.getX() - mDownPos.x; - } else if (mNavBarPosition.isLeftEdge()) { - return mDownPos.x - ev.getX(); - } else { - return ev.getY() - mDownPos.y; - } - } - - @Override - public boolean allowInterceptByParent() { - return !mPassedPilferInputSlop; - } } diff --git a/quickstep/recents_ui_overrides/src/com/android/quickstep/inputconsumers/InputConsumer.java b/quickstep/recents_ui_overrides/src/com/android/quickstep/inputconsumers/InputConsumer.java index f5cf654b15..a1e5d47a53 100644 --- a/quickstep/recents_ui_overrides/src/com/android/quickstep/inputconsumers/InputConsumer.java +++ b/quickstep/recents_ui_overrides/src/com/android/quickstep/inputconsumers/InputConsumer.java @@ -33,7 +33,6 @@ public interface InputConsumer { int TYPE_SCREEN_PINNED = 1 << 6; int TYPE_OVERVIEW_WITHOUT_FOCUS = 1 << 7; int TYPE_RESET_GESTURE = 1 << 8; - int TYPE_FALLBACK_NO_BUTTON = 1 << 9; String[] NAMES = new String[] { "TYPE_NO_OP", // 0 @@ -45,7 +44,6 @@ public interface InputConsumer { "TYPE_SCREEN_PINNED", // 6 "TYPE_OVERVIEW_WITHOUT_FOCUS", // 7 "TYPE_RESET_GESTURE", // 8 - "TYPE_FALLBACK_NO_BUTTON", // 9 }; InputConsumer NO_OP = () -> TYPE_NO_OP; diff --git a/quickstep/recents_ui_overrides/src/com/android/quickstep/inputconsumers/OtherActivityInputConsumer.java b/quickstep/recents_ui_overrides/src/com/android/quickstep/inputconsumers/OtherActivityInputConsumer.java index a4d2f39d29..9114995cc9 100644 --- a/quickstep/recents_ui_overrides/src/com/android/quickstep/inputconsumers/OtherActivityInputConsumer.java +++ b/quickstep/recents_ui_overrides/src/com/android/quickstep/inputconsumers/OtherActivityInputConsumer.java @@ -49,20 +49,16 @@ import com.android.launcher3.R; import com.android.launcher3.util.Preconditions; import com.android.launcher3.util.RaceConditionTracker; import com.android.launcher3.util.TraceHelper; -import com.android.quickstep.ActivityControlHelper; +import com.android.quickstep.BaseSwipeUpHandler; import com.android.quickstep.OverviewCallbacks; -import com.android.quickstep.RecentsModel; import com.android.quickstep.SwipeSharedState; import com.android.quickstep.SysUINavigationMode; import com.android.quickstep.SysUINavigationMode.Mode; -import com.android.quickstep.WindowTransformSwipeHandler; -import com.android.quickstep.WindowTransformSwipeHandler.GestureEndTarget; import com.android.quickstep.util.CachedEventDispatcher; import com.android.quickstep.util.MotionPauseDetector; import com.android.quickstep.util.NavBarPosition; import com.android.quickstep.util.RecentsAnimationListenerSet; import com.android.systemui.shared.system.ActivityManagerWrapper; -import com.android.systemui.shared.system.InputConsumerController; import com.android.systemui.shared.system.InputMonitorCompat; import java.util.function.Consumer; @@ -83,16 +79,15 @@ public class OtherActivityInputConsumer extends ContextWrapper implements InputC private final CachedEventDispatcher mRecentsViewDispatcher = new CachedEventDispatcher(); private final RunningTaskInfo mRunningTask; - private final RecentsModel mRecentsModel; private final Intent mHomeIntent; - private final ActivityControlHelper mActivityControlHelper; private final OverviewCallbacks mOverviewCallbacks; - private final InputConsumerController mInputConsumer; private final SwipeSharedState mSwipeSharedState; private final InputMonitorCompat mInputMonitorCompat; private final SysUINavigationMode.Mode mMode; private final RectF mSwipeTouchRegion; + private final BaseSwipeUpHandler.Factory mHandlerFactory; + private final NavBarPosition mNavBarPosition; private final Consumer mOnCompleteCallback; @@ -100,7 +95,7 @@ public class OtherActivityInputConsumer extends ContextWrapper implements InputC private final float mMotionPauseMinDisplacement; private VelocityTracker mVelocityTracker; - private WindowTransformSwipeHandler mInteractionHandler; + private BaseSwipeUpHandler mInteractionHandler; private final boolean mIsDeferredDownTarget; private final PointF mDownPos = new PointF(); @@ -114,7 +109,7 @@ public class OtherActivityInputConsumer extends ContextWrapper implements InputC private final boolean mDisableHorizontalSwipe; // Slop used to check when we start moving window. - private boolean mPaddedWindowMoveSlop; + private boolean mPassedWindowMoveSlop; // Slop used to determine when we say that the gesture has started. private boolean mPassedPilferInputSlop; @@ -122,26 +117,24 @@ public class OtherActivityInputConsumer extends ContextWrapper implements InputC private float mStartDisplacement; private Handler mMainThreadHandler; - private Runnable mCancelRecentsAnimationRunnable = () -> { + private Runnable mCancelRecentsAnimationRunnable = () -> ActivityManagerWrapper.getInstance().cancelRecentsAnimation( true /* restoreHomeStackPosition */); - }; public OtherActivityInputConsumer(Context base, RunningTaskInfo runningTaskInfo, - RecentsModel recentsModel, Intent homeIntent, ActivityControlHelper activityControl, - boolean isDeferredDownTarget, OverviewCallbacks overviewCallbacks, - InputConsumerController inputConsumer, + Intent homeIntent, boolean isDeferredDownTarget, OverviewCallbacks overviewCallbacks, Consumer onCompleteCallback, SwipeSharedState swipeSharedState, InputMonitorCompat inputMonitorCompat, - RectF swipeTouchRegion, boolean disableHorizontalSwipe) { + RectF swipeTouchRegion, boolean disableHorizontalSwipe, + BaseSwipeUpHandler.Factory handlerFactory) { super(base); mMainThreadHandler = new Handler(Looper.getMainLooper()); mRunningTask = runningTaskInfo; - mRecentsModel = recentsModel; mHomeIntent = homeIntent; mMode = SysUINavigationMode.getMode(base); mSwipeTouchRegion = swipeTouchRegion; + mHandlerFactory = handlerFactory; mMotionPauseDetector = new MotionPauseDetector(base); mMotionPauseMinDisplacement = base.getResources().getDimension( @@ -150,11 +143,9 @@ public class OtherActivityInputConsumer extends ContextWrapper implements InputC mVelocityTracker = VelocityTracker.obtain(); mInputMonitorCompat = inputMonitorCompat; - mActivityControlHelper = activityControl; boolean continuingPreviousGesture = swipeSharedState.getActiveListener() != null; mIsDeferredDownTarget = !continuingPreviousGesture && isDeferredDownTarget; mOverviewCallbacks = overviewCallbacks; - mInputConsumer = inputConsumer; mSwipeSharedState = swipeSharedState; mNavBarPosition = new NavBarPosition(base); @@ -163,7 +154,7 @@ public class OtherActivityInputConsumer extends ContextWrapper implements InputC float slop = QUICKSTEP_TOUCH_SLOP_RATIO * mTouchSlop; mSquaredTouchSlop = slop * slop; - mPassedPilferInputSlop = mPaddedWindowMoveSlop = continuingPreviousGesture; + mPassedPilferInputSlop = mPassedWindowMoveSlop = continuingPreviousGesture; mDisableHorizontalSwipe = !mPassedPilferInputSlop && disableHorizontalSwipe; } @@ -186,7 +177,7 @@ public class OtherActivityInputConsumer extends ContextWrapper implements InputC } // Proxy events to recents view - if (mPaddedWindowMoveSlop && mInteractionHandler != null + if (mPassedWindowMoveSlop && mInteractionHandler != null && !mRecentsViewDispatcher.hasConsumer()) { mRecentsViewDispatcher.setConsumer(mInteractionHandler.getRecentsViewDispatcher( mNavBarPosition.getRotationMode())); @@ -251,12 +242,12 @@ public class OtherActivityInputConsumer extends ContextWrapper implements InputC float displacement = getDisplacement(ev); float displacementX = mLastPos.x - mDownPos.x; - if (!mPaddedWindowMoveSlop) { + if (!mPassedWindowMoveSlop) { if (!mIsDeferredDownTarget) { // Normal gesture, ensure we pass the drag slop before we start tracking // the gesture if (Math.abs(displacement) > mTouchSlop) { - mPaddedWindowMoveSlop = true; + mPassedWindowMoveSlop = true; mStartDisplacement = Math.min(displacement, -mTouchSlop); } } @@ -279,8 +270,8 @@ public class OtherActivityInputConsumer extends ContextWrapper implements InputC // we pass the actual touch slop startTouchTrackingForWindowAnimation(ev.getEventTime()); } - if (!mPaddedWindowMoveSlop) { - mPaddedWindowMoveSlop = true; + if (!mPassedWindowMoveSlop) { + mPassedWindowMoveSlop = true; mStartDisplacement = Math.min(displacement, -mTouchSlop); } @@ -289,7 +280,7 @@ public class OtherActivityInputConsumer extends ContextWrapper implements InputC } if (mInteractionHandler != null) { - if (mPaddedWindowMoveSlop) { + if (mPassedWindowMoveSlop) { // Move mInteractionHandler.updateDisplacement(displacement - mStartDisplacement); } @@ -333,12 +324,9 @@ public class OtherActivityInputConsumer extends ContextWrapper implements InputC TOUCH_INTERACTION_LOG.addLog("startRecentsAnimation"); RecentsAnimationListenerSet listenerSet = mSwipeSharedState.getActiveListener(); - final WindowTransformSwipeHandler handler = new WindowTransformSwipeHandler( - mRunningTask, this, touchTimeMs, mActivityControlHelper, - listenerSet != null, mInputConsumer); + final BaseSwipeUpHandler handler = mHandlerFactory.newHandler(mRunningTask, touchTimeMs, + listenerSet != null); - // Preload the plan - mRecentsModel.getTasks(null); mInteractionHandler = handler; handler.setGestureEndCallback(this::onInteractionGestureFinished); mMotionPauseDetector.setOnMotionPauseListener(handler::onMotionPauseChanged); @@ -364,7 +352,7 @@ public class OtherActivityInputConsumer extends ContextWrapper implements InputC RaceConditionTracker.onEvent(UP_EVT, ENTER); TraceHelper.endSection("TouchInt"); - if (mPaddedWindowMoveSlop && mInteractionHandler != null) { + if (mPassedWindowMoveSlop && mInteractionHandler != null) { if (ev.getActionMasked() == ACTION_CANCEL) { mInteractionHandler.onGestureCancelled(); } else { @@ -407,14 +395,7 @@ public class OtherActivityInputConsumer extends ContextWrapper implements InputC // The consumer is being switched while we are active. Set up the shared state to be // used by the next animation removeListener(); - GestureEndTarget endTarget = mInteractionHandler.getGestureEndTarget(); - mSwipeSharedState.canGestureBeContinued = endTarget != null && endTarget.canBeContinued; - mSwipeSharedState.goingToLauncher = endTarget != null && endTarget.isLauncher; - if (mSwipeSharedState.canGestureBeContinued) { - mInteractionHandler.cancelCurrentAnimation(mSwipeSharedState); - } else { - mInteractionHandler.reset(); - } + mInteractionHandler.onConsumerAboutToBeSwitched(mSwipeSharedState); } } From 2af71dd058deb86dd575b0043ad87cf1ba16c596 Mon Sep 17 00:00:00 2001 From: vadimt Date: Thu, 11 Jul 2019 12:52:43 -0700 Subject: [PATCH 027/108] Removing tracing for a fixed bug. Bug: 133867119 Change-Id: I796118f5ff0c27db002bb0e3369e651c95b06bbe --- .../quickstep/TouchInteractionService.java | 3 --- .../inputconsumers/OverviewInputConsumer.java | 3 --- .../launcher3/LauncherStateManager.java | 5 ---- .../allapps/AllAppsTransitionController.java | 4 --- .../compat/AccessibilityManagerCompat.java | 3 --- .../launcher3/testing/TestProtocol.java | 2 -- .../AbstractStateChangeTouchController.java | 26 ------------------- .../launcher3/touch/SwipeDetector.java | 17 ------------ .../launcher3/views/BaseDragLayer.java | 6 ----- 9 files changed, 69 deletions(-) diff --git a/quickstep/recents_ui_overrides/src/com/android/quickstep/TouchInteractionService.java b/quickstep/recents_ui_overrides/src/com/android/quickstep/TouchInteractionService.java index fafa4d34ca..62f46ecbfb 100644 --- a/quickstep/recents_ui_overrides/src/com/android/quickstep/TouchInteractionService.java +++ b/quickstep/recents_ui_overrides/src/com/android/quickstep/TouchInteractionService.java @@ -508,9 +508,6 @@ public class TouchInteractionService extends Service implements } private void onInputEvent(InputEvent ev) { - if (TestProtocol.sDebugTracing) { - Log.d(TestProtocol.EVENTS_TO_OVERVIEW_MISSING_TAG, "onInputEvent " + ev); - } if (!(ev instanceof MotionEvent)) { Log.e(TAG, "Unknown event " + ev); return; diff --git a/quickstep/recents_ui_overrides/src/com/android/quickstep/inputconsumers/OverviewInputConsumer.java b/quickstep/recents_ui_overrides/src/com/android/quickstep/inputconsumers/OverviewInputConsumer.java index f2e53bb18c..e55389161c 100644 --- a/quickstep/recents_ui_overrides/src/com/android/quickstep/inputconsumers/OverviewInputConsumer.java +++ b/quickstep/recents_ui_overrides/src/com/android/quickstep/inputconsumers/OverviewInputConsumer.java @@ -82,9 +82,6 @@ public class OverviewInputConsumer @Override public void onMotionEvent(MotionEvent ev) { - if (TestProtocol.sDebugTracing) { - Log.d(TestProtocol.EVENTS_TO_OVERVIEW_MISSING_TAG, "onMotionEvent " + ev); - } if (!mProxyTouch) { return; } diff --git a/src/com/android/launcher3/LauncherStateManager.java b/src/com/android/launcher3/LauncherStateManager.java index 2c8c208456..ccd6efaf55 100644 --- a/src/com/android/launcher3/LauncherStateManager.java +++ b/src/com/android/launcher3/LauncherStateManager.java @@ -429,11 +429,6 @@ public class LauncherStateManager { // Only change the stable states after the transitions have finished if (state != mCurrentStableState) { mLastStableState = state.getHistoryForState(mCurrentStableState); - if (TestProtocol.sDebugTracing) { - Log.d(TestProtocol.NO_ALLAPPS_EVENT_TAG, - "mCurrentStableState = " + state.getClass().getSimpleName() + " @ " + - android.util.Log.getStackTraceString(new Throwable())); - } mCurrentStableState = state; } diff --git a/src/com/android/launcher3/allapps/AllAppsTransitionController.java b/src/com/android/launcher3/allapps/AllAppsTransitionController.java index 4683893ea0..a64374bc37 100644 --- a/src/com/android/launcher3/allapps/AllAppsTransitionController.java +++ b/src/com/android/launcher3/allapps/AllAppsTransitionController.java @@ -168,10 +168,6 @@ public class AllAppsTransitionController implements StateHandler, OnDeviceProfil @Override public void setStateWithAnimation(LauncherState toState, AnimatorSetBuilder builder, AnimationConfig config) { - if (TestProtocol.sDebugTracing) { - Log.d(TestProtocol.NO_ALLAPPS_EVENT_TAG, - "setStateWithAnimation " + toState.getClass().getSimpleName()); - } float targetProgress = toState.getVerticalProgress(mLauncher); if (Float.compare(mProgress, targetProgress) == 0) { setAlphas(toState, config, builder); diff --git a/src/com/android/launcher3/compat/AccessibilityManagerCompat.java b/src/com/android/launcher3/compat/AccessibilityManagerCompat.java index 43ae65175f..81c95cbdd4 100644 --- a/src/com/android/launcher3/compat/AccessibilityManagerCompat.java +++ b/src/com/android/launcher3/compat/AccessibilityManagerCompat.java @@ -53,9 +53,6 @@ public class AccessibilityManagerCompat { } public static void sendStateEventToTest(Context context, int stateOrdinal) { - if (com.android.launcher3.testing.TestProtocol.sDebugTracing) { - android.util.Log.e(TestProtocol.NO_ALLAPPS_EVENT_TAG, "sendStateEventToTest"); - } final AccessibilityManager accessibilityManager = getAccessibilityManagerForTest(context); if (accessibilityManager == null) return; diff --git a/src/com/android/launcher3/testing/TestProtocol.java b/src/com/android/launcher3/testing/TestProtocol.java index 3774042c93..d6d0577c9f 100644 --- a/src/com/android/launcher3/testing/TestProtocol.java +++ b/src/com/android/launcher3/testing/TestProtocol.java @@ -73,10 +73,8 @@ public final class TestProtocol { public static boolean sDebugTracing = false; public static final String REQUEST_ENABLE_DEBUG_TRACING = "enable-debug-tracing"; public static final String REQUEST_DISABLE_DEBUG_TRACING = "disable-debug-tracing"; - public static final String NO_ALLAPPS_EVENT_TAG = "b/133867119"; public static final String NO_DRAG_TAG = "b/133009122"; public static final String NO_START_TAG = "b/132900132"; public static final String NO_START_TASK_TAG = "b/133765434"; public static final String NO_OVERVIEW_EVENT_TAG = "b/134532571"; - public static final String EVENTS_TO_OVERVIEW_MISSING_TAG = "b/133867119"; } diff --git a/src/com/android/launcher3/touch/AbstractStateChangeTouchController.java b/src/com/android/launcher3/touch/AbstractStateChangeTouchController.java index 6f53140eab..7252410e03 100644 --- a/src/com/android/launcher3/touch/AbstractStateChangeTouchController.java +++ b/src/com/android/launcher3/touch/AbstractStateChangeTouchController.java @@ -118,9 +118,6 @@ public abstract class AbstractStateChangeTouchController @Override public final boolean onControllerInterceptTouchEvent(MotionEvent ev) { - if (TestProtocol.sDebugTracing) { - Log.d(TestProtocol.NO_ALLAPPS_EVENT_TAG, "onControllerInterceptTouchEvent 1 " + ev); - } if (ev.getAction() == MotionEvent.ACTION_DOWN) { mNoIntercept = !canInterceptTouch(ev); if (mNoIntercept) { @@ -150,9 +147,6 @@ public abstract class AbstractStateChangeTouchController return false; } - if (TestProtocol.sDebugTracing) { - Log.d(TestProtocol.NO_ALLAPPS_EVENT_TAG, "onControllerInterceptTouchEvent 2 "); - } onControllerTouchEvent(ev); return mDetector.isDraggingOrSettling(); } @@ -240,9 +234,6 @@ public abstract class AbstractStateChangeTouchController @Override public void onDragStart(boolean start) { - if (TestProtocol.sDebugTracing) { - Log.d(TestProtocol.NO_ALLAPPS_EVENT_TAG, "onDragStart 1 " + start); - } mStartState = mLauncher.getStateManager().getState(); if (mStartState == ALL_APPS) { mStartContainerType = LauncherLogProto.ContainerType.ALLAPPS; @@ -252,9 +243,6 @@ public abstract class AbstractStateChangeTouchController mStartContainerType = LauncherLogProto.ContainerType.TASKSWITCHER; } if (mCurrentAnimation == null) { - if (TestProtocol.sDebugTracing) { - Log.d(TestProtocol.NO_ALLAPPS_EVENT_TAG, "onDragStart 2"); - } mFromState = mStartState; mToState = null; cancelAnimationControllers(); @@ -376,9 +364,6 @@ public abstract class AbstractStateChangeTouchController @Override public void onDragEnd(float velocity, boolean fling) { - if (com.android.launcher3.testing.TestProtocol.sDebugTracing) { - android.util.Log.e(TestProtocol.NO_ALLAPPS_EVENT_TAG, "onDragEnd"); - } final int logAction = fling ? Touch.FLING : Touch.SWIPE; boolean blockedFling = fling && mFlingBlockCheck.isBlocked(); @@ -515,9 +500,6 @@ public abstract class AbstractStateChangeTouchController } protected void onSwipeInteractionCompleted(LauncherState targetState, int logAction) { - if (com.android.launcher3.testing.TestProtocol.sDebugTracing) { - android.util.Log.e(TestProtocol.NO_ALLAPPS_EVENT_TAG, "onSwipeInteractionCompleted 1"); - } if (mAtomicComponentsController != null) { mAtomicComponentsController.getAnimationPlayer().end(); mAtomicComponentsController = null; @@ -535,11 +517,6 @@ public abstract class AbstractStateChangeTouchController logReachedState(logAction, targetState); } mLauncher.getStateManager().goToState(targetState, false /* animated */); - - if (com.android.launcher3.testing.TestProtocol.sDebugTracing) { - android.util.Log.e( - TestProtocol.NO_ALLAPPS_EVENT_TAG, "onSwipeInteractionCompleted 2"); - } } } @@ -563,9 +540,6 @@ public abstract class AbstractStateChangeTouchController } private void cancelAnimationControllers() { - if (TestProtocol.sDebugTracing) { - Log.d(TestProtocol.NO_ALLAPPS_EVENT_TAG, "cancelAnimationControllers"); - } mCurrentAnimation = null; cancelAtomicComponentsController(); mDetector.finishedScrolling(); diff --git a/src/com/android/launcher3/touch/SwipeDetector.java b/src/com/android/launcher3/touch/SwipeDetector.java index 3d454046a5..3777a41ad8 100644 --- a/src/com/android/launcher3/touch/SwipeDetector.java +++ b/src/com/android/launcher3/touch/SwipeDetector.java @@ -158,9 +158,6 @@ public class SwipeDetector { // SETTLING -> (View settled) -> IDLE private void setState(ScrollState newState) { - if (TestProtocol.sDebugTracing) { - Log.d(TestProtocol.NO_ALLAPPS_EVENT_TAG, "setState -- start: " + newState); - } if (DBG) { Log.d(TAG, "setState:" + mState + "->" + newState); } @@ -168,9 +165,6 @@ public class SwipeDetector { if (newState == ScrollState.DRAGGING) { initializeDragging(); if (mState == ScrollState.IDLE) { - if (TestProtocol.sDebugTracing) { - Log.d(TestProtocol.NO_ALLAPPS_EVENT_TAG, "setState -- 1: " + newState); - } reportDragStart(false /* recatch */); } else if (mState == ScrollState.SETTLING) { reportDragStart(true /* recatch */); @@ -181,11 +175,6 @@ public class SwipeDetector { } mState = newState; - if (com.android.launcher3.testing.TestProtocol.sDebugTracing) { - android.util.Log.e(TestProtocol.NO_ALLAPPS_EVENT_TAG, - "setState: " + newState + " @ " + android.util.Log.getStackTraceString( - new Throwable())); - } } public boolean isDraggingOrSettling() { @@ -324,15 +313,9 @@ public class SwipeDetector { break; } mDisplacement = mDir.getDisplacement(ev, pointerIndex, mDownPos, mIsRtl); - if (TestProtocol.sDebugTracing) { - Log.d(TestProtocol.NO_ALLAPPS_EVENT_TAG, "onTouchEvent 1"); - } // handle state and listener calls. if (mState != ScrollState.DRAGGING && shouldScrollStart(ev, pointerIndex)) { - if (TestProtocol.sDebugTracing) { - Log.d(TestProtocol.NO_ALLAPPS_EVENT_TAG, "onTouchEvent 2"); - } setState(ScrollState.DRAGGING); } if (mState == ScrollState.DRAGGING) { diff --git a/src/com/android/launcher3/views/BaseDragLayer.java b/src/com/android/launcher3/views/BaseDragLayer.java index 1e70c7f812..15f2724708 100644 --- a/src/com/android/launcher3/views/BaseDragLayer.java +++ b/src/com/android/launcher3/views/BaseDragLayer.java @@ -152,9 +152,6 @@ public abstract class BaseDragLayer } private TouchController findControllerToHandleTouch(MotionEvent ev) { - if (TestProtocol.sDebugTracing) { - Log.d(TestProtocol.EVENTS_TO_OVERVIEW_MISSING_TAG, "findControllerToHandleTouch " + ev); - } if (shouldDisableGestures(ev)) return null; AbstractFloatingView topView = AbstractFloatingView.getTopOpenView(mActivity); @@ -315,9 +312,6 @@ public abstract class BaseDragLayer * Proxies the touch events to the gesture handlers */ public boolean proxyTouchEvent(MotionEvent ev) { - if (TestProtocol.sDebugTracing) { - Log.d(TestProtocol.EVENTS_TO_OVERVIEW_MISSING_TAG, "proxyTouchEvent " + ev); - } boolean handled; if (mProxyTouchController != null) { handled = mProxyTouchController.onControllerTouchEvent(ev); From 853852351f3b1bd9fbaa063b0e99cd8067e61c50 Mon Sep 17 00:00:00 2001 From: vadimt Date: Fri, 28 Jun 2019 12:04:36 -0700 Subject: [PATCH 028/108] Correctly restarting Launcher from OOP tests Waiting for touch interaction service; waiting for package-restart events. Bug: 136215685 Change-Id: I0c31c09fe3a58b898168dfdb4e4d23757b94a47c --- .../android/quickstep/TouchInteractionService.java | 4 ++++ .../android/quickstep/TouchInteractionService.java | 7 +++++++ .../quickstep/QuickstepTestInformationHandler.java | 9 ++++++++- .../launcher3/testing/TestInformationHandler.java | 5 +++++ .../android/launcher3/testing/TestProtocol.java | 1 + .../launcher3/tapl/LauncherInstrumentation.java | 14 ++++++++++++++ 6 files changed, 39 insertions(+), 1 deletion(-) diff --git a/go/quickstep/src/com/android/quickstep/TouchInteractionService.java b/go/quickstep/src/com/android/quickstep/TouchInteractionService.java index c902826ed8..917800f2a6 100644 --- a/go/quickstep/src/com/android/quickstep/TouchInteractionService.java +++ b/go/quickstep/src/com/android/quickstep/TouchInteractionService.java @@ -185,4 +185,8 @@ public class TouchInteractionService extends Service { } return mMyBinder; } + + public static boolean isInputMonitorInitialized() { + return true; + } } diff --git a/quickstep/recents_ui_overrides/src/com/android/quickstep/TouchInteractionService.java b/quickstep/recents_ui_overrides/src/com/android/quickstep/TouchInteractionService.java index 0ef2f5c5ad..dd04024539 100644 --- a/quickstep/recents_ui_overrides/src/com/android/quickstep/TouchInteractionService.java +++ b/quickstep/recents_ui_overrides/src/com/android/quickstep/TouchInteractionService.java @@ -226,12 +226,17 @@ public class TouchInteractionService extends Service implements }; private static boolean sConnected = false; + private static boolean sInputMonitorInitialized = false; private static final SwipeSharedState sSwipeSharedState = new SwipeSharedState(); public static boolean isConnected() { return sConnected; } + public static boolean isInputMonitorInitialized() { + return sInputMonitorInitialized; + } + public static SwipeSharedState getSwipeSharedState() { return sSwipeSharedState; } @@ -325,6 +330,7 @@ public class TouchInteractionService extends Service implements mInputMonitorCompat.dispose(); mInputMonitorCompat = null; } + sInputMonitorInitialized = false; } private void initInputMonitor() { @@ -342,6 +348,7 @@ public class TouchInteractionService extends Service implements Log.e(TAG, "Unable to create input monitor", e); } initTouchBounds(); + sInputMonitorInitialized = true; } private int getNavbarSize(String resName) { diff --git a/quickstep/src/com/android/quickstep/QuickstepTestInformationHandler.java b/quickstep/src/com/android/quickstep/QuickstepTestInformationHandler.java index 89513634fe..b59e13362d 100644 --- a/quickstep/src/com/android/quickstep/QuickstepTestInformationHandler.java +++ b/quickstep/src/com/android/quickstep/QuickstepTestInformationHandler.java @@ -10,7 +10,8 @@ import com.android.quickstep.util.LayoutUtils; public class QuickstepTestInformationHandler extends TestInformationHandler { - public QuickstepTestInformationHandler(Context context) { } + public QuickstepTestInformationHandler(Context context) { + } @Override public Bundle call(String method) { @@ -29,6 +30,12 @@ public class QuickstepTestInformationHandler extends TestInformationHandler { response.putInt(TestProtocol.TEST_INFO_RESPONSE_FIELD, (int) swipeHeight); return response; } + + case TestProtocol.REQUEST_IS_LAUNCHER_INITIALIZED: { + response.putBoolean(TestProtocol.TEST_INFO_RESPONSE_FIELD, + TouchInteractionService.isInputMonitorInitialized()); + break; + } } return super.call(method); diff --git a/src/com/android/launcher3/testing/TestInformationHandler.java b/src/com/android/launcher3/testing/TestInformationHandler.java index d2e196138c..bab454f070 100644 --- a/src/com/android/launcher3/testing/TestInformationHandler.java +++ b/src/com/android/launcher3/testing/TestInformationHandler.java @@ -74,6 +74,11 @@ public class TestInformationHandler implements ResourceBasedOverride { break; } + case TestProtocol.REQUEST_IS_LAUNCHER_INITIALIZED: { + response.putBoolean(TestProtocol.TEST_INFO_RESPONSE_FIELD, true); + break; + } + case TestProtocol.REQUEST_ENABLE_DEBUG_TRACING: TestProtocol.sDebugTracing = true; break; diff --git a/src/com/android/launcher3/testing/TestProtocol.java b/src/com/android/launcher3/testing/TestProtocol.java index 3774042c93..3a07be0968 100644 --- a/src/com/android/launcher3/testing/TestProtocol.java +++ b/src/com/android/launcher3/testing/TestProtocol.java @@ -66,6 +66,7 @@ public final class TestProtocol { "all-apps-to-overview-swipe-height"; public static final String REQUEST_HOME_TO_ALL_APPS_SWIPE_HEIGHT = "home-to-all-apps-swipe-height"; + public static final String REQUEST_IS_LAUNCHER_INITIALIZED = "is-launcher-initialized"; public static final String REQUEST_FREEZE_APP_LIST = "freeze-app-list"; public static final String REQUEST_UNFREEZE_APP_LIST = "unfreeze-app-list"; public static final String REQUEST_APP_LIST_FREEZE_FLAGS = "app-list-freeze-flags"; diff --git a/tests/tapl/com/android/launcher3/tapl/LauncherInstrumentation.java b/tests/tapl/com/android/launcher3/tapl/LauncherInstrumentation.java index 11b0665d95..2b0a794ea6 100644 --- a/tests/tapl/com/android/launcher3/tapl/LauncherInstrumentation.java +++ b/tests/tapl/com/android/launcher3/tapl/LauncherInstrumentation.java @@ -444,6 +444,8 @@ public final class LauncherInstrumentation { } private UiObject2 verifyContainerType(ContainerType containerType) { + waitForTouchInteractionService(); + assertEquals("Unexpected display rotation", mExpectedRotation, mDevice.getDisplayRotation()); @@ -514,6 +516,18 @@ public final class LauncherInstrumentation { } } + private void waitForTouchInteractionService() { + for (int i = 0; i < 100; ++i) { + if (getTestInfo( + TestProtocol.REQUEST_IS_LAUNCHER_INITIALIZED). + getBoolean(TestProtocol.TEST_INFO_RESPONSE_FIELD)) { + return; + } + SystemClock.sleep(100); + } + fail("TouchInteractionService didn't connect"); + } + Parcelable executeAndWaitForEvent(Runnable command, UiAutomation.AccessibilityEventFilter eventFilter, String message) { try { From 8874e5f8a7d575341b1ec34d3f16b624e615834b Mon Sep 17 00:00:00 2001 From: Becky Date: Thu, 11 Jul 2019 13:54:03 -0700 Subject: [PATCH 029/108] Fill the logging container in the AllAppsContainerView This would fix the issue that when drag and drop an icon from the all apps page, it doesn't have the right container information logged. Logging after this fix: 07-11 10:57:04.392 12969 12969 D UserEvent: action:DRAGDROP 07-11 10:57:04.392 12969 12969 D UserEvent: Source child:APP_ICON parent:ALLAPPS 07-11 10:57:04.392 12969 12969 D UserEvent: Destination child:APP_ICON parent:WORKSPACE id=0 07-11 10:57:04.392 12969 12969 D UserEvent: Elapsed container 744 ms, session 17440 ms, action 739 ms Test: manual Bug: 111935715 Change-Id: Ifb078e57697b051e3a527c16abaad40663eae687 --- .../android/launcher3/allapps/AllAppsContainerView.java | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/src/com/android/launcher3/allapps/AllAppsContainerView.java b/src/com/android/launcher3/allapps/AllAppsContainerView.java index ea9b077c62..b279cfc0be 100644 --- a/src/com/android/launcher3/allapps/AllAppsContainerView.java +++ b/src/com/android/launcher3/allapps/AllAppsContainerView.java @@ -50,6 +50,7 @@ import com.android.launcher3.Utilities; import com.android.launcher3.compat.AccessibilityManagerCompat; import com.android.launcher3.config.FeatureFlags; import com.android.launcher3.keyboard.FocusedItemDecorator; +import com.android.launcher3.userevent.nano.LauncherLogProto.ContainerType; import com.android.launcher3.userevent.nano.LauncherLogProto.Target; import com.android.launcher3.util.ItemInfoMatcher; import com.android.launcher3.util.MultiValueAlpha; @@ -297,7 +298,11 @@ public class AllAppsContainerView extends SpringRelativeLayout implements DragSo @Override public void fillInLogContainerData(View v, ItemInfo info, Target target, Target targetParent) { - // This is filled in {@link AllAppsRecyclerView} + if (getApps().hasFilter()) { + targetParent.containerType = ContainerType.SEARCHRESULT; + } else { + targetParent.containerType = ContainerType.ALLAPPS; + } } @Override From 1fd52d9024a6ac3b1dd38f8518903e7c332bc750 Mon Sep 17 00:00:00 2001 From: vadimt Date: Thu, 11 Jul 2019 16:00:12 -0700 Subject: [PATCH 030/108] Remove tracing for a fixed bug Bug: 132900132 Change-Id: Ic4ce3669f88c932e392b7517ec9fda11384dc334 --- .../launcher3/BaseDraggingActivity.java | 8 ------ src/com/android/launcher3/BubbleTextView.java | 3 -- src/com/android/launcher3/Launcher.java | 5 ---- .../allapps/AllAppsContainerView.java | 3 -- .../allapps/AlphabeticalAppsList.java | 5 ---- .../launcher3/testing/TestProtocol.java | 1 - .../launcher3/touch/ItemClickHandler.java | 28 ++----------------- .../launcher3/views/BaseDragLayer.java | 3 -- 8 files changed, 2 insertions(+), 54 deletions(-) diff --git a/src/com/android/launcher3/BaseDraggingActivity.java b/src/com/android/launcher3/BaseDraggingActivity.java index f69b172480..50553095d6 100644 --- a/src/com/android/launcher3/BaseDraggingActivity.java +++ b/src/com/android/launcher3/BaseDraggingActivity.java @@ -135,10 +135,6 @@ public abstract class BaseDraggingActivity extends BaseActivity public boolean startActivitySafely(View v, Intent intent, @Nullable ItemInfo item, @Nullable String sourceContainer) { - if (TestProtocol.sDebugTracing) { - android.util.Log.d(TestProtocol.NO_START_TAG, - "startActivitySafely 1"); - } if (mIsSafeModeEnabled && !Utilities.isSystemApp(this, intent)) { Toast.makeText(this, R.string.safemode_shortcut_error, Toast.LENGTH_SHORT).show(); return false; @@ -162,10 +158,6 @@ public abstract class BaseDraggingActivity extends BaseActivity startShortcutIntentSafely(intent, optsBundle, item, sourceContainer); } else if (user == null || user.equals(Process.myUserHandle())) { // Could be launching some bookkeeping activity - if (TestProtocol.sDebugTracing) { - android.util.Log.d(TestProtocol.NO_START_TAG, - "startActivitySafely 2"); - } startActivity(intent, optsBundle); AppLaunchTracker.INSTANCE.get(this).onStartApp(intent.getComponent(), Process.myUserHandle(), sourceContainer); diff --git a/src/com/android/launcher3/BubbleTextView.java b/src/com/android/launcher3/BubbleTextView.java index 1619e3645f..22c69f59a5 100644 --- a/src/com/android/launcher3/BubbleTextView.java +++ b/src/com/android/launcher3/BubbleTextView.java @@ -319,9 +319,6 @@ public class BubbleTextView extends TextView implements ItemInfoUpdateReceiver, @Override public boolean onTouchEvent(MotionEvent event) { - if (TestProtocol.sDebugTracing) { - Log.d(TestProtocol.NO_START_TAG, "BubbleTextView.onTouchEvent " + event); - } // Call the superclass onTouchEvent first, because sometimes it changes the state to // isPressed() on an ACTION_UP boolean result = super.onTouchEvent(event); diff --git a/src/com/android/launcher3/Launcher.java b/src/com/android/launcher3/Launcher.java index bc3aa7ef40..9229832687 100644 --- a/src/com/android/launcher3/Launcher.java +++ b/src/com/android/launcher3/Launcher.java @@ -1809,11 +1809,6 @@ public class Launcher extends BaseDraggingActivity implements LauncherExterns, public boolean startActivitySafely(View v, Intent intent, ItemInfo item, @Nullable String sourceContainer) { - if (TestProtocol.sDebugTracing) { - android.util.Log.d(TestProtocol.NO_START_TAG, - "startActivitySafely outer"); - } - if (!hasBeenResumed()) { // Workaround an issue where the WM launch animation is clobbered when finishing the // recents animation into launcher. Defer launching the activity until Launcher is diff --git a/src/com/android/launcher3/allapps/AllAppsContainerView.java b/src/com/android/launcher3/allapps/AllAppsContainerView.java index ea9b077c62..12a493013f 100644 --- a/src/com/android/launcher3/allapps/AllAppsContainerView.java +++ b/src/com/android/launcher3/allapps/AllAppsContainerView.java @@ -626,9 +626,6 @@ public class AllAppsContainerView extends SpringRelativeLayout implements DragSo @Override public boolean dispatchTouchEvent(MotionEvent ev) { - if (TestProtocol.sDebugTracing) { - Log.d(TestProtocol.NO_START_TAG, "AllAppsContainerView.dispatchTouchEvent " + ev); - } final boolean result = super.dispatchTouchEvent(ev); switch (ev.getActionMasked()) { case MotionEvent.ACTION_DOWN: diff --git a/src/com/android/launcher3/allapps/AlphabeticalAppsList.java b/src/com/android/launcher3/allapps/AlphabeticalAppsList.java index 2ad92e16f8..1369441fe1 100644 --- a/src/com/android/launcher3/allapps/AlphabeticalAppsList.java +++ b/src/com/android/launcher3/allapps/AlphabeticalAppsList.java @@ -301,11 +301,6 @@ public class AlphabeticalAppsList implements AllAppsStore.OnUpdateListener { } private void refreshRecyclerView() { - if (TestProtocol.sDebugTracing) { - android.util.Log.d(TestProtocol.NO_START_TAG, - "refreshRecyclerView @ " + android.util.Log.getStackTraceString( - new Throwable())); - } if (mAdapter != null) { mAdapter.notifyDataSetChanged(); } diff --git a/src/com/android/launcher3/testing/TestProtocol.java b/src/com/android/launcher3/testing/TestProtocol.java index 011ff86e2c..e28eba8094 100644 --- a/src/com/android/launcher3/testing/TestProtocol.java +++ b/src/com/android/launcher3/testing/TestProtocol.java @@ -75,7 +75,6 @@ public final class TestProtocol { public static final String REQUEST_ENABLE_DEBUG_TRACING = "enable-debug-tracing"; public static final String REQUEST_DISABLE_DEBUG_TRACING = "disable-debug-tracing"; public static final String NO_DRAG_TAG = "b/133009122"; - public static final String NO_START_TAG = "b/132900132"; public static final String NO_START_TASK_TAG = "b/133765434"; public static final String NO_OVERVIEW_EVENT_TAG = "b/134532571"; } diff --git a/src/com/android/launcher3/touch/ItemClickHandler.java b/src/com/android/launcher3/touch/ItemClickHandler.java index 85f763d095..2895a89be3 100644 --- a/src/com/android/launcher3/touch/ItemClickHandler.java +++ b/src/com/android/launcher3/touch/ItemClickHandler.java @@ -68,28 +68,12 @@ public class ItemClickHandler { } private static void onClick(View v, String sourceContainer) { - if (TestProtocol.sDebugTracing) { - android.util.Log.d(TestProtocol.NO_START_TAG, - "onClick 1"); - } // Make sure that rogue clicks don't get through while allapps is launching, or after the // view has detached (it's possible for this to happen if the view is removed mid touch). - if (v.getWindowToken() == null) { - if (TestProtocol.sDebugTracing) { - android.util.Log.d(TestProtocol.NO_START_TAG, - "onClick 2"); - } - return; - } + if (v.getWindowToken() == null) return; Launcher launcher = Launcher.getLauncher(v.getContext()); - if (!launcher.getWorkspace().isFinishedSwitchingState()) { - if (TestProtocol.sDebugTracing) { - android.util.Log.d(TestProtocol.NO_START_TAG, - "onClick 3"); - } - return; - } + if (!launcher.getWorkspace().isFinishedSwitchingState()) return; Object tag = v.getTag(); if (tag instanceof WorkspaceItemInfo) { @@ -99,10 +83,6 @@ public class ItemClickHandler { onClickFolderIcon(v); } } else if (tag instanceof AppInfo) { - if (TestProtocol.sDebugTracing) { - android.util.Log.d(TestProtocol.NO_START_TAG, - "onClick 4"); - } startAppShortcutOrInfoActivity(v, (AppInfo) tag, launcher, sourceContainer == null ? CONTAINER_ALL_APPS: sourceContainer); } else if (tag instanceof LauncherAppWidgetInfo) { @@ -234,10 +214,6 @@ public class ItemClickHandler { private static void startAppShortcutOrInfoActivity(View v, ItemInfo item, Launcher launcher, @Nullable String sourceContainer) { - if (TestProtocol.sDebugTracing) { - android.util.Log.d(TestProtocol.NO_START_TAG, - "startAppShortcutOrInfoActivity"); - } Intent intent; if (item instanceof PromiseAppInfo) { PromiseAppInfo promiseAppInfo = (PromiseAppInfo) item; diff --git a/src/com/android/launcher3/views/BaseDragLayer.java b/src/com/android/launcher3/views/BaseDragLayer.java index 15f2724708..8bf33bf05c 100644 --- a/src/com/android/launcher3/views/BaseDragLayer.java +++ b/src/com/android/launcher3/views/BaseDragLayer.java @@ -256,9 +256,6 @@ public abstract class BaseDragLayer @Override public boolean dispatchTouchEvent(MotionEvent ev) { - if (TestProtocol.sDebugTracing) { - Log.d(TestProtocol.NO_START_TAG, "BaseDragLayer.dispatchTouchEvent " + ev); - } switch (ev.getAction()) { case ACTION_DOWN: { float x = ev.getX(); From e1463f5580ed46a37816e586f75eab697d4c3a7b Mon Sep 17 00:00:00 2001 From: Tony Wickham Date: Thu, 11 Jul 2019 16:55:01 -0700 Subject: [PATCH 031/108] Defer jumping to NORMAL state if overview is still peeking Bug: 137316430 Change-Id: I1ace19bb229d07bd9dfe5ed6f60c63715b9f8cf2 --- .../FlingAndHoldTouchController.java | 15 +++++++++++++++ .../touch/AbstractStateChangeTouchController.java | 14 ++++++++------ 2 files changed, 23 insertions(+), 6 deletions(-) diff --git a/quickstep/recents_ui_overrides/src/com/android/launcher3/uioverrides/touchcontrollers/FlingAndHoldTouchController.java b/quickstep/recents_ui_overrides/src/com/android/launcher3/uioverrides/touchcontrollers/FlingAndHoldTouchController.java index 3fe4bcfd9c..f06b8a910f 100644 --- a/quickstep/recents_ui_overrides/src/com/android/launcher3/uioverrides/touchcontrollers/FlingAndHoldTouchController.java +++ b/quickstep/recents_ui_overrides/src/com/android/launcher3/uioverrides/touchcontrollers/FlingAndHoldTouchController.java @@ -167,6 +167,21 @@ public class FlingAndHoldTouchController extends PortraitStatesTouchController { mMotionPauseDetector.clear(); } + @Override + protected void goToTargetState(LauncherState targetState, int logAction) { + if (mPeekAnim != null && mPeekAnim.isStarted()) { + // Don't jump to the target state until overview is no longer peeking. + mPeekAnim.addListener(new AnimatorListenerAdapter() { + @Override + public void onAnimationEnd(Animator animation) { + FlingAndHoldTouchController.super.goToTargetState(targetState, logAction); + } + }); + } else { + super.goToTargetState(targetState, logAction); + } + } + @Override protected void updateAnimatorBuilderOnReinit(AnimatorSetBuilder builder) { if (handlingOverviewAnim()) { diff --git a/src/com/android/launcher3/touch/AbstractStateChangeTouchController.java b/src/com/android/launcher3/touch/AbstractStateChangeTouchController.java index 7252410e03..ae69f3b32d 100644 --- a/src/com/android/launcher3/touch/AbstractStateChangeTouchController.java +++ b/src/com/android/launcher3/touch/AbstractStateChangeTouchController.java @@ -31,7 +31,6 @@ import android.animation.AnimatorListenerAdapter; import android.animation.AnimatorSet; import android.animation.ValueAnimator; import android.os.SystemClock; -import android.util.Log; import android.view.HapticFeedbackConstants; import android.view.MotionEvent; @@ -43,7 +42,6 @@ import com.android.launcher3.Utilities; import com.android.launcher3.anim.AnimationSuccessListener; import com.android.launcher3.anim.AnimatorPlaybackController; import com.android.launcher3.anim.AnimatorSetBuilder; -import com.android.launcher3.testing.TestProtocol; import com.android.launcher3.userevent.nano.LauncherLogProto; import com.android.launcher3.userevent.nano.LauncherLogProto.Action.Direction; import com.android.launcher3.userevent.nano.LauncherLogProto.Action.Touch; @@ -513,13 +511,17 @@ public abstract class AbstractStateChangeTouchController shouldGoToTargetState = !reachedTarget; } if (shouldGoToTargetState) { - if (targetState != mStartState) { - logReachedState(logAction, targetState); - } - mLauncher.getStateManager().goToState(targetState, false /* animated */); + goToTargetState(targetState, logAction); } } + protected void goToTargetState(LauncherState targetState, int logAction) { + if (targetState != mStartState) { + logReachedState(logAction, targetState); + } + mLauncher.getStateManager().goToState(targetState, false /* animated */); + } + private void logReachedState(int logAction, LauncherState targetState) { // Transition complete. log the action mLauncher.getUserEventDispatcher().logStateChangeAction(logAction, From 7400bb3f725d288766ddf9e9256327fcb90015c5 Mon Sep 17 00:00:00 2001 From: Anna Wasewicz Date: Thu, 11 Jul 2019 18:58:05 -0700 Subject: [PATCH 032/108] Set the chips flag to false in QP1A. This flag should be off by default. Chips should not be running in QP1A. Bug:137290162 Change-Id: I159e1bd00d1f9ff4f6cf63daf93a68e3e8d063c8 --- src/com/android/launcher3/config/BaseFlags.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/com/android/launcher3/config/BaseFlags.java b/src/com/android/launcher3/config/BaseFlags.java index 54efcb7868..45639e0a43 100644 --- a/src/com/android/launcher3/config/BaseFlags.java +++ b/src/com/android/launcher3/config/BaseFlags.java @@ -105,7 +105,7 @@ abstract class BaseFlags { "ENABLE_QUICKSTEP_LIVE_TILE", false, "Enable live tile in Quickstep overview"); public static final TogglableFlag ENABLE_HINTS_IN_OVERVIEW = new TogglableFlag( - "ENABLE_HINTS_IN_OVERVIEW", true, + "ENABLE_HINTS_IN_OVERVIEW", false, "Show chip hints and gleams on the overview screen"); public static final TogglableFlag FAKE_LANDSCAPE_UI = new TogglableFlag( From 39cfa03d11f134b997da3e94bd5d44d4e32fa75a Mon Sep 17 00:00:00 2001 From: Winson Chung Date: Fri, 12 Jul 2019 12:02:24 -0700 Subject: [PATCH 033/108] Update the home stack bounds with the transition end points - When the user dismisses splitscreen while launcher is hidden and was previously minimized, getLocationOnScreen() will continue to return the old position until the first view root traversal after the window is shown. As a result, we will end up with home bounds for the minimized state and the wrong target bounds calculated Bug: 135952890 Test: Enter splitscreen, launcher another app, dismiss splitscreen and then swipe up Change-Id: Id19dfa664623b2b855db4209999508c76a9aacdc --- .../WindowTransformSwipeHandler.java | 32 ++++++++++++------- .../quickstep/util/ClipAnimationHelper.java | 6 +++- 2 files changed, 26 insertions(+), 12 deletions(-) diff --git a/quickstep/recents_ui_overrides/src/com/android/quickstep/WindowTransformSwipeHandler.java b/quickstep/recents_ui_overrides/src/com/android/quickstep/WindowTransformSwipeHandler.java index ac7ba3fc3d..d81bb31e60 100644 --- a/quickstep/recents_ui_overrides/src/com/android/quickstep/WindowTransformSwipeHandler.java +++ b/quickstep/recents_ui_overrides/src/com/android/quickstep/WindowTransformSwipeHandler.java @@ -381,12 +381,31 @@ public class WindowTransformSwipeHandler } } + private Rect getStackBounds(DeviceProfile dp) { + if (mActivity != null) { + int loc[] = new int[2]; + View rootView = mActivity.getRootView(); + rootView.getLocationOnScreen(loc); + return new Rect(loc[0], loc[1], loc[0] + rootView.getWidth(), + loc[1] + rootView.getHeight()); + } else { + return new Rect(0, 0, dp.widthPx, dp.heightPx); + } + } + private void initTransitionEndpoints(DeviceProfile dp) { mDp = dp; Rect tempRect = new Rect(); mTransitionDragLength = mActivityControlHelper.getSwipeUpDestinationAndLength( dp, mContext, tempRect); + if (!dp.isMultiWindowMode) { + // When updating the target rect, also update the home bounds since the location on + // screen of the launcher window may be stale (position is not updated until first + // traversal after the window is resized). We only do this for non-multiwindow because + // we otherwise use the minimized home bounds provided by the system. + mClipAnimationHelper.updateHomeBounds(getStackBounds(dp)); + } mClipAnimationHelper.updateTargetRect(tempRect); if (mMode == Mode.NO_BUTTON) { // We can drag all the way to the top of the screen. @@ -776,21 +795,12 @@ public class WindowTransformSwipeHandler .getOverviewWindowBounds(targetSet.minimizedHomeBounds, runningTaskTarget); dp = dp.getMultiWindowProfile(mContext, new Point( targetSet.minimizedHomeBounds.width(), targetSet.minimizedHomeBounds.height())); - dp.updateInsets(targetSet.homeContentInsets); } else { - if (mActivity != null) { - int loc[] = new int[2]; - View rootView = mActivity.getRootView(); - rootView.getLocationOnScreen(loc); - overviewStackBounds = new Rect(loc[0], loc[1], loc[0] + rootView.getWidth(), - loc[1] + rootView.getHeight()); - } else { - overviewStackBounds = new Rect(0, 0, dp.widthPx, dp.heightPx); - } // If we are not in multi-window mode, home insets should be same as system insets. dp = dp.copy(mContext); - dp.updateInsets(targetSet.homeContentInsets); + overviewStackBounds = getStackBounds(dp); } + dp.updateInsets(targetSet.homeContentInsets); dp.updateIsSeascape(mContext.getSystemService(WindowManager.class)); if (runningTaskTarget != null) { diff --git a/quickstep/recents_ui_overrides/src/com/android/quickstep/util/ClipAnimationHelper.java b/quickstep/recents_ui_overrides/src/com/android/quickstep/util/ClipAnimationHelper.java index de671e04aa..9809112a0d 100644 --- a/quickstep/recents_ui_overrides/src/com/android/quickstep/util/ClipAnimationHelper.java +++ b/quickstep/recents_ui_overrides/src/com/android/quickstep/util/ClipAnimationHelper.java @@ -119,8 +119,12 @@ public class ClipAnimationHelper { } public void updateSource(Rect homeStackBounds, RemoteAnimationTargetCompat target) { - mHomeStackBounds.set(homeStackBounds); updateSourceStack(target); + updateHomeBounds(homeStackBounds); + } + + public void updateHomeBounds(Rect homeStackBounds) { + mHomeStackBounds.set(homeStackBounds); } public void updateTargetRect(Rect targetRect) { From d91cec72feb435d403192080edc28747889d02fa Mon Sep 17 00:00:00 2001 From: vadimt Date: Fri, 12 Jul 2019 12:26:08 -0700 Subject: [PATCH 034/108] Simplifying switching to home for some tests Change-Id: I696d0267a2c36a18080396657bed07f7b1654a7d --- .../quickstep/AppPredictionsUITests.java | 6 ++--- .../ui/DefaultLayoutProviderTest.java | 6 ++--- .../com/android/launcher3/ui/WorkTabTest.java | 2 +- .../ui/widget/AddConfigWidgetTest.java | 2 +- .../launcher3/ui/widget/AddWidgetTest.java | 2 +- .../launcher3/ui/widget/BindWidgetTest.java | 2 +- .../ui/widget/RequestPinItemTest.java | 2 +- .../util/rule/LauncherActivityRule.java | 26 ++++--------------- 8 files changed, 16 insertions(+), 32 deletions(-) diff --git a/quickstep/tests/src/com/android/quickstep/AppPredictionsUITests.java b/quickstep/tests/src/com/android/quickstep/AppPredictionsUITests.java index d9fcf4d97a..d0956d1f6d 100644 --- a/quickstep/tests/src/com/android/quickstep/AppPredictionsUITests.java +++ b/quickstep/tests/src/com/android/quickstep/AppPredictionsUITests.java @@ -88,7 +88,7 @@ public class AppPredictionsUITests extends AbstractQuickStepTest { */ @Test public void testPredictionExistsInAllApps() { - mActivityMonitor.startLauncher(); + mDevice.pressHome(); mLauncher.pressHome().switchToAllApps(); // Dispatch an update @@ -103,7 +103,7 @@ public class AppPredictionsUITests extends AbstractQuickStepTest { */ @Test public void testPredictionsDeferredUntilHome() { - mActivityMonitor.startLauncher(); + mDevice.pressHome(); sendPredictionUpdate(mSampleApp1, mSampleApp2); mLauncher.pressHome().switchToAllApps(); waitForLauncherCondition("Predictions were not updated in loading state", @@ -120,7 +120,7 @@ public class AppPredictionsUITests extends AbstractQuickStepTest { @Test public void testPredictionsDisabled() { - mActivityMonitor.startLauncher(); + mDevice.pressHome(); sendPredictionUpdate(); mLauncher.pressHome().switchToAllApps(); diff --git a/tests/src/com/android/launcher3/ui/DefaultLayoutProviderTest.java b/tests/src/com/android/launcher3/ui/DefaultLayoutProviderTest.java index 58c74cef16..a76b4a4886 100644 --- a/tests/src/com/android/launcher3/ui/DefaultLayoutProviderTest.java +++ b/tests/src/com/android/launcher3/ui/DefaultLayoutProviderTest.java @@ -72,7 +72,7 @@ public class DefaultLayoutProviderTest extends AbstractLauncherUiTest { writeLayout(new LauncherLayoutBuilder().atHotseat(0).putApp(SETTINGS_APP, SETTINGS_APP)); // Launch the home activity - mActivityMonitor.startLauncher(); + mDevice.pressHome(); waitForModelLoaded(); mLauncher.getWorkspace().getHotseatAppIcon(getSettingsApp().getLabel().toString()); @@ -88,7 +88,7 @@ public class DefaultLayoutProviderTest extends AbstractLauncherUiTest { info.getComponent().getClassName(), 2, 2)); // Launch the home activity - mActivityMonitor.startLauncher(); + mDevice.pressHome(); waitForModelLoaded(); // Verify widget present @@ -105,7 +105,7 @@ public class DefaultLayoutProviderTest extends AbstractLauncherUiTest { .build()); // Launch the home activity - mActivityMonitor.startLauncher(); + mDevice.pressHome(); waitForModelLoaded(); mLauncher.getWorkspace().getHotseatFolder("Folder: Copy"); diff --git a/tests/src/com/android/launcher3/ui/WorkTabTest.java b/tests/src/com/android/launcher3/ui/WorkTabTest.java index c93c20a616..79c2d071d5 100644 --- a/tests/src/com/android/launcher3/ui/WorkTabTest.java +++ b/tests/src/com/android/launcher3/ui/WorkTabTest.java @@ -53,7 +53,7 @@ public class WorkTabTest extends AbstractLauncherUiTest { @Test public void workTabExists() { - mActivityMonitor.startLauncher(); + mDevice.pressHome(); executeOnLauncher(launcher -> launcher.getStateManager().goToState(ALL_APPS)); diff --git a/tests/src/com/android/launcher3/ui/widget/AddConfigWidgetTest.java b/tests/src/com/android/launcher3/ui/widget/AddConfigWidgetTest.java index dc72bda9a3..3206a69bbf 100644 --- a/tests/src/com/android/launcher3/ui/widget/AddConfigWidgetTest.java +++ b/tests/src/com/android/launcher3/ui/widget/AddConfigWidgetTest.java @@ -98,7 +98,7 @@ public class AddConfigWidgetTest extends AbstractLauncherUiTest { lockRotation(true); clearHomescreen(); - mActivityMonitor.startLauncher(); + mDevice.pressHome(); final Widgets widgets = mLauncher.getWorkspace().openAllWidgets(); diff --git a/tests/src/com/android/launcher3/ui/widget/AddWidgetTest.java b/tests/src/com/android/launcher3/ui/widget/AddWidgetTest.java index 4529a80d1d..276c6144a2 100644 --- a/tests/src/com/android/launcher3/ui/widget/AddWidgetTest.java +++ b/tests/src/com/android/launcher3/ui/widget/AddWidgetTest.java @@ -55,7 +55,7 @@ public class AddWidgetTest extends AbstractLauncherUiTest { private void performTest() throws Throwable { clearHomescreen(); - mActivityMonitor.startLauncher(); + mDevice.pressHome(); final LauncherAppWidgetProviderInfo widgetInfo = TestViewHelpers.findWidgetProvider(this, false /* hasConfigureScreen */); diff --git a/tests/src/com/android/launcher3/ui/widget/BindWidgetTest.java b/tests/src/com/android/launcher3/ui/widget/BindWidgetTest.java index d36126bb17..3a7df64e81 100644 --- a/tests/src/com/android/launcher3/ui/widget/BindWidgetTest.java +++ b/tests/src/com/android/launcher3/ui/widget/BindWidgetTest.java @@ -267,7 +267,7 @@ public class BindWidgetTest extends AbstractLauncherUiTest { resetLoaderState(); // Launch the home activity - mActivityMonitor.startLauncher(); + mDevice.pressHome(); waitForModelLoaded(); } diff --git a/tests/src/com/android/launcher3/ui/widget/RequestPinItemTest.java b/tests/src/com/android/launcher3/ui/widget/RequestPinItemTest.java index 6122daec2c..a9a5090988 100644 --- a/tests/src/com/android/launcher3/ui/widget/RequestPinItemTest.java +++ b/tests/src/com/android/launcher3/ui/widget/RequestPinItemTest.java @@ -131,7 +131,7 @@ public class RequestPinItemTest extends AbstractLauncherUiTest { lockRotation(true); clearHomescreen(); - mActivityMonitor.startLauncher(); + mDevice.pressHome(); // Open Pin item activity BlockingBroadcastReceiver openMonitor = new BlockingBroadcastReceiver( diff --git a/tests/src/com/android/launcher3/util/rule/LauncherActivityRule.java b/tests/src/com/android/launcher3/util/rule/LauncherActivityRule.java index 2aba7a56de..204240324e 100644 --- a/tests/src/com/android/launcher3/util/rule/LauncherActivityRule.java +++ b/tests/src/com/android/launcher3/util/rule/LauncherActivityRule.java @@ -15,11 +15,6 @@ */ package com.android.launcher3.util.rule; -import static com.android.launcher3.tapl.TestHelpers.getHomeIntentInPackage; - -import static androidx.test.InstrumentationRegistry.getInstrumentation; -import static androidx.test.InstrumentationRegistry.getTargetContext; - import android.app.Activity; import android.app.Application; import android.app.Application.ActivityLifecycleCallbacks; @@ -52,26 +47,15 @@ public class LauncherActivityRule implements TestRule { } public Callable itemExists(final ItemOperator op) { - return new Callable() { - - @Override - public Boolean call() throws Exception { - Launcher launcher = getActivity(); - if (launcher == null) { - return false; - } - return launcher.getWorkspace().getFirstMatch(op) != null; + return () -> { + Launcher launcher = getActivity(); + if (launcher == null) { + return false; } + return launcher.getWorkspace().getFirstMatch(op) != null; }; } - /** - * Starts the launcher activity in the target package. - */ - public void startLauncher() { - getInstrumentation().startActivitySync(getHomeIntentInPackage(getTargetContext())); - } - private class MyStatement extends Statement implements ActivityLifecycleCallbacks { private final Statement mBase; From 5818f9b3c523d41ba0e399a1513e22bb83d38abc Mon Sep 17 00:00:00 2001 From: Tony Date: Fri, 12 Jul 2019 18:02:09 -0700 Subject: [PATCH 035/108] Fix overshoot velocity in 2-button landscape mode Now we use the velocity towards the middle of the screen (e.g. x when in landscape) instead of always using y. Test: testBackground with @PortraitLandscape Bug: 135567630 Change-Id: I77ab6bdf0d556475a6c182ae91914a718a81e1c4 --- .../src/com/android/quickstep/WindowTransformSwipeHandler.java | 2 +- .../tests/src/com/android/quickstep/TaplTestsQuickstep.java | 3 +-- src/com/android/launcher3/anim/Interpolators.java | 3 ++- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/quickstep/recents_ui_overrides/src/com/android/quickstep/WindowTransformSwipeHandler.java b/quickstep/recents_ui_overrides/src/com/android/quickstep/WindowTransformSwipeHandler.java index ac7ba3fc3d..4f351bae9d 100644 --- a/quickstep/recents_ui_overrides/src/com/android/quickstep/WindowTransformSwipeHandler.java +++ b/quickstep/recents_ui_overrides/src/com/android/quickstep/WindowTransformSwipeHandler.java @@ -976,7 +976,7 @@ public class WindowTransformSwipeHandler if (Math.abs(endVelocity) > minFlingVelocity && mTransitionDragLength > 0) { if (endTarget == RECENTS && mMode != Mode.NO_BUTTON) { Interpolators.OvershootParams overshoot = new Interpolators.OvershootParams( - startShift, endShift, endShift, velocityPxPerMs.y, + startShift, endShift, endShift, endVelocity / 1000, mTransitionDragLength); endShift = overshoot.end; interpolator = overshoot.interpolator; diff --git a/quickstep/tests/src/com/android/quickstep/TaplTestsQuickstep.java b/quickstep/tests/src/com/android/quickstep/TaplTestsQuickstep.java index 9e3bf2f56e..885fdbf423 100644 --- a/quickstep/tests/src/com/android/quickstep/TaplTestsQuickstep.java +++ b/quickstep/tests/src/com/android/quickstep/TaplTestsQuickstep.java @@ -17,7 +17,6 @@ package com.android.quickstep; import static com.android.launcher3.ui.TaplTestsLauncher3.getAppPackageName; - import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertNotNull; import static org.junit.Assert.assertTrue; @@ -208,7 +207,7 @@ public class TaplTestsQuickstep extends AbstractQuickStepTest { @Test @NavigationModeSwitch -// @PortraitLandscape + @PortraitLandscape public void testBackground() throws Exception { startAppFast(resolveSystemApp(Intent.CATEGORY_APP_CALCULATOR)); final Background background = mLauncher.getBackground(); diff --git a/src/com/android/launcher3/anim/Interpolators.java b/src/com/android/launcher3/anim/Interpolators.java index b169cb80be..8443231e8d 100644 --- a/src/com/android/launcher3/anim/Interpolators.java +++ b/src/com/android/launcher3/anim/Interpolators.java @@ -144,7 +144,8 @@ public class Interpolators { public static Interpolator clampToProgress(Interpolator interpolator, float lowerBound, float upperBound) { if (upperBound <= lowerBound) { - throw new IllegalArgumentException("lowerBound must be less than upperBound"); + throw new IllegalArgumentException(String.format( + "lowerBound (%f) must be less than upperBound (%f)", lowerBound, upperBound)); } return t -> { if (t < lowerBound) { From 69ac3349353242e267512119c0c3077cf2f5a647 Mon Sep 17 00:00:00 2001 From: Riddle Hsu Date: Mon, 15 Jul 2019 18:49:06 +0800 Subject: [PATCH 036/108] Don't preload overview if current home isn't gestural overview During first boot, home activity after FallbackHome may be an one-time setup. If the overview is preloaded at this moment, system won't resume the real home after the one-time setup is finished because the activity stack is not empty. Since the navigation mode doesn't support gesture during the first time setup, and in order to keep the ability to preload launcher if it is also the overview, these conditions are combined to guard the case of first boot. Fix: 137281732 Test: Build sdk_gphone_x86-userdebug. Run "emulator -wipe-data" and check the recents activity won't start during booting. Change-Id: I4b20f61f4a412371c19b379410c8a0a188e41276 --- .../src/com/android/quickstep/TouchInteractionService.java | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/quickstep/recents_ui_overrides/src/com/android/quickstep/TouchInteractionService.java b/quickstep/recents_ui_overrides/src/com/android/quickstep/TouchInteractionService.java index 22c18d0b00..fd4b3940a5 100644 --- a/quickstep/recents_ui_overrides/src/com/android/quickstep/TouchInteractionService.java +++ b/quickstep/recents_ui_overrides/src/com/android/quickstep/TouchInteractionService.java @@ -708,6 +708,10 @@ public class TouchInteractionService extends Service implements if (!mIsUserUnlocked) { return; } + if (!mMode.hasGestures && !mOverviewComponentObserver.isHomeAndOverviewSame()) { + // Prevent the overview from being started before the real home on first boot. + return; + } final ActivityControlHelper activityControl = mOverviewComponentObserver.getActivityControlHelper(); From 092b6f8cbf40b0f144fb4d903f92ade6bdbacb0e Mon Sep 17 00:00:00 2001 From: vadimt Date: Thu, 27 Jun 2019 19:16:38 -0700 Subject: [PATCH 037/108] Adding system health diags for inporoc tests Bug: 133891845 Change-Id: I90161bfc9db5983a45dfb89728a82ec1e3d81f19 --- .../testcomponent/TestCommandReceiver.java | 17 +++- .../launcher3/ui/AbstractLauncherUiTest.java | 7 +- .../tapl/LauncherInstrumentation.java | 84 ++++--------------- .../android/launcher3/tapl/TestHelpers.java | 68 +++++++++++++++ 4 files changed, 102 insertions(+), 74 deletions(-) diff --git a/tests/src/com/android/launcher3/testcomponent/TestCommandReceiver.java b/tests/src/com/android/launcher3/testcomponent/TestCommandReceiver.java index fa23b8d5b9..6a6916eec3 100644 --- a/tests/src/com/android/launcher3/testcomponent/TestCommandReceiver.java +++ b/tests/src/com/android/launcher3/testcomponent/TestCommandReceiver.java @@ -32,13 +32,14 @@ import android.os.Bundle; import android.os.ParcelFileDescriptor; import android.util.Base64; +import androidx.test.InstrumentationRegistry; + +import com.android.launcher3.tapl.TestHelpers; + import java.io.File; import java.io.FileNotFoundException; -import java.io.FileOutputStream; import java.io.IOException; -import androidx.test.InstrumentationRegistry; - /** * Content provider to receive commands from tests */ @@ -47,6 +48,7 @@ public class TestCommandReceiver extends ContentProvider { public static final String ENABLE_TEST_LAUNCHER = "enable-test-launcher"; public static final String DISABLE_TEST_LAUNCHER = "disable-test-launcher"; public static final String KILL_PROCESS = "kill-process"; + public static final String GET_SYSTEM_HEALTH_MESSAGE = "get-system-health-message"; @Override public boolean onCreate() { @@ -99,6 +101,12 @@ public class TestCommandReceiver extends ContentProvider { killBackgroundProcesses(arg); return null; } + + case GET_SYSTEM_HEALTH_MESSAGE: { + final Bundle response = new Bundle(); + response.putString("result", TestHelpers.getSystemHealthMessage(getContext())); + return response; + } } return super.call(method, arg, extras); } @@ -122,7 +130,8 @@ public class TestCommandReceiver extends ContentProvider { // Create an empty file so that we can pass its descriptor try { file.createNewFile(); - } catch (IOException e) { } + } catch (IOException e) { + } } return ParcelFileDescriptor.open(file, MODE_READ_WRITE); diff --git a/tests/src/com/android/launcher3/ui/AbstractLauncherUiTest.java b/tests/src/com/android/launcher3/ui/AbstractLauncherUiTest.java index e39fc76a0b..361f2fb533 100644 --- a/tests/src/com/android/launcher3/ui/AbstractLauncherUiTest.java +++ b/tests/src/com/android/launcher3/ui/AbstractLauncherUiTest.java @@ -51,6 +51,7 @@ import com.android.launcher3.compat.LauncherAppsCompat; import com.android.launcher3.model.AppLaunchTracker; import com.android.launcher3.tapl.LauncherInstrumentation; import com.android.launcher3.tapl.TestHelpers; +import com.android.launcher3.testcomponent.TestCommandReceiver; import com.android.launcher3.util.PackageManagerHelper; import com.android.launcher3.util.Wait; import com.android.launcher3.util.rule.FailureWatcher; @@ -98,7 +99,11 @@ public abstract class AbstractLauncherUiTest { } catch (RemoteException e) { throw new RuntimeException(e); } - if (TestHelpers.isInLauncherProcess()) Utilities.enableRunningInTestHarnessForTests(); + if (TestHelpers.isInLauncherProcess()) { + Utilities.enableRunningInTestHarnessForTests(); + mLauncher.setSystemHealthSupplier(() -> TestCommandReceiver.callCommand( + TestCommandReceiver.GET_SYSTEM_HEALTH_MESSAGE).getString("result")); + } } protected final LauncherActivityRule mActivityMonitor = new LauncherActivityRule(); diff --git a/tests/tapl/com/android/launcher3/tapl/LauncherInstrumentation.java b/tests/tapl/com/android/launcher3/tapl/LauncherInstrumentation.java index 5a6c898104..0fed337a04 100644 --- a/tests/tapl/com/android/launcher3/tapl/LauncherInstrumentation.java +++ b/tests/tapl/com/android/launcher3/tapl/LauncherInstrumentation.java @@ -39,7 +39,6 @@ import android.graphics.Rect; import android.net.Uri; import android.os.Build; import android.os.Bundle; -import android.os.DropBoxManager; import android.os.Parcelable; import android.os.SystemClock; import android.text.TextUtils; @@ -73,6 +72,7 @@ import java.util.Deque; import java.util.LinkedList; import java.util.List; import java.util.concurrent.TimeoutException; +import java.util.function.Supplier; /** * The main tapl object. The only object that can be explicitly constructed by the using code. It @@ -133,6 +133,7 @@ public final class LauncherInstrumentation { private int mExpectedRotation = Surface.ROTATION_0; private final Uri mTestProviderUri; private final Deque mDiagnosticContext = new LinkedList<>(); + private Supplier mSystemHealthSupplier; /** * Constructs the root of TAPL hierarchy. You get all other objects from it. @@ -285,79 +286,24 @@ public final class LauncherInstrumentation { return "Background"; } - private static String truncateCrash(String text, int maxLines) { - String[] lines = text.split("\\r?\\n"); - StringBuilder ret = new StringBuilder(); - for (int i = 0; i < maxLines && i < lines.length; i++) { - ret.append(lines[i]); - ret.append('\n'); - } - if (lines.length > maxLines) { - ret.append("... "); - ret.append(lines.length - maxLines); - ret.append(" more lines truncated ...\n"); - } - return ret.toString(); - } - - private String checkCrash(String label) { - DropBoxManager dropbox = (DropBoxManager) getContext().getSystemService( - Context.DROPBOX_SERVICE); - Assert.assertNotNull("Unable access the DropBoxManager service", dropbox); - - long timestamp = 0; - DropBoxManager.Entry entry; - int crashCount = 0; - StringBuilder errorDetails = new StringBuilder(); - while (null != (entry = dropbox.getNextEntry(label, timestamp))) { - String dropboxSnippet; - try { - dropboxSnippet = entry.getText(4096); - } finally { - entry.close(); - } - - crashCount++; - errorDetails.append(label); - errorDetails.append(": "); - errorDetails.append(truncateCrash(dropboxSnippet, 40)); - errorDetails.append(" ...\n"); - - timestamp = entry.getTimeMillis(); - } - Assert.assertEquals(errorDetails.toString(), 0, crashCount); - return crashCount > 0 ? errorDetails.toString() : null; + public void setSystemHealthSupplier(Supplier supplier) { + this.mSystemHealthSupplier = supplier; } private String getSystemHealthMessage() { + final String testPackage = getContext().getPackageName(); try { - StringBuilder errors = new StringBuilder(); - - final String testPackage = getContext().getPackageName(); - try { - mDevice.executeShellCommand("pm grant " + testPackage + - " android.permission.READ_LOGS"); - mDevice.executeShellCommand("pm grant " + testPackage + - " android.permission.PACKAGE_USAGE_STATS"); - } catch (IOException e) { - e.printStackTrace(); - } - - final String[] labels = { - "system_server_crash", - "system_server_native_crash", - "system_server_anr", - }; - - for (String label : labels) { - final String crash = checkCrash(label); - if (crash != null) errors.append(crash); - } - - return errors.length() != 0 ? errors.toString() : null; - } catch (Exception e) { - return null; + mDevice.executeShellCommand("pm grant " + testPackage + + " android.permission.READ_LOGS"); + mDevice.executeShellCommand("pm grant " + testPackage + + " android.permission.PACKAGE_USAGE_STATS"); + } catch (IOException e) { + e.printStackTrace(); } + + return mSystemHealthSupplier != null + ? mSystemHealthSupplier.get() + : TestHelpers.getSystemHealthMessage(getContext()); } private void fail(String message) { diff --git a/tests/tapl/com/android/launcher3/tapl/TestHelpers.java b/tests/tapl/com/android/launcher3/tapl/TestHelpers.java index 93554d2452..e19f91a20a 100644 --- a/tests/tapl/com/android/launcher3/tapl/TestHelpers.java +++ b/tests/tapl/com/android/launcher3/tapl/TestHelpers.java @@ -26,6 +26,9 @@ import android.content.Intent; import android.content.pm.ActivityInfo; import android.content.pm.ResolveInfo; import android.content.res.Resources; +import android.os.DropBoxManager; + +import org.junit.Assert; import java.util.List; @@ -81,4 +84,69 @@ public class TestHelpers { } return "com.android.systemui"; } + + private static String truncateCrash(String text, int maxLines) { + String[] lines = text.split("\\r?\\n"); + StringBuilder ret = new StringBuilder(); + for (int i = 0; i < maxLines && i < lines.length; i++) { + ret.append(lines[i]); + ret.append('\n'); + } + if (lines.length > maxLines) { + ret.append("... "); + ret.append(lines.length - maxLines); + ret.append(" more lines truncated ...\n"); + } + return ret.toString(); + } + + private static String checkCrash(Context context, String label) { + DropBoxManager dropbox = (DropBoxManager) context.getSystemService(Context.DROPBOX_SERVICE); + Assert.assertNotNull("Unable access the DropBoxManager service", dropbox); + + long timestamp = 0; + DropBoxManager.Entry entry; + int crashCount = 0; + StringBuilder errorDetails = new StringBuilder(); + while (null != (entry = dropbox.getNextEntry(label, timestamp))) { + String dropboxSnippet; + try { + dropboxSnippet = entry.getText(4096); + } finally { + entry.close(); + } + + crashCount++; + errorDetails.append(label); + errorDetails.append(": "); + errorDetails.append(truncateCrash(dropboxSnippet, 40)); + errorDetails.append(" ...\n"); + + timestamp = entry.getTimeMillis(); + } + Assert.assertEquals(errorDetails.toString(), 0, crashCount); + return crashCount > 0 ? errorDetails.toString() : null; + } + + public static String getSystemHealthMessage(Context context) { + try { + StringBuilder errors = new StringBuilder(); + + final String[] labels = { + "system_server_crash", + "system_server_native_crash", + "system_server_anr", + }; + + for (String label : labels) { + final String crash = checkCrash(context, label); + if (crash != null) errors.append(crash); + } + + return errors.length() != 0 ? errors.toString() : null; + } catch (Exception e) { + return "Failed to get system health diags, maybe build your test via .bp instead of " + + ".mk? " + android.util.Log.getStackTraceString(e); + } + } } From 8820399e57c78000c8e25e2c91de706063878a07 Mon Sep 17 00:00:00 2001 From: vadimt Date: Mon, 15 Jul 2019 13:30:32 -0700 Subject: [PATCH 038/108] Waiting for launcher to start in workTabExists() Change-Id: I08c5385b188dda81ee0dfc1bfd639a0892bd6584 --- tests/src/com/android/launcher3/ui/WorkTabTest.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/src/com/android/launcher3/ui/WorkTabTest.java b/tests/src/com/android/launcher3/ui/WorkTabTest.java index 79c2d071d5..d9edc35874 100644 --- a/tests/src/com/android/launcher3/ui/WorkTabTest.java +++ b/tests/src/com/android/launcher3/ui/WorkTabTest.java @@ -54,7 +54,7 @@ public class WorkTabTest extends AbstractLauncherUiTest { @Test public void workTabExists() { mDevice.pressHome(); - + waitForLauncherCondition("Launcher didn't start", launcher -> launcher != null); executeOnLauncher(launcher -> launcher.getStateManager().goToState(ALL_APPS)); /* From 7dcd09433094e1585a6c454081c15f4878c2ee94 Mon Sep 17 00:00:00 2001 From: Bill Yi Date: Mon, 15 Jul 2019 15:34:10 -0700 Subject: [PATCH 039/108] Import translations. DO NOT MERGE Auto-generated-cl: translation import Bug: 64712476 Change-Id: I897d0df49125785a4524fedb8dcdbad50f758337 --- quickstep/res/values-fr/strings.xml | 2 +- quickstep/res/values-hi/strings.xml | 2 +- quickstep/res/values-mr/strings.xml | 2 +- res/values-ca/strings.xml | 2 +- res/values-in/strings.xml | 12 ++++++------ res/values-mr/strings.xml | 14 +++++++------- res/values-ru/strings.xml | 2 +- 7 files changed, 18 insertions(+), 18 deletions(-) diff --git a/quickstep/res/values-fr/strings.xml b/quickstep/res/values-fr/strings.xml index 5394f495e9..01dcff202d 100644 --- a/quickstep/res/values-fr/strings.xml +++ b/quickstep/res/values-fr/strings.xml @@ -33,5 +33,5 @@ "Encore %1$s aujourd\'hui" "Suggestions d\'applications" "Toutes les applications" - "Vos applications prévues" + "Applications prévues pour vous" diff --git a/quickstep/res/values-hi/strings.xml b/quickstep/res/values-hi/strings.xml index 0467af4b2d..387d509587 100644 --- a/quickstep/res/values-hi/strings.xml +++ b/quickstep/res/values-hi/strings.xml @@ -27,7 +27,7 @@ "बंद करें" "ऐप्लिकेशन इस्तेमाल की सेटिंग" "सभी ऐप्लिकेशन बंद करें" - "हाल ही में इस्तेमाल किए गए एेप्लिकेशन" + "हाल ही में इस्तेमाल किए गए ऐप्लिकेशन" "%1$s, %2$s" "<1 मिनट" "आज %1$s और चलेगा" diff --git a/quickstep/res/values-mr/strings.xml b/quickstep/res/values-mr/strings.xml index 1ca558a240..cccece749c 100644 --- a/quickstep/res/values-mr/strings.xml +++ b/quickstep/res/values-mr/strings.xml @@ -27,7 +27,7 @@ "बंद" "अ‍ॅप वापर सेटिंग्ज" "सर्व साफ करा" - "अलीकडील अॅप्स" + "अलीकडील अ‍ॅप्स" "%1$s, %2$s" "१मिहून कमी" "आज %1$sशिल्लक आहे" diff --git a/res/values-ca/strings.xml b/res/values-ca/strings.xml index c0859d3b4d..50f92daf28 100644 --- a/res/values-ca/strings.xml +++ b/res/values-ca/strings.xml @@ -88,7 +88,7 @@ "Punts de notificació" "Activats" "Desactivats" - "Cal que tingui accés a les notificacions" + "Cal accés a les notificacions" "Per veure els punts de notificació, activa les notificacions de l\'aplicació %1$s" "Canvia la configuració" "Mostra els punts de notificació" diff --git a/res/values-in/strings.xml b/res/values-in/strings.xml index 3054214b5e..211f735b49 100644 --- a/res/values-in/strings.xml +++ b/res/values-in/strings.xml @@ -30,10 +30,10 @@ "Layar utama" "Tindakan khusus" "Sentuh lama untuk memilih widget." - "Tap dua kalip & tahan untuk mengambil widget atau menggunakan tindakan khusus." + "Ketuk dua kali & tahan untuk mengambil widget atau menggunakan tindakan khusus." "%1$d × %2$d" "lebar %1$d x tinggi %2$d" - "Tap lama untuk menempatkan secara manual" + "Sentuh lama untuk menempatkan secara manual" "Tambahkan otomatis" "Telusuri aplikasi" "Memuat aplikasi…" @@ -41,8 +41,8 @@ "Telusuri aplikasi lainnya" "Aplikasi" "Notifikasi" - "Tap lama untuk memilih pintasan." - "Tap dua kali & tahan untuk memilih pintasan atau menggunakan tindakan khusus." + "Sentuh lama untuk memilih pintasan." + "Ketuk dua kali & tahan untuk memilih pintasan atau menggunakan tindakan khusus." "Tidak ada ruang lagi pada layar Utama ini." "Tidak ada ruang tersisa di baki Favorit" "Daftar aplikasi" @@ -73,8 +73,8 @@ "Layar utama %1$d dari %2$d" "Halaman layar utama baru" "Folder dibuka, %1$d x %2$d" - "Tap untuk menutup folder" - "Tap untuk menyimpan ganti nama" + "Ketuk untuk menutup folder" + "Ketuk untuk menyimpan ganti nama" "Folder ditutup" "Folder diganti namanya menjadi %1$s" "Folder: %1$s" diff --git a/res/values-mr/strings.xml b/res/values-mr/strings.xml index 19c06976b0..49e38982cd 100644 --- a/res/values-mr/strings.xml +++ b/res/values-mr/strings.xml @@ -35,18 +35,18 @@ "%1$d रूंद बाय %2$d उंच" "स्वतः ठेवण्यासाठी स्पर्श करा आणि धरून ठेवा" "आपोआप जोडा" - "अॅप्स शोधा" - "अॅप्स लोड करत आहे…" - "\"%1$s\" शी जुळणारे कोणतेही अॅप्स आढळले नाहीत" - "अधिक अॅप्स शोधा" + "अ‍ॅप्स शोधा" + "अ‍ॅप्स लोड करत आहे…" + "\"%1$s\" शी जुळणारे कोणतेही अ‍ॅप्स आढळले नाहीत" + "अधिक अ‍ॅप्स शोधा" "ॲप" "सूचना" "शॉर्टकट निवडण्यासाठी स्पर्श करा आणि धरून ठेवा." "शॉर्टकट निवडण्यासाठी किंवा कस्टम क्रिया वापरण्यासाठी दोनदा टॅप करा आणि धरून ठेवा." "या मुख्य स्क्रीनवर आणखी जागा नाही." "आवडीच्या ट्रे मध्ये आणखी जागा नाही" - "अॅप्स सूची" - "वैयक्तिक अॅप्स सूची" + "अ‍ॅप्स सूची" + "वैयक्तिक अ‍ॅप्स सूची" "कामाच्या ठिकाणी वापरली जाणाऱ्या अॅप्सची सूची" "होम" "काढा" @@ -136,7 +136,7 @@ "कामाची अ‍ॅप्स येथे मिळवा" "प्रत्येक कार्य अ‍ॅपला एक बॅज असतो आणि तो तुमच्या संस्थेकडून सुरक्षित ठेवला जातो. अधिक सहज अ‍ॅक्सेससाठी अ‍ॅप्स तुमच्या होम स्क्रीनवर हलवा." "तुमच्या संस्थेकडून व्यवस्थापित" - "सूचना आणि अॅप्स बंद आहेत" + "सूचना आणि अ‍ॅप्स बंद आहेत" "बंद करा" "बंद केले" "हे करता आले नाही: %1$s" diff --git a/res/values-ru/strings.xml b/res/values-ru/strings.xml index 34e267da9b..23b00d0936 100644 --- a/res/values-ru/strings.xml +++ b/res/values-ru/strings.xml @@ -90,7 +90,7 @@ "Значки уведомлений" "Включены" "Отключены" - "Нет доступа к уведомлениям" + "Нужен доступ к уведомлениям" "Чтобы показывать значки уведомлений, включите уведомления в приложении \"%1$s\"" "Изменить настройки" "Показывать значки уведомлений" From 22065f290cd6d52a7d72e165759bf8b3b536e17c Mon Sep 17 00:00:00 2001 From: Bill Yi Date: Mon, 15 Jul 2019 15:37:48 -0700 Subject: [PATCH 040/108] Import translations. DO NOT MERGE Auto-generated-cl: translation import Bug: 64712476 Change-Id: I249348f471abce9332ca65e07ebb9bde8c5b1d7b --- quickstep/res/values-fr/strings.xml | 2 +- quickstep/res/values-hi/strings.xml | 2 +- quickstep/res/values-mr/strings.xml | 2 +- res/values-ca/strings.xml | 2 +- res/values-in/strings.xml | 12 ++++++------ res/values-mr/strings.xml | 14 +++++++------- res/values-ru/strings.xml | 2 +- 7 files changed, 18 insertions(+), 18 deletions(-) diff --git a/quickstep/res/values-fr/strings.xml b/quickstep/res/values-fr/strings.xml index 5394f495e9..01dcff202d 100644 --- a/quickstep/res/values-fr/strings.xml +++ b/quickstep/res/values-fr/strings.xml @@ -33,5 +33,5 @@ "Encore %1$s aujourd\'hui" "Suggestions d\'applications" "Toutes les applications" - "Vos applications prévues" + "Applications prévues pour vous" diff --git a/quickstep/res/values-hi/strings.xml b/quickstep/res/values-hi/strings.xml index 0467af4b2d..387d509587 100644 --- a/quickstep/res/values-hi/strings.xml +++ b/quickstep/res/values-hi/strings.xml @@ -27,7 +27,7 @@ "बंद करें" "ऐप्लिकेशन इस्तेमाल की सेटिंग" "सभी ऐप्लिकेशन बंद करें" - "हाल ही में इस्तेमाल किए गए एेप्लिकेशन" + "हाल ही में इस्तेमाल किए गए ऐप्लिकेशन" "%1$s, %2$s" "<1 मिनट" "आज %1$s और चलेगा" diff --git a/quickstep/res/values-mr/strings.xml b/quickstep/res/values-mr/strings.xml index 1ca558a240..cccece749c 100644 --- a/quickstep/res/values-mr/strings.xml +++ b/quickstep/res/values-mr/strings.xml @@ -27,7 +27,7 @@ "बंद" "अ‍ॅप वापर सेटिंग्ज" "सर्व साफ करा" - "अलीकडील अॅप्स" + "अलीकडील अ‍ॅप्स" "%1$s, %2$s" "१मिहून कमी" "आज %1$sशिल्लक आहे" diff --git a/res/values-ca/strings.xml b/res/values-ca/strings.xml index c0859d3b4d..50f92daf28 100644 --- a/res/values-ca/strings.xml +++ b/res/values-ca/strings.xml @@ -88,7 +88,7 @@ "Punts de notificació" "Activats" "Desactivats" - "Cal que tingui accés a les notificacions" + "Cal accés a les notificacions" "Per veure els punts de notificació, activa les notificacions de l\'aplicació %1$s" "Canvia la configuració" "Mostra els punts de notificació" diff --git a/res/values-in/strings.xml b/res/values-in/strings.xml index 3054214b5e..211f735b49 100644 --- a/res/values-in/strings.xml +++ b/res/values-in/strings.xml @@ -30,10 +30,10 @@ "Layar utama" "Tindakan khusus" "Sentuh lama untuk memilih widget." - "Tap dua kalip & tahan untuk mengambil widget atau menggunakan tindakan khusus." + "Ketuk dua kali & tahan untuk mengambil widget atau menggunakan tindakan khusus." "%1$d × %2$d" "lebar %1$d x tinggi %2$d" - "Tap lama untuk menempatkan secara manual" + "Sentuh lama untuk menempatkan secara manual" "Tambahkan otomatis" "Telusuri aplikasi" "Memuat aplikasi…" @@ -41,8 +41,8 @@ "Telusuri aplikasi lainnya" "Aplikasi" "Notifikasi" - "Tap lama untuk memilih pintasan." - "Tap dua kali & tahan untuk memilih pintasan atau menggunakan tindakan khusus." + "Sentuh lama untuk memilih pintasan." + "Ketuk dua kali & tahan untuk memilih pintasan atau menggunakan tindakan khusus." "Tidak ada ruang lagi pada layar Utama ini." "Tidak ada ruang tersisa di baki Favorit" "Daftar aplikasi" @@ -73,8 +73,8 @@ "Layar utama %1$d dari %2$d" "Halaman layar utama baru" "Folder dibuka, %1$d x %2$d" - "Tap untuk menutup folder" - "Tap untuk menyimpan ganti nama" + "Ketuk untuk menutup folder" + "Ketuk untuk menyimpan ganti nama" "Folder ditutup" "Folder diganti namanya menjadi %1$s" "Folder: %1$s" diff --git a/res/values-mr/strings.xml b/res/values-mr/strings.xml index 19c06976b0..49e38982cd 100644 --- a/res/values-mr/strings.xml +++ b/res/values-mr/strings.xml @@ -35,18 +35,18 @@ "%1$d रूंद बाय %2$d उंच" "स्वतः ठेवण्यासाठी स्पर्श करा आणि धरून ठेवा" "आपोआप जोडा" - "अॅप्स शोधा" - "अॅप्स लोड करत आहे…" - "\"%1$s\" शी जुळणारे कोणतेही अॅप्स आढळले नाहीत" - "अधिक अॅप्स शोधा" + "अ‍ॅप्स शोधा" + "अ‍ॅप्स लोड करत आहे…" + "\"%1$s\" शी जुळणारे कोणतेही अ‍ॅप्स आढळले नाहीत" + "अधिक अ‍ॅप्स शोधा" "ॲप" "सूचना" "शॉर्टकट निवडण्यासाठी स्पर्श करा आणि धरून ठेवा." "शॉर्टकट निवडण्यासाठी किंवा कस्टम क्रिया वापरण्यासाठी दोनदा टॅप करा आणि धरून ठेवा." "या मुख्य स्क्रीनवर आणखी जागा नाही." "आवडीच्या ट्रे मध्ये आणखी जागा नाही" - "अॅप्स सूची" - "वैयक्तिक अॅप्स सूची" + "अ‍ॅप्स सूची" + "वैयक्तिक अ‍ॅप्स सूची" "कामाच्या ठिकाणी वापरली जाणाऱ्या अॅप्सची सूची" "होम" "काढा" @@ -136,7 +136,7 @@ "कामाची अ‍ॅप्स येथे मिळवा" "प्रत्येक कार्य अ‍ॅपला एक बॅज असतो आणि तो तुमच्या संस्थेकडून सुरक्षित ठेवला जातो. अधिक सहज अ‍ॅक्सेससाठी अ‍ॅप्स तुमच्या होम स्क्रीनवर हलवा." "तुमच्या संस्थेकडून व्यवस्थापित" - "सूचना आणि अॅप्स बंद आहेत" + "सूचना आणि अ‍ॅप्स बंद आहेत" "बंद करा" "बंद केले" "हे करता आले नाही: %1$s" diff --git a/res/values-ru/strings.xml b/res/values-ru/strings.xml index 34e267da9b..23b00d0936 100644 --- a/res/values-ru/strings.xml +++ b/res/values-ru/strings.xml @@ -90,7 +90,7 @@ "Значки уведомлений" "Включены" "Отключены" - "Нет доступа к уведомлениям" + "Нужен доступ к уведомлениям" "Чтобы показывать значки уведомлений, включите уведомления в приложении \"%1$s\"" "Изменить настройки" "Показывать значки уведомлений" From 7a4ed2f258939f8d558bd9264dfa6f1940883db2 Mon Sep 17 00:00:00 2001 From: vadimt Date: Mon, 15 Jul 2019 18:48:06 -0700 Subject: [PATCH 041/108] Removing tracing for fixed bugs Bug: 133009122 Bug: 133765434 Bug: 134532571 Change-Id: I37aa1851a1bc0874c0b9acf561bde28966e9b523 --- .../LauncherActivityControllerHelper.java | 3 --- .../WindowTransformSwipeHandler.java | 21 ------------------ .../com/android/quickstep/views/TaskView.java | 9 -------- src/com/android/launcher3/Launcher.java | 3 --- .../launcher3/LauncherStateManager.java | 8 ------- src/com/android/launcher3/Workspace.java | 8 ------- .../dragndrop/BaseItemDragListener.java | 3 --- .../launcher3/dragndrop/DragController.java | 22 ------------------- .../popup/PopupContainerWithArrow.java | 5 ----- .../launcher3/testing/TestProtocol.java | 3 --- .../launcher3/views/BaseDragLayer.java | 8 ------- .../com/android/launcher3/tapl/AllApps.java | 2 -- .../android/launcher3/tapl/Background.java | 2 -- .../android/launcher3/tapl/Launchable.java | 2 -- .../android/launcher3/tapl/OverviewTask.java | 2 -- .../com/android/launcher3/tapl/Workspace.java | 4 ---- 16 files changed, 105 deletions(-) diff --git a/quickstep/recents_ui_overrides/src/com/android/quickstep/LauncherActivityControllerHelper.java b/quickstep/recents_ui_overrides/src/com/android/quickstep/LauncherActivityControllerHelper.java index b2a71a4882..894edd46c7 100644 --- a/quickstep/recents_ui_overrides/src/com/android/quickstep/LauncherActivityControllerHelper.java +++ b/quickstep/recents_ui_overrides/src/com/android/quickstep/LauncherActivityControllerHelper.java @@ -194,9 +194,6 @@ public final class LauncherActivityControllerHelper implements ActivityControlHe @Override public AnimationFactory prepareRecentsUI(Launcher activity, boolean activityVisible, boolean animateActivity, Consumer callback) { - if (TestProtocol.sDebugTracing) { - Log.d(TestProtocol.NO_OVERVIEW_EVENT_TAG, "prepareRecentsUI"); - } final LauncherState startState = activity.getStateManager().getState(); LauncherState resetState = startState; diff --git a/quickstep/recents_ui_overrides/src/com/android/quickstep/WindowTransformSwipeHandler.java b/quickstep/recents_ui_overrides/src/com/android/quickstep/WindowTransformSwipeHandler.java index c60b28de3b..6f30a5651c 100644 --- a/quickstep/recents_ui_overrides/src/com/android/quickstep/WindowTransformSwipeHandler.java +++ b/quickstep/recents_ui_overrides/src/com/android/quickstep/WindowTransformSwipeHandler.java @@ -439,32 +439,17 @@ public class WindowTransformSwipeHandler extends } private void onLauncherStart(final T activity) { - if (TestProtocol.sDebugTracing) { - Log.d(TestProtocol.NO_OVERVIEW_EVENT_TAG, "onLauncherStart"); - } if (mActivity != activity) { return; } - if (TestProtocol.sDebugTracing) { - Log.d(TestProtocol.NO_OVERVIEW_EVENT_TAG, "onLauncherStart 1"); - } if (mStateCallback.hasStates(STATE_HANDLER_INVALIDATED)) { return; } - if (TestProtocol.sDebugTracing) { - Log.d(TestProtocol.NO_OVERVIEW_EVENT_TAG, "onLauncherStart 2"); - } // If we've already ended the gesture and are going home, don't prepare recents UI, // as that will set the state as BACKGROUND_APP, overriding the animation to NORMAL. if (mGestureEndTarget != HOME) { - if (TestProtocol.sDebugTracing) { - Log.d(TestProtocol.NO_OVERVIEW_EVENT_TAG, "onLauncherStart 3"); - } Runnable initAnimFactory = () -> { - if (TestProtocol.sDebugTracing) { - Log.d(TestProtocol.NO_OVERVIEW_EVENT_TAG, "onLauncherStart 4"); - } mAnimationFactory = mActivityControlHelper.prepareRecentsUI(mActivity, mWasLauncherAlreadyVisible, true, this::onAnimatorPlaybackControllerCreated); @@ -474,14 +459,8 @@ public class WindowTransformSwipeHandler extends // Launcher is visible, but might be about to stop. Thus, if we prepare recents // now, it might get overridden by moveToRestState() in onStop(). To avoid this, // wait until the next gesture (and possibly launcher) starts. - if (TestProtocol.sDebugTracing) { - Log.d(TestProtocol.NO_OVERVIEW_EVENT_TAG, "onLauncherStart 5"); - } mStateCallback.addCallback(STATE_GESTURE_STARTED, initAnimFactory); } else { - if (TestProtocol.sDebugTracing) { - Log.d(TestProtocol.NO_OVERVIEW_EVENT_TAG, "onLauncherStart 6"); - } initAnimFactory.run(); } } diff --git a/quickstep/recents_ui_overrides/src/com/android/quickstep/views/TaskView.java b/quickstep/recents_ui_overrides/src/com/android/quickstep/views/TaskView.java index b26fdce92f..2211eb4dd7 100644 --- a/quickstep/recents_ui_overrides/src/com/android/quickstep/views/TaskView.java +++ b/quickstep/recents_ui_overrides/src/com/android/quickstep/views/TaskView.java @@ -192,9 +192,6 @@ public class TaskView extends FrameLayout implements PageCallbacks, Reusable { super(context, attrs, defStyleAttr); mActivity = BaseDraggingActivity.fromContext(context); setOnClickListener((view) -> { - if (com.android.launcher3.testing.TestProtocol.sDebugTracing) { - android.util.Log.d(TestProtocol.NO_START_TASK_TAG, "TaskView onClick"); - } if (getTask() == null) { return; } @@ -291,9 +288,6 @@ public class TaskView extends FrameLayout implements PageCallbacks, Reusable { public void launchTask(boolean animate, boolean freezeTaskList, Consumer resultCallback, Handler resultCallbackHandler) { - if (com.android.launcher3.testing.TestProtocol.sDebugTracing) { - android.util.Log.d(TestProtocol.NO_START_TASK_TAG, "launchTask"); - } if (ENABLE_QUICKSTEP_LIVE_TILE.get()) { if (isRunningTask()) { getRecentsView().finishRecentsAnimation(false /* toRecents */, @@ -308,9 +302,6 @@ public class TaskView extends FrameLayout implements PageCallbacks, Reusable { private void launchTaskInternal(boolean animate, boolean freezeTaskList, Consumer resultCallback, Handler resultCallbackHandler) { - if (com.android.launcher3.testing.TestProtocol.sDebugTracing) { - android.util.Log.d(TestProtocol.NO_START_TASK_TAG, "launchTaskInternal"); - } if (mTask != null) { final ActivityOptions opts; if (animate) { diff --git a/src/com/android/launcher3/Launcher.java b/src/com/android/launcher3/Launcher.java index 9229832687..03fdc971dd 100644 --- a/src/com/android/launcher3/Launcher.java +++ b/src/com/android/launcher3/Launcher.java @@ -890,9 +890,6 @@ public class Launcher extends BaseDraggingActivity implements LauncherExterns, @Override protected void onStart() { - if (TestProtocol.sDebugTracing) { - Log.d(TestProtocol.NO_OVERVIEW_EVENT_TAG, "Launcher.onStart"); - } RaceConditionTracker.onEvent(ON_START_EVT, ENTER); super.onStart(); if (mLauncherCallbacks != null) { diff --git a/src/com/android/launcher3/LauncherStateManager.java b/src/com/android/launcher3/LauncherStateManager.java index ccd6efaf55..d66e5813b9 100644 --- a/src/com/android/launcher3/LauncherStateManager.java +++ b/src/com/android/launcher3/LauncherStateManager.java @@ -403,10 +403,6 @@ public class LauncherStateManager { } private void onStateTransitionStart(LauncherState state) { - if (TestProtocol.sDebugTracing) { - android.util.Log.d(TestProtocol.NO_DRAG_TAG, - "onStateTransitionStart"); - } if (mState != state) { mState.onStateDisabled(mLauncher); } @@ -575,10 +571,6 @@ public class LauncherStateManager { private final AnimatorSet mAnim; public StartAnimRunnable(AnimatorSet anim) { - if (TestProtocol.sDebugTracing) { - android.util.Log.d(TestProtocol.NO_DRAG_TAG, - "StartAnimRunnable"); - } mAnim = anim; } diff --git a/src/com/android/launcher3/Workspace.java b/src/com/android/launcher3/Workspace.java index 9f846bbc4d..8cd0822991 100644 --- a/src/com/android/launcher3/Workspace.java +++ b/src/com/android/launcher3/Workspace.java @@ -370,10 +370,6 @@ public class Workspace extends PagedView @Override public void onDragStart(DropTarget.DragObject dragObject, DragOptions options) { - if (TestProtocol.sDebugTracing) { - android.util.Log.d(TestProtocol.NO_DRAG_TAG, - "onDragStart 1"); - } if (ENFORCE_DRAG_EVENT_ORDER) { enforceDragParity("onDragStart", 0, 0); } @@ -424,10 +420,6 @@ public class Workspace extends PagedView } // Always enter the spring loaded mode - if (TestProtocol.sDebugTracing) { - android.util.Log.d(TestProtocol.NO_DRAG_TAG, - "onDragStart 2"); - } mLauncher.getStateManager().goToState(SPRING_LOADED); } diff --git a/src/com/android/launcher3/dragndrop/BaseItemDragListener.java b/src/com/android/launcher3/dragndrop/BaseItemDragListener.java index c719c1c986..1b08723f63 100644 --- a/src/com/android/launcher3/dragndrop/BaseItemDragListener.java +++ b/src/com/android/launcher3/dragndrop/BaseItemDragListener.java @@ -137,9 +137,6 @@ public abstract class BaseItemDragListener extends InternalStateHandler implemen @Override public boolean shouldStartDrag(double distanceDragged) { - if (TestProtocol.sDebugTracing) { - Log.d(TestProtocol.NO_DRAG_TAG, "BIDL.shouldStartDrag"); - } // Stay in pre-drag mode, if workspace is locked. return !mLauncher.isWorkspaceLocked(); } diff --git a/src/com/android/launcher3/dragndrop/DragController.java b/src/com/android/launcher3/dragndrop/DragController.java index 72a1abb833..d32dd2eb98 100644 --- a/src/com/android/launcher3/dragndrop/DragController.java +++ b/src/com/android/launcher3/dragndrop/DragController.java @@ -474,10 +474,6 @@ public class DragController implements DragDriver.EventListener, TouchController } private void handleMoveEvent(int x, int y) { - if (TestProtocol.sDebugTracing) { - android.util.Log.d(TestProtocol.NO_DRAG_TAG, - "handleMoveEvent 1"); - } mDragObject.dragView.move(x, y); // Drop on someone? @@ -492,22 +488,8 @@ public class DragController implements DragDriver.EventListener, TouchController mLastTouch[0] = x; mLastTouch[1] = y; - if (TestProtocol.sDebugTracing) { - Log.d(TestProtocol.NO_DRAG_TAG, - "handleMoveEvent Conditions " + - mIsInPreDrag + ", " + - (mIsInPreDrag && mOptions.preDragCondition != null) + ", " + - (mIsInPreDrag && mOptions.preDragCondition != null - && mOptions.preDragCondition.shouldStartDrag( - mDistanceSinceScroll))); - } - if (mIsInPreDrag && mOptions.preDragCondition != null && mOptions.preDragCondition.shouldStartDrag(mDistanceSinceScroll)) { - if (TestProtocol.sDebugTracing) { - android.util.Log.d(TestProtocol.NO_DRAG_TAG, - "handleMoveEvent 2"); - } callOnDragStart(); } } @@ -545,10 +527,6 @@ public class DragController implements DragDriver.EventListener, TouchController * Call this from a drag source view. */ public boolean onControllerTouchEvent(MotionEvent ev) { - if (TestProtocol.sDebugTracing) { - android.util.Log.d(TestProtocol.NO_DRAG_TAG, - "onControllerTouchEvent"); - } if (mDragDriver == null || mOptions == null || mOptions.isAccessibleDrag) { return false; } diff --git a/src/com/android/launcher3/popup/PopupContainerWithArrow.java b/src/com/android/launcher3/popup/PopupContainerWithArrow.java index 9719a1892f..25d9f7976a 100644 --- a/src/com/android/launcher3/popup/PopupContainerWithArrow.java +++ b/src/com/android/launcher3/popup/PopupContainerWithArrow.java @@ -449,11 +449,6 @@ public class PopupContainerWithArrow extends ArrowPopup implements DragSource, @Override public boolean shouldStartDrag(double distanceDragged) { - if (TestProtocol.sDebugTracing) { - Log.d(TestProtocol.NO_DRAG_TAG, - "createPreDragCondition().shouldStartDrag " + distanceDragged + ", " - + mStartDragThreshold); - } return distanceDragged > mStartDragThreshold; } diff --git a/src/com/android/launcher3/testing/TestProtocol.java b/src/com/android/launcher3/testing/TestProtocol.java index e28eba8094..6bdc0ab462 100644 --- a/src/com/android/launcher3/testing/TestProtocol.java +++ b/src/com/android/launcher3/testing/TestProtocol.java @@ -74,7 +74,4 @@ public final class TestProtocol { public static boolean sDebugTracing = false; public static final String REQUEST_ENABLE_DEBUG_TRACING = "enable-debug-tracing"; public static final String REQUEST_DISABLE_DEBUG_TRACING = "disable-debug-tracing"; - public static final String NO_DRAG_TAG = "b/133009122"; - public static final String NO_START_TASK_TAG = "b/133765434"; - public static final String NO_OVERVIEW_EVENT_TAG = "b/134532571"; } diff --git a/src/com/android/launcher3/views/BaseDragLayer.java b/src/com/android/launcher3/views/BaseDragLayer.java index 8bf33bf05c..594a24630b 100644 --- a/src/com/android/launcher3/views/BaseDragLayer.java +++ b/src/com/android/launcher3/views/BaseDragLayer.java @@ -230,10 +230,6 @@ public abstract class BaseDragLayer @Override public boolean onTouchEvent(MotionEvent ev) { - if (TestProtocol.sDebugTracing) { - android.util.Log.d(TestProtocol.NO_DRAG_TAG, - "onTouchEvent " + ev); - } int action = ev.getAction(); if (action == ACTION_UP || action == ACTION_CANCEL) { if (mTouchCompleteListener != null) { @@ -243,10 +239,6 @@ public abstract class BaseDragLayer } if (mActiveController != null) { - if (TestProtocol.sDebugTracing) { - android.util.Log.d(TestProtocol.NO_DRAG_TAG, - "onTouchEvent 1"); - } return mActiveController.onControllerTouchEvent(ev); } else { // In case no child view handled the touch event, we may not get onIntercept anymore diff --git a/tests/tapl/com/android/launcher3/tapl/AllApps.java b/tests/tapl/com/android/launcher3/tapl/AllApps.java index 0ac5e9f887..9ff354a7eb 100644 --- a/tests/tapl/com/android/launcher3/tapl/AllApps.java +++ b/tests/tapl/com/android/launcher3/tapl/AllApps.java @@ -181,7 +181,6 @@ public class AllApps extends LauncherInstrumentation.VisibleContainer { * Flings backward (up) and waits the fling's end. */ public void flingBackward() { - mLauncher.getTestInfo(TestProtocol.REQUEST_ENABLE_DEBUG_TRACING); try (LauncherInstrumentation.Closable c = mLauncher.addContextLayer("want to fling backward in all apps")) { final UiObject2 allAppsContainer = verifyActiveContainer(); @@ -190,7 +189,6 @@ public class AllApps extends LauncherInstrumentation.VisibleContainer { allAppsContainer, Direction.UP, 1, new Rect(0, mHeight / 2, 0, 0), 10); verifyActiveContainer(); } - mLauncher.getTestInfo(TestProtocol.REQUEST_DISABLE_DEBUG_TRACING); } /** diff --git a/tests/tapl/com/android/launcher3/tapl/Background.java b/tests/tapl/com/android/launcher3/tapl/Background.java index c9eaf276d7..060bf30202 100644 --- a/tests/tapl/com/android/launcher3/tapl/Background.java +++ b/tests/tapl/com/android/launcher3/tapl/Background.java @@ -59,7 +59,6 @@ public class Background extends LauncherInstrumentation.VisibleContainer { } protected void goToOverviewUnchecked(int expectedState) { - mLauncher.getTestInfo(TestProtocol.REQUEST_ENABLE_DEBUG_TRACING); switch (mLauncher.getNavigationModel()) { case ZERO_BUTTON: { final int centerX = mLauncher.getDevice().getDisplayWidth() / 2; @@ -112,7 +111,6 @@ public class Background extends LauncherInstrumentation.VisibleContainer { mLauncher.waitForSystemUiObject("recent_apps").click(); break; } - mLauncher.getTestInfo(TestProtocol.REQUEST_DISABLE_DEBUG_TRACING); } protected String getSwipeHeightRequestName() { diff --git a/tests/tapl/com/android/launcher3/tapl/Launchable.java b/tests/tapl/com/android/launcher3/tapl/Launchable.java index 04b8019450..82af7b03ac 100644 --- a/tests/tapl/com/android/launcher3/tapl/Launchable.java +++ b/tests/tapl/com/android/launcher3/tapl/Launchable.java @@ -53,11 +53,9 @@ abstract class Launchable { private Background launch(BySelector selector) { LauncherInstrumentation.log("Launchable.launch before click " + mObject.getVisibleCenter() + " in " + mObject.getVisibleBounds()); - mLauncher.getTestInfo(TestProtocol.REQUEST_ENABLE_DEBUG_TRACING); mLauncher.assertTrue( "Launching an app didn't open a new window: " + mObject.getText(), mObject.clickAndWait(Until.newWindow(), WAIT_TIME_MS)); - mLauncher.getTestInfo(TestProtocol.REQUEST_DISABLE_DEBUG_TRACING); mLauncher.assertTrue( "App didn't start: " + selector, mLauncher.getDevice().wait(Until.hasObject(selector), diff --git a/tests/tapl/com/android/launcher3/tapl/OverviewTask.java b/tests/tapl/com/android/launcher3/tapl/OverviewTask.java index 641c413538..6e3332260b 100644 --- a/tests/tapl/com/android/launcher3/tapl/OverviewTask.java +++ b/tests/tapl/com/android/launcher3/tapl/OverviewTask.java @@ -64,14 +64,12 @@ public final class OverviewTask { */ public Background open() { verifyActiveContainer(); - mLauncher.getTestInfo(TestProtocol.REQUEST_ENABLE_DEBUG_TRACING); try (LauncherInstrumentation.Closable c = mLauncher.addContextLayer( "clicking an overview task")) { mLauncher.assertTrue("Launching task didn't open a new window: " + mTask.getParent().getContentDescription(), mTask.clickAndWait(Until.newWindow(), WAIT_TIME_MS)); } - mLauncher.getTestInfo(TestProtocol.REQUEST_DISABLE_DEBUG_TRACING); return new Background(mLauncher); } } diff --git a/tests/tapl/com/android/launcher3/tapl/Workspace.java b/tests/tapl/com/android/launcher3/tapl/Workspace.java index b01b6f363c..07f8b64433 100644 --- a/tests/tapl/com/android/launcher3/tapl/Workspace.java +++ b/tests/tapl/com/android/launcher3/tapl/Workspace.java @@ -67,7 +67,6 @@ public final class Workspace extends Home { "switchToAllApps: swipeHeight = " + swipeHeight + ", slop = " + mLauncher.getTouchSlop()); - mLauncher.getTestInfo(TestProtocol.REQUEST_ENABLE_DEBUG_TRACING); mLauncher.swipeToState( start.x, start.y, @@ -75,7 +74,6 @@ public final class Workspace extends Home { start.y - swipeHeight - mLauncher.getTouchSlop(), 60, ALL_APPS_STATE_ORDINAL); - mLauncher.getTestInfo(TestProtocol.REQUEST_DISABLE_DEBUG_TRACING); try (LauncherInstrumentation.Closable c1 = mLauncher.addContextLayer( "swiped to all apps")) { @@ -157,7 +155,6 @@ public final class Workspace extends Home { static void dragIconToWorkspace( LauncherInstrumentation launcher, Launchable launchable, Point dest, String longPressIndicator) { - launcher.getTestInfo(TestProtocol.REQUEST_ENABLE_DEBUG_TRACING); LauncherInstrumentation.log("dragIconToWorkspace: begin"); final Point launchableCenter = launchable.getObject().getVisibleCenter(); final long downTime = SystemClock.uptimeMillis(); @@ -172,7 +169,6 @@ public final class Workspace extends Home { downTime, SystemClock.uptimeMillis(), MotionEvent.ACTION_UP, dest); LauncherInstrumentation.log("dragIconToWorkspace: end"); launcher.waitUntilGone("drop_target_bar"); - launcher.getTestInfo(TestProtocol.REQUEST_DISABLE_DEBUG_TRACING); } /** From 2e4b665933b5c67d062b3c09787a8d42c8586d17 Mon Sep 17 00:00:00 2001 From: Sunny Goyal Date: Thu, 11 Jul 2019 11:55:22 -0700 Subject: [PATCH 042/108] Adding horizontal swipe support for 3p launcher Bug: 137197916 Change-Id: I0fb5db791b3471d651db43f0e8c30b8d5baf9f27 --- .../android/quickstep/BaseSwipeUpHandler.java | 157 ++++++++- .../quickstep/TouchInteractionService.java | 20 +- .../WindowTransformSwipeHandler.java | 135 ++------ .../fallback/FallbackRecentsView.java | 12 + .../FallbackNoButtonInputConsumer.java | 304 ++++++++++++++---- .../OtherActivityInputConsumer.java | 27 +- .../android/quickstep/views/RecentsView.java | 3 +- 7 files changed, 460 insertions(+), 198 deletions(-) diff --git a/quickstep/recents_ui_overrides/src/com/android/quickstep/BaseSwipeUpHandler.java b/quickstep/recents_ui_overrides/src/com/android/quickstep/BaseSwipeUpHandler.java index d34b604a76..3032ca3079 100644 --- a/quickstep/recents_ui_overrides/src/com/android/quickstep/BaseSwipeUpHandler.java +++ b/quickstep/recents_ui_overrides/src/com/android/quickstep/BaseSwipeUpHandler.java @@ -18,26 +18,41 @@ package com.android.quickstep; import static android.os.VibrationEffect.EFFECT_CLICK; import static android.os.VibrationEffect.createPredefined; +import static com.android.launcher3.Utilities.postAsyncCallback; import static com.android.launcher3.anim.Interpolators.DEACCEL; +import static com.android.launcher3.config.FeatureFlags.ENABLE_QUICKSTEP_LIVE_TILE; import static com.android.quickstep.TouchInteractionService.BACKGROUND_EXECUTOR; +import static com.android.quickstep.TouchInteractionService.MAIN_THREAD_EXECUTOR; +import static com.android.quickstep.TouchInteractionService.TOUCH_INTERACTION_LOG; import android.annotation.TargetApi; import android.app.ActivityManager.RunningTaskInfo; import android.content.Context; +import android.content.Intent; import android.graphics.PointF; import android.os.Build; +import android.os.Handler; +import android.os.Looper; import android.os.VibrationEffect; import android.os.Vibrator; import android.provider.Settings; import android.view.MotionEvent; import android.view.animation.Interpolator; +import com.android.launcher3.BaseDraggingActivity; +import com.android.launcher3.DeviceProfile; +import com.android.launcher3.R; import com.android.launcher3.Utilities; import com.android.launcher3.graphics.RotationMode; +import com.android.quickstep.ActivityControlHelper.ActivityInitListener; +import com.android.quickstep.inputconsumers.InputConsumer; import com.android.quickstep.util.ClipAnimationHelper; import com.android.quickstep.util.ClipAnimationHelper.TransformParams; import com.android.quickstep.util.SwipeAnimationTargetSet.SwipeAnimationListener; import com.android.quickstep.views.RecentsView; +import com.android.quickstep.views.TaskView; +import com.android.systemui.shared.system.InputConsumerController; +import com.android.systemui.shared.system.SyncRtSurfaceTransactionApplierCompat; import java.util.function.Consumer; @@ -47,7 +62,10 @@ import androidx.annotation.UiThread; * Base class for swipe up handler with some utility methods */ @TargetApi(Build.VERSION_CODES.Q) -public abstract class BaseSwipeUpHandler implements SwipeAnimationListener { +public abstract class BaseSwipeUpHandler + implements SwipeAnimationListener { + + private static final String TAG = "BaseSwipeUpHandler"; // Start resisting when swiping past this factor of mTransitionDragLength. private static final float DRAG_LENGTH_FACTOR_START_PULLBACK = 1.4f; @@ -61,6 +79,9 @@ public abstract class BaseSwipeUpHandler implements SwipeAnimationListener { protected float mDragLengthFactor = 1; protected final Context mContext; + protected final OverviewComponentObserver mOverviewComponentObserver; + protected final ActivityControlHelper mActivityControlHelper; + protected final RecentsModel mRecentsModel; protected final ClipAnimationHelper mClipAnimationHelper; protected final TransformParams mTransformParams = new TransformParams(); @@ -73,18 +94,48 @@ public abstract class BaseSwipeUpHandler implements SwipeAnimationListener { // visible. protected final AnimatedFloat mCurrentShift = new AnimatedFloat(this::updateFinalShift); + protected final ActivityInitListener mActivityInitListener; + protected final RecentsAnimationWrapper mRecentsAnimationWrapper; + + protected T mActivity; protected RecentsView mRecentsView; + protected DeviceProfile mDp; + private final int mPageSpacing; protected Runnable mGestureEndCallback; - protected BaseSwipeUpHandler(Context context) { - mContext = context; - mClipAnimationHelper = new ClipAnimationHelper(context); + protected final Handler mMainThreadHandler = MAIN_THREAD_EXECUTOR.getHandler(); + protected MultiStateCallback mStateCallback; + protected boolean mCanceled; + protected int mFinishingRecentsAnimationForNewTaskId = -1; + + protected BaseSwipeUpHandler(Context context, + OverviewComponentObserver overviewComponentObserver, + RecentsModel recentsModel, InputConsumerController inputConsumer) { + mContext = context; + mOverviewComponentObserver = overviewComponentObserver; + mActivityControlHelper = overviewComponentObserver.getActivityControlHelper(); + mRecentsModel = recentsModel; + mActivityInitListener = + mActivityControlHelper.createActivityInitListener(this::onActivityInit); + mRecentsAnimationWrapper = new RecentsAnimationWrapper(inputConsumer, + this::createNewInputProxyHandler); + + mClipAnimationHelper = new ClipAnimationHelper(context); + mPageSpacing = context.getResources().getDimensionPixelSize(R.dimen.recents_page_spacing); mVibrator = context.getSystemService(Vibrator.class); } - public void performHapticFeedback() { + protected void setStateOnUiThread(int stateFlag) { + if (Looper.myLooper() == mMainThreadHandler.getLooper()) { + mStateCallback.setState(stateFlag); + } else { + postAsyncCallback(mMainThreadHandler, () -> mStateCallback.setState(stateFlag)); + } + } + + protected void performHapticFeedback() { if (!mVibrator.hasVibrator()) { return; } @@ -130,12 +181,76 @@ public abstract class BaseSwipeUpHandler implements SwipeAnimationListener { mGestureEndCallback = gestureEndCallback; } + public abstract Intent getLaunchIntent(); + + protected void linkRecentsViewScroll() { + SyncRtSurfaceTransactionApplierCompat.create(mRecentsView, applier -> { + mTransformParams.setSyncTransactionApplier(applier); + mRecentsAnimationWrapper.runOnInit(() -> + mRecentsAnimationWrapper.targetSet.addDependentTransactionApplier(applier)); + }); + + mRecentsView.setOnScrollChangeListener((v, scrollX, scrollY, oldScrollX, oldScrollY) -> { + if (moveWindowWithRecentsScroll()) { + updateFinalShift(); + } + }); + mRecentsView.setRecentsAnimationWrapper(mRecentsAnimationWrapper); + mRecentsView.setClipAnimationHelper(mClipAnimationHelper); + } + + protected void startNewTask(int successStateFlag, Consumer resultCallback) { + // Launch the task user scrolled to (mRecentsView.getNextPage()). + if (ENABLE_QUICKSTEP_LIVE_TILE.get()) { + // We finish recents animation inside launchTask() when live tile is enabled. + mRecentsView.getTaskViewAt(mRecentsView.getNextPage()).launchTask(false /* animate */, + true /* freezeTaskList */); + } else { + int taskId = mRecentsView.getTaskViewAt(mRecentsView.getNextPage()).getTask().key.id; + mFinishingRecentsAnimationForNewTaskId = taskId; + mRecentsAnimationWrapper.finish(true /* toRecents */, () -> { + if (!mCanceled) { + TaskView nextTask = mRecentsView.getTaskView(taskId); + if (nextTask != null) { + nextTask.launchTask(false /* animate */, true /* freezeTaskList */, + success -> { + resultCallback.accept(success); + if (!success) { + mActivityControlHelper.onLaunchTaskFailed(mActivity); + nextTask.notifyTaskLaunchFailed(TAG); + } else { + mActivityControlHelper.onLaunchTaskSuccess(mActivity); + } + }, mMainThreadHandler); + } + setStateOnUiThread(successStateFlag); + } + mCanceled = false; + mFinishingRecentsAnimationForNewTaskId = -1; + }); + } + TOUCH_INTERACTION_LOG.addLog("finishRecentsAnimation", true); + } + + /** + * Return true if the window should be translated horizontally if the recents view scrolls + */ + protected abstract boolean moveWindowWithRecentsScroll(); + + protected abstract boolean onActivityInit(final T activity, Boolean alreadyOnHome); + + /** + * Called to create a input proxy for the running task + */ + @UiThread + protected abstract InputConsumer createNewInputProxyHandler(); + /** * Called when the value of {@link #mCurrentShift} changes */ + @UiThread public abstract void updateFinalShift(); - /** * Called when motion pause is detected */ @@ -150,15 +265,39 @@ public abstract class BaseSwipeUpHandler implements SwipeAnimationListener { @UiThread public abstract void onGestureEnded(float endVelocity, PointF velocity, PointF downPos); - public void onConsumerAboutToBeSwitched(SwipeSharedState sharedState) { } + public abstract void onConsumerAboutToBeSwitched(SwipeSharedState sharedState); public void setIsLikelyToStartNewTask(boolean isLikelyToStartNewTask) { } - public void initWhenReady() { } + public void initWhenReady() { + // Preload the plan + mRecentsModel.getTasks(null); + + mActivityInitListener.register(); + } + + /** + * Applies the transform on the recents animation without any additional null checks + */ + protected void applyTransformUnchecked() { + float shift = mCurrentShift.value; + float offsetX = mRecentsView == null ? 0 : mRecentsView.getScrollOffset(); + float offsetScale = getTaskCurveScaleForOffsetX(offsetX, + mClipAnimationHelper.getTargetRect().width()); + mTransformParams.setProgress(shift).setOffsetX(offsetX).setOffsetScale(offsetScale); + mClipAnimationHelper.applyTransform(mRecentsAnimationWrapper.targetSet, + mTransformParams); + } + + private float getTaskCurveScaleForOffsetX(float offsetX, float taskWidth) { + float distanceToReachEdge = mDp.widthPx / 2 + taskWidth / 2 + mPageSpacing; + float interpolation = Math.min(1, offsetX / distanceToReachEdge); + return TaskView.getCurveScaleForInterpolation(interpolation); + } public interface Factory { BaseSwipeUpHandler newHandler(RunningTaskInfo runningTask, - long touchTimeMs, boolean continuingLastGesture); + long touchTimeMs, boolean continuingLastGesture, boolean isLikelyToStartNewTask); } } diff --git a/quickstep/recents_ui_overrides/src/com/android/quickstep/TouchInteractionService.java b/quickstep/recents_ui_overrides/src/com/android/quickstep/TouchInteractionService.java index fd4b3940a5..4bc4c761b0 100644 --- a/quickstep/recents_ui_overrides/src/com/android/quickstep/TouchInteractionService.java +++ b/quickstep/recents_ui_overrides/src/com/android/quickstep/TouchInteractionService.java @@ -649,20 +649,17 @@ public class TouchInteractionService extends Service implements final boolean shouldDefer; final BaseSwipeUpHandler.Factory factory; - final Intent homeIntent; if (mMode == Mode.NO_BUTTON && !mOverviewComponentObserver.isHomeAndOverviewSame()) { - shouldDefer = true; + shouldDefer = !sSwipeSharedState.recentsAnimationFinishInterrupted; factory = mFallbackNoButtonFactory; - homeIntent = mOverviewComponentObserver.getHomeIntent(); } else { shouldDefer = mOverviewComponentObserver.getActivityControlHelper() .deferStartingActivity(mActiveNavBarRegion, event); factory = mWindowTreansformFactory; - homeIntent = mOverviewComponentObserver.getOverviewIntent(); } - return new OtherActivityInputConsumer(this, runningTaskInfo, homeIntent, + return new OtherActivityInputConsumer(this, runningTaskInfo, shouldDefer, mOverviewCallbacks, this::onConsumerInactive, sSwipeSharedState, mInputMonitorCompat, mSwipeTouchRegion, disableHorizontalSwipe(event), factory); @@ -809,16 +806,15 @@ public class TouchInteractionService extends Service implements } private BaseSwipeUpHandler createWindowTransformSwipeHandler(RunningTaskInfo runningTask, - long touchTimeMs, boolean continuingLastGesture) { - return new WindowTransformSwipeHandler( - runningTask, this, touchTimeMs, - mOverviewComponentObserver.getActivityControlHelper(), - continuingLastGesture, mInputConsumer, mRecentsModel); + long touchTimeMs, boolean continuingLastGesture, boolean isLikelyToStartNewTask) { + return new WindowTransformSwipeHandler(runningTask, this, touchTimeMs, + mOverviewComponentObserver, continuingLastGesture, mInputConsumer, mRecentsModel); } private BaseSwipeUpHandler createFallbackNoButtonSwipeHandler(RunningTaskInfo runningTask, - long touchTimeMs, boolean continuingLastGesture) { - return new FallbackNoButtonInputConsumer(this, mOverviewComponentObserver, runningTask); + long touchTimeMs, boolean continuingLastGesture, boolean isLikelyToStartNewTask) { + return new FallbackNoButtonInputConsumer(this, mOverviewComponentObserver, runningTask, + mRecentsModel, mInputConsumer, isLikelyToStartNewTask, continuingLastGesture); } public static void startRecentsActivityAsync(Intent intent, RecentsAnimationListener listener) { diff --git a/quickstep/recents_ui_overrides/src/com/android/quickstep/WindowTransformSwipeHandler.java b/quickstep/recents_ui_overrides/src/com/android/quickstep/WindowTransformSwipeHandler.java index c60b28de3b..184b8e131c 100644 --- a/quickstep/recents_ui_overrides/src/com/android/quickstep/WindowTransformSwipeHandler.java +++ b/quickstep/recents_ui_overrides/src/com/android/quickstep/WindowTransformSwipeHandler.java @@ -18,7 +18,6 @@ package com.android.quickstep; import static com.android.launcher3.BaseActivity.INVISIBLE_BY_STATE_HANDLER; import static com.android.launcher3.BaseActivity.STATE_HANDLER_INVISIBILITY_FLAGS; import static com.android.launcher3.Utilities.SINGLE_FRAME_MS; -import static com.android.launcher3.Utilities.postAsyncCallback; import static com.android.launcher3.anim.Interpolators.ACCEL_1_5; import static com.android.launcher3.anim.Interpolators.DEACCEL; import static com.android.launcher3.anim.Interpolators.LINEAR; @@ -32,7 +31,6 @@ import static com.android.launcher3.views.FloatingIconView.SHAPE_PROGRESS_DURATI import static com.android.quickstep.ActivityControlHelper.AnimationFactory.ShelfAnimState.HIDE; import static com.android.quickstep.ActivityControlHelper.AnimationFactory.ShelfAnimState.PEEK; import static com.android.quickstep.MultiStateCallback.DEBUG_STATES; -import static com.android.quickstep.TouchInteractionService.MAIN_THREAD_EXECUTOR; import static com.android.quickstep.TouchInteractionService.TOUCH_INTERACTION_LOG; import static com.android.quickstep.WindowTransformSwipeHandler.GestureEndTarget.HOME; import static com.android.quickstep.WindowTransformSwipeHandler.GestureEndTarget.LAST_TASK; @@ -48,14 +46,13 @@ import android.animation.ValueAnimator; import android.annotation.TargetApi; import android.app.ActivityManager.RunningTaskInfo; import android.content.Context; +import android.content.Intent; import android.graphics.Canvas; import android.graphics.Point; import android.graphics.PointF; import android.graphics.Rect; import android.graphics.RectF; import android.os.Build; -import android.os.Handler; -import android.os.Looper; import android.os.SystemClock; import android.util.Log; import android.view.View; @@ -82,7 +79,6 @@ import com.android.launcher3.userevent.nano.LauncherLogProto.ContainerType; import com.android.launcher3.util.RaceConditionTracker; import com.android.launcher3.util.TraceHelper; import com.android.launcher3.views.FloatingIconView; -import com.android.quickstep.ActivityControlHelper.ActivityInitListener; import com.android.quickstep.ActivityControlHelper.AnimationFactory; import com.android.quickstep.ActivityControlHelper.AnimationFactory.ShelfAnimState; import com.android.quickstep.ActivityControlHelper.HomeAnimationFactory; @@ -99,14 +95,14 @@ import com.android.systemui.shared.recents.model.ThumbnailData; import com.android.systemui.shared.system.InputConsumerController; import com.android.systemui.shared.system.LatencyTrackerCompat; import com.android.systemui.shared.system.RemoteAnimationTargetCompat; -import com.android.systemui.shared.system.SyncRtSurfaceTransactionApplierCompat; import com.android.systemui.shared.system.WindowCallbacksCompat; import androidx.annotation.NonNull; import androidx.annotation.UiThread; @TargetApi(Build.VERSION_CODES.O) -public class WindowTransformSwipeHandler extends BaseSwipeUpHandler +public class WindowTransformSwipeHandler + extends BaseSwipeUpHandler implements OnApplyWindowInsetsListener { private static final String TAG = WindowTransformSwipeHandler.class.getSimpleName(); @@ -219,35 +215,24 @@ public class WindowTransformSwipeHandler extends // Either RectFSpringAnim (if animating home) or ObjectAnimator (from mCurrentShift) otherwise private RunningWindowAnim mRunningWindowAnim; private boolean mIsShelfPeeking; - private DeviceProfile mDp; private boolean mContinuingLastGesture; // To avoid UI jump when gesture is started, we offset the animation by the threshold. private float mShiftAtGestureStart = 0; - private final Handler mMainThreadHandler = MAIN_THREAD_EXECUTOR.getHandler(); - - private final ActivityControlHelper mActivityControlHelper; - private final ActivityInitListener mActivityInitListener; - private final RecentsModel mRecentsModel; - - private final SysUINavigationMode.Mode mMode; + private final Mode mMode; private final int mRunningTaskId; private ThumbnailData mTaskSnapshot; - private MultiStateCallback mStateCallback; // Used to control launcher components throughout the swipe gesture. private AnimatorPlaybackController mLauncherTransitionController; private boolean mHasLauncherTransitionControllerStarted; - private T mActivity; private AnimationFactory mAnimationFactory = (t) -> { }; private LiveTileOverlay mLiveTileOverlay = new LiveTileOverlay(); - private boolean mCanceled; private boolean mWasLauncherAlreadyVisible; - private int mFinishingRecentsAnimationForNewTaskId = -1; private boolean mPassedOverviewThreshold; private boolean mGestureStarted; @@ -256,24 +241,17 @@ public class WindowTransformSwipeHandler extends private PointF mDownPos; private boolean mIsLikelyToStartNewTask; - private final RecentsAnimationWrapper mRecentsAnimationWrapper; - private final long mTouchTimeMs; private long mLauncherFrameDrawnTime; public WindowTransformSwipeHandler(RunningTaskInfo runningTaskInfo, Context context, - long touchTimeMs, ActivityControlHelper controller, boolean continuingLastGesture, + long touchTimeMs, OverviewComponentObserver overviewComponentObserver, + boolean continuingLastGesture, InputConsumerController inputConsumer, RecentsModel recentsModel) { - super(context); + super(context, overviewComponentObserver, recentsModel, inputConsumer); mRunningTaskId = runningTaskInfo.id; mTouchTimeMs = touchTimeMs; - mActivityControlHelper = controller; - mRecentsModel = recentsModel; - mActivityInitListener = mActivityControlHelper - .createActivityInitListener(this::onActivityInit); mContinuingLastGesture = continuingLastGesture; - mRecentsAnimationWrapper = new RecentsAnimationWrapper(inputConsumer, - this::createNewInputProxyHandler); mMode = SysUINavigationMode.getMode(context); initStateCallbacks(); @@ -342,14 +320,6 @@ public class WindowTransformSwipeHandler extends } } - private void setStateOnUiThread(int stateFlag) { - if (Looper.myLooper() == mMainThreadHandler.getLooper()) { - mStateCallback.setState(stateFlag); - } else { - postAsyncCallback(mMainThreadHandler, () -> mStateCallback.setState(stateFlag)); - } - } - private Rect getStackBounds(DeviceProfile dp) { if (mActivity != null) { int loc[] = new int[2]; @@ -383,14 +353,7 @@ public class WindowTransformSwipeHandler extends } @Override - public void initWhenReady() { - // Preload the plan - mRecentsModel.getTasks(null); - - mActivityInitListener.register(); - } - - private boolean onActivityInit(final T activity, Boolean alreadyOnHome) { + protected boolean onActivityInit(final T activity, Boolean alreadyOnHome) { if (mActivity == activity) { return true; } @@ -411,19 +374,7 @@ public class WindowTransformSwipeHandler extends } mRecentsView = activity.getOverviewPanel(); - SyncRtSurfaceTransactionApplierCompat.create(mRecentsView, applier -> { - mTransformParams.setSyncTransactionApplier(applier); - mRecentsAnimationWrapper.runOnInit(() -> - mRecentsAnimationWrapper.targetSet.addDependentTransactionApplier(applier)); - }); - - mRecentsView.setOnScrollChangeListener((v, scrollX, scrollY, oldScrollX, oldScrollY) -> { - if (mGestureEndTarget != HOME) { - updateFinalShift(); - } - }); - mRecentsView.setRecentsAnimationWrapper(mRecentsAnimationWrapper); - mRecentsView.setClipAnimationHelper(mClipAnimationHelper); + linkRecentsViewScroll(); mRecentsView.setLiveTileOverlay(mLiveTileOverlay); mActivity.getRootView().getOverlay().add(mLiveTileOverlay); @@ -438,6 +389,11 @@ public class WindowTransformSwipeHandler extends return true; } + @Override + protected boolean moveWindowWithRecentsScroll() { + return mGestureEndTarget != HOME; + } + private void onLauncherStart(final T activity) { if (TestProtocol.sDebugTracing) { Log.d(TestProtocol.NO_OVERVIEW_EVENT_TAG, "onLauncherStart"); @@ -654,20 +610,18 @@ public class WindowTransformSwipeHandler extends updateLauncherTransitionProgress(); } - @UiThread + @Override + public Intent getLaunchIntent() { + return mOverviewComponentObserver.getOverviewIntent(); + } + @Override public void updateFinalShift() { - float shift = mCurrentShift.value; SwipeAnimationTargetSet controller = mRecentsAnimationWrapper.getController(); if (controller != null) { - float offsetX = mRecentsView == null ? 0 : mRecentsView.getScrollOffset(); - float offsetScale = getTaskCurveScaleForOffsetX(offsetX, - mClipAnimationHelper.getTargetRect().width()); - mTransformParams.setProgress(shift).setOffsetX(offsetX).setOffsetScale(offsetScale); - mClipAnimationHelper.applyTransform(mRecentsAnimationWrapper.targetSet, - mTransformParams); - updateSysUiFlags(shift); + applyTransformUnchecked(); + updateSysUiFlags(mCurrentShift.value); } if (ENABLE_QUICKSTEP_LIVE_TILE.get()) { @@ -817,8 +771,8 @@ public class WindowTransformSwipeHandler extends handleNormalGestureEnd(endVelocity, isFling, velocity, false /* isCancel */); } - @UiThread - private InputConsumer createNewInputProxyHandler() { + @Override + protected InputConsumer createNewInputProxyHandler() { endRunningWindowAnim(true /* cancel */); endLauncherTransitionController(); if (!ENABLE_QUICKSTEP_LIVE_TILE.get()) { @@ -1208,40 +1162,15 @@ public class WindowTransformSwipeHandler extends @UiThread private void startNewTask() { - // Launch the task user scrolled to (mRecentsView.getNextPage()). - if (ENABLE_QUICKSTEP_LIVE_TILE.get()) { - // We finish recents animation inside launchTask() when live tile is enabled. - mRecentsView.getTaskViewAt(mRecentsView.getNextPage()).launchTask(false /* animate */, - true /* freezeTaskList */); - } else { - int taskId = mRecentsView.getTaskViewAt(mRecentsView.getNextPage()).getTask().key.id; - mFinishingRecentsAnimationForNewTaskId = taskId; - mRecentsAnimationWrapper.finish(true /* toRecents */, () -> { - if (!mCanceled) { - TaskView nextTask = mRecentsView.getTaskView(taskId); - if (nextTask != null) { - nextTask.launchTask(false /* animate */, true /* freezeTaskList */, - success -> { - if (!success) { - // We couldn't launch the task, so take user to overview so they can - // decide what to do instead of staying in this broken state. - endLauncherTransitionController(); - mActivityControlHelper.onLaunchTaskFailed(mActivity); - nextTask.notifyTaskLaunchFailed(TAG); - updateSysUiFlags(1 /* windowProgress == overview */); - } else { - mActivityControlHelper.onLaunchTaskSuccess(mActivity); - } - }, mMainThreadHandler); - doLogGesture(NEW_TASK); - } - reset(); - } - mCanceled = false; - mFinishingRecentsAnimationForNewTaskId = -1; - }); - } - TOUCH_INTERACTION_LOG.addLog("finishRecentsAnimation", true); + startNewTask(STATE_HANDLER_INVALIDATED, success -> { + if (!success) { + // We couldn't launch the task, so take user to overview so they can + // decide what to do instead of staying in this broken state. + endLauncherTransitionController(); + updateSysUiFlags(1 /* windowProgress == overview */); + } + doLogGesture(NEW_TASK); + }); } private void reset() { diff --git a/quickstep/recents_ui_overrides/src/com/android/quickstep/fallback/FallbackRecentsView.java b/quickstep/recents_ui_overrides/src/com/android/quickstep/fallback/FallbackRecentsView.java index c28761804b..eaf6ebac80 100644 --- a/quickstep/recents_ui_overrides/src/com/android/quickstep/fallback/FallbackRecentsView.java +++ b/quickstep/recents_ui_overrides/src/com/android/quickstep/fallback/FallbackRecentsView.java @@ -87,6 +87,12 @@ public class FallbackRecentsView extends RecentsView { super.draw(canvas); } + @Override + public void reset() { + super.reset(); + resetViewUI(); + } + @Override protected void getTaskSize(DeviceProfile dp, Rect outRect) { LayoutUtils.calculateFallbackTaskSize(getContext(), dp, outRect); @@ -114,6 +120,12 @@ public class FallbackRecentsView extends RecentsView { } } + @Override + public void resetTaskVisuals() { + super.resetTaskVisuals(); + setFullscreenProgress(mFullscreenProgress); + } + @Override protected void onLayout(boolean changed, int left, int top, int right, int bottom) { super.onLayout(changed, left, top, right, bottom); diff --git a/quickstep/recents_ui_overrides/src/com/android/quickstep/inputconsumers/FallbackNoButtonInputConsumer.java b/quickstep/recents_ui_overrides/src/com/android/quickstep/inputconsumers/FallbackNoButtonInputConsumer.java index a5a8f388f4..a0e806eee3 100644 --- a/quickstep/recents_ui_overrides/src/com/android/quickstep/inputconsumers/FallbackNoButtonInputConsumer.java +++ b/quickstep/recents_ui_overrides/src/com/android/quickstep/inputconsumers/FallbackNoButtonInputConsumer.java @@ -15,15 +15,16 @@ */ package com.android.quickstep.inputconsumers; +import static com.android.quickstep.MultiStateCallback.DEBUG_STATES; import static com.android.quickstep.RecentsActivity.EXTRA_TASK_ID; import static com.android.quickstep.RecentsActivity.EXTRA_THUMBNAIL; +import static com.android.quickstep.inputconsumers.FallbackNoButtonInputConsumer.GestureEndTarget.NEW_TASK; import static com.android.quickstep.WindowTransformSwipeHandler.MIN_PROGRESS_FOR_OVERVIEW; import static com.android.quickstep.inputconsumers.FallbackNoButtonInputConsumer.GestureEndTarget.HOME; import static com.android.quickstep.inputconsumers.FallbackNoButtonInputConsumer.GestureEndTarget.LAST_TASK; import static com.android.quickstep.inputconsumers.FallbackNoButtonInputConsumer.GestureEndTarget.RECENTS; import android.animation.Animator; -import android.animation.AnimatorListenerAdapter; import android.animation.AnimatorSet; import android.app.ActivityManager.RunningTaskInfo; import android.app.ActivityOptions; @@ -34,24 +35,53 @@ import android.graphics.Rect; import android.os.Bundle; import android.view.WindowManager; -import com.android.launcher3.DeviceProfile; import com.android.launcher3.InvariantDeviceProfile; import com.android.launcher3.R; -import com.android.quickstep.ActivityControlHelper; +import com.android.launcher3.anim.AnimationSuccessListener; import com.android.quickstep.AnimatedFloat; import com.android.quickstep.BaseSwipeUpHandler; +import com.android.quickstep.MultiStateCallback; import com.android.quickstep.OverviewComponentObserver; +import com.android.quickstep.RecentsActivity; +import com.android.quickstep.RecentsModel; +import com.android.quickstep.SwipeSharedState; +import com.android.quickstep.fallback.FallbackRecentsView; import com.android.quickstep.util.ObjectWrapper; import com.android.quickstep.util.SwipeAnimationTargetSet; +import com.android.quickstep.views.TaskView; import com.android.systemui.shared.recents.model.ThumbnailData; +import com.android.systemui.shared.system.ActivityOptionsCompat; +import com.android.systemui.shared.system.InputConsumerController; import com.android.systemui.shared.system.RemoteAnimationTargetCompat; -public class FallbackNoButtonInputConsumer extends BaseSwipeUpHandler { +public class FallbackNoButtonInputConsumer extends BaseSwipeUpHandler { + + private static final String[] STATE_NAMES = DEBUG_STATES ? new String[5] : null; + + private static int getFlagForIndex(int index, String name) { + if (DEBUG_STATES) { + STATE_NAMES[index] = name; + } + return 1 << index; + } + + private static final int STATE_RECENTS_PRESENT = + getFlagForIndex(0, "STATE_RECENTS_PRESENT"); + private static final int STATE_HANDLER_INVALIDATED = + getFlagForIndex(1, "STATE_HANDLER_INVALIDATED"); + + private static final int STATE_GESTURE_CANCELLED = + getFlagForIndex(2, "STATE_GESTURE_CANCELLED"); + private static final int STATE_GESTURE_COMPLETED = + getFlagForIndex(3, "STATE_GESTURE_COMPLETED"); + private static final int STATE_APP_CONTROLLER_RECEIVED = + getFlagForIndex(4, "STATE_APP_CONTROLLER_RECEIVED"); public enum GestureEndTarget { HOME(3, 100, 1), RECENTS(1, 300, 0), - LAST_TASK(0, 150, 1); + LAST_TASK(0, 150, 1), + NEW_TASK(0, 150, 1); private final float mEndProgress; private final long mDurationMultiplier; @@ -64,53 +94,131 @@ public class FallbackNoButtonInputConsumer extends BaseSwipeUpHandler { } } - private final ActivityControlHelper mActivityControlHelper; - private final OverviewComponentObserver mOverviewComponentObserver; private final int mRunningTaskId; - private final DeviceProfile mDP; private final Rect mTargetRect = new Rect(); private final AnimatedFloat mLauncherAlpha = new AnimatedFloat(this::onLauncherAlphaChanged); - private SwipeAnimationTargetSet mSwipeAnimationTargetSet; - private boolean mIsMotionPaused = false; private GestureEndTarget mEndTarget; + private final boolean mInQuickSwitchMode; + private final boolean mContinuingLastGesture; + + private Animator mFinishAnimation; + public FallbackNoButtonInputConsumer(Context context, OverviewComponentObserver overviewComponentObserver, - RunningTaskInfo runningTaskInfo) { - super(context); - mOverviewComponentObserver = overviewComponentObserver; - mActivityControlHelper = overviewComponentObserver.getActivityControlHelper(); + RunningTaskInfo runningTaskInfo, RecentsModel recentsModel, + InputConsumerController inputConsumer, + boolean isLikelyToStartNewTask, boolean continuingLastGesture) { + super(context, overviewComponentObserver, recentsModel, inputConsumer); mRunningTaskId = runningTaskInfo.id; - mDP = InvariantDeviceProfile.INSTANCE.get(context).getDeviceProfile(context).copy(context); + mDp = InvariantDeviceProfile.INSTANCE.get(context).getDeviceProfile(context).copy(context); mLauncherAlpha.value = 1; + mInQuickSwitchMode = isLikelyToStartNewTask || continuingLastGesture; + mContinuingLastGesture = continuingLastGesture; mClipAnimationHelper.setBaseAlphaCallback((t, a) -> mLauncherAlpha.value); + initStateCallbacks(); initTransitionTarget(); } + private void initStateCallbacks() { + mStateCallback = new MultiStateCallback(STATE_NAMES); + + mStateCallback.addCallback(STATE_HANDLER_INVALIDATED, + this::onHandlerInvalidated); + mStateCallback.addCallback(STATE_RECENTS_PRESENT | STATE_HANDLER_INVALIDATED, + this::onHandlerInvalidatedWithRecents); + + mStateCallback.addCallback(STATE_GESTURE_CANCELLED | STATE_APP_CONTROLLER_RECEIVED, + this::finishAnimationTargetSetAnimationComplete); + + if (mInQuickSwitchMode) { + mStateCallback.addCallback(STATE_GESTURE_COMPLETED | STATE_APP_CONTROLLER_RECEIVED + | STATE_RECENTS_PRESENT, + this::finishAnimationTargetSet); + } else { + mStateCallback.addCallback(STATE_GESTURE_COMPLETED | STATE_APP_CONTROLLER_RECEIVED, + this::finishAnimationTargetSet); + } + } + private void onLauncherAlphaChanged() { - if (mSwipeAnimationTargetSet != null && mEndTarget == null) { - mClipAnimationHelper.applyTransform(mSwipeAnimationTargetSet, mTransformParams); + if (mRecentsAnimationWrapper.targetSet != null && mEndTarget == null) { + applyTransformUnchecked(); } } + @Override + protected boolean onActivityInit(final RecentsActivity activity, Boolean alreadyOnHome) { + mActivity = activity; + mRecentsView = activity.getOverviewPanel(); + linkRecentsViewScroll(); + mRecentsView.setDisallowScrollToClearAll(true); + mRecentsView.getClearAllButton().setVisibilityAlpha(0); + + ((FallbackRecentsView) mRecentsView).setZoomProgress(1); + + if (!mContinuingLastGesture) { + mRecentsView.onGestureAnimationStart(mRunningTaskId); + } + setStateOnUiThread(STATE_RECENTS_PRESENT); + return true; + } + + @Override + protected boolean moveWindowWithRecentsScroll() { + return mInQuickSwitchMode; + } + + @Override + public void initWhenReady() { + if (mInQuickSwitchMode) { + // Only init if we are in quickswitch mode + super.initWhenReady(); + } + } + + @Override + public void updateDisplacement(float displacement) { + if (!mInQuickSwitchMode) { + super.updateDisplacement(displacement); + } + } + + @Override + protected InputConsumer createNewInputProxyHandler() { + // Just consume all input on the active task + return InputConsumer.NO_OP; + } + @Override public void onMotionPauseChanged(boolean isPaused) { - mIsMotionPaused = isPaused; - mLauncherAlpha.animateToValue(mLauncherAlpha.value, isPaused ? 0 : 1) - .setDuration(150).start(); - performHapticFeedback(); + if (!mInQuickSwitchMode) { + mIsMotionPaused = isPaused; + mLauncherAlpha.animateToValue(mLauncherAlpha.value, isPaused ? 0 : 1) + .setDuration(150).start(); + performHapticFeedback(); + } + } + + @Override + public Intent getLaunchIntent() { + if (mInQuickSwitchMode) { + return mOverviewComponentObserver.getOverviewIntent(); + } else { + return mOverviewComponentObserver.getHomeIntent(); + } } @Override public void updateFinalShift() { mTransformParams.setProgress(mCurrentShift.value); - if (mSwipeAnimationTargetSet != null) { - mClipAnimationHelper.applyTransform(mSwipeAnimationTargetSet, mTransformParams); + if (mRecentsAnimationWrapper.targetSet != null) { + applyTransformUnchecked(); } } @@ -118,41 +226,90 @@ public class FallbackNoButtonInputConsumer extends BaseSwipeUpHandler { public void onGestureCancelled() { updateDisplacement(0); mEndTarget = LAST_TASK; - finishAnimationTargetSetAnimationComplete(); + setStateOnUiThread(STATE_GESTURE_CANCELLED); } @Override public void onGestureEnded(float endVelocity, PointF velocity, PointF downPos) { - float flingThreshold = mContext.getResources() - .getDimension(R.dimen.quickstep_fling_threshold_velocity); - boolean isFling = Math.abs(endVelocity) > flingThreshold; - - if (isFling) { - mEndTarget = endVelocity < 0 ? HOME : LAST_TASK; - } else if (mIsMotionPaused) { - mEndTarget = RECENTS; + if (mInQuickSwitchMode) { + // For now set it to non-null, it will be reset before starting the animation + mEndTarget = LAST_TASK; } else { - mEndTarget = mCurrentShift.value >= MIN_PROGRESS_FOR_OVERVIEW ? HOME : LAST_TASK; + float flingThreshold = mContext.getResources() + .getDimension(R.dimen.quickstep_fling_threshold_velocity); + boolean isFling = Math.abs(endVelocity) > flingThreshold; + + if (isFling) { + mEndTarget = endVelocity < 0 ? HOME : LAST_TASK; + } else if (mIsMotionPaused) { + mEndTarget = RECENTS; + } else { + mEndTarget = mCurrentShift.value >= MIN_PROGRESS_FOR_OVERVIEW ? HOME : LAST_TASK; + } } - if (mSwipeAnimationTargetSet != null) { - finishAnimationTargetSet(); + setStateOnUiThread(STATE_GESTURE_COMPLETED); + } + + @Override + public void onConsumerAboutToBeSwitched(SwipeSharedState sharedState) { + if (mInQuickSwitchMode && mEndTarget != null) { + sharedState.canGestureBeContinued = true; + sharedState.goingToLauncher = false; + + mCanceled = true; + mCurrentShift.cancelAnimation(); + if (mFinishAnimation != null) { + mFinishAnimation.cancel(); + } + + if (mRecentsView != null) { + if (mFinishingRecentsAnimationForNewTaskId != -1) { + TaskView newRunningTaskView = mRecentsView.getTaskView( + mFinishingRecentsAnimationForNewTaskId); + int newRunningTaskId = newRunningTaskView != null + ? newRunningTaskView.getTask().key.id + : -1; + mRecentsView.setCurrentTask(newRunningTaskId); + sharedState.setRecentsAnimationFinishInterrupted(newRunningTaskId); + } + mRecentsView.setOnScrollChangeListener(null); + } + } else { + setStateOnUiThread(STATE_HANDLER_INVALIDATED); } } + + private void onHandlerInvalidated() { + mActivityInitListener.unregister(); + if (mGestureEndCallback != null) { + mGestureEndCallback.run(); + } + } + + private void onHandlerInvalidatedWithRecents() { + mRecentsView.onGestureAnimationEnd(); + mRecentsView.setDisallowScrollToClearAll(false); + mRecentsView.getClearAllButton().setVisibilityAlpha(1); + } + + private void finishAnimationTargetSetAnimationComplete() { switch (mEndTarget) { case HOME: - mSwipeAnimationTargetSet.finishController(true, null, true); + mRecentsAnimationWrapper.finish(true, null, true); break; case LAST_TASK: - mSwipeAnimationTargetSet.finishController(false, null, false); + mRecentsAnimationWrapper.finish(false, null, false); break; case RECENTS: { ThumbnailData thumbnail = - mSwipeAnimationTargetSet.controller.screenshotTask(mRunningTaskId); - mSwipeAnimationTargetSet.controller.setCancelWithDeferredScreenshot(true); + mRecentsAnimationWrapper.targetSet.controller.screenshotTask(mRunningTaskId); + mRecentsAnimationWrapper.setCancelWithDeferredScreenshot(true); ActivityOptions options = ActivityOptions.makeCustomAnimation(mContext, 0, 0); + ActivityOptionsCompat.setFreezeRecentTasksList(options); + Bundle extras = new Bundle(); extras.putBinder(EXTRA_THUMBNAIL, new ObjectWrapper<>(thumbnail)); extras.putInt(EXTRA_TASK_ID, mRunningTaskId); @@ -160,33 +317,58 @@ public class FallbackNoButtonInputConsumer extends BaseSwipeUpHandler { Intent intent = new Intent(mOverviewComponentObserver.getOverviewIntent()) .putExtras(extras); mContext.startActivity(intent, options.toBundle()); - mSwipeAnimationTargetSet.controller.cleanupScreenshot(); + mRecentsAnimationWrapper.targetSet.controller.cleanupScreenshot(); + break; + } + case NEW_TASK: { + startNewTask(STATE_HANDLER_INVALIDATED, b -> {}); break; } } - if (mGestureEndCallback != null) { - mGestureEndCallback.run(); - } + + setStateOnUiThread(STATE_HANDLER_INVALIDATED); } private void finishAnimationTargetSet() { + if (mInQuickSwitchMode) { + // Recalculate the end target, some views might have been initialized after + // gesture has ended. + if (mRecentsView == null || !mRecentsAnimationWrapper.hasTargets()) { + mEndTarget = LAST_TASK; + } else { + final int runningTaskIndex = mRecentsView.getRunningTaskIndex(); + final int taskToLaunch = mRecentsView.getNextPage(); + mEndTarget = (runningTaskIndex >= 0 && taskToLaunch != runningTaskIndex) + ? NEW_TASK : LAST_TASK; + } + } + float endProgress = mEndTarget.mEndProgress; - if (mCurrentShift.value != endProgress) { + if (mCurrentShift.value != endProgress || mInQuickSwitchMode) { AnimatorSet anim = new AnimatorSet(); anim.play(mLauncherAlpha.animateToValue( mLauncherAlpha.value, mEndTarget.mLauncherAlpha)); anim.play(mCurrentShift.animateToValue(mCurrentShift.value, endProgress)); - anim.setDuration((long) (mEndTarget.mDurationMultiplier * - Math.abs(endProgress - mCurrentShift.value))); - anim.addListener(new AnimatorListenerAdapter() { + + long duration = (long) (mEndTarget.mDurationMultiplier * + Math.abs(endProgress - mCurrentShift.value)); + if (mRecentsView != null) { + duration = Math.max(duration, mRecentsView.getScroller().getDuration()); + } + + anim.setDuration(duration); + anim.addListener(new AnimationSuccessListener() { + @Override - public void onAnimationEnd(Animator animation) { + public void onAnimationSuccess(Animator animator) { finishAnimationTargetSetAnimationComplete(); + mFinishAnimation = null; } }); anim.start(); + mFinishAnimation = anim; } else { finishAnimationTargetSetAnimationComplete(); } @@ -194,34 +376,36 @@ public class FallbackNoButtonInputConsumer extends BaseSwipeUpHandler { @Override public void onRecentsAnimationStart(SwipeAnimationTargetSet targetSet) { - mSwipeAnimationTargetSet = targetSet; - Rect overviewStackBounds = new Rect(0, 0, mDP.widthPx, mDP.heightPx); + mRecentsAnimationWrapper.setController(targetSet); + mRecentsAnimationWrapper.enableInputConsumer(); + Rect overviewStackBounds = new Rect(0, 0, mDp.widthPx, mDp.heightPx); RemoteAnimationTargetCompat runningTaskTarget = targetSet.findTask(mRunningTaskId); - mDP.updateIsSeascape(mContext.getSystemService(WindowManager.class)); + mDp.updateIsSeascape(mContext.getSystemService(WindowManager.class)); if (targetSet.homeContentInsets != null) { - mDP.updateInsets(targetSet.homeContentInsets); + mDp.updateInsets(targetSet.homeContentInsets); } if (runningTaskTarget != null) { mClipAnimationHelper.updateSource(overviewStackBounds, runningTaskTarget); } - mClipAnimationHelper.prepareAnimation(mDP, false /* isOpening */); + mClipAnimationHelper.prepareAnimation(mDp, false /* isOpening */); initTransitionTarget(); - mClipAnimationHelper.applyTransform(mSwipeAnimationTargetSet, mTransformParams); + applyTransformUnchecked(); - if (mEndTarget != null) { - finishAnimationTargetSet(); - } + setStateOnUiThread(STATE_APP_CONTROLLER_RECEIVED); } private void initTransitionTarget() { mTransitionDragLength = mActivityControlHelper.getSwipeUpDestinationAndLength( - mDP, mContext, mTargetRect); - mDragLengthFactor = (float) mDP.heightPx / mTransitionDragLength; + mDp, mContext, mTargetRect); + mDragLengthFactor = (float) mDp.heightPx / mTransitionDragLength; mClipAnimationHelper.updateTargetRect(mTargetRect); } @Override - public void onRecentsAnimationCanceled() { } + public void onRecentsAnimationCanceled() { + mRecentsAnimationWrapper.setController(null); + setStateOnUiThread(STATE_HANDLER_INVALIDATED); + } } diff --git a/quickstep/recents_ui_overrides/src/com/android/quickstep/inputconsumers/OtherActivityInputConsumer.java b/quickstep/recents_ui_overrides/src/com/android/quickstep/inputconsumers/OtherActivityInputConsumer.java index 9114995cc9..86766d99fb 100644 --- a/quickstep/recents_ui_overrides/src/com/android/quickstep/inputconsumers/OtherActivityInputConsumer.java +++ b/quickstep/recents_ui_overrides/src/com/android/quickstep/inputconsumers/OtherActivityInputConsumer.java @@ -35,7 +35,6 @@ import android.annotation.TargetApi; import android.app.ActivityManager.RunningTaskInfo; import android.content.Context; import android.content.ContextWrapper; -import android.content.Intent; import android.graphics.PointF; import android.graphics.RectF; import android.os.Build; @@ -79,7 +78,6 @@ public class OtherActivityInputConsumer extends ContextWrapper implements InputC private final CachedEventDispatcher mRecentsViewDispatcher = new CachedEventDispatcher(); private final RunningTaskInfo mRunningTask; - private final Intent mHomeIntent; private final OverviewCallbacks mOverviewCallbacks; private final SwipeSharedState mSwipeSharedState; private final InputMonitorCompat mInputMonitorCompat; @@ -117,12 +115,13 @@ public class OtherActivityInputConsumer extends ContextWrapper implements InputC private float mStartDisplacement; private Handler mMainThreadHandler; - private Runnable mCancelRecentsAnimationRunnable = () -> + private Runnable mCancelRecentsAnimationRunnable = () -> { ActivityManagerWrapper.getInstance().cancelRecentsAnimation( true /* restoreHomeStackPosition */); + }; public OtherActivityInputConsumer(Context base, RunningTaskInfo runningTaskInfo, - Intent homeIntent, boolean isDeferredDownTarget, OverviewCallbacks overviewCallbacks, + boolean isDeferredDownTarget, OverviewCallbacks overviewCallbacks, Consumer onCompleteCallback, SwipeSharedState swipeSharedState, InputMonitorCompat inputMonitorCompat, RectF swipeTouchRegion, boolean disableHorizontalSwipe, @@ -131,7 +130,6 @@ public class OtherActivityInputConsumer extends ContextWrapper implements InputC mMainThreadHandler = new Handler(Looper.getMainLooper()); mRunningTask = runningTaskInfo; - mHomeIntent = homeIntent; mMode = SysUINavigationMode.getMode(base); mSwipeTouchRegion = swipeTouchRegion; mHandlerFactory = handlerFactory; @@ -204,7 +202,7 @@ public class OtherActivityInputConsumer extends ContextWrapper implements InputC // Start the window animation on down to give more time for launcher to draw if the // user didn't start the gesture over the back button if (!mIsDeferredDownTarget) { - startTouchTrackingForWindowAnimation(ev.getEventTime()); + startTouchTrackingForWindowAnimation(ev.getEventTime(), false); } RaceConditionTracker.onEvent(DOWN_EVT, EXIT); @@ -253,6 +251,10 @@ public class OtherActivityInputConsumer extends ContextWrapper implements InputC } } + float horizontalDist = Math.abs(displacementX); + float upDist = -displacement; + boolean isLikelyToStartNewTask = horizontalDist > upDist; + if (!mPassedPilferInputSlop) { float displacementY = mLastPos.y - mDownPos.y; if (squaredHypot(displacementX, displacementY) >= mSquaredTouchSlop) { @@ -268,7 +270,8 @@ public class OtherActivityInputConsumer extends ContextWrapper implements InputC if (mIsDeferredDownTarget) { // Deferred gesture, start the animation and gesture tracking once // we pass the actual touch slop - startTouchTrackingForWindowAnimation(ev.getEventTime()); + startTouchTrackingForWindowAnimation( + ev.getEventTime(), isLikelyToStartNewTask); } if (!mPassedWindowMoveSlop) { mPassedWindowMoveSlop = true; @@ -286,9 +289,6 @@ public class OtherActivityInputConsumer extends ContextWrapper implements InputC } if (mMode == Mode.NO_BUTTON) { - float horizontalDist = Math.abs(displacementX); - float upDist = -displacement; - boolean isLikelyToStartNewTask = horizontalDist > upDist; mMotionPauseDetector.setDisallowPause(upDist < mMotionPauseMinDisplacement || isLikelyToStartNewTask); mMotionPauseDetector.addPosition(displacement, ev.getEventTime()); @@ -320,12 +320,13 @@ public class OtherActivityInputConsumer extends ContextWrapper implements InputC mInteractionHandler.onGestureStarted(); } - private void startTouchTrackingForWindowAnimation(long touchTimeMs) { + private void startTouchTrackingForWindowAnimation( + long touchTimeMs, boolean isLikelyToStartNewTask) { TOUCH_INTERACTION_LOG.addLog("startRecentsAnimation"); RecentsAnimationListenerSet listenerSet = mSwipeSharedState.getActiveListener(); final BaseSwipeUpHandler handler = mHandlerFactory.newHandler(mRunningTask, touchTimeMs, - listenerSet != null); + listenerSet != null, isLikelyToStartNewTask); mInteractionHandler = handler; handler.setGestureEndCallback(this::onInteractionGestureFinished); @@ -340,7 +341,7 @@ public class OtherActivityInputConsumer extends ContextWrapper implements InputC RecentsAnimationListenerSet newListenerSet = mSwipeSharedState.newRecentsAnimationListenerSet(); newListenerSet.addListener(handler); - startRecentsActivityAsync(mHomeIntent, newListenerSet); + startRecentsActivityAsync(handler.getLaunchIntent(), newListenerSet); } } diff --git a/quickstep/recents_ui_overrides/src/com/android/quickstep/views/RecentsView.java b/quickstep/recents_ui_overrides/src/com/android/quickstep/views/RecentsView.java index 432f8a1355..6bf3155b41 100644 --- a/quickstep/recents_ui_overrides/src/com/android/quickstep/views/RecentsView.java +++ b/quickstep/recents_ui_overrides/src/com/android/quickstep/views/RecentsView.java @@ -289,7 +289,7 @@ public abstract class RecentsView extends PagedView impl @ViewDebug.ExportedProperty(category = "launcher") private float mContentAlpha = 1; @ViewDebug.ExportedProperty(category = "launcher") - private float mFullscreenProgress = 0; + protected float mFullscreenProgress = 0; // Keeps track of task id whose visual state should not be reset private int mIgnoreResetTaskId = -1; @@ -604,6 +604,7 @@ public abstract class RecentsView extends PagedView impl TaskView taskView = (TaskView) getChildAt(i); if (mIgnoreResetTaskId != taskView.getTask().key.id) { taskView.resetVisualProperties(); + taskView.setStableAlpha(mContentAlpha); } } if (mRunningTaskTileHidden) { From 587c3cef518d744b6d5973fc7da73e817e415d7b Mon Sep 17 00:00:00 2001 From: Sunny Goyal Date: Fri, 12 Jul 2019 10:17:12 -0700 Subject: [PATCH 043/108] Fixing multiwindow transition when using 3P launcher Bug: 137197916 Change-Id: I3c5cfc290972187d9d556a722afc61489d0d0629 --- .../android/quickstep/BaseSwipeUpHandler.java | 76 ++++++++++++++++++- .../android/quickstep/RecentsActivity.java | 14 ++-- .../WindowTransformSwipeHandler.java | 74 +----------------- .../FallbackNoButtonInputConsumer.java | 35 +-------- 4 files changed, 87 insertions(+), 112 deletions(-) diff --git a/quickstep/recents_ui_overrides/src/com/android/quickstep/BaseSwipeUpHandler.java b/quickstep/recents_ui_overrides/src/com/android/quickstep/BaseSwipeUpHandler.java index 3032ca3079..23fe2dee10 100644 --- a/quickstep/recents_ui_overrides/src/com/android/quickstep/BaseSwipeUpHandler.java +++ b/quickstep/recents_ui_overrides/src/com/android/quickstep/BaseSwipeUpHandler.java @@ -29,7 +29,9 @@ import android.annotation.TargetApi; import android.app.ActivityManager.RunningTaskInfo; import android.content.Context; import android.content.Intent; +import android.graphics.Point; import android.graphics.PointF; +import android.graphics.Rect; import android.os.Build; import android.os.Handler; import android.os.Looper; @@ -37,21 +39,27 @@ import android.os.VibrationEffect; import android.os.Vibrator; import android.provider.Settings; import android.view.MotionEvent; +import android.view.View; +import android.view.WindowManager; import android.view.animation.Interpolator; import com.android.launcher3.BaseDraggingActivity; import com.android.launcher3.DeviceProfile; +import com.android.launcher3.InvariantDeviceProfile; import com.android.launcher3.R; import com.android.launcher3.Utilities; import com.android.launcher3.graphics.RotationMode; import com.android.quickstep.ActivityControlHelper.ActivityInitListener; +import com.android.quickstep.SysUINavigationMode.Mode; import com.android.quickstep.inputconsumers.InputConsumer; import com.android.quickstep.util.ClipAnimationHelper; import com.android.quickstep.util.ClipAnimationHelper.TransformParams; +import com.android.quickstep.util.SwipeAnimationTargetSet; import com.android.quickstep.util.SwipeAnimationTargetSet.SwipeAnimationListener; import com.android.quickstep.views.RecentsView; import com.android.quickstep.views.TaskView; import com.android.systemui.shared.system.InputConsumerController; +import com.android.systemui.shared.system.RemoteAnimationTargetCompat; import com.android.systemui.shared.system.SyncRtSurfaceTransactionApplierCompat; import java.util.function.Consumer; @@ -66,6 +74,7 @@ public abstract class BaseSwipeUpHandler implements SwipeAnimationListener { private static final String TAG = "BaseSwipeUpHandler"; + protected static final Rect TEMP_RECT = new Rect(); // Start resisting when swiping past this factor of mTransitionDragLength. private static final float DRAG_LENGTH_FACTOR_START_PULLBACK = 1.4f; @@ -82,11 +91,13 @@ public abstract class BaseSwipeUpHandler protected final OverviewComponentObserver mOverviewComponentObserver; protected final ActivityControlHelper mActivityControlHelper; protected final RecentsModel mRecentsModel; + protected final int mRunningTaskId; protected final ClipAnimationHelper mClipAnimationHelper; protected final TransformParams mTransformParams = new TransformParams(); private final Vibrator mVibrator; + protected final Mode mMode; // Shift in the range of [0, 1]. // 0 => preview snapShot is completely visible, and hotseat is completely translated down @@ -112,19 +123,23 @@ public abstract class BaseSwipeUpHandler protected BaseSwipeUpHandler(Context context, OverviewComponentObserver overviewComponentObserver, - RecentsModel recentsModel, InputConsumerController inputConsumer) { + RecentsModel recentsModel, InputConsumerController inputConsumer, int runningTaskId) { mContext = context; mOverviewComponentObserver = overviewComponentObserver; mActivityControlHelper = overviewComponentObserver.getActivityControlHelper(); mRecentsModel = recentsModel; mActivityInitListener = mActivityControlHelper.createActivityInitListener(this::onActivityInit); + mRunningTaskId = runningTaskId; mRecentsAnimationWrapper = new RecentsAnimationWrapper(inputConsumer, this::createNewInputProxyHandler); + mMode = SysUINavigationMode.getMode(context); mClipAnimationHelper = new ClipAnimationHelper(context); mPageSpacing = context.getResources().getDimensionPixelSize(R.dimen.recents_page_spacing); mVibrator = context.getSystemService(Vibrator.class); + initTransitionEndpoints(InvariantDeviceProfile.INSTANCE.get(mContext) + .getDeviceProfile(mContext)); } protected void setStateOnUiThread(int stateFlag) { @@ -232,6 +247,65 @@ public abstract class BaseSwipeUpHandler TOUCH_INTERACTION_LOG.addLog("finishRecentsAnimation", true); } + @Override + public void onRecentsAnimationStart(SwipeAnimationTargetSet targetSet) { + DeviceProfile dp = InvariantDeviceProfile.INSTANCE.get(mContext).getDeviceProfile(mContext); + final Rect overviewStackBounds; + RemoteAnimationTargetCompat runningTaskTarget = targetSet.findTask(mRunningTaskId); + + if (targetSet.minimizedHomeBounds != null && runningTaskTarget != null) { + overviewStackBounds = mActivityControlHelper + .getOverviewWindowBounds(targetSet.minimizedHomeBounds, runningTaskTarget); + dp = dp.getMultiWindowProfile(mContext, new Point( + overviewStackBounds.width(), overviewStackBounds.height())); + } else { + // If we are not in multi-window mode, home insets should be same as system insets. + dp = dp.copy(mContext); + overviewStackBounds = getStackBounds(dp); + } + dp.updateInsets(targetSet.homeContentInsets); + dp.updateIsSeascape(mContext.getSystemService(WindowManager.class)); + if (runningTaskTarget != null) { + mClipAnimationHelper.updateSource(overviewStackBounds, runningTaskTarget); + } + + mClipAnimationHelper.prepareAnimation(dp, false /* isOpening */); + initTransitionEndpoints(dp); + + mRecentsAnimationWrapper.setController(targetSet); + } + + private Rect getStackBounds(DeviceProfile dp) { + if (mActivity != null) { + int loc[] = new int[2]; + View rootView = mActivity.getRootView(); + rootView.getLocationOnScreen(loc); + return new Rect(loc[0], loc[1], loc[0] + rootView.getWidth(), + loc[1] + rootView.getHeight()); + } else { + return new Rect(0, 0, dp.widthPx, dp.heightPx); + } + } + + protected void initTransitionEndpoints(DeviceProfile dp) { + mDp = dp; + + mTransitionDragLength = mActivityControlHelper.getSwipeUpDestinationAndLength( + dp, mContext, TEMP_RECT); + if (!dp.isMultiWindowMode) { + // When updating the target rect, also update the home bounds since the location on + // screen of the launcher window may be stale (position is not updated until first + // traversal after the window is resized). We only do this for non-multiwindow because + // we otherwise use the minimized home bounds provided by the system. + mClipAnimationHelper.updateHomeBounds(getStackBounds(dp)); + } + mClipAnimationHelper.updateTargetRect(TEMP_RECT); + if (mMode == Mode.NO_BUTTON) { + // We can drag all the way to the top of the screen. + mDragLengthFactor = (float) dp.heightPx / mTransitionDragLength; + } + } + /** * Return true if the window should be translated horizontally if the recents view scrolls */ diff --git a/quickstep/recents_ui_overrides/src/com/android/quickstep/RecentsActivity.java b/quickstep/recents_ui_overrides/src/com/android/quickstep/RecentsActivity.java index 61767e5f74..60e7b12ec4 100644 --- a/quickstep/recents_ui_overrides/src/com/android/quickstep/RecentsActivity.java +++ b/quickstep/recents_ui_overrides/src/com/android/quickstep/RecentsActivity.java @@ -87,12 +87,14 @@ public final class RecentsActivity extends BaseRecentsActivity { @Override protected void onNewIntent(Intent intent) { - int taskID = intent.getIntExtra(EXTRA_TASK_ID, 0); - IBinder thumbnail = intent.getExtras().getBinder(EXTRA_THUMBNAIL); - if (taskID != 0 && thumbnail instanceof ObjectWrapper) { - ThumbnailData thumbnailData = ((ObjectWrapper) thumbnail).get(); - mFallbackRecentsView.showCurrentTask(taskID); - mFallbackRecentsView.updateThumbnail(taskID, thumbnailData); + if (intent.getExtras() != null) { + int taskID = intent.getIntExtra(EXTRA_TASK_ID, 0); + IBinder thumbnail = intent.getExtras().getBinder(EXTRA_THUMBNAIL); + if (taskID != 0 && thumbnail instanceof ObjectWrapper) { + ThumbnailData thumbnailData = ((ObjectWrapper) thumbnail).get(); + mFallbackRecentsView.showCurrentTask(taskID); + mFallbackRecentsView.updateThumbnail(taskID, thumbnailData); + } } intent.removeExtra(EXTRA_TASK_ID); intent.removeExtra(EXTRA_THUMBNAIL); diff --git a/quickstep/recents_ui_overrides/src/com/android/quickstep/WindowTransformSwipeHandler.java b/quickstep/recents_ui_overrides/src/com/android/quickstep/WindowTransformSwipeHandler.java index ec16d881a5..d0332529be 100644 --- a/quickstep/recents_ui_overrides/src/com/android/quickstep/WindowTransformSwipeHandler.java +++ b/quickstep/recents_ui_overrides/src/com/android/quickstep/WindowTransformSwipeHandler.java @@ -48,9 +48,7 @@ import android.app.ActivityManager.RunningTaskInfo; import android.content.Context; import android.content.Intent; import android.graphics.Canvas; -import android.graphics.Point; import android.graphics.PointF; -import android.graphics.Rect; import android.graphics.RectF; import android.os.Build; import android.os.SystemClock; @@ -59,13 +57,11 @@ import android.view.View; import android.view.View.OnApplyWindowInsetsListener; import android.view.ViewTreeObserver.OnDrawListener; import android.view.WindowInsets; -import android.view.WindowManager; import android.view.animation.Interpolator; import com.android.launcher3.AbstractFloatingView; import com.android.launcher3.BaseDraggingActivity; import com.android.launcher3.DeviceProfile; -import com.android.launcher3.InvariantDeviceProfile; import com.android.launcher3.R; import com.android.launcher3.Utilities; import com.android.launcher3.anim.AnimationSuccessListener; @@ -106,8 +102,6 @@ public class WindowTransformSwipeHandler implements OnApplyWindowInsetsListener { private static final String TAG = WindowTransformSwipeHandler.class.getSimpleName(); - private static final Rect TEMP_RECT = new Rect(); - private static final String[] STATE_NAMES = DEBUG_STATES ? new String[16] : null; private static int getFlagForIndex(int index, String name) { @@ -220,9 +214,6 @@ public class WindowTransformSwipeHandler // To avoid UI jump when gesture is started, we offset the animation by the threshold. private float mShiftAtGestureStart = 0; - private final Mode mMode; - - private final int mRunningTaskId; private ThumbnailData mTaskSnapshot; // Used to control launcher components throughout the swipe gesture. @@ -248,16 +239,10 @@ public class WindowTransformSwipeHandler long touchTimeMs, OverviewComponentObserver overviewComponentObserver, boolean continuingLastGesture, InputConsumerController inputConsumer, RecentsModel recentsModel) { - super(context, overviewComponentObserver, recentsModel, inputConsumer); - mRunningTaskId = runningTaskInfo.id; + super(context, overviewComponentObserver, recentsModel, inputConsumer, runningTaskInfo.id); mTouchTimeMs = touchTimeMs; mContinuingLastGesture = continuingLastGesture; - - mMode = SysUINavigationMode.getMode(context); initStateCallbacks(); - - DeviceProfile dp = InvariantDeviceProfile.INSTANCE.get(mContext).getDeviceProfile(mContext); - initTransitionEndpoints(dp); } private void initStateCallbacks() { @@ -320,38 +305,6 @@ public class WindowTransformSwipeHandler } } - private Rect getStackBounds(DeviceProfile dp) { - if (mActivity != null) { - int loc[] = new int[2]; - View rootView = mActivity.getRootView(); - rootView.getLocationOnScreen(loc); - return new Rect(loc[0], loc[1], loc[0] + rootView.getWidth(), - loc[1] + rootView.getHeight()); - } else { - return new Rect(0, 0, dp.widthPx, dp.heightPx); - } - } - - private void initTransitionEndpoints(DeviceProfile dp) { - mDp = dp; - - Rect tempRect = new Rect(); - mTransitionDragLength = mActivityControlHelper.getSwipeUpDestinationAndLength( - dp, mContext, tempRect); - if (!dp.isMultiWindowMode) { - // When updating the target rect, also update the home bounds since the location on - // screen of the launcher window may be stale (position is not updated until first - // traversal after the window is resized). We only do this for non-multiwindow because - // we otherwise use the minimized home bounds provided by the system. - mClipAnimationHelper.updateHomeBounds(getStackBounds(dp)); - } - mClipAnimationHelper.updateTargetRect(tempRect); - if (mMode == Mode.NO_BUTTON) { - // We can drag all the way to the top of the screen. - mDragLengthFactor = (float) dp.heightPx / mTransitionDragLength; - } - } - @Override protected boolean onActivityInit(final T activity, Boolean alreadyOnHome) { if (mActivity == activity) { @@ -678,30 +631,7 @@ public class WindowTransformSwipeHandler @Override public void onRecentsAnimationStart(SwipeAnimationTargetSet targetSet) { - DeviceProfile dp = InvariantDeviceProfile.INSTANCE.get(mContext).getDeviceProfile(mContext); - final Rect overviewStackBounds; - RemoteAnimationTargetCompat runningTaskTarget = targetSet.findTask(mRunningTaskId); - - if (targetSet.minimizedHomeBounds != null && runningTaskTarget != null) { - overviewStackBounds = mActivityControlHelper - .getOverviewWindowBounds(targetSet.minimizedHomeBounds, runningTaskTarget); - dp = dp.getMultiWindowProfile(mContext, new Point( - targetSet.minimizedHomeBounds.width(), targetSet.minimizedHomeBounds.height())); - } else { - // If we are not in multi-window mode, home insets should be same as system insets. - dp = dp.copy(mContext); - overviewStackBounds = getStackBounds(dp); - } - dp.updateInsets(targetSet.homeContentInsets); - dp.updateIsSeascape(mContext.getSystemService(WindowManager.class)); - - if (runningTaskTarget != null) { - mClipAnimationHelper.updateSource(overviewStackBounds, runningTaskTarget); - } - mClipAnimationHelper.prepareAnimation(dp, false /* isOpening */); - initTransitionEndpoints(dp); - - mRecentsAnimationWrapper.setController(targetSet); + super.onRecentsAnimationStart(targetSet); TOUCH_INTERACTION_LOG.addLog("startRecentsAnimationCallback", targetSet.apps.length); setStateOnUiThread(STATE_APP_CONTROLLER_RECEIVED); diff --git a/quickstep/recents_ui_overrides/src/com/android/quickstep/inputconsumers/FallbackNoButtonInputConsumer.java b/quickstep/recents_ui_overrides/src/com/android/quickstep/inputconsumers/FallbackNoButtonInputConsumer.java index a0e806eee3..53e9461de6 100644 --- a/quickstep/recents_ui_overrides/src/com/android/quickstep/inputconsumers/FallbackNoButtonInputConsumer.java +++ b/quickstep/recents_ui_overrides/src/com/android/quickstep/inputconsumers/FallbackNoButtonInputConsumer.java @@ -31,11 +31,8 @@ import android.app.ActivityOptions; import android.content.Context; import android.content.Intent; import android.graphics.PointF; -import android.graphics.Rect; import android.os.Bundle; -import android.view.WindowManager; -import com.android.launcher3.InvariantDeviceProfile; import com.android.launcher3.R; import com.android.launcher3.anim.AnimationSuccessListener; import com.android.quickstep.AnimatedFloat; @@ -52,7 +49,6 @@ import com.android.quickstep.views.TaskView; import com.android.systemui.shared.recents.model.ThumbnailData; import com.android.systemui.shared.system.ActivityOptionsCompat; import com.android.systemui.shared.system.InputConsumerController; -import com.android.systemui.shared.system.RemoteAnimationTargetCompat; public class FallbackNoButtonInputConsumer extends BaseSwipeUpHandler { @@ -94,10 +90,6 @@ public class FallbackNoButtonInputConsumer extends BaseSwipeUpHandler mLauncherAlpha.value); initStateCallbacks(); - initTransitionTarget(); } private void initStateCallbacks() { @@ -376,33 +365,13 @@ public class FallbackNoButtonInputConsumer extends BaseSwipeUpHandler Date: Fri, 12 Jul 2019 14:19:18 -0700 Subject: [PATCH 044/108] Adding support for swipe operation when on home screen Bug: 137197916 Change-Id: Ic85bf9767d4a9a77dafc1c60c02555f3d2a5d8a2 --- .../android/quickstep/BaseSwipeUpHandler.java | 4 +- .../WindowTransformSwipeHandler.java | 3 +- .../fallback/FallbackRecentsView.java | 44 ++++++++++++++++ .../FallbackNoButtonInputConsumer.java | 51 ++++++++++++++++--- .../android/quickstep/views/RecentsView.java | 14 ++--- .../android/quickstep/RecentTasksList.java | 15 ++---- 6 files changed, 104 insertions(+), 27 deletions(-) diff --git a/quickstep/recents_ui_overrides/src/com/android/quickstep/BaseSwipeUpHandler.java b/quickstep/recents_ui_overrides/src/com/android/quickstep/BaseSwipeUpHandler.java index 23fe2dee10..72a9da6a36 100644 --- a/quickstep/recents_ui_overrides/src/com/android/quickstep/BaseSwipeUpHandler.java +++ b/quickstep/recents_ui_overrides/src/com/android/quickstep/BaseSwipeUpHandler.java @@ -70,7 +70,7 @@ import androidx.annotation.UiThread; * Base class for swipe up handler with some utility methods */ @TargetApi(Build.VERSION_CODES.Q) -public abstract class BaseSwipeUpHandler +public abstract class BaseSwipeUpHandler implements SwipeAnimationListener { private static final String TAG = "BaseSwipeUpHandler"; @@ -109,7 +109,7 @@ public abstract class BaseSwipeUpHandler protected final RecentsAnimationWrapper mRecentsAnimationWrapper; protected T mActivity; - protected RecentsView mRecentsView; + protected Q mRecentsView; protected DeviceProfile mDp; private final int mPageSpacing; diff --git a/quickstep/recents_ui_overrides/src/com/android/quickstep/WindowTransformSwipeHandler.java b/quickstep/recents_ui_overrides/src/com/android/quickstep/WindowTransformSwipeHandler.java index d0332529be..922f8e2c10 100644 --- a/quickstep/recents_ui_overrides/src/com/android/quickstep/WindowTransformSwipeHandler.java +++ b/quickstep/recents_ui_overrides/src/com/android/quickstep/WindowTransformSwipeHandler.java @@ -86,6 +86,7 @@ import com.android.quickstep.util.RectFSpringAnim; import com.android.quickstep.util.RemoteAnimationTargetSet; import com.android.quickstep.util.SwipeAnimationTargetSet; import com.android.quickstep.views.LiveTileOverlay; +import com.android.quickstep.views.RecentsView; import com.android.quickstep.views.TaskView; import com.android.systemui.shared.recents.model.ThumbnailData; import com.android.systemui.shared.system.InputConsumerController; @@ -98,7 +99,7 @@ import androidx.annotation.UiThread; @TargetApi(Build.VERSION_CODES.O) public class WindowTransformSwipeHandler - extends BaseSwipeUpHandler + extends BaseSwipeUpHandler implements OnApplyWindowInsetsListener { private static final String TAG = WindowTransformSwipeHandler.class.getSimpleName(); diff --git a/quickstep/recents_ui_overrides/src/com/android/quickstep/fallback/FallbackRecentsView.java b/quickstep/recents_ui_overrides/src/com/android/quickstep/fallback/FallbackRecentsView.java index eaf6ebac80..2e9c0a3c4d 100644 --- a/quickstep/recents_ui_overrides/src/com/android/quickstep/fallback/FallbackRecentsView.java +++ b/quickstep/recents_ui_overrides/src/com/android/quickstep/fallback/FallbackRecentsView.java @@ -17,6 +17,7 @@ package com.android.quickstep.fallback; import static com.android.launcher3.LauncherAnimUtils.SCALE_PROPERTY; +import android.app.ActivityManager.RunningTaskInfo; import android.content.Context; import android.graphics.Canvas; import android.graphics.Rect; @@ -31,6 +32,10 @@ import com.android.quickstep.RecentsActivity; import com.android.quickstep.util.LayoutUtils; import com.android.quickstep.views.RecentsView; import com.android.quickstep.views.TaskView; +import com.android.systemui.shared.recents.model.Task; +import com.android.systemui.shared.recents.model.Task.TaskKey; + +import java.util.ArrayList; public class FallbackRecentsView extends RecentsView { @@ -54,6 +59,8 @@ public class FallbackRecentsView extends RecentsView { private float mZoomScale = 1f; private float mZoomTranslationY = 0f; + private RunningTaskInfo mRunningTaskInfo; + public FallbackRecentsView(Context context, AttributeSet attrs) { this(context, attrs, 0); } @@ -151,4 +158,41 @@ public class FallbackRecentsView extends RecentsView { TRANSLATION_Y.set(this, Utilities.mapRange(mZoomInProgress, 0, mZoomTranslationY)); FULLSCREEN_PROGRESS.set(this, mZoomInProgress); } + + public void onGestureAnimationStart(RunningTaskInfo runningTaskInfo) { + mRunningTaskInfo = runningTaskInfo; + onGestureAnimationStart(runningTaskInfo == null ? -1 : runningTaskInfo.taskId); + } + + @Override + public void setCurrentTask(int runningTaskId) { + super.setCurrentTask(runningTaskId); + if (mRunningTaskInfo != null && mRunningTaskInfo.taskId != runningTaskId) { + mRunningTaskInfo = null; + } + } + + @Override + protected void applyLoadPlan(ArrayList tasks) { + // When quick-switching on 3p-launcher, we add a "dummy" tile corresponding to Launcher + // as well. This tile is never shown as we have setCurrentTaskHidden, but allows use to + // track the index of the next task appropriately, as it we are switching on any other app. + if (mRunningTaskInfo != null && mRunningTaskInfo.taskId == mRunningTaskId) { + // Check if the task list has running task + boolean found = false; + for (Task t : tasks) { + if (t.key.id == mRunningTaskId) { + found = true; + break; + } + } + if (!found) { + ArrayList newList = new ArrayList<>(tasks.size() + 1); + newList.addAll(tasks); + newList.add(Task.from(new TaskKey(mRunningTaskInfo), mRunningTaskInfo, false)); + tasks = newList; + } + } + super.applyLoadPlan(tasks); + } } diff --git a/quickstep/recents_ui_overrides/src/com/android/quickstep/inputconsumers/FallbackNoButtonInputConsumer.java b/quickstep/recents_ui_overrides/src/com/android/quickstep/inputconsumers/FallbackNoButtonInputConsumer.java index 53e9461de6..7abf62d351 100644 --- a/quickstep/recents_ui_overrides/src/com/android/quickstep/inputconsumers/FallbackNoButtonInputConsumer.java +++ b/quickstep/recents_ui_overrides/src/com/android/quickstep/inputconsumers/FallbackNoButtonInputConsumer.java @@ -47,10 +47,12 @@ import com.android.quickstep.util.ObjectWrapper; import com.android.quickstep.util.SwipeAnimationTargetSet; import com.android.quickstep.views.TaskView; import com.android.systemui.shared.recents.model.ThumbnailData; +import com.android.systemui.shared.system.ActivityManagerWrapper; import com.android.systemui.shared.system.ActivityOptionsCompat; import com.android.systemui.shared.system.InputConsumerController; -public class FallbackNoButtonInputConsumer extends BaseSwipeUpHandler { +public class FallbackNoButtonInputConsumer extends + BaseSwipeUpHandler { private static final String[] STATE_NAMES = DEBUG_STATES ? new String[5] : null; @@ -97,6 +99,11 @@ public class FallbackNoButtonInputConsumer extends BaseSwipeUpHandler mLauncherAlpha.value); + mRunningOverHome = ActivityManagerWrapper.isHomeTask(runningTaskInfo); + mSwipeUpOverHome = mRunningOverHome && !mInQuickSwitchMode; + + if (mSwipeUpOverHome) { + mClipAnimationHelper.setBaseAlphaCallback((t, a) -> 1 - mLauncherAlpha.value); + } else { + mClipAnimationHelper.setBaseAlphaCallback((t, a) -> mLauncherAlpha.value); + } + initStateCallbacks(); } @@ -149,10 +165,14 @@ public class FallbackNoButtonInputConsumer extends BaseSwipeUpHandler extends PagedView impl private int mTaskListChangeId = -1; // Only valid until the launcher state changes to NORMAL - private int mRunningTaskId = -1; + protected int mRunningTaskId = -1; private boolean mRunningTaskTileHidden; private Task mTmpRunningTask; @@ -532,7 +532,7 @@ public abstract class RecentsView extends PagedView impl return true; } - private void applyLoadPlan(ArrayList tasks) { + protected void applyLoadPlan(ArrayList tasks) { if (mPendingAnimation != null) { mPendingAnimation.addEndListener((onEndListener) -> applyLoadPlan(tasks)); return; @@ -855,12 +855,14 @@ public abstract class RecentsView extends PagedView impl * is called. Also scrolls the view to this task. */ public void showCurrentTask(int runningTaskId) { - if (getChildCount() == 0) { + if (getTaskView(runningTaskId) == null) { + boolean wasEmpty = getChildCount() == 0; // Add an empty view for now until the task plan is loaded and applied final TaskView taskView = mTaskViewPool.getView(); - addView(taskView); - addView(mClearAllButton); - + addView(taskView, 0); + if (wasEmpty) { + addView(mClearAllButton); + } // The temporary running task is only used for the duration between the start of the // gesture and the task list is loaded and applied mTmpRunningTask = new Task(new Task.TaskKey(runningTaskId, 0, new Intent(), diff --git a/quickstep/src/com/android/quickstep/RecentTasksList.java b/quickstep/src/com/android/quickstep/RecentTasksList.java index 7a1d0e83f6..d807b8973a 100644 --- a/quickstep/src/com/android/quickstep/RecentTasksList.java +++ b/quickstep/src/com/android/quickstep/RecentTasksList.java @@ -28,8 +28,6 @@ import com.android.launcher3.MainThreadExecutor; import com.android.systemui.shared.recents.model.Task; import com.android.systemui.shared.system.ActivityManagerWrapper; import com.android.systemui.shared.system.KeyguardManagerCompat; -import com.android.systemui.shared.system.RecentTaskInfoCompat; -import com.android.systemui.shared.system.TaskDescriptionCompat; import com.android.systemui.shared.system.TaskStackChangeListener; import java.util.ArrayList; import java.util.Collections; @@ -86,8 +84,9 @@ public class RecentTasksList extends TaskStackChangeListener { : () -> callback.accept(copyOf(mTasks)); if (mLastLoadedId == mChangeId && (!mLastLoadHadKeysOnly || loadKeysOnly)) { - // The list is up to date, callback with the same list - mMainThreadExecutor.execute(resultCallback); + // The list is up to date, send the callback on the next frame, + // so that requestID can be returned first. + mMainThreadExecutor.getHandler().post(resultCallback); return requestLoadId; } @@ -165,15 +164,11 @@ public class RecentTasksList extends TaskStackChangeListener { int taskCount = rawTasks.size(); for (int i = 0; i < taskCount; i++) { ActivityManager.RecentTaskInfo rawTask = rawTasks.get(i); - RecentTaskInfoCompat t = new RecentTaskInfoCompat(rawTask); Task.TaskKey taskKey = new Task.TaskKey(rawTask); Task task; if (!loadKeysOnly) { - ActivityManager.TaskDescription rawTd = t.getTaskDescription(); - TaskDescriptionCompat td = new TaskDescriptionCompat(rawTd); - boolean isLocked = tmpLockedUsers.get(t.getUserId()); - task = new Task(taskKey, td.getPrimaryColor(), td.getBackgroundColor(), - t.supportsSplitScreenMultiWindow(), isLocked, rawTd, t.getTopActivity()); + boolean isLocked = tmpLockedUsers.get(taskKey.userId); + task = Task.from(taskKey, rawTask, isLocked); } else { task = new Task(taskKey); } From 726cccf54a0cc6b7a2545b3554f9b338a9bb1df1 Mon Sep 17 00:00:00 2001 From: vadimt Date: Tue, 16 Jul 2019 11:19:01 -0700 Subject: [PATCH 045/108] Adding message popups to anomaly diagnoser Change-Id: I6bf125ad5c311062c8f2f6953c0a4d6155203672 --- .../android/launcher3/tapl/LauncherInstrumentation.java | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/tests/tapl/com/android/launcher3/tapl/LauncherInstrumentation.java b/tests/tapl/com/android/launcher3/tapl/LauncherInstrumentation.java index 0fed337a04..cc403d48f2 100644 --- a/tests/tapl/com/android/launcher3/tapl/LauncherInstrumentation.java +++ b/tests/tapl/com/android/launcher3/tapl/LauncherInstrumentation.java @@ -266,11 +266,17 @@ public final class LauncherInstrumentation { } private String getAnomalyMessage() { - final UiObject2 object = mDevice.findObject(By.res("android", "alertTitle")); + UiObject2 object = mDevice.findObject(By.res("android", "alertTitle")); if (object != null) { return "System alert popup is visible: " + object.getText(); } + object = mDevice.findObject(By.res("android", "message")); + if (object != null) { + return "Message popup by " + object.getApplicationPackage() + " is visible: " + + object.getText(); + } + if (hasSystemUiObject("keyguard_status_view")) return "Phone is locked"; if (!mDevice.hasObject(By.textStartsWith(""))) return "Screen is empty"; From 42bd7dad6c6bf5dd5011d0257de745f5a837248c Mon Sep 17 00:00:00 2001 From: Jon Miranda Date: Tue, 16 Jul 2019 13:49:03 -0700 Subject: [PATCH 046/108] Fix app open/close animation in RTL. Bug: 135165284 Change-Id: Ib50f213904cb7ac7c769fac04dbfc70005fe25b8 --- .../launcher3/views/FloatingIconView.java | 29 ++++++++++++++----- 1 file changed, 21 insertions(+), 8 deletions(-) diff --git a/src/com/android/launcher3/views/FloatingIconView.java b/src/com/android/launcher3/views/FloatingIconView.java index 4fdd83b657..e09a9e8bfc 100644 --- a/src/com/android/launcher3/views/FloatingIconView.java +++ b/src/com/android/launcher3/views/FloatingIconView.java @@ -18,6 +18,7 @@ package com.android.launcher3.views; import static com.android.launcher3.LauncherAnimUtils.DRAWABLE_ALPHA; import static com.android.launcher3.Utilities.getBadge; import static com.android.launcher3.Utilities.getFullDrawable; +import static com.android.launcher3.Utilities.isRtl; import static com.android.launcher3.Utilities.mapToRange; import static com.android.launcher3.anim.Interpolators.LINEAR; import static com.android.launcher3.config.FeatureFlags.ADAPTIVE_ICON_WINDOW_ANIM; @@ -129,6 +130,7 @@ public class FloatingIconView extends View implements private final Launcher mLauncher; private final int mBlurSizeOutline; + private final boolean mIsRtl; private boolean mIsVerticalBarLayout = false; private boolean mIsAdaptiveIcon = false; @@ -174,6 +176,7 @@ public class FloatingIconView extends View implements mLauncher = Launcher.getLauncher(context); mBlurSizeOutline = getResources().getDimensionPixelSize( R.dimen.blur_size_medium_outline); + mIsRtl = Utilities.isRtl(getResources()); mListenerView = new ListenerView(context, attrs); mFgSpringX = new SpringAnimation(this, mFgTransXProperty) @@ -213,7 +216,10 @@ public class FloatingIconView extends View implements setAlpha(alpha); LayoutParams lp = (LayoutParams) getLayoutParams(); - float dX = rect.left - lp.leftMargin; + float dX = mIsRtl + ? rect.left + - (mLauncher.getDeviceProfile().widthPx - lp.getMarginStart() - lp.width) + : rect.left - lp.getMarginStart(); float dY = rect.top - lp.topMargin; setTranslationX(dX); setTranslationY(dY); @@ -323,14 +329,18 @@ public class FloatingIconView extends View implements mPositionOut.set(position); lp.ignoreInsets = true; // Position the floating view exactly on top of the original - lp.leftMargin = Math.round(position.left); lp.topMargin = Math.round(position.top); - + if (mIsRtl) { + lp.setMarginStart(Math.round(mLauncher.getDeviceProfile().widthPx - position.right)); + } else { + lp.setMarginStart(Math.round(position.left)); + } // Set the properties here already to make sure they are available when running the first // animation frame. - layout(lp.leftMargin, lp.topMargin, lp.leftMargin + lp.width, lp.topMargin - + lp.height); - + int left = mIsRtl + ? mLauncher.getDeviceProfile().widthPx - lp.getMarginStart() - lp.width + : lp.leftMargin; + layout(left, lp.topMargin, left + lp.width, lp.topMargin + lp.height); } /** @@ -514,8 +524,11 @@ public class FloatingIconView extends View implements } else { lp.height = (int) Math.max(lp.height, lp.width * aspectRatio); } - layout(lp.leftMargin, lp.topMargin, lp.leftMargin + lp.width, lp.topMargin - + lp.height); + + int left = mIsRtl + ? mLauncher.getDeviceProfile().widthPx - lp.getMarginStart() - lp.width + : lp.leftMargin; + layout(left, lp.topMargin, left + lp.width, lp.topMargin + lp.height); float scale = Math.max((float) lp.height / originalHeight, (float) lp.width / originalWidth); From 2c7917d100fee33eb7817b065fc697f10d4b5b65 Mon Sep 17 00:00:00 2001 From: Vinit Nayak Date: Mon, 15 Jul 2019 13:56:41 -0700 Subject: [PATCH 047/108] Reload task list when task is removed Instead of individually removing tasks, ask for all tasks to get accurate list. This method is invoked whenever user presses back on a root activity, which causes the task to be killed from perspective of the activity. Test: Visually inspected, recent task no longer disappears. Open any app, hit back, and then go to overview quickly. App should remain in recents list. Fixes: 135687618 Change-Id: I1c135673ae987016db5df0b83f5ea8e345d3c7c1 (cherry picked from commit 8651219f7e41beee312b206eb543f35166d588f1) --- quickstep/src/com/android/quickstep/RecentTasksList.java | 7 +------ 1 file changed, 1 insertion(+), 6 deletions(-) diff --git a/quickstep/src/com/android/quickstep/RecentTasksList.java b/quickstep/src/com/android/quickstep/RecentTasksList.java index d807b8973a..e41dba94cc 100644 --- a/quickstep/src/com/android/quickstep/RecentTasksList.java +++ b/quickstep/src/com/android/quickstep/RecentTasksList.java @@ -119,12 +119,7 @@ public class RecentTasksList extends TaskStackChangeListener { @Override public void onTaskRemoved(int taskId) { - for (int i = mTasks.size() - 1; i >= 0; i--) { - if (mTasks.get(i).key.id == taskId) { - mTasks.remove(i); - return; - } - } + mTasks = loadTasksInBackground(Integer.MAX_VALUE, false); } @Override From 6a75e52f85c751b4b2832c312abd09e7812611e2 Mon Sep 17 00:00:00 2001 From: vadimt Date: Tue, 16 Jul 2019 16:19:58 -0700 Subject: [PATCH 048/108] Getting starting point of swipe from overview to all apps via protocol Change-Id: Idf04579b67011dac45b081a81367cde2d1274117 --- .../PortraitStatesTouchController.java | 7 +++++-- .../quickstep/QuickstepTestInformationHandler.java | 11 ++++++++++- .../android/launcher3/testing/TestProtocol.java | 1 + .../tapl/com/android/launcher3/tapl/Overview.java | 14 +++++++++----- 4 files changed, 25 insertions(+), 8 deletions(-) diff --git a/quickstep/src/com/android/launcher3/uioverrides/touchcontrollers/PortraitStatesTouchController.java b/quickstep/src/com/android/launcher3/uioverrides/touchcontrollers/PortraitStatesTouchController.java index 6030cea938..109d751c48 100644 --- a/quickstep/src/com/android/launcher3/uioverrides/touchcontrollers/PortraitStatesTouchController.java +++ b/quickstep/src/com/android/launcher3/uioverrides/touchcontrollers/PortraitStatesTouchController.java @@ -51,7 +51,6 @@ import com.android.quickstep.OverviewInteractionState; import com.android.quickstep.RecentsModel; import com.android.quickstep.TouchInteractionService; import com.android.quickstep.util.LayoutUtils; -import com.android.systemui.shared.system.QuickStepContract; /** * Touch controller for handling various state transitions in portrait UI. @@ -296,9 +295,13 @@ public class PortraitStatesTouchController extends AbstractStateChangeTouchContr * @return true if the event is over the hotseat */ static boolean isTouchOverHotseat(Launcher launcher, MotionEvent ev) { + return (ev.getY() >= getHotseatTop(launcher)); + } + + public static int getHotseatTop(Launcher launcher) { DeviceProfile dp = launcher.getDeviceProfile(); int hotseatHeight = dp.hotseatBarSizePx + dp.getInsets().bottom; - return (ev.getY() >= (launcher.getDragLayer().getHeight() - hotseatHeight)); + return launcher.getDragLayer().getHeight() - hotseatHeight; } private static class InterpolatorWrapper implements Interpolator { diff --git a/quickstep/src/com/android/quickstep/QuickstepTestInformationHandler.java b/quickstep/src/com/android/quickstep/QuickstepTestInformationHandler.java index b59e13362d..57ed244d2b 100644 --- a/quickstep/src/com/android/quickstep/QuickstepTestInformationHandler.java +++ b/quickstep/src/com/android/quickstep/QuickstepTestInformationHandler.java @@ -6,6 +6,7 @@ import android.os.Bundle; import com.android.launcher3.testing.TestInformationHandler; import com.android.launcher3.testing.TestProtocol; import com.android.launcher3.uioverrides.states.OverviewState; +import com.android.launcher3.uioverrides.touchcontrollers.PortraitStatesTouchController; import com.android.quickstep.util.LayoutUtils; public class QuickstepTestInformationHandler extends TestInformationHandler { @@ -34,7 +35,15 @@ public class QuickstepTestInformationHandler extends TestInformationHandler { case TestProtocol.REQUEST_IS_LAUNCHER_INITIALIZED: { response.putBoolean(TestProtocol.TEST_INFO_RESPONSE_FIELD, TouchInteractionService.isInputMonitorInitialized()); - break; + return response; + } + + case TestProtocol.REQUEST_HOTSEAT_TOP: { + if (mLauncher == null) return null; + + response.putInt(TestProtocol.TEST_INFO_RESPONSE_FIELD, + PortraitStatesTouchController.getHotseatTop(mLauncher)); + return response; } } diff --git a/src/com/android/launcher3/testing/TestProtocol.java b/src/com/android/launcher3/testing/TestProtocol.java index e28eba8094..f6a26925bc 100644 --- a/src/com/android/launcher3/testing/TestProtocol.java +++ b/src/com/android/launcher3/testing/TestProtocol.java @@ -66,6 +66,7 @@ public final class TestProtocol { "all-apps-to-overview-swipe-height"; public static final String REQUEST_HOME_TO_ALL_APPS_SWIPE_HEIGHT = "home-to-all-apps-swipe-height"; + public static final String REQUEST_HOTSEAT_TOP = "hotseat-top"; public static final String REQUEST_IS_LAUNCHER_INITIALIZED = "is-launcher-initialized"; public static final String REQUEST_FREEZE_APP_LIST = "freeze-app-list"; public static final String REQUEST_UNFREEZE_APP_LIST = "unfreeze-app-list"; diff --git a/tests/tapl/com/android/launcher3/tapl/Overview.java b/tests/tapl/com/android/launcher3/tapl/Overview.java index 058831f180..da68da3ba6 100644 --- a/tests/tapl/com/android/launcher3/tapl/Overview.java +++ b/tests/tapl/com/android/launcher3/tapl/Overview.java @@ -19,9 +19,9 @@ package com.android.launcher3.tapl; import static com.android.launcher3.testing.TestProtocol.ALL_APPS_STATE_ORDINAL; import androidx.annotation.NonNull; -import androidx.test.uiautomator.UiObject2; import com.android.launcher3.tapl.LauncherInstrumentation.ContainerType; +import com.android.launcher3.testing.TestProtocol; /** * Overview pane. @@ -51,11 +51,15 @@ public final class Overview extends BaseOverview { // Swipe from an app icon to the top. LauncherInstrumentation.log("Overview.switchToAllApps before swipe"); - final UiObject2 allApps = mLauncher.waitForLauncherObject("apps_view"); - mLauncher.swipeToState(mLauncher.getDevice().getDisplayWidth() / 2, - allApps.getVisibleBounds().top, + mLauncher.swipeToState( mLauncher.getDevice().getDisplayWidth() / 2, - 0, 50, ALL_APPS_STATE_ORDINAL); + mLauncher.getTestInfo( + TestProtocol.REQUEST_HOTSEAT_TOP). + getInt(TestProtocol.TEST_INFO_RESPONSE_FIELD), + mLauncher.getDevice().getDisplayWidth() / 2, + 0, + 50, + ALL_APPS_STATE_ORDINAL); try (LauncherInstrumentation.Closable c1 = mLauncher.addContextLayer( "swiped all way up from overview")) { From bf0042107c433de499e10b91a412b6c3e4a3bcbc Mon Sep 17 00:00:00 2001 From: vadimt Date: Tue, 16 Jul 2019 19:05:57 -0700 Subject: [PATCH 049/108] Temporarily disabling checking TouchInteractionService Change-Id: I953f251373f7bfb471eb203ee4ceda4375f17703 --- .../com/android/launcher3/tapl/LauncherInstrumentation.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/tapl/com/android/launcher3/tapl/LauncherInstrumentation.java b/tests/tapl/com/android/launcher3/tapl/LauncherInstrumentation.java index cc403d48f2..ec2107fb8a 100644 --- a/tests/tapl/com/android/launcher3/tapl/LauncherInstrumentation.java +++ b/tests/tapl/com/android/launcher3/tapl/LauncherInstrumentation.java @@ -396,7 +396,7 @@ public final class LauncherInstrumentation { } private UiObject2 verifyContainerType(ContainerType containerType) { - waitForTouchInteractionService(); + //waitForTouchInteractionService(); assertEquals("Unexpected display rotation", mExpectedRotation, mDevice.getDisplayRotation()); From 31d0a9c562c39b9feb8a75c89bde147a24a21e32 Mon Sep 17 00:00:00 2001 From: Anna Wasewicz Date: Thu, 11 Jul 2019 18:58:05 -0700 Subject: [PATCH 050/108] Set the chips flag to false in QP1A. This flag should be off by default. Chips should not be running in QP1A. Bug:137290162 Change-Id: I159e1bd00d1f9ff4f6cf63daf93a68e3e8d063c8 (cherry picked from commit 7400bb3f725d288766ddf9e9256327fcb90015c5) --- src/com/android/launcher3/config/BaseFlags.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/com/android/launcher3/config/BaseFlags.java b/src/com/android/launcher3/config/BaseFlags.java index 54efcb7868..45639e0a43 100644 --- a/src/com/android/launcher3/config/BaseFlags.java +++ b/src/com/android/launcher3/config/BaseFlags.java @@ -105,7 +105,7 @@ abstract class BaseFlags { "ENABLE_QUICKSTEP_LIVE_TILE", false, "Enable live tile in Quickstep overview"); public static final TogglableFlag ENABLE_HINTS_IN_OVERVIEW = new TogglableFlag( - "ENABLE_HINTS_IN_OVERVIEW", true, + "ENABLE_HINTS_IN_OVERVIEW", false, "Show chip hints and gleams on the overview screen"); public static final TogglableFlag FAKE_LANDSCAPE_UI = new TogglableFlag( From e88d8acd85a670272c2d619980658730e6c558c7 Mon Sep 17 00:00:00 2001 From: Sunny Goyal Date: Wed, 17 Jul 2019 11:38:59 -0700 Subject: [PATCH 051/108] Adding spring animation when swiping up to home in 3P Launcher Bug: 137197916 Change-Id: Ic9808a30e8cd4e0b2a221c4b03bc29489038e092 --- .../android/quickstep/BaseSwipeUpHandler.java | 119 ++++++++++++++++++ .../LauncherActivityControllerHelper.java | 8 +- .../WindowTransformSwipeHandler.java | 103 +-------------- .../FallbackNoButtonInputConsumer.java | 84 +++++++++---- .../quickstep/util/RectFSpringAnim.java | 2 +- .../quickstep/ActivityControlHelper.java | 10 ++ 6 files changed, 198 insertions(+), 128 deletions(-) diff --git a/quickstep/recents_ui_overrides/src/com/android/quickstep/BaseSwipeUpHandler.java b/quickstep/recents_ui_overrides/src/com/android/quickstep/BaseSwipeUpHandler.java index 72a9da6a36..e3d622f97e 100644 --- a/quickstep/recents_ui_overrides/src/com/android/quickstep/BaseSwipeUpHandler.java +++ b/quickstep/recents_ui_overrides/src/com/android/quickstep/BaseSwipeUpHandler.java @@ -19,12 +19,15 @@ import static android.os.VibrationEffect.EFFECT_CLICK; import static android.os.VibrationEffect.createPredefined; import static com.android.launcher3.Utilities.postAsyncCallback; +import static com.android.launcher3.anim.Interpolators.ACCEL_1_5; import static com.android.launcher3.anim.Interpolators.DEACCEL; import static com.android.launcher3.config.FeatureFlags.ENABLE_QUICKSTEP_LIVE_TILE; +import static com.android.launcher3.views.FloatingIconView.SHAPE_PROGRESS_DURATION; import static com.android.quickstep.TouchInteractionService.BACKGROUND_EXECUTOR; import static com.android.quickstep.TouchInteractionService.MAIN_THREAD_EXECUTOR; import static com.android.quickstep.TouchInteractionService.TOUCH_INTERACTION_LOG; +import android.animation.Animator; import android.annotation.TargetApi; import android.app.ActivityManager.RunningTaskInfo; import android.content.Context; @@ -32,6 +35,7 @@ import android.content.Intent; import android.graphics.Point; import android.graphics.PointF; import android.graphics.Rect; +import android.graphics.RectF; import android.os.Build; import android.os.Handler; import android.os.Looper; @@ -48,12 +52,19 @@ import com.android.launcher3.DeviceProfile; import com.android.launcher3.InvariantDeviceProfile; import com.android.launcher3.R; import com.android.launcher3.Utilities; +import com.android.launcher3.anim.AnimationSuccessListener; +import com.android.launcher3.anim.AnimatorPlaybackController; +import com.android.launcher3.anim.Interpolators; import com.android.launcher3.graphics.RotationMode; +import com.android.launcher3.views.FloatingIconView; import com.android.quickstep.ActivityControlHelper.ActivityInitListener; +import com.android.quickstep.ActivityControlHelper.HomeAnimationFactory; import com.android.quickstep.SysUINavigationMode.Mode; import com.android.quickstep.inputconsumers.InputConsumer; import com.android.quickstep.util.ClipAnimationHelper; import com.android.quickstep.util.ClipAnimationHelper.TransformParams; +import com.android.quickstep.util.RectFSpringAnim; +import com.android.quickstep.util.RemoteAnimationTargetSet; import com.android.quickstep.util.SwipeAnimationTargetSet; import com.android.quickstep.util.SwipeAnimationTargetSet.SwipeAnimationListener; import com.android.quickstep.views.RecentsView; @@ -369,9 +380,117 @@ public abstract class BaseSwipeUpHandler * @param startProgress The progress of {@link #mCurrentShift} to start the window from. * @param homeAnimationFactory The home animation factory. */ - private RectFSpringAnim createWindowAnimationToHome(float startProgress, + @Override + protected RectFSpringAnim createWindowAnimationToHome(float startProgress, HomeAnimationFactory homeAnimationFactory) { - final RemoteAnimationTargetSet targetSet = mRecentsAnimationWrapper.targetSet; - final RectF startRect = new RectF(mClipAnimationHelper.applyTransform(targetSet, - mTransformParams.setProgress(startProgress), false /* launcherOnTop */)); - final RectF targetRect = homeAnimationFactory.getWindowTargetRect(); - - final View floatingView = homeAnimationFactory.getFloatingView(); - final boolean isFloatingIconView = floatingView instanceof FloatingIconView; - RectFSpringAnim anim = new RectFSpringAnim(startRect, targetRect, mActivity.getResources()); - if (isFloatingIconView) { - FloatingIconView fiv = (FloatingIconView) floatingView; - anim.addAnimatorListener(fiv); - fiv.setOnTargetChangeListener(anim::onTargetPositionChanged); - } - - AnimatorPlaybackController homeAnim = homeAnimationFactory.createActivityAnimationToHome(); - - // End on a "round-enough" radius so that the shape reveal doesn't have to do too much - // rounding at the end of the animation. - float startRadius = mClipAnimationHelper.getCurrentCornerRadius(); - float endRadius = startRect.width() / 6f; - // We want the window alpha to be 0 once this threshold is met, so that the - // FolderIconView can be seen morphing into the icon shape. - final float windowAlphaThreshold = isFloatingIconView ? 1f - SHAPE_PROGRESS_DURATION : 1f; - anim.addOnUpdateListener(new RectFSpringAnim.OnUpdateListener() { - @Override - public void onUpdate(RectF currentRect, float progress) { - homeAnim.setPlayFraction(progress); - - float alphaProgress = ACCEL_1_5.getInterpolation(progress); - float windowAlpha = Utilities.boundToRange(Utilities.mapToRange(alphaProgress, 0, - windowAlphaThreshold, 1.5f, 0f, Interpolators.LINEAR), 0, 1); - mTransformParams.setProgress(progress) - .setCurrentRectAndTargetAlpha(currentRect, windowAlpha); - if (isFloatingIconView) { - mTransformParams.setCornerRadius(endRadius * progress + startRadius - * (1f - progress)); - } - mClipAnimationHelper.applyTransform(targetSet, mTransformParams, - false /* launcherOnTop */); - - if (isFloatingIconView) { - ((FloatingIconView) floatingView).update(currentRect, 1f, progress, - windowAlphaThreshold, mClipAnimationHelper.getCurrentCornerRadius(), false); - } - - updateSysUiFlags(Math.max(progress, mCurrentShift.value)); - } - - @Override - public void onCancel() { - if (isFloatingIconView) { - ((FloatingIconView) floatingView).fastFinish(); - } - } - }); + RectFSpringAnim anim = + super.createWindowAnimationToHome(startProgress, homeAnimationFactory); + anim.addOnUpdateListener((r, p) -> updateSysUiFlags(Math.max(p, mCurrentShift.value))); anim.addAnimatorListener(new AnimationSuccessListener() { @Override public void onAnimationStart(Animator animation) { - homeAnim.dispatchOnStart(); if (mActivity != null) { mActivity.getRootView().getOverlay().remove(mLiveTileOverlay); } @@ -1036,7 +978,6 @@ public class WindowTransformSwipeHandler @Override public void onAnimationSuccess(Animator animator) { - homeAnim.getAnimationPlayer().end(); if (mRecentsView != null) { mRecentsView.post(mRecentsView::resetTaskVisuals); } @@ -1270,38 +1211,4 @@ public class WindowTransformSwipeHandler return app.isNotInRecents || app.activityType == RemoteAnimationTargetCompat.ACTIVITY_TYPE_HOME; } - - private interface RunningWindowAnim { - void end(); - - void cancel(); - - static RunningWindowAnim wrap(Animator animator) { - return new RunningWindowAnim() { - @Override - public void end() { - animator.end(); - } - - @Override - public void cancel() { - animator.cancel(); - } - }; - } - - static RunningWindowAnim wrap(RectFSpringAnim rectFSpringAnim) { - return new RunningWindowAnim() { - @Override - public void end() { - rectFSpringAnim.end(); - } - - @Override - public void cancel() { - rectFSpringAnim.cancel(); - } - }; - } - } } diff --git a/quickstep/recents_ui_overrides/src/com/android/quickstep/inputconsumers/FallbackNoButtonInputConsumer.java b/quickstep/recents_ui_overrides/src/com/android/quickstep/inputconsumers/FallbackNoButtonInputConsumer.java index 7abf62d351..631c34c22d 100644 --- a/quickstep/recents_ui_overrides/src/com/android/quickstep/inputconsumers/FallbackNoButtonInputConsumer.java +++ b/quickstep/recents_ui_overrides/src/com/android/quickstep/inputconsumers/FallbackNoButtonInputConsumer.java @@ -18,11 +18,12 @@ package com.android.quickstep.inputconsumers; import static com.android.quickstep.MultiStateCallback.DEBUG_STATES; import static com.android.quickstep.RecentsActivity.EXTRA_TASK_ID; import static com.android.quickstep.RecentsActivity.EXTRA_THUMBNAIL; -import static com.android.quickstep.inputconsumers.FallbackNoButtonInputConsumer.GestureEndTarget.NEW_TASK; import static com.android.quickstep.WindowTransformSwipeHandler.MIN_PROGRESS_FOR_OVERVIEW; import static com.android.quickstep.inputconsumers.FallbackNoButtonInputConsumer.GestureEndTarget.HOME; import static com.android.quickstep.inputconsumers.FallbackNoButtonInputConsumer.GestureEndTarget.LAST_TASK; +import static com.android.quickstep.inputconsumers.FallbackNoButtonInputConsumer.GestureEndTarget.NEW_TASK; import static com.android.quickstep.inputconsumers.FallbackNoButtonInputConsumer.GestureEndTarget.RECENTS; +import static com.android.quickstep.views.RecentsView.UPDATE_SYSUI_FLAGS_THRESHOLD; import android.animation.Animator; import android.animation.AnimatorSet; @@ -31,10 +32,13 @@ import android.app.ActivityOptions; import android.content.Context; import android.content.Intent; import android.graphics.PointF; +import android.graphics.RectF; import android.os.Bundle; import com.android.launcher3.R; import com.android.launcher3.anim.AnimationSuccessListener; +import com.android.launcher3.anim.AnimatorPlaybackController; +import com.android.quickstep.ActivityControlHelper.HomeAnimationFactory; import com.android.quickstep.AnimatedFloat; import com.android.quickstep.BaseSwipeUpHandler; import com.android.quickstep.MultiStateCallback; @@ -44,6 +48,7 @@ import com.android.quickstep.RecentsModel; import com.android.quickstep.SwipeSharedState; import com.android.quickstep.fallback.FallbackRecentsView; import com.android.quickstep.util.ObjectWrapper; +import com.android.quickstep.util.RectFSpringAnim; import com.android.quickstep.util.SwipeAnimationTargetSet; import com.android.quickstep.views.TaskView; import com.android.systemui.shared.recents.model.ThumbnailData; @@ -102,10 +107,10 @@ public class FallbackNoButtonInputConsumer extends private final boolean mRunningOverHome; private final boolean mSwipeUpOverHome; - private final RunningTaskInfo mRunningTaskInfo; - private Animator mFinishAnimation; + private final PointF mEndVelocityPxPerMs = new PointF(0, 0.5f); + private RunningWindowAnim mFinishAnimation; public FallbackNoButtonInputConsumer(Context context, OverviewComponentObserver overviewComponentObserver, @@ -226,6 +231,8 @@ public class FallbackNoButtonInputConsumer extends @Override public void updateFinalShift() { mTransformParams.setProgress(mCurrentShift.value); + mRecentsAnimationWrapper.setWindowThresholdCrossed(!mInQuickSwitchMode + && (mCurrentShift.value > 1 - UPDATE_SYSUI_FLAGS_THRESHOLD)); if (mRecentsAnimationWrapper.targetSet != null) { applyTransformUnchecked(); } @@ -240,6 +247,7 @@ public class FallbackNoButtonInputConsumer extends @Override public void onGestureEnded(float endVelocity, PointF velocity, PointF downPos) { + mEndVelocityPxPerMs.set(0, velocity.y / 1000); if (mInQuickSwitchMode) { // For now set it to non-null, it will be reset before starting the animation mEndTarget = LAST_TASK; @@ -288,12 +296,14 @@ public class FallbackNoButtonInputConsumer extends } } - private void onHandlerInvalidated() { mActivityInitListener.unregister(); if (mGestureEndCallback != null) { mGestureEndCallback.run(); } + if (mFinishAnimation != null) { + mFinishAnimation.end(); + } } private void onHandlerInvalidatedWithRecents() { @@ -364,31 +374,39 @@ public class FallbackNoButtonInputConsumer extends } float endProgress = mEndTarget.mEndProgress; - + long duration = (long) (mEndTarget.mDurationMultiplier * + Math.abs(endProgress - mCurrentShift.value)); + if (mRecentsView != null) { + duration = Math.max(duration, mRecentsView.getScroller().getDuration()); + } if (mCurrentShift.value != endProgress || mInQuickSwitchMode) { - AnimatorSet anim = new AnimatorSet(); - anim.play(mLauncherAlpha.animateToValue( - mLauncherAlpha.value, mEndTarget.mLauncherAlpha)); - anim.play(mCurrentShift.animateToValue(mCurrentShift.value, endProgress)); - - - long duration = (long) (mEndTarget.mDurationMultiplier * - Math.abs(endProgress - mCurrentShift.value)); - if (mRecentsView != null) { - duration = Math.max(duration, mRecentsView.getScroller().getDuration()); - } - - anim.setDuration(duration); - anim.addListener(new AnimationSuccessListener() { + AnimationSuccessListener endListener = new AnimationSuccessListener() { @Override public void onAnimationSuccess(Animator animator) { finishAnimationTargetSetAnimationComplete(); mFinishAnimation = null; } - }); - anim.start(); - mFinishAnimation = anim; + }; + + if (mEndTarget == HOME && !mRunningOverHome) { + RectFSpringAnim anim = createWindowAnimationToHome(mCurrentShift.value, duration); + anim.addAnimatorListener(endListener); + anim.start(mEndVelocityPxPerMs); + mFinishAnimation = RunningWindowAnim.wrap(anim); + } else { + + AnimatorSet anim = new AnimatorSet(); + anim.play(mLauncherAlpha.animateToValue( + mLauncherAlpha.value, mEndTarget.mLauncherAlpha)); + anim.play(mCurrentShift.animateToValue(mCurrentShift.value, endProgress)); + + anim.setDuration(duration); + anim.addListener(endListener); + anim.start(); + mFinishAnimation = RunningWindowAnim.wrap(anim); + } + } else { finishAnimationTargetSetAnimationComplete(); } @@ -412,4 +430,26 @@ public class FallbackNoButtonInputConsumer extends mRecentsAnimationWrapper.setController(null); setStateOnUiThread(STATE_HANDLER_INVALIDATED); } + + /** + * Creates an animation that transforms the current app window into the home app. + * @param startProgress The progress of {@link #mCurrentShift} to start the window from. + */ + private RectFSpringAnim createWindowAnimationToHome(float startProgress, long duration) { + HomeAnimationFactory factory = new HomeAnimationFactory() { + @Override + public RectF getWindowTargetRect() { + return HomeAnimationFactory.getDefaultWindowTargetRect(mDp); + } + + @Override + public AnimatorPlaybackController createActivityAnimationToHome() { + AnimatorSet anim = new AnimatorSet(); + anim.play(mLauncherAlpha.animateToValue(mLauncherAlpha.value, 1)); + anim.setDuration(duration); + return AnimatorPlaybackController.wrap(anim, duration); + } + }; + return createWindowAnimationToHome(startProgress, factory); + } } diff --git a/quickstep/recents_ui_overrides/src/com/android/quickstep/util/RectFSpringAnim.java b/quickstep/recents_ui_overrides/src/com/android/quickstep/util/RectFSpringAnim.java index 9c5cf2042b..c6eafe6a64 100644 --- a/quickstep/recents_ui_overrides/src/com/android/quickstep/util/RectFSpringAnim.java +++ b/quickstep/recents_ui_overrides/src/com/android/quickstep/util/RectFSpringAnim.java @@ -237,6 +237,6 @@ public class RectFSpringAnim { public interface OnUpdateListener { void onUpdate(RectF currentRect, float progress); - void onCancel(); + default void onCancel() { } } } diff --git a/quickstep/src/com/android/quickstep/ActivityControlHelper.java b/quickstep/src/com/android/quickstep/ActivityControlHelper.java index cd2c9cb1bf..5c9c7d4cab 100644 --- a/quickstep/src/com/android/quickstep/ActivityControlHelper.java +++ b/quickstep/src/com/android/quickstep/ActivityControlHelper.java @@ -152,5 +152,15 @@ public interface ActivityControlHelper { default void playAtomicAnimation(float velocity) { // No-op } + + static RectF getDefaultWindowTargetRect(DeviceProfile dp) { + final int halfIconSize = dp.iconSizePx / 2; + final float targetCenterX = dp.availableWidthPx / 2f; + final float targetCenterY = dp.availableHeightPx - dp.hotseatBarSizePx; + // Fallback to animate to center of screen. + return new RectF(targetCenterX - halfIconSize, targetCenterY - halfIconSize, + targetCenterX + halfIconSize, targetCenterY + halfIconSize); + } + } } From 20d6a27608146c013cf8da1413d828a5cf52bb80 Mon Sep 17 00:00:00 2001 From: Winson Chung Date: Wed, 17 Jul 2019 11:42:16 -0700 Subject: [PATCH 052/108] Use non-android package name for context creation - Speculative fix for mismatch between navigation mode reported to the tests vs. what mode the device is in based on the bug report. Original change to the package name was in ag/6866716 Bug: 136033787 Change-Id: I51f964daa8c42b671733cf3fab19d086e19a9063 --- .../com/android/launcher3/tapl/LauncherInstrumentation.java | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/tests/tapl/com/android/launcher3/tapl/LauncherInstrumentation.java b/tests/tapl/com/android/launcher3/tapl/LauncherInstrumentation.java index cc403d48f2..831726b8a5 100644 --- a/tests/tapl/com/android/launcher3/tapl/LauncherInstrumentation.java +++ b/tests/tapl/com/android/launcher3/tapl/LauncherInstrumentation.java @@ -208,7 +208,7 @@ public final class LauncherInstrumentation { try { // Workaround, use constructed context because both the instrumentation context and the // app context are not constructed with resources that take overlays into account - final Context ctx = baseContext.createPackageContext("android", 0); + final Context ctx = baseContext.createPackageContext(getLauncherPackageName(), 0); for (int i = 0; i < 100; ++i) { final int currentInteractionMode = getCurrentInteractionMode(ctx); final NavigationModel model = getNavigationModel(currentInteractionMode); @@ -918,7 +918,7 @@ public final class LauncherInstrumentation { int getEdgeSensitivityWidth() { try { final Context context = mInstrumentation.getTargetContext().createPackageContext( - "android", 0); + getLauncherPackageName(), 0); return context.getResources().getDimensionPixelSize( getSystemDimensionResId(context, "config_backGestureInset")) + 1; } catch (PackageManager.NameNotFoundException e) { From bc2782647803d2a8942311f917d66a91bdc24d8d Mon Sep 17 00:00:00 2001 From: Jon Miranda Date: Tue, 2 Jul 2019 14:35:11 -0700 Subject: [PATCH 053/108] Fix bug where icon is no present during app close animation. * WindowTransformSwipeHandler closes all AbstractFloatingViews, including ListenerView, which results in FloatingIconView getting removed. * In IconLoadResult.onIconLoaded, we remove the check for isIconLoaded since its not needed. This was also causing a race condition since isIconLoaded is not set to true until after we tell onIconLoaded to run. * In BaseDragLayer, we have a delay before checking if the view is open and then closing the floating view if true. This caused issues since we reycle the view. Now we check if the view is open before running the delay to call close. Bug: 136044361 Change-Id: I7442a589a62c3cdf90b70d146e0ecf3e4300ddf7 (cherry picked from commit 826cdcd32fa91afe932c8c07be1a4e92a6f73301) --- .../android/quickstep/WindowTransformSwipeHandler.java | 3 ++- src/com/android/launcher3/views/BaseDragLayer.java | 10 ++++------ src/com/android/launcher3/views/FloatingIconView.java | 10 +++++----- 3 files changed, 11 insertions(+), 12 deletions(-) diff --git a/quickstep/recents_ui_overrides/src/com/android/quickstep/WindowTransformSwipeHandler.java b/quickstep/recents_ui_overrides/src/com/android/quickstep/WindowTransformSwipeHandler.java index f1d1141bcd..ac7ba3fc3d 100644 --- a/quickstep/recents_ui_overrides/src/com/android/quickstep/WindowTransformSwipeHandler.java +++ b/quickstep/recents_ui_overrides/src/com/android/quickstep/WindowTransformSwipeHandler.java @@ -505,7 +505,8 @@ public class WindowTransformSwipeHandler initAnimFactory.run(); } } - AbstractFloatingView.closeAllOpenViews(activity, mWasLauncherAlreadyVisible); + AbstractFloatingView.closeAllOpenViewsExcept(activity, mWasLauncherAlreadyVisible, + AbstractFloatingView.TYPE_LISTENER); if (mWasLauncherAlreadyVisible) { mStateCallback.setState(STATE_LAUNCHER_DRAWN); diff --git a/src/com/android/launcher3/views/BaseDragLayer.java b/src/com/android/launcher3/views/BaseDragLayer.java index c1ba780503..15f2724708 100644 --- a/src/com/android/launcher3/views/BaseDragLayer.java +++ b/src/com/android/launcher3/views/BaseDragLayer.java @@ -221,12 +221,10 @@ public abstract class BaseDragLayer if (child instanceof AbstractFloatingView) { // Handles the case where the view is removed without being properly closed. // This can happen if something goes wrong during a state change/transition. - postDelayed(() -> { - AbstractFloatingView floatingView = (AbstractFloatingView) child; - if (floatingView.isOpen()) { - floatingView.close(false); - } - }, SINGLE_FRAME_MS); + AbstractFloatingView floatingView = (AbstractFloatingView) child; + if (floatingView.isOpen()) { + postDelayed(() -> floatingView.close(false), SINGLE_FRAME_MS); + } } } diff --git a/src/com/android/launcher3/views/FloatingIconView.java b/src/com/android/launcher3/views/FloatingIconView.java index b6c4fedac9..ab4b576bf9 100644 --- a/src/com/android/launcher3/views/FloatingIconView.java +++ b/src/com/android/launcher3/views/FloatingIconView.java @@ -574,17 +574,17 @@ public class FloatingIconView extends View implements if (cancellationSignal.isCanceled()) { return; } - if (mIconLoadResult.isIconLoaded) { - setIcon(originalView, mIconLoadResult.drawable, mIconLoadResult.badge, - mIconLoadResult.iconOffset); - } + + setIcon(originalView, mIconLoadResult.drawable, mIconLoadResult.badge, + mIconLoadResult.iconOffset); + // Delay swapping views until the icon is loaded to prevent a flash. setVisibility(VISIBLE); originalView.setVisibility(INVISIBLE); }; + mLoadIconSignal = cancellationSignal; } } - mLoadIconSignal = cancellationSignal; } private void setBackgroundDrawableBounds(float scale) { From 2f7d1fa4a80f8f805f0e64c353b891bf6c612f70 Mon Sep 17 00:00:00 2001 From: vadimt Date: Wed, 17 Jul 2019 14:03:45 -0700 Subject: [PATCH 054/108] Using correct gesture margins in overview Change-Id: I0108858279559e10633825f7de22211515f0e9b7 --- .../QuickstepTestInformationHandler.java | 31 +++++++++++++++++++ .../android/quickstep/views/RecentsView.java | 11 +++++++ .../launcher3/testing/TestProtocol.java | 2 ++ .../android/launcher3/tapl/BaseOverview.java | 15 ++++++--- 4 files changed, 54 insertions(+), 5 deletions(-) rename quickstep/{ => recents_ui_overrides}/src/com/android/quickstep/QuickstepTestInformationHandler.java (58%) diff --git a/quickstep/src/com/android/quickstep/QuickstepTestInformationHandler.java b/quickstep/recents_ui_overrides/src/com/android/quickstep/QuickstepTestInformationHandler.java similarity index 58% rename from quickstep/src/com/android/quickstep/QuickstepTestInformationHandler.java rename to quickstep/recents_ui_overrides/src/com/android/quickstep/QuickstepTestInformationHandler.java index 57ed244d2b..b507044e0a 100644 --- a/quickstep/src/com/android/quickstep/QuickstepTestInformationHandler.java +++ b/quickstep/recents_ui_overrides/src/com/android/quickstep/QuickstepTestInformationHandler.java @@ -3,11 +3,15 @@ package com.android.quickstep; import android.content.Context; import android.os.Bundle; +import com.android.launcher3.MainThreadExecutor; import com.android.launcher3.testing.TestInformationHandler; import com.android.launcher3.testing.TestProtocol; import com.android.launcher3.uioverrides.states.OverviewState; import com.android.launcher3.uioverrides.touchcontrollers.PortraitStatesTouchController; import com.android.quickstep.util.LayoutUtils; +import com.android.quickstep.views.RecentsView; + +import java.util.concurrent.ExecutionException; public class QuickstepTestInformationHandler extends TestInformationHandler { @@ -45,6 +49,33 @@ public class QuickstepTestInformationHandler extends TestInformationHandler { PortraitStatesTouchController.getHotseatTop(mLauncher)); return response; } + + case TestProtocol.REQUEST_OVERVIEW_LEFT_GESTURE_MARGIN: { + try { + final int leftMargin = new MainThreadExecutor().submit(() -> + mLauncher.getOverviewPanel().getLeftGestureMargin()).get(); + response.putInt(TestProtocol.TEST_INFO_RESPONSE_FIELD, leftMargin); + } catch (ExecutionException e) { + e.printStackTrace(); + } catch (InterruptedException e) { + e.printStackTrace(); + } + return response; + } + + case TestProtocol.REQUEST_OVERVIEW_RIGHT_GESTURE_MARGIN: { + try { + final int rightMargin = new MainThreadExecutor().submit(() -> + mLauncher.getOverviewPanel().getRightGestureMargin()). + get(); + response.putInt(TestProtocol.TEST_INFO_RESPONSE_FIELD, rightMargin); + } catch (ExecutionException e) { + e.printStackTrace(); + } catch (InterruptedException e) { + e.printStackTrace(); + } + return response; + } } return super.call(method); diff --git a/quickstep/recents_ui_overrides/src/com/android/quickstep/views/RecentsView.java b/quickstep/recents_ui_overrides/src/com/android/quickstep/views/RecentsView.java index 66ddc727f5..b566837da6 100644 --- a/quickstep/recents_ui_overrides/src/com/android/quickstep/views/RecentsView.java +++ b/quickstep/recents_ui_overrides/src/com/android/quickstep/views/RecentsView.java @@ -73,6 +73,7 @@ import android.view.MotionEvent; import android.view.View; import android.view.ViewDebug; import android.view.ViewGroup; +import android.view.WindowInsets; import android.view.accessibility.AccessibilityEvent; import android.view.accessibility.AccessibilityNodeInfo; import android.widget.ListView; @@ -1742,4 +1743,14 @@ public abstract class RecentsView extends PagedView impl updateEnabledOverlays(); } } + + public int getLeftGestureMargin() { + final WindowInsets insets = getRootWindowInsets(); + return Math.max(insets.getSystemGestureInsets().left, insets.getSystemWindowInsetLeft()); + } + + public int getRightGestureMargin() { + final WindowInsets insets = getRootWindowInsets(); + return Math.max(insets.getSystemGestureInsets().right, insets.getSystemWindowInsetRight()); + } } diff --git a/src/com/android/launcher3/testing/TestProtocol.java b/src/com/android/launcher3/testing/TestProtocol.java index f69b278963..079ab6d8fe 100644 --- a/src/com/android/launcher3/testing/TestProtocol.java +++ b/src/com/android/launcher3/testing/TestProtocol.java @@ -71,6 +71,8 @@ public final class TestProtocol { public static final String REQUEST_FREEZE_APP_LIST = "freeze-app-list"; public static final String REQUEST_UNFREEZE_APP_LIST = "unfreeze-app-list"; public static final String REQUEST_APP_LIST_FREEZE_FLAGS = "app-list-freeze-flags"; + public static final String REQUEST_OVERVIEW_LEFT_GESTURE_MARGIN = "overview-left-margin"; + public static final String REQUEST_OVERVIEW_RIGHT_GESTURE_MARGIN = "overview-right-margin"; public static boolean sDebugTracing = false; public static final String REQUEST_ENABLE_DEBUG_TRACING = "enable-debug-tracing"; diff --git a/tests/tapl/com/android/launcher3/tapl/BaseOverview.java b/tests/tapl/com/android/launcher3/tapl/BaseOverview.java index ae93867191..04a0f12714 100644 --- a/tests/tapl/com/android/launcher3/tapl/BaseOverview.java +++ b/tests/tapl/com/android/launcher3/tapl/BaseOverview.java @@ -23,6 +23,8 @@ import androidx.test.uiautomator.BySelector; import androidx.test.uiautomator.Direction; import androidx.test.uiautomator.UiObject2; +import com.android.launcher3.testing.TestProtocol; + import java.util.Collections; import java.util.List; @@ -30,7 +32,6 @@ import java.util.List; * Common overview pane for both Launcher and fallback recents */ public class BaseOverview extends LauncherInstrumentation.VisibleContainer { - private static final int FLING_SPEED = LauncherInstrumentation.isAvd() ? 500 : 1500; private static final int FLINGS_FOR_DISMISS_LIMIT = 40; BaseOverview(LauncherInstrumentation launcher) { @@ -51,8 +52,10 @@ public class BaseOverview extends LauncherInstrumentation.VisibleContainer { mLauncher.addContextLayer("want to fling forward in overview")) { LauncherInstrumentation.log("Overview.flingForward before fling"); final UiObject2 overview = verifyActiveContainer(); - mLauncher.scroll(overview, Direction.LEFT, 1, - new Rect(mLauncher.getEdgeSensitivityWidth(), 0, 0, 0), 20); + final int leftMargin = mLauncher.getTestInfo( + TestProtocol.REQUEST_OVERVIEW_LEFT_GESTURE_MARGIN). + getInt(TestProtocol.TEST_INFO_RESPONSE_FIELD); + mLauncher.scroll(overview, Direction.LEFT, 1, new Rect(leftMargin, 0, 0, 0), 20); verifyActiveContainer(); } } @@ -87,8 +90,10 @@ public class BaseOverview extends LauncherInstrumentation.VisibleContainer { mLauncher.addContextLayer("want to fling backward in overview")) { LauncherInstrumentation.log("Overview.flingBackward before fling"); final UiObject2 overview = verifyActiveContainer(); - mLauncher.scroll(overview, Direction.RIGHT, 1, - new Rect(0, 0, mLauncher.getEdgeSensitivityWidth(), 0), 20); + final int rightMargin = mLauncher.getTestInfo( + TestProtocol.REQUEST_OVERVIEW_RIGHT_GESTURE_MARGIN). + getInt(TestProtocol.TEST_INFO_RESPONSE_FIELD); + mLauncher.scroll(overview, Direction.RIGHT, 1, new Rect(0, 0, rightMargin, 0), 20); verifyActiveContainer(); } } From ae86d22dfb6d365b52bd1465a1b3f2811d721882 Mon Sep 17 00:00:00 2001 From: Hyunyoung Song Date: Wed, 17 Jul 2019 17:04:40 -0700 Subject: [PATCH 055/108] Guard against NPE inside BaseIconFactory Bug: 137253043 This is a bandage fix. Ideally, we should really figure out why TaskIconCache will be sending null icon drawable to BaseIconFactory. Change-Id: Ie005006baeddc9a3379283fe7139e590daad9a57 --- .../com/android/launcher3/icons/BaseIconFactory.java | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) diff --git a/iconloaderlib/src/com/android/launcher3/icons/BaseIconFactory.java b/iconloaderlib/src/com/android/launcher3/icons/BaseIconFactory.java index db5515b741..fc7d6b329f 100644 --- a/iconloaderlib/src/com/android/launcher3/icons/BaseIconFactory.java +++ b/iconloaderlib/src/com/android/launcher3/icons/BaseIconFactory.java @@ -22,6 +22,7 @@ import android.graphics.drawable.Drawable; import android.os.Build; import android.os.Process; import android.os.UserHandle; +import androidx.annotation.NonNull; /** * This class will be moved to androidx library. There shouldn't be any dependency outside @@ -154,7 +155,7 @@ public class BaseIconFactory implements AutoCloseable { * @param scale returns the scale result from normalization * @return a bitmap suitable for disaplaying as an icon at various system UIs. */ - public BitmapInfo createBadgedIconBitmap(Drawable icon, UserHandle user, + public BitmapInfo createBadgedIconBitmap(@NonNull Drawable icon, UserHandle user, boolean shrinkNonAdaptiveIcons, boolean isInstantApp, float[] scale) { if (scale == null) { scale = new float[1]; @@ -207,8 +208,11 @@ public class BaseIconFactory implements AutoCloseable { mDisableColorExtractor = true; } - private Drawable normalizeAndWrapToAdaptiveIcon(Drawable icon, boolean shrinkNonAdaptiveIcons, - RectF outIconBounds, float[] outScale) { + private Drawable normalizeAndWrapToAdaptiveIcon(@NonNull Drawable icon, + boolean shrinkNonAdaptiveIcons, RectF outIconBounds, float[] outScale) { + if (icon == null) { + return null; + } float scale = 1f; if (shrinkNonAdaptiveIcons && ATLEAST_OREO) { @@ -264,7 +268,7 @@ public class BaseIconFactory implements AutoCloseable { * @param icon drawable that should be flattened to a bitmap * @param scale the scale to apply before drawing {@param icon} on the canvas */ - public Bitmap createIconBitmap(Drawable icon, float scale, int size) { + public Bitmap createIconBitmap(@NonNull Drawable icon, float scale, int size) { Bitmap bitmap = Bitmap.createBitmap(size, size, Bitmap.Config.ARGB_8888); if (icon == null) { return bitmap; From 04ca73b59019fe731b172d65aee4e7ff0058d2c7 Mon Sep 17 00:00:00 2001 From: vadimt Date: Wed, 17 Jul 2019 18:55:53 -0700 Subject: [PATCH 056/108] Fixing starting scrolls outside of view Change-Id: I0237603d25edc60522c41a3d20615391d5b4f3b6 --- .../com/android/launcher3/tapl/LauncherInstrumentation.java | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/tests/tapl/com/android/launcher3/tapl/LauncherInstrumentation.java b/tests/tapl/com/android/launcher3/tapl/LauncherInstrumentation.java index 1e74552f76..a5b0d25671 100644 --- a/tests/tapl/com/android/launcher3/tapl/LauncherInstrumentation.java +++ b/tests/tapl/com/android/launcher3/tapl/LauncherInstrumentation.java @@ -782,7 +782,7 @@ public final class LauncherInstrumentation { startX = endX = rect.centerX(); final int vertCenter = rect.centerY(); final float halfGestureHeight = rect.height() * percent / 2.0f; - startY = (int) (vertCenter + halfGestureHeight); + startY = (int) (vertCenter + halfGestureHeight) - 1; endY = (int) (vertCenter - halfGestureHeight); } break; @@ -798,7 +798,7 @@ public final class LauncherInstrumentation { startY = endY = rect.centerY(); final int horizCenter = rect.centerX(); final float halfGestureWidth = rect.width() * percent / 2.0f; - startX = (int) (horizCenter + halfGestureWidth); + startX = (int) (horizCenter + halfGestureWidth) - 1; endX = (int) (horizCenter - halfGestureWidth); } break; From 11b5535556cc3d53d7e521715178ddcd4b708daf Mon Sep 17 00:00:00 2001 From: Jon Miranda Date: Wed, 17 Jul 2019 21:24:07 -0700 Subject: [PATCH 057/108] Skip TouchInteractionService preload if restore task is pending. Otherwise the preload may cause launcher to restore too early, resulting in data loss. Bug: 131315856 Change-Id: I4412c8f691286ba142e9c748a908a3ed42713a82 --- .../src/com/android/quickstep/TouchInteractionService.java | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/quickstep/recents_ui_overrides/src/com/android/quickstep/TouchInteractionService.java b/quickstep/recents_ui_overrides/src/com/android/quickstep/TouchInteractionService.java index 4bc4c761b0..debed898ef 100644 --- a/quickstep/recents_ui_overrides/src/com/android/quickstep/TouchInteractionService.java +++ b/quickstep/recents_ui_overrides/src/com/android/quickstep/TouchInteractionService.java @@ -76,6 +76,7 @@ import com.android.launcher3.compat.UserManagerCompat; import com.android.launcher3.logging.EventLogArray; import com.android.launcher3.logging.UserEventDispatcher; import com.android.launcher3.model.AppLaunchTracker; +import com.android.launcher3.provider.RestoreDbTask; import com.android.launcher3.testing.TestProtocol; import com.android.launcher3.util.LooperExecutor; import com.android.launcher3.util.UiThreadHelper; @@ -710,6 +711,12 @@ public class TouchInteractionService extends Service implements return; } + if (RestoreDbTask.isPending(this)) { + // Preloading while a restore is pending may cause launcher to start the restore + // too early. + return; + } + final ActivityControlHelper activityControl = mOverviewComponentObserver.getActivityControlHelper(); if (activityControl.getCreatedActivity() == null) { From f33b6d4378c6029265742bdc19d805b73b096ffa Mon Sep 17 00:00:00 2001 From: Tony Wickham Date: Thu, 18 Jul 2019 14:38:46 -0700 Subject: [PATCH 058/108] Allow TouchControllers to override shouldDisableGestures Currently only StatusBarTouchController overrides this to always return false, so that you can swipe down for notifications during transition to home screen from an app (in gesture nav). Bug: 137161198 Change-Id: I803c37937d5294810cbe0c1bbffcd5dddcc5ca3b --- .../touchcontrollers/StatusBarTouchController.java | 6 ++++++ src/com/android/launcher3/util/TouchController.java | 4 ++++ src/com/android/launcher3/views/BaseDragLayer.java | 10 +++++----- 3 files changed, 15 insertions(+), 5 deletions(-) diff --git a/quickstep/src/com/android/launcher3/uioverrides/touchcontrollers/StatusBarTouchController.java b/quickstep/src/com/android/launcher3/uioverrides/touchcontrollers/StatusBarTouchController.java index f5ba3725df..18996ddb03 100644 --- a/quickstep/src/com/android/launcher3/uioverrides/touchcontrollers/StatusBarTouchController.java +++ b/quickstep/src/com/android/launcher3/uioverrides/touchcontrollers/StatusBarTouchController.java @@ -166,4 +166,10 @@ public class StatusBarTouchController implements TouchController { mSysUiProxy = RecentsModel.INSTANCE.get(mLauncher).getSystemUiProxy(); return mSysUiProxy != null; } + + @Override + public boolean allowWhenGesturesDisabled() { + // Always allow intercepting touches for this controller. + return true; + } } \ No newline at end of file diff --git a/src/com/android/launcher3/util/TouchController.java b/src/com/android/launcher3/util/TouchController.java index fc1d819f78..2cd28bbe8d 100644 --- a/src/com/android/launcher3/util/TouchController.java +++ b/src/com/android/launcher3/util/TouchController.java @@ -32,5 +32,9 @@ public interface TouchController { */ boolean onControllerInterceptTouchEvent(MotionEvent ev); + default boolean allowWhenGesturesDisabled() { + return false; + } + default void dump(String prefix, PrintWriter writer) { } } diff --git a/src/com/android/launcher3/views/BaseDragLayer.java b/src/com/android/launcher3/views/BaseDragLayer.java index 8bf33bf05c..4fe3d99d1e 100644 --- a/src/com/android/launcher3/views/BaseDragLayer.java +++ b/src/com/android/launcher3/views/BaseDragLayer.java @@ -21,7 +21,6 @@ import static android.view.MotionEvent.ACTION_DOWN; import static android.view.MotionEvent.ACTION_UP; import static com.android.launcher3.Utilities.SINGLE_FRAME_MS; -import static com.android.launcher3.Utilities.shouldDisableGestures; import android.annotation.TargetApi; import android.content.Context; @@ -30,7 +29,6 @@ import android.graphics.Rect; import android.graphics.RectF; import android.os.Build; import android.util.AttributeSet; -import android.util.Log; import android.util.Property; import android.view.MotionEvent; import android.view.View; @@ -152,15 +150,17 @@ public abstract class BaseDragLayer } private TouchController findControllerToHandleTouch(MotionEvent ev) { - if (shouldDisableGestures(ev)) return null; + boolean gesturesEnabled = !Utilities.shouldDisableGestures(ev); AbstractFloatingView topView = AbstractFloatingView.getTopOpenView(mActivity); - if (topView != null && topView.onControllerInterceptTouchEvent(ev)) { + if (topView != null && (gesturesEnabled || topView.allowWhenGesturesDisabled()) + && topView.onControllerInterceptTouchEvent(ev)) { return topView; } for (TouchController controller : mControllers) { - if (controller.onControllerInterceptTouchEvent(ev)) { + if ((gesturesEnabled || controller.allowWhenGesturesDisabled()) + && controller.onControllerInterceptTouchEvent(ev)) { return controller; } } From c0a1b7046d803451d2ad754959c03488d48226ca Mon Sep 17 00:00:00 2001 From: vadimt Date: Tue, 16 Jul 2019 16:33:22 -0700 Subject: [PATCH 059/108] Improving TAPL code around fallback recents Change-Id: I9cd1caa2725f1d3967447130f4e34c4cf878514b --- tests/tapl/com/android/launcher3/tapl/Background.java | 3 ++- tests/tapl/com/android/launcher3/tapl/BaseOverview.java | 2 +- .../android/launcher3/tapl/LauncherInstrumentation.java | 8 ++++++-- 3 files changed, 9 insertions(+), 4 deletions(-) diff --git a/tests/tapl/com/android/launcher3/tapl/Background.java b/tests/tapl/com/android/launcher3/tapl/Background.java index 060bf30202..bcce8ef579 100644 --- a/tests/tapl/com/android/launcher3/tapl/Background.java +++ b/tests/tapl/com/android/launcher3/tapl/Background.java @@ -54,7 +54,8 @@ public class Background extends LauncherInstrumentation.VisibleContainer { "want to switch from background to overview")) { verifyActiveContainer(); goToOverviewUnchecked(BACKGROUND_APP_STATE_ORDINAL); - return new BaseOverview(mLauncher); + return mLauncher.isFallbackOverview() ? + new BaseOverview(mLauncher) : new Overview(mLauncher); } } diff --git a/tests/tapl/com/android/launcher3/tapl/BaseOverview.java b/tests/tapl/com/android/launcher3/tapl/BaseOverview.java index 04a0f12714..bbd2c29e3e 100644 --- a/tests/tapl/com/android/launcher3/tapl/BaseOverview.java +++ b/tests/tapl/com/android/launcher3/tapl/BaseOverview.java @@ -41,7 +41,7 @@ public class BaseOverview extends LauncherInstrumentation.VisibleContainer { @Override protected LauncherInstrumentation.ContainerType getContainerType() { - return LauncherInstrumentation.ContainerType.BASE_OVERVIEW; + return LauncherInstrumentation.ContainerType.FALLBACK_OVERVIEW; } /** diff --git a/tests/tapl/com/android/launcher3/tapl/LauncherInstrumentation.java b/tests/tapl/com/android/launcher3/tapl/LauncherInstrumentation.java index a5b0d25671..79379e5922 100644 --- a/tests/tapl/com/android/launcher3/tapl/LauncherInstrumentation.java +++ b/tests/tapl/com/android/launcher3/tapl/LauncherInstrumentation.java @@ -87,7 +87,7 @@ public final class LauncherInstrumentation { // Types for launcher containers that the user is interacting with. "Background" is a // pseudo-container corresponding to inactive launcher covered by another app. enum ContainerType { - WORKSPACE, ALL_APPS, OVERVIEW, WIDGETS, BACKGROUND, BASE_OVERVIEW + WORKSPACE, ALL_APPS, OVERVIEW, WIDGETS, BACKGROUND, FALLBACK_OVERVIEW } public enum NavigationModel {ZERO_BUTTON, TWO_BUTTON, THREE_BUTTON} @@ -451,7 +451,7 @@ public final class LauncherInstrumentation { return waitForLauncherObject(OVERVIEW_RES_ID); } - case BASE_OVERVIEW: { + case FALLBACK_OVERVIEW: { return waitForFallbackLauncherObject(OVERVIEW_RES_ID); } case BACKGROUND: { @@ -739,6 +739,10 @@ public final class LauncherInstrumentation { return mDevice.getLauncherPackageName(); } + boolean isFallbackOverview() { + return !getOverviewPackageName().equals(getLauncherPackageName()); + } + @NonNull public UiDevice getDevice() { return mDevice; From c8d496fe002b9d6e0c9ee1ddf7ce27b0a2399abe Mon Sep 17 00:00:00 2001 From: vadimt Date: Thu, 18 Jul 2019 18:24:47 -0700 Subject: [PATCH 060/108] Fix waiting for launcher initialization Bug: 137836033 Change-Id: Ifc8ce867abd85eaeacd09a2b39636ecc4109c046 --- .../android/quickstep/TouchInteractionService.java | 2 +- .../quickstep/QuickstepTestInformationHandler.java | 2 +- .../android/quickstep/TouchInteractionService.java | 11 +++++------ .../launcher3/tapl/LauncherInstrumentation.java | 6 +++--- 4 files changed, 10 insertions(+), 11 deletions(-) diff --git a/go/quickstep/src/com/android/quickstep/TouchInteractionService.java b/go/quickstep/src/com/android/quickstep/TouchInteractionService.java index 917800f2a6..577b175661 100644 --- a/go/quickstep/src/com/android/quickstep/TouchInteractionService.java +++ b/go/quickstep/src/com/android/quickstep/TouchInteractionService.java @@ -186,7 +186,7 @@ public class TouchInteractionService extends Service { return mMyBinder; } - public static boolean isInputMonitorInitialized() { + public static boolean isInitialized() { return true; } } diff --git a/quickstep/recents_ui_overrides/src/com/android/quickstep/QuickstepTestInformationHandler.java b/quickstep/recents_ui_overrides/src/com/android/quickstep/QuickstepTestInformationHandler.java index b507044e0a..4eb9df2cbd 100644 --- a/quickstep/recents_ui_overrides/src/com/android/quickstep/QuickstepTestInformationHandler.java +++ b/quickstep/recents_ui_overrides/src/com/android/quickstep/QuickstepTestInformationHandler.java @@ -38,7 +38,7 @@ public class QuickstepTestInformationHandler extends TestInformationHandler { case TestProtocol.REQUEST_IS_LAUNCHER_INITIALIZED: { response.putBoolean(TestProtocol.TEST_INFO_RESPONSE_FIELD, - TouchInteractionService.isInputMonitorInitialized()); + TouchInteractionService.isInitialized()); return response; } diff --git a/quickstep/recents_ui_overrides/src/com/android/quickstep/TouchInteractionService.java b/quickstep/recents_ui_overrides/src/com/android/quickstep/TouchInteractionService.java index debed898ef..d10e5123d5 100644 --- a/quickstep/recents_ui_overrides/src/com/android/quickstep/TouchInteractionService.java +++ b/quickstep/recents_ui_overrides/src/com/android/quickstep/TouchInteractionService.java @@ -77,7 +77,6 @@ import com.android.launcher3.logging.EventLogArray; import com.android.launcher3.logging.UserEventDispatcher; import com.android.launcher3.model.AppLaunchTracker; import com.android.launcher3.provider.RestoreDbTask; -import com.android.launcher3.testing.TestProtocol; import com.android.launcher3.util.LooperExecutor; import com.android.launcher3.util.UiThreadHelper; import com.android.quickstep.SysUINavigationMode.Mode; @@ -154,6 +153,7 @@ public class TouchInteractionService extends Service implements MAIN_THREAD_EXECUTOR.execute(TouchInteractionService.this::initInputMonitor); MAIN_THREAD_EXECUTOR.execute(TouchInteractionService.this::onSystemUiProxySet); MAIN_THREAD_EXECUTOR.execute(() -> preloadOverview(true /* fromInit */)); + sIsInitialized = true; } @Override @@ -227,15 +227,15 @@ public class TouchInteractionService extends Service implements }; private static boolean sConnected = false; - private static boolean sInputMonitorInitialized = false; + private static boolean sIsInitialized = false; private static final SwipeSharedState sSwipeSharedState = new SwipeSharedState(); public static boolean isConnected() { return sConnected; } - public static boolean isInputMonitorInitialized() { - return sInputMonitorInitialized; + public static boolean isInitialized() { + return sIsInitialized; } public static SwipeSharedState getSwipeSharedState() { @@ -336,7 +336,6 @@ public class TouchInteractionService extends Service implements mInputMonitorCompat.dispose(); mInputMonitorCompat = null; } - sInputMonitorInitialized = false; } private void initInputMonitor() { @@ -354,7 +353,6 @@ public class TouchInteractionService extends Service implements Log.e(TAG, "Unable to create input monitor", e); } initTouchBounds(); - sInputMonitorInitialized = true; } private int getNavbarSize(String resName) { @@ -492,6 +490,7 @@ public class TouchInteractionService extends Service implements @Override public void onDestroy() { + sIsInitialized = false; if (mIsUserUnlocked) { mInputConsumer.unregisterInputConsumer(); mOverviewComponentObserver.onDestroy(); diff --git a/tests/tapl/com/android/launcher3/tapl/LauncherInstrumentation.java b/tests/tapl/com/android/launcher3/tapl/LauncherInstrumentation.java index 79379e5922..8639ea207d 100644 --- a/tests/tapl/com/android/launcher3/tapl/LauncherInstrumentation.java +++ b/tests/tapl/com/android/launcher3/tapl/LauncherInstrumentation.java @@ -396,7 +396,7 @@ public final class LauncherInstrumentation { } private UiObject2 verifyContainerType(ContainerType containerType) { - //waitForTouchInteractionService(); + waitForLauncherInitialized(); assertEquals("Unexpected display rotation", mExpectedRotation, mDevice.getDisplayRotation()); @@ -468,7 +468,7 @@ public final class LauncherInstrumentation { } } - private void waitForTouchInteractionService() { + private void waitForLauncherInitialized() { for (int i = 0; i < 100; ++i) { if (getTestInfo( TestProtocol.REQUEST_IS_LAUNCHER_INITIALIZED). @@ -477,7 +477,7 @@ public final class LauncherInstrumentation { } SystemClock.sleep(100); } - fail("TouchInteractionService didn't connect"); + fail("Launcher didn't initialize"); } Parcelable executeAndWaitForEvent(Runnable command, From 76d2a6fcc37110d65a112eea7dbc25854b3270df Mon Sep 17 00:00:00 2001 From: vadimt Date: Fri, 19 Jul 2019 10:40:25 -0700 Subject: [PATCH 061/108] Improving system health diags Change-Id: I207c5b9c9ad9e99646419b7a4bd77b59a067f26d --- .../android/launcher3/tapl/TestHelpers.java | 36 +++++++++---------- 1 file changed, 18 insertions(+), 18 deletions(-) diff --git a/tests/tapl/com/android/launcher3/tapl/TestHelpers.java b/tests/tapl/com/android/launcher3/tapl/TestHelpers.java index e19f91a20a..ebe5eac5f5 100644 --- a/tests/tapl/com/android/launcher3/tapl/TestHelpers.java +++ b/tests/tapl/com/android/launcher3/tapl/TestHelpers.java @@ -30,6 +30,7 @@ import android.os.DropBoxManager; import org.junit.Assert; +import java.util.Date; import java.util.List; public class TestHelpers { @@ -104,28 +105,21 @@ public class TestHelpers { DropBoxManager dropbox = (DropBoxManager) context.getSystemService(Context.DROPBOX_SERVICE); Assert.assertNotNull("Unable access the DropBoxManager service", dropbox); - long timestamp = 0; + long timestamp = System.currentTimeMillis() - 5 * 60000; DropBoxManager.Entry entry; - int crashCount = 0; StringBuilder errorDetails = new StringBuilder(); while (null != (entry = dropbox.getNextEntry(label, timestamp))) { - String dropboxSnippet; - try { - dropboxSnippet = entry.getText(4096); - } finally { - entry.close(); - } - - crashCount++; - errorDetails.append(label); - errorDetails.append(": "); - errorDetails.append(truncateCrash(dropboxSnippet, 40)); - errorDetails.append(" ...\n"); - timestamp = entry.getTimeMillis(); + errorDetails.append(new Date(timestamp)); + errorDetails.append(": "); + errorDetails.append(entry.getTag()); + errorDetails.append(": "); + final String dropboxSnippet = entry.getText(4096); + if (dropboxSnippet != null) errorDetails.append(truncateCrash(dropboxSnippet, 40)); + errorDetails.append(" ...\n"); + entry.close(); } - Assert.assertEquals(errorDetails.toString(), 0, crashCount); - return crashCount > 0 ? errorDetails.toString() : null; + return errorDetails.length() != 0 ? errorDetails.toString() : null; } public static String getSystemHealthMessage(Context context) { @@ -133,9 +127,15 @@ public class TestHelpers { StringBuilder errors = new StringBuilder(); final String[] labels = { + "system_app_anr", + "system_app_crash", + "system_app_native_crash", + "system_app_wtf", + "system_server_anr", "system_server_crash", "system_server_native_crash", - "system_server_anr", + "system_server_watchdog", + "system_server_wtf", }; for (String label : labels) { From 21cd128141931279ac21433da4fed1f2884be4b7 Mon Sep 17 00:00:00 2001 From: vadimt Date: Fri, 19 Jul 2019 12:12:49 -0700 Subject: [PATCH 062/108] Logging original exception in PortraitLandscapeRunner Change-Id: I672e563df45f1f0dcdda5b1f863919f0150e73e6 --- .../com/android/launcher3/ui/PortraitLandscapeRunner.java | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/tests/src/com/android/launcher3/ui/PortraitLandscapeRunner.java b/tests/src/com/android/launcher3/ui/PortraitLandscapeRunner.java index 0f36292f90..ddcb4da883 100644 --- a/tests/src/com/android/launcher3/ui/PortraitLandscapeRunner.java +++ b/tests/src/com/android/launcher3/ui/PortraitLandscapeRunner.java @@ -1,5 +1,6 @@ package com.android.launcher3.ui; +import android.util.Log; import android.view.Surface; import com.android.launcher3.tapl.TestHelpers; @@ -9,6 +10,7 @@ import org.junit.runner.Description; import org.junit.runners.model.Statement; class PortraitLandscapeRunner implements TestRule { + private static final String TAG = "PortraitLandscapeRunner"; private AbstractLauncherUiTest mTest; public PortraitLandscapeRunner(AbstractLauncherUiTest test) { @@ -36,6 +38,9 @@ class PortraitLandscapeRunner implements TestRule { evaluateInPortrait(); evaluateInLandscape(); + } catch (Exception e) { + Log.e(TAG, "Exception", e); + throw e; } finally { mTest.mDevice.setOrientationNatural(); mTest.executeOnLauncher(launcher -> From bc4d213535f296f90ad8dabe22eea13cc8ace838 Mon Sep 17 00:00:00 2001 From: Zak Cohen Date: Thu, 18 Jul 2019 15:40:49 -0700 Subject: [PATCH 063/108] TaskView - add a getter for the bitmap data. This allows other components to get it directly from the view, rather than retaining their own copy. Bug: 137129923 Tested: Manual Change-Id: Ibab307517c31cd3cb59b4d77ff390fd97546e86d --- .../src/com/android/quickstep/views/TaskThumbnailView.java | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/quickstep/recents_ui_overrides/src/com/android/quickstep/views/TaskThumbnailView.java b/quickstep/recents_ui_overrides/src/com/android/quickstep/views/TaskThumbnailView.java index d55a520443..7f1e8980b9 100644 --- a/quickstep/recents_ui_overrides/src/com/android/quickstep/views/TaskThumbnailView.java +++ b/quickstep/recents_ui_overrides/src/com/android/quickstep/views/TaskThumbnailView.java @@ -410,4 +410,11 @@ public class TaskThumbnailView extends View { return new ColorMatrixColorFilter(COLOR_MATRIX); } + + public Bitmap getThumbnail() { + if (mThumbnailData == null) { + return null; + } + return mThumbnailData.thumbnail; + } } From 3fca6aaec2883c4bb3108fc272589d8f89b59ba0 Mon Sep 17 00:00:00 2001 From: Tony Wickham Date: Fri, 19 Jul 2019 16:48:55 -0700 Subject: [PATCH 064/108] Finish recents animation when touching during animation to recents This regressed in ag/8542000, where we cancel the animation instead of ending it. We should only cancel when going to home; in other cases, we should still call end(). Bug: 137487381 Change-Id: I093954908c3ac747ec3132aa700c8be2f927631a --- .../android/quickstep/WindowTransformSwipeHandler.java | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/quickstep/recents_ui_overrides/src/com/android/quickstep/WindowTransformSwipeHandler.java b/quickstep/recents_ui_overrides/src/com/android/quickstep/WindowTransformSwipeHandler.java index df37759cc4..cc9719b418 100644 --- a/quickstep/recents_ui_overrides/src/com/android/quickstep/WindowTransformSwipeHandler.java +++ b/quickstep/recents_ui_overrides/src/com/android/quickstep/WindowTransformSwipeHandler.java @@ -56,6 +56,9 @@ import android.view.ViewTreeObserver.OnDrawListener; import android.view.WindowInsets; import android.view.animation.Interpolator; +import androidx.annotation.NonNull; +import androidx.annotation.UiThread; + import com.android.launcher3.AbstractFloatingView; import com.android.launcher3.BaseDraggingActivity; import com.android.launcher3.DeviceProfile; @@ -88,9 +91,6 @@ import com.android.systemui.shared.system.LatencyTrackerCompat; import com.android.systemui.shared.system.RemoteAnimationTargetCompat; import com.android.systemui.shared.system.WindowCallbacksCompat; -import androidx.annotation.NonNull; -import androidx.annotation.UiThread; - @TargetApi(Build.VERSION_CODES.O) public class WindowTransformSwipeHandler extends BaseSwipeUpHandler @@ -677,7 +677,7 @@ public class WindowTransformSwipeHandler @Override protected InputConsumer createNewInputProxyHandler() { - endRunningWindowAnim(true /* cancel */); + endRunningWindowAnim(mGestureEndTarget == HOME /* cancel */); endLauncherTransitionController(); if (!ENABLE_QUICKSTEP_LIVE_TILE.get()) { // Hide the task view, if not already hidden From b6841ac630fd4ca894e2638586511e3085c40baa Mon Sep 17 00:00:00 2001 From: Tony Wickham Date: Mon, 22 Jul 2019 12:39:59 -0700 Subject: [PATCH 065/108] Revert the changes that prevented touch on RecentsView during animation The original bug that was solving seems to be fixed by other changes, and this allows users to scroll, dismiss, etc on recent tasks before fully reaching overview from an app. Bug: 137487381 Change-Id: I28a708811bba3ce739ce261f19eb29558d8f0e7d --- .../android/quickstep/RecentsAnimationWrapper.java | 9 ++------- .../com/android/quickstep/views/RecentsView.java | 5 ----- .../touchcontrollers/StatusBarTouchController.java | 6 ------ src/com/android/launcher3/PagedView.java | 8 ++------ src/com/android/launcher3/Utilities.java | 14 ++------------ .../android/launcher3/util/TouchController.java | 4 ---- src/com/android/launcher3/views/BaseDragLayer.java | 8 ++------ 7 files changed, 8 insertions(+), 46 deletions(-) diff --git a/quickstep/recents_ui_overrides/src/com/android/quickstep/RecentsAnimationWrapper.java b/quickstep/recents_ui_overrides/src/com/android/quickstep/RecentsAnimationWrapper.java index ddd28a3500..ca89c33929 100644 --- a/quickstep/recents_ui_overrides/src/com/android/quickstep/RecentsAnimationWrapper.java +++ b/quickstep/recents_ui_overrides/src/com/android/quickstep/RecentsAnimationWrapper.java @@ -19,12 +19,12 @@ import static android.view.MotionEvent.ACTION_CANCEL; import static android.view.MotionEvent.ACTION_DOWN; import static android.view.MotionEvent.ACTION_UP; -import static com.android.launcher3.Utilities.FLAG_NO_GESTURES; - import android.view.InputEvent; import android.view.KeyEvent; import android.view.MotionEvent; +import androidx.annotation.UiThread; + import com.android.launcher3.util.Preconditions; import com.android.quickstep.inputconsumers.InputConsumer; import com.android.quickstep.util.SwipeAnimationTargetSet; @@ -33,8 +33,6 @@ import com.android.systemui.shared.system.InputConsumerController; import java.util.ArrayList; import java.util.function.Supplier; -import androidx.annotation.UiThread; - /** * Wrapper around RecentsAnimationController to help with some synchronization */ @@ -184,10 +182,7 @@ public class RecentsAnimationWrapper { } } if (mInputConsumer != null) { - int flags = ev.getEdgeFlags(); - ev.setEdgeFlags(flags | FLAG_NO_GESTURES); mInputConsumer.onMotionEvent(ev); - ev.setEdgeFlags(flags); } return true; diff --git a/quickstep/recents_ui_overrides/src/com/android/quickstep/views/RecentsView.java b/quickstep/recents_ui_overrides/src/com/android/quickstep/views/RecentsView.java index b566837da6..6ff297dea3 100644 --- a/quickstep/recents_ui_overrides/src/com/android/quickstep/views/RecentsView.java +++ b/quickstep/recents_ui_overrides/src/com/android/quickstep/views/RecentsView.java @@ -473,11 +473,6 @@ public abstract class RecentsView extends PagedView impl } } - @Override - protected boolean shouldBlockGestures(MotionEvent ev) { - return Utilities.shouldDisableGestures(ev); - } - @Override public boolean onTouchEvent(MotionEvent ev) { super.onTouchEvent(ev); diff --git a/quickstep/src/com/android/launcher3/uioverrides/touchcontrollers/StatusBarTouchController.java b/quickstep/src/com/android/launcher3/uioverrides/touchcontrollers/StatusBarTouchController.java index 18996ddb03..f5ba3725df 100644 --- a/quickstep/src/com/android/launcher3/uioverrides/touchcontrollers/StatusBarTouchController.java +++ b/quickstep/src/com/android/launcher3/uioverrides/touchcontrollers/StatusBarTouchController.java @@ -166,10 +166,4 @@ public class StatusBarTouchController implements TouchController { mSysUiProxy = RecentsModel.INSTANCE.get(mLauncher).getSystemUiProxy(); return mSysUiProxy != null; } - - @Override - public boolean allowWhenGesturesDisabled() { - // Always allow intercepting touches for this controller. - return true; - } } \ No newline at end of file diff --git a/src/com/android/launcher3/PagedView.java b/src/com/android/launcher3/PagedView.java index bd52ffe4b2..d2b8d4e300 100644 --- a/src/com/android/launcher3/PagedView.java +++ b/src/com/android/launcher3/PagedView.java @@ -848,7 +848,7 @@ public abstract class PagedView extends ViewGrou */ // Skip touch handling if there are no pages to swipe - if (getChildCount() <= 0 || shouldBlockGestures(ev)) return false; + if (getChildCount() <= 0) return false; acquireVelocityTrackerAndAddMovement(ev); @@ -1093,14 +1093,10 @@ public abstract class PagedView extends ViewGrou mAllowOverScroll = enable; } - protected boolean shouldBlockGestures(MotionEvent ev) { - return false; - } - @Override public boolean onTouchEvent(MotionEvent ev) { // Skip touch handling if there are no pages to swipe - if (getChildCount() <= 0 || shouldBlockGestures(ev)) return false; + if (getChildCount() <= 0) return false; acquireVelocityTrackerAndAddMovement(ev); diff --git a/src/com/android/launcher3/Utilities.java b/src/com/android/launcher3/Utilities.java index 65aa3a775d..fc5cd8a888 100644 --- a/src/com/android/launcher3/Utilities.java +++ b/src/com/android/launcher3/Utilities.java @@ -16,6 +16,8 @@ package com.android.launcher3; +import static com.android.launcher3.ItemInfoWithIcon.FLAG_ICON_BADGED; + import android.animation.ValueAnimator; import android.annotation.TargetApi; import android.app.ActivityManager; @@ -92,8 +94,6 @@ import java.util.concurrent.TimeUnit; import java.util.regex.Matcher; import java.util.regex.Pattern; -import static com.android.launcher3.ItemInfoWithIcon.FLAG_ICON_BADGED; - /** * Various utilities shared amongst the Launcher's classes. */ @@ -127,16 +127,6 @@ public final class Utilities { */ public static final int EDGE_NAV_BAR = 1 << 8; - /** - * Set on a motion event do disallow any gestures and only handle touch. - * See {@link MotionEvent#setEdgeFlags(int)}. - */ - public static final int FLAG_NO_GESTURES = 1 << 9; - - public static boolean shouldDisableGestures(MotionEvent ev) { - return (ev.getEdgeFlags() & FLAG_NO_GESTURES) == FLAG_NO_GESTURES; - } - /** * Indicates if the device has a debug build. Should only be used to store additional info or * add extra logging and not for changing the app behavior. diff --git a/src/com/android/launcher3/util/TouchController.java b/src/com/android/launcher3/util/TouchController.java index 2cd28bbe8d..fc1d819f78 100644 --- a/src/com/android/launcher3/util/TouchController.java +++ b/src/com/android/launcher3/util/TouchController.java @@ -32,9 +32,5 @@ public interface TouchController { */ boolean onControllerInterceptTouchEvent(MotionEvent ev); - default boolean allowWhenGesturesDisabled() { - return false; - } - default void dump(String prefix, PrintWriter writer) { } } diff --git a/src/com/android/launcher3/views/BaseDragLayer.java b/src/com/android/launcher3/views/BaseDragLayer.java index 7b16409d9f..f2f2f3b537 100644 --- a/src/com/android/launcher3/views/BaseDragLayer.java +++ b/src/com/android/launcher3/views/BaseDragLayer.java @@ -150,17 +150,13 @@ public abstract class BaseDragLayer } private TouchController findControllerToHandleTouch(MotionEvent ev) { - boolean gesturesEnabled = !Utilities.shouldDisableGestures(ev); - AbstractFloatingView topView = AbstractFloatingView.getTopOpenView(mActivity); - if (topView != null && (gesturesEnabled || topView.allowWhenGesturesDisabled()) - && topView.onControllerInterceptTouchEvent(ev)) { + if (topView != null && topView.onControllerInterceptTouchEvent(ev)) { return topView; } for (TouchController controller : mControllers) { - if ((gesturesEnabled || controller.allowWhenGesturesDisabled()) - && controller.onControllerInterceptTouchEvent(ev)) { + if (controller.onControllerInterceptTouchEvent(ev)) { return controller; } } From 20aa2e4f51da9d35a0f699ff864fe56ae31f2220 Mon Sep 17 00:00:00 2001 From: vadimt Date: Mon, 22 Jul 2019 16:54:29 -0700 Subject: [PATCH 066/108] Logging start and end of linear gesture Change-Id: Ie0756c89e3871b3f4e12849ef52c44f84a5ceeee --- .../tapl/com/android/launcher3/tapl/LauncherInstrumentation.java | 1 + 1 file changed, 1 insertion(+) diff --git a/tests/tapl/com/android/launcher3/tapl/LauncherInstrumentation.java b/tests/tapl/com/android/launcher3/tapl/LauncherInstrumentation.java index 8639ea207d..b76a82c6e2 100644 --- a/tests/tapl/com/android/launcher3/tapl/LauncherInstrumentation.java +++ b/tests/tapl/com/android/launcher3/tapl/LauncherInstrumentation.java @@ -821,6 +821,7 @@ public final class LauncherInstrumentation { // Inject a swipe gesture. Inject exactly 'steps' motion points, incrementing event time by a // fixed interval each time. void linearGesture(int startX, int startY, int endX, int endY, int steps) { + log("linearGesture: " + startX + ", " + startY + " -> " + endX + ", " + endY); final long downTime = SystemClock.uptimeMillis(); final Point start = new Point(startX, startY); final Point end = new Point(endX, endY); From 44515f42c0e532e4121f7c6019161cfbd37b3ba1 Mon Sep 17 00:00:00 2001 From: vadimt Date: Tue, 23 Jul 2019 12:36:05 -0700 Subject: [PATCH 067/108] Allowing both normal-case and uppercase versions of widget prompt The prompt is "Add automatically" Bug: 138152531 Change-Id: I5f1a15563e1e11768579711108a28070b72b4454 --- .../android/launcher3/tapl/AddToHomeScreenPrompt.java | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/tests/tapl/com/android/launcher3/tapl/AddToHomeScreenPrompt.java b/tests/tapl/com/android/launcher3/tapl/AddToHomeScreenPrompt.java index 7f561a2af3..6813400b87 100644 --- a/tests/tapl/com/android/launcher3/tapl/AddToHomeScreenPrompt.java +++ b/tests/tapl/com/android/launcher3/tapl/AddToHomeScreenPrompt.java @@ -19,7 +19,11 @@ package com.android.launcher3.tapl; import androidx.test.uiautomator.By; import androidx.test.uiautomator.UiObject2; +import java.util.regex.Pattern; + public class AddToHomeScreenPrompt { + private static final Pattern ADD_AUTOMATICALLY = + Pattern.compile("ADD AUTOMATICALLY|Add automatically"); private final LauncherInstrumentation mLauncher; private final UiObject2 mWidgetCell; @@ -33,9 +37,6 @@ public class AddToHomeScreenPrompt { public void addAutomatically() { mLauncher.waitForObjectInContainer( mWidgetCell.getParent().getParent().getParent().getParent(), - By.text(LauncherInstrumentation.isAvd() - ? "ADD AUTOMATICALLY" - : "Add automatically")). - click(); + By.text(ADD_AUTOMATICALLY)).click(); } } From d418f3c3fa17c4c4a0ae552541ca78acd42917ff Mon Sep 17 00:00:00 2001 From: Tony Wickham Date: Tue, 23 Jul 2019 13:33:53 -0700 Subject: [PATCH 068/108] Set FastBitmapDrawable scale=1 before drawing it in DragView When we draw the icon to the DragView, we draw it with the current scale, which is > 1 when animating the icon down. Instead, we should always draw the icon with scale 1 since the DragView itself is scaled. Bug: 138236583 Change-Id: I6bca5cf28c54d58476240e0e68900a8f08ffe60b --- src/com/android/launcher3/graphics/DragPreviewProvider.java | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/com/android/launcher3/graphics/DragPreviewProvider.java b/src/com/android/launcher3/graphics/DragPreviewProvider.java index 7eb4015bfa..9263a2ac94 100644 --- a/src/com/android/launcher3/graphics/DragPreviewProvider.java +++ b/src/com/android/launcher3/graphics/DragPreviewProvider.java @@ -29,6 +29,7 @@ import android.os.Handler; import android.view.View; import com.android.launcher3.BubbleTextView; +import com.android.launcher3.FastBitmapDrawable; import com.android.launcher3.Launcher; import com.android.launcher3.R; import com.android.launcher3.config.FeatureFlags; @@ -87,6 +88,9 @@ public class DragPreviewProvider { Rect bounds = getDrawableBounds(d); destCanvas.translate(blurSizeOutline / 2 - bounds.left, blurSizeOutline / 2 - bounds.top); + if (d instanceof FastBitmapDrawable) { + ((FastBitmapDrawable) d).setScale(1); + } d.draw(destCanvas); } else { final Rect clipRect = mTempRect; From 34828b1942d9442a05463ddee0c61118af70341c Mon Sep 17 00:00:00 2001 From: vadimt Date: Tue, 23 Jul 2019 13:54:05 -0700 Subject: [PATCH 069/108] Improving "Add automatically" recognition Bug: 138152531 Change-Id: I204233f06a80d2d17b24dd9622c7a2152b1303a0 --- .../com/android/launcher3/tapl/AddToHomeScreenPrompt.java | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/tests/tapl/com/android/launcher3/tapl/AddToHomeScreenPrompt.java b/tests/tapl/com/android/launcher3/tapl/AddToHomeScreenPrompt.java index 6813400b87..03d1600783 100644 --- a/tests/tapl/com/android/launcher3/tapl/AddToHomeScreenPrompt.java +++ b/tests/tapl/com/android/launcher3/tapl/AddToHomeScreenPrompt.java @@ -16,6 +16,8 @@ package com.android.launcher3.tapl; +import static java.util.regex.Pattern.CASE_INSENSITIVE; + import androidx.test.uiautomator.By; import androidx.test.uiautomator.UiObject2; @@ -23,7 +25,7 @@ import java.util.regex.Pattern; public class AddToHomeScreenPrompt { private static final Pattern ADD_AUTOMATICALLY = - Pattern.compile("ADD AUTOMATICALLY|Add automatically"); + Pattern.compile("^Add automatically$", CASE_INSENSITIVE); private final LauncherInstrumentation mLauncher; private final UiObject2 mWidgetCell; From 9566a044009bbf5d53b1b8684ace9fd57815cdb3 Mon Sep 17 00:00:00 2001 From: Jon Miranda Date: Tue, 23 Jul 2019 15:22:30 -0700 Subject: [PATCH 070/108] Fix bug where rounded corners were being set despite being disabled. Bug: 138117089 Change-Id: Icb852e2e07d80c45ad3406ef432b89720887fccf --- .../android/launcher3/QuickstepAppTransitionManagerImpl.java | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/quickstep/src/com/android/launcher3/QuickstepAppTransitionManagerImpl.java b/quickstep/src/com/android/launcher3/QuickstepAppTransitionManagerImpl.java index 44324cb2e4..b60a017dd8 100644 --- a/quickstep/src/com/android/launcher3/QuickstepAppTransitionManagerImpl.java +++ b/quickstep/src/com/android/launcher3/QuickstepAppTransitionManagerImpl.java @@ -32,6 +32,7 @@ import static com.android.launcher3.dragndrop.DragLayer.ALPHA_INDEX_TRANSITIONS; import static com.android.launcher3.views.FloatingIconView.SHAPE_PROGRESS_DURATION; import static com.android.quickstep.TaskUtils.taskIsATargetWithMode; import static com.android.systemui.shared.system.QuickStepContract.getWindowCornerRadius; +import static com.android.systemui.shared.system.QuickStepContract.supportsRoundedCornersOnWindows; import static com.android.systemui.shared.system.RemoteAnimationTargetCompat.MODE_CLOSING; import static com.android.systemui.shared.system.RemoteAnimationTargetCompat.MODE_OPENING; @@ -495,6 +496,8 @@ public abstract class QuickstepAppTransitionManagerImpl extends LauncherAppTrans endCrop = windowTargetBounds.height(); } + final float initialWindowRadius = supportsRoundedCornersOnWindows(mLauncher.getResources()) + ? startCrop / 2f : 0f; final float windowRadius = mDeviceProfile.isMultiWindowMode ? 0 : getWindowCornerRadius(mLauncher.getResources()); appAnimator.addUpdateListener(new MultiValueUpdateListener() { @@ -506,7 +509,7 @@ public abstract class QuickstepAppTransitionManagerImpl extends LauncherAppTrans alphaDuration, LINEAR); FloatProp mCroppedSize = new FloatProp(startCrop, endCrop, 0, CROP_DURATION, EXAGGERATED_EASE); - FloatProp mWindowRadius = new FloatProp(startCrop / 2f, windowRadius, 0, + FloatProp mWindowRadius = new FloatProp(initialWindowRadius, windowRadius, 0, RADIUS_DURATION, EXAGGERATED_EASE); @Override From a50538198079c36f3352be26e679b4067af3badc Mon Sep 17 00:00:00 2001 From: vadimt Date: Tue, 23 Jul 2019 15:48:02 -0700 Subject: [PATCH 071/108] TAPL: adding 1 to gesture margins to avoid accidentally triggering back Change-Id: I7152d60dffc2085313dc1466693b599e4efe0394 --- .../com/android/launcher3/tapl/LauncherInstrumentation.java | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/tests/tapl/com/android/launcher3/tapl/LauncherInstrumentation.java b/tests/tapl/com/android/launcher3/tapl/LauncherInstrumentation.java index b76a82c6e2..eac5de782d 100644 --- a/tests/tapl/com/android/launcher3/tapl/LauncherInstrumentation.java +++ b/tests/tapl/com/android/launcher3/tapl/LauncherInstrumentation.java @@ -778,7 +778,7 @@ public final class LauncherInstrumentation { startX = endX = rect.centerX(); final int vertCenter = rect.centerY(); final float halfGestureHeight = rect.height() * percent / 2.0f; - startY = (int) (vertCenter - halfGestureHeight); + startY = (int) (vertCenter - halfGestureHeight) + 1; endY = (int) (vertCenter + halfGestureHeight); } break; @@ -794,7 +794,7 @@ public final class LauncherInstrumentation { startY = endY = rect.centerY(); final int horizCenter = rect.centerX(); final float halfGestureWidth = rect.width() * percent / 2.0f; - startX = (int) (horizCenter - halfGestureWidth); + startX = (int) (horizCenter - halfGestureWidth) + 1; endX = (int) (horizCenter + halfGestureWidth); } break; From 48ba8c864cdddddad80f5566372cf98a7988aca9 Mon Sep 17 00:00:00 2001 From: Winson Chung Date: Tue, 23 Jul 2019 11:48:21 -0700 Subject: [PATCH 072/108] Fix regression in assistant window handling - Skip the assistant as the running task when handling swipe up - Also ensure that we fall into the overview input consumer if we are swiping it from the assistant over home - Skip accounting for the scroll offset when there is no running task Bug: 136282913 Change-Id: I28e45e407702d6d6aebaa0232cd96ccb10047644 --- .../quickstep/TouchInteractionService.java | 27 ++++++++++++++++--- .../android/quickstep/views/RecentsView.java | 3 +++ 2 files changed, 27 insertions(+), 3 deletions(-) diff --git a/quickstep/recents_ui_overrides/src/com/android/quickstep/TouchInteractionService.java b/quickstep/recents_ui_overrides/src/com/android/quickstep/TouchInteractionService.java index d10e5123d5..77563400f4 100644 --- a/quickstep/recents_ui_overrides/src/com/android/quickstep/TouchInteractionService.java +++ b/quickstep/recents_ui_overrides/src/com/android/quickstep/TouchInteractionService.java @@ -33,11 +33,13 @@ import static com.android.systemui.shared.system.QuickStepContract.SYSUI_STATE_N import static com.android.systemui.shared.system.QuickStepContract.SYSUI_STATE_OVERVIEW_DISABLED; import static com.android.systemui.shared.system.QuickStepContract.SYSUI_STATE_SCREEN_PINNING; import static com.android.systemui.shared.system.QuickStepContract.SYSUI_STATE_STATUS_BAR_KEYGUARD_SHOWING_OCCLUDED; +import static com.android.systemui.shared.system.RemoteAnimationTargetCompat.ACTIVITY_TYPE_ASSISTANT; import android.annotation.TargetApi; import android.app.ActivityManager; import android.app.ActivityManager.RunningTaskInfo; import android.app.Service; +import android.app.TaskInfo; import android.content.BroadcastReceiver; import android.content.ComponentName; import android.content.Context; @@ -102,6 +104,7 @@ import com.android.systemui.shared.system.QuickStepContract.SystemUiStateFlags; import com.android.systemui.shared.system.RecentsAnimationListener; import com.android.systemui.shared.system.SystemGestureExclusionListenerCompat; +import com.android.systemui.shared.system.TaskInfoCompat; import java.io.FileDescriptor; import java.io.PrintWriter; import java.util.Arrays; @@ -566,7 +569,7 @@ public class TouchInteractionService extends Service implements if (isInValidSystemUiState) { // This handles apps launched in direct boot mode (e.g. dialer) as well as apps // launched while device is locked even after exiting direct boot mode (e.g. camera). - return createDeviceLockedInputConsumer(mAM.getRunningTask(0)); + return createDeviceLockedInputConsumer(mAM.getRunningTask(ACTIVITY_TYPE_ASSISTANT)); } else { return mResetGestureInputConsumer; } @@ -604,7 +607,7 @@ public class TouchInteractionService extends Service implements } private InputConsumer newBaseConsumer(boolean useSharedState, MotionEvent event) { - final RunningTaskInfo runningTaskInfo = mAM.getRunningTask(0); + RunningTaskInfo runningTaskInfo = mAM.getRunningTask(0); if (!useSharedState) { sSwipeSharedState.clearAllState(false /* finishAnimation */); } @@ -616,6 +619,17 @@ public class TouchInteractionService extends Service implements final ActivityControlHelper activityControl = mOverviewComponentObserver.getActivityControlHelper(); + boolean forceOverviewInputConsumer = false; + if (isExcludedAssistant(runningTaskInfo)) { + // In the case where we are in the excluded assistant state, ignore it and treat the + // running activity as the task behind the assistant + runningTaskInfo = mAM.getRunningTask(ACTIVITY_TYPE_ASSISTANT); + final ComponentName homeComponent = + mOverviewComponentObserver.getHomeIntent().getComponent(); + forceOverviewInputConsumer = + runningTaskInfo.baseIntent.getComponent().equals(homeComponent); + } + if (runningTaskInfo == null && !sSwipeSharedState.goingToLauncher && !sSwipeSharedState.recentsAnimationFinishInterrupted) { return mResetGestureInputConsumer; @@ -625,7 +639,8 @@ public class TouchInteractionService extends Service implements RunningTaskInfo info = new ActivityManager.RunningTaskInfo(); info.id = sSwipeSharedState.nextRunningTaskId; return createOtherActivityInputConsumer(event, info); - } else if (sSwipeSharedState.goingToLauncher || activityControl.isResumed()) { + } else if (sSwipeSharedState.goingToLauncher || activityControl.isResumed() + || forceOverviewInputConsumer) { return createOverviewInputConsumer(event); } else if (ENABLE_QUICKSTEP_LIVE_TILE.get() && activityControl.isInLiveTileMode()) { return createOverviewInputConsumer(event); @@ -637,6 +652,12 @@ public class TouchInteractionService extends Service implements } } + private boolean isExcludedAssistant(TaskInfo info) { + return info != null + && TaskInfoCompat.getActivityType(info) == ACTIVITY_TYPE_ASSISTANT + && (info.baseIntent.getFlags() & Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS) != 0; + } + private boolean disableHorizontalSwipe(MotionEvent event) { // mExclusionRegion can change on binder thread, use a local instance here. Region exclusionRegion = mExclusionRegion; diff --git a/quickstep/recents_ui_overrides/src/com/android/quickstep/views/RecentsView.java b/quickstep/recents_ui_overrides/src/com/android/quickstep/views/RecentsView.java index b566837da6..01f922fec2 100644 --- a/quickstep/recents_ui_overrides/src/com/android/quickstep/views/RecentsView.java +++ b/quickstep/recents_ui_overrides/src/com/android/quickstep/views/RecentsView.java @@ -1697,6 +1697,9 @@ public abstract class RecentsView extends PagedView impl * @return How many pixels the running task is offset on the x-axis due to the current scrollX. */ public float getScrollOffset() { + if (getRunningTaskIndex() == -1) { + return 0; + } int startScroll = getScrollForPage(getRunningTaskIndex()); int offsetX = startScroll - getScrollX(); offsetX *= getScaleX(); From cd7b00853ba60671f6637a5f51e97bdb942bab88 Mon Sep 17 00:00:00 2001 From: vadimt Date: Tue, 23 Jul 2019 16:49:48 -0700 Subject: [PATCH 073/108] Adding debug tracing Bug: 138251824 Change-Id: Ibe3de964aeacbf83fd46cc53fda7d15c9401fe4d --- .../quickstep/TouchInteractionService.java | 16 ++++++++++++++++ .../quickstep/NavigationModeSwitchRule.java | 2 ++ .../android/launcher3/testing/TestProtocol.java | 2 ++ .../launcher3/tapl/LauncherInstrumentation.java | 8 ++++++++ 4 files changed, 28 insertions(+) diff --git a/quickstep/recents_ui_overrides/src/com/android/quickstep/TouchInteractionService.java b/quickstep/recents_ui_overrides/src/com/android/quickstep/TouchInteractionService.java index d10e5123d5..86c4a06a79 100644 --- a/quickstep/recents_ui_overrides/src/com/android/quickstep/TouchInteractionService.java +++ b/quickstep/recents_ui_overrides/src/com/android/quickstep/TouchInteractionService.java @@ -77,6 +77,7 @@ import com.android.launcher3.logging.EventLogArray; import com.android.launcher3.logging.UserEventDispatcher; import com.android.launcher3.model.AppLaunchTracker; import com.android.launcher3.provider.RestoreDbTask; +import com.android.launcher3.testing.TestProtocol; import com.android.launcher3.util.LooperExecutor; import com.android.launcher3.util.UiThreadHelper; import com.android.quickstep.SysUINavigationMode.Mode; @@ -339,16 +340,25 @@ public class TouchInteractionService extends Service implements } private void initInputMonitor() { + if (TestProtocol.sDebugTracing) { + Log.d(TestProtocol.NO_BACKGROUND_TO_OVERVIEW_TAG, "initInputMonitor 1"); + } if (!mMode.hasGestures || mISystemUiProxy == null) { return; } disposeEventHandlers(); + if (TestProtocol.sDebugTracing) { + Log.d(TestProtocol.NO_BACKGROUND_TO_OVERVIEW_TAG, "initInputMonitor 2"); + } try { mInputMonitorCompat = InputMonitorCompat.fromBundle(mISystemUiProxy .monitorGestureInput("swipe-up", mDefaultDisplayId), KEY_EXTRA_INPUT_MONITOR); mInputEventReceiver = mInputMonitorCompat.getInputReceiver(Looper.getMainLooper(), mMainChoreographer, this::onInputEvent); + if (TestProtocol.sDebugTracing) { + Log.d(TestProtocol.NO_BACKGROUND_TO_OVERVIEW_TAG, "initInputMonitor 3"); + } } catch (RemoteException e) { Log.e(TAG, "Unable to create input monitor", e); } @@ -406,6 +416,9 @@ public class TouchInteractionService extends Service implements @Override public void onNavigationModeChanged(Mode newMode) { + if (TestProtocol.sDebugTracing) { + Log.d(TestProtocol.NO_BACKGROUND_TO_OVERVIEW_TAG, "onNavigationModeChanged " + newMode); + } if (mMode.hasGestures != newMode.hasGestures) { if (newMode.hasGestures) { getSystemService(DisplayManager.class).registerDisplayListener( @@ -515,6 +528,9 @@ public class TouchInteractionService extends Service implements } private void onInputEvent(InputEvent ev) { + if (TestProtocol.sDebugTracing) { + Log.d(TestProtocol.NO_BACKGROUND_TO_OVERVIEW_TAG, "onInputEvent " + ev); + } if (!(ev instanceof MotionEvent)) { Log.e(TAG, "Unknown event " + ev); return; diff --git a/quickstep/tests/src/com/android/quickstep/NavigationModeSwitchRule.java b/quickstep/tests/src/com/android/quickstep/NavigationModeSwitchRule.java index 3b35c86af8..b6cd1bec3c 100644 --- a/quickstep/tests/src/com/android/quickstep/NavigationModeSwitchRule.java +++ b/quickstep/tests/src/com/android/quickstep/NavigationModeSwitchRule.java @@ -80,6 +80,7 @@ public class NavigationModeSwitchRule implements TestRule { return new Statement() { @Override public void evaluate() throws Throwable { + mLauncher.enableDebugTracing(); final Context context = getInstrumentation().getContext(); final int currentInteractionMode = LauncherInstrumentation.getCurrentInteractionMode(context); @@ -104,6 +105,7 @@ public class NavigationModeSwitchRule implements TestRule { } finally { setActiveOverlay(prevOverlayPkg, originalMode); } + mLauncher.disableDebugTracing(); } public void evaluateWithoutChangingSetting(Statement base) throws Throwable { diff --git a/src/com/android/launcher3/testing/TestProtocol.java b/src/com/android/launcher3/testing/TestProtocol.java index 079ab6d8fe..9846a04271 100644 --- a/src/com/android/launcher3/testing/TestProtocol.java +++ b/src/com/android/launcher3/testing/TestProtocol.java @@ -77,4 +77,6 @@ public final class TestProtocol { public static boolean sDebugTracing = false; public static final String REQUEST_ENABLE_DEBUG_TRACING = "enable-debug-tracing"; public static final String REQUEST_DISABLE_DEBUG_TRACING = "disable-debug-tracing"; + + public static final String NO_BACKGROUND_TO_OVERVIEW_TAG = "b/138251824"; } diff --git a/tests/tapl/com/android/launcher3/tapl/LauncherInstrumentation.java b/tests/tapl/com/android/launcher3/tapl/LauncherInstrumentation.java index b76a82c6e2..2ed2646339 100644 --- a/tests/tapl/com/android/launcher3/tapl/LauncherInstrumentation.java +++ b/tests/tapl/com/android/launcher3/tapl/LauncherInstrumentation.java @@ -937,4 +937,12 @@ public final class LauncherInstrumentation { getContext().getSystemService(WindowManager.class).getDefaultDisplay().getRealSize(size); return size; } + + public void enableDebugTracing() { + getTestInfo(TestProtocol.REQUEST_ENABLE_DEBUG_TRACING); + } + + public void disableDebugTracing() { + getTestInfo(TestProtocol.REQUEST_DISABLE_DEBUG_TRACING); + } } \ No newline at end of file From fbd77c48cc147ae71ba0da4d89e5f21df2fcfc3f Mon Sep 17 00:00:00 2001 From: Tony Wickham Date: Tue, 23 Jul 2019 16:58:45 -0700 Subject: [PATCH 074/108] Distinguish mDragHandleProgress from mMidProgress mMidProgress is intended to be the point at which we reach Overview when swiping up and thus start scrimming it as All Apps shows above it. For that reason, mMidProgress needs to match OverviewState's progress. In contrast, the drag handle (accessibility arrow) can move up sooner to avoid overlapping with the QSB; for this, we added mDragHandleProgress. Bug: 136800511 Change-Id: I2825ff798707530420855257350e492b4b9b77dc --- .../android/quickstep/views/ShelfScrimView.java | 16 +++++++++++----- 1 file changed, 11 insertions(+), 5 deletions(-) diff --git a/quickstep/src/com/android/quickstep/views/ShelfScrimView.java b/quickstep/src/com/android/quickstep/views/ShelfScrimView.java index 63c8023f6d..5a2f5c162a 100644 --- a/quickstep/src/com/android/quickstep/views/ShelfScrimView.java +++ b/quickstep/src/com/android/quickstep/views/ShelfScrimView.java @@ -74,6 +74,9 @@ public class ShelfScrimView extends ScrimView implements NavigationModeChangeLis private int mMidAlpha; private float mMidProgress; + // The progress at which the drag handle starts moving up with the shelf. + private float mDragHandleProgress; + private Interpolator mBeforeMidProgressColorInterpolator = ACCEL; private Interpolator mAfterMidProgressColorInterpolator = ACCEL; @@ -150,15 +153,16 @@ public class ShelfScrimView extends ScrimView implements NavigationModeChangeLis if ((OVERVIEW.getVisibleElements(mLauncher) & ALL_APPS_HEADER_EXTRA) == 0) { mMidProgress = 1; + mDragHandleProgress = 1; mMidAlpha = 0; } else { mMidAlpha = Themes.getAttrInteger(getContext(), R.attr.allAppsInterimScrimAlpha); + mMidProgress = OVERVIEW.getVerticalProgress(mLauncher); Rect hotseatPadding = dp.getHotseatLayoutPadding(); int hotseatSize = dp.hotseatBarSizePx + dp.getInsets().bottom - hotseatPadding.bottom - hotseatPadding.top; - float arrowTop = Math.min(hotseatSize, OverviewState.getDefaultSwipeHeight(dp)); - mMidProgress = 1 - (arrowTop / mShiftRange); - + float dragHandleTop = Math.min(hotseatSize, OverviewState.getDefaultSwipeHeight(dp)); + mDragHandleProgress = 1 - (dragHandleTop / mShiftRange); } mTopOffset = dp.getInsets().top - mShelfOffset; mShelfTopAtThreshold = mShiftRange * SCRIM_CATCHUP_THRESHOLD + mTopOffset; @@ -199,8 +203,6 @@ public class ShelfScrimView extends ScrimView implements NavigationModeChangeLis mProgress, mMidProgress, 1, mMidAlpha, 0, mBeforeMidProgressColorInterpolator)); mShelfColor = setColorAlphaBound(mEndScrim, alpha); } else { - mDragHandleOffset += mShiftRange * (mMidProgress - mProgress); - // Note that these ranges and interpolators are inverted because progress goes 1 to 0. int alpha = Math.round( Utilities.mapToRange(mProgress, (float) 0, mMidProgress, (float) mEndAlpha, @@ -212,6 +214,10 @@ public class ShelfScrimView extends ScrimView implements NavigationModeChangeLis (float) 0, LINEAR)); mRemainingScreenColor = setColorAlphaBound(mScrimColor, remainingScrimAlpha); } + + if (mProgress < mDragHandleProgress) { + mDragHandleOffset += mShiftRange * (mDragHandleProgress - mProgress); + } } @Override From 064cba456090fe1b651f98e0e891b3b84e541b1f Mon Sep 17 00:00:00 2001 From: Anna Wasewicz Date: Tue, 23 Jul 2019 17:34:34 -0700 Subject: [PATCH 075/108] Changing ENABLE_HINTS_IN_OVERVIEW flag to be true in qt-r1-dev. It should be false in qt-dev and true in qt-r1-dev. Bug: 138252347 Change-Id: If9de47ef937ecb3da9c8d43eea8ad4b6e6885582 --- src/com/android/launcher3/config/BaseFlags.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/com/android/launcher3/config/BaseFlags.java b/src/com/android/launcher3/config/BaseFlags.java index 45639e0a43..54efcb7868 100644 --- a/src/com/android/launcher3/config/BaseFlags.java +++ b/src/com/android/launcher3/config/BaseFlags.java @@ -105,7 +105,7 @@ abstract class BaseFlags { "ENABLE_QUICKSTEP_LIVE_TILE", false, "Enable live tile in Quickstep overview"); public static final TogglableFlag ENABLE_HINTS_IN_OVERVIEW = new TogglableFlag( - "ENABLE_HINTS_IN_OVERVIEW", false, + "ENABLE_HINTS_IN_OVERVIEW", true, "Show chip hints and gleams on the overview screen"); public static final TogglableFlag FAKE_LANDSCAPE_UI = new TogglableFlag( From 0dd1c782f0cb1653f191a2ec9db72f8f26190dc8 Mon Sep 17 00:00:00 2001 From: vadimt Date: Tue, 23 Jul 2019 17:30:04 -0700 Subject: [PATCH 076/108] Checking Launcher internal integrity from tests In particular, we check that the stable Launcher state equals its current state. This can help detect Launcher being in a corrupted state as in b/133867119. The check gets called by tests when the Launcher is not transitioning from state to state. Bug: 137307838 Change-Id: I3d36edff35e42d14be6b9a52351bd6f709be75e8 --- .../launcher3/ui/AbstractLauncherUiTest.java | 71 +++++++++++++++++++ .../tapl/LauncherInstrumentation.java | 17 ++++- 2 files changed, 87 insertions(+), 1 deletion(-) diff --git a/tests/src/com/android/launcher3/ui/AbstractLauncherUiTest.java b/tests/src/com/android/launcher3/ui/AbstractLauncherUiTest.java index 361f2fb533..8dc8cea40d 100644 --- a/tests/src/com/android/launcher3/ui/AbstractLauncherUiTest.java +++ b/tests/src/com/android/launcher3/ui/AbstractLauncherUiTest.java @@ -17,6 +17,7 @@ package com.android.launcher3.ui; import static androidx.test.InstrumentationRegistry.getInstrumentation; +import static com.android.launcher3.tapl.LauncherInstrumentation.ContainerType; import static com.android.launcher3.ui.TaplTestsLauncher3.getAppPackageName; import static org.junit.Assert.assertTrue; @@ -45,6 +46,7 @@ import com.android.launcher3.LauncherAppState; import com.android.launcher3.LauncherModel; import com.android.launcher3.LauncherSettings; import com.android.launcher3.LauncherState; +import com.android.launcher3.LauncherStateManager; import com.android.launcher3.MainThreadExecutor; import com.android.launcher3.Utilities; import com.android.launcher3.compat.LauncherAppsCompat; @@ -52,6 +54,7 @@ import com.android.launcher3.model.AppLaunchTracker; import com.android.launcher3.tapl.LauncherInstrumentation; import com.android.launcher3.tapl.TestHelpers; import com.android.launcher3.testcomponent.TestCommandReceiver; +import com.android.launcher3.testing.TestProtocol; import com.android.launcher3.util.PackageManagerHelper; import com.android.launcher3.util.Wait; import com.android.launcher3.util.rule.FailureWatcher; @@ -103,6 +106,10 @@ public abstract class AbstractLauncherUiTest { Utilities.enableRunningInTestHarnessForTests(); mLauncher.setSystemHealthSupplier(() -> TestCommandReceiver.callCommand( TestCommandReceiver.GET_SYSTEM_HEALTH_MESSAGE).getString("result")); + mLauncher.setOnSettledStateAction( + containerType -> executeOnLauncher( + launcher -> + checkLauncherIntegrity(launcher, containerType))); } } @@ -379,4 +386,68 @@ public abstract class AbstractLauncherUiTest { protected int getAllAppsScroll(Launcher launcher) { return launcher.getAppsView().getActiveRecyclerView().getCurrentScrollY(); } + + private static void checkLauncherIntegrity( + Launcher launcher, ContainerType expectedContainerType) { + if (launcher != null) { + final LauncherStateManager stateManager = launcher.getStateManager(); + final LauncherState stableState = stateManager.getCurrentStableState(); + + assertTrue("Stable state != state: " + stableState.getClass().getSimpleName() + ", " + + stateManager.getState().getClass().getSimpleName(), + stableState == stateManager.getState()); + + final boolean isResumed = launcher.hasBeenResumed(); + assertTrue("hasBeenResumed() != isStarted(), hasBeenResumed(): " + isResumed, + isResumed == launcher.isStarted()); + assertTrue("hasBeenResumed() != isUserActive(), hasBeenResumed(): " + isResumed, + isResumed == launcher.isUserActive()); + + final int ordinal = stableState.ordinal; + + switch (expectedContainerType) { + case WORKSPACE: + case WIDGETS: { + assertTrue( + "Launcher is not resumed in state: " + expectedContainerType, + isResumed); + assertTrue(TestProtocol.stateOrdinalToString(ordinal), + ordinal == TestProtocol.NORMAL_STATE_ORDINAL); + break; + } + case ALL_APPS: { + assertTrue( + "Launcher is not resumed in state: " + expectedContainerType, + isResumed); + assertTrue(TestProtocol.stateOrdinalToString(ordinal), + ordinal == TestProtocol.ALL_APPS_STATE_ORDINAL); + break; + } + case OVERVIEW: { + assertTrue( + "Launcher is not resumed in state: " + expectedContainerType, + isResumed); + assertTrue(TestProtocol.stateOrdinalToString(ordinal), + ordinal == TestProtocol.OVERVIEW_STATE_ORDINAL); + break; + } + case BACKGROUND: { + assertTrue("Launcher is resumed in state: " + expectedContainerType, + !isResumed); + assertTrue(TestProtocol.stateOrdinalToString(ordinal), + ordinal == TestProtocol.NORMAL_STATE_ORDINAL); + break; + } + default: + throw new IllegalArgumentException( + "Illegal container: " + expectedContainerType); + } + } else { + assertTrue( + "Container type is not BACKGROUND or FALLBACK_OVERVIEW: " + + expectedContainerType, + expectedContainerType == ContainerType.BACKGROUND || + expectedContainerType == ContainerType.FALLBACK_OVERVIEW); + } + } } diff --git a/tests/tapl/com/android/launcher3/tapl/LauncherInstrumentation.java b/tests/tapl/com/android/launcher3/tapl/LauncherInstrumentation.java index eac5de782d..db88202e79 100644 --- a/tests/tapl/com/android/launcher3/tapl/LauncherInstrumentation.java +++ b/tests/tapl/com/android/launcher3/tapl/LauncherInstrumentation.java @@ -72,6 +72,7 @@ import java.util.Deque; import java.util.LinkedList; import java.util.List; import java.util.concurrent.TimeoutException; +import java.util.function.Consumer; import java.util.function.Supplier; /** @@ -86,7 +87,7 @@ public final class LauncherInstrumentation { // Types for launcher containers that the user is interacting with. "Background" is a // pseudo-container corresponding to inactive launcher covered by another app. - enum ContainerType { + public enum ContainerType { WORKSPACE, ALL_APPS, OVERVIEW, WIDGETS, BACKGROUND, FALLBACK_OVERVIEW } @@ -135,6 +136,8 @@ public final class LauncherInstrumentation { private final Deque mDiagnosticContext = new LinkedList<>(); private Supplier mSystemHealthSupplier; + private Consumer mOnSettledStateAction; + /** * Constructs the root of TAPL hierarchy. You get all other objects from it. */ @@ -296,6 +299,10 @@ public final class LauncherInstrumentation { this.mSystemHealthSupplier = supplier; } + public void setOnSettledStateAction(Consumer onSettledStateAction) { + mOnSettledStateAction = onSettledStateAction; + } + private String getSystemHealthMessage() { final String testPackage = getContext().getPackageName(); try { @@ -415,6 +422,14 @@ public final class LauncherInstrumentation { assertTrue(error, error == null); log("verifyContainerType: " + containerType); + final UiObject2 container = verifyVisibleObjects(containerType); + + if (mOnSettledStateAction != null) mOnSettledStateAction.accept(containerType); + + return container; + } + + private UiObject2 verifyVisibleObjects(ContainerType containerType) { try (Closable c = addContextLayer( "but the current state is not " + containerType.name())) { switch (containerType) { From a8971c1462f276b2b4d6daab6b18941b9dc9a94a Mon Sep 17 00:00:00 2001 From: Winson Chung Date: Tue, 9 Jul 2019 11:33:50 -0700 Subject: [PATCH 077/108] Copy resume callbacks list prior to making callbacks - Starting a deferred activity can trigger a new callback to be added to the list while we are iterating it Bug: 136613192 Change-Id: I6690ab0695bb73f11bf343fb41e9fc86b4afec1b Merged-In: I6690ab0695bb73f11bf343fb41e9fc86b4afec1b (cherry picked from commit 940b0ac0157945a40d8b3b44d976da53aaeff81f) --- src/com/android/launcher3/Launcher.java | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/src/com/android/launcher3/Launcher.java b/src/com/android/launcher3/Launcher.java index d9af4da8e8..bc3aa7ef40 100644 --- a/src/com/android/launcher3/Launcher.java +++ b/src/com/android/launcher3/Launcher.java @@ -952,10 +952,14 @@ public class Launcher extends BaseDraggingActivity implements LauncherExterns, mHandler.removeCallbacks(mHandleDeferredResume); Utilities.postAsyncCallback(mHandler, mHandleDeferredResume); - for (OnResumeCallback cb : mOnResumeCallbacks) { - cb.onLauncherResume(); + if (!mOnResumeCallbacks.isEmpty()) { + final ArrayList resumeCallbacks = new ArrayList<>(mOnResumeCallbacks); + mOnResumeCallbacks.clear(); + for (int i = resumeCallbacks.size() - 1; i >= 0; i--) { + resumeCallbacks.get(i).onLauncherResume(); + } + resumeCallbacks.clear(); } - mOnResumeCallbacks.clear(); if (mLauncherCallbacks != null) { mLauncherCallbacks.onResume(); From 4e6c45bcd3717af05a892a92565d55aa20728644 Mon Sep 17 00:00:00 2001 From: Sunny Goyal Date: Tue, 23 Jul 2019 11:26:38 -0700 Subject: [PATCH 078/108] Using the first frame delay based on the display refresh rate instead of hardcoding it to 16ms > Creating a utility class for caching display property changes Bug: 128940249 Change-Id: I6f9a214548de65bd1c8530508d665ee88312da4a --- .../AppToOverviewAnimationProvider.java | 5 +- .../TaskViewTouchController.java | 6 +- .../android/quickstep/RecentsActivity.java | 2 +- .../WindowTransformSwipeHandler.java | 6 +- .../launcher3/LauncherAnimationRunner.java | 9 +- .../launcher3/LauncherInitListener.java | 2 +- .../QuickstepAppTransitionManagerImpl.java | 4 +- .../quickstep/RecentsActivityTracker.java | 2 +- .../util/RemoteAnimationProvider.java | 5 +- .../launcher3/FirstFrameAnimatorHelper.java | 23 +-- .../android/launcher3/anim/Interpolators.java | 7 +- .../AbstractStateChangeTouchController.java | 12 +- .../launcher3/util/DefaultDisplay.java | 166 ++++++++++++++++++ .../launcher3/views/BaseDragLayer.java | 5 +- 14 files changed, 212 insertions(+), 42 deletions(-) create mode 100644 src/com/android/launcher3/util/DefaultDisplay.java diff --git a/go/quickstep/src/com/android/quickstep/AppToOverviewAnimationProvider.java b/go/quickstep/src/com/android/quickstep/AppToOverviewAnimationProvider.java index fe159b5f02..92900f2168 100644 --- a/go/quickstep/src/com/android/quickstep/AppToOverviewAnimationProvider.java +++ b/go/quickstep/src/com/android/quickstep/AppToOverviewAnimationProvider.java @@ -25,6 +25,7 @@ import static com.android.systemui.shared.system.RemoteAnimationTargetCompat.MOD import android.animation.AnimatorSet; import android.animation.ValueAnimator; import android.app.ActivityOptions; +import android.content.Context; import android.os.Handler; import android.util.Log; @@ -151,7 +152,7 @@ final class AppToOverviewAnimationProvider imple } @Override - public ActivityOptions toActivityOptions(Handler handler, long duration) { + public ActivityOptions toActivityOptions(Handler handler, long duration, Context context) { LauncherAnimationRunner runner = new LauncherAnimationRunner(handler, false /* startAtFrontOfQueue */) { @@ -165,7 +166,7 @@ final class AppToOverviewAnimationProvider imple ); return; } - result.setAnimation(createWindowAnimation(targetCompats)); + result.setAnimation(createWindowAnimation(targetCompats), context); } }; return ActivityOptionsCompat.makeRemoteAnimation( diff --git a/quickstep/recents_ui_overrides/src/com/android/launcher3/uioverrides/touchcontrollers/TaskViewTouchController.java b/quickstep/recents_ui_overrides/src/com/android/launcher3/uioverrides/touchcontrollers/TaskViewTouchController.java index 8e32bb370e..00e4f58e92 100644 --- a/quickstep/recents_ui_overrides/src/com/android/launcher3/uioverrides/touchcontrollers/TaskViewTouchController.java +++ b/quickstep/recents_ui_overrides/src/com/android/launcher3/uioverrides/touchcontrollers/TaskViewTouchController.java @@ -16,10 +16,10 @@ package com.android.launcher3.uioverrides.touchcontrollers; import static com.android.launcher3.AbstractFloatingView.TYPE_ACCESSIBLE; -import static com.android.launcher3.Utilities.SINGLE_FRAME_MS; import static com.android.launcher3.anim.Interpolators.scrollInterpolatorForVelocity; import static com.android.launcher3.config.FeatureFlags.ENABLE_QUICKSTEP_LIVE_TILE; import static com.android.launcher3.config.FeatureFlags.QUICKSTEP_SPRINGS; +import static com.android.launcher3.util.DefaultDisplay.getSingleFrameMs; import android.animation.Animator; import android.animation.AnimatorListenerAdapter; @@ -266,8 +266,8 @@ public abstract class TaskViewTouchController animationDuration *= LauncherAnimUtils.blockedFlingDurationFactor(velocity); } - float nextFrameProgress = Utilities.boundToRange( - progress + velocity * SINGLE_FRAME_MS / Math.abs(mEndDisplacement), 0f, 1f); + float nextFrameProgress = Utilities.boundToRange(progress + + velocity * getSingleFrameMs(mActivity) / Math.abs(mEndDisplacement), 0f, 1f); mCurrentAnimation.setEndAction(() -> onCurrentAnimationEnd(goingToEnd, logAction)); diff --git a/quickstep/recents_ui_overrides/src/com/android/quickstep/RecentsActivity.java b/quickstep/recents_ui_overrides/src/com/android/quickstep/RecentsActivity.java index 60e7b12ec4..f08ae4a827 100644 --- a/quickstep/recents_ui_overrides/src/com/android/quickstep/RecentsActivity.java +++ b/quickstep/recents_ui_overrides/src/com/android/quickstep/RecentsActivity.java @@ -155,7 +155,7 @@ public final class RecentsActivity extends BaseRecentsActivity { mFallbackRecentsView.resetViewUI(); } }); - result.setAnimation(anim); + result.setAnimation(anim, RecentsActivity.this); } }; return ActivityOptionsCompat.makeRemoteAnimation(new RemoteAnimationAdapterCompat( diff --git a/quickstep/recents_ui_overrides/src/com/android/quickstep/WindowTransformSwipeHandler.java b/quickstep/recents_ui_overrides/src/com/android/quickstep/WindowTransformSwipeHandler.java index cc9719b418..363e4cc6be 100644 --- a/quickstep/recents_ui_overrides/src/com/android/quickstep/WindowTransformSwipeHandler.java +++ b/quickstep/recents_ui_overrides/src/com/android/quickstep/WindowTransformSwipeHandler.java @@ -17,12 +17,12 @@ package com.android.quickstep; import static com.android.launcher3.BaseActivity.INVISIBLE_BY_STATE_HANDLER; import static com.android.launcher3.BaseActivity.STATE_HANDLER_INVISIBILITY_FLAGS; -import static com.android.launcher3.Utilities.SINGLE_FRAME_MS; import static com.android.launcher3.anim.Interpolators.DEACCEL; import static com.android.launcher3.anim.Interpolators.LINEAR; import static com.android.launcher3.anim.Interpolators.OVERSHOOT_1_2; import static com.android.launcher3.config.FeatureFlags.ENABLE_QUICKSTEP_LIVE_TILE; import static com.android.launcher3.config.FeatureFlags.QUICKSTEP_SPRINGS; +import static com.android.launcher3.util.DefaultDisplay.getSingleFrameMs; import static com.android.launcher3.util.RaceConditionTracker.ENTER; import static com.android.launcher3.util.RaceConditionTracker.EXIT; import static com.android.launcher3.util.SystemUiController.UI_STATE_OVERVIEW; @@ -780,14 +780,14 @@ public class WindowTransformSwipeHandler interpolator = endTarget == RECENTS ? OVERSHOOT_1_2 : DEACCEL; } else { startShift = Utilities.boundToRange(currentShift - velocityPxPerMs.y - * SINGLE_FRAME_MS / mTransitionDragLength, 0, mDragLengthFactor); + * getSingleFrameMs(mContext) / mTransitionDragLength, 0, mDragLengthFactor); float minFlingVelocity = mContext.getResources() .getDimension(R.dimen.quickstep_fling_min_velocity); if (Math.abs(endVelocity) > minFlingVelocity && mTransitionDragLength > 0) { if (endTarget == RECENTS && mMode != Mode.NO_BUTTON) { Interpolators.OvershootParams overshoot = new Interpolators.OvershootParams( startShift, endShift, endShift, endVelocity / 1000, - mTransitionDragLength); + mTransitionDragLength, mContext); endShift = overshoot.end; interpolator = overshoot.interpolator; duration = Utilities.boundToRange(overshoot.duration, MIN_OVERSHOOT_DURATION, diff --git a/quickstep/src/com/android/launcher3/LauncherAnimationRunner.java b/quickstep/src/com/android/launcher3/LauncherAnimationRunner.java index 78f6ffa88c..a8e29569b1 100644 --- a/quickstep/src/com/android/launcher3/LauncherAnimationRunner.java +++ b/quickstep/src/com/android/launcher3/LauncherAnimationRunner.java @@ -15,8 +15,8 @@ */ package com.android.launcher3; -import static com.android.launcher3.Utilities.SINGLE_FRAME_MS; import static com.android.launcher3.Utilities.postAsyncCallback; +import static com.android.launcher3.util.DefaultDisplay.getSingleFrameMs; import static com.android.systemui.shared.recents.utilities.Utilities .postAtFrontOfQueueAsynchronously; @@ -24,6 +24,7 @@ import android.animation.Animator; import android.animation.AnimatorListenerAdapter; import android.animation.AnimatorSet; import android.annotation.TargetApi; +import android.content.Context; import android.os.Build; import android.os.Handler; @@ -66,7 +67,7 @@ public abstract class LauncherAnimationRunner implements RemoteAnimationRunnerCo /** * Called on the UI thread when the animation targets are received. The implementation must - * call {@link AnimationResult#setAnimation(AnimatorSet)} with the target animation to be run. + * call {@link AnimationResult#setAnimation} with the target animation to be run. */ @UiThread public abstract void onCreateAnimation( @@ -110,7 +111,7 @@ public abstract class LauncherAnimationRunner implements RemoteAnimationRunnerCo } @UiThread - public void setAnimation(AnimatorSet animation) { + public void setAnimation(AnimatorSet animation, Context context) { if (mInitialized) { throw new IllegalStateException("Animation already initialized"); } @@ -134,7 +135,7 @@ public abstract class LauncherAnimationRunner implements RemoteAnimationRunnerCo // Because t=0 has the app icon in its original spot, we can skip the // first frame and have the same movement one frame earlier. - mAnimator.setCurrentPlayTime(SINGLE_FRAME_MS); + mAnimator.setCurrentPlayTime(getSingleFrameMs(context)); } } } diff --git a/quickstep/src/com/android/launcher3/LauncherInitListener.java b/quickstep/src/com/android/launcher3/LauncherInitListener.java index c5c5323ec5..b9ce1ceee5 100644 --- a/quickstep/src/com/android/launcher3/LauncherInitListener.java +++ b/quickstep/src/com/android/launcher3/LauncherInitListener.java @@ -85,7 +85,7 @@ public class LauncherInitListener extends InternalStateHandler implements Activi register(); - Bundle options = animProvider.toActivityOptions(handler, duration).toBundle(); + Bundle options = animProvider.toActivityOptions(handler, duration, context).toBundle(); context.startActivity(addToIntent(new Intent((intent))), options); } } diff --git a/quickstep/src/com/android/launcher3/QuickstepAppTransitionManagerImpl.java b/quickstep/src/com/android/launcher3/QuickstepAppTransitionManagerImpl.java index 44324cb2e4..fc8d02a713 100644 --- a/quickstep/src/com/android/launcher3/QuickstepAppTransitionManagerImpl.java +++ b/quickstep/src/com/android/launcher3/QuickstepAppTransitionManagerImpl.java @@ -218,7 +218,7 @@ public abstract class QuickstepAppTransitionManagerImpl extends LauncherAppTrans anim.addListener(mForceInvisibleListener); } - result.setAnimation(anim); + result.setAnimation(anim, mLauncher); } }; @@ -819,7 +819,7 @@ public abstract class QuickstepAppTransitionManagerImpl extends LauncherAppTrans } mLauncher.clearForceInvisibleFlag(INVISIBLE_ALL); - result.setAnimation(anim); + result.setAnimation(anim, mLauncher); } } } diff --git a/quickstep/src/com/android/quickstep/RecentsActivityTracker.java b/quickstep/src/com/android/quickstep/RecentsActivityTracker.java index 0822e6199b..f9d2f11cba 100644 --- a/quickstep/src/com/android/quickstep/RecentsActivityTracker.java +++ b/quickstep/src/com/android/quickstep/RecentsActivityTracker.java @@ -68,7 +68,7 @@ public class RecentsActivityTracker implements Ac Context context, Handler handler, long duration) { register(); - Bundle options = animProvider.toActivityOptions(handler, duration).toBundle(); + Bundle options = animProvider.toActivityOptions(handler, duration, context).toBundle(); context.startActivity(intent, options); } diff --git a/quickstep/src/com/android/quickstep/util/RemoteAnimationProvider.java b/quickstep/src/com/android/quickstep/util/RemoteAnimationProvider.java index a7e6d74f02..4503a43542 100644 --- a/quickstep/src/com/android/quickstep/util/RemoteAnimationProvider.java +++ b/quickstep/src/com/android/quickstep/util/RemoteAnimationProvider.java @@ -17,6 +17,7 @@ package com.android.quickstep.util; import android.animation.AnimatorSet; import android.app.ActivityOptions; +import android.content.Context; import android.os.Handler; import com.android.launcher3.LauncherAnimationRunner; @@ -32,14 +33,14 @@ public interface RemoteAnimationProvider { AnimatorSet createWindowAnimation(RemoteAnimationTargetCompat[] targets); - default ActivityOptions toActivityOptions(Handler handler, long duration) { + default ActivityOptions toActivityOptions(Handler handler, long duration, Context context) { LauncherAnimationRunner runner = new LauncherAnimationRunner(handler, false /* startAtFrontOfQueue */) { @Override public void onCreateAnimation(RemoteAnimationTargetCompat[] targetCompats, AnimationResult result) { - result.setAnimation(createWindowAnimation(targetCompats)); + result.setAnimation(createWindowAnimation(targetCompats), context); } }; return ActivityOptionsCompat.makeRemoteAnimation( diff --git a/src/com/android/launcher3/FirstFrameAnimatorHelper.java b/src/com/android/launcher3/FirstFrameAnimatorHelper.java index c967a96e48..6c5bc40b3e 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.Utilities.SINGLE_FRAME_MS; +import static com.android.launcher3.util.DefaultDisplay.getSingleFrameMs; import android.animation.ValueAnimator; import android.animation.ValueAnimator.AnimatorUpdateListener; @@ -108,17 +108,20 @@ public class FirstFrameAnimatorHelper implements OnDrawListener, OnAttachStateCh // For the second frame, if the first frame took more than 16ms, // adjust the start time and pretend it took only 16ms anyway. This // prevents a large jump in the animation due to an expensive first frame - } else if (frameNum == 1 && currentTime < mStartTime + MAX_DELAY && - !mAdjustedSecondFrameTime && - currentTime > mStartTime + SINGLE_FRAME_MS && - currentPlayTime > SINGLE_FRAME_MS) { - animation.setCurrentPlayTime(SINGLE_FRAME_MS); - mAdjustedSecondFrameTime = true; } else { - if (frameNum > 1) { - mRootView.post(() -> animation.removeUpdateListener(this)); + int singleFrameMS = getSingleFrameMs(mRootView.getContext()); + if (frameNum == 1 && currentTime < mStartTime + MAX_DELAY && + !mAdjustedSecondFrameTime && + currentTime > mStartTime + singleFrameMS && + currentPlayTime > singleFrameMS) { + animation.setCurrentPlayTime(singleFrameMS); + mAdjustedSecondFrameTime = true; + } else { + if (frameNum > 1) { + mRootView.post(() -> animation.removeUpdateListener(this)); + } + if (DEBUG) print(animation); } - if (DEBUG) print(animation); } mHandlingOnAnimationUpdate = false; } else { diff --git a/src/com/android/launcher3/anim/Interpolators.java b/src/com/android/launcher3/anim/Interpolators.java index 8443231e8d..c45cd85aad 100644 --- a/src/com/android/launcher3/anim/Interpolators.java +++ b/src/com/android/launcher3/anim/Interpolators.java @@ -16,8 +16,9 @@ package com.android.launcher3.anim; -import static com.android.launcher3.Utilities.SINGLE_FRAME_MS; +import static com.android.launcher3.util.DefaultDisplay.getSingleFrameMs; +import android.content.Context; import android.graphics.Path; import android.view.animation.AccelerateDecelerateInterpolator; import android.view.animation.AccelerateInterpolator; @@ -188,13 +189,13 @@ public class Interpolators { * @param totalDistancePx The distance against which progress is calculated. */ public OvershootParams(float startProgress, float overshootPastProgress, - float endProgress, float velocityPxPerMs, int totalDistancePx) { + float endProgress, float velocityPxPerMs, int totalDistancePx, Context context) { velocityPxPerMs = Math.abs(velocityPxPerMs); start = startProgress; int startPx = (int) (start * totalDistancePx); // Overshoot by about half a frame. float overshootBy = OVERSHOOT_FACTOR * velocityPxPerMs * - SINGLE_FRAME_MS / totalDistancePx / 2; + getSingleFrameMs(context) / totalDistancePx / 2; overshootBy = Utilities.boundToRange(overshootBy, 0.02f, 0.15f); end = overshootPastProgress + overshootBy; int endPx = (int) (end * totalDistancePx); diff --git a/src/com/android/launcher3/touch/AbstractStateChangeTouchController.java b/src/com/android/launcher3/touch/AbstractStateChangeTouchController.java index ae69f3b32d..49f515ad4b 100644 --- a/src/com/android/launcher3/touch/AbstractStateChangeTouchController.java +++ b/src/com/android/launcher3/touch/AbstractStateChangeTouchController.java @@ -22,9 +22,9 @@ import static com.android.launcher3.LauncherState.OVERVIEW; import static com.android.launcher3.LauncherStateManager.ANIM_ALL; import static com.android.launcher3.LauncherStateManager.ATOMIC_OVERVIEW_SCALE_COMPONENT; import static com.android.launcher3.LauncherStateManager.NON_ATOMIC_COMPONENT; -import static com.android.launcher3.Utilities.SINGLE_FRAME_MS; import static com.android.launcher3.anim.Interpolators.scrollInterpolatorForVelocity; import static com.android.launcher3.config.FeatureFlags.QUICKSTEP_SPRINGS; +import static com.android.launcher3.util.DefaultDisplay.getSingleFrameMs; import android.animation.Animator; import android.animation.AnimatorListenerAdapter; @@ -55,8 +55,6 @@ import com.android.launcher3.util.TouchController; public abstract class AbstractStateChangeTouchController implements TouchController, SwipeDetector.Listener { - private static final String TAG = "ASCTouchController"; - // Progress after which the transition is assumed to be a success in case user does not fling public static final float SUCCESS_TRANSITION_PROGRESS = 0.5f; @@ -396,8 +394,8 @@ public abstract class AbstractStateChangeTouchController duration = 0; startProgress = 1; } else { - startProgress = Utilities.boundToRange( - progress + velocity * SINGLE_FRAME_MS * mProgressMultiplier, 0f, 1f); + startProgress = Utilities.boundToRange(progress + + velocity * getSingleFrameMs(mLauncher) * mProgressMultiplier, 0f, 1f); duration = SwipeDetector.calculateDuration(velocity, endProgress - Math.max(progress, 0)) * durationMultiplier; } @@ -414,8 +412,8 @@ public abstract class AbstractStateChangeTouchController duration = 0; startProgress = 0; } else { - startProgress = Utilities.boundToRange( - progress + velocity * SINGLE_FRAME_MS * mProgressMultiplier, 0f, 1f); + startProgress = Utilities.boundToRange(progress + + velocity * getSingleFrameMs(mLauncher) * mProgressMultiplier, 0f, 1f); duration = SwipeDetector.calculateDuration(velocity, Math.min(progress, 1) - endProgress) * durationMultiplier; } diff --git a/src/com/android/launcher3/util/DefaultDisplay.java b/src/com/android/launcher3/util/DefaultDisplay.java new file mode 100644 index 0000000000..7719f084d7 --- /dev/null +++ b/src/com/android/launcher3/util/DefaultDisplay.java @@ -0,0 +1,166 @@ +/* + * Copyright (C) 2019 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package com.android.launcher3.util; + +import android.content.Context; +import android.graphics.Point; +import android.hardware.display.DisplayManager; +import android.hardware.display.DisplayManager.DisplayListener; +import android.os.Handler; +import android.os.Message; +import android.util.Log; +import android.view.Display; +import android.view.WindowManager; + +import java.util.ArrayList; + +/** + * Utility class to cache properties of default display to avoid a system RPC on every call. + */ +public class DefaultDisplay implements DisplayListener { + + public static final MainThreadInitializedObject INSTANCE = + new MainThreadInitializedObject<>(DefaultDisplay::new); + + private static final String TAG = "DefaultDisplay"; + + public static final int CHANGE_SIZE = 1 << 0; + public static final int CHANGE_ROTATION = 1 << 1; + public static final int CHANGE_FRAME_DELAY = 1 << 2; + + private final Context mContext; + private final int mId; + private final ArrayList mListeners = new ArrayList<>(); + private final Handler mChangeHandler; + private Info mInfo; + + private DefaultDisplay(Context context) { + mContext = context; + mInfo = new Info(context); + mId = mInfo.id; + mChangeHandler = new Handler(this::onChange); + + context.getSystemService(DisplayManager.class) + .registerDisplayListener(this, new Handler(UiThreadHelper.getBackgroundLooper())); + } + + @Override + public final void onDisplayAdded(int displayId) { } + + @Override + public final void onDisplayRemoved(int displayId) { } + + @Override + public final void onDisplayChanged(int displayId) { + if (displayId != mId) { + return; + } + + Info oldInfo = mInfo; + Info info = new Info(mContext); + + int change = 0; + if (info.hasDifferentSize(oldInfo)) { + change |= CHANGE_SIZE; + } + if (oldInfo.rotation != info.rotation) { + change |= CHANGE_ROTATION; + } + if (info.singleFrameMs != oldInfo.singleFrameMs) { + change |= CHANGE_FRAME_DELAY; + } + + if (change != 0) { + mInfo = info; + mChangeHandler.sendEmptyMessage(change); + } + } + + public static int getSingleFrameMs(Context context) { + return INSTANCE.get(context).getInfo().singleFrameMs; + } + + public Info getInfo() { + return mInfo; + } + + public void addChangeListener(DisplayInfoChangeListener listener) { + mListeners.add(listener); + } + + public void removeChangeListener(DisplayInfoChangeListener listener) { + mListeners.remove(listener); + } + + private boolean onChange(Message msg) { + for (int i = mListeners.size() - 1; i >= 0; i--) { + mListeners.get(i).onDisplayInfoChanged(mInfo, msg.what); + } + return true; + } + + public static class Info { + + public final int id; + public final int rotation; + public final int singleFrameMs; + + public final Point realSize; + public final Point smallestSize; + public final Point largestSize; + + private Info(Context context) { + Display display = context.getSystemService(WindowManager.class).getDefaultDisplay(); + + id = display.getDisplayId(); + rotation = display.getRotation(); + + float refreshRate = display.getRefreshRate(); + singleFrameMs = refreshRate > 0 ? (int) (1000 / refreshRate) : 16; + + realSize = new Point(); + smallestSize = new Point(); + largestSize = new Point(); + display.getRealSize(realSize); + display.getCurrentSizeRange(smallestSize, largestSize); + } + + private boolean hasDifferentSize(Info info) { + if (!realSize.equals(info.realSize) + && !realSize.equals(info.realSize.y, info.realSize.x)) { + Log.d(TAG, String.format("Display size changed from %s to %s", + info.realSize, realSize)); + return true; + } + + if (!smallestSize.equals(info.smallestSize) || !largestSize.equals(info.largestSize)) { + Log.d(TAG, String.format("Available size changed from [%s, %s] to [%s, %s]", + smallestSize, largestSize, info.smallestSize, info.largestSize)); + return true; + } + + return false; + } + } + + /** + * Interface for listening for display changes + */ + public interface DisplayInfoChangeListener { + + void onDisplayInfoChanged(Info info, int flags); + } +} diff --git a/src/com/android/launcher3/views/BaseDragLayer.java b/src/com/android/launcher3/views/BaseDragLayer.java index f2f2f3b537..799762d8fe 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_CANCEL; import static android.view.MotionEvent.ACTION_DOWN; import static android.view.MotionEvent.ACTION_UP; -import static com.android.launcher3.Utilities.SINGLE_FRAME_MS; +import static com.android.launcher3.util.DefaultDisplay.getSingleFrameMs; import android.annotation.TargetApi; import android.content.Context; @@ -41,7 +41,6 @@ import android.widget.FrameLayout; import com.android.launcher3.AbstractFloatingView; import com.android.launcher3.InsettableFrameLayout; import com.android.launcher3.Utilities; -import com.android.launcher3.testing.TestProtocol; import com.android.launcher3.util.MultiValueAlpha; import com.android.launcher3.util.MultiValueAlpha.AlphaProperty; import com.android.launcher3.util.TouchController; @@ -219,7 +218,7 @@ public abstract class BaseDragLayer // This can happen if something goes wrong during a state change/transition. AbstractFloatingView floatingView = (AbstractFloatingView) child; if (floatingView.isOpen()) { - postDelayed(() -> floatingView.close(false), SINGLE_FRAME_MS); + postDelayed(() -> floatingView.close(false), getSingleFrameMs(getContext())); } } } From e734efba8dc58ea145dc0a620f18cbe2032f70ce Mon Sep 17 00:00:00 2001 From: Jon Miranda Date: Tue, 23 Jul 2019 15:22:30 -0700 Subject: [PATCH 079/108] Fix bug where rounded corners were being set despite being disabled. Bug: 138117089 Change-Id: Icb852e2e07d80c45ad3406ef432b89720887fccf --- .../android/launcher3/QuickstepAppTransitionManagerImpl.java | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/quickstep/src/com/android/launcher3/QuickstepAppTransitionManagerImpl.java b/quickstep/src/com/android/launcher3/QuickstepAppTransitionManagerImpl.java index 44324cb2e4..b60a017dd8 100644 --- a/quickstep/src/com/android/launcher3/QuickstepAppTransitionManagerImpl.java +++ b/quickstep/src/com/android/launcher3/QuickstepAppTransitionManagerImpl.java @@ -32,6 +32,7 @@ import static com.android.launcher3.dragndrop.DragLayer.ALPHA_INDEX_TRANSITIONS; import static com.android.launcher3.views.FloatingIconView.SHAPE_PROGRESS_DURATION; import static com.android.quickstep.TaskUtils.taskIsATargetWithMode; import static com.android.systemui.shared.system.QuickStepContract.getWindowCornerRadius; +import static com.android.systemui.shared.system.QuickStepContract.supportsRoundedCornersOnWindows; import static com.android.systemui.shared.system.RemoteAnimationTargetCompat.MODE_CLOSING; import static com.android.systemui.shared.system.RemoteAnimationTargetCompat.MODE_OPENING; @@ -495,6 +496,8 @@ public abstract class QuickstepAppTransitionManagerImpl extends LauncherAppTrans endCrop = windowTargetBounds.height(); } + final float initialWindowRadius = supportsRoundedCornersOnWindows(mLauncher.getResources()) + ? startCrop / 2f : 0f; final float windowRadius = mDeviceProfile.isMultiWindowMode ? 0 : getWindowCornerRadius(mLauncher.getResources()); appAnimator.addUpdateListener(new MultiValueUpdateListener() { @@ -506,7 +509,7 @@ public abstract class QuickstepAppTransitionManagerImpl extends LauncherAppTrans alphaDuration, LINEAR); FloatProp mCroppedSize = new FloatProp(startCrop, endCrop, 0, CROP_DURATION, EXAGGERATED_EASE); - FloatProp mWindowRadius = new FloatProp(startCrop / 2f, windowRadius, 0, + FloatProp mWindowRadius = new FloatProp(initialWindowRadius, windowRadius, 0, RADIUS_DURATION, EXAGGERATED_EASE); @Override From 0832d4778136d66062dc36e4f092920e0da0ac93 Mon Sep 17 00:00:00 2001 From: Hyunyoung Song Date: Wed, 24 Jul 2019 17:20:18 -0700 Subject: [PATCH 080/108] Folder text should show dark highlight when longpressed Broken only on dark theme + super bright wallpaper Bug: 138245847 Change-Id: Ib8627ebd49ac2b31bbd747c15ae6b55eb22efffa --- res/values/styles.xml | 1 + 1 file changed, 1 insertion(+) diff --git a/res/values/styles.xml b/res/values/styles.xml index 881f65d276..339aef5b60 100644 --- a/res/values/styles.xml +++ b/res/values/styles.xml @@ -104,6 +104,7 @@