diff --git a/Android.bp b/Android.bp index e3dd5e56ad..c5832441c7 100644 --- a/Android.bp +++ b/Android.bp @@ -29,23 +29,3 @@ java_library_static { ], platform_apis: true, } - - -android_library { - name: "icon-loader", - sdk_version: "28", - static_libs: [ - "androidx.core_core", - ], - resource_dirs: [ - "res", - ], - srcs: [ - "src/com/android/launcher3/icons/BaseIconFactory.java", - "src/com/android/launcher3/icons/BitmapInfo.java", - "src/com/android/launcher3/icons/IconNormalizer.java", - "src/com/android/launcher3/icons/FixedScaleDrawable.java", - "src/com/android/launcher3/icons/ShadowGenerator.java", - "src/com/android/launcher3/icons/ColorExtractor.java", - ], -} diff --git a/Android.mk b/Android.mk index 5614e25cac..422c6f02b1 100644 --- a/Android.mk +++ b/Android.mk @@ -37,6 +37,14 @@ LOCAL_UNINSTALLABLE_MODULE := true LOCAL_SDK_VERSION := current include $(BUILD_PREBUILT) +include $(CLEAR_VARS) +LOCAL_MODULE := libLauncherProtos +LOCAL_MODULE_TAGS := optional +LOCAL_MODULE_CLASS := JAVA_LIBRARIES +LOCAL_SRC_FILES := libs/launcher_protos.jar +LOCAL_UNINSTALLABLE_MODULE := true +LOCAL_SDK_VERSION := current +include $(BUILD_PREBUILT) # # Build rule for plugin lib (needed to write a plugin). # @@ -67,7 +75,8 @@ LOCAL_MODULE_TAGS := optional LOCAL_STATIC_ANDROID_LIBRARIES := \ androidx.recyclerview_recyclerview \ androidx.dynamicanimation_dynamicanimation \ - androidx.preference_preference + androidx.preference_preference \ + iconloader LOCAL_STATIC_JAVA_LIBRARIES := LauncherPluginLib @@ -161,10 +170,10 @@ LOCAL_AAPT2_ONLY := true LOCAL_MODULE_TAGS := optional ifneq (,$(wildcard frameworks/base)) - LOCAL_STATIC_JAVA_LIBRARIES := SystemUISharedLib + LOCAL_STATIC_JAVA_LIBRARIES := SystemUISharedLib launcherprotosnano LOCAL_PRIVATE_PLATFORM_APIS := true else - LOCAL_STATIC_JAVA_LIBRARIES := libSharedSystemUI + LOCAL_STATIC_JAVA_LIBRARIES := libSharedSystemUI libLauncherProtos LOCAL_SDK_VERSION := system_current LOCAL_MIN_SDK_VERSION := 26 endif @@ -225,10 +234,10 @@ LOCAL_USE_AAPT2 := true LOCAL_MODULE_TAGS := optional ifneq (,$(wildcard frameworks/base)) - LOCAL_STATIC_JAVA_LIBRARIES := SystemUISharedLib + LOCAL_STATIC_JAVA_LIBRARIES := SystemUISharedLib launcherprotosnano LOCAL_PRIVATE_PLATFORM_APIS := true else - LOCAL_STATIC_JAVA_LIBRARIES := libSharedSystemUI + LOCAL_STATIC_JAVA_LIBRARIES := libSharedSystemUI libLauncherProtos LOCAL_SDK_VERSION := system_current LOCAL_MIN_SDK_VERSION := 26 endif diff --git a/build.gradle b/build.gradle index 476e92bf67..33409c5d02 100644 --- a/build.gradle +++ b/build.gradle @@ -4,19 +4,17 @@ buildscript { google() } dependencies { - classpath 'com.android.tools.build:gradle:3.2.1' - classpath 'com.google.protobuf:protobuf-gradle-plugin:0.8.6' + classpath GRADLE_CLASS_PATH + classpath PROTOBUF_CLASS_PATH } } -final String SUPPORT_LIBS_VERSION = '1.0.0-alpha1' - apply plugin: 'com.android.application' apply plugin: 'com.google.protobuf' android { - compileSdkVersion 28 - buildToolsVersion '28.0.3' + compileSdkVersion COMPILE_SDK.toInteger() + buildToolsVersion BUILD_TOOLS_VERSION defaultConfig { minSdkVersion 21 @@ -120,9 +118,15 @@ repositories { } dependencies { - implementation "androidx.dynamicanimation:dynamicanimation:${SUPPORT_LIBS_VERSION}" - implementation "androidx.recyclerview:recyclerview:${SUPPORT_LIBS_VERSION}" - implementation 'com.google.protobuf.nano:protobuf-javanano:3.0.0-alpha-7' + implementation "androidx.dynamicanimation:dynamicanimation:${ANDROID_X_VERSION}" + implementation "androidx.recyclerview:recyclerview:${ANDROID_X_VERSION}" + implementation "androidx.preference:preference:${ANDROID_X_VERSION}" + implementation PROTOBUF_DEPENDENCY + implementation project(':IconLoader') + + // This is already included in sysui_shared + aospImplementation fileTree(dir: "libs", include: 'plugin_core.jar') + l3goImplementation fileTree(dir: "libs", include: 'plugin_core.jar') quickstepImplementation fileTree(dir: "quickstep/libs", include: 'sysui_shared.jar') @@ -133,7 +137,7 @@ dependencies { androidTestImplementation 'com.android.support.test:runner:1.0.0' androidTestImplementation 'com.android.support.test:rules:1.0.0' androidTestImplementation 'com.android.support.test.uiautomator:uiautomator-v18:2.1.2' - androidTestImplementation "androidx.annotation:annotation:${SUPPORT_LIBS_VERSION}" + androidTestImplementation "androidx.annotation:annotation:${ANDROID_X_VERSION}" } protobuf { diff --git a/go/res/drawable/ic_widget.xml b/go/res/drawable/ic_widget.xml deleted file mode 100644 index 53368760ee..0000000000 --- a/go/res/drawable/ic_widget.xml +++ /dev/null @@ -1,25 +0,0 @@ - - - - diff --git a/go/res/values-af/strings.xml b/go/res/values-af/strings.xml deleted file mode 100644 index 10ac473c1f..0000000000 --- a/go/res/values-af/strings.xml +++ /dev/null @@ -1,26 +0,0 @@ - - - - - "Raak en hou om \'n kortpad op te tel." - "Dubbeltik en hou om \'n kortpad op te tel of gebruik gepasmaakte handelinge." - "Kortpaaie" - "%1$s-kortpaaie" - diff --git a/go/res/values-am/strings.xml b/go/res/values-am/strings.xml deleted file mode 100644 index b3b253f423..0000000000 --- a/go/res/values-am/strings.xml +++ /dev/null @@ -1,26 +0,0 @@ - - - - - "አንድ አቋራጭ ለመውሰድ ነክተው ይያዙ" - "አንድ አቋራጭ ለመውሰድ ወይም ብጁ እርምጃዎችን ለመጠቀም ሁለቴ መታ አድርገው ይያዙ።" - "አቋራጮች" - "%1$s አቋራጮች" - diff --git a/go/res/values-ar/strings.xml b/go/res/values-ar/strings.xml deleted file mode 100644 index 9888d0f7ca..0000000000 --- a/go/res/values-ar/strings.xml +++ /dev/null @@ -1,26 +0,0 @@ - - - - - "المس مع الاستمرار لاختيار اختصار." - "يمكنك النقر مرّتين مع الاستمرار لاختيار اختصار أو استخدام الإجراءات المخصصة." - "الاختصارات" - "اختصارات %1$s" - diff --git a/go/res/values-as/strings.xml b/go/res/values-as/strings.xml deleted file mode 100644 index 6b5807f97b..0000000000 --- a/go/res/values-as/strings.xml +++ /dev/null @@ -1,26 +0,0 @@ - - - - - "কোনো শ্বৰ্টকাট বাছনি কৰিবলৈ স্পৰ্শ কৰি ৰাখক।" - "কোনো শ্বৰ্টকাট বাছনি কৰিবলৈ দুবাৰ টিপি ৰাখক বা নিজৰ উপযোগিতা অনুসৰি বনোৱা কাৰ্যসমূহ ব্যৱহাৰ কৰক।" - "শ্বৰ্টকাটসমূহ" - "%1$s শ্বৰ্টকাটসমূহ" - diff --git a/go/res/values-az/strings.xml b/go/res/values-az/strings.xml deleted file mode 100644 index c4b8cb7801..0000000000 --- a/go/res/values-az/strings.xml +++ /dev/null @@ -1,26 +0,0 @@ - - - - - "Qısayolu seçmək üçün toxunub saxlayın." - "Qısayolu seçmək üçün iki dəfə basıb saxlayın və ya fərdi əməliyyatlardan istifadə edin." - "Qısayollar" - "%1$s qısayolları" - diff --git a/go/res/values-b+sr+Latn/strings.xml b/go/res/values-b+sr+Latn/strings.xml deleted file mode 100644 index 0da5699410..0000000000 --- a/go/res/values-b+sr+Latn/strings.xml +++ /dev/null @@ -1,26 +0,0 @@ - - - - - "Dodirnite i zadržite da biste izabrali prečicu." - "Dvaput dodirnite i zadržite da biste izabrali prečicu ili koristite prilagođene radnje." - "Prečice" - "Prečice za %1$s" - diff --git a/go/res/values-be/strings.xml b/go/res/values-be/strings.xml deleted file mode 100644 index 4189e35fa0..0000000000 --- a/go/res/values-be/strings.xml +++ /dev/null @@ -1,26 +0,0 @@ - - - - - "Дакраніцеся і ўтрымлiвайце ярлык, каб дадаць яго." - "Дакраніцеся двойчы і ўтрымлівайце, каб выбраць ярлык або выкарыстоўваць спецыяльныя дзеянні." - "Ярлыкі" - "Ярлыкі %1$s" - diff --git a/go/res/values-bg/strings.xml b/go/res/values-bg/strings.xml deleted file mode 100644 index 1b85992d99..0000000000 --- a/go/res/values-bg/strings.xml +++ /dev/null @@ -1,26 +0,0 @@ - - - - - "Докоснете и задръжте за избор на пряк път." - "Докоснете двукратно и задръжте за избор на пряк път или използвайте персонализирани действия." - "Преки пътища" - "Преки пътища за %1$s" - diff --git a/go/res/values-bn/strings.xml b/go/res/values-bn/strings.xml deleted file mode 100644 index c56c925a29..0000000000 --- a/go/res/values-bn/strings.xml +++ /dev/null @@ -1,26 +0,0 @@ - - - - - "কোনও শর্টকাট বেছে নিতে টাচ করে ধরে রাখুন।" - "কোনও শর্টকাট বেছে নিতে ডাবল ট্যাপ করে ধরে রাখুন অথবা কাস্টম ক্রিয়াগুলি ব্যবহার করুন।" - "শর্টকাট" - "%1$s এর শর্টকাট" - diff --git a/go/res/values-bs/strings.xml b/go/res/values-bs/strings.xml deleted file mode 100644 index 3141b9d8fd..0000000000 --- a/go/res/values-bs/strings.xml +++ /dev/null @@ -1,26 +0,0 @@ - - - - - "Dodirnite i držite da uzmete prečicu." - "Dodirnite dvaput i držite da uzmete prečicu ili koristite prilagođene akcije." - "Prečice" - "Prečice aplikacije %1$s" - diff --git a/go/res/values-ca/strings.xml b/go/res/values-ca/strings.xml deleted file mode 100644 index 3b5c3f7b56..0000000000 --- a/go/res/values-ca/strings.xml +++ /dev/null @@ -1,26 +0,0 @@ - - - - - "Mantén premuda una drecera per seleccionar-la." - "Fes doble toc i mantén premut per seleccionar una drecera o per utilitzar accions personalitzades." - "Dreceres" - "Dreceres de l\'aplicació %1$s" - diff --git a/go/res/values-cs/strings.xml b/go/res/values-cs/strings.xml deleted file mode 100644 index e4018f2c0f..0000000000 --- a/go/res/values-cs/strings.xml +++ /dev/null @@ -1,26 +0,0 @@ - - - - - "Zkratku vyberete podržením." - "Dvojitým klepnutím a podržením vyberte zkratku, případně použijte vlastní akce." - "Zkratky" - "Zkratky aplikace %1$s" - diff --git a/go/res/values-da/strings.xml b/go/res/values-da/strings.xml deleted file mode 100644 index 821d36a7da..0000000000 --- a/go/res/values-da/strings.xml +++ /dev/null @@ -1,26 +0,0 @@ - - - - - "Hold en genvej nede for at samle den op." - "Tryk to gange, og hold en genvej nede for at samle den op og bruge tilpassede handlinger." - "Genveje" - "%1$s-genveje" - diff --git a/go/res/values-de/strings.xml b/go/res/values-de/strings.xml deleted file mode 100644 index 43a1b3a9e1..0000000000 --- a/go/res/values-de/strings.xml +++ /dev/null @@ -1,26 +0,0 @@ - - - - - "Doppeltippen und halten, um eine Verknüpfung auszuwählen." - "Doppeltippen und halten, um eine Verknüpfung auszuwählen oder benutzerdefinierte Aktionen zu nutzen." - "Verknüpfungen" - "%1$s-Verknüpfungen" - diff --git a/go/res/values-el/strings.xml b/go/res/values-el/strings.xml deleted file mode 100644 index ae59907d16..0000000000 --- a/go/res/values-el/strings.xml +++ /dev/null @@ -1,26 +0,0 @@ - - - - - "Αγγίξτε παρατεταμένα για να σηκώσετε μια συντόμευση." - "Πατήσετε δύο φορές παρατεταμένα για να σηκώσετε μια συντόμευση ή για να χρησιμοποιήσετε προσαρμοσμένες ενέργειες." - "Συντομεύσεις" - "Συντομεύσεις %1$s" - diff --git a/go/res/values-en-rAU/strings.xml b/go/res/values-en-rAU/strings.xml deleted file mode 100644 index 2ee2c26457..0000000000 --- a/go/res/values-en-rAU/strings.xml +++ /dev/null @@ -1,26 +0,0 @@ - - - - - "Touch & hold to pick up a shortcut." - "Double-tap & hold to pick up a shortcut or use custom actions." - "Shortcuts" - "%1$s shortcuts" - diff --git a/go/res/values-en-rGB/strings.xml b/go/res/values-en-rGB/strings.xml deleted file mode 100644 index 2ee2c26457..0000000000 --- a/go/res/values-en-rGB/strings.xml +++ /dev/null @@ -1,26 +0,0 @@ - - - - - "Touch & hold to pick up a shortcut." - "Double-tap & hold to pick up a shortcut or use custom actions." - "Shortcuts" - "%1$s shortcuts" - diff --git a/go/res/values-en-rIN/strings.xml b/go/res/values-en-rIN/strings.xml deleted file mode 100644 index 2ee2c26457..0000000000 --- a/go/res/values-en-rIN/strings.xml +++ /dev/null @@ -1,26 +0,0 @@ - - - - - "Touch & hold to pick up a shortcut." - "Double-tap & hold to pick up a shortcut or use custom actions." - "Shortcuts" - "%1$s shortcuts" - diff --git a/go/res/values-es-rUS/strings.xml b/go/res/values-es-rUS/strings.xml deleted file mode 100644 index 5212c035d3..0000000000 --- a/go/res/values-es-rUS/strings.xml +++ /dev/null @@ -1,26 +0,0 @@ - - - - - "Mantén presionado para elegir un acceso directo." - "Presiona dos veces y mantén presionado para elegir un acceso directo o usar acciones personalizadas." - "Accesos directos" - "Accesos directos de %1$s" - diff --git a/go/res/values-es/strings.xml b/go/res/values-es/strings.xml deleted file mode 100644 index 3ae45889cf..0000000000 --- a/go/res/values-es/strings.xml +++ /dev/null @@ -1,26 +0,0 @@ - - - - - "Mantén pulsado el acceso directo que quieras." - "Toca dos veces y mantén pulsado el acceso directo o utiliza acciones personalizadas." - "Accesos directos" - "Accesos directos de %1$s" - diff --git a/go/res/values-et/strings.xml b/go/res/values-et/strings.xml deleted file mode 100644 index 2513e65a33..0000000000 --- a/go/res/values-et/strings.xml +++ /dev/null @@ -1,26 +0,0 @@ - - - - - "Otsetee valimiseks puudutage seda pikalt." - "Topeltpuudutage ja hoidke otsetee valimiseks või kohandatud toimingute kasutamiseks." - "Otseteed" - "Rakenduse %1$s otseteed" - diff --git a/go/res/values-eu/strings.xml b/go/res/values-eu/strings.xml deleted file mode 100644 index 9949ef091d..0000000000 --- a/go/res/values-eu/strings.xml +++ /dev/null @@ -1,26 +0,0 @@ - - - - - "Eduki sakatuta lasterbide bat aukeratzeko." - "Sakatu birritan eta eduki sakatuta lasterbide bat aukeratzeko edo ekintza pertsonalizatuak erabiltzeko." - "Lasterbideak" - "%1$s aplikazioaren lasterbidea" - diff --git a/go/res/values-fa/strings.xml b/go/res/values-fa/strings.xml deleted file mode 100644 index f1584d9ff7..0000000000 --- a/go/res/values-fa/strings.xml +++ /dev/null @@ -1,26 +0,0 @@ - - - - - "برای انتخاب یک میان‌بر، لمس کنید و نگه‌دارید." - "برای انتخاب میان‌بر، دو ضربه سریع بزنید و نگه دارید یا از کنش‌های سفارشی استفاده کنید." - "میان‌برها" - "میان‌برهای %1$s" - diff --git a/go/res/values-fi/strings.xml b/go/res/values-fi/strings.xml deleted file mode 100644 index da9b0e1c42..0000000000 --- a/go/res/values-fi/strings.xml +++ /dev/null @@ -1,26 +0,0 @@ - - - - - "Valitse pikakuvake painamalla sitä pitkään." - "Valitse pikakuvake tai käytä muokattuja toimintoja kaksoisnapauttamalla ja painamalla pitkään." - "Pikakuvakkeet" - "Kohteen %1$s pikakuvakkeet" - diff --git a/go/res/values-fr-rCA/strings.xml b/go/res/values-fr-rCA/strings.xml deleted file mode 100644 index c7fd6d6423..0000000000 --- a/go/res/values-fr-rCA/strings.xml +++ /dev/null @@ -1,26 +0,0 @@ - - - - - "Maintenez un doigt sur le raccourci pour l\'ajouter" - "Touchez 2x un raccourci et maintenez doigt dessus pour l’aj. ou utiliser des actions personnalisées." - "Raccourcis" - "Raccourcis : %1$s" - diff --git a/go/res/values-fr/strings.xml b/go/res/values-fr/strings.xml deleted file mode 100644 index 238fe73d75..0000000000 --- a/go/res/values-fr/strings.xml +++ /dev/null @@ -1,26 +0,0 @@ - - - - - "Appui prolongé pour sélectionner raccourci." - "Appuyez 2 fois et maintenez pression pour sélectionner raccourci ou utilisez actions personnalisées." - "Raccourcis" - "Raccourcis %1$s" - diff --git a/go/res/values-gl/strings.xml b/go/res/values-gl/strings.xml deleted file mode 100644 index 31621d5c2c..0000000000 --- a/go/res/values-gl/strings.xml +++ /dev/null @@ -1,26 +0,0 @@ - - - - - "Mantén premido un atallo para seleccionalo." - "Toca dúas veces e mantén premido para seleccionar un atallo ou utiliza accións personalizadas." - "Atallos" - "Atallos da aplicación %1$s" - diff --git a/go/res/values-gu/strings.xml b/go/res/values-gu/strings.xml deleted file mode 100644 index bdb549ff7f..0000000000 --- a/go/res/values-gu/strings.xml +++ /dev/null @@ -1,26 +0,0 @@ - - - - - "એક શૉર્ટકટ ચૂંટવા ટૅપ કરી રાખો." - "એક શૉર્ટકટ ચૂંટવા અથવા કોઈ કસ્ટમ ક્રિયાઓનો ઉપયોગ કરવા માટે બે વાર ટૅપ કરી રાખો." - "શૉર્ટકટ" - "%1$s શૉર્ટકટ" - diff --git a/go/res/values-hi/strings.xml b/go/res/values-hi/strings.xml deleted file mode 100644 index 2c1650a0dd..0000000000 --- a/go/res/values-hi/strings.xml +++ /dev/null @@ -1,26 +0,0 @@ - - - - - "शॉर्टकट चुनने के लिए छूकर रखें." - "शॉर्टकट चुनने के लिए दो बार छूएं और कुछ देर दबाएं रखें या अपने मुताबिक कार्रवाइयों का इस्तेमाल करें." - "शॉर्टकट" - "%1$s शॉर्टकट" - diff --git a/go/res/values-hr/strings.xml b/go/res/values-hr/strings.xml deleted file mode 100644 index fccdeb59d7..0000000000 --- a/go/res/values-hr/strings.xml +++ /dev/null @@ -1,26 +0,0 @@ - - - - - "Dodirnite i zadržite kako biste podigli prečac." - "Dvaput dodirnite i zadržite pritisak kako biste podigli prečac ili pokušajte prilagođenim radnjama." - "Prečaci" - "Prečaci za aplikaciju %1$s" - diff --git a/go/res/values-hu/strings.xml b/go/res/values-hu/strings.xml deleted file mode 100644 index 369c22745a..0000000000 --- a/go/res/values-hu/strings.xml +++ /dev/null @@ -1,26 +0,0 @@ - - - - - "Felvételhez tartsa nyomva a parancsikont." - "Parancsikon felvételéhez koppintson rá duplán és tartsa nyomva, vagy használjon egyéni műveleteket." - "Parancsikonok" - "%1$s-parancsikonok" - diff --git a/go/res/values-hy/strings.xml b/go/res/values-hy/strings.xml deleted file mode 100644 index 4747f6df35..0000000000 --- a/go/res/values-hy/strings.xml +++ /dev/null @@ -1,26 +0,0 @@ - - - - - "Կրկնակի հպեք և պահեք՝ դյուրանցում ընտրելու համար։" - "Կրկնակի հպեք և պահեք՝ դյուրանցում ընտրելու համար կամ օգտվեք հարմարեցրած գործողություններից:" - "Դյուրանցումներ" - "%1$s դյուրանցումներ" - diff --git a/go/res/values-in/strings.xml b/go/res/values-in/strings.xml deleted file mode 100644 index c8b9da306d..0000000000 --- a/go/res/values-in/strings.xml +++ /dev/null @@ -1,26 +0,0 @@ - - - - - "Tap lama untuk memilih pintasan." - "Tap dua kali & tahan untuk memilih pintasan atau menggunakan tindakan khusus." - "Pintasan" - "Pintasan %1$s" - diff --git a/go/res/values-is/strings.xml b/go/res/values-is/strings.xml deleted file mode 100644 index b8bb923746..0000000000 --- a/go/res/values-is/strings.xml +++ /dev/null @@ -1,26 +0,0 @@ - - - - - "Haltu fingri á flýtileið til að grípa hana." - "Ýttu tvisvar og haltu fingri á flýtileið til að grípa hana eða notaðu sérsniðnar aðgerðir." - "Flýtileiðir" - "%1$s flýtileiðir" - diff --git a/go/res/values-it/strings.xml b/go/res/values-it/strings.xml deleted file mode 100644 index bc5d99863d..0000000000 --- a/go/res/values-it/strings.xml +++ /dev/null @@ -1,26 +0,0 @@ - - - - - "Tocca e tieni premuto per scegliere la scorciatoia" - "Tocca due volte e tieni premuto per scegliere una scorciatoia o per usare azioni personalizzate." - "Scorciatoie" - "Scorciatoie di %1$s" - diff --git a/go/res/values-iw/strings.xml b/go/res/values-iw/strings.xml deleted file mode 100644 index f541d4d316..0000000000 --- a/go/res/values-iw/strings.xml +++ /dev/null @@ -1,26 +0,0 @@ - - - - - "כדי להוסיף קיצור דרך, מקישים עליו פעמיים ומחזיקים." - "כדי להוסיף קיצור דרך או להשתמש בפעולות מותאמות אישית, מקישים על קיצור הדרך פעמיים ומחזיקים." - "קיצורי דרך" - "קיצורי דרך לאפליקציה %1$s" - diff --git a/go/res/values-ja/strings.xml b/go/res/values-ja/strings.xml deleted file mode 100644 index 8f02d7f4eb..0000000000 --- a/go/res/values-ja/strings.xml +++ /dev/null @@ -1,26 +0,0 @@ - - - - - "ショートカットを追加するには押し続けます。" - "ダブルタップ後に押し続けてショートカットを選択するか、カスタム操作を使用してください。" - "ショートカット" - "「%1$s」のショートカット" - diff --git a/go/res/values-ka/strings.xml b/go/res/values-ka/strings.xml deleted file mode 100644 index 1b46534788..0000000000 --- a/go/res/values-ka/strings.xml +++ /dev/null @@ -1,26 +0,0 @@ - - - - - "შეეხეთ და დააყოვნეთ მალსახმობის ასარჩევად." - "ორმაგად შეეხეთ და გეჭიროთ მალსახმობის ასარჩევად ან მორგებული მოქმედებების გამოსაყენებლად." - "მალსახმობები" - "%1$s-ის მალსახმობები" - diff --git a/go/res/values-kk/strings.xml b/go/res/values-kk/strings.xml deleted file mode 100644 index e909818afc..0000000000 --- a/go/res/values-kk/strings.xml +++ /dev/null @@ -1,26 +0,0 @@ - - - - - "Таңбашаны таңдау үшін оны түртіп, ұстап тұрыңыз." - "Таңбашаны таңдау немесе арнаулы әрекеттерді пайдалану үшін екі рет түртіп, ұстап тұрыңыз." - "Таңбашалар" - "%1$s таңбаша" - diff --git a/go/res/values-km/strings.xml b/go/res/values-km/strings.xml deleted file mode 100644 index 40082a4b9d..0000000000 --- a/go/res/values-km/strings.xml +++ /dev/null @@ -1,26 +0,0 @@ - - - - - "ប៉ះ ហើយចុចឲ្យជាប់ដើម្បីរើសផ្លូវកាត់មួយ។" - "ប៉ះពីរដង ហើយចុចឱ្យជាប់ដើម្បីរើសផ្លូវកាត់មួយ ឬប្រើសកម្មភាពផ្ទាល់ខ្លួន។" - "ផ្លូវកាត់" - "ផ្លូវកាត់សម្រាប់ %1$s" - diff --git a/go/res/values-kn/strings.xml b/go/res/values-kn/strings.xml deleted file mode 100644 index 9c121fd294..0000000000 --- a/go/res/values-kn/strings.xml +++ /dev/null @@ -1,26 +0,0 @@ - - - - - "ಸ್ಪರ್ಶಿಸಿ ಮತ್ತು ಶಾರ್ಟ್‌ಕಟ್ ಆರಿಸಲು ಹೋಲ್ಡ್ ಮಾಡಿ." - "ಡಬಲ್ ಟ್ಯಾಪ್ ಮಾಡಿ ಮತ್ತು ಶಾರ್ಟ್‌ಕಟ್ ಆರಿಸಿಕೊಳ್ಳಲು ಹೋಲ್ಡ್ ಮಾಡಿ ಅಥವಾ ಕಸ್ಟಮ್ ಕ್ರಿಯೆಗಳನ್ನು ಬಳಸಿ." - "ಶಾರ್ಟ್‌ಕಟ್‌ಗಳು" - "%1$s ಶಾರ್ಟ್‌ಕಟ್‌ಗಳು" - diff --git a/go/res/values-ko/strings.xml b/go/res/values-ko/strings.xml deleted file mode 100644 index 60f925e36b..0000000000 --- a/go/res/values-ko/strings.xml +++ /dev/null @@ -1,26 +0,0 @@ - - - - - "바로가기를 선택하려면 길게 터치하세요." - "바로가기를 선택하려면 두 번 탭한 다음 길게 터치하거나 맞춤 액션을 사용합니다." - "바로가기" - "%1$s 바로가기" - diff --git a/go/res/values-ky/strings.xml b/go/res/values-ky/strings.xml deleted file mode 100644 index 4c7e973cef..0000000000 --- a/go/res/values-ky/strings.xml +++ /dev/null @@ -1,26 +0,0 @@ - - - - - "Кыска жолду тандоо үчүн басып туруңуз." - "Кыска жолду тандоо үчүн эки жолу таптап, кармап туруңуз же ыңгайлаштырылган аракеттерди колдонуңуз." - "Кыска жолдор" - "%1$s кыска жол" - diff --git a/go/res/values-lo/strings.xml b/go/res/values-lo/strings.xml deleted file mode 100644 index 7864884acc..0000000000 --- a/go/res/values-lo/strings.xml +++ /dev/null @@ -1,26 +0,0 @@ - - - - - "ແຕະຄ້າງໄວ້ເພື່ອຮັບປຸ່ມລັດ." - "ແຕະສອງເທື່ອຄ້າງໄວ້ເພື່ອຮັບປຸ່ມລັດ ຫຼື ໃຊ້ຄຳສັ່ງແບບກຳນົດເອງ." - "ປຸ່ມລັດ" - "ປຸ່ມລັດ %1$s" - diff --git a/go/res/values-lt/strings.xml b/go/res/values-lt/strings.xml deleted file mode 100644 index 8f49032cfb..0000000000 --- a/go/res/values-lt/strings.xml +++ /dev/null @@ -1,26 +0,0 @@ - - - - - "Dukart pal. ir palaik., kad pasir. spart. klav." - "Dukart palieskite ir palaikykite, kad pasirinkt. spartųjį klavišą ar naudotumėte tinkintus veiksmus." - "Spartieji klavišai" - "„%1$s“ spartieji klavišai" - diff --git a/go/res/values-lv/strings.xml b/go/res/values-lv/strings.xml deleted file mode 100644 index 04315ebaa0..0000000000 --- a/go/res/values-lv/strings.xml +++ /dev/null @@ -1,26 +0,0 @@ - - - - - "Lai izvēlētos saīsni, pieskarieties un turiet to." - "Lai atlasītu saīsni, veiciet dubultskārienu uz tās un turiet to vai arī veiciet pielāgotas darbības." - "Saīsnes" - "Lietotnes %1$s saīsnes" - diff --git a/go/res/values-mk/strings.xml b/go/res/values-mk/strings.xml deleted file mode 100644 index 52d66b5e28..0000000000 --- a/go/res/values-mk/strings.xml +++ /dev/null @@ -1,26 +0,0 @@ - - - - - "Допрете двапати и задржете за да изберете кратенка." - "Допрете двапати и задржете за да изберете кратенка или да користите приспособени дејства." - "Кратенки" - "Кратенки за %1$s" - diff --git a/go/res/values-ml/strings.xml b/go/res/values-ml/strings.xml deleted file mode 100644 index b3c12e16e1..0000000000 --- a/go/res/values-ml/strings.xml +++ /dev/null @@ -1,26 +0,0 @@ - - - - - "ഒരു കുറുക്കുവഴി ചേർക്കുന്നതിന് അത് സ്‌പർശിച്ച് പിടിക്കുക." - "ഒരു കുറുക്കുവഴി തിരഞ്ഞെടുക്കാനോ ഇഷ്ടാനുസൃത പ്രവർത്തനങ്ങൾ ഉപയോഗിക്കാനോ രണ്ടുതവണ ടാപ്പുചെയ്ത് പിടിക്കുക." - "കുറുക്കുവഴികൾ" - "%1$s കുറുക്കുവഴികൾ" - diff --git a/go/res/values-mn/strings.xml b/go/res/values-mn/strings.xml deleted file mode 100644 index c89dfd1bdc..0000000000 --- a/go/res/values-mn/strings.xml +++ /dev/null @@ -1,26 +0,0 @@ - - - - - "Товчлол авах бол удаан дарна уу." - "Товчлол авах болон тохируулсан үйлдлийг ашиглахын тулд хоёр товшоод хүлээнэ үү." - "Товчлол" - "%1$s-н товчлол" - diff --git a/go/res/values-mr/strings.xml b/go/res/values-mr/strings.xml deleted file mode 100644 index 2c767b4f19..0000000000 --- a/go/res/values-mr/strings.xml +++ /dev/null @@ -1,26 +0,0 @@ - - - - - "शॉर्टकट निवडण्यासाठी स्पर्श करा आणि धरून ठेवा." - "शॉर्टकट निवडण्यासाठी किंवा कस्टम क्रिया वापरण्यासाठी दोनदा टॅप करा आणि धरून ठेवा." - "शॉर्टकट" - "%1$s शॉर्टकट" - diff --git a/go/res/values-ms/strings.xml b/go/res/values-ms/strings.xml deleted file mode 100644 index 42add9a197..0000000000 --- a/go/res/values-ms/strings.xml +++ /dev/null @@ -1,26 +0,0 @@ - - - - - "Sentuh & tahan untuk mengambil pintasan." - "Ketik dua kali & tahan untuk mengambil pintasan atau menggunakan tindakan tersuai." - "Pintasan" - "Pintasan %1$s" - diff --git a/go/res/values-my/strings.xml b/go/res/values-my/strings.xml deleted file mode 100644 index 5784df63bf..0000000000 --- a/go/res/values-my/strings.xml +++ /dev/null @@ -1,26 +0,0 @@ - - - - - "လက်ကွက်ဖြတ်လမ်းတစ်ခုကို ရွေးရန် ထိပြီး ဖိထားပါ" - "လက်ကွက်ဖြတ်လမ်းကို ရွေးရန် (သို့) စိတ်ကြိုက်လုပ်ဆောင်ချက်များကို သုံးရန်နှစ်ချက်တို့ပြီး ဖိထားပါ။" - "ဖြတ်လမ်းလင့်ခ်များ" - "%1$s ဖြတ်လမ်းလင့်ခ်များ" - diff --git a/go/res/values-nb/strings.xml b/go/res/values-nb/strings.xml deleted file mode 100644 index 2a5ffb6e7c..0000000000 --- a/go/res/values-nb/strings.xml +++ /dev/null @@ -1,26 +0,0 @@ - - - - - "Trykk og hold for å velge en snarvei." - "Dobbelttrykk og hold for å velge en snarvei eller bruke tilpassede handlinger." - "Snarveier" - "%1$s-snarveier" - diff --git a/go/res/values-ne/strings.xml b/go/res/values-ne/strings.xml deleted file mode 100644 index 0be0375f3a..0000000000 --- a/go/res/values-ne/strings.xml +++ /dev/null @@ -1,26 +0,0 @@ - - - - - "कुनै सटकर्ट छनौट गर्न छोइराख्नुहोस्।" - "कुनै सर्टकट छनौट गर्न दुईपटक ट्याप गरेर होल्ड गर्नुहोस् वा रोजेका कारबाहीहरू प्रयोग गर्नुहोस्।" - "सर्टकटहरू" - "%1$s सर्टकटहरू" - diff --git a/go/res/values-nl/strings.xml b/go/res/values-nl/strings.xml deleted file mode 100644 index 5bcd016b4a..0000000000 --- a/go/res/values-nl/strings.xml +++ /dev/null @@ -1,26 +0,0 @@ - - - - - "Tik en houd vast om snelkoppeling toe te voegen." - "Dubbeltik en houd vast om een snelkoppeling toe te voegen of aangepaste acties te gebruiken." - "Snelkoppelingen" - "%1$s-snelkoppelingen" - diff --git a/go/res/values-or/strings.xml b/go/res/values-or/strings.xml deleted file mode 100644 index 3ec8a72038..0000000000 --- a/go/res/values-or/strings.xml +++ /dev/null @@ -1,26 +0,0 @@ - - - - - "ଏକ ଶର୍ଟକଟ୍ ଚୟନ କରିବାକୁ ଦାବି ଧରନ୍ତୁ।" - "ଡବଲ୍‌-ଟାପ୍‌ କରନ୍ତୁ ଏବଂ ଏକ ଶର୍ଟକଟ୍ ଚୟନ କରିବାକୁ ଧରି ରଖନ୍ତୁ କିମ୍ୱା କଷ୍ଟମ୍ ପ୍ରକ୍ରିୟା ବ୍ୟବହାର କରନ୍ତୁ।" - "ଶର୍ଟକଟ୍‍" - "%1$sର ଶର୍ଟକଟ୍" - diff --git a/go/res/values-pa/strings.xml b/go/res/values-pa/strings.xml deleted file mode 100644 index c7e4abf3a8..0000000000 --- a/go/res/values-pa/strings.xml +++ /dev/null @@ -1,26 +0,0 @@ - - - - - "ਕੋਈ ਸ਼ਾਰਟਕੱਟ ਚੁਣਨ ਲਈ ਸਪੱਰਸ਼ ਕਰੋ ਅਤੇ ਦਬਾ ਕੇ ਰੱਖੋ।" - "ਕੋਈ ਸ਼ਾਰਟਕੱਟ ਚੁਣਨ ਲਈ ਦੋ ਵਾਰ ਟੈਪ ਕਰੋ ਅਤੇ ਦਬਾ ਕੇ ਰੱਖੋ ਜਾਂ ਵਿਉਂਂਤੀ ਕਾਰਵਾਈਆਂ ਵਰਤੋ।" - "ਸ਼ਾਰਟਕੱਟ" - "%1$s ਸ਼ਾਰਟਕੱਟ" - diff --git a/go/res/values-pl/strings.xml b/go/res/values-pl/strings.xml deleted file mode 100644 index 0861daaa57..0000000000 --- a/go/res/values-pl/strings.xml +++ /dev/null @@ -1,26 +0,0 @@ - - - - - "Naciśnij i przytrzymaj, by wybrać skrót." - "Kliknij dwukrotnie i przytrzymaj, by wybrać skrót lub użyć działań niestandardowych." - "Skróty" - "%1$s – skróty" - diff --git a/go/res/values-pt-rPT/strings.xml b/go/res/values-pt-rPT/strings.xml deleted file mode 100644 index 7a75a05456..0000000000 --- a/go/res/values-pt-rPT/strings.xml +++ /dev/null @@ -1,26 +0,0 @@ - - - - - "Toque sem soltar para escolher um atalho." - "Toque duas vezes sem soltar para escolher um atalho ou utilize ações personalizadas." - "Atalhos" - "Atalhos da aplicação %1$s" - diff --git a/go/res/values-pt/strings.xml b/go/res/values-pt/strings.xml deleted file mode 100644 index 53bbfc41a6..0000000000 --- a/go/res/values-pt/strings.xml +++ /dev/null @@ -1,26 +0,0 @@ - - - - - "Toque e segure para selecionar um atalho." - "Toque duas vezes na tela e segure para selecionar um atalho ou usar ações personalizadas." - "Atalhos" - "Atalhos do app %1$s" - diff --git a/go/res/values-ro/strings.xml b/go/res/values-ro/strings.xml deleted file mode 100644 index 75d1796b57..0000000000 --- a/go/res/values-ro/strings.xml +++ /dev/null @@ -1,26 +0,0 @@ - - - - - "Atingeți și țineți apăsat pentru a selecta o comandă rapidă." - "Atingeți de două ori și țineți apăsat pentru comandă rapidă sau folosiți acțiuni personalizate." - "Comenzi rapide" - "Comenzi rapide pentru %1$s" - diff --git a/go/res/values-ru/strings.xml b/go/res/values-ru/strings.xml deleted file mode 100644 index 9c5c8cd340..0000000000 --- a/go/res/values-ru/strings.xml +++ /dev/null @@ -1,26 +0,0 @@ - - - - - "Чтобы выбрать ярлык, нажмите на него и удерживайте." - "Чтобы выбрать ярлык или использовать специальные действия, нажмите на него дважды и не отпускайте." - "Ярлыки" - "%1$s: ярлыки" - diff --git a/go/res/values-si/strings.xml b/go/res/values-si/strings.xml deleted file mode 100644 index 4b25c90b0b..0000000000 --- a/go/res/values-si/strings.xml +++ /dev/null @@ -1,26 +0,0 @@ - - - - - "කෙටි මගක් තෝරා ගැනීමට ස්පර්ශ කර අල්ලාගෙන සිටින්න." - "විජට් එකක් තෝරා ගැනීමට හෝ අභිරුචි භාවිත කිරීමට දෙවරක් තට්ටු කර අල්ලා ගෙන සිටින්න." - "කෙටි මං" - "කෙටි මං %1$s" - diff --git a/go/res/values-sk/strings.xml b/go/res/values-sk/strings.xml deleted file mode 100644 index fc02933734..0000000000 --- a/go/res/values-sk/strings.xml +++ /dev/null @@ -1,26 +0,0 @@ - - - - - "Skratku pridáte pridržaním." - "Skratku pridáte dvojitým klepnutím a pridržaním alebo pomocou vlastných akcií." - "Skratky" - "Skratky aplikácie %1$s" - diff --git a/go/res/values-sl/strings.xml b/go/res/values-sl/strings.xml deleted file mode 100644 index 6ecedfb166..0000000000 --- a/go/res/values-sl/strings.xml +++ /dev/null @@ -1,26 +0,0 @@ - - - - - "Pridržite bližnjico, da jo izberete." - "Dvakrat se dotaknite bližnjice in jo pridržite, da jo izberete, ali pa uporabite dejanja po meri." - "Bližnjice" - "Bližnjice za %1$s" - diff --git a/go/res/values-sq/strings.xml b/go/res/values-sq/strings.xml deleted file mode 100644 index bb74db6b55..0000000000 --- a/go/res/values-sq/strings.xml +++ /dev/null @@ -1,26 +0,0 @@ - - - - - "Prek dhe mbaj prekur për të zgjedhur një shkurtore." - "Prek dy herë dhe mbaj prekur për të zgjedhur një shkurtore ose për të përdorur veprimet e personalizuara." - "Shkurtoret" - "%1$s shkurtore" - diff --git a/go/res/values-sr/strings.xml b/go/res/values-sr/strings.xml deleted file mode 100644 index 0b9aea2f9a..0000000000 --- a/go/res/values-sr/strings.xml +++ /dev/null @@ -1,26 +0,0 @@ - - - - - "Додирните и задржите да бисте изабрали пречицу." - "Двапут додирните и задржите да бисте изабрали пречицу или користите прилагођене радње." - "Пречице" - "Пречице за %1$s" - diff --git a/go/res/values-sv/strings.xml b/go/res/values-sv/strings.xml deleted file mode 100644 index c3f434c276..0000000000 --- a/go/res/values-sv/strings.xml +++ /dev/null @@ -1,26 +0,0 @@ - - - - - "Tryck länge om du vill ta upp en genväg." - "Tryck snabbt två gånger och håll kvar om du vill ta upp en genväg eller använda anpassade åtgärder." - "Genvägar" - "Genvägar för %1$s" - diff --git a/go/res/values-sw/strings.xml b/go/res/values-sw/strings.xml deleted file mode 100644 index 13c12e4a6c..0000000000 --- a/go/res/values-sw/strings.xml +++ /dev/null @@ -1,26 +0,0 @@ - - - - - "Gusa na ushikilie ili uchague njia ya mkato." - "Gusa mara mbili na ushikilie ile uchague njia ya mkato au utumie vitendo maalum." - "Njia za mkato" - "Njia za mkato za %1$s" - diff --git a/go/res/values-ta/strings.xml b/go/res/values-ta/strings.xml deleted file mode 100644 index 50059b65f9..0000000000 --- a/go/res/values-ta/strings.xml +++ /dev/null @@ -1,26 +0,0 @@ - - - - - "குறுக்குவழியைச் சேர்க்க, தொட்டு பிடித்திருக்கவும்." - "குறுக்குவழியை சேர்க்க, இருமுறை தட்டிப் பிடித்திருக்கவும் அல்லது தனிப்பயன் செயல்களைப் பயன்படுத்தவும்." - "குறுக்குவழிகள்" - "%1$s குறுக்குவழிகள்" - diff --git a/go/res/values-te/strings.xml b/go/res/values-te/strings.xml deleted file mode 100644 index 0bdf743342..0000000000 --- a/go/res/values-te/strings.xml +++ /dev/null @@ -1,26 +0,0 @@ - - - - - "సత్వరమార్గాన్ని ఎంచుకోవడానికి తాకి & నొక్కి ఉంచండి." - "సత్వరమార్గాన్ని ఎంచుకోవడానికి లేదా అనుకూల చర్యలను ఉపయోగించడానికి రెండుసార్లు నొక్కి &ఉంచండి." - "సత్వరమార్గాలు" - "%1$s సత్వరమార్గాలు" - diff --git a/go/res/values-th/strings.xml b/go/res/values-th/strings.xml deleted file mode 100644 index e73d89fb0e..0000000000 --- a/go/res/values-th/strings.xml +++ /dev/null @@ -1,26 +0,0 @@ - - - - - "แตะค้างไว้เพื่อเลือกทางลัด" - "แตะสองครั้งค้างไว้เพื่อเลือกทางลัดหรือใช้การกระทำที่กำหนดเอง" - "ทางลัด" - "ทางลัด %1$s" - diff --git a/go/res/values-tl/strings.xml b/go/res/values-tl/strings.xml deleted file mode 100644 index 8f44ec5742..0000000000 --- a/go/res/values-tl/strings.xml +++ /dev/null @@ -1,26 +0,0 @@ - - - - - "Pindutin nang matagal upang kumuha ng shortcut." - "I-double tap nang matagal upang kumuha ng shortcut o gumamit ng mga custom na pagkilos." - "Mga Shortcut" - "Mga shortcut sa %1$s" - diff --git a/go/res/values-tr/strings.xml b/go/res/values-tr/strings.xml deleted file mode 100644 index f0f3cce6d1..0000000000 --- a/go/res/values-tr/strings.xml +++ /dev/null @@ -1,26 +0,0 @@ - - - - - "Kısayol seçmek için dokunun ve basılı tutun." - "Bir kısayolu seçmek veya özel işlemleri kullanmak için iki kez dokunun ve basılı tutun." - "Kısayollar" - "%1$s kısayolları" - diff --git a/go/res/values-uk/strings.xml b/go/res/values-uk/strings.xml deleted file mode 100644 index 8d1f58395b..0000000000 --- a/go/res/values-uk/strings.xml +++ /dev/null @@ -1,26 +0,0 @@ - - - - - "Натисніть і утримуйте, щоб вибрати ярлик." - "Двічі натисніть і утримуйте, щоб вибрати ярлик, або виконайте іншу дію." - "Ярлики" - "Ярлики додатка %1$s" - diff --git a/go/res/values-ur/strings.xml b/go/res/values-ur/strings.xml deleted file mode 100644 index 46bd823d8e..0000000000 --- a/go/res/values-ur/strings.xml +++ /dev/null @@ -1,26 +0,0 @@ - - - - - "کوئی شارٹ کٹ منتخب کرنے کیلئے ٹچ کریں اور دبائے رکھیں۔" - "کوئی شارٹ کٹ منتخب کرنے یا حسب ضرورت کاروائیاں استعمال کرنے کیلئے دو بار تھپتھپائیں اور دبائے رکھیں۔" - "شارٹ کٹس" - "%1$s شارٹ کٹس" - diff --git a/go/res/values-uz/strings.xml b/go/res/values-uz/strings.xml deleted file mode 100644 index 318bc15722..0000000000 --- a/go/res/values-uz/strings.xml +++ /dev/null @@ -1,26 +0,0 @@ - - - - - "Yorliqni tanlab olish uchun bosib turing." - "Ikki marta bosib va bosib turgan holatda yorliqni tanlang yoki maxsus amaldan foydalaning." - "Yorliqlar" - "%1$s ilovasi yorliqlari" - diff --git a/go/res/values-vi/strings.xml b/go/res/values-vi/strings.xml deleted file mode 100644 index 1197619c57..0000000000 --- a/go/res/values-vi/strings.xml +++ /dev/null @@ -1,26 +0,0 @@ - - - - - "Chạm và giữ để chọn lối tắt." - "Nhấn đúp và giữ để chọn lối tắt hoặc sử dụng hành động tùy chỉnh." - "Lối tắt" - "Lối tắt %1$s" - diff --git a/go/res/values-zh-rCN/strings.xml b/go/res/values-zh-rCN/strings.xml deleted file mode 100644 index 57351d37f5..0000000000 --- a/go/res/values-zh-rCN/strings.xml +++ /dev/null @@ -1,26 +0,0 @@ - - - - - "触摸并按住快捷方式即可选择快捷方式。" - "点按两次并按住快捷方式即可选择快捷方式,您也可以使用自定义操作。" - "快捷方式" - "%1$s快捷方式" - diff --git a/go/res/values-zh-rHK/strings.xml b/go/res/values-zh-rHK/strings.xml deleted file mode 100644 index dea7749f68..0000000000 --- a/go/res/values-zh-rHK/strings.xml +++ /dev/null @@ -1,26 +0,0 @@ - - - - - "按住捷徑即可選取捷徑。" - "扲兩下然後扲住就可以揀選捷徑,或者用自訂嘅操作。" - "捷徑" - "%1$s 捷徑" - diff --git a/go/res/values-zh-rTW/strings.xml b/go/res/values-zh-rTW/strings.xml deleted file mode 100644 index 07ae2ed5b4..0000000000 --- a/go/res/values-zh-rTW/strings.xml +++ /dev/null @@ -1,26 +0,0 @@ - - - - - "按住捷徑即可選取。" - "輕觸兩下並按住捷徑即可選取,你也可以使用自訂動作。" - "捷徑" - "「%1$s」捷徑" - diff --git a/go/res/values-zu/strings.xml b/go/res/values-zu/strings.xml deleted file mode 100644 index e5051df1f1..0000000000 --- a/go/res/values-zu/strings.xml +++ /dev/null @@ -1,26 +0,0 @@ - - - - - "Thinta futhi ubambe ukuze ukhethe isinqamuleli." - "Thepha kabulu futhi ubambe ukuze ukhethe isinqamuleli noma usebenzise izenzo zangokwezifiso." - "Izinqamuleli" - "%1$s izinqamuleli" - diff --git a/go/res/values/strings.xml b/go/res/values/strings.xml deleted file mode 100644 index 8ef2e62430..0000000000 --- a/go/res/values/strings.xml +++ /dev/null @@ -1,33 +0,0 @@ - - - - - - - Touch & hold to pick up a shortcut. - - Double-tap & hold to pick up a shortcut or use custom actions. - - Shortcuts - - - - %1$s shortcuts - - diff --git a/go/src/com/android/launcher3/model/LoaderResults.java b/go/src/com/android/launcher3/model/LoaderResults.java new file mode 100644 index 0000000000..b82f362496 --- /dev/null +++ b/go/src/com/android/launcher3/model/LoaderResults.java @@ -0,0 +1,42 @@ +/* + * 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.model; + +import com.android.launcher3.AllAppsList; +import com.android.launcher3.LauncherAppState; +import com.android.launcher3.LauncherModel.Callbacks; + +import java.lang.ref.WeakReference; + +/** + * Helper class to handle results of {@link com.android.launcher3.model.LoaderTask}. + */ +public class LoaderResults extends BaseLoaderResults { + + public LoaderResults(LauncherAppState app, BgDataModel dataModel, + AllAppsList allAppsList, int pageToBindFirst, WeakReference callbacks) { + super(app, dataModel, allAppsList, pageToBindFirst, callbacks); + } + + @Override + public void bindDeepShortcuts() { + } + + @Override + public void bindWidgets() { + } +} diff --git a/go/src/com/android/launcher3/model/WidgetsModel.java b/go/src/com/android/launcher3/model/WidgetsModel.java new file mode 100644 index 0000000000..18f3f9d91c --- /dev/null +++ b/go/src/com/android/launcher3/model/WidgetsModel.java @@ -0,0 +1,67 @@ +/* + * 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.model; + +import android.content.Context; +import android.os.UserHandle; + +import com.android.launcher3.icons.ComponentWithLabel; +import com.android.launcher3.LauncherAppState; +import com.android.launcher3.util.PackageUserKey; +import com.android.launcher3.widget.WidgetListRowEntry; + +import java.util.ArrayList; +import java.util.Collections; +import java.util.List; +import java.util.Set; + +import androidx.annotation.Nullable; + +/** + * Widgets data model that is used by the adapters of the widget views and controllers. + * + *

The widgets and shortcuts are organized using package name as its index. + */ +public class WidgetsModel { + private static final ArrayList EMPTY_WIDGET_LIST = new ArrayList<>(); + + /** + * Returns a list of {@link WidgetListRowEntry}. All {@link WidgetItem} in a single row + * are sorted (based on label and user), but the overall list of {@link WidgetListRowEntry}s + * is not sorted. This list is sorted at the UI when using + * {@link com.android.launcher3.widget.WidgetsDiffReporter} + * + * @see com.android.launcher3.widget.WidgetsListAdapter#setWidgets(ArrayList) + */ + public synchronized ArrayList getWidgetsList(Context context) { + return EMPTY_WIDGET_LIST; + } + + /** + * @param packageUser If null, all widgets and shortcuts are updated and returned, otherwise + * only widgets and shortcuts associated with the package/user are. + */ + public List update(LauncherAppState app, + @Nullable PackageUserKey packageUser) { + return Collections.emptyList(); + } + + + public void onPackageIconsUpdated(Set packageNames, UserHandle user, + LauncherAppState app) { + } +} \ No newline at end of file diff --git a/gradle.properties b/gradle.properties new file mode 100644 index 0000000000..b299cfe516 --- /dev/null +++ b/gradle.properties @@ -0,0 +1,13 @@ +# Until all the dependencies move to android X +android.useAndroidX = true +android.enableJetifier = true + +ANDROID_X_VERSION=1.0.0-beta01 + +GRADLE_CLASS_PATH=com.android.tools.build:gradle:3.2.0-rc03 + +PROTOBUF_CLASS_PATH=com.google.protobuf:protobuf-gradle-plugin:0.8.6 +PROTOBUF_DEPENDENCY=com.google.protobuf.nano:protobuf-javanano:3.0.0-alpha-7 + +BUILD_TOOLS_VERSION=28.0.3 +COMPILE_SDK=28 \ No newline at end of file diff --git a/iconloaderlib/Android.bp b/iconloaderlib/Android.bp new file mode 100644 index 0000000000..8a71f94ed8 --- /dev/null +++ b/iconloaderlib/Android.bp @@ -0,0 +1,28 @@ +// 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. + +android_library { + name: "iconloader", + sdk_version: "28", + min_sdk_version: "21", + static_libs: [ + "androidx.core_core", + ], + resource_dirs: [ + "res", + ], + srcs: [ + "src/**/*.java", + ], +} diff --git a/res/layout/hotseat.xml b/iconloaderlib/AndroidManifest.xml similarity index 51% rename from res/layout/hotseat.xml rename to iconloaderlib/AndroidManifest.xml index 00f0b5ff8a..b30258da2a 100644 --- a/res/layout/hotseat.xml +++ b/iconloaderlib/AndroidManifest.xml @@ -1,5 +1,6 @@ - - - - + + diff --git a/iconloaderlib/build.gradle b/iconloaderlib/build.gradle new file mode 100644 index 0000000000..d08029386a --- /dev/null +++ b/iconloaderlib/build.gradle @@ -0,0 +1,50 @@ +buildscript { + repositories { + mavenCentral() + google() + } + dependencies { + classpath GRADLE_CLASS_PATH + } +} + +apply plugin: 'com.android.library' + +android { + compileSdkVersion COMPILE_SDK.toInteger() + buildToolsVersion BUILD_TOOLS_VERSION + publishNonDefault true + + defaultConfig { + minSdkVersion 21 + targetSdkVersion 28 + versionCode 1 + versionName "1.0" + } + + sourceSets { + main { + java.srcDirs = ['src'] + manifest.srcFile 'AndroidManifest.xml' + res.srcDirs = ['res'] + } + } + + lintOptions { + abortOnError false + } + + tasks.withType(JavaCompile) { + options.compilerArgs << "-Xlint:unchecked" << "-Xlint:deprecation" + } +} + + +repositories { + mavenCentral() + google() +} + +dependencies { + implementation "androidx.core:core:${ANDROID_X_VERSION}" +} diff --git a/res/drawable-v26/adaptive_icon_drawable_wrapper.xml b/iconloaderlib/res/drawable-v26/adaptive_icon_drawable_wrapper.xml similarity index 100% rename from res/drawable-v26/adaptive_icon_drawable_wrapper.xml rename to iconloaderlib/res/drawable-v26/adaptive_icon_drawable_wrapper.xml diff --git a/res/drawable/ic_instant_app_badge.xml b/iconloaderlib/res/drawable/ic_instant_app_badge.xml similarity index 93% rename from res/drawable/ic_instant_app_badge.xml rename to iconloaderlib/res/drawable/ic_instant_app_badge.xml index cc532309c9..b74317e5f2 100644 --- a/res/drawable/ic_instant_app_badge.xml +++ b/iconloaderlib/res/drawable/ic_instant_app_badge.xml @@ -21,23 +21,19 @@ - \ No newline at end of file + diff --git a/iconloaderlib/res/values/colors.xml b/iconloaderlib/res/values/colors.xml new file mode 100644 index 0000000000..873b2fc5fb --- /dev/null +++ b/iconloaderlib/res/values/colors.xml @@ -0,0 +1,21 @@ + + + + #FFFFFF + diff --git a/iconloaderlib/res/values/dimens.xml b/iconloaderlib/res/values/dimens.xml new file mode 100644 index 0000000000..e8c0c44f72 --- /dev/null +++ b/iconloaderlib/res/values/dimens.xml @@ -0,0 +1,19 @@ + + + + + 24dp + diff --git a/src/com/android/launcher3/icons/BaseIconFactory.java b/iconloaderlib/src/com/android/launcher3/icons/BaseIconFactory.java similarity index 98% rename from src/com/android/launcher3/icons/BaseIconFactory.java rename to iconloaderlib/src/com/android/launcher3/icons/BaseIconFactory.java index cd60de55a8..243903cc8c 100644 --- a/src/com/android/launcher3/icons/BaseIconFactory.java +++ b/iconloaderlib/src/com/android/launcher3/icons/BaseIconFactory.java @@ -18,8 +18,6 @@ import android.os.Build; import android.os.Process; import android.os.UserHandle; -import com.android.launcher3.R; - import static android.graphics.Paint.DITHER_FLAG; import static android.graphics.Paint.FILTER_BITMAP_FLAG; import static com.android.launcher3.icons.ShadowGenerator.BLUR_FACTOR; @@ -81,6 +79,7 @@ public class BaseIconFactory { return mNormalizer; } + @SuppressWarnings("deprecation") public BitmapInfo createIconBitmap(Intent.ShortcutIconResource iconRes) { try { Resources resources = mPm.getResourcesForApplication(iconRes.packageName); @@ -184,8 +183,7 @@ public class BaseIconFactory { RectF outIconBounds, float[] outScale) { float scale = 1f; - if (shrinkNonAdaptiveIcons) { - boolean[] outShape = new boolean[1]; + if (shrinkNonAdaptiveIcons && ATLEAST_OREO) { if (mWrapperIcon == null) { mWrapperIcon = mContext.getDrawable(R.drawable.adaptive_icon_drawable_wrapper) .mutate(); @@ -193,7 +191,7 @@ public class BaseIconFactory { AdaptiveIconDrawable dr = (AdaptiveIconDrawable) mWrapperIcon; dr.setBounds(0, 0, 1, 1); scale = getNormalizer().getScale(icon, outIconBounds); - if (ATLEAST_OREO && !(icon instanceof AdaptiveIconDrawable)) { + if (!(icon instanceof AdaptiveIconDrawable)) { FixedScaleDrawable fsd = ((FixedScaleDrawable) dr.getForeground()); fsd.setDrawable(icon); fsd.setScale(scale); diff --git a/src/com/android/launcher3/icons/BitmapInfo.java b/iconloaderlib/src/com/android/launcher3/icons/BitmapInfo.java similarity index 100% rename from src/com/android/launcher3/icons/BitmapInfo.java rename to iconloaderlib/src/com/android/launcher3/icons/BitmapInfo.java diff --git a/src/com/android/launcher3/icons/ColorExtractor.java b/iconloaderlib/src/com/android/launcher3/icons/ColorExtractor.java similarity index 100% rename from src/com/android/launcher3/icons/ColorExtractor.java rename to iconloaderlib/src/com/android/launcher3/icons/ColorExtractor.java diff --git a/src/com/android/launcher3/icons/FixedScaleDrawable.java b/iconloaderlib/src/com/android/launcher3/icons/FixedScaleDrawable.java similarity index 100% rename from src/com/android/launcher3/icons/FixedScaleDrawable.java rename to iconloaderlib/src/com/android/launcher3/icons/FixedScaleDrawable.java diff --git a/iconloaderlib/src/com/android/launcher3/icons/GraphicsUtils.java b/iconloaderlib/src/com/android/launcher3/icons/GraphicsUtils.java new file mode 100644 index 0000000000..b096cecb5c --- /dev/null +++ b/iconloaderlib/src/com/android/launcher3/icons/GraphicsUtils.java @@ -0,0 +1,36 @@ +/* + * 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.icons; + +import androidx.annotation.ColorInt; + +public class GraphicsUtils { + + /** + * Set the alpha component of {@code color} to be {@code alpha}. Unlike the support lib version, + * it bounds the alpha in valid range instead of throwing an exception to allow for safer + * interpolation of color animations + */ + @ColorInt + public static int setColorAlphaBound(int color, int alpha) { + if (alpha < 0) { + alpha = 0; + } else if (alpha > 255) { + alpha = 255; + } + return (color & 0x00ffffff) | (alpha << 24); + } +} diff --git a/src/com/android/launcher3/icons/IconNormalizer.java b/iconloaderlib/src/com/android/launcher3/icons/IconNormalizer.java similarity index 98% rename from src/com/android/launcher3/icons/IconNormalizer.java rename to iconloaderlib/src/com/android/launcher3/icons/IconNormalizer.java index 8eb82524e8..05908df99b 100644 --- a/src/com/android/launcher3/icons/IconNormalizer.java +++ b/iconloaderlib/src/com/android/launcher3/icons/IconNormalizer.java @@ -20,9 +20,6 @@ import android.content.Context; import android.graphics.Bitmap; import android.graphics.Canvas; import android.graphics.Color; -import android.graphics.Paint; -import android.graphics.PorterDuff; -import android.graphics.PorterDuffXfermode; import android.graphics.Rect; import android.graphics.RectF; import android.graphics.drawable.AdaptiveIconDrawable; diff --git a/src/com/android/launcher3/icons/ShadowGenerator.java b/iconloaderlib/src/com/android/launcher3/icons/ShadowGenerator.java similarity index 96% rename from src/com/android/launcher3/icons/ShadowGenerator.java rename to iconloaderlib/src/com/android/launcher3/icons/ShadowGenerator.java index 6491b7ec15..455c58c91b 100644 --- a/src/com/android/launcher3/icons/ShadowGenerator.java +++ b/iconloaderlib/src/com/android/launcher3/icons/ShadowGenerator.java @@ -16,6 +16,8 @@ package com.android.launcher3.icons; +import static com.android.launcher3.icons.GraphicsUtils.setColorAlphaBound; + import android.graphics.Bitmap; import android.graphics.Bitmap.Config; import android.graphics.BlurMaskFilter; @@ -27,8 +29,6 @@ import android.graphics.PorterDuff; import android.graphics.PorterDuffXfermode; import android.graphics.RectF; -import androidx.core.graphics.ColorUtils; - /** * Utility class to add shadows to bitmaps. */ @@ -142,12 +142,12 @@ public class ShadowGenerator { // Key shadow p.setShadowLayer(shadowBlur, 0, keyShadowDistance, - ColorUtils.setAlphaComponent(Color.BLACK, keyShadowAlpha)); + setColorAlphaBound(Color.BLACK, keyShadowAlpha)); c.drawRoundRect(bounds, radius, radius, p); // Ambient shadow p.setShadowLayer(shadowBlur, 0, 0, - ColorUtils.setAlphaComponent(Color.BLACK, ambientShadowAlpha)); + setColorAlphaBound(Color.BLACK, ambientShadowAlpha)); c.drawRoundRect(bounds, radius, radius, p); if (Color.alpha(color) < 255) { diff --git a/libs/README.txt b/libs/README.txt new file mode 100644 index 0000000000..9109592561 --- /dev/null +++ b/libs/README.txt @@ -0,0 +1,8 @@ +These jar are compiled in the frameworks/base of the platform tree. + +launcher_protos.jar is defined as launcherprotosnano in the following file: +frameworks/base/core/protos/android/stats/launcher/Android.bp + +plugin_core.jar is defined as PluginCoreLib in the following file: +frameworks/base/packages/SystemUI/plugin/Android.bp + diff --git a/libs/launcher_protos.jar b/libs/launcher_protos.jar new file mode 100644 index 0000000000..c0439363b8 Binary files /dev/null and b/libs/launcher_protos.jar differ diff --git a/quickstep/libs/sysui_shared.jar b/quickstep/libs/sysui_shared.jar index 6f3fa4be55..a1b3476a64 100644 Binary files a/quickstep/libs/sysui_shared.jar and b/quickstep/libs/sysui_shared.jar differ diff --git a/quickstep/res/values/config.xml b/quickstep/res/values/config.xml index d8ca1c47c1..3fbfcdd6c4 100644 --- a/quickstep/res/values/config.xml +++ b/quickstep/res/values/config.xml @@ -20,6 +20,8 @@ com.android.quickstep.logging.UserEventDispatcherExtension + com.android.quickstep.logging.StatsLogCompatManager + 3 diff --git a/quickstep/src/com/android/launcher3/LauncherAppTransitionManagerImpl.java b/quickstep/src/com/android/launcher3/LauncherAppTransitionManagerImpl.java index d7bbfe06e1..9e85469363 100644 --- a/quickstep/src/com/android/launcher3/LauncherAppTransitionManagerImpl.java +++ b/quickstep/src/com/android/launcher3/LauncherAppTransitionManagerImpl.java @@ -420,7 +420,10 @@ public class LauncherAppTransitionManagerImpl extends LauncherAppTransitionManag mLauncher.getWorkspace().getPageIndicator().pauseAnimations(); mDragLayer.setLayerType(View.LAYER_TYPE_HARDWARE, null); - endListener = this::resetContentView; + endListener = () -> { + resetContentView(); + mDragLayer.getScrim().hideSysUiScrim(false); + }; } return new Pair<>(launcherAnimator, endListener); } @@ -794,8 +797,6 @@ public class LauncherAppTransitionManagerImpl extends LauncherAppTransitionManag workspaceAnimator.setDuration(333); workspaceAnimator.setInterpolator(Interpolators.DEACCEL_1_7); - mDragLayer.getScrim().hideSysUiScrim(true); - // Pause page indicator animations as they lead to layer trashing. mLauncher.getWorkspace().getPageIndicator().pauseAnimations(); mDragLayer.setLayerType(View.LAYER_TYPE_HARDWARE, null); @@ -815,7 +816,6 @@ public class LauncherAppTransitionManagerImpl extends LauncherAppTransitionManag mDragLayerAlpha.setValue(1f); mDragLayer.setLayerType(View.LAYER_TYPE_NONE, null); mDragLayer.setTranslationY(0f); - mDragLayer.getScrim().hideSysUiScrim(false); } private boolean hasControlRemoteAppTransitionPermission() { diff --git a/quickstep/src/com/android/quickstep/TaskUtils.java b/quickstep/src/com/android/quickstep/TaskUtils.java index 5cae2b9199..4b86a7fa88 100644 --- a/quickstep/src/com/android/quickstep/TaskUtils.java +++ b/quickstep/src/com/android/quickstep/TaskUtils.java @@ -59,7 +59,6 @@ public class TaskUtils { */ public static CharSequence getTitle(Context context, Task task) { LauncherAppsCompat launcherAppsCompat = LauncherAppsCompat.getInstance(context); - UserManagerCompat userManagerCompat = UserManagerCompat.getInstance(context); PackageManager packageManager = context.getPackageManager(); UserHandle user = UserHandle.of(task.key.userId); ApplicationInfo applicationInfo = launcherAppsCompat.getApplicationInfo( @@ -68,7 +67,7 @@ public class TaskUtils { Log.e(TAG, "Failed to get title for task " + task); return ""; } - return userManagerCompat.getBadgedLabelForUser( + return packageManager.getUserBadgedLabel( applicationInfo.loadLabel(packageManager), user); } diff --git a/quickstep/src/com/android/quickstep/logging/StatsLogCompatManager.java b/quickstep/src/com/android/quickstep/logging/StatsLogCompatManager.java new file mode 100644 index 0000000000..2f411efc7b --- /dev/null +++ b/quickstep/src/com/android/quickstep/logging/StatsLogCompatManager.java @@ -0,0 +1,105 @@ +/* + * 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.quickstep.logging; + +import android.content.Context; +import android.content.Intent; +import android.stats.launcher.nano.LauncherExtension; +import android.stats.launcher.nano.LauncherTarget; + +import static android.stats.launcher.nano.Launcher.ALLAPPS; +import static android.stats.launcher.nano.Launcher.HOME; +import static android.stats.launcher.nano.Launcher.LAUNCH_APP; +import static android.stats.launcher.nano.Launcher.LAUNCH_TASK; +import static android.stats.launcher.nano.Launcher.BACKGROUND; +import static android.stats.launcher.nano.Launcher.OVERVIEW; + +import android.view.View; + +import com.android.launcher3.ItemInfo; +import com.android.launcher3.logging.StatsLogManager; +import com.android.launcher3.logging.StatsLogUtils; +import com.android.launcher3.userevent.nano.LauncherLogProto.Target; +import com.android.launcher3.util.ComponentKey; +import com.android.systemui.shared.system.StatsLogCompat; +import com.google.protobuf.nano.MessageNano; + +import androidx.annotation.Nullable; + +/** + * This method calls the StatsLog hidden method until they are made available public. + * + * To see if the logs are properly sent to statsd, execute following command. + * $ adb root && adb shell statsd + * $ adb shell cmd stats print-logs + * $ adb logcat | grep statsd OR $ adb logcat -b stats + */ +public class StatsLogCompatManager extends StatsLogManager { + + private static final int SUPPORTED_TARGET_DEPTH = 2; + + public StatsLogCompatManager(Context context) { } + + @Override + public void logAppLaunch(View v, Intent intent) { + LauncherExtension ext = new LauncherExtension(); + ext.srcTarget = new LauncherTarget[SUPPORTED_TARGET_DEPTH]; + int srcState = mStateProvider.getCurrentState(); + fillInLauncherExtension(v, ext); + StatsLogCompat.write(LAUNCH_APP, srcState, BACKGROUND /* dstState */, + MessageNano.toByteArray(ext), true); + } + + @Override + public void logTaskLaunch(View v, ComponentKey componentKey) { + LauncherExtension ext = new LauncherExtension(); + ext.srcTarget = new LauncherTarget[SUPPORTED_TARGET_DEPTH]; + int srcState = OVERVIEW; + fillInLauncherExtension(v, ext); + StatsLogCompat.write(LAUNCH_TASK, srcState, BACKGROUND /* dstState */, + MessageNano.toByteArray(ext), true); + } + + public static boolean fillInLauncherExtension(View v, LauncherExtension extension) { + StatsLogUtils.LogContainerProvider provider = StatsLogUtils.getLaunchProviderRecursive(v); + if (v == null || !(v.getTag() instanceof ItemInfo) || provider == null) { + return false; + } + ItemInfo itemInfo = (ItemInfo) v.getTag(); + Target child = new Target(); + Target parent = new Target(); + provider.fillInLogContainerData(v, itemInfo, child, parent); + copy(child, extension.srcTarget[0]); + copy(parent, extension.srcTarget[1]); + return true; + } + + private static void copy(Target src, LauncherTarget dst) { + // fill in + } + + @Override + public void verify() { + if(!(StatsLogUtils.LAUNCHER_STATE_ALLAPPS == ALLAPPS && + StatsLogUtils.LAUNCHER_STATE_BACKGROUND == BACKGROUND && + StatsLogUtils.LAUNCHER_STATE_OVERVIEW == OVERVIEW && + StatsLogUtils.LAUNCHER_STATE_HOME == HOME)) { + throw new IllegalStateException( + "StatsLogUtil constants doesn't match enums in launcher.proto"); + } + } +} diff --git a/quickstep/src/com/android/quickstep/logging/UserEventDispatcherExtension.java b/quickstep/src/com/android/quickstep/logging/UserEventDispatcherExtension.java index 6dff187ea5..4392851c0e 100644 --- a/quickstep/src/com/android/quickstep/logging/UserEventDispatcherExtension.java +++ b/quickstep/src/com/android/quickstep/logging/UserEventDispatcherExtension.java @@ -34,6 +34,7 @@ import com.android.systemui.shared.system.MetricsLoggerCompat; * quickstep interactions. */ @SuppressWarnings("unused") +@Deprecated public class UserEventDispatcherExtension extends UserEventDispatcher { private static final String TAG = "UserEventDispatcher"; diff --git a/quickstep/src/com/android/quickstep/views/ShelfScrimView.java b/quickstep/src/com/android/quickstep/views/ShelfScrimView.java index 896557550a..d2b3bcc170 100644 --- a/quickstep/src/com/android/quickstep/views/ShelfScrimView.java +++ b/quickstep/src/com/android/quickstep/views/ShelfScrimView.java @@ -18,8 +18,7 @@ package com.android.quickstep.views; import static com.android.launcher3.LauncherState.OVERVIEW; import static com.android.launcher3.anim.Interpolators.ACCEL; import static com.android.launcher3.anim.Interpolators.LINEAR; - -import static androidx.core.graphics.ColorUtils.setAlphaComponent; +import static com.android.launcher3.icons.GraphicsUtils.setColorAlphaBound; import android.content.Context; import android.graphics.Canvas; @@ -141,7 +140,7 @@ public class ShelfScrimView extends ScrimView { int alpha = Math.round(Utilities.mapToRange( mProgress, mMidProgress, 1, mMidAlpha, 0, ACCEL)); - mShelfColor = setAlphaComponent(mEndScrim, alpha); + mShelfColor = setColorAlphaBound(mEndScrim, alpha); } else { mDragHandleOffset += mShiftRange * (mMidProgress - mProgress); @@ -149,12 +148,12 @@ public class ShelfScrimView extends ScrimView { int alpha = Math.round( Utilities.mapToRange(mProgress, (float) 0, mMidProgress, (float) mEndAlpha, (float) mMidAlpha, Interpolators.clampToProgress(ACCEL, 0.5f, 1f))); - mShelfColor = setAlphaComponent(mEndScrim, alpha); + mShelfColor = setColorAlphaBound(mEndScrim, alpha); int remainingScrimAlpha = Math.round( Utilities.mapToRange(mProgress, (float) 0, mMidProgress, mMaxScrimAlpha, (float) 0, LINEAR)); - mRemainingScreenColor = setAlphaComponent(mScrimColor, remainingScrimAlpha); + mRemainingScreenColor = setColorAlphaBound(mScrimColor, remainingScrimAlpha); } } diff --git a/quickstep/src/com/android/quickstep/views/TaskView.java b/quickstep/src/com/android/quickstep/views/TaskView.java index 31aaab0607..301b08a3f7 100644 --- a/quickstep/src/com/android/quickstep/views/TaskView.java +++ b/quickstep/src/com/android/quickstep/views/TaskView.java @@ -167,9 +167,12 @@ public class TaskView extends FrameLayout implements PageCallbacks { return; } launchTask(true /* animate */); + fromContext(context).getUserEventDispatcher().logTaskLaunchOrDismiss( Touch.TAP, Direction.NONE, getRecentsView().indexOfChild(this), TaskUtils.getLaunchComponentKeyForTask(getTask().key)); + fromContext(context).getStatsLogManager().logTaskLaunch(getRecentsView(), + TaskUtils.getLaunchComponentKeyForTask(getTask().key)); }); setOutlineProvider(new TaskOutlineProvider(getResources())); } diff --git a/res/layout/all_apps.xml b/res/layout/all_apps.xml index 02d793e1c0..b1e6f2efd7 100644 --- a/res/layout/all_apps.xml +++ b/res/layout/all_apps.xml @@ -26,7 +26,9 @@ android:focusable="false" android:saveEnabled="false" > - + diff --git a/res/layout/launcher.xml b/res/layout/launcher.xml index 304d012d24..87078b93e3 100644 --- a/res/layout/launcher.xml +++ b/res/layout/launcher.xml @@ -56,22 +56,25 @@ android:id="@+id/drop_target_bar" layout="@layout/drop_target_bar" /> - + android:layout_height="match_parent" /> - + android:layout_height="match_parent" + android:theme="@style/HomeScreenElementTheme" + android:importantForAccessibility="no" + launcher:containerType="hotseat" /> + diff --git a/res/values/colors.xml b/res/values/colors.xml index eb207af1eb..3c8fe1e253 100644 --- a/res/values/colors.xml +++ b/res/values/colors.xml @@ -34,7 +34,6 @@ #757575 #E0E0E0 - #FFFFFF #E5E5E5 #9AA0A6 diff --git a/res/values/config.xml b/res/values/config.xml index 5e83ab7666..b33cfa113e 100644 --- a/res/values/config.xml +++ b/res/values/config.xml @@ -84,6 +84,7 @@ + @@ -130,7 +131,6 @@ - diff --git a/tests/src/com/android/launcher3/logging/FileLogTest.java b/robolectric_tests/src/com/android/launcher3/logging/FileLogTest.java similarity index 89% rename from tests/src/com/android/launcher3/logging/FileLogTest.java rename to robolectric_tests/src/com/android/launcher3/logging/FileLogTest.java index e031f1d34a..096db57f90 100644 --- a/tests/src/com/android/launcher3/logging/FileLogTest.java +++ b/robolectric_tests/src/com/android/launcher3/logging/FileLogTest.java @@ -1,13 +1,11 @@ package com.android.launcher3.logging; -import androidx.test.InstrumentationRegistry; -import androidx.test.filters.SmallTest; -import androidx.test.runner.AndroidJUnit4; - import org.junit.After; import org.junit.Before; import org.junit.Test; import org.junit.runner.RunWith; +import org.robolectric.RobolectricTestRunner; +import org.robolectric.RuntimeEnvironment; import java.io.File; import java.io.PrintWriter; @@ -20,8 +18,7 @@ import static org.junit.Assert.assertTrue; /** * Tests for {@link FileLog} */ -@SmallTest -@RunWith(AndroidJUnit4.class) +@RunWith(RobolectricTestRunner.class) public class FileLogTest { private File mTempDir; @@ -30,9 +27,9 @@ public class FileLogTest { public void setUp() throws Exception { int count = 0; do { - mTempDir = new File(InstrumentationRegistry.getTargetContext().getCacheDir(), + mTempDir = new File(RuntimeEnvironment.application.getCacheDir(), "log-test-" + (count++)); - } while(!mTempDir.mkdir()); + } while (!mTempDir.mkdir()); FileLog.setDir(mTempDir); } diff --git a/tests/src/com/android/launcher3/util/GridOccupancyTest.java b/robolectric_tests/src/com/android/launcher3/util/GridOccupancyTest.java similarity index 92% rename from tests/src/com/android/launcher3/util/GridOccupancyTest.java rename to robolectric_tests/src/com/android/launcher3/util/GridOccupancyTest.java index cbf30b1788..aa51ad20c6 100644 --- a/tests/src/com/android/launcher3/util/GridOccupancyTest.java +++ b/robolectric_tests/src/com/android/launcher3/util/GridOccupancyTest.java @@ -1,10 +1,8 @@ package com.android.launcher3.util; -import androidx.test.filters.SmallTest; -import androidx.test.runner.AndroidJUnit4; - import org.junit.Test; import org.junit.runner.RunWith; +import org.robolectric.RobolectricTestRunner; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertFalse; @@ -13,8 +11,7 @@ import static org.junit.Assert.assertTrue; /** * Unit tests for {@link GridOccupancy} */ -@SmallTest -@RunWith(AndroidJUnit4.class) +@RunWith(RobolectricTestRunner.class) public class GridOccupancyTest { @Test @@ -24,7 +21,7 @@ public class GridOccupancyTest { 0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 1, 1, 0, 0, 0 - ); + ); int[] vacant = new int[2]; assertTrue(grid.findVacantCell(vacant, 2, 2)); diff --git a/settings.gradle b/settings.gradle new file mode 100644 index 0000000000..b52bd4f784 --- /dev/null +++ b/settings.gradle @@ -0,0 +1,2 @@ +include ':IconLoader' +project(':IconLoader').projectDir = new File(rootDir, 'iconloaderlib') diff --git a/src/com/android/launcher3/BaseActivity.java b/src/com/android/launcher3/BaseActivity.java index 7b565273f2..77b6010c26 100644 --- a/src/com/android/launcher3/BaseActivity.java +++ b/src/com/android/launcher3/BaseActivity.java @@ -28,6 +28,9 @@ import android.view.ContextThemeWrapper; import android.view.View.AccessibilityDelegate; import com.android.launcher3.DeviceProfile.OnDeviceProfileChangeListener; +import com.android.launcher3.logging.StatsLogManager; +import com.android.launcher3.logging.StatsLogUtils; +import com.android.launcher3.logging.StatsLogUtils.LogStateProvider; import com.android.launcher3.logging.UserEventDispatcher; import com.android.launcher3.logging.UserEventDispatcher.UserEventDelegate; import com.android.launcher3.uioverrides.UiFactory; @@ -41,7 +44,7 @@ import java.util.ArrayList; import androidx.annotation.IntDef; -public abstract class BaseActivity extends Activity implements UserEventDelegate{ +public abstract class BaseActivity extends Activity implements UserEventDelegate, LogStateProvider{ public static final int INVISIBLE_BY_STATE_HANDLER = 1 << 0; public static final int INVISIBLE_BY_APP_TRANSITIONS = 1 << 1; @@ -72,6 +75,7 @@ public abstract class BaseActivity extends Activity implements UserEventDelegate protected DeviceProfile mDeviceProfile; protected UserEventDispatcher mUserEventDispatcher; + protected StatsLogManager mStatsLogManager; protected SystemUiController mSystemUiController; private static final int ACTIVITY_STATE_STARTED = 1 << 0; @@ -104,8 +108,17 @@ public abstract class BaseActivity extends Activity implements UserEventDelegate return null; } + public int getCurrentState() { return StatsLogUtils.LAUNCHER_STATE_BACKGROUND; } + public void modifyUserEvent(LauncherLogProto.LauncherEvent event) {} + public final StatsLogManager getStatsLogManager() { + if (mStatsLogManager == null) { + mStatsLogManager = StatsLogManager.newInstance(this, this); + } + return mStatsLogManager; + } + public final UserEventDispatcher getUserEventDispatcher() { if (mUserEventDispatcher == null) { mUserEventDispatcher = UserEventDispatcher.newInstance(this, this); diff --git a/src/com/android/launcher3/BaseDraggingActivity.java b/src/com/android/launcher3/BaseDraggingActivity.java index f5fbf80dcd..152dc84d01 100644 --- a/src/com/android/launcher3/BaseDraggingActivity.java +++ b/src/com/android/launcher3/BaseDraggingActivity.java @@ -200,6 +200,7 @@ public abstract class BaseDraggingActivity extends BaseActivity intent.getComponent(), user, intent.getSourceBounds(), optsBundle); } getUserEventDispatcher().logAppLaunch(v, intent); + getStatsLogManager().logAppLaunch(v, intent); return true; } catch (ActivityNotFoundException|SecurityException e) { Toast.makeText(this, R.string.activity_not_found, Toast.LENGTH_SHORT).show(); diff --git a/src/com/android/launcher3/BubbleTextView.java b/src/com/android/launcher3/BubbleTextView.java index 8513d63a78..455fd1866d 100644 --- a/src/com/android/launcher3/BubbleTextView.java +++ b/src/com/android/launcher3/BubbleTextView.java @@ -16,6 +16,8 @@ package com.android.launcher3; +import static com.android.launcher3.icons.GraphicsUtils.setColorAlphaBound; + import android.animation.Animator; import android.animation.AnimatorListenerAdapter; import android.animation.ObjectAnimator; @@ -53,8 +55,6 @@ import com.android.launcher3.model.PackageItemInfo; import java.text.NumberFormat; -import androidx.core.graphics.ColorUtils; - /** * TextView that draws a bubble behind the text. We cannot use a LineBackgroundSpan * because we want to make the bubble taller than the text and TextView's clip is @@ -473,8 +473,7 @@ public class BubbleTextView extends TextView implements ItemInfoUpdateReceiver, // Special case to prevent text shadows in high contrast mode return Color.TRANSPARENT; } - return ColorUtils.setAlphaComponent( - mTextColor, Math.round(Color.alpha(mTextColor) * mTextAlpha)); + return setColorAlphaBound(mTextColor, Math.round(Color.alpha(mTextColor) * mTextAlpha)); } /** diff --git a/src/com/android/launcher3/DragSource.java b/src/com/android/launcher3/DragSource.java index 93f865c9f9..d4d7b99fd4 100644 --- a/src/com/android/launcher3/DragSource.java +++ b/src/com/android/launcher3/DragSource.java @@ -19,7 +19,7 @@ package com.android.launcher3; import android.view.View; import com.android.launcher3.DropTarget.DragObject; -import com.android.launcher3.logging.UserEventDispatcher.LogContainerProvider; +import com.android.launcher3.logging.StatsLogUtils.LogContainerProvider; /** * Interface defining an object that can originate a drag. diff --git a/src/com/android/launcher3/Hotseat.java b/src/com/android/launcher3/Hotseat.java index 15a9f2e06b..6b5db307bc 100644 --- a/src/com/android/launcher3/Hotseat.java +++ b/src/com/android/launcher3/Hotseat.java @@ -26,14 +26,13 @@ import android.view.ViewDebug; import android.view.ViewGroup; import android.widget.FrameLayout; -import com.android.launcher3.logging.UserEventDispatcher.LogContainerProvider; -import com.android.launcher3.userevent.nano.LauncherLogProto.ContainerType; +import com.android.launcher3.logging.StatsLogUtils.LogContainerProvider; +import com.android.launcher3.userevent.nano.LauncherLogProto; import com.android.launcher3.userevent.nano.LauncherLogProto.Target; -public class Hotseat extends FrameLayout implements LogContainerProvider, Insettable { +public class Hotseat extends CellLayout implements LogContainerProvider, Insettable { private final Launcher mLauncher; - private CellLayout mContent; @ViewDebug.ExportedProperty(category = "launcher") private boolean mHasVerticalHotseat; @@ -51,38 +50,23 @@ public class Hotseat extends FrameLayout implements LogContainerProvider, Insett mLauncher = Launcher.getLauncher(context); } - public CellLayout getLayout() { - return mContent; - } - - /* Get the orientation invariant order of the item in the hotseat for persistence. */ - int getOrderInHotseat(int x, int y) { - return mHasVerticalHotseat ? (mContent.getCountY() - y - 1) : x; - } - /* Get the orientation specific coordinates given an invariant order in the hotseat. */ int getCellXFromOrder(int rank) { return mHasVerticalHotseat ? 0 : rank; } int getCellYFromOrder(int rank) { - return mHasVerticalHotseat ? (mContent.getCountY() - (rank + 1)) : 0; - } - - @Override - protected void onFinishInflate() { - super.onFinishInflate(); - mContent = findViewById(R.id.layout); + return mHasVerticalHotseat ? (getCountY() - (rank + 1)) : 0; } void resetLayout(boolean hasVerticalHotseat) { - mContent.removeAllViewsInLayout(); + removeAllViewsInLayout(); mHasVerticalHotseat = hasVerticalHotseat; InvariantDeviceProfile idp = mLauncher.getDeviceProfile().inv; if (hasVerticalHotseat) { - mContent.setGridSize(1, idp.numHotseatIcons); + setGridSize(1, idp.numHotseatIcons); } else { - mContent.setGridSize(idp.numHotseatIcons, 1); + setGridSize(idp.numHotseatIcons, 1); } } @@ -90,15 +74,16 @@ public class Hotseat extends FrameLayout implements LogContainerProvider, Insett public boolean onInterceptTouchEvent(MotionEvent ev) { // We don't want any clicks to go through to the hotseat unless the workspace is in // the normal state or an accessible drag is in progress. - return !mLauncher.getWorkspace().workspaceIconsCanBeDragged() && - !mLauncher.getAccessibilityDelegate().isInAccessibleDrag(); + return (!mLauncher.getWorkspace().workspaceIconsCanBeDragged() + && !mLauncher.getAccessibilityDelegate().isInAccessibleDrag()) + || super.onInterceptTouchEvent(ev); } @Override public void fillInLogContainerData(View v, ItemInfo info, Target target, Target targetParent) { target.gridX = info.cellX; target.gridY = info.cellY; - targetParent.containerType = ContainerType.HOTSEAT; + targetParent.containerType = LauncherLogProto.ContainerType.HOTSEAT; } @Override @@ -121,7 +106,7 @@ public class Hotseat extends FrameLayout implements LogContainerProvider, Insett lp.height = grid.hotseatBarSizePx + insets.bottom; } Rect padding = grid.getHotseatLayoutPadding(); - getLayout().setPadding(padding.left, padding.top, padding.right, padding.bottom); + setPadding(padding.left, padding.top, padding.right, padding.bottom); setLayoutParams(lp); InsettableFrameLayout.dispatchInsets(this, insets); diff --git a/src/com/android/launcher3/InstallShortcutReceiver.java b/src/com/android/launcher3/InstallShortcutReceiver.java index 851454b77b..73c999a923 100644 --- a/src/com/android/launcher3/InstallShortcutReceiver.java +++ b/src/com/android/launcher3/InstallShortcutReceiver.java @@ -659,8 +659,8 @@ public class InstallShortcutReceiver extends BroadcastReceiver { info.applyFrom(iconInfo); info.title = Utilities.trim(name); - info.contentDescription = UserManagerCompat.getInstance(app.getContext()) - .getBadgedLabelForUser(info.title, info.user); + info.contentDescription = app.getContext().getPackageManager() + .getUserBadgedLabel(info.title, info.user); info.intent = intent; return info; } diff --git a/src/com/android/launcher3/Launcher.java b/src/com/android/launcher3/Launcher.java index 3ae9a49e70..36967cd4e5 100644 --- a/src/com/android/launcher3/Launcher.java +++ b/src/com/android/launcher3/Launcher.java @@ -91,6 +91,7 @@ import com.android.launcher3.icons.IconCache; import com.android.launcher3.keyboard.CustomActionsPopup; import com.android.launcher3.keyboard.ViewGroupFocusHelper; import com.android.launcher3.logging.FileLog; +import com.android.launcher3.logging.StatsLogUtils; import com.android.launcher3.logging.UserEventDispatcher; import com.android.launcher3.logging.UserEventDispatcher.UserEventDelegate; import com.android.launcher3.model.ModelWriter; @@ -206,7 +207,6 @@ public class Launcher extends BaseDraggingActivity implements LauncherExterns, private final int[] mTmpAddItemCellCoordinates = new int[2]; @Thunk Hotseat mHotseat; - @Nullable private View mHotseatSearchBox; private DropTargetBar mDropTargetBar; @@ -913,7 +913,6 @@ public class Launcher extends BaseDraggingActivity implements LauncherExterns, mWorkspace.initParentViews(mDragLayer); mOverviewPanel = findViewById(R.id.overview_panel); mHotseat = findViewById(R.id.hotseat); - mHotseatSearchBox = findViewById(R.id.search_container_hotseat); mLauncherView.setSystemUiVisibility(View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN | View.SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION @@ -1158,10 +1157,6 @@ public class Launcher extends BaseDraggingActivity implements LauncherExterns, return mHotseat; } - public View getHotseatSearchBox() { - return mHotseatSearchBox; - } - public T getOverviewPanel() { return (T) mOverviewPanel; } @@ -1609,6 +1604,16 @@ public class Launcher extends BaseDraggingActivity implements LauncherExterns, } } + @Override + public int getCurrentState() { + if(mStateManager.getState() == LauncherState.ALL_APPS) { + return StatsLogUtils.LAUNCHER_STATE_ALLAPPS; + } else if (mStateManager.getState() == LauncherState.OVERVIEW) { + return StatsLogUtils.LAUNCHER_STATE_OVERVIEW; + } + return StatsLogUtils.LAUNCHER_STATE_HOME; + } + @Override public void modifyUserEvent(LauncherLogProto.LauncherEvent event) { if (event.srcTarget != null && event.srcTarget.length > 0 && @@ -1643,23 +1648,15 @@ public class Launcher extends BaseDraggingActivity implements LauncherExterns, boolean isHotseatLayout(View layout) { // TODO: Remove this method - return mHotseat != null && layout != null && - (layout instanceof CellLayout) && (layout == mHotseat.getLayout()); + return mHotseat != null && (layout == mHotseat); } /** * Returns the CellLayout of the specified container at the specified screen. */ public CellLayout getCellLayout(int container, int screenId) { - if (container == LauncherSettings.Favorites.CONTAINER_HOTSEAT) { - if (mHotseat != null) { - return mHotseat.getLayout(); - } else { - return null; - } - } else { - return mWorkspace.getScreenWithId(screenId); - } + return (container == LauncherSettings.Favorites.CONTAINER_HOTSEAT) + ? mHotseat : mWorkspace.getScreenWithId(screenId); } @Override @@ -2270,7 +2267,7 @@ public class Launcher extends BaseDraggingActivity implements LauncherExterns, } writer.println(prefix + " Hotseat"); - ViewGroup layout = mHotseat.getLayout().getShortcutsAndWidgets(); + ViewGroup layout = mHotseat.getShortcutsAndWidgets(); for (int j = 0; j < layout.getChildCount(); j++) { Object tag = layout.getChildAt(j).getTag(); if (tag != null) { diff --git a/src/com/android/launcher3/ShortcutInfo.java b/src/com/android/launcher3/ShortcutInfo.java index 7717d91883..19c647fd74 100644 --- a/src/com/android/launcher3/ShortcutInfo.java +++ b/src/com/android/launcher3/ShortcutInfo.java @@ -24,7 +24,6 @@ import android.os.Build; import android.text.TextUtils; import com.android.launcher3.LauncherSettings.Favorites; -import com.android.launcher3.compat.UserManagerCompat; import com.android.launcher3.icons.IconCache; import com.android.launcher3.shortcuts.ShortcutInfoCompat; import com.android.launcher3.util.ContentWriter; @@ -172,8 +171,7 @@ public class ShortcutInfo extends ItemInfoWithIcon { if (TextUtils.isEmpty(label)) { label = shortcutInfo.getShortLabel(); } - contentDescription = UserManagerCompat.getInstance(context) - .getBadgedLabelForUser(label, user); + contentDescription = context.getPackageManager().getUserBadgedLabel(label, user); if (shortcutInfo.isEnabled()) { runtimeStatusFlags &= ~FLAG_DISABLED_BY_PUBLISHER; } else { diff --git a/src/com/android/launcher3/Workspace.java b/src/com/android/launcher3/Workspace.java index 3f7d68d12f..7a8d984d74 100644 --- a/src/com/android/launcher3/Workspace.java +++ b/src/com/android/launcher3/Workspace.java @@ -85,8 +85,8 @@ import com.android.launcher3.userevent.nano.LauncherLogProto.Action; import com.android.launcher3.userevent.nano.LauncherLogProto.ContainerType; import com.android.launcher3.userevent.nano.LauncherLogProto.Target; import com.android.launcher3.util.IntArray; -import com.android.launcher3.util.IntSparseArrayMap; import com.android.launcher3.util.IntSet; +import com.android.launcher3.util.IntSparseArrayMap; import com.android.launcher3.util.ItemInfoMatcher; import com.android.launcher3.util.PackageUserKey; import com.android.launcher3.util.Thunk; @@ -880,7 +880,7 @@ public class Workspace extends PagedView final CellLayout layout; if (container == LauncherSettings.Favorites.CONTAINER_HOTSEAT) { - layout = mLauncher.getHotseat().getLayout(); + layout = mLauncher.getHotseat(); // Hide folder title in the hotseat if (child instanceof FolderIcon) { @@ -1517,7 +1517,7 @@ public class Workspace extends PagedView @Override protected void enableAccessibleDrag(boolean enable) { super.enableAccessibleDrag(enable); - setEnableForLayout(mLauncher.getHotseat().getLayout(),enable); + setEnableForLayout(mLauncher.getHotseat(),enable); } }); } @@ -1625,11 +1625,7 @@ public class Workspace extends PagedView mDragViewVisualCenter = d.getVisualCenter(mDragViewVisualCenter); // We want the point to be mapped to the dragTarget. - if (mLauncher.isHotseatLayout(dropTargetLayout)) { - mapPointFromSelfToHotseatLayout(mLauncher.getHotseat(), mDragViewVisualCenter); - } else { - mapPointFromSelfToChild(dropTargetLayout, mDragViewVisualCenter); - } + mapPointFromDropLayout(mLauncher.getHotseat(), mDragViewVisualCenter); int spanX; int spanY; @@ -1831,11 +1827,7 @@ public class Workspace extends PagedView // We want the point to be mapped to the dragTarget. if (dropTargetLayout != null) { - if (mLauncher.isHotseatLayout(dropTargetLayout)) { - mapPointFromSelfToHotseatLayout(mLauncher.getHotseat(), mDragViewVisualCenter); - } else { - mapPointFromSelfToChild(dropTargetLayout, mDragViewVisualCenter); - } + mapPointFromDropLayout(mLauncher.getHotseat(), mDragViewVisualCenter); } boolean droppedOnOriginalCell = false; @@ -2195,7 +2187,7 @@ public class Workspace extends PagedView * Convert the 2D coordinate xy from the parent View's coordinate space to this CellLayout's * coordinate space. The argument xy is modified with the return result. */ - void mapPointFromSelfToChild(View v, float[] xy) { + private void mapPointFromSelfToChild(View v, float[] xy) { xy[0] = xy[0] - v.getLeft(); xy[1] = xy[1] - v.getTop(); } @@ -2211,14 +2203,23 @@ public class Workspace extends PagedView mTempXY[1] <= hotseat.getBottom(); } - void mapPointFromSelfToHotseatLayout(Hotseat hotseat, float[] xy) { - mTempXY[0] = (int) xy[0]; - mTempXY[1] = (int) xy[1]; - mLauncher.getDragLayer().getDescendantCoordRelativeToSelf(this, mTempXY, true); - mLauncher.getDragLayer().mapCoordInSelfToDescendant(hotseat.getLayout(), mTempXY); + /** + * Updates the point in {@param xy} to point to the co-ordinate space of {@param layout} + * @param layout either hotseat of a page in workspace + * @param xy the point location in workspace co-ordinate space + */ + private void mapPointFromDropLayout(CellLayout layout, float[] xy) { + if (mLauncher.isHotseatLayout(layout)) { + mTempXY[0] = (int) xy[0]; + mTempXY[1] = (int) xy[1]; + mLauncher.getDragLayer().getDescendantCoordRelativeToSelf(this, mTempXY, true); + mLauncher.getDragLayer().mapCoordInSelfToDescendant(layout, mTempXY); - xy[0] = mTempXY[0]; - xy[1] = mTempXY[1]; + xy[0] = mTempXY[0]; + xy[1] = mTempXY[1]; + } else { + mapPointFromSelfToChild(layout, xy); + } } private boolean isDragWidget(DragObject d) { @@ -2254,11 +2255,7 @@ public class Workspace extends PagedView // Handle the drag over if (mDragTargetLayout != null) { // We want the point to be mapped to the dragTarget. - if (mLauncher.isHotseatLayout(mDragTargetLayout)) { - mapPointFromSelfToHotseatLayout(mLauncher.getHotseat(), mDragViewVisualCenter); - } else { - mapPointFromSelfToChild(mDragTargetLayout, mDragViewVisualCenter); - } + mapPointFromDropLayout(mLauncher.getHotseat(), mDragViewVisualCenter); int minSpanX = item.spanX; int minSpanY = item.spanY; @@ -2329,7 +2326,7 @@ public class Workspace extends PagedView // Test to see if we are over the hotseat first if (mLauncher.getHotseat() != null && !isDragWidget(d)) { if (isPointInSelfOverHotseat(d.x, d.y)) { - layout = mLauncher.getHotseat().getLayout(); + layout = mLauncher.getHotseat(); } } @@ -2967,8 +2964,7 @@ public class Workspace extends PagedView * Returns a specific CellLayout */ CellLayout getParentCellLayoutForView(View v) { - ArrayList layouts = getWorkspaceAndHotseatCellLayouts(); - for (CellLayout layout : layouts) { + for (CellLayout layout : getWorkspaceAndHotseatCellLayouts()) { if (layout.getShortcutsAndWidgets().indexOfChild(v) > -1) { return layout; } @@ -2977,56 +2973,31 @@ public class Workspace extends PagedView } /** - * Returns a list of all the CellLayouts in the workspace. + * Returns a list of all the CellLayouts on the Homescreen. */ - ArrayList getWorkspaceAndHotseatCellLayouts() { - ArrayList layouts = new ArrayList<>(); + private CellLayout[] getWorkspaceAndHotseatCellLayouts() { int screenCount = getChildCount(); - for (int screen = 0; screen < screenCount; screen++) { - layouts.add(((CellLayout) getChildAt(screen))); - } + final CellLayout[] layouts; if (mLauncher.getHotseat() != null) { - layouts.add(mLauncher.getHotseat().getLayout()); + layouts = new CellLayout[screenCount + 1]; + layouts[screenCount] = mLauncher.getHotseat(); + } else { + layouts = new CellLayout[screenCount]; + } + for (int screen = 0; screen < screenCount; screen++) { + layouts[screen] = (CellLayout) getChildAt(screen); } return layouts; } - /** - * We should only use this to search for specific children. Do not use this method to modify - * ShortcutsAndWidgetsContainer directly. Includes ShortcutAndWidgetContainers from - * the hotseat and workspace pages - */ - ArrayList getAllShortcutAndWidgetContainers() { - ArrayList childrenLayouts = new ArrayList<>(); - int screenCount = getChildCount(); - for (int screen = 0; screen < screenCount; screen++) { - childrenLayouts.add(((CellLayout) getChildAt(screen)).getShortcutsAndWidgets()); - } - if (mLauncher.getHotseat() != null) { - childrenLayouts.add(mLauncher.getHotseat().getLayout().getShortcutsAndWidgets()); - } - return childrenLayouts; - } - public View getHomescreenIconByItemId(final int id) { - return getFirstMatch(new ItemOperator() { - - @Override - public boolean evaluate(ItemInfo info, View v) { - return info != null && info.id == id; - } - }); + return getFirstMatch((info, v) -> info != null && info.id == id); } public LauncherAppWidgetHostView getWidgetForAppWidgetId(final int appWidgetId) { - return (LauncherAppWidgetHostView) getFirstMatch(new ItemOperator() { - - @Override - public boolean evaluate(ItemInfo info, View v) { - return (info instanceof LauncherAppWidgetInfo) && - ((LauncherAppWidgetInfo) info).appWidgetId == appWidgetId; - } - }); + return (LauncherAppWidgetHostView) getFirstMatch((info, v) -> + (info instanceof LauncherAppWidgetInfo) && + ((LauncherAppWidgetInfo) info).appWidgetId == appWidgetId); } public View getFirstMatch(final ItemOperator operator) { @@ -3063,8 +3034,7 @@ public class Workspace extends PagedView * shortcuts are not removed. */ public void removeItemsByMatcher(final ItemInfoMatcher matcher) { - ArrayList cellLayouts = getWorkspaceAndHotseatCellLayouts(); - for (final CellLayout layoutParent: cellLayouts) { + for (final CellLayout layoutParent: getWorkspaceAndHotseatCellLayouts()) { final ViewGroup layout = layoutParent.getShortcutsAndWidgets(); IntSparseArrayMap idToViewMap = new IntSparseArrayMap<>(); @@ -3122,10 +3092,8 @@ public class Workspace extends PagedView * @param op the operator to map over the shortcuts */ public void mapOverItems(boolean recurse, ItemOperator op) { - ArrayList containers = getAllShortcutAndWidgetContainers(); - final int containerCount = containers.size(); - for (int containerIdx = 0; containerIdx < containerCount; containerIdx++) { - ShortcutAndWidgetContainer container = containers.get(containerIdx); + for (CellLayout layout : getWorkspaceAndHotseatCellLayouts()) { + ShortcutAndWidgetContainer container = layout.getShortcutsAndWidgets(); // map over all the shortcuts on the workspace final int itemCount = container.getChildCount(); for (int itemIdx = 0; itemIdx < itemCount; itemIdx++) { diff --git a/src/com/android/launcher3/WorkspaceStateTransitionAnimation.java b/src/com/android/launcher3/WorkspaceStateTransitionAnimation.java index e734e70533..3e094935d9 100644 --- a/src/com/android/launcher3/WorkspaceStateTransitionAnimation.java +++ b/src/com/android/launcher3/WorkspaceStateTransitionAnimation.java @@ -88,7 +88,7 @@ public class WorkspaceStateTransitionAnimation { Interpolator scaleInterpolator = builder.getInterpolator(ANIM_WORKSPACE_SCALE, ZOOM_OUT); propertySetter.setFloat(mWorkspace, SCALE_PROPERTY, mNewScale, scaleInterpolator); float hotseatIconsAlpha = (elements & HOTSEAT_ICONS) != 0 ? 1 : 0; - propertySetter.setViewAlpha(mLauncher.getHotseat().getLayout(), hotseatIconsAlpha, + propertySetter.setViewAlpha(mLauncher.getHotseat(), hotseatIconsAlpha, fadeInterpolator); propertySetter.setViewAlpha(mLauncher.getWorkspace().getPageIndicator(), hotseatIconsAlpha, fadeInterpolator); @@ -105,9 +105,6 @@ public class WorkspaceStateTransitionAnimation { propertySetter.setFloat(mWorkspace, View.TRANSLATION_Y, scaleAndTranslation[2], translationInterpolator); - propertySetter.setViewAlpha(mLauncher.getHotseatSearchBox(), - (elements & HOTSEAT_SEARCH_BOX) != 0 ? 1 : 0, fadeInterpolator); - // Set scrim WorkspaceAndHotseatScrim scrim = mLauncher.getDragLayer().getScrim(); propertySetter.setFloat(scrim, SCRIM_PROGRESS, state.getWorkspaceScrimAlpha(mLauncher), diff --git a/src/com/android/launcher3/allapps/AllAppsRecyclerView.java b/src/com/android/launcher3/allapps/AllAppsRecyclerView.java index fa07d4d75c..180ca48166 100644 --- a/src/com/android/launcher3/allapps/AllAppsRecyclerView.java +++ b/src/com/android/launcher3/allapps/AllAppsRecyclerView.java @@ -33,7 +33,7 @@ import com.android.launcher3.Launcher; import com.android.launcher3.LauncherAppState; import com.android.launcher3.R; import com.android.launcher3.graphics.DrawableFactory; -import com.android.launcher3.logging.UserEventDispatcher.LogContainerProvider; +import com.android.launcher3.logging.StatsLogUtils.LogContainerProvider; import com.android.launcher3.userevent.nano.LauncherLogProto.ContainerType; import com.android.launcher3.userevent.nano.LauncherLogProto.Target; import com.android.launcher3.views.RecyclerViewFastScroller; diff --git a/src/com/android/launcher3/allapps/AllAppsTransitionController.java b/src/com/android/launcher3/allapps/AllAppsTransitionController.java index e7313e8411..2d6be7b08c 100644 --- a/src/com/android/launcher3/allapps/AllAppsTransitionController.java +++ b/src/com/android/launcher3/allapps/AllAppsTransitionController.java @@ -91,11 +91,6 @@ public class AllAppsTransitionController implements StateHandler, OnDeviceProfil return mShiftRange; } - private void onProgressAnimationStart() { - // Initialize values that should not change until #onDragEnd - mAppsView.setVisibility(View.VISIBLE); - } - @Override public void onDeviceProfileChanged(DeviceProfile dp) { mIsVerticalLayout = dp.isVerticalBarLayout(); @@ -195,16 +190,15 @@ public class AllAppsTransitionController implements StateHandler, OnDeviceProfil PropertySetter setter = config == null ? NO_ANIM_PROPERTY_SETTER : config.getPropertySetter(builder); int visibleElements = toState.getVisibleElements(mLauncher); - boolean hasHeader = (visibleElements & ALL_APPS_HEADER) != 0; boolean hasHeaderExtra = (visibleElements & ALL_APPS_HEADER_EXTRA) != 0; boolean hasContent = (visibleElements & ALL_APPS_CONTENT) != 0; Interpolator allAppsFade = builder.getInterpolator(ANIM_ALL_APPS_FADE, LINEAR); - setter.setViewAlpha(mAppsView.getSearchView(), hasHeader ? 1 : 0, allAppsFade); setter.setViewAlpha(mAppsView.getContentView(), hasContent ? 1 : 0, allAppsFade); setter.setViewAlpha(mAppsView.getScrollBar(), hasContent ? 1 : 0, allAppsFade); mAppsView.getFloatingHeaderView().setContentVisibility(hasHeaderExtra, hasContent, setter, allAppsFade); + mAppsView.getSearchUiManager().setContentVisibility(visibleElements, setter, allAppsFade); setter.setInt(mScrimView, ScrimView.DRAG_HANDLE_ALPHA, (visibleElements & VERTICAL_SWIPE_INDICATOR) != 0 ? 255 : 0, LINEAR); @@ -216,11 +210,6 @@ public class AllAppsTransitionController implements StateHandler, OnDeviceProfil public void onAnimationSuccess(Animator animator) { onProgressAnimationEnd(); } - - @Override - public void onAnimationStart(Animator animation) { - onProgressAnimationStart(); - } }; } @@ -247,13 +236,9 @@ public class AllAppsTransitionController implements StateHandler, OnDeviceProfil */ private void onProgressAnimationEnd() { if (Float.compare(mProgress, 1f) == 0) { - mAppsView.setVisibility(View.INVISIBLE); mAppsView.reset(false /* animate */); } else if (isAllAppsExpanded()) { - mAppsView.setVisibility(View.VISIBLE); mAppsView.onScrollUpEnd(); - } else { - mAppsView.setVisibility(View.VISIBLE); } } diff --git a/src/com/android/launcher3/allapps/SearchUiManager.java b/src/com/android/launcher3/allapps/SearchUiManager.java index 68193f5c1c..51b90f71eb 100644 --- a/src/com/android/launcher3/allapps/SearchUiManager.java +++ b/src/com/android/launcher3/allapps/SearchUiManager.java @@ -16,6 +16,9 @@ package com.android.launcher3.allapps; import android.view.KeyEvent; +import android.view.animation.Interpolator; + +import com.android.launcher3.anim.PropertySetter; /** * Interface for controlling the Apps search UI. @@ -37,4 +40,10 @@ public interface SearchUiManager { * some UI beforehand. */ void preDispatchKeyEvent(KeyEvent keyEvent); + + /** + * Called as part of state transition to update the content UI + */ + void setContentVisibility(int visibleElements, PropertySetter setter, + Interpolator interpolator); } diff --git a/src/com/android/launcher3/allapps/search/AppsSearchContainerLayout.java b/src/com/android/launcher3/allapps/search/AppsSearchContainerLayout.java index 15cc2caae6..b1e23d4e22 100644 --- a/src/com/android/launcher3/allapps/search/AppsSearchContainerLayout.java +++ b/src/com/android/launcher3/allapps/search/AppsSearchContainerLayout.java @@ -19,6 +19,7 @@ import static android.view.View.MeasureSpec.EXACTLY; import static android.view.View.MeasureSpec.getSize; import static android.view.View.MeasureSpec.makeMeasureSpec; +import static com.android.launcher3.LauncherState.ALL_APPS_HEADER; import static com.android.launcher3.icons.IconNormalizer.ICON_VISIBLE_AREA_FACTOR; import android.content.Context; @@ -32,6 +33,7 @@ import android.util.AttributeSet; import android.view.KeyEvent; import android.view.View; import android.view.ViewGroup.MarginLayoutParams; +import android.view.animation.Interpolator; import com.android.launcher3.DeviceProfile; import com.android.launcher3.ExtendedEditText; @@ -42,6 +44,7 @@ import com.android.launcher3.allapps.AllAppsContainerView; import com.android.launcher3.allapps.AllAppsStore; import com.android.launcher3.allapps.AlphabeticalAppsList; import com.android.launcher3.allapps.SearchUiManager; +import com.android.launcher3.anim.PropertySetter; import com.android.launcher3.graphics.TintedDrawableSpan; import com.android.launcher3.util.ComponentKey; @@ -214,4 +217,10 @@ public class AppsSearchContainerLayout extends ExtendedEditText insets.bottom + mlp.topMargin + mFixedTranslationY); } } + + @Override + public void setContentVisibility(int visibleElements, PropertySetter setter, + Interpolator interpolator) { + setter.setViewAlpha(this, (visibleElements & ALL_APPS_HEADER) != 0 ? 1 : 0, interpolator); + } } diff --git a/src/com/android/launcher3/compat/UserManagerCompat.java b/src/com/android/launcher3/compat/UserManagerCompat.java index ad5147734e..e13d2a6e17 100644 --- a/src/com/android/launcher3/compat/UserManagerCompat.java +++ b/src/com/android/launcher3/compat/UserManagerCompat.java @@ -57,7 +57,6 @@ public abstract class UserManagerCompat { public abstract List getUserProfiles(); public abstract long getSerialNumberForUser(UserHandle user); public abstract UserHandle getUserForSerialNumber(long serialNumber); - public abstract CharSequence getBadgedLabelForUser(CharSequence label, UserHandle user); public abstract boolean isQuietModeEnabled(UserHandle user); public abstract boolean isUserUnlocked(UserHandle user); diff --git a/src/com/android/launcher3/compat/UserManagerCompatVL.java b/src/com/android/launcher3/compat/UserManagerCompatVL.java index ef7284226b..4688052830 100644 --- a/src/com/android/launcher3/compat/UserManagerCompatVL.java +++ b/src/com/android/launcher3/compat/UserManagerCompatVL.java @@ -17,7 +17,6 @@ package com.android.launcher3.compat; import android.content.Context; -import android.content.pm.PackageManager; import android.os.UserHandle; import android.os.UserManager; import android.util.ArrayMap; @@ -30,7 +29,6 @@ import java.util.List; public class UserManagerCompatVL extends UserManagerCompat { protected final UserManager mUserManager; - private final PackageManager mPm; protected LongSparseArray mUsers; // Create a separate reverse map as LongSparseArray.indexOfValue checks if objects are same @@ -39,7 +37,6 @@ public class UserManagerCompatVL extends UserManagerCompat { UserManagerCompatVL(Context context) { mUserManager = (UserManager) context.getSystemService(Context.USER_SERVICE); - mPm = context.getPackageManager(); } @Override @@ -125,13 +122,5 @@ public class UserManagerCompatVL extends UserManagerCompat { } return getUserProfiles().size() > 1; } - - @Override - public CharSequence getBadgedLabelForUser(CharSequence label, UserHandle user) { - if (user == null) { - return label; - } - return mPm.getUserBadgedLabel(label, user); - } } diff --git a/src/com/android/launcher3/folder/FolderAnimationManager.java b/src/com/android/launcher3/folder/FolderAnimationManager.java index fa890b99df..2461e284dc 100644 --- a/src/com/android/launcher3/folder/FolderAnimationManager.java +++ b/src/com/android/launcher3/folder/FolderAnimationManager.java @@ -20,6 +20,7 @@ import static com.android.launcher3.BubbleTextView.TEXT_ALPHA_PROPERTY; import static com.android.launcher3.LauncherAnimUtils.SCALE_PROPERTY; import static com.android.launcher3.folder.ClippedFolderIconLayoutRule.MAX_NUM_ITEMS_IN_PREVIEW; import static com.android.launcher3.folder.FolderShape.getShape; +import static com.android.launcher3.icons.GraphicsUtils.setColorAlphaBound; import android.animation.Animator; import android.animation.AnimatorListenerAdapter; @@ -46,8 +47,6 @@ import com.android.launcher3.util.Themes; import java.util.List; -import androidx.core.graphics.ColorUtils; - /** * Manages the opening and closing animations for a {@link Folder}. * @@ -153,8 +152,8 @@ public class FolderAnimationManager { // Set up the Folder background. final int finalColor = Themes.getAttrColor(mContext, android.R.attr.colorPrimary); - final int initialColor = - ColorUtils.setAlphaComponent(finalColor, mPreviewBackground.getBackgroundAlpha()); + final int initialColor = setColorAlphaBound( + finalColor, mPreviewBackground.getBackgroundAlpha()); mFolderBackground.mutate(); mFolderBackground.setColor(mIsOpening ? initialColor : finalColor); diff --git a/src/com/android/launcher3/folder/PreviewBackground.java b/src/com/android/launcher3/folder/PreviewBackground.java index 8443953bd9..f2683a5f9a 100644 --- a/src/com/android/launcher3/folder/PreviewBackground.java +++ b/src/com/android/launcher3/folder/PreviewBackground.java @@ -17,6 +17,7 @@ package com.android.launcher3.folder; import static com.android.launcher3.folder.FolderShape.getShape; +import static com.android.launcher3.icons.GraphicsUtils.setColorAlphaBound; import android.animation.Animator; import android.animation.AnimatorListenerAdapter; @@ -41,8 +42,6 @@ import com.android.launcher3.Launcher; import com.android.launcher3.R; import com.android.launcher3.util.Themes; -import androidx.core.graphics.ColorUtils; - /** * This object represents a FolderIcon preview background. It stores drawing / measurement * information, handles drawing, and animation (accept state <--> rest state). @@ -189,7 +188,7 @@ public class PreviewBackground { public int getBgColor() { int alpha = (int) Math.min(MAX_BG_OPACITY, BG_OPACITY * mColorMultiplier); - return ColorUtils.setAlphaComponent(mBgColor, alpha); + return setColorAlphaBound(mBgColor, alpha); } public int getBadgeColor() { @@ -275,7 +274,7 @@ public class PreviewBackground { } public void drawBackgroundStroke(Canvas canvas) { - mPaint.setColor(ColorUtils.setAlphaComponent(mBgColor, mStrokeAlpha)); + mPaint.setColor(setColorAlphaBound(mBgColor, mStrokeAlpha)); mPaint.setStyle(Paint.Style.STROKE); mPaint.setStrokeWidth(mStrokeWidth); diff --git a/src/com/android/launcher3/graphics/IconPalette.java b/src/com/android/launcher3/graphics/IconPalette.java index cda07c31a2..3d4a1001a2 100644 --- a/src/com/android/launcher3/graphics/IconPalette.java +++ b/src/com/android/launcher3/graphics/IconPalette.java @@ -16,6 +16,8 @@ package com.android.launcher3.graphics; +import static com.android.launcher3.icons.GraphicsUtils.setColorAlphaBound; + import android.app.Notification; import android.content.Context; import android.graphics.Color; @@ -147,7 +149,7 @@ public class IconPalette { } public static int getMutedColor(int color, float whiteScrimAlpha) { - int whiteScrim = ColorUtils.setAlphaComponent(Color.WHITE, (int) (255 * whiteScrimAlpha)); + int whiteScrim = setColorAlphaBound(Color.WHITE, (int) (255 * whiteScrimAlpha)); return ColorUtils.compositeColors(whiteScrim, color); } } diff --git a/src/com/android/launcher3/graphics/WorkspaceAndHotseatScrim.java b/src/com/android/launcher3/graphics/WorkspaceAndHotseatScrim.java index 00cc1a7e2c..66f9dbfcdc 100644 --- a/src/com/android/launcher3/graphics/WorkspaceAndHotseatScrim.java +++ b/src/com/android/launcher3/graphics/WorkspaceAndHotseatScrim.java @@ -19,6 +19,8 @@ package com.android.launcher3.graphics; import static android.content.Intent.ACTION_SCREEN_OFF; import static android.content.Intent.ACTION_USER_PRESENT; +import static com.android.launcher3.icons.GraphicsUtils.setColorAlphaBound; + import android.animation.ObjectAnimator; import android.content.BroadcastReceiver; import android.content.Context; @@ -121,7 +123,6 @@ public class WorkspaceAndHotseatScrim implements private Workspace mWorkspace; - private final boolean mHasSysUiScrim; private boolean mDrawTopScrim, mDrawBottomScrim; private final RectF mFinalMaskRect = new RectF(); @@ -149,15 +150,9 @@ public class WorkspaceAndHotseatScrim implements mMaskHeight = Utilities.pxFromDp(ALPHA_MASK_BITMAP_DP, view.getResources().getDisplayMetrics()); - - mHasSysUiScrim = !mWallpaperColorInfo.supportsDarkText(); - if (mHasSysUiScrim) { - mTopScrim = Themes.getAttrDrawable(view.getContext(), R.attr.workspaceStatusBarScrim); - mBottomMask = createDitheredAlphaMask(); - } else { - mTopScrim = null; - mBottomMask = null; - } + mTopScrim = Themes.getAttrDrawable(view.getContext(), R.attr.workspaceStatusBarScrim); + mBottomMask = mTopScrim == null ? null : createDitheredAlphaMask(); + mHideSysUiScrim = mTopScrim == null; view.addOnAttachStateChangeListener(this); onExtractedColorsChanged(mWallpaperColorInfo); @@ -174,18 +169,18 @@ public class WorkspaceAndHotseatScrim implements mWorkspace.computeScrollWithoutInvalidation(); CellLayout currCellLayout = mWorkspace.getCurrentDragOverlappingLayout(); canvas.save(); - if (currCellLayout != null && currCellLayout != mLauncher.getHotseat().getLayout()) { + if (currCellLayout != null && currCellLayout != mLauncher.getHotseat()) { // Cut a hole in the darkening scrim on the page that should be highlighted, if any. mLauncher.getDragLayer() .getDescendantRectRelativeToSelf(currCellLayout, mHighlightRect); canvas.clipRect(mHighlightRect, Region.Op.DIFFERENCE); } - canvas.drawColor(ColorUtils.setAlphaComponent(mFullScrimColor, mScrimAlpha)); + canvas.drawColor(setColorAlphaBound(mFullScrimColor, mScrimAlpha)); canvas.restore(); } - if (!mHideSysUiScrim && mHasSysUiScrim) { + if (!mHideSysUiScrim) { if (mSysUiProgress <= 0) { mAnimateScrimOnNextDraw = false; return; @@ -213,8 +208,9 @@ public class WorkspaceAndHotseatScrim implements } public void onInsetsChanged(Rect insets) { - mDrawTopScrim = insets.top > 0; - mDrawBottomScrim = !mLauncher.getDeviceProfile().isVerticalBarLayout(); + mDrawTopScrim = mTopScrim != null && insets.top > 0; + mDrawBottomScrim = mBottomMask != null && + !mLauncher.getDeviceProfile().isVerticalBarLayout(); } private void setScrimProgress(float progress) { @@ -230,7 +226,7 @@ public class WorkspaceAndHotseatScrim implements mWallpaperColorInfo.addOnChangeListener(this); onExtractedColorsChanged(mWallpaperColorInfo); - if (mHasSysUiScrim) { + if (mTopScrim != null) { IntentFilter filter = new IntentFilter(ACTION_SCREEN_OFF); filter.addAction(ACTION_USER_PRESENT); // When the device wakes up + keyguard is gone mRoot.getContext().registerReceiver(mReceiver, filter); @@ -240,7 +236,7 @@ public class WorkspaceAndHotseatScrim implements @Override public void onViewDetachedFromWindow(View view) { mWallpaperColorInfo.removeOnChangeListener(this); - if (mHasSysUiScrim) { + if (mTopScrim != null) { mRoot.getContext().unregisterReceiver(mReceiver); } } @@ -259,14 +255,14 @@ public class WorkspaceAndHotseatScrim implements } public void setSize(int w, int h) { - if (mHasSysUiScrim) { + if (mTopScrim != null) { mTopScrim.setBounds(0, 0, w, h); mFinalMaskRect.set(0, h - mMaskHeight, w, h); } } public void hideSysUiScrim(boolean hideSysUiScrim) { - mHideSysUiScrim = hideSysUiScrim; + mHideSysUiScrim = hideSysUiScrim || (mTopScrim == null); if (!hideSysUiScrim) { mAnimateScrimOnNextDraw = true; } @@ -281,18 +277,18 @@ public class WorkspaceAndHotseatScrim implements } private void reapplySysUiAlpha() { - if (mHasSysUiScrim) { - reapplySysUiAlphaNoInvalidate(); - if (!mHideSysUiScrim) { - invalidate(); - } + reapplySysUiAlphaNoInvalidate(); + if (!mHideSysUiScrim) { + invalidate(); } } private void reapplySysUiAlphaNoInvalidate() { float factor = mSysUiProgress * mSysUiAnimMultiplier; mBottomMaskPaint.setAlpha(Math.round(MAX_HOTSEAT_SCRIM_ALPHA * factor)); - mTopScrim.setAlpha(Math.round(255 * factor)); + if (mTopScrim != null) { + mTopScrim.setAlpha(Math.round(255 * factor)); + } } public void invalidate() { @@ -309,7 +305,7 @@ public class WorkspaceAndHotseatScrim implements LinearGradient lg = new LinearGradient(0, 0, 0, gradientHeight, new int[]{ 0x00FFFFFF, - ColorUtils.setAlphaComponent(Color.WHITE, (int) (0xFF * 0.95)), + setColorAlphaBound(Color.WHITE, (int) (0xFF * 0.95)), 0xFFFFFFFF}, new float[]{0f, 0.8f, 1f}, Shader.TileMode.CLAMP); diff --git a/src/com/android/launcher3/icons/BaseIconCache.java b/src/com/android/launcher3/icons/BaseIconCache.java index 2afe7139fd..1f810b39f1 100644 --- a/src/com/android/launcher3/icons/BaseIconCache.java +++ b/src/com/android/launcher3/icons/BaseIconCache.java @@ -16,13 +16,13 @@ package com.android.launcher3.icons; import static com.android.launcher3.icons.BitmapInfo.LOW_RES_ICON; +import static com.android.launcher3.icons.GraphicsUtils.setColorAlphaBound; import android.content.ComponentName; import android.content.ContentValues; import android.content.Context; import android.content.pm.ActivityInfo; import android.content.pm.ApplicationInfo; -import android.content.pm.LauncherActivityInfo; import android.content.pm.PackageInfo; import android.content.pm.PackageManager; import android.content.pm.PackageManager.NameNotFoundException; @@ -33,6 +33,7 @@ import android.database.sqlite.SQLiteException; import android.graphics.Bitmap; import android.graphics.BitmapFactory; import android.graphics.drawable.Drawable; +import android.os.Build; import android.os.Build.VERSION; import android.os.Handler; import android.os.Process; @@ -41,15 +42,11 @@ import android.text.TextUtils; import android.util.Log; import com.android.launcher3.IconProvider; -import com.android.launcher3.ItemInfoWithIcon; import com.android.launcher3.LauncherFiles; import com.android.launcher3.LauncherModel; -import com.android.launcher3.MainThreadExecutor; import com.android.launcher3.Utilities; -import com.android.launcher3.compat.LauncherAppsCompat; import com.android.launcher3.compat.UserManagerCompat; import com.android.launcher3.graphics.BitmapRenderer; -import com.android.launcher3.model.PackageItemInfo; import com.android.launcher3.util.ComponentKey; import com.android.launcher3.util.InstantAppResolver; import com.android.launcher3.util.Preconditions; @@ -60,7 +57,6 @@ import java.util.HashMap; import java.util.HashSet; import androidx.annotation.NonNull; -import androidx.core.graphics.ColorUtils; public class BaseIconCache { @@ -80,12 +76,10 @@ public class BaseIconCache { private final HashMap mDefaultIcons = new HashMap<>(); - final MainThreadExecutor mMainThreadExecutor = new MainThreadExecutor(); final Context mContext; final PackageManager mPackageManager; final IconProvider mIconProvider; final UserManagerCompat mUserManager; - final LauncherAppsCompat mLauncherApps; private final HashMap mCache = new HashMap<>(INITIAL_ICON_CACHE_CAPACITY); @@ -101,13 +95,12 @@ public class BaseIconCache { mContext = context; mPackageManager = context.getPackageManager(); mUserManager = UserManagerCompat.getInstance(mContext); - mLauncherApps = LauncherAppsCompat.getInstance(mContext); mInstantAppResolver = InstantAppResolver.newInstance(mContext); mIconProvider = IconProvider.newInstance(context); mWorkerHandler = new Handler(LauncherModel.getWorkerLooper()); - if (BitmapRenderer.USE_HARDWARE_BITMAP) { + if (BitmapRenderer.USE_HARDWARE_BITMAP && Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) { mDecodeOptions = new BitmapFactory.Options(); mDecodeOptions.inPreferredConfig = Bitmap.Config.HARDWARE; } else { @@ -161,14 +154,6 @@ public class BaseIconCache { return getFullResDefaultActivityIcon(); } - public Drawable getFullResIcon(LauncherActivityInfo info) { - return getFullResIcon(info, true); - } - - public Drawable getFullResIcon(LauncherActivityInfo info, boolean flattenDrawable) { - return mIconProvider.getIcon(info, mIconDpi, flattenDrawable); - } - protected BitmapInfo makeDefaultIcon(UserHandle user) { try (LauncherIcons li = LauncherIcons.obtain(mContext)) { return li.createBadgedIconBitmap( @@ -238,10 +223,10 @@ public class BaseIconCache { } if (entry == null) { entry = new CacheEntry(); - cachingLogic.loadIcon(mContext, this, object, entry); + cachingLogic.loadIcon(mContext, object, entry); } - entry.title = cachingLogic.getLabel(object, mPackageManager); - entry.contentDescription = mUserManager.getBadgedLabelForUser(entry.title, user); + entry.title = cachingLogic.getLabel(object); + entry.contentDescription = mPackageManager.getUserBadgedLabel(entry.title, user); mCache.put(key, entry); ContentValues values = newContentValues(entry, entry.title.toString(), @@ -262,22 +247,6 @@ public class BaseIconCache { mIconDb.insertOrReplace(values); } - /** - * Fill in {@param infoInOut} with the corresponding icon and label. - */ - public synchronized void getTitleAndIconForApp( - PackageItemInfo infoInOut, boolean useLowResIcon) { - CacheEntry entry = getEntryForPackageLocked( - infoInOut.packageName, infoInOut.user, useLowResIcon); - applyCacheEntry(entry, infoInOut); - } - - protected void applyCacheEntry(CacheEntry entry, ItemInfoWithIcon info) { - info.title = Utilities.trim(entry.title); - info.contentDescription = entry.contentDescription; - info.applyFrom((entry.icon == null) ? getDefaultIcon(info.user) : entry); - } - public synchronized BitmapInfo getDefaultIcon(UserHandle user) { if (!mDefaultIcons.containsKey(user)) { mDefaultIcons.put(user, makeDefaultIcon(user)); @@ -323,7 +292,7 @@ public class BaseIconCache { providerFetchedOnce = true; if (object != null) { - cachingLogic.loadIcon(mContext, this, object, entry); + cachingLogic.loadIcon(mContext, object, entry); } else { if (usePackageIcon) { CacheEntry packageEntry = getEntryForPackageLocked( @@ -350,8 +319,8 @@ public class BaseIconCache { providerFetchedOnce = true; } if (object != null) { - entry.title = cachingLogic.getLabel(object, mPackageManager); - entry.contentDescription = mUserManager.getBadgedLabelForUser(entry.title, user); + entry.title = cachingLogic.getLabel(object); + entry.contentDescription = mPackageManager.getUserBadgedLabel(entry.title, user); } } } @@ -400,7 +369,7 @@ public class BaseIconCache { * Gets an entry for the package, which can be used as a fallback entry for various components. * This method is not thread safe, it must be called from a synchronized method. */ - private CacheEntry getEntryForPackageLocked(String packageName, UserHandle user, + protected CacheEntry getEntryForPackageLocked(String packageName, UserHandle user, boolean useLowResIcon) { Preconditions.assertWorkerThread(); ComponentKey cacheKey = getPackageKey(packageName, user); @@ -430,7 +399,7 @@ public class BaseIconCache { li.recycle(); entry.title = appInfo.loadLabel(mPackageManager); - entry.contentDescription = mUserManager.getBadgedLabelForUser(entry.title, user); + entry.contentDescription = mPackageManager.getUserBadgedLabel(entry.title, user); entry.icon = useLowResIcon ? LOW_RES_ICON : iconInfo.icon; entry.color = iconInfo.color; @@ -466,13 +435,13 @@ public class BaseIconCache { Long.toString(mUserManager.getSerialNumberForUser(cacheKey.user))}); if (c.moveToNext()) { // Set the alpha to be 255, so that we never have a wrong color - entry.color = ColorUtils.setAlphaComponent(c.getInt(0), 255); + entry.color = setColorAlphaBound(c.getInt(0), 255); entry.title = c.getString(1); if (entry.title == null) { entry.title = ""; entry.contentDescription = ""; } else { - entry.contentDescription = mUserManager.getBadgedLabelForUser( + entry.contentDescription = mPackageManager.getUserBadgedLabel( entry.title, cacheKey.user); } diff --git a/src/com/android/launcher3/icons/CachingLogic.java b/src/com/android/launcher3/icons/CachingLogic.java index 24186ef990..0a3da04d78 100644 --- a/src/com/android/launcher3/icons/CachingLogic.java +++ b/src/com/android/launcher3/icons/CachingLogic.java @@ -17,8 +17,6 @@ package com.android.launcher3.icons; import android.content.ComponentName; import android.content.Context; -import android.content.pm.LauncherActivityInfo; -import android.content.pm.PackageManager; import android.os.UserHandle; public interface CachingLogic { @@ -27,61 +25,7 @@ public interface CachingLogic { UserHandle getUser(T object); - CharSequence getLabel(T object, PackageManager pm); + CharSequence getLabel(T object); - void loadIcon(Context context, BaseIconCache cache, T object, BitmapInfo target); - - CachingLogic LAUNCHER_ACTIVITY_INFO = - new CachingLogic() { - - @Override - public ComponentName getComponent(LauncherActivityInfo object) { - return object.getComponentName(); - } - - @Override - public UserHandle getUser(LauncherActivityInfo object) { - return object.getUser(); - } - - @Override - public CharSequence getLabel(LauncherActivityInfo object, PackageManager pm) { - return object.getLabel(); - } - - @Override - public void loadIcon(Context context, BaseIconCache cache, LauncherActivityInfo object, - BitmapInfo target) { - LauncherIcons li = LauncherIcons.obtain(context); - li.createBadgedIconBitmap(cache.getFullResIcon(object), object.getUser(), - object.getApplicationInfo().targetSdkVersion).applyTo(target); - li.recycle(); - } - }; - - CachingLogic COMPONENT_WITH_LABEL = - new CachingLogic() { - - @Override - public ComponentName getComponent(ComponentWithLabel object) { - return object.getComponent(); - } - - @Override - public UserHandle getUser(ComponentWithLabel object) { - return object.getUser(); - } - - @Override - public CharSequence getLabel(ComponentWithLabel object, PackageManager pm) { - return object.getLabel(pm); - } - - @Override - public void loadIcon(Context context, BaseIconCache cache, - ComponentWithLabel object, BitmapInfo target) { - // Do not load icon. - target.icon = BitmapInfo.LOW_RES_ICON; - } - }; + void loadIcon(Context context, T object, BitmapInfo target); } diff --git a/src/com/android/launcher3/icons/ComponentWithLabel.java b/src/com/android/launcher3/icons/ComponentWithLabel.java index 2badb4c373..7bb8832eed 100644 --- a/src/com/android/launcher3/icons/ComponentWithLabel.java +++ b/src/com/android/launcher3/icons/ComponentWithLabel.java @@ -16,6 +16,7 @@ package com.android.launcher3.icons; import android.content.ComponentName; +import android.content.Context; import android.content.pm.PackageManager; import android.os.UserHandle; @@ -26,4 +27,36 @@ public interface ComponentWithLabel { UserHandle getUser(); CharSequence getLabel(PackageManager pm); + + + class ComponentCachingLogic implements CachingLogic { + + private final PackageManager mPackageManager; + + public ComponentCachingLogic(Context context) { + mPackageManager = context.getPackageManager(); + } + + @Override + public ComponentName getComponent(ComponentWithLabel object) { + return object.getComponent(); + } + + @Override + public UserHandle getUser(ComponentWithLabel object) { + return object.getUser(); + } + + @Override + public CharSequence getLabel(ComponentWithLabel object) { + return object.getLabel(mPackageManager); + } + + @Override + public void loadIcon(Context context, + ComponentWithLabel object, BitmapInfo target) { + // Do not load icon. + target.icon = BitmapInfo.LOW_RES_ICON; + } + } } diff --git a/src/com/android/launcher3/icons/IconCache.java b/src/com/android/launcher3/icons/IconCache.java index 6e2ca28ec6..e10ff5b1b8 100644 --- a/src/com/android/launcher3/icons/IconCache.java +++ b/src/com/android/launcher3/icons/IconCache.java @@ -16,15 +16,13 @@ package com.android.launcher3.icons; -import static com.android.launcher3.icons.CachingLogic.COMPONENT_WITH_LABEL; -import static com.android.launcher3.icons.CachingLogic.LAUNCHER_ACTIVITY_INFO; - import android.content.Context; import android.content.Intent; import android.content.pm.LauncherActivityInfo; import android.content.pm.PackageInfo; import android.content.pm.PackageManager; import android.content.pm.PackageManager.NameNotFoundException; +import android.graphics.drawable.Drawable; import android.os.Handler; import android.os.Process; import android.os.UserHandle; @@ -34,8 +32,11 @@ import com.android.launcher3.AppInfo; import com.android.launcher3.InvariantDeviceProfile; import com.android.launcher3.ItemInfoWithIcon; import com.android.launcher3.LauncherModel; +import com.android.launcher3.MainThreadExecutor; import com.android.launcher3.ShortcutInfo; import com.android.launcher3.Utilities; +import com.android.launcher3.compat.LauncherAppsCompat; +import com.android.launcher3.icons.ComponentWithLabel.ComponentCachingLogic; import com.android.launcher3.model.PackageItemInfo; import com.android.launcher3.util.Preconditions; import com.android.launcher3.util.Provider; @@ -49,10 +50,21 @@ public class IconCache extends BaseIconCache { private static final String TAG = "Launcher.IconCache"; + private final MainThreadExecutor mMainThreadExecutor = new MainThreadExecutor(); + + private final CachingLogic mComponentWithLabelCachingLogic; + private final CachingLogic mLauncherActivityInfoCachingLogic; + + private final LauncherAppsCompat mLauncherApps; + private int mPendingIconRequestCount = 0; public IconCache(Context context, InvariantDeviceProfile inv) { super(context, inv.fillResIconDpi, inv.iconBitmapSize); + mComponentWithLabelCachingLogic = new ComponentCachingLogic(context); + mLauncherActivityInfoCachingLogic = new LauncherActivtiyCachingLogic(this); + mLauncherApps = LauncherAppsCompat.getInstance(mContext); + } /** @@ -65,7 +77,7 @@ public class IconCache extends BaseIconCache { PackageManager.GET_UNINSTALLED_PACKAGES); long userSerial = mUserManager.getSerialNumberForUser(user); for (LauncherActivityInfo app : mLauncherApps.getActivityList(packageName, user)) { - addIconToDBAndMemCache(app, LAUNCHER_ACTIVITY_INFO, info, userSerial, + addIconToDBAndMemCache(app, mLauncherActivityInfoCachingLogic, info, userSerial, false /*replace existing*/); } } catch (NameNotFoundException e) { @@ -115,7 +127,7 @@ public class IconCache extends BaseIconCache { */ public synchronized void updateTitleAndIcon(AppInfo application) { CacheEntry entry = cacheLocked(application.componentName, - application.user, Provider.of(null), LAUNCHER_ACTIVITY_INFO, + application.user, Provider.of(null), mLauncherActivityInfoCachingLogic, false, application.usingLowResIcon()); if (entry.icon != null && !isDefaultIcon(entry.icon, application.user)) { applyCacheEntry(entry, application); @@ -151,8 +163,8 @@ public class IconCache extends BaseIconCache { public synchronized String getTitleNoCache(ComponentWithLabel info) { CacheEntry entry = cacheLocked(info.getComponent(), info.getUser(), Provider.of(info), - COMPONENT_WITH_LABEL, false /* usePackageIcon */, true /* useLowResIcon */, - false /* addToMemCache */); + mComponentWithLabelCachingLogic, false /* usePackageIcon */, + true /* useLowResIcon */, false /* addToMemCache */); return Utilities.trim(entry.title); } @@ -164,11 +176,35 @@ public class IconCache extends BaseIconCache { @NonNull Provider activityInfoProvider, boolean usePkgIcon, boolean useLowResIcon) { CacheEntry entry = cacheLocked(infoInOut.getTargetComponent(), infoInOut.user, - activityInfoProvider, - LAUNCHER_ACTIVITY_INFO, usePkgIcon, useLowResIcon); + activityInfoProvider, mLauncherActivityInfoCachingLogic, usePkgIcon, useLowResIcon); applyCacheEntry(entry, infoInOut); } + + /** + * Fill in {@param infoInOut} with the corresponding icon and label. + */ + public synchronized void getTitleAndIconForApp( + PackageItemInfo infoInOut, boolean useLowResIcon) { + CacheEntry entry = getEntryForPackageLocked( + infoInOut.packageName, infoInOut.user, useLowResIcon); + applyCacheEntry(entry, infoInOut); + } + + protected void applyCacheEntry(CacheEntry entry, ItemInfoWithIcon info) { + info.title = Utilities.trim(entry.title); + info.contentDescription = entry.contentDescription; + info.applyFrom((entry.icon == null) ? getDefaultIcon(info.user) : entry); + } + + public Drawable getFullResIcon(LauncherActivityInfo info) { + return getFullResIcon(info, true); + } + + public Drawable getFullResIcon(LauncherActivityInfo info, boolean flattenDrawable) { + return mIconProvider.getIcon(info, mIconDpi, flattenDrawable); + } + public static abstract class IconLoadRequest extends HandlerRunnable { IconLoadRequest(Handler handler, Runnable endRunnable) { super(handler, endRunnable); diff --git a/src/com/android/launcher3/icons/LauncherActivtiyCachingLogic.java b/src/com/android/launcher3/icons/LauncherActivtiyCachingLogic.java new file mode 100644 index 0000000000..8c85b1c799 --- /dev/null +++ b/src/com/android/launcher3/icons/LauncherActivtiyCachingLogic.java @@ -0,0 +1,54 @@ +/* + * 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.icons; + +import android.content.ComponentName; +import android.content.Context; +import android.content.pm.LauncherActivityInfo; +import android.os.UserHandle; + +public class LauncherActivtiyCachingLogic implements CachingLogic { + + private final IconCache mCache; + + public LauncherActivtiyCachingLogic(IconCache cache) { + mCache = cache; + } + + @Override + public ComponentName getComponent(LauncherActivityInfo object) { + return object.getComponentName(); + } + + @Override + public UserHandle getUser(LauncherActivityInfo object) { + return object.getUser(); + } + + @Override + public CharSequence getLabel(LauncherActivityInfo object) { + return object.getLabel(); + } + + @Override + public void loadIcon(Context context, LauncherActivityInfo object, + BitmapInfo target) { + LauncherIcons li = LauncherIcons.obtain(context); + li.createBadgedIconBitmap(mCache.getFullResIcon(object), + object.getUser(), object.getApplicationInfo().targetSdkVersion).applyTo(target); + li.recycle(); + } +} \ No newline at end of file diff --git a/src/com/android/launcher3/logging/LoggerUtils.java b/src/com/android/launcher3/logging/LoggerUtils.java index 1c4327c499..4ef86265f5 100644 --- a/src/com/android/launcher3/logging/LoggerUtils.java +++ b/src/com/android/launcher3/logging/LoggerUtils.java @@ -40,6 +40,7 @@ import java.lang.reflect.Modifier; /** * Helper methods for logging. */ +@Deprecated public class LoggerUtils { private static final ArrayMap> sNameCache = new ArrayMap<>(); private static final String UNKNOWN = "UNKNOWN"; diff --git a/src/com/android/launcher3/logging/StatsLogManager.java b/src/com/android/launcher3/logging/StatsLogManager.java new file mode 100644 index 0000000000..d332dc5ce3 --- /dev/null +++ b/src/com/android/launcher3/logging/StatsLogManager.java @@ -0,0 +1,46 @@ +/* + * 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.logging; + +import android.content.Context; +import android.content.Intent; +import android.view.View; + +import com.android.launcher3.R; +import com.android.launcher3.util.ComponentKey; +import com.android.launcher3.util.ResourceBasedOverride; +import com.android.launcher3.logging.StatsLogUtils.LogStateProvider; + +/** + * Handles the user event logging in Q. + * Since the AOSP Launcher3 doesn't take part in the StatsLog logging, the class + * itself is abstract. + */ +public abstract class StatsLogManager implements ResourceBasedOverride { + + protected LogStateProvider mStateProvider; + public static StatsLogManager newInstance(Context context, LogStateProvider stateProvider) { + StatsLogManager mgr = Overrides.getObject(StatsLogManager.class, + context.getApplicationContext(), R.string.stats_log_manager_class); + mgr.mStateProvider = stateProvider; + mgr.verify(); + return mgr; + } + + public void logAppLaunch(View v, Intent intent) { } + public void logTaskLaunch(View v, ComponentKey key) { } + public void verify() {} // TODO: should move into robo tests +} diff --git a/src/com/android/launcher3/logging/StatsLogUtils.java b/src/com/android/launcher3/logging/StatsLogUtils.java new file mode 100644 index 0000000000..647f255af3 --- /dev/null +++ b/src/com/android/launcher3/logging/StatsLogUtils.java @@ -0,0 +1,67 @@ +package com.android.launcher3.logging; + +import android.view.View; +import android.view.ViewParent; + +import com.android.launcher3.ItemInfo; +import com.android.launcher3.userevent.nano.LauncherLogProto.Target; + +import androidx.annotation.Nullable; + + +public class StatsLogUtils { + + // Defined in android.stats.launcher.nano + // As they cannot be linked in this file, defining again. + public final static int LAUNCHER_STATE_BACKGROUND = 0; + public final static int LAUNCHER_STATE_HOME = 1; + public final static int LAUNCHER_STATE_OVERVIEW = 2; + public final static int LAUNCHER_STATE_ALLAPPS = 3; + + private final static int MAXIMUM_VIEW_HIERARCHY_LEVEL = 5; + + public interface LogStateProvider { + int getCurrentState(); + } + + /** + * Implemented by containers to provide a container source for a given child. + * + * Currently, + */ + public interface LogContainerProvider { + + /** + * Copies data from the source to the destination proto. + * + * @param v source of the data + * @param info source of the data + * @param target dest of the data + * @param targetParent dest of the data + */ + void fillInLogContainerData(View v, ItemInfo info, Target target, Target targetParent); + } + + /** + * Recursively finds the parent of the given child which implements IconLogInfoProvider + */ + public static LogContainerProvider getLaunchProviderRecursive(@Nullable View v) { + ViewParent parent; + if (v != null) { + parent = v.getParent(); + } else { + return null; + } + + // Optimization to only check up to 5 parents. + int count = MAXIMUM_VIEW_HIERARCHY_LEVEL; + while (parent != null && count-- > 0) { + if (parent instanceof LogContainerProvider) { + return (LogContainerProvider) parent; + } else { + parent = parent.getParent(); + } + } + return null; + } +} diff --git a/src/com/android/launcher3/logging/UserEventDispatcher.java b/src/com/android/launcher3/logging/UserEventDispatcher.java index a318dc0eb6..e11516890c 100644 --- a/src/com/android/launcher3/logging/UserEventDispatcher.java +++ b/src/com/android/launcher3/logging/UserEventDispatcher.java @@ -41,9 +41,9 @@ import com.android.launcher3.ItemInfo; import com.android.launcher3.R; import com.android.launcher3.Utilities; import com.android.launcher3.config.FeatureFlags; +import com.android.launcher3.logging.StatsLogUtils.LogContainerProvider; import com.android.launcher3.userevent.nano.LauncherLogProto; import com.android.launcher3.userevent.nano.LauncherLogProto.Action; -import com.android.launcher3.userevent.nano.LauncherLogProto.ContainerType; import com.android.launcher3.userevent.nano.LauncherLogProto.LauncherEvent; import com.android.launcher3.userevent.nano.LauncherLogProto.Target; import com.android.launcher3.util.ComponentKey; @@ -62,10 +62,9 @@ import androidx.annotation.Nullable; * * $ adb shell setprop log.tag.UserEvent VERBOSE */ +@Deprecated public class UserEventDispatcher implements ResourceBasedOverride { - private final static int MAXIMUM_VIEW_HIERARCHY_LEVEL = 5; - private static final String TAG = "UserEvent"; private static final boolean IS_VERBOSE = FeatureFlags.IS_DOGFOOD_BUILD && Utilities.isPropertyEnabled(LogConfig.USEREVENT); @@ -96,42 +95,19 @@ public class UserEventDispatcher implements ResourceBasedOverride { } /** - * Implemented by containers to provide a container source for a given child. + * Fills in the container data on the given event if the given view is not null. + * @return whether container data was added. */ - public interface LogContainerProvider { - - /** - * Copies data from the source to the destination proto. - * - * @param v source of the data - * @param info source of the data - * @param target dest of the data - * @param targetParent dest of the data - */ - void fillInLogContainerData(View v, ItemInfo info, Target target, Target targetParent); - } - - /** - * Recursively finds the parent of the given child which implements IconLogInfoProvider - */ - public static LogContainerProvider getLaunchProviderRecursive(@Nullable View v) { - ViewParent parent; - if (v != null) { - parent = v.getParent(); - } else { - return null; + @Deprecated + public static boolean fillInLogContainerData(LauncherLogProto.LauncherEvent event, @Nullable View v) { + // Fill in grid(x,y), pageIndex of the child and container type of the parent + LogContainerProvider provider = StatsLogUtils.getLaunchProviderRecursive(v); + if (v == null || !(v.getTag() instanceof ItemInfo) || provider == null) { + return false; } - - // Optimization to only check up to 5 parents. - int count = MAXIMUM_VIEW_HIERARCHY_LEVEL; - while (parent != null && count-- > 0) { - if (parent instanceof LogContainerProvider) { - return (LogContainerProvider) parent; - } else { - parent = parent.getParent(); - } - } - return null; + ItemInfo itemInfo = (ItemInfo) v.getTag(); + provider.fillInLogContainerData(v, itemInfo, event.srcTarget[0], event.srcTarget[1]); + return true; } private boolean mSessionStarted; @@ -150,21 +126,7 @@ public class UserEventDispatcher implements ResourceBasedOverride { // intentHash required // -------------------------------------------------------------- - /** - * Fills in the container data on the given event if the given view is not null. - * @return whether container data was added. - */ - protected boolean fillInLogContainerData(LauncherEvent event, @Nullable View v) { - // Fill in grid(x,y), pageIndex of the child and container type of the parent - LogContainerProvider provider = getLaunchProviderRecursive(v); - if (v == null || !(v.getTag() instanceof ItemInfo) || provider == null) { - return false; - } - ItemInfo itemInfo = (ItemInfo) v.getTag(); - provider.fillInLogContainerData(v, itemInfo, event.srcTarget[0], event.srcTarget[1]); - return true; - } - + @Deprecated public void logAppLaunch(View v, Intent intent) { LauncherEvent event = newLauncherEvent(newTouchAction(Action.Touch.TAP), newItemTarget(v, mInstantAppResolver), newTarget(Target.Type.CONTAINER)); @@ -181,6 +143,7 @@ public class UserEventDispatcher implements ResourceBasedOverride { public void logActionTip(int actionType, int viewType) { } + @Deprecated public void logTaskLaunchOrDismiss(int action, int direction, int taskIndex, ComponentKey componentKey) { LauncherEvent event = newLauncherEvent(newTouchAction(action), // TAP or SWIPE or FLING @@ -363,7 +326,7 @@ public class UserEventDispatcher implements ResourceBasedOverride { } public void logDeepShortcutsOpen(View icon) { - LogContainerProvider provider = getLaunchProviderRecursive(icon); + LogContainerProvider provider = StatsLogUtils.getLaunchProviderRecursive(icon); if (icon == null || !(icon.getTag() instanceof ItemInfo)) { return; } @@ -376,15 +339,6 @@ public class UserEventDispatcher implements ResourceBasedOverride { resetElapsedContainerMillis("deep shortcut open"); } - /* Currently we are only interested in whether this event happens or not and don't - * care about which screen moves to where. */ - public void logOverviewReorder() { - LauncherEvent event = newLauncherEvent(newTouchAction(Action.Touch.DRAGDROP), - newContainerTarget(ContainerType.WORKSPACE), - newContainerTarget(ContainerType.OVERVIEW)); - dispatchUserEvent(event, null); - } - public void logDragNDrop(DropTarget.DragObject dragObj, View dropTargetAsView) { LauncherEvent event = newLauncherEvent(newTouchAction(Action.Touch.DRAGDROP), newItemTarget(dragObj.originalDragInfo, mInstantAppResolver), diff --git a/src/com/android/launcher3/model/LoaderResults.java b/src/com/android/launcher3/model/BaseLoaderResults.java similarity index 85% rename from src/com/android/launcher3/model/LoaderResults.java rename to src/com/android/launcher3/model/BaseLoaderResults.java index 1d18e7667b..d3dc91f3be 100644 --- a/src/com/android/launcher3/model/LoaderResults.java +++ b/src/com/android/launcher3/model/BaseLoaderResults.java @@ -30,47 +30,44 @@ import com.android.launcher3.LauncherSettings; import com.android.launcher3.MainThreadExecutor; import com.android.launcher3.PagedView; import com.android.launcher3.config.FeatureFlags; -import com.android.launcher3.util.ComponentKey; import com.android.launcher3.util.IntArray; import com.android.launcher3.util.IntSet; import com.android.launcher3.util.LooperIdleLock; import com.android.launcher3.util.ViewOnDrawExecutor; -import com.android.launcher3.widget.WidgetListRowEntry; import java.lang.ref.WeakReference; import java.util.ArrayList; import java.util.Collections; import java.util.Comparator; -import java.util.HashMap; import java.util.Iterator; import java.util.concurrent.Executor; /** - * Helper class to handle results of {@link com.android.launcher3.model.LoaderTask}. + * Base Helper class to handle results of {@link com.android.launcher3.model.LoaderTask}. */ -public class LoaderResults { +public abstract class BaseLoaderResults { - private static final String TAG = "LoaderResults"; - private static final int INVALID_SCREEN_ID = -1; + protected static final String TAG = "LoaderResults"; + protected static final int INVALID_SCREEN_ID = -1; private static final int ITEMS_CHUNK = 6; // batch size for the workspace icons - private final Executor mUiExecutor; + protected final Executor mUiExecutor; - private final LauncherAppState mApp; - private final BgDataModel mBgDataModel; + protected final LauncherAppState mApp; + protected final BgDataModel mBgDataModel; private final AllAppsList mBgAllAppsList; - private final int mPageToBindFirst; + protected final int mPageToBindFirst; - private final WeakReference mCallbacks; + protected final WeakReference mCallbacks; - public LoaderResults(LauncherAppState app, BgDataModel dataModel, + public BaseLoaderResults(LauncherAppState app, BgDataModel dataModel, AllAppsList allAppsList, int pageToBindFirst, WeakReference callbacks) { mUiExecutor = new MainThreadExecutor(); mApp = app; mBgDataModel = dataModel; mBgAllAppsList = allAppsList; mPageToBindFirst = pageToBindFirst; - mCallbacks = callbacks == null ? new WeakReference(null) : callbacks; + mCallbacks = callbacks == null ? new WeakReference<>(null) : callbacks; } /** @@ -152,8 +149,8 @@ public class LoaderResults { Executor mainExecutor = mUiExecutor; // Load items on the current page. - bindWorkspaceItems(currentWorkspaceItems, currentAppWidgets, mainExecutor); - + bindWorkspaceItems(currentWorkspaceItems, mainExecutor); + bindAppWidgets(currentAppWidgets, mainExecutor); // In case of validFirstPage, only bind the first screen, and defer binding the // remaining screens after first onDraw (and an optional the fade animation whichever // happens later). @@ -173,8 +170,8 @@ public class LoaderResults { } }); - bindWorkspaceItems(otherWorkspaceItems, otherAppWidgets, deferredExecutor); - + bindWorkspaceItems(otherWorkspaceItems, deferredExecutor); + bindAppWidgets(otherAppWidgets, deferredExecutor); // Tell the workspace that we're done binding items r = new Runnable() { public void run() { @@ -252,7 +249,7 @@ public class LoaderResults { /** Sorts the set of items by hotseat, workspace (spatially from top to bottom, left to * right) */ - private void sortWorkspaceItemsSpatially(ArrayList workspaceItems) { + protected void sortWorkspaceItemsSpatially(ArrayList workspaceItems) { final InvariantDeviceProfile profile = mApp.getInvariantDeviceProfile(); final int screenCols = profile.numColumns; final int screenCellCount = profile.numColumns * profile.numRows; @@ -288,14 +285,12 @@ public class LoaderResults { }); } - private void bindWorkspaceItems(final ArrayList workspaceItems, - final ArrayList appWidgets, + protected void bindWorkspaceItems(final ArrayList workspaceItems, final Executor executor) { if (com.android.launcher3.Utilities.IS_RUNNING_IN_TEST_HARNESS && com.android.launcher3.Utilities.IS_DEBUG_DEVICE) { - android.util.Log.d("b/117332845", - android.util.Log.getStackTraceString(new Throwable())); + Log.d("b/117332845", Log.getStackTraceString(new Throwable())); } // Bind the workspace items int N = workspaceItems.size(); @@ -307,22 +302,25 @@ public class LoaderResults { public void run() { Callbacks callbacks = mCallbacks.get(); if (callbacks != null) { - callbacks.bindItems(workspaceItems.subList(start, start+chunkSize), false); + callbacks.bindItems(workspaceItems.subList(start, start + chunkSize), + false); } } }; executor.execute(r); } + } - // Bind the widgets, one at a time + private void bindAppWidgets(ArrayList appWidgets, Executor executor) { + int N;// Bind the widgets, one at a time N = appWidgets.size(); for (int i = 0; i < N; i++) { final ItemInfo widget = appWidgets.get(i); final Runnable r = new Runnable() { public void run() { - Callbacks callbacks = mCallbacks.get(); - if (callbacks != null) { - callbacks.bindItems(Collections.singletonList(widget), false); + Callbacks callbacks = mCallbacks.get(); + if (callbacks != null) { + callbacks.bindItems(Collections.singletonList(widget), false); } } }; @@ -330,18 +328,7 @@ public class LoaderResults { } } - public void bindDeepShortcuts() { - final HashMap shortcutMapCopy; - synchronized (mBgDataModel) { - shortcutMapCopy = new HashMap<>(mBgDataModel.deepShortcutMap); - } - mUiExecutor.execute(() -> { - Callbacks callbacks = mCallbacks.get(); - if (callbacks != null) { - callbacks.bindDeepShortcutMap(shortcutMapCopy); - } - }); - } + public abstract void bindDeepShortcuts(); public void bindAllApps() { // shallow copy @@ -359,19 +346,7 @@ public class LoaderResults { mUiExecutor.execute(r); } - public void bindWidgets() { - final ArrayList widgets = - mBgDataModel.widgetsModel.getWidgetsList(mApp.getContext()); - Runnable r = new Runnable() { - public void run() { - Callbacks callbacks = mCallbacks.get(); - if (callbacks != null) { - callbacks.bindAllWidgets(widgets); - } - } - }; - mUiExecutor.execute(r); - } + public abstract void bindWidgets(); public LooperIdleLock newIdleLock(Object lock) { LooperIdleLock idleLock = new LooperIdleLock(lock, Looper.getMainLooper()); diff --git a/src/com/android/launcher3/model/LoaderCursor.java b/src/com/android/launcher3/model/LoaderCursor.java index ea4d32b282..3aeb1c078c 100644 --- a/src/com/android/launcher3/model/LoaderCursor.java +++ b/src/com/android/launcher3/model/LoaderCursor.java @@ -22,6 +22,7 @@ import android.content.Context; import android.content.Intent; import android.content.Intent.ShortcutIconResource; import android.content.pm.LauncherActivityInfo; +import android.content.pm.PackageManager; import android.database.Cursor; import android.database.CursorWrapper; import android.graphics.BitmapFactory; @@ -41,7 +42,6 @@ import com.android.launcher3.ShortcutInfo; import com.android.launcher3.Utilities; import com.android.launcher3.Workspace; import com.android.launcher3.compat.LauncherAppsCompat; -import com.android.launcher3.compat.UserManagerCompat; import com.android.launcher3.config.FeatureFlags; import com.android.launcher3.icons.BitmapInfo; import com.android.launcher3.icons.LauncherIcons; @@ -64,7 +64,7 @@ public class LoaderCursor extends CursorWrapper { public final LongSparseArray allUsers = new LongSparseArray<>(); private final Context mContext; - private final UserManagerCompat mUserManager; + private final PackageManager mPM; private final IconCache mIconCache; private final InvariantDeviceProfile mIDP; @@ -100,7 +100,7 @@ public class LoaderCursor extends CursorWrapper { mContext = app.getContext(); mIconCache = app.getIconCache(); mIDP = app.getInvariantDeviceProfile(); - mUserManager = UserManagerCompat.getInstance(mContext); + mPM = mContext.getPackageManager(); // Init column indices iconIndex = getColumnIndexOrThrow(LauncherSettings.Favorites.ICON); @@ -228,7 +228,7 @@ public class LoaderCursor extends CursorWrapper { throw new InvalidParameterException("Invalid restoreType " + restoreFlag); } - info.contentDescription = mUserManager.getBadgedLabelForUser(info.title, info.user); + info.contentDescription = mPM.getUserBadgedLabel(info.title, info.user); info.itemType = itemType; info.status = restoreFlag; return info; @@ -284,7 +284,7 @@ public class LoaderCursor extends CursorWrapper { info.title = componentName.getClassName(); } - info.contentDescription = mUserManager.getBadgedLabelForUser(info.title, info.user); + info.contentDescription = mPM.getUserBadgedLabel(info.title, info.user); return info; } diff --git a/src/com/android/launcher3/model/LoaderTask.java b/src/com/android/launcher3/model/LoaderTask.java index 8b3e2c9a86..8551e6fbc0 100644 --- a/src/com/android/launcher3/model/LoaderTask.java +++ b/src/com/android/launcher3/model/LoaderTask.java @@ -20,8 +20,6 @@ import static com.android.launcher3.ItemInfoWithIcon.FLAG_DISABLED_LOCKED_USER; import static com.android.launcher3.ItemInfoWithIcon.FLAG_DISABLED_SAFEMODE; import static com.android.launcher3.ItemInfoWithIcon.FLAG_DISABLED_SUSPENDED; import static com.android.launcher3.folder.ClippedFolderIconLayoutRule.MAX_NUM_ITEMS_IN_PREVIEW; -import static com.android.launcher3.icons.CachingLogic.COMPONENT_WITH_LABEL; -import static com.android.launcher3.icons.CachingLogic.LAUNCHER_ACTIVITY_INFO; import static com.android.launcher3.model.LoaderResults.filterCurrentWorkspaceItems; import android.appwidget.AppWidgetProviderInfo; @@ -46,6 +44,7 @@ import com.android.launcher3.AllAppsList; import com.android.launcher3.AppInfo; import com.android.launcher3.FolderInfo; import com.android.launcher3.icons.ComponentWithLabel; +import com.android.launcher3.icons.ComponentWithLabel.ComponentCachingLogic; import com.android.launcher3.icons.IconCacheUpdateHandler; import com.android.launcher3.icons.IconCache; import com.android.launcher3.InstallShortcutReceiver; @@ -63,6 +62,7 @@ import com.android.launcher3.compat.UserManagerCompat; import com.android.launcher3.config.FeatureFlags; import com.android.launcher3.folder.Folder; import com.android.launcher3.folder.FolderIconPreviewVerifier; +import com.android.launcher3.icons.LauncherActivtiyCachingLogic; import com.android.launcher3.icons.LauncherIcons; import com.android.launcher3.logging.FileLog; import com.android.launcher3.provider.ImportDataTask; @@ -202,7 +202,8 @@ public class LoaderTask implements Runnable { TraceHelper.partitionSection(TAG, "step 2.3: Update icon cache"); IconCacheUpdateHandler updateHandler = mIconCache.getUpdateHandler(); setIgnorePackages(updateHandler); - updateHandler.updateIcons(allActivityList, LAUNCHER_ACTIVITY_INFO, + updateHandler.updateIcons(allActivityList, + new LauncherActivtiyCachingLogic(mApp.getIconCache()), mApp.getModel()::onPackageIconsUpdated); // Take a break @@ -233,7 +234,7 @@ public class LoaderTask implements Runnable { verifyNotStopped(); TraceHelper.partitionSection(TAG, "step 4.3: Update icon cache"); - updateHandler.updateIcons(allWidgetsList, COMPONENT_WITH_LABEL, + updateHandler.updateIcons(allWidgetsList, new ComponentCachingLogic(mApp.getContext()), mApp.getModel()::onWidgetLabelsUpdated); verifyNotStopped(); diff --git a/src/com/android/launcher3/settings/PreferenceHighlighter.java b/src/com/android/launcher3/settings/PreferenceHighlighter.java index 4ed4cf1133..8ba814686f 100644 --- a/src/com/android/launcher3/settings/PreferenceHighlighter.java +++ b/src/com/android/launcher3/settings/PreferenceHighlighter.java @@ -15,7 +15,7 @@ */ package com.android.launcher3.settings; -import static androidx.core.graphics.ColorUtils.setAlphaComponent; +import static com.android.launcher3.icons.GraphicsUtils.setColorAlphaBound; import android.animation.Animator; import android.animation.AnimatorListenerAdapter; @@ -57,7 +57,7 @@ public class PreferenceHighlighter extends ItemDecoration implements Runnable { private static final long HIGHLIGHT_DURATION = 15000L; private static final long HIGHLIGHT_FADE_OUT_DURATION = 500L; private static final long HIGHLIGHT_FADE_IN_DURATION = 200L; - private static final int END_COLOR = setAlphaComponent(Color.WHITE, 0); + private static final int END_COLOR = setColorAlphaBound(Color.WHITE, 0); private final Paint mPaint = new Paint(); private final RecyclerView mRv; @@ -91,7 +91,7 @@ public class PreferenceHighlighter extends ItemDecoration implements Runnable { if (!mHighLightStarted) { // Start highlight - int colorTo = setAlphaComponent(Themes.getColorAccent(mRv.getContext()), 66); + int colorTo = setColorAlphaBound(Themes.getColorAccent(mRv.getContext()), 66); ObjectAnimator anim = ObjectAnimator.ofArgb(this, HIGHLIGHT_COLOR, END_COLOR, colorTo); anim.setDuration(HIGHLIGHT_FADE_IN_DURATION); anim.setRepeatMode(ValueAnimator.REVERSE); diff --git a/src/com/android/launcher3/views/DoubleShadowBubbleTextView.java b/src/com/android/launcher3/views/DoubleShadowBubbleTextView.java index 64e166eeb8..323eecb91b 100644 --- a/src/com/android/launcher3/views/DoubleShadowBubbleTextView.java +++ b/src/com/android/launcher3/views/DoubleShadowBubbleTextView.java @@ -16,6 +16,8 @@ package com.android.launcher3.views; +import static com.android.launcher3.icons.GraphicsUtils.setColorAlphaBound; + import android.content.Context; import android.content.res.TypedArray; import android.graphics.Canvas; @@ -26,8 +28,6 @@ import android.widget.TextView; import com.android.launcher3.BubbleTextView; import com.android.launcher3.R; -import androidx.core.graphics.ColorUtils; - /** * Extension of {@link BubbleTextView} which draws two shadows on the text (ambient and key shadows} */ @@ -60,7 +60,7 @@ public class DoubleShadowBubbleTextView extends BubbleTextView { // We enhance the shadow by drawing the shadow twice getPaint().setShadowLayer(mShadowInfo.ambientShadowBlur, 0, 0, - ColorUtils.setAlphaComponent(mShadowInfo.ambientShadowColor, alpha)); + setColorAlphaBound(mShadowInfo.ambientShadowColor, alpha)); drawWithoutBadge(canvas); canvas.save(); @@ -69,7 +69,7 @@ public class DoubleShadowBubbleTextView extends BubbleTextView { getScrollY() + getHeight()); getPaint().setShadowLayer(mShadowInfo.keyShadowBlur, 0.0f, mShadowInfo.keyShadowOffset, - ColorUtils.setAlphaComponent(mShadowInfo.keyShadowColor, alpha)); + setColorAlphaBound(mShadowInfo.keyShadowColor, alpha)); drawWithoutBadge(canvas); canvas.restore(); @@ -107,11 +107,11 @@ public class DoubleShadowBubbleTextView extends BubbleTextView { return true; } else if (ambientShadowAlpha > 0) { textView.getPaint().setShadowLayer(ambientShadowBlur, 0, 0, - ColorUtils.setAlphaComponent(ambientShadowColor, textAlpha)); + setColorAlphaBound(ambientShadowColor, textAlpha)); return true; } else if (keyShadowAlpha > 0) { textView.getPaint().setShadowLayer(keyShadowBlur, 0.0f, keyShadowOffset, - ColorUtils.setAlphaComponent(keyShadowColor, textAlpha)); + setColorAlphaBound(keyShadowColor, textAlpha)); return true; } else { return false; diff --git a/src/com/android/launcher3/views/OptionsPopupView.java b/src/com/android/launcher3/views/OptionsPopupView.java index c540b59c1c..6ba2f4069c 100644 --- a/src/com/android/launcher3/views/OptionsPopupView.java +++ b/src/com/android/launcher3/views/OptionsPopupView.java @@ -34,6 +34,7 @@ import android.widget.Toast; import com.android.launcher3.Launcher; import com.android.launcher3.R; import com.android.launcher3.Utilities; +import com.android.launcher3.config.FeatureFlags; import com.android.launcher3.popup.ArrowPopup; import com.android.launcher3.shortcuts.DeepShortcutView; import com.android.launcher3.userevent.nano.LauncherLogProto.Action; @@ -151,8 +152,10 @@ public class OptionsPopupView extends ArrowPopup ArrayList options = new ArrayList<>(); options.add(new OptionItem(R.string.wallpaper_button_text, R.drawable.ic_wallpaper, ControlType.WALLPAPER_BUTTON, OptionsPopupView::startWallpaperPicker)); - options.add(new OptionItem(R.string.widget_button_text, R.drawable.ic_widget, - ControlType.WIDGETS_BUTTON, OptionsPopupView::onWidgetsClicked)); + if (!FeatureFlags.GO_DISABLE_WIDGETS) { + options.add(new OptionItem(R.string.widget_button_text, R.drawable.ic_widget, + ControlType.WIDGETS_BUTTON, OptionsPopupView::onWidgetsClicked)); + } options.add(new OptionItem(R.string.settings_button_text, R.drawable.ic_setting, ControlType.SETTINGS_BUTTON, OptionsPopupView::startSettings)); diff --git a/src/com/android/launcher3/views/ScrimView.java b/src/com/android/launcher3/views/ScrimView.java index 6fd84db26a..deb09654cf 100644 --- a/src/com/android/launcher3/views/ScrimView.java +++ b/src/com/android/launcher3/views/ScrimView.java @@ -22,9 +22,9 @@ import static com.android.launcher3.LauncherState.ALL_APPS; import static com.android.launcher3.LauncherState.NORMAL; import static com.android.launcher3.anim.Interpolators.ACCEL; import static com.android.launcher3.anim.Interpolators.DEACCEL; +import static com.android.launcher3.icons.GraphicsUtils.setColorAlphaBound; import static androidx.core.graphics.ColorUtils.compositeColors; -import static androidx.core.graphics.ColorUtils.setAlphaComponent; import android.animation.Animator; import android.animation.AnimatorListenerAdapter; @@ -182,7 +182,7 @@ public class ScrimView extends View implements Insettable, OnChangeListener, @Override public void onExtractedColorsChanged(WallpaperColorInfo wallpaperColorInfo) { mScrimColor = wallpaperColorInfo.getMainColor(); - mEndFlatColor = compositeColors(mEndScrim, setAlphaComponent( + mEndFlatColor = compositeColors(mEndScrim, setColorAlphaBound( mScrimColor, Math.round(mMaxScrimAlpha * 255))); mEndFlatColorAlpha = Color.alpha(mEndFlatColor); updateColors(); @@ -201,7 +201,7 @@ public class ScrimView extends View implements Insettable, OnChangeListener, public void reInitUi() { } protected void updateColors() { - mCurrentFlatColor = mProgress >= 1 ? 0 : setAlphaComponent( + mCurrentFlatColor = mProgress >= 1 ? 0 : setColorAlphaBound( mEndFlatColor, Math.round((1 - mProgress) * mEndFlatColorAlpha)); } diff --git a/src/com/android/launcher3/widget/BaseWidgetSheet.java b/src/com/android/launcher3/widget/BaseWidgetSheet.java index 48c18f8538..673b3cc14f 100644 --- a/src/com/android/launcher3/widget/BaseWidgetSheet.java +++ b/src/com/android/launcher3/widget/BaseWidgetSheet.java @@ -17,6 +17,7 @@ package com.android.launcher3.widget; import static android.view.ViewGroup.LayoutParams.MATCH_PARENT; +import static com.android.launcher3.icons.GraphicsUtils.setColorAlphaBound; import static com.android.launcher3.logging.LoggerUtils.newContainerTarget; import android.content.Context; @@ -42,8 +43,6 @@ import com.android.launcher3.util.Themes; import com.android.launcher3.views.AbstractSlideInView; import com.android.launcher3.views.BaseDragLayer; -import androidx.core.graphics.ColorUtils; - /** * Base class for various widgets popup */ @@ -162,11 +161,11 @@ abstract class BaseWidgetSheet extends AbstractSlideInView private static View createColorScrim(Context context) { View view = new View(context); - view.forceHasOverlappingRendering(false); + if (Utilities.ATLEAST_NOUGAT) view.forceHasOverlappingRendering(false); WallpaperColorInfo colors = WallpaperColorInfo.getInstance(context); int alpha = context.getResources().getInteger(R.integer.extracted_color_gradient_alpha); - view.setBackgroundColor(ColorUtils.setAlphaComponent(colors.getSecondaryColor(), alpha)); + view.setBackgroundColor(setColorAlphaBound(colors.getSecondaryColor(), alpha)); BaseDragLayer.LayoutParams lp = new BaseDragLayer.LayoutParams(MATCH_PARENT, MATCH_PARENT); lp.ignoreInsets = true; diff --git a/src_shortcuts_overrides/com/android/launcher3/model/LoaderResults.java b/src_shortcuts_overrides/com/android/launcher3/model/LoaderResults.java new file mode 100644 index 0000000000..9785887ac7 --- /dev/null +++ b/src_shortcuts_overrides/com/android/launcher3/model/LoaderResults.java @@ -0,0 +1,67 @@ +/* + * Copyright (C) 2017 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.android.launcher3.model; + +import com.android.launcher3.AllAppsList; +import com.android.launcher3.LauncherAppState; +import com.android.launcher3.LauncherModel.Callbacks; +import com.android.launcher3.util.ComponentKey; +import com.android.launcher3.widget.WidgetListRowEntry; + +import java.lang.ref.WeakReference; +import java.util.ArrayList; +import java.util.HashMap; + +/** + * Helper class to handle results of {@link com.android.launcher3.model.LoaderTask}. + */ +public class LoaderResults extends BaseLoaderResults { + + public LoaderResults(LauncherAppState app, BgDataModel dataModel, + AllAppsList allAppsList, int pageToBindFirst, WeakReference callbacks) { + super(app, dataModel, allAppsList, pageToBindFirst, callbacks); + } + + @Override + public void bindDeepShortcuts() { + final HashMap shortcutMapCopy; + synchronized (mBgDataModel) { + shortcutMapCopy = new HashMap<>(mBgDataModel.deepShortcutMap); + } + mUiExecutor.execute(() -> { + Callbacks callbacks = mCallbacks.get(); + if (callbacks != null) { + callbacks.bindDeepShortcutMap(shortcutMapCopy); + } + }); + } + + @Override + public void bindWidgets() { + final ArrayList widgets = + mBgDataModel.widgetsModel.getWidgetsList(mApp.getContext()); + Runnable r = new Runnable() { + public void run() { + Callbacks callbacks = mCallbacks.get(); + if (callbacks != null) { + callbacks.bindAllWidgets(widgets); + } + } + }; + mUiExecutor.execute(r); + } +} diff --git a/src/com/android/launcher3/model/WidgetsModel.java b/src_shortcuts_overrides/com/android/launcher3/model/WidgetsModel.java similarity index 100% rename from src/com/android/launcher3/model/WidgetsModel.java rename to src_shortcuts_overrides/com/android/launcher3/model/WidgetsModel.java diff --git a/tests/dummy_app/Android.mk b/tests/dummy_app/Android.mk new file mode 100644 index 0000000000..f4ab582ebf --- /dev/null +++ b/tests/dummy_app/Android.mk @@ -0,0 +1,18 @@ +LOCAL_PATH:= $(call my-dir) +include $(CLEAR_VARS) + +LOCAL_MODULE_TAGS := samples + +# Only compile source java files in this apk. +LOCAL_SRC_FILES := $(call all-java-files-under, src) + +LOCAL_PACKAGE_NAME := Aardwolf + +LOCAL_SDK_VERSION := current + +LOCAL_DEX_PREOPT := false + +include $(BUILD_PACKAGE) + +# Use the following include to make our test apk. +include $(call all-makefiles-under,$(LOCAL_PATH)) diff --git a/tests/dummy_app/AndroidManifest.xml b/tests/dummy_app/AndroidManifest.xml new file mode 100644 index 0000000000..0546015a52 --- /dev/null +++ b/tests/dummy_app/AndroidManifest.xml @@ -0,0 +1,36 @@ + + + + + + + + + + + + + + + diff --git a/tests/dummy_app/res/layout/empty_activity.xml b/tests/dummy_app/res/layout/empty_activity.xml new file mode 100644 index 0000000000..377c56bc36 --- /dev/null +++ b/tests/dummy_app/res/layout/empty_activity.xml @@ -0,0 +1,24 @@ + + + + + diff --git a/tests/dummy_app/res/mipmap-anydpi/ic_launcher1.xml b/tests/dummy_app/res/mipmap-anydpi/ic_launcher1.xml new file mode 100644 index 0000000000..37c8c7387a --- /dev/null +++ b/tests/dummy_app/res/mipmap-anydpi/ic_launcher1.xml @@ -0,0 +1,21 @@ + + + + + + + + diff --git a/tests/dummy_app/res/mipmap-anydpi/ic_launcher2.xml b/tests/dummy_app/res/mipmap-anydpi/ic_launcher2.xml new file mode 100644 index 0000000000..20b2986b6c --- /dev/null +++ b/tests/dummy_app/res/mipmap-anydpi/ic_launcher2.xml @@ -0,0 +1,19 @@ + + + + + + diff --git a/tests/dummy_app/res/mipmap-xxhdpi/ic_launcher1.png b/tests/dummy_app/res/mipmap-xxhdpi/ic_launcher1.png new file mode 100644 index 0000000000..73bc8e65b2 Binary files /dev/null and b/tests/dummy_app/res/mipmap-xxhdpi/ic_launcher1.png differ diff --git a/tests/dummy_app/res/mipmap-xxhdpi/ic_launcher2.png b/tests/dummy_app/res/mipmap-xxhdpi/ic_launcher2.png new file mode 100644 index 0000000000..cd40b63c20 Binary files /dev/null and b/tests/dummy_app/res/mipmap-xxhdpi/ic_launcher2.png differ diff --git a/tests/dummy_app/res/mipmap-xxhdpi/icon_back_1.png b/tests/dummy_app/res/mipmap-xxhdpi/icon_back_1.png new file mode 100644 index 0000000000..8debef3fc7 Binary files /dev/null and b/tests/dummy_app/res/mipmap-xxhdpi/icon_back_1.png differ diff --git a/tests/dummy_app/res/mipmap-xxhdpi/icon_fore_1.png b/tests/dummy_app/res/mipmap-xxhdpi/icon_fore_1.png new file mode 100644 index 0000000000..de4079bd28 Binary files /dev/null and b/tests/dummy_app/res/mipmap-xxhdpi/icon_fore_1.png differ diff --git a/tests/dummy_app/res/mipmap-xxxhdpi/ic_launcher1.png b/tests/dummy_app/res/mipmap-xxxhdpi/ic_launcher1.png new file mode 100644 index 0000000000..889a99cfb7 Binary files /dev/null and b/tests/dummy_app/res/mipmap-xxxhdpi/ic_launcher1.png differ diff --git a/tests/dummy_app/res/mipmap-xxxhdpi/ic_launcher2.png b/tests/dummy_app/res/mipmap-xxxhdpi/ic_launcher2.png new file mode 100644 index 0000000000..973bb794b2 Binary files /dev/null and b/tests/dummy_app/res/mipmap-xxxhdpi/ic_launcher2.png differ diff --git a/tests/dummy_app/res/mipmap-xxxhdpi/icon_back_1.png b/tests/dummy_app/res/mipmap-xxxhdpi/icon_back_1.png new file mode 100644 index 0000000000..70c0ebd783 Binary files /dev/null and b/tests/dummy_app/res/mipmap-xxxhdpi/icon_back_1.png differ diff --git a/tests/dummy_app/res/mipmap-xxxhdpi/icon_fore_1.png b/tests/dummy_app/res/mipmap-xxxhdpi/icon_fore_1.png new file mode 100644 index 0000000000..9d91632113 Binary files /dev/null and b/tests/dummy_app/res/mipmap-xxxhdpi/icon_fore_1.png differ diff --git a/tests/dummy_app/res/values/colors.xml b/tests/dummy_app/res/values/colors.xml new file mode 100644 index 0000000000..b5ce66e9fb --- /dev/null +++ b/tests/dummy_app/res/values/colors.xml @@ -0,0 +1,4 @@ + + + #455A64 + \ No newline at end of file diff --git a/tests/dummy_app/src/com/example/android/aardwolf/Activity1.java b/tests/dummy_app/src/com/example/android/aardwolf/Activity1.java new file mode 100644 index 0000000000..d4eab1545d --- /dev/null +++ b/tests/dummy_app/src/com/example/android/aardwolf/Activity1.java @@ -0,0 +1,31 @@ +/* + * Copyright (C) 2017 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.example.android.aardwolf; + +import android.app.Activity; +import android.os.Bundle; +import android.view.View; + +public class Activity1 extends Activity { + @Override + public void onCreate(Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + View view = getLayoutInflater().inflate(R.layout.empty_activity, null); + setContentView(view); + } +} + diff --git a/tests/res/raw/aardwolf_dummy_app.apk b/tests/res/raw/aardwolf_dummy_app.apk new file mode 100644 index 0000000000..39fb368ca9 Binary files /dev/null and b/tests/res/raw/aardwolf_dummy_app.apk differ diff --git a/tests/src/com/android/launcher3/ui/AbstractLauncherUiTest.java b/tests/src/com/android/launcher3/ui/AbstractLauncherUiTest.java index 532d3e8b00..bc5aaeeb75 100644 --- a/tests/src/com/android/launcher3/ui/AbstractLauncherUiTest.java +++ b/tests/src/com/android/launcher3/ui/AbstractLauncherUiTest.java @@ -296,11 +296,6 @@ public abstract class AbstractLauncherUiTest { Process.myUserHandle()).get(0); } - protected LauncherActivityInfo getChromeApp() { - return LauncherAppsCompat.getInstance(mTargetContext) - .getActivityList("com.android.chrome", Process.myUserHandle()).get(0); - } - /** * Broadcast receiver which blocks until the result is received. */ diff --git a/tests/src/com/android/launcher3/ui/AllAppsIconToHomeTest.java b/tests/src/com/android/launcher3/ui/AllAppsIconToHomeTest.java index 916007607f..9354862487 100644 --- a/tests/src/com/android/launcher3/ui/AllAppsIconToHomeTest.java +++ b/tests/src/com/android/launcher3/ui/AllAppsIconToHomeTest.java @@ -1,18 +1,10 @@ package com.android.launcher3.ui; -import static org.junit.Assert.assertTrue; - import android.content.pm.LauncherActivityInfo; + import androidx.test.filters.LargeTest; import androidx.test.runner.AndroidJUnit4; -import androidx.test.uiautomator.By; -import androidx.test.uiautomator.UiObject2; -import androidx.test.uiautomator.Until; -import com.android.launcher3.util.Condition; -import com.android.launcher3.util.Wait; - -import org.junit.Ignore; import org.junit.Test; import org.junit.runner.RunWith; @@ -24,37 +16,23 @@ import org.junit.runner.RunWith; public class AllAppsIconToHomeTest extends AbstractLauncherUiTest { @Test - @Ignore - public void testDragIcon_portrait() throws Throwable { - lockRotation(true); - performTest(); - } - - @Test - @Ignore - public void testDragIcon_landscape() throws Throwable { - lockRotation(false); - performTest(); - } - - private void performTest() throws Throwable { + @PortraitLandscape + public void testDragIcon() throws Throwable { LauncherActivityInfo settingsApp = getSettingsApp(); clearHomescreen(); mDevice.pressHome(); mDevice.waitForIdle(); - // Open all apps and wait for load complete. - final UiObject2 appsContainer = TestViewHelpers.openAllApps(); - Wait.atMost(null, Condition.minChildCount(appsContainer, 2), DEFAULT_UI_TIMEOUT); - - // Drag icon to homescreen. - UiObject2 icon = scrollAndFind(appsContainer, By.text(settingsApp.getLabel().toString())); - TestViewHelpers.dragToWorkspace(icon, true); - - // Verify that the icon works on homescreen. - mDevice.findObject(By.text(settingsApp.getLabel().toString())).click(); - assertTrue(mDevice.wait(Until.hasObject(By.pkg( - settingsApp.getComponentName().getPackageName()).depth(0)), DEFAULT_UI_TIMEOUT)); + final String appName = settingsApp.getLabel().toString(); + // 1. Open all apps and wait for load complete. + // 2. Drag icon to homescreen. + // 3. Verify that the icon works on homescreen. + mLauncher.getWorkspace(). + switchToAllApps(). + getAppIcon(appName). + dragToWorkspace(). + getWorkspaceAppIcon(appName). + launch(settingsApp.getComponentName().getPackageName()); } } diff --git a/tests/src/com/android/launcher3/ui/ShortcutsLaunchTest.java b/tests/src/com/android/launcher3/ui/ShortcutsLaunchTest.java index d7a7f6bbe7..1fea4d5c88 100644 --- a/tests/src/com/android/launcher3/ui/ShortcutsLaunchTest.java +++ b/tests/src/com/android/launcher3/ui/ShortcutsLaunchTest.java @@ -1,22 +1,18 @@ package com.android.launcher3.ui; -import static org.junit.Assert.assertNotNull; import static org.junit.Assert.assertTrue; import android.content.pm.LauncherActivityInfo; -import android.graphics.Point; + import androidx.test.filters.LargeTest; import androidx.test.runner.AndroidJUnit4; -import androidx.test.uiautomator.By; -import androidx.test.uiautomator.UiObject2; -import androidx.test.uiautomator.Until; -import android.view.MotionEvent; -import com.android.launcher3.R; -import com.android.launcher3.util.Condition; -import com.android.launcher3.util.Wait; +import com.android.launcher3.Launcher; +import com.android.launcher3.popup.ArrowPopup; +import com.android.launcher3.tapl.AppIconMenu; +import com.android.launcher3.tapl.AppIconMenuItem; +import com.android.launcher3.views.OptionsPopupView; -import org.junit.Ignore; import org.junit.Test; import org.junit.runner.RunWith; @@ -27,47 +23,30 @@ import org.junit.runner.RunWith; @RunWith(AndroidJUnit4.class) public class ShortcutsLaunchTest extends AbstractLauncherUiTest { - @Test - @Ignore - public void testAppLauncher_portrait() throws Exception { - lockRotation(true); - performTest(); + private boolean isOptionsPopupVisible(Launcher launcher) { + final ArrowPopup popup = OptionsPopupView.getOptionsPopup(launcher); + return popup != null && popup.isShown(); } @Test - @Ignore - public void testAppLauncher_landscape() throws Exception { - lockRotation(false); - performTest(); - } - - private void performTest() throws Exception { + @PortraitLandscape + public void testAppLauncher() throws Exception { mActivityMonitor.startLauncher(); - LauncherActivityInfo testApp = getSettingsApp(); + final LauncherActivityInfo testApp = getSettingsApp(); - // Open all apps and wait for load complete - final UiObject2 appsContainer = TestViewHelpers.openAllApps(); - Wait.atMost(null, Condition.minChildCount(appsContainer, 2), DEFAULT_UI_TIMEOUT); + final AppIconMenu menu = mLauncher. + pressHome(). + switchToAllApps(). + getAppIcon(testApp.getLabel().toString()). + openMenu(); - // Find settings app and verify shortcuts appear when long pressed - UiObject2 icon = scrollAndFind(appsContainer, By.text(testApp.getLabel().toString())); - // Press icon center until shortcuts appear - Point iconCenter = icon.getVisibleCenter(); - TestViewHelpers.sendPointer(MotionEvent.ACTION_DOWN, iconCenter); - UiObject2 deepShortcutsContainer = TestViewHelpers.findViewById( - R.id.deep_shortcuts_container); - assertNotNull(deepShortcutsContainer); - TestViewHelpers.sendPointer(MotionEvent.ACTION_UP, iconCenter); + executeOnLauncher( + launcher -> assertTrue("Launcher internal state didn't switch to Showing Menu", + isOptionsPopupVisible(launcher))); - // Verify that launching a shortcut opens a page with the same text - assertTrue(deepShortcutsContainer.getChildCount() > 0); + final AppIconMenuItem menuItem = menu.getMenuItem(1); + final String itemName = menuItem.getText(); - // Pick second children as it starts showing shortcuts. - UiObject2 shortcut = deepShortcutsContainer.getChildren().get(1) - .findObject(TestViewHelpers.getSelectorForId(R.id.bubble_text)); - shortcut.click(); - assertTrue(mDevice.wait(Until.hasObject(By.pkg( - testApp.getComponentName().getPackageName()) - .text(shortcut.getText())), DEFAULT_UI_TIMEOUT)); + menuItem.launch(testApp.getComponentName().getPackageName(), itemName); } } diff --git a/tests/src/com/android/launcher3/ui/ShortcutsToHomeTest.java b/tests/src/com/android/launcher3/ui/ShortcutsToHomeTest.java index 436c6991db..4c2c959b72 100644 --- a/tests/src/com/android/launcher3/ui/ShortcutsToHomeTest.java +++ b/tests/src/com/android/launcher3/ui/ShortcutsToHomeTest.java @@ -1,22 +1,12 @@ package com.android.launcher3.ui; -import static org.junit.Assert.assertNotNull; -import static org.junit.Assert.assertTrue; - import android.content.pm.LauncherActivityInfo; -import android.graphics.Point; + import androidx.test.filters.LargeTest; import androidx.test.runner.AndroidJUnit4; -import androidx.test.uiautomator.By; -import androidx.test.uiautomator.UiObject2; -import androidx.test.uiautomator.Until; -import android.view.MotionEvent; -import com.android.launcher3.R; -import com.android.launcher3.util.Condition; -import com.android.launcher3.util.Wait; +import com.android.launcher3.tapl.AppIconMenuItem; -import org.junit.Ignore; import org.junit.Test; import org.junit.runner.RunWith; @@ -28,51 +18,30 @@ import org.junit.runner.RunWith; public class ShortcutsToHomeTest extends AbstractLauncherUiTest { @Test - @Ignore - public void testDragIcon_portrait() throws Throwable { - lockRotation(true); - performTest(); - } - - @Test - @Ignore - public void testDragIcon_landscape() throws Throwable { - lockRotation(false); - performTest(); - } - - private void performTest() throws Throwable { + @PortraitLandscape + public void testDragIcon() throws Throwable { clearHomescreen(); mActivityMonitor.startLauncher(); - LauncherActivityInfo testApp = getSettingsApp(); + LauncherActivityInfo testApp = getSettingsApp(); - // Open all apps and wait for load complete. - final UiObject2 appsContainer = TestViewHelpers.openAllApps(); - Wait.atMost(null, Condition.minChildCount(appsContainer, 2), DEFAULT_UI_TIMEOUT); + // 1. Open all apps and wait for load complete. + // 2. Find the app and long press it to show shortcuts. + // 3. Press icon center until shortcuts appear + final AppIconMenuItem menuItem = mLauncher. + getWorkspace(). + switchToAllApps(). + getAppIcon(testApp.getLabel().toString()). + openMenu(). + getMenuItem(0); + final String shortcutName = menuItem.getText(); - // Find the app and long press it to show shortcuts. - UiObject2 icon = scrollAndFind(appsContainer, By.text(testApp.getLabel().toString())); - // Press icon center until shortcuts appear - Point iconCenter = icon.getVisibleCenter(); - TestViewHelpers.sendPointer(MotionEvent.ACTION_DOWN, iconCenter); - UiObject2 deepShortcutsContainer = TestViewHelpers.findViewById( - R.id.deep_shortcuts_container); - assertNotNull(deepShortcutsContainer); - TestViewHelpers.sendPointer(MotionEvent.ACTION_UP, iconCenter); - - // Drag the first shortcut to the home screen. - assertTrue(deepShortcutsContainer.getChildCount() > 0); - UiObject2 shortcut = deepShortcutsContainer.getChildren().get(1) - .findObject(TestViewHelpers.getSelectorForId(R.id.bubble_text)); - String shortcutName = shortcut.getText(); - TestViewHelpers.dragToWorkspace(shortcut, false); - - // Verify that the shortcut works on home screen - // (the app opens and has the same text as the shortcut). - mDevice.findObject(By.text(shortcutName)).click(); - assertTrue(mDevice.wait(Until.hasObject(By.pkg( - testApp.getComponentName().getPackageName()) - .text(shortcutName)), DEFAULT_UI_TIMEOUT)); + // 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(testApp.getComponentName().getPackageName(), shortcutName); } } diff --git a/tests/src/com/android/launcher3/util/IntSetTest.java b/tests/src/com/android/launcher3/util/IntSetTest.java deleted file mode 100644 index 934b749f5e..0000000000 --- a/tests/src/com/android/launcher3/util/IntSetTest.java +++ /dev/null @@ -1,58 +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.util; - -import org.junit.Test; -import org.junit.runner.RunWith; - -import androidx.test.filters.SmallTest; -import androidx.test.runner.AndroidJUnit4; - -import static org.junit.Assert.assertEquals; -import static org.junit.Assert.assertFalse; -import static org.junit.Assert.assertTrue; - -/** - * Unit tests for {@link IntSet} - */ -@SmallTest -@RunWith(AndroidJUnit4.class) -public class IntSetTest { - - @Test - public void testDuplicateEntries() { - IntSet set = new IntSet(); - - set.add(2); - assertEquals(1, set.size()); - - set.add(2); - assertEquals(1, set.size()); - assertTrue(set.contains(2)); - assertFalse(set.contains(1)); - - set.add(1); - assertEquals(2, set.size()); - assertTrue(set.contains(2)); - assertTrue(set.contains(1)); - - - set.add(10); - assertEquals(3, set.size()); - - assertEquals("1, 2, 10", set.mArray.toConcatString()); - } -} diff --git a/tests/src/com/android/launcher3/util/TestUtil.java b/tests/src/com/android/launcher3/util/TestUtil.java new file mode 100644 index 0000000000..1338dcb108 --- /dev/null +++ b/tests/src/com/android/launcher3/util/TestUtil.java @@ -0,0 +1,51 @@ +/* + * 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.util; + +import static androidx.test.InstrumentationRegistry.getContext; +import static androidx.test.InstrumentationRegistry.getInstrumentation; + +import android.content.res.Resources; + +import androidx.test.uiautomator.UiDevice; + +import java.io.FileOutputStream; +import java.io.IOException; +import java.io.InputStream; + +public class TestUtil { + public static void installDummyApp() throws IOException { + // Copy apk from resources to a local file and install from there. + final Resources resources = getContext().getResources(); + final InputStream in = resources.openRawResource( + resources.getIdentifier("aardwolf_dummy_app", + "raw", getContext().getPackageName())); + final String apkFilename = getInstrumentation().getTargetContext(). + getFilesDir().getPath() + "/dummy_app.apk"; + + final FileOutputStream out = new FileOutputStream(apkFilename); + byte[] buff = new byte[1024]; + int read; + + while ((read = in.read(buff)) > 0) { + out.write(buff, 0, read); + } + in.close(); + out.close(); + + UiDevice.getInstance(getInstrumentation()).executeShellCommand("pm install " + apkFilename); + } +} diff --git a/tests/tapl/com/android/launcher3/tapl/AppIcon.java b/tests/tapl/com/android/launcher3/tapl/AppIcon.java index b7ae9f1497..efefc0dca2 100644 --- a/tests/tapl/com/android/launcher3/tapl/AppIcon.java +++ b/tests/tapl/com/android/launcher3/tapl/AppIcon.java @@ -16,23 +16,19 @@ package com.android.launcher3.tapl; +import android.graphics.Point; import android.widget.TextView; import androidx.test.uiautomator.By; import androidx.test.uiautomator.BySelector; import androidx.test.uiautomator.UiObject2; -import androidx.test.uiautomator.Until; /** * App icon, whether in all apps or in workspace/ */ -public final class AppIcon { - private final LauncherInstrumentation mLauncher; - private final UiObject2 mIcon; - +public final class AppIcon extends Launchable { AppIcon(LauncherInstrumentation launcher, UiObject2 icon) { - mLauncher = launcher; - mIcon = icon; + super(launcher, icon); } static BySelector getAppIconSelector(String appName) { @@ -40,20 +36,13 @@ public final class AppIcon { } /** - * Clicks the icon to launch its app. + * Long-clicks the icon to open its menu. */ - public Background launch(String packageName) { - LauncherInstrumentation.log("AppIcon.launch before click " + mIcon.getVisibleCenter()); - LauncherInstrumentation.assertTrue( - "Launching an app didn't open a new window: " + mIcon.getText(), - mIcon.clickAndWait(Until.newWindow(), LauncherInstrumentation.WAIT_TIME_MS)); - LauncherInstrumentation.assertTrue( - "App didn't start: " + packageName, mLauncher.getDevice().wait(Until.hasObject( - By.pkg(packageName).depth(0)), LauncherInstrumentation.WAIT_TIME_MS)); - return new Background(mLauncher); - } - - UiObject2 getIcon() { - return mIcon; + public AppIconMenu openMenu() { + final Point iconCenter = mObject.getVisibleCenter(); + mLauncher.longTap(iconCenter.x, iconCenter.y); + final UiObject2 deepShortcutsContainer = mLauncher.waitForLauncherObject( + "deep_shortcuts_container"); + return new AppIconMenu(mLauncher, deepShortcutsContainer); } } diff --git a/tests/tapl/com/android/launcher3/tapl/AppIconMenu.java b/tests/tapl/com/android/launcher3/tapl/AppIconMenu.java new file mode 100644 index 0000000000..2a03f9a089 --- /dev/null +++ b/tests/tapl/com/android/launcher3/tapl/AppIconMenu.java @@ -0,0 +1,46 @@ +/* + * 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.tapl; + +import static org.junit.Assert.assertTrue; + +import androidx.test.uiautomator.UiObject2; + +/** + * Context menu of an app icon. + */ +public class AppIconMenu { + private final LauncherInstrumentation mLauncher; + private final UiObject2 mDeepShortcutsContainer; + + AppIconMenu(LauncherInstrumentation launcher, + UiObject2 deepShortcutsContainer) { + mLauncher = launcher; + mDeepShortcutsContainer = deepShortcutsContainer; + } + + /** + * Returns a menu item with a given number. Fails if it doesn't exist. + */ + public AppIconMenuItem getMenuItem(int itemNumber) { + assertTrue(mDeepShortcutsContainer.getChildCount() > itemNumber); + + final UiObject2 shortcut = mLauncher.waitForObjectInContainer( + mDeepShortcutsContainer.getChildren().get(itemNumber), "bubble_text"); + return new AppIconMenuItem(mLauncher, shortcut); + } +} diff --git a/tests/tapl/com/android/launcher3/tapl/AppIconMenuItem.java b/tests/tapl/com/android/launcher3/tapl/AppIconMenuItem.java new file mode 100644 index 0000000000..c39f8d1675 --- /dev/null +++ b/tests/tapl/com/android/launcher3/tapl/AppIconMenuItem.java @@ -0,0 +1,35 @@ +/* + * 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.tapl; + +import androidx.test.uiautomator.UiObject2; + +/** + * Menu item in an app icon menu. + */ +public class AppIconMenuItem extends Launchable { + AppIconMenuItem(LauncherInstrumentation launcher, UiObject2 shortcut) { + super(launcher, shortcut); + } + + /** + * Returns the visible text of the menu item. + */ + public String getText() { + return mObject.getText(); + } +} diff --git a/tests/tapl/com/android/launcher3/tapl/Launchable.java b/tests/tapl/com/android/launcher3/tapl/Launchable.java new file mode 100644 index 0000000000..7e2c9660d5 --- /dev/null +++ b/tests/tapl/com/android/launcher3/tapl/Launchable.java @@ -0,0 +1,81 @@ +/* + * 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.tapl; + +import android.graphics.Point; + +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; + +/** + * Ancestor for AppIcon and AppMenuItem. + */ +class Launchable { + private static final int DRAG_SPEED = 500; + protected final LauncherInstrumentation mLauncher; + + protected final UiObject2 mObject; + + Launchable(LauncherInstrumentation launcher, UiObject2 object) { + mObject = object; + mLauncher = launcher; + } + + UiObject2 getObject() { + return mObject; + } + + /** + * Clicks the object to launch its app. + */ + public Background launch(String expectedPackageName) { + return launch(expectedPackageName, By.pkg(expectedPackageName).depth(0)); + } + + /** + * Clicks the object to launch its app. + */ + public Background launch(String expectedPackageName, String expectedAppText) { + return launch(expectedPackageName, By.pkg(expectedPackageName).text(expectedAppText)); + } + + private Background launch(String errorMessage, BySelector selector) { + LauncherInstrumentation.log("Launchable.launch before click " + + mObject.getVisibleCenter()); + LauncherInstrumentation.assertTrue( + "Launching an app didn't open a new window: " + mObject.getText(), + mObject.clickAndWait(Until.newWindow(), LauncherInstrumentation.WAIT_TIME_MS)); + LauncherInstrumentation.assertTrue( + "App didn't start: " + errorMessage, + mLauncher.getDevice().wait(Until.hasObject(selector), + LauncherInstrumentation.WAIT_TIME_MS)); + return new Background(mLauncher); + } + + /** + * Drags an object to the center of homescreen. + */ + public Workspace dragToWorkspace() { + final UiDevice device = mLauncher.getDevice(); + mObject.drag(new Point( + device.getDisplayWidth() / 2, device.getDisplayHeight() / 2), DRAG_SPEED); + return new Workspace(mLauncher); + } +} diff --git a/tests/tapl/com/android/launcher3/tapl/LauncherInstrumentation.java b/tests/tapl/com/android/launcher3/tapl/LauncherInstrumentation.java index 31abc53c91..67106f7eac 100644 --- a/tests/tapl/com/android/launcher3/tapl/LauncherInstrumentation.java +++ b/tests/tapl/com/android/launcher3/tapl/LauncherInstrumentation.java @@ -28,6 +28,13 @@ import android.util.Log; import android.view.Surface; import android.view.accessibility.AccessibilityEvent; +import androidx.annotation.NonNull; +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.TestProtocol; import com.android.quickstep.SwipeUpSetting; @@ -36,13 +43,6 @@ import org.junit.Assert; import java.lang.ref.WeakReference; import java.util.concurrent.TimeoutException; -import androidx.annotation.NonNull; -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; - /** * The main tapl object. The only object that can be explicitly constructed by the using code. It * produces all other objects. @@ -394,6 +394,11 @@ public final class LauncherInstrumentation { return mDevice; } + void longTap(int x, int y) { + mDevice.drag(x, y, x, y, 0); + } + + void swipe(int startX, int startY, int endX, int endY) { executeAndWaitForEvent( () -> mDevice.swipe(startX, startY, endX, endY, 60), diff --git a/tests/tapl/com/android/launcher3/tapl/Workspace.java b/tests/tapl/com/android/launcher3/tapl/Workspace.java index 493f26ae9c..c63822e2ea 100644 --- a/tests/tapl/com/android/launcher3/tapl/Workspace.java +++ b/tests/tapl/com/android/launcher3/tapl/Workspace.java @@ -19,12 +19,12 @@ package com.android.launcher3.tapl; import static junit.framework.TestCase.assertTrue; import android.graphics.Point; -import androidx.test.uiautomator.Direction; -import androidx.test.uiautomator.UiObject2; import android.view.KeyEvent; import androidx.annotation.NonNull; import androidx.annotation.Nullable; +import androidx.test.uiautomator.Direction; +import androidx.test.uiautomator.UiObject2; /** * Operations on the workspace screen. @@ -85,6 +85,21 @@ public final class Workspace extends Home { return icon != null ? new AppIcon(mLauncher, icon) : null; } + + /** + * Returns an icon for the app; fails if the icon doesn't exist. + * + * @param appName name of the app + * @return app icon. + */ + @NonNull + public AppIcon getWorkspaceAppIcon(String appName) { + return new AppIcon(mLauncher, + mLauncher.getObjectInContainer( + verifyActiveContainer(), + AppIcon.getAppIconSelector(appName))); + } + /** * Ensures that workspace is scrollable. If it's not, drags an icon icons from hotseat to the * second screen. @@ -111,7 +126,7 @@ public final class Workspace extends Home { private void dragIconToNextScreen(AppIcon app, UiObject2 workspace) { final Point dest = new Point( mLauncher.getDevice().getDisplayWidth(), workspace.getVisibleBounds().centerY()); - app.getIcon().drag(dest, ICON_DRAG_SPEED); + app.getObject().drag(dest, ICON_DRAG_SPEED); verifyActiveContainer(); }