Merge "Update adjacent page hints" into ub-now-porkchop
diff --git a/res/layout/apps_customize_application.xml b/res/layout/apps_customize_application.xml
index 17f4a8e..c56cdf3 100644
--- a/res/layout/apps_customize_application.xml
+++ b/res/layout/apps_customize_application.xml
@@ -14,10 +14,8 @@
limitations under the License.
-->
-<com.android.launcher3.PagedViewIcon
+<com.android.launcher3.BubbleTextView
xmlns:android="http://schemas.android.com/apk/res/android"
- xmlns:launcher="http://schemas.android.com/apk/res-auto/com.android.launcher3"
-
style="@style/WorkspaceIcon.AppsCustomize"
android:id="@+id/application_icon"
android:focusable="true" />
diff --git a/res/values-af/strings.xml b/res/values-af/strings.xml
index bb933f7..5f10b21 100644
--- a/res/values-af/strings.xml
+++ b/res/values-af/strings.xml
@@ -77,6 +77,8 @@
<string name="permlab_write_settings" msgid="3574213698004620587">"skryf Tuis-instellings en -kortpaaie"</string>
<string name="permdesc_write_settings" msgid="5440712911516509985">"Laat die program toe om die instellings en kortpaaie in Tuis te verander."</string>
<string name="gadget_error_text" msgid="6081085226050792095">"Kon nie legstuk laai nie"</string>
+ <!-- no translation found for gadget_setup_text (8274003207686040488) -->
+ <skip />
<string name="uninstall_system_app_text" msgid="4172046090762920660">"Dit is \'n stelselprogram en kan nie gedeïnstalleer word nie."</string>
<string name="dream_name" msgid="1530253749244328964">"Vuurpyllanseerder"</string>
<string name="folder_hint_text" msgid="6617836969016293992">"Naamlose vouer"</string>
diff --git a/res/values-am/strings.xml b/res/values-am/strings.xml
index 51d5c70..9d0b185 100644
--- a/res/values-am/strings.xml
+++ b/res/values-am/strings.xml
@@ -77,6 +77,8 @@
<string name="permlab_write_settings" msgid="3574213698004620587">"የመነሻ ቅንብሮችን እና አቋራጮችን ይጽፋል"</string>
<string name="permdesc_write_settings" msgid="5440712911516509985">"መተግብሪያው ቅንብሮችን እና አቋራጮችን በመነሻ ውስጥ እንዲቀይራቸው ያስችለዋል።"</string>
<string name="gadget_error_text" msgid="6081085226050792095">"ፍርግም የመጫን ችግር"</string>
+ <!-- no translation found for gadget_setup_text (8274003207686040488) -->
+ <skip />
<string name="uninstall_system_app_text" msgid="4172046090762920660">"ይህ የስርዓት መተግበሪያ ነው እና ማራገፍ አይቻልም።"</string>
<string name="dream_name" msgid="1530253749244328964">"የሮኬት ማስጀመሪያ"</string>
<string name="folder_hint_text" msgid="6617836969016293992">"ስም-አልባ አቃፊ"</string>
diff --git a/res/values-ar/strings.xml b/res/values-ar/strings.xml
index cb62184..b0d6589 100644
--- a/res/values-ar/strings.xml
+++ b/res/values-ar/strings.xml
@@ -77,6 +77,8 @@
<string name="permlab_write_settings" msgid="3574213698004620587">"كتابة إعدادات واختصارات الشاشة الرئيسية"</string>
<string name="permdesc_write_settings" msgid="5440712911516509985">"للسماح للتطبيق بتغيير الإعدادات والاختصارات في الشاشة الرئيسية."</string>
<string name="gadget_error_text" msgid="6081085226050792095">"حدثت مشكلة أثناء تحميل الأداة"</string>
+ <!-- no translation found for gadget_setup_text (8274003207686040488) -->
+ <skip />
<string name="uninstall_system_app_text" msgid="4172046090762920660">"هذا تطبيق نظام وتتعذر إزالته."</string>
<string name="dream_name" msgid="1530253749244328964">"قاذفة صواريخ"</string>
<string name="folder_hint_text" msgid="6617836969016293992">"مجلد بدون اسم"</string>
diff --git a/res/values-bg/strings.xml b/res/values-bg/strings.xml
index 5f93a9a..0b59e1a 100644
--- a/res/values-bg/strings.xml
+++ b/res/values-bg/strings.xml
@@ -77,6 +77,8 @@
<string name="permlab_write_settings" msgid="3574213698004620587">"запис на настройките и преките пътища в Начало"</string>
<string name="permdesc_write_settings" msgid="5440712911516509985">"Разрешава на приложението да променя настройките и преките пътища в Начало."</string>
<string name="gadget_error_text" msgid="6081085226050792095">"Проблем при зареждане на приспособлението"</string>
+ <!-- no translation found for gadget_setup_text (8274003207686040488) -->
+ <skip />
<string name="uninstall_system_app_text" msgid="4172046090762920660">"Това е системно приложение и не може да се деинсталира."</string>
<string name="dream_name" msgid="1530253749244328964">"Ракетна площадка"</string>
<string name="folder_hint_text" msgid="6617836969016293992">"Папка без име"</string>
diff --git a/res/values-ca/strings.xml b/res/values-ca/strings.xml
index 7fc9051..82db602 100644
--- a/res/values-ca/strings.xml
+++ b/res/values-ca/strings.xml
@@ -77,6 +77,8 @@
<string name="permlab_write_settings" msgid="3574213698004620587">"escriu la configuració i les dreceres de la pantalla d\'inici"</string>
<string name="permdesc_write_settings" msgid="5440712911516509985">"Permet que l\'aplicació canviï la configuració i les dreceres de la pantalla d\'inici."</string>
<string name="gadget_error_text" msgid="6081085226050792095">"S\'ha produït un problema en carregar el widget"</string>
+ <!-- no translation found for gadget_setup_text (8274003207686040488) -->
+ <skip />
<string name="uninstall_system_app_text" msgid="4172046090762920660">"Aquesta aplicació és una aplicació del sistema i no es pot desinstal·lar."</string>
<string name="dream_name" msgid="1530253749244328964">"Rocket Launcher"</string>
<string name="folder_hint_text" msgid="6617836969016293992">"Carpeta sense nom"</string>
diff --git a/res/values-cs/strings.xml b/res/values-cs/strings.xml
index e90afb0..0d2a607 100644
--- a/res/values-cs/strings.xml
+++ b/res/values-cs/strings.xml
@@ -77,6 +77,8 @@
<string name="permlab_write_settings" msgid="3574213698004620587">"zápis nastavení a odkazů plochy"</string>
<string name="permdesc_write_settings" msgid="5440712911516509985">"Umožňuje aplikaci změnit nastavení a odkazy na ploše."</string>
<string name="gadget_error_text" msgid="6081085226050792095">"Problém s načtením widgetu"</string>
+ <!-- no translation found for gadget_setup_text (8274003207686040488) -->
+ <skip />
<string name="uninstall_system_app_text" msgid="4172046090762920660">"Toto je systémová aplikace a nelze ji odinstalovat."</string>
<string name="dream_name" msgid="1530253749244328964">"Rocket Launcher"</string>
<string name="folder_hint_text" msgid="6617836969016293992">"Složka bez názvu"</string>
diff --git a/res/values-da/strings.xml b/res/values-da/strings.xml
index 60ea2c6..1a71c17 100644
--- a/res/values-da/strings.xml
+++ b/res/values-da/strings.xml
@@ -77,6 +77,8 @@
<string name="permlab_write_settings" msgid="3574213698004620587">"skrive indstillinger og genveje for startskærmen"</string>
<string name="permdesc_write_settings" msgid="5440712911516509985">"Tillader, at appen ændrer indstillingerne og genvejene på startskærmen."</string>
<string name="gadget_error_text" msgid="6081085226050792095">"Der er problemer med indlæsning af widgetten"</string>
+ <!-- no translation found for gadget_setup_text (8274003207686040488) -->
+ <skip />
<string name="uninstall_system_app_text" msgid="4172046090762920660">"Dette er en systemapp, som ikke kan afinstalleres."</string>
<string name="dream_name" msgid="1530253749244328964">"Rocket Launcher"</string>
<string name="folder_hint_text" msgid="6617836969016293992">"Unavngiven mappe"</string>
diff --git a/res/values-de/strings.xml b/res/values-de/strings.xml
index 1e225eb..f04fb16 100644
--- a/res/values-de/strings.xml
+++ b/res/values-de/strings.xml
@@ -77,6 +77,8 @@
<string name="permlab_write_settings" msgid="3574213698004620587">"Einstellungen und Verknüpfungen für den Startbildschirm schreiben"</string>
<string name="permdesc_write_settings" msgid="5440712911516509985">"Ermöglicht der App, die Einstellungen und Verknüpfungen auf dem Startbildschirm zu ändern"</string>
<string name="gadget_error_text" msgid="6081085226050792095">"Problem beim Laden des Widgets"</string>
+ <!-- no translation found for gadget_setup_text (8274003207686040488) -->
+ <skip />
<string name="uninstall_system_app_text" msgid="4172046090762920660">"Dies ist eine Systemanwendung, die nicht deinstalliert werden kann."</string>
<string name="dream_name" msgid="1530253749244328964">"Rocket Launcher"</string>
<string name="folder_hint_text" msgid="6617836969016293992">"Unbenannter Ordner"</string>
diff --git a/res/values-el/strings.xml b/res/values-el/strings.xml
index ccc5a29..2ee3c21 100644
--- a/res/values-el/strings.xml
+++ b/res/values-el/strings.xml
@@ -77,6 +77,7 @@
<string name="permlab_write_settings" msgid="3574213698004620587">"εγγραφή ρυθμίσεων και συντομεύσεων αρχικής οθόνης"</string>
<string name="permdesc_write_settings" msgid="5440712911516509985">"Επιτρέπει στην εφαρμογή την αλλαγή των ρυθμίσεων και των συντομεύσεων στην Αρχική οθόνη."</string>
<string name="gadget_error_text" msgid="6081085226050792095">"Παρουσιάστηκε πρόβλημα στη φόρτωση του γραφικού στοιχείου"</string>
+ <string name="gadget_setup_text" msgid="8274003207686040488">"Ρύθμιση"</string>
<string name="uninstall_system_app_text" msgid="4172046090762920660">"Αυτή είναι μια εφαρμογή συστήματος και δεν είναι δυνατή η κατάργηση της εγκατάστασής της."</string>
<string name="dream_name" msgid="1530253749244328964">"Rocket Launcher"</string>
<string name="folder_hint_text" msgid="6617836969016293992">"Φάκελος χωρίς όνομα"</string>
diff --git a/res/values-en-rGB/strings.xml b/res/values-en-rGB/strings.xml
index 7be42db..d127c27 100644
--- a/res/values-en-rGB/strings.xml
+++ b/res/values-en-rGB/strings.xml
@@ -77,6 +77,8 @@
<string name="permlab_write_settings" msgid="3574213698004620587">"write Home settings and shortcuts"</string>
<string name="permdesc_write_settings" msgid="5440712911516509985">"Allows the app to change the settings and shortcuts in Home."</string>
<string name="gadget_error_text" msgid="6081085226050792095">"Problem loading widget"</string>
+ <!-- no translation found for gadget_setup_text (8274003207686040488) -->
+ <skip />
<string name="uninstall_system_app_text" msgid="4172046090762920660">"This is a system app and can\'t be uninstalled."</string>
<string name="dream_name" msgid="1530253749244328964">"Rocket Launcher"</string>
<string name="folder_hint_text" msgid="6617836969016293992">"Unnamed Folder"</string>
diff --git a/res/values-en-rIN/strings.xml b/res/values-en-rIN/strings.xml
index 7be42db..d127c27 100644
--- a/res/values-en-rIN/strings.xml
+++ b/res/values-en-rIN/strings.xml
@@ -77,6 +77,8 @@
<string name="permlab_write_settings" msgid="3574213698004620587">"write Home settings and shortcuts"</string>
<string name="permdesc_write_settings" msgid="5440712911516509985">"Allows the app to change the settings and shortcuts in Home."</string>
<string name="gadget_error_text" msgid="6081085226050792095">"Problem loading widget"</string>
+ <!-- no translation found for gadget_setup_text (8274003207686040488) -->
+ <skip />
<string name="uninstall_system_app_text" msgid="4172046090762920660">"This is a system app and can\'t be uninstalled."</string>
<string name="dream_name" msgid="1530253749244328964">"Rocket Launcher"</string>
<string name="folder_hint_text" msgid="6617836969016293992">"Unnamed Folder"</string>
diff --git a/res/values-es-rUS/strings.xml b/res/values-es-rUS/strings.xml
index 304f027..1d38832 100644
--- a/res/values-es-rUS/strings.xml
+++ b/res/values-es-rUS/strings.xml
@@ -77,6 +77,8 @@
<string name="permlab_write_settings" msgid="3574213698004620587">"escribir configuración y accesos directos de la pantalla principal"</string>
<string name="permdesc_write_settings" msgid="5440712911516509985">"Permite que la aplicación cambie la configuración y los accesos directos de la pantalla principal."</string>
<string name="gadget_error_text" msgid="6081085226050792095">"Problema al cargar el widget"</string>
+ <!-- no translation found for gadget_setup_text (8274003207686040488) -->
+ <skip />
<string name="uninstall_system_app_text" msgid="4172046090762920660">"Esta es una aplicación del sistema y no se puede desinstalar."</string>
<string name="dream_name" msgid="1530253749244328964">"Lanzacohetes"</string>
<string name="folder_hint_text" msgid="6617836969016293992">"Carpeta sin nombre"</string>
diff --git a/res/values-es/strings.xml b/res/values-es/strings.xml
index dbb3c43..87982de 100644
--- a/res/values-es/strings.xml
+++ b/res/values-es/strings.xml
@@ -77,6 +77,8 @@
<string name="permlab_write_settings" msgid="3574213698004620587">"escribir información de accesos directos y de ajustes de la pantalla de inicio"</string>
<string name="permdesc_write_settings" msgid="5440712911516509985">"Permite que las aplicaciones cambien los ajustes y los accesos directos de la pantalla de inicio."</string>
<string name="gadget_error_text" msgid="6081085226050792095">"Problema al cargar el widget"</string>
+ <!-- no translation found for gadget_setup_text (8274003207686040488) -->
+ <skip />
<string name="uninstall_system_app_text" msgid="4172046090762920660">"Esta aplicación es del sistema y no se puede desinstalar."</string>
<string name="dream_name" msgid="1530253749244328964">"Rocket Launcher"</string>
<string name="folder_hint_text" msgid="6617836969016293992">"Carpeta sin nombre"</string>
diff --git a/res/values-et-rEE/strings.xml b/res/values-et-rEE/strings.xml
index 05f38b0..b33987e 100644
--- a/res/values-et-rEE/strings.xml
+++ b/res/values-et-rEE/strings.xml
@@ -77,6 +77,8 @@
<string name="permlab_write_settings" msgid="3574213698004620587">"kirjuta avaekraani seaded ja otseteed"</string>
<string name="permdesc_write_settings" msgid="5440712911516509985">"Võimaldab rakendusel muuta avaekraanil seadeid ja otseteid."</string>
<string name="gadget_error_text" msgid="6081085226050792095">"Probleem vidina laadimisel"</string>
+ <!-- no translation found for gadget_setup_text (8274003207686040488) -->
+ <skip />
<string name="uninstall_system_app_text" msgid="4172046090762920660">"See on süsteemirakendus ja seda ei saa desinstallida."</string>
<string name="dream_name" msgid="1530253749244328964">"Rocket Launcher"</string>
<string name="folder_hint_text" msgid="6617836969016293992">"Nimetu kaust"</string>
diff --git a/res/values-fa/strings.xml b/res/values-fa/strings.xml
index 3a63ad9..f67facc 100644
--- a/res/values-fa/strings.xml
+++ b/res/values-fa/strings.xml
@@ -77,6 +77,8 @@
<string name="permlab_write_settings" msgid="3574213698004620587">"نوشتن تنظیمات و میانبرهای صفحه اصلی"</string>
<string name="permdesc_write_settings" msgid="5440712911516509985">"به برنامه اجازه میدهد تنظیمات و میانبرها را در صفحه اصلی تغییر دهد."</string>
<string name="gadget_error_text" msgid="6081085226050792095">"مشکل در بارگیری ابزارک"</string>
+ <!-- no translation found for gadget_setup_text (8274003207686040488) -->
+ <skip />
<string name="uninstall_system_app_text" msgid="4172046090762920660">"این برنامه سیستمی است و حذف نصب نمیشود."</string>
<string name="dream_name" msgid="1530253749244328964">"Rocket Launcher"</string>
<string name="folder_hint_text" msgid="6617836969016293992">"پوشه بینام"</string>
diff --git a/res/values-fi/strings.xml b/res/values-fi/strings.xml
index 4c09e34..70c5176 100644
--- a/res/values-fi/strings.xml
+++ b/res/values-fi/strings.xml
@@ -77,6 +77,8 @@
<string name="permlab_write_settings" msgid="3574213698004620587">"kirjoita aloitusruudun asetuksia ja pikakuvakkeita"</string>
<string name="permdesc_write_settings" msgid="5440712911516509985">"Antaa sovelluksen muuttaa aloitusruudun asetuksia ja pikakuvakkeita."</string>
<string name="gadget_error_text" msgid="6081085226050792095">"Ongelma ladattaessa widgetiä"</string>
+ <!-- no translation found for gadget_setup_text (8274003207686040488) -->
+ <skip />
<string name="uninstall_system_app_text" msgid="4172046090762920660">"Tämä on järjestelmäsovellus, eikä sitä voi poistaa."</string>
<string name="dream_name" msgid="1530253749244328964">"Sinko"</string>
<string name="folder_hint_text" msgid="6617836969016293992">"Nimetön kansio"</string>
diff --git a/res/values-fr-rCA/strings.xml b/res/values-fr-rCA/strings.xml
index 8674cd3..5e2bed9 100644
--- a/res/values-fr-rCA/strings.xml
+++ b/res/values-fr-rCA/strings.xml
@@ -77,6 +77,8 @@
<string name="permlab_write_settings" msgid="3574213698004620587">"enregistrer les paramètres de la page d\'accueil et des raccourcis"</string>
<string name="permdesc_write_settings" msgid="5440712911516509985">"Permet à l\'application de modifier les paramètres et les raccourcis de l\'écran d\'accueil."</string>
<string name="gadget_error_text" msgid="6081085226050792095">"Problème lors du chargement du widget"</string>
+ <!-- no translation found for gadget_setup_text (8274003207686040488) -->
+ <skip />
<string name="uninstall_system_app_text" msgid="4172046090762920660">"Impossible de désinstaller cette application, car il s\'agit d\'une application système."</string>
<string name="dream_name" msgid="1530253749244328964">"Lance-missile"</string>
<string name="folder_hint_text" msgid="6617836969016293992">"Dossier sans nom"</string>
diff --git a/res/values-fr/strings.xml b/res/values-fr/strings.xml
index 17cdab7..0f59ad7 100644
--- a/res/values-fr/strings.xml
+++ b/res/values-fr/strings.xml
@@ -77,6 +77,8 @@
<string name="permlab_write_settings" msgid="3574213698004620587">"modifier les paramètres et les raccourcis de l\'écran d\'accueil"</string>
<string name="permdesc_write_settings" msgid="5440712911516509985">"Permettre à l\'application de modifier les paramètres et les raccourcis de l\'écran d\'accueil"</string>
<string name="gadget_error_text" msgid="6081085226050792095">"Problème lors du chargement du widget."</string>
+ <!-- no translation found for gadget_setup_text (8274003207686040488) -->
+ <skip />
<string name="uninstall_system_app_text" msgid="4172046090762920660">"Impossible de désinstaller cette application, car il s\'agit d\'une application système."</string>
<string name="dream_name" msgid="1530253749244328964">"Rocket Launcher"</string>
<string name="folder_hint_text" msgid="6617836969016293992">"Dossier sans nom"</string>
diff --git a/res/values-hi/strings.xml b/res/values-hi/strings.xml
index 49943aa..0e2aa4f 100644
--- a/res/values-hi/strings.xml
+++ b/res/values-hi/strings.xml
@@ -77,6 +77,8 @@
<string name="permlab_write_settings" msgid="3574213698004620587">"होम सेटिंग और शॉर्टकट लिखें"</string>
<string name="permdesc_write_settings" msgid="5440712911516509985">"ऐप्लिकेशन को होम में सेटिंग और शॉर्टकट बदलने देती है."</string>
<string name="gadget_error_text" msgid="6081085226050792095">"विजेट लोड करने में समस्या"</string>
+ <!-- no translation found for gadget_setup_text (8274003207686040488) -->
+ <skip />
<string name="uninstall_system_app_text" msgid="4172046090762920660">"यह एक सिस्टम ऐप्लिकेशन है और इसे अनइंस्टॉल नहीं किया जा सकता."</string>
<string name="dream_name" msgid="1530253749244328964">"रॉकेट लॉन्चर"</string>
<string name="folder_hint_text" msgid="6617836969016293992">"अनामित फ़ोल्डर"</string>
diff --git a/res/values-hr/strings.xml b/res/values-hr/strings.xml
index 696d2a7..b1a3b26 100644
--- a/res/values-hr/strings.xml
+++ b/res/values-hr/strings.xml
@@ -77,6 +77,8 @@
<string name="permlab_write_settings" msgid="3574213698004620587">"pisanje postavki početnog zaslona i prečaca"</string>
<string name="permdesc_write_settings" msgid="5440712911516509985">"Aplikaciji omogućuje promjenu postavki i prečaca na početnom zaslonu."</string>
<string name="gadget_error_text" msgid="6081085226050792095">"Problem pri učitavanju widgeta"</string>
+ <!-- no translation found for gadget_setup_text (8274003207686040488) -->
+ <skip />
<string name="uninstall_system_app_text" msgid="4172046090762920660">"Ovo je aplikacija sustava i ne može se ukloniti."</string>
<string name="dream_name" msgid="1530253749244328964">"Lansirna rampa"</string>
<string name="folder_hint_text" msgid="6617836969016293992">"Neimenovana mapa"</string>
diff --git a/res/values-hu/strings.xml b/res/values-hu/strings.xml
index 33ee617..1481406 100644
--- a/res/values-hu/strings.xml
+++ b/res/values-hu/strings.xml
@@ -77,6 +77,8 @@
<string name="permlab_write_settings" msgid="3574213698004620587">"Főoldal beállításainak és parancsikonjainak írása"</string>
<string name="permdesc_write_settings" msgid="5440712911516509985">"Lehetővé teszi az alkalmazás számára, hogy módosítsa a kezdőképernyő beállításait és parancsikonjait."</string>
<string name="gadget_error_text" msgid="6081085226050792095">"Probléma történt a modul betöltésekor"</string>
+ <!-- no translation found for gadget_setup_text (8274003207686040488) -->
+ <skip />
<string name="uninstall_system_app_text" msgid="4172046090762920660">"Ez egy rendszeralkalmazás, és nem lehet eltávolítani."</string>
<string name="dream_name" msgid="1530253749244328964">"Aknavető"</string>
<string name="folder_hint_text" msgid="6617836969016293992">"Névtelen mappa"</string>
diff --git a/res/values-hy-rAM/strings.xml b/res/values-hy-rAM/strings.xml
index 2aa5cc0..0a3ff0e 100644
--- a/res/values-hy-rAM/strings.xml
+++ b/res/values-hy-rAM/strings.xml
@@ -77,6 +77,8 @@
<string name="permlab_write_settings" msgid="3574213698004620587">"ստեղծել հիմնաէջի կարգավորումներ ու դյուրանցումներ"</string>
<string name="permdesc_write_settings" msgid="5440712911516509985">"Ծրագրին թույլ է տալիս փոփոխել հիմնաէջի կարգավորումներն ու դյուրանցումները:"</string>
<string name="gadget_error_text" msgid="6081085226050792095">"Վիջեթի բեռնման խնդիր կա"</string>
+ <!-- no translation found for gadget_setup_text (8274003207686040488) -->
+ <skip />
<string name="uninstall_system_app_text" msgid="4172046090762920660">"Սա համակարգային ծրագիր է և չի կարող ապատեղադրվել:"</string>
<string name="dream_name" msgid="1530253749244328964">"Հրթիռային թողարկիչ"</string>
<string name="folder_hint_text" msgid="6617836969016293992">"Անանուն թղթապանակ"</string>
diff --git a/res/values-in/strings.xml b/res/values-in/strings.xml
index db6f9a1..e0aa1fb 100644
--- a/res/values-in/strings.xml
+++ b/res/values-in/strings.xml
@@ -77,6 +77,8 @@
<string name="permlab_write_settings" msgid="3574213698004620587">"menulis setelan dan pintasan layar Utama"</string>
<string name="permdesc_write_settings" msgid="5440712911516509985">"Mengizinkan aplikasi mengubah setelan dan pintasan di layar Utama."</string>
<string name="gadget_error_text" msgid="6081085226050792095">"Masalah memuat widget"</string>
+ <!-- no translation found for gadget_setup_text (8274003207686040488) -->
+ <skip />
<string name="uninstall_system_app_text" msgid="4172046090762920660">"Ini adalah aplikasi sistem dan tidak dapat dicopot pemasangannya."</string>
<string name="dream_name" msgid="1530253749244328964">"Rocket Launcher"</string>
<string name="folder_hint_text" msgid="6617836969016293992">"Folder Tanpa Nama"</string>
diff --git a/res/values-it/strings.xml b/res/values-it/strings.xml
index 388fcca..6f712f7 100644
--- a/res/values-it/strings.xml
+++ b/res/values-it/strings.xml
@@ -77,6 +77,8 @@
<string name="permlab_write_settings" msgid="3574213698004620587">"creazione di impostazioni e scorciatoie in Home"</string>
<string name="permdesc_write_settings" msgid="5440712911516509985">"Consente all\'app di modificare le impostazioni e le scorciatoie in Home."</string>
<string name="gadget_error_text" msgid="6081085226050792095">"Errore durante il caricamento del widget"</string>
+ <!-- no translation found for gadget_setup_text (8274003207686040488) -->
+ <skip />
<string name="uninstall_system_app_text" msgid="4172046090762920660">"Questa è un\'app di sistema e non può essere disinstallata."</string>
<string name="dream_name" msgid="1530253749244328964">"Lanciamissili"</string>
<string name="folder_hint_text" msgid="6617836969016293992">"Cartella senza nome"</string>
diff --git a/res/values-iw/strings.xml b/res/values-iw/strings.xml
index c87d948..cb4bcc5 100644
--- a/res/values-iw/strings.xml
+++ b/res/values-iw/strings.xml
@@ -77,6 +77,8 @@
<string name="permlab_write_settings" msgid="3574213698004620587">"כתוב הגדרות וקיצורי דרך של דף הבית"</string>
<string name="permdesc_write_settings" msgid="5440712911516509985">"מאפשר לאפליקציה לשנות את ההגדרות וקיצורי הדרך בדף הבית."</string>
<string name="gadget_error_text" msgid="6081085226050792095">"בעיה בטעינת ווידג\'ט"</string>
+ <!-- no translation found for gadget_setup_text (8274003207686040488) -->
+ <skip />
<string name="uninstall_system_app_text" msgid="4172046090762920660">"זוהי אפליקציית מערכת ולא ניתן להסיר את התקנתה."</string>
<string name="dream_name" msgid="1530253749244328964">"Rocket Launcher"</string>
<string name="folder_hint_text" msgid="6617836969016293992">"תיקיה ללא שם"</string>
diff --git a/res/values-ja/strings.xml b/res/values-ja/strings.xml
index aeddd07..36eaf5a 100644
--- a/res/values-ja/strings.xml
+++ b/res/values-ja/strings.xml
@@ -77,6 +77,8 @@
<string name="permlab_write_settings" msgid="3574213698004620587">"ホームの設定とショートカットの書き込み"</string>
<string name="permdesc_write_settings" msgid="5440712911516509985">"ホームの設定とショートカットの変更をアプリに許可します。"</string>
<string name="gadget_error_text" msgid="6081085226050792095">"ウィジェットを表示できません"</string>
+ <!-- no translation found for gadget_setup_text (8274003207686040488) -->
+ <skip />
<string name="uninstall_system_app_text" msgid="4172046090762920660">"このシステムアプリはアンインストールできません。"</string>
<string name="dream_name" msgid="1530253749244328964">"Rocket Launcher"</string>
<string name="folder_hint_text" msgid="6617836969016293992">"名前のないフォルダ"</string>
diff --git a/res/values-ka-rGE/strings.xml b/res/values-ka-rGE/strings.xml
index a1ab308..e354ab0 100644
--- a/res/values-ka-rGE/strings.xml
+++ b/res/values-ka-rGE/strings.xml
@@ -77,6 +77,8 @@
<string name="permlab_write_settings" msgid="3574213698004620587">"მთავარი ეკრანის პარამეტრებისა და მალსახმობების ჩაწერა"</string>
<string name="permdesc_write_settings" msgid="5440712911516509985">"აპისთვის მთავარი ეკრანის პარამეტრებისა და მალსახმობების შეცვლის უფლების მიცემა."</string>
<string name="gadget_error_text" msgid="6081085226050792095">"პრობლემა ვიჯეტის ჩატვირთვისას"</string>
+ <!-- no translation found for gadget_setup_text (8274003207686040488) -->
+ <skip />
<string name="uninstall_system_app_text" msgid="4172046090762920660">"ეს სისტემური აპია და მისი წაშლა შეუძლებელია."</string>
<string name="dream_name" msgid="1530253749244328964">"ფეიერვერკი"</string>
<string name="folder_hint_text" msgid="6617836969016293992">"უსახელო საქაღალდე"</string>
diff --git a/res/values-km-rKH/strings.xml b/res/values-km-rKH/strings.xml
index 2a7a782..56c8bc7 100644
--- a/res/values-km-rKH/strings.xml
+++ b/res/values-km-rKH/strings.xml
@@ -77,6 +77,8 @@
<string name="permlab_write_settings" msgid="3574213698004620587">"សរសេរការកំណត់ និងផ្លូវកាត់លើអេក្រង់ដើម"</string>
<string name="permdesc_write_settings" msgid="5440712911516509985">"អនុញ្ញាតឲ្យកម្មវិធីប្ដូរការកំណត់ និងផ្លូវកាត់ក្នុងអេក្រង់ដើម។"</string>
<string name="gadget_error_text" msgid="6081085226050792095">"បញ្ហាក្នុងការផ្ទុកធាតុក្រាហ្វិក"</string>
+ <!-- no translation found for gadget_setup_text (8274003207686040488) -->
+ <skip />
<string name="uninstall_system_app_text" msgid="4172046090762920660">"នេះជាកម្មវិធីប្រព័ន្ធ មិនអាចលុបបានទេ។"</string>
<string name="dream_name" msgid="1530253749244328964">"កម្មវិធីចាប់ផ្ដើមរ៉ូកែត"</string>
<string name="folder_hint_text" msgid="6617836969016293992">"ថតគ្មានឈ្មោះ"</string>
@@ -85,7 +87,7 @@
<string name="workspace_scroll_format" msgid="8458889198184077399">"អេក្រង់ដើម %1$d នៃ %2$d"</string>
<string name="apps_customize_apps_scroll_format" msgid="370005296147130238">"ទំព័រកម្មវិធី %1$d នៃ %2$d"</string>
<string name="apps_customize_widgets_scroll_format" msgid="3106209519974971521">"ទំព័រធាតុក្រាហ្វិក %1$d នៃ %2$d"</string>
- <string name="first_run_cling_title" msgid="2459738000155917941">"សូមស្វាគមន៍"</string>
+ <string name="first_run_cling_title" msgid="2459738000155917941">"សូមស្វាគមន៍"</string>
<string name="first_run_cling_description" msgid="6447072552696253358">"ធ្វើដោយខ្លួនឯងនៅលើអេក្រង់ដើម។"</string>
<string name="first_run_cling_custom_content_hint" msgid="6090628589029352439"></string>
<string name="first_run_cling_search_bar_hint" msgid="5909062802402452582"></string>
diff --git a/res/values-ko/strings.xml b/res/values-ko/strings.xml
index 392cfec..0746de9 100644
--- a/res/values-ko/strings.xml
+++ b/res/values-ko/strings.xml
@@ -77,6 +77,8 @@
<string name="permlab_write_settings" msgid="3574213698004620587">"홈 설정 및 바로가기 쓰기"</string>
<string name="permdesc_write_settings" msgid="5440712911516509985">"앱이 홈에 있는 설정 및 바로가기를 변경할 수 있도록 합니다."</string>
<string name="gadget_error_text" msgid="6081085226050792095">"위젯을 로드하는 중 문제가 발생했습니다."</string>
+ <!-- no translation found for gadget_setup_text (8274003207686040488) -->
+ <skip />
<string name="uninstall_system_app_text" msgid="4172046090762920660">"시스템 앱은 제거할 수 없습니다."</string>
<string name="dream_name" msgid="1530253749244328964">"로켓 실행기"</string>
<string name="folder_hint_text" msgid="6617836969016293992">"이름이 없는 폴더"</string>
diff --git a/res/values-lo-rLA/strings.xml b/res/values-lo-rLA/strings.xml
index 185f4f8..e628100 100644
--- a/res/values-lo-rLA/strings.xml
+++ b/res/values-lo-rLA/strings.xml
@@ -36,7 +36,7 @@
<string name="rename_folder_label" msgid="3727762225964550653">"ຊື່ໂຟນເດີ"</string>
<string name="rename_folder_title" msgid="3771389277707820891">"ປ່ຽນຊື່ໂຟນເດີ"</string>
<string name="rename_action" msgid="5559600076028658757">"ຕົກລົງ"</string>
- <string name="cancel_action" msgid="7009134900002915310">"ຍົກເລີກ"</string>
+ <string name="cancel_action" msgid="7009134900002915310">"ຍົກເລີກ"</string>
<string name="menu_item_add_item" msgid="1264911265836810421">"ເພີ່ມໃສ່ໜ້າຈໍຫຼັກ"</string>
<string name="group_applications" msgid="3797214114206693605">"ແອັບຯ"</string>
<string name="group_shortcuts" msgid="6012256992764410535">"ທາງລັດ"</string>
@@ -77,6 +77,7 @@
<string name="permlab_write_settings" msgid="3574213698004620587">"ຂຽນການຕັ້ງຄ່າໜ້າຫຼັກ ແລະທາງລັດ"</string>
<string name="permdesc_write_settings" msgid="5440712911516509985">"ອະນຸຍາດໃຫ້ແອັບຯດັ່ງກ່າວ ປ່ຽນການຕັ້ງຄ່າ ແລະທາງລັດໃນໜ້າຫຼັກ."</string>
<string name="gadget_error_text" msgid="6081085226050792095">"ມີບັນຫາໃນການໂຫລດວິດເຈັດ"</string>
+ <string name="gadget_setup_text" msgid="8274003207686040488">"ຕິດຕັ້ງ"</string>
<string name="uninstall_system_app_text" msgid="4172046090762920660">"ນີ້ແມ່ນແອັບຯຂອງລະບົບ ແລະບໍ່ສາມາດຖອນການຕິດຕັ້ງອອກໄດ້."</string>
<string name="dream_name" msgid="1530253749244328964">"Rocket Launcher"</string>
<string name="folder_hint_text" msgid="6617836969016293992">"ໂຟນເດີຍັງບໍ່ຖືກຕັ້ງຊື່"</string>
@@ -114,7 +115,7 @@
<string name="package_state_unknown" msgid="7592128424511031410">"ບໍ່ຮູ້ຈັກ"</string>
<string name="package_state_error" msgid="7672093962724223588">"ບໍ່ໄດ້ກູ້ຂໍ້ມູນມາເທື່ອ"</string>
<string name="abandoned_clean_all" msgid="5256770727689657618">"ລຶບທັງໝົດ"</string>
- <string name="abandoned_clean_this" msgid="7610119707847920412">"ລຶບ"</string>
+ <string name="abandoned_clean_this" msgid="7610119707847920412">"ລຶບ"</string>
<string name="abandoned_search" msgid="891119232568284442">"ຊອກຫາ"</string>
<string name="abandoned_promises_title" msgid="7096178467971716750">"ແອັບຯນີ້ຍັງບໍ່ໄດ້ຕິດຕັ້ງເທື່ອ"</string>
<string name="abandoned_promise_explanation" msgid="3990027586878167529">"ແອັບຯສຳລັບໄອຄອນນີ້ຍັງບໍ່ໄດ້ຕິດຕັ້ງເທື່ອ. ທ່ານສາມາດລຶບມັນອອກ ຫຼືຊອກຫາແອັບຯ ແລ້ວຕິດຕັ້ງມັນໄດ້ດ້ວຍຕົນເອງ."</string>
diff --git a/res/values-lt/strings.xml b/res/values-lt/strings.xml
index 9acb910..29cd23b 100644
--- a/res/values-lt/strings.xml
+++ b/res/values-lt/strings.xml
@@ -77,6 +77,8 @@
<string name="permlab_write_settings" msgid="3574213698004620587">"rašyti pagrindinio puslapio nustatymus ir sparčiuosius klavišus"</string>
<string name="permdesc_write_settings" msgid="5440712911516509985">"Programai leidžiama keisti pagrindinio puslapio nustatymus ir sparčiuosius klavišus."</string>
<string name="gadget_error_text" msgid="6081085226050792095">"Problema įkeliant valdiklį"</string>
+ <!-- no translation found for gadget_setup_text (8274003207686040488) -->
+ <skip />
<string name="uninstall_system_app_text" msgid="4172046090762920660">"Tai sistemos programa ir jos negalima pašalinti."</string>
<string name="dream_name" msgid="1530253749244328964">"Rocket Launcher"</string>
<string name="folder_hint_text" msgid="6617836969016293992">"Aplankas be pavadinimo"</string>
diff --git a/res/values-lv/strings.xml b/res/values-lv/strings.xml
index b71a7df..b694dd0 100644
--- a/res/values-lv/strings.xml
+++ b/res/values-lv/strings.xml
@@ -77,6 +77,8 @@
<string name="permlab_write_settings" msgid="3574213698004620587">"rakstīt sākuma ekrāna iestatījumus un saīsnes"</string>
<string name="permdesc_write_settings" msgid="5440712911516509985">"Ļauj lietotnei mainīt iestatījumus un saīsnes sākuma ekrānā."</string>
<string name="gadget_error_text" msgid="6081085226050792095">"Ielādējot logrīku, radās problēma."</string>
+ <!-- no translation found for gadget_setup_text (8274003207686040488) -->
+ <skip />
<string name="uninstall_system_app_text" msgid="4172046090762920660">"Šī ir sistēmas lietotne, un to nevar atinstalēt."</string>
<string name="dream_name" msgid="1530253749244328964">"Rocket Launcher"</string>
<string name="folder_hint_text" msgid="6617836969016293992">"Mape bez nosaukuma"</string>
diff --git a/res/values-mn-rMN/strings.xml b/res/values-mn-rMN/strings.xml
index 358cea3..0d0b519 100644
--- a/res/values-mn-rMN/strings.xml
+++ b/res/values-mn-rMN/strings.xml
@@ -77,6 +77,7 @@
<string name="permlab_write_settings" msgid="3574213698004620587">"Нүүрний тохиргоо болон товчлолыг бичих"</string>
<string name="permdesc_write_settings" msgid="5440712911516509985">"Апп нь Нүүрэндэх товчлол болон тохиргоог өөрчилж чадна."</string>
<string name="gadget_error_text" msgid="6081085226050792095">"Виджет ачаалахад асуудал гарав"</string>
+ <string name="gadget_setup_text" msgid="8274003207686040488">"Тохируулга"</string>
<string name="uninstall_system_app_text" msgid="4172046090762920660">"Энэ апп нь системийн апп ба устгах боломжгүй."</string>
<string name="dream_name" msgid="1530253749244328964">"Пуужин хөөргөгч"</string>
<string name="folder_hint_text" msgid="6617836969016293992">"Нэргүй фолдер"</string>
diff --git a/res/values-ms-rMY/strings.xml b/res/values-ms-rMY/strings.xml
index 0c83d83..fc2ec33 100644
--- a/res/values-ms-rMY/strings.xml
+++ b/res/values-ms-rMY/strings.xml
@@ -77,6 +77,8 @@
<string name="permlab_write_settings" msgid="3574213698004620587">"tulis tetapan dan pintasan Laman Utama"</string>
<string name="permdesc_write_settings" msgid="5440712911516509985">"Membenarkan apl menukar tetapan dan pintasan di Laman Utama."</string>
<string name="gadget_error_text" msgid="6081085226050792095">"Masalah memuatkan widget"</string>
+ <!-- no translation found for gadget_setup_text (8274003207686040488) -->
+ <skip />
<string name="uninstall_system_app_text" msgid="4172046090762920660">"Ini ialah apl sistem dan tidak boleh dinyahpasang."</string>
<string name="dream_name" msgid="1530253749244328964">"Pelancar Roket"</string>
<string name="folder_hint_text" msgid="6617836969016293992">"Folder Tanpa Nama"</string>
diff --git a/res/values-nb/strings.xml b/res/values-nb/strings.xml
index f43eea7..71c2fed 100644
--- a/res/values-nb/strings.xml
+++ b/res/values-nb/strings.xml
@@ -77,6 +77,8 @@
<string name="permlab_write_settings" msgid="3574213698004620587">"angi startsideinnstillinger og -snarveier"</string>
<string name="permdesc_write_settings" msgid="5440712911516509985">"Lar appen endre innstillingene og snarveiene på startsiden."</string>
<string name="gadget_error_text" msgid="6081085226050792095">"Problem ved innlasting av modul"</string>
+ <!-- no translation found for gadget_setup_text (8274003207686040488) -->
+ <skip />
<string name="uninstall_system_app_text" msgid="4172046090762920660">"Dette er en systemapp som ikke kan avinstalleres."</string>
<string name="dream_name" msgid="1530253749244328964">"Rocket Launcher"</string>
<string name="folder_hint_text" msgid="6617836969016293992">"Mappe uten navn"</string>
diff --git a/res/values-nl/strings.xml b/res/values-nl/strings.xml
index a0add2f..95b8725 100644
--- a/res/values-nl/strings.xml
+++ b/res/values-nl/strings.xml
@@ -77,6 +77,8 @@
<string name="permlab_write_settings" msgid="3574213698004620587">"instellingen en snelkoppelingen op de startpagina schrijven"</string>
<string name="permdesc_write_settings" msgid="5440712911516509985">"De app toestaan de instellingen en snelkoppelingen op de startpagina te wijzigen."</string>
<string name="gadget_error_text" msgid="6081085226050792095">"Probleem bij het laden van widget"</string>
+ <!-- no translation found for gadget_setup_text (8274003207686040488) -->
+ <skip />
<string name="uninstall_system_app_text" msgid="4172046090762920660">"Dit is een systeemapp die niet kan worden verwijderd."</string>
<string name="dream_name" msgid="1530253749244328964">"Rocket Launcher"</string>
<string name="folder_hint_text" msgid="6617836969016293992">"Naamloze map"</string>
diff --git a/res/values-pl/strings.xml b/res/values-pl/strings.xml
index 9d32b34..95c8fe3 100644
--- a/res/values-pl/strings.xml
+++ b/res/values-pl/strings.xml
@@ -77,6 +77,8 @@
<string name="permlab_write_settings" msgid="3574213698004620587">"zapisywanie ustawień i skrótów na ekranie głównym"</string>
<string name="permdesc_write_settings" msgid="5440712911516509985">"Umożliwia aplikacji zmianę ustawień i skrótów na ekranie głównym."</string>
<string name="gadget_error_text" msgid="6081085226050792095">"Problem podczas ładowania widżetu"</string>
+ <!-- no translation found for gadget_setup_text (8274003207686040488) -->
+ <skip />
<string name="uninstall_system_app_text" msgid="4172046090762920660">"To aplikacja systemowa i nie można jej odinstalować."</string>
<string name="dream_name" msgid="1530253749244328964">"Wyrzutnia rakiet"</string>
<string name="folder_hint_text" msgid="6617836969016293992">"Folder bez nazwy"</string>
diff --git a/res/values-pt-rPT/strings.xml b/res/values-pt-rPT/strings.xml
index 4734def..6cecbf9 100644
--- a/res/values-pt-rPT/strings.xml
+++ b/res/values-pt-rPT/strings.xml
@@ -77,6 +77,8 @@
<string name="permlab_write_settings" msgid="3574213698004620587">"escrever definições e atalhos do Ecrã principal"</string>
<string name="permdesc_write_settings" msgid="5440712911516509985">"Permite à aplicação alterar as definições e os atalhos no Ecrã Principal."</string>
<string name="gadget_error_text" msgid="6081085226050792095">"Problema ao carregar o widget"</string>
+ <!-- no translation found for gadget_setup_text (8274003207686040488) -->
+ <skip />
<string name="uninstall_system_app_text" msgid="4172046090762920660">"É uma aplicação de sistema e não pode ser desinstalada."</string>
<string name="dream_name" msgid="1530253749244328964">"Lança-mísseis"</string>
<string name="folder_hint_text" msgid="6617836969016293992">"Pasta sem nome"</string>
diff --git a/res/values-pt/strings.xml b/res/values-pt/strings.xml
index c1d8764..f24687f 100644
--- a/res/values-pt/strings.xml
+++ b/res/values-pt/strings.xml
@@ -77,6 +77,8 @@
<string name="permlab_write_settings" msgid="3574213698004620587">"gravar configurações e atalhos da tela inicial"</string>
<string name="permdesc_write_settings" msgid="5440712911516509985">"Permite que o aplicativo altere as configurações e os atalhos na tela inicial."</string>
<string name="gadget_error_text" msgid="6081085226050792095">"Problema ao carregar o widget"</string>
+ <!-- no translation found for gadget_setup_text (8274003207686040488) -->
+ <skip />
<string name="uninstall_system_app_text" msgid="4172046090762920660">"Este é um aplicativo do sistema e não pode ser desinstalado."</string>
<string name="dream_name" msgid="1530253749244328964">"Rocket Launcher"</string>
<string name="folder_hint_text" msgid="6617836969016293992">"Pasta sem nome"</string>
diff --git a/res/values-ro/strings.xml b/res/values-ro/strings.xml
index 72180bf..07cf8fb 100644
--- a/res/values-ro/strings.xml
+++ b/res/values-ro/strings.xml
@@ -77,6 +77,8 @@
<string name="permlab_write_settings" msgid="3574213698004620587">"scrie setări și comenzi rapide pentru ecranul de pornire"</string>
<string name="permdesc_write_settings" msgid="5440712911516509985">"Permite aplicației să modifice setările și comenzile rapide din ecranul de pornire."</string>
<string name="gadget_error_text" msgid="6081085226050792095">"Problemă la încărcarea widgetului"</string>
+ <!-- no translation found for gadget_setup_text (8274003207686040488) -->
+ <skip />
<string name="uninstall_system_app_text" msgid="4172046090762920660">"Aceasta este o aplicație de sistem și nu poate fi dezinstalată."</string>
<string name="dream_name" msgid="1530253749244328964">"Rocket Launcher"</string>
<string name="folder_hint_text" msgid="6617836969016293992">"Dosar fără nume"</string>
diff --git a/res/values-ru/strings.xml b/res/values-ru/strings.xml
index 1ff78ff..e065213 100644
--- a/res/values-ru/strings.xml
+++ b/res/values-ru/strings.xml
@@ -77,6 +77,8 @@
<string name="permlab_write_settings" msgid="3574213698004620587">"Изменение настроек и ярлыков главного экрана"</string>
<string name="permdesc_write_settings" msgid="5440712911516509985">"Приложение сможет изменять настройки и ярлыки на главном экране."</string>
<string name="gadget_error_text" msgid="6081085226050792095">"Не удалось загрузить виджет"</string>
+ <!-- no translation found for gadget_setup_text (8274003207686040488) -->
+ <skip />
<string name="uninstall_system_app_text" msgid="4172046090762920660">"Это системное приложение, его нельзя удалить."</string>
<string name="dream_name" msgid="1530253749244328964">"Rocket Launcher"</string>
<string name="folder_hint_text" msgid="6617836969016293992">"Папка без названия"</string>
diff --git a/res/values-sk/strings.xml b/res/values-sk/strings.xml
index 80a61b7..4e4d88e 100644
--- a/res/values-sk/strings.xml
+++ b/res/values-sk/strings.xml
@@ -77,6 +77,8 @@
<string name="permlab_write_settings" msgid="3574213698004620587">"zápis nastavení a odkazov plochy"</string>
<string name="permdesc_write_settings" msgid="5440712911516509985">"Povoľuje aplikácii zmeniť nastavenia a odkazy na ploche."</string>
<string name="gadget_error_text" msgid="6081085226050792095">"Problém s načítaním miniaplikácií"</string>
+ <!-- no translation found for gadget_setup_text (8274003207686040488) -->
+ <skip />
<string name="uninstall_system_app_text" msgid="4172046090762920660">"Toto je systémová aplikácia a nedá sa odinštalovať."</string>
<string name="dream_name" msgid="1530253749244328964">"Raketomet"</string>
<string name="folder_hint_text" msgid="6617836969016293992">"Nepomenovaný priečinok"</string>
diff --git a/res/values-sl/strings.xml b/res/values-sl/strings.xml
index 228876f..f3fa342 100644
--- a/res/values-sl/strings.xml
+++ b/res/values-sl/strings.xml
@@ -77,6 +77,8 @@
<string name="permlab_write_settings" msgid="3574213698004620587">"zapis nastavitev in bližnjic na začetnem zaslonu"</string>
<string name="permdesc_write_settings" msgid="5440712911516509985">"Aplikaciji dovoli spreminjanje nastavitev in bližnjic na začetnem zaslonu."</string>
<string name="gadget_error_text" msgid="6081085226050792095">"Težava pri nalaganju pripomočka"</string>
+ <!-- no translation found for gadget_setup_text (8274003207686040488) -->
+ <skip />
<string name="uninstall_system_app_text" msgid="4172046090762920660">"To je sistemska aplikacija in je ni mogoče odstraniti."</string>
<string name="dream_name" msgid="1530253749244328964">"Raketno izstrelišče"</string>
<string name="folder_hint_text" msgid="6617836969016293992">"Neimenovana mapa"</string>
diff --git a/res/values-sr/strings.xml b/res/values-sr/strings.xml
index 4b8abfd..1caf549 100644
--- a/res/values-sr/strings.xml
+++ b/res/values-sr/strings.xml
@@ -77,6 +77,8 @@
<string name="permlab_write_settings" msgid="3574213698004620587">"уписивање подешавања и пречица на почетном екрану"</string>
<string name="permdesc_write_settings" msgid="5440712911516509985">"Дозвољава апликацији да мења подешавања и пречице на почетном екрану."</string>
<string name="gadget_error_text" msgid="6081085226050792095">"Проблем при учитавању виџета"</string>
+ <!-- no translation found for gadget_setup_text (8274003207686040488) -->
+ <skip />
<string name="uninstall_system_app_text" msgid="4172046090762920660">"Ово је системска апликација и не може да се деинсталира."</string>
<string name="dream_name" msgid="1530253749244328964">"Лансер ракета"</string>
<string name="folder_hint_text" msgid="6617836969016293992">"Неименовани директоријум"</string>
diff --git a/res/values-sv/strings.xml b/res/values-sv/strings.xml
index bdf2ca6..d33f533 100644
--- a/res/values-sv/strings.xml
+++ b/res/values-sv/strings.xml
@@ -77,6 +77,8 @@
<string name="permlab_write_settings" msgid="3574213698004620587">"skriva inställningar och genvägar för startsidan"</string>
<string name="permdesc_write_settings" msgid="5440712911516509985">"Tillåter att appen ändrar inställningar och genvägar på startsidan."</string>
<string name="gadget_error_text" msgid="6081085226050792095">"Det gick inte att läsa in widgeten"</string>
+ <!-- no translation found for gadget_setup_text (8274003207686040488) -->
+ <skip />
<string name="uninstall_system_app_text" msgid="4172046090762920660">"Det här är en systemapp som inte kan avinstalleras."</string>
<string name="dream_name" msgid="1530253749244328964">"Rocket Launcher"</string>
<string name="folder_hint_text" msgid="6617836969016293992">"Namnlös mapp"</string>
diff --git a/res/values-sw/strings.xml b/res/values-sw/strings.xml
index 72764eb..f20819a 100644
--- a/res/values-sw/strings.xml
+++ b/res/values-sw/strings.xml
@@ -77,6 +77,8 @@
<string name="permlab_write_settings" msgid="3574213698004620587">"andika mipangilio ya skrini ya Mwanzo na njia za mkato"</string>
<string name="permdesc_write_settings" msgid="5440712911516509985">"Huruhusu programu kubadilisha mipangilio na njia za mkato katika skrini ya Mwanzo."</string>
<string name="gadget_error_text" msgid="6081085226050792095">"Tatizo la kupakia wijeti"</string>
+ <!-- no translation found for gadget_setup_text (8274003207686040488) -->
+ <skip />
<string name="uninstall_system_app_text" msgid="4172046090762920660">"Hii ni programu ya mfumo na haiwezi kuondolewa."</string>
<string name="dream_name" msgid="1530253749244328964">"Kizinduzi cha Roketi"</string>
<string name="folder_hint_text" msgid="6617836969016293992">"Folda isiyo na jina"</string>
diff --git a/res/values-th/strings.xml b/res/values-th/strings.xml
index e00c551..ff0887a 100644
--- a/res/values-th/strings.xml
+++ b/res/values-th/strings.xml
@@ -77,6 +77,8 @@
<string name="permlab_write_settings" msgid="3574213698004620587">"เขียนการตั้งค่าและทางลัดหน้าแรกแล้ว"</string>
<string name="permdesc_write_settings" msgid="5440712911516509985">"อนุญาตให้แอปเปลี่ยนการตั้งค่าและทางลัดในหน้าแรก"</string>
<string name="gadget_error_text" msgid="6081085226050792095">"มีปัญหาขณะโหลดวิดเจ็ต"</string>
+ <!-- no translation found for gadget_setup_text (8274003207686040488) -->
+ <skip />
<string name="uninstall_system_app_text" msgid="4172046090762920660">"นี่เป็นแอประบบและไม่สามารถถอนการติดตั้งได้"</string>
<string name="dream_name" msgid="1530253749244328964">"Rocket Launcher"</string>
<string name="folder_hint_text" msgid="6617836969016293992">"โฟลเดอร์ที่ไม่มีชื่อ"</string>
diff --git a/res/values-tl/strings.xml b/res/values-tl/strings.xml
index 75b5ce1..be5f8ce 100644
--- a/res/values-tl/strings.xml
+++ b/res/values-tl/strings.xml
@@ -77,6 +77,8 @@
<string name="permlab_write_settings" msgid="3574213698004620587">"magsulat ng mga setting at shortcut ng Home"</string>
<string name="permdesc_write_settings" msgid="5440712911516509985">"Pinapayagan ang app na baguhin ang mga setting at shortcut sa Home."</string>
<string name="gadget_error_text" msgid="6081085226050792095">"Problema sa pag-load ng widget"</string>
+ <!-- no translation found for gadget_setup_text (8274003207686040488) -->
+ <skip />
<string name="uninstall_system_app_text" msgid="4172046090762920660">"Isa itong app ng system at hindi maaaring i-uninstall."</string>
<string name="dream_name" msgid="1530253749244328964">"Rocket Launcher"</string>
<string name="folder_hint_text" msgid="6617836969016293992">"Walang Pangalang Folder"</string>
diff --git a/res/values-tr/strings.xml b/res/values-tr/strings.xml
index d8ceb99..f90a96d 100644
--- a/res/values-tr/strings.xml
+++ b/res/values-tr/strings.xml
@@ -77,6 +77,8 @@
<string name="permlab_write_settings" msgid="3574213698004620587">"Ana ekran ayarlarını ve kısayollarını yaz"</string>
<string name="permdesc_write_settings" msgid="5440712911516509985">"Uygulamaya, Ana ekrandaki ayarları ve kısayolları değiştirme izni verir."</string>
<string name="gadget_error_text" msgid="6081085226050792095">"Widget yüklenirken sorun oluştu"</string>
+ <!-- no translation found for gadget_setup_text (8274003207686040488) -->
+ <skip />
<string name="uninstall_system_app_text" msgid="4172046090762920660">"Bu bir sistem uygulamasıdır ve yüklemesi kaldırılamaz."</string>
<string name="dream_name" msgid="1530253749244328964">"Roket Fırlatıcı"</string>
<string name="folder_hint_text" msgid="6617836969016293992">"Adsız Klasör"</string>
diff --git a/res/values-uk/strings.xml b/res/values-uk/strings.xml
index 197b201..cb89a2a 100644
--- a/res/values-uk/strings.xml
+++ b/res/values-uk/strings.xml
@@ -77,6 +77,8 @@
<string name="permlab_write_settings" msgid="3574213698004620587">"записувати налаштування та ярлики головного екрана"</string>
<string name="permdesc_write_settings" msgid="5440712911516509985">"Дозволяє програмі змінювати налаштування та ярлики на головному екрані."</string>
<string name="gadget_error_text" msgid="6081085226050792095">"Проблема із завантаженням віджета"</string>
+ <!-- no translation found for gadget_setup_text (8274003207686040488) -->
+ <skip />
<string name="uninstall_system_app_text" msgid="4172046090762920660">"Це системна програма, її неможливо видалити."</string>
<string name="dream_name" msgid="1530253749244328964">"Rocket Launcher"</string>
<string name="folder_hint_text" msgid="6617836969016293992">"Папка без назви"</string>
diff --git a/res/values-vi/strings.xml b/res/values-vi/strings.xml
index 164a2c7..6102cee 100644
--- a/res/values-vi/strings.xml
+++ b/res/values-vi/strings.xml
@@ -77,6 +77,8 @@
<string name="permlab_write_settings" msgid="3574213698004620587">"ghi cài đặt và lối tắt trên Màn hình chính"</string>
<string name="permdesc_write_settings" msgid="5440712911516509985">"Cho phép ứng dụng thay đổi cài đặt và lối tắt trên Màn hình chính."</string>
<string name="gadget_error_text" msgid="6081085226050792095">"Sự cố khi tải tiện ích con"</string>
+ <!-- no translation found for gadget_setup_text (8274003207686040488) -->
+ <skip />
<string name="uninstall_system_app_text" msgid="4172046090762920660">"Đây là ứng dụng hệ thống và không thể gỡ cài đặt."</string>
<string name="dream_name" msgid="1530253749244328964">"Rocket Launcher"</string>
<string name="folder_hint_text" msgid="6617836969016293992">"Thư mục chưa đặt tên"</string>
diff --git a/res/values-zh-rCN/strings.xml b/res/values-zh-rCN/strings.xml
index c29cfb0..3561aec 100644
--- a/res/values-zh-rCN/strings.xml
+++ b/res/values-zh-rCN/strings.xml
@@ -77,6 +77,8 @@
<string name="permlab_write_settings" msgid="3574213698004620587">"写入主屏幕设置和快捷方式"</string>
<string name="permdesc_write_settings" msgid="5440712911516509985">"允许应用更改主屏幕中的设置和快捷方式。"</string>
<string name="gadget_error_text" msgid="6081085226050792095">"加载小部件时出现问题"</string>
+ <!-- no translation found for gadget_setup_text (8274003207686040488) -->
+ <skip />
<string name="uninstall_system_app_text" msgid="4172046090762920660">"这是系统应用,无法卸载。"</string>
<string name="dream_name" msgid="1530253749244328964">"火箭发射器"</string>
<string name="folder_hint_text" msgid="6617836969016293992">"未命名文件夹"</string>
diff --git a/res/values-zh-rHK/strings.xml b/res/values-zh-rHK/strings.xml
index 254a070..d60af8a 100644
--- a/res/values-zh-rHK/strings.xml
+++ b/res/values-zh-rHK/strings.xml
@@ -77,6 +77,8 @@
<string name="permlab_write_settings" msgid="3574213698004620587">"寫入主畫面的設定和捷徑"</string>
<string name="permdesc_write_settings" msgid="5440712911516509985">"允許應用程式更改主畫面中的設定和捷徑。"</string>
<string name="gadget_error_text" msgid="6081085226050792095">"載入小工具時發生問題"</string>
+ <!-- no translation found for gadget_setup_text (8274003207686040488) -->
+ <skip />
<string name="uninstall_system_app_text" msgid="4172046090762920660">"這是系統應用程式,無法將其解除安裝。"</string>
<string name="dream_name" msgid="1530253749244328964">"Rocket Launcher"</string>
<string name="folder_hint_text" msgid="6617836969016293992">"未命名的資料夾"</string>
diff --git a/res/values-zh-rTW/strings.xml b/res/values-zh-rTW/strings.xml
index e017ae2..18d0890 100644
--- a/res/values-zh-rTW/strings.xml
+++ b/res/values-zh-rTW/strings.xml
@@ -77,6 +77,8 @@
<string name="permlab_write_settings" msgid="3574213698004620587">"寫入主螢幕設定和捷徑"</string>
<string name="permdesc_write_settings" msgid="5440712911516509985">"允許應用程式變更主螢幕中的設定和捷徑。"</string>
<string name="gadget_error_text" msgid="6081085226050792095">"載入小工具時發生問題"</string>
+ <!-- no translation found for gadget_setup_text (8274003207686040488) -->
+ <skip />
<string name="uninstall_system_app_text" msgid="4172046090762920660">"這是系統應用程式,不可解除安裝。"</string>
<string name="dream_name" msgid="1530253749244328964">"Rocket Launcher"</string>
<string name="folder_hint_text" msgid="6617836969016293992">"未命名的資料夾"</string>
diff --git a/res/values-zu/strings.xml b/res/values-zu/strings.xml
index d3d2fbb..094c227 100644
--- a/res/values-zu/strings.xml
+++ b/res/values-zu/strings.xml
@@ -77,6 +77,8 @@
<string name="permlab_write_settings" msgid="3574213698004620587">"bhala izilungiselelo zokuthi Ikhaya nezinqamuleli"</string>
<string name="permdesc_write_settings" msgid="5440712911516509985">"Ivumela uhlelo lokusebenza ukuthi lushintshe izilungiselelo nezinqamuleli Ekhaya."</string>
<string name="gadget_error_text" msgid="6081085226050792095">"Inkinga yokulayisha iwijethi"</string>
+ <!-- no translation found for gadget_setup_text (8274003207686040488) -->
+ <skip />
<string name="uninstall_system_app_text" msgid="4172046090762920660">"Lolu uhlelo lokusebenza lwesistimu futhi alikwazi ukukhishwa."</string>
<string name="dream_name" msgid="1530253749244328964">"Isiqalisi se-Rocket"</string>
<string name="folder_hint_text" msgid="6617836969016293992">"Ifolda engenagama"</string>
diff --git a/res/values/attrs.xml b/res/values/attrs.xml
index 552e84c..0db60c9 100644
--- a/res/values/attrs.xml
+++ b/res/values/attrs.xml
@@ -106,7 +106,6 @@
<declare-styleable name="BubbleTextView">
<!-- A spacing override for the icons within a page -->
<attr name="customShadows" format="boolean" />
- <attr name="glowColor" format="color" />
</declare-styleable>
<!-- AppsCustomizePagedView specific attributes. These attributes are used to
diff --git a/res/values/colors.xml b/res/values/colors.xml
index 5e9c6ec..8aa2184 100644
--- a/res/values/colors.xml
+++ b/res/values/colors.xml
@@ -34,7 +34,6 @@
<color name="quantum_panel_text_color">#FF666666</color>
<color name="quantum_panel_text_shadow_color">#FFC4C4C4</color>
- <color name="folder_items_glow_color">#FFCCCCCC</color>
<color name="outline_color">#FFFFFFFF</color>
<color name="widget_text_panel">#FF374248</color>
diff --git a/res/values/dimens.xml b/res/values/dimens.xml
index 893d7c0..b2e183c 100644
--- a/res/values/dimens.xml
+++ b/res/values/dimens.xml
@@ -101,4 +101,8 @@
<!-- The amount that the preview contents are inset from the preview background -->
<dimen name="folder_preview_padding">4dp</dimen>
<dimen name="folder_name_padding">10dp</dimen>
+
+<!-- Sizes for managed profile badges -->
+ <dimen name="profile_badge_size">24dp</dimen>
+ <dimen name="profile_badge_margin">4dp</dimen>
</resources>
diff --git a/res/values/strings.xml b/res/values/strings.xml
index aa5f7b6..ff3509b 100644
--- a/res/values/strings.xml
+++ b/res/values/strings.xml
@@ -243,6 +243,12 @@
<string name="workspace_cling_title">Organize your space</string>
<!-- The description of how to use the workspace [CHAR_LIMIT=70] -->
<string name="workspace_cling_move_item">Touch & hold background to manage wallpaper, widgets and settings.</string>
+ <!-- The title text for workspace longpress action [CHAR_LIMIT=40] -->
+ <string name="workspace_cling_longpress_title">Wallpapers, widgets, & settings</string>
+ <!-- The description of how to use the workspace [CHAR_LIMIT=70] -->
+ <string name="workspace_cling_longpress_description">Touch & hold background to customize</string>
+ <!-- The description of the button to dismiss the cling [CHAR_LIMIT=30] -->
+ <string name="workspace_cling_longpress_dismiss">GOT IT</string>
<!-- The title text for the Folder cling [CHAR_LIMIT=30] -->
<string name="folder_cling_title">Here\'s a folder</string>
<!-- The description of how to create a folder [CHAR_LIMIT=70] -->
diff --git a/res/values/styles.xml b/res/values/styles.xml
index 6079eee..0569306 100644
--- a/res/values/styles.xml
+++ b/res/values/styles.xml
@@ -91,7 +91,8 @@
<item name="android:shadowRadius">2.0</item>
<item name="android:shadowDx">0</item>
<item name="android:shadowDy">2</item>
- <item name="android:shadowColor">#FFC4C4C4</item>
+ <item name="android:shadowColor">@color/quantum_panel_text_shadow_color</item>
+ <item name="customShadows">false</item>
</style>
<style name="WorkspaceIcon.Folder">
@@ -103,7 +104,6 @@
<item name="android:shadowDy">2</item>
<item name="customShadows">false</item>
- <item name="glowColor">@color/folder_items_glow_color</item>
</style>
<style name="SearchDropTargetBar">
diff --git a/src/com/android/launcher3/AppsCustomizePagedView.java b/src/com/android/launcher3/AppsCustomizePagedView.java
index b2228f7..9f9c34b 100644
--- a/src/com/android/launcher3/AppsCustomizePagedView.java
+++ b/src/com/android/launcher3/AppsCustomizePagedView.java
@@ -28,7 +28,6 @@
import android.content.res.Resources;
import android.content.res.TypedArray;
import android.graphics.Bitmap;
-import android.graphics.Canvas;
import android.graphics.Point;
import android.graphics.Rect;
import android.graphics.drawable.Drawable;
@@ -44,12 +43,12 @@
import android.view.View;
import android.view.ViewGroup;
import android.view.animation.AccelerateInterpolator;
-import android.view.animation.DecelerateInterpolator;
import android.widget.GridLayout;
import android.widget.ImageView;
import android.widget.Toast;
import com.android.launcher3.DropTarget.DragObject;
+import com.android.launcher3.compat.AppWidgetManagerCompat;
import java.util.ArrayList;
import java.util.Collections;
@@ -144,8 +143,7 @@
*/
public class AppsCustomizePagedView extends PagedViewWithDraggableItems implements
View.OnClickListener, View.OnKeyListener, DragSource,
- PagedViewIcon.PressedCallback, PagedViewWidget.ShortPressListener,
- LauncherTransitionable {
+ PagedViewWidget.ShortPressListener, LauncherTransitionable {
static final String TAG = "AppsCustomizePagedView";
private static Rect sTmpRect = new Rect();
@@ -167,7 +165,6 @@
// Save and Restore
private int mSaveInstanceStateItemIndex = -1;
- private PagedViewIcon mPressedIcon;
// Content
private ArrayList<AppInfo> mApps;
@@ -179,7 +176,6 @@
private int mClingFocusedY;
// Caching
- private Canvas mCanvas;
private IconCache mIconCache;
// Dimens
@@ -227,13 +223,10 @@
mApps = new ArrayList<AppInfo>();
mWidgets = new ArrayList<Object>();
mIconCache = (LauncherAppState.getInstance()).getIconCache();
- mCanvas = new Canvas();
mRunningTasks = new ArrayList<AppsCustomizeAsyncTask>();
// Save the default widget preview background
TypedArray a = context.obtainStyledAttributes(attrs, R.styleable.AppsCustomizePagedView, 0, 0);
- LauncherAppState app = LauncherAppState.getInstance();
- DeviceProfile grid = app.getDynamicGrid().getDeviceProfile();
mWidgetCountX = a.getInt(R.styleable.AppsCustomizePagedView_widgetCountX, 2);
mWidgetCountY = a.getInt(R.styleable.AppsCustomizePagedView_widgetCountY, 2);
mClingFocusedX = a.getInt(R.styleable.AppsCustomizePagedView_clingFocusedX, 0);
@@ -394,7 +387,6 @@
if (!app.shouldShowAppOrWidgetProvider(widget.provider)) {
continue;
}
- widget.label = widget.label.trim();
if (widget.minWidth > 0 && widget.minHeight > 0) {
// Ensure that all widgets we show can be added on a workspace of this size
int[] spanXY = Launcher.getSpanForWidget(mLauncher, widget);
@@ -444,39 +436,29 @@
@Override
public void onClick(View v) {
// When we have exited all apps or are in transition, disregard clicks
- if (!mLauncher.isAllAppsVisible() ||
- mLauncher.getWorkspace().isSwitchingState()) return;
+ if (!mLauncher.isAllAppsVisible()
+ || mLauncher.getWorkspace().isSwitchingState()
+ || !(v instanceof PagedViewWidget)) return;
- if (v instanceof PagedViewIcon) {
- // Animate some feedback to the click
- final AppInfo appInfo = (AppInfo) v.getTag();
-
- // Lock the drawable state to pressed until we return to Launcher
- if (mPressedIcon != null) {
- mPressedIcon.lockDrawableState();
- }
- mLauncher.onClickPagedViewIcon(v, appInfo);
- } else if (v instanceof PagedViewWidget) {
- // Let the user know that they have to long press to add a widget
- if (mWidgetInstructionToast != null) {
- mWidgetInstructionToast.cancel();
- }
- mWidgetInstructionToast = Toast.makeText(getContext(),R.string.long_press_widget_to_add,
- Toast.LENGTH_SHORT);
- mWidgetInstructionToast.show();
-
- // Create a little animation to show that the widget can move
- float offsetY = getResources().getDimensionPixelSize(R.dimen.dragViewOffsetY);
- final ImageView p = (ImageView) v.findViewById(R.id.widget_preview);
- AnimatorSet bounce = LauncherAnimUtils.createAnimatorSet();
- ValueAnimator tyuAnim = LauncherAnimUtils.ofFloat(p, "translationY", offsetY);
- tyuAnim.setDuration(125);
- ValueAnimator tydAnim = LauncherAnimUtils.ofFloat(p, "translationY", 0f);
- tydAnim.setDuration(100);
- bounce.play(tyuAnim).before(tydAnim);
- bounce.setInterpolator(new AccelerateInterpolator());
- bounce.start();
+ // Let the user know that they have to long press to add a widget
+ if (mWidgetInstructionToast != null) {
+ mWidgetInstructionToast.cancel();
}
+ mWidgetInstructionToast = Toast.makeText(getContext(),R.string.long_press_widget_to_add,
+ Toast.LENGTH_SHORT);
+ mWidgetInstructionToast.show();
+
+ // Create a little animation to show that the widget can move
+ float offsetY = getResources().getDimensionPixelSize(R.dimen.dragViewOffsetY);
+ final ImageView p = (ImageView) v.findViewById(R.id.widget_preview);
+ AnimatorSet bounce = LauncherAnimUtils.createAnimatorSet();
+ ValueAnimator tyuAnim = LauncherAnimUtils.ofFloat(p, "translationY", offsetY);
+ tyuAnim.setDuration(125);
+ ValueAnimator tydAnim = LauncherAnimUtils.ofFloat(p, "translationY", 0f);
+ tydAnim.setDuration(100);
+ bounce.play(tyuAnim).before(tydAnim);
+ bounce.setInterpolator(new AccelerateInterpolator());
+ bounce.start();
}
public boolean onKey(View v, int keyCode, KeyEvent event) {
@@ -492,7 +474,6 @@
}
private void beginDraggingApplication(View v) {
- mLauncher.getWorkspace().onDragStartedWithItem(v);
mLauncher.getWorkspace().beginDragShared(v, this);
}
@@ -534,18 +515,9 @@
@Override
public void run() {
mWidgetLoadingId = mLauncher.getAppWidgetHost().allocateAppWidgetId();
- // Options will be null for platforms with JB or lower, so this serves as an
- // SDK level check.
- if (options == null) {
- if (AppWidgetManager.getInstance(mLauncher).bindAppWidgetIdIfAllowed(
- mWidgetLoadingId, info.componentName)) {
- mWidgetCleanupState = WIDGET_BOUND;
- }
- } else {
- if (AppWidgetManager.getInstance(mLauncher).bindAppWidgetIdIfAllowed(
- mWidgetLoadingId, info.componentName, options)) {
- mWidgetCleanupState = WIDGET_BOUND;
- }
+ if(AppWidgetManagerCompat.getInstance(mLauncher).bindAppWidgetIdIfAllowed(
+ mWidgetLoadingId, pInfo, options)) {
+ mWidgetCleanupState = WIDGET_BOUND;
}
}
};
@@ -673,9 +645,8 @@
int[] previewSizeBeforeScale = new int[1];
- preview = getWidgetPreviewLoader().generateWidgetPreview(createWidgetInfo.componentName,
- createWidgetInfo.previewImage, createWidgetInfo.icon, spanX, spanY,
- maxWidth, maxHeight, null, previewSizeBeforeScale);
+ preview = getWidgetPreviewLoader().generateWidgetPreview(createWidgetInfo.info,
+ spanX, spanY, maxWidth, maxHeight, null, previewSizeBeforeScale);
// Compare the size of the drag preview to the preview in the AppsCustomize tray
int previewWidthInAppsCustomize = Math.min(previewSizeBeforeScale[0],
@@ -692,15 +663,7 @@
} else {
PendingAddShortcutInfo createShortcutInfo = (PendingAddShortcutInfo) v.getTag();
Drawable icon = mIconCache.getFullResIcon(createShortcutInfo.shortcutActivityInfo);
- preview = Bitmap.createBitmap(icon.getIntrinsicWidth(),
- icon.getIntrinsicHeight(), Bitmap.Config.ARGB_8888);
-
- mCanvas.setBitmap(preview);
- mCanvas.save();
- WidgetPreviewLoader.renderDrawableToBitmap(icon, preview, 0, 0,
- icon.getIntrinsicWidth(), icon.getIntrinsicHeight());
- mCanvas.restore();
- mCanvas.setBitmap(null);
+ preview = Utilities.createIconBitmap(icon, mLauncher);
createItemInfo.spanX = createItemInfo.spanY = 1;
}
@@ -726,7 +689,7 @@
protected boolean beginDragging(final View v) {
if (!super.beginDragging(v)) return false;
- if (v instanceof PagedViewIcon) {
+ if (v instanceof BubbleTextView) {
beginDraggingApplication(v);
} else if (v instanceof PagedViewWidget) {
if (!beginDraggingWidget(v)) {
@@ -741,9 +704,6 @@
public void run() {
// We don't enter spring-loaded mode if the drag has been cancelled
if (mLauncher.getDragController().isDragging()) {
- // Reset the alpha on the dragged icon before we drag
- resetDrawableState();
-
// Go into spring loaded mode (must happen before we startDrag())
mLauncher.enterSpringLoadedDragMode();
}
@@ -992,10 +952,10 @@
ArrayList<Bitmap> images = new ArrayList<Bitmap>();
for (int i = startIndex; i < endIndex; ++i) {
AppInfo info = mApps.get(i);
- PagedViewIcon icon = (PagedViewIcon) mLayoutInflater.inflate(
+ BubbleTextView icon = (BubbleTextView) mLayoutInflater.inflate(
R.layout.apps_customize_application, layout, false);
- icon.applyFromApplicationInfo(info, true, this);
- icon.setOnClickListener(this);
+ icon.applyFromApplicationInfo(info);
+ icon.setOnClickListener(mLauncher);
icon.setOnLongClickListener(this);
icon.setOnTouchListener(this);
icon.setOnKeyListener(this);
@@ -1559,23 +1519,6 @@
cancelAllTasks();
}
- @Override
- public void iconPressed(PagedViewIcon icon) {
- // Reset the previously pressed icon and store a reference to the pressed icon so that
- // we can reset it on return to Launcher (in Launcher.onResume())
- if (mPressedIcon != null) {
- mPressedIcon.resetDrawableState();
- }
- mPressedIcon = icon;
- }
-
- public void resetDrawableState() {
- if (mPressedIcon != null) {
- mPressedIcon.resetDrawableState();
- mPressedIcon = null;
- }
- }
-
/*
* We load an extra page on each side to prevent flashes from scrolling and loading of the
* widget previews in the background with the AsyncTasks.
diff --git a/src/com/android/launcher3/BubbleTextView.java b/src/com/android/launcher3/BubbleTextView.java
index 5c2bb99..869b0ac 100644
--- a/src/com/android/launcher3/BubbleTextView.java
+++ b/src/com/android/launcher3/BubbleTextView.java
@@ -23,14 +23,13 @@
import android.content.res.TypedArray;
import android.graphics.Bitmap;
import android.graphics.Canvas;
-import android.graphics.Rect;
import android.graphics.Region;
-import android.graphics.Region.Op;
import android.graphics.drawable.Drawable;
import android.util.AttributeSet;
import android.util.Log;
import android.util.SparseArray;
import android.util.TypedValue;
+import android.view.KeyEvent;
import android.view.MotionEvent;
import android.view.ViewConfiguration;
import android.widget.TextView;
@@ -44,12 +43,11 @@
private static SparseArray<Theme> sPreloaderThemes = new SparseArray<>(2);
- static final float SHADOW_LARGE_RADIUS = 4.0f;
- static final float SHADOW_SMALL_RADIUS = 1.75f;
- static final float SHADOW_Y_OFFSET = 2.0f;
- static final int SHADOW_LARGE_COLOUR = 0xDD000000;
- static final int SHADOW_SMALL_COLOUR = 0xCC000000;
- static final float PADDING_H = 8.0f;
+ private static final float SHADOW_LARGE_RADIUS = 4.0f;
+ private static final float SHADOW_SMALL_RADIUS = 1.75f;
+ private static final float SHADOW_Y_OFFSET = 2.0f;
+ private static final int SHADOW_LARGE_COLOUR = 0xDD000000;
+ private static final int SHADOW_SMALL_COLOUR = 0xCC000000;
static final float PADDING_V = 3.0f;
private static final String TAG = "BubbleTextView";
@@ -57,14 +55,7 @@
private static final boolean DEBUG = false;
private HolographicOutlineHelper mOutlineHelper;
- private final Canvas mTempCanvas = new Canvas();
- private final Rect mTempRect = new Rect();
- private boolean mDidInvalidateForPressedState;
- private Bitmap mPressedOrFocusedBackground;
- private int mFocusedOutlineColor;
- private int mFocusedGlowColor;
- private int mPressedOutlineColor;
- private int mPressedGlowColor;
+ private Bitmap mPressedBackground;
private float mSlop;
@@ -72,14 +63,15 @@
private final boolean mCustomShadowsEnabled;
private boolean mIsTextVisible;
+ // TODO: Remove custom background handling code, as no instance of BubbleTextView use any
+ // background.
private boolean mBackgroundSizeChanged;
private final Drawable mBackground;
private boolean mStayPressed;
+ private boolean mIgnorePressedStateChange;
private CheckLongPressHelper mLongPressHelper;
- private CharSequence mDefaultText = "";
-
public BubbleTextView(Context context) {
this(context, null, 0);
}
@@ -91,11 +83,8 @@
public BubbleTextView(Context context, AttributeSet attrs, int defStyle) {
super(context, attrs, defStyle);
- Resources res = context.getResources();
TypedArray a = context.obtainStyledAttributes(attrs,
R.styleable.BubbleTextView, defStyle, 0);
- setGlowColor(a.getColor(R.styleable.BubbleTextView_glowColor,
- res.getColor(R.color.outline_color)));
mCustomShadowsEnabled = a.getBoolean(R.styleable.BubbleTextView_customShadows, true);
a.recycle();
@@ -143,6 +132,7 @@
if (info.contentDescription != null) {
setContentDescription(info.contentDescription);
}
+ setText(info.title);
setTag(info);
if (info.wasPromise) {
@@ -150,6 +140,22 @@
}
}
+ public void applyFromApplicationInfo(AppInfo info) {
+ LauncherAppState app = LauncherAppState.getInstance();
+ DeviceProfile grid = app.getDynamicGrid().getDeviceProfile();
+
+ Drawable topDrawable = Utilities.createIconDrawable(info.iconBitmap);
+ topDrawable.setBounds(0, 0, grid.allAppsIconSizePx, grid.allAppsIconSizePx);
+ setCompoundDrawables(null, topDrawable, null, null);
+ setCompoundDrawablePadding(grid.iconDrawablePaddingPx);
+ setText(info.title);
+ if (info.contentDescription != null) {
+ setContentDescription(info.contentDescription);
+ }
+ setTag(info);
+ }
+
+
@Override
protected boolean setFrame(int left, int top, int right, int bottom) {
if (getLeft() != left || getRight() != right || getTop() != top || getBottom() != bottom) {
@@ -169,98 +175,22 @@
LauncherModel.checkItemInfo((ItemInfo) tag);
}
super.setTag(tag);
- if (tag instanceof ShortcutInfo) {
- final ShortcutInfo info = (ShortcutInfo) tag;
- mDefaultText = info.title;
- setText(mDefaultText);
- }
}
@Override
- protected void drawableStateChanged() {
- if (isPressed()) {
- // In this case, we have already created the pressed outline on ACTION_DOWN,
- // so we just need to do an invalidate to trigger draw
- if (!mDidInvalidateForPressedState) {
- setCellLayoutPressedOrFocusedIcon();
- }
- } else {
- // Otherwise, either clear the pressed/focused background, or create a background
- // for the focused state
- final boolean backgroundEmptyBefore = mPressedOrFocusedBackground == null;
- if (!mStayPressed) {
- mPressedOrFocusedBackground = null;
- }
- if (isFocused()) {
- if (getLayout() == null) {
- // In some cases, we get focus before we have been layed out. Set the
- // background to null so that it will get created when the view is drawn.
- mPressedOrFocusedBackground = null;
- } else {
- mPressedOrFocusedBackground = createGlowingOutline(
- mTempCanvas, mFocusedGlowColor, mFocusedOutlineColor);
- }
- mStayPressed = false;
- setCellLayoutPressedOrFocusedIcon();
- }
- final boolean backgroundEmptyNow = mPressedOrFocusedBackground == null;
- if (!backgroundEmptyBefore && backgroundEmptyNow) {
- setCellLayoutPressedOrFocusedIcon();
- }
+ public void setPressed(boolean pressed) {
+ super.setPressed(pressed);
+
+ if (!mIgnorePressedStateChange) {
+ updateIconState();
}
+ }
- Drawable d = mBackground;
- if (d != null && d.isStateful()) {
- d.setState(getDrawableState());
+ private void updateIconState() {
+ Drawable top = getCompoundDrawables()[1];
+ if (top instanceof FastBitmapDrawable) {
+ ((FastBitmapDrawable) top).setPressed(isPressed() || mStayPressed);
}
- super.drawableStateChanged();
- }
-
- /**
- * Draw this BubbleTextView into the given Canvas.
- *
- * @param destCanvas the canvas to draw on
- * @param padding the horizontal and vertical padding to use when drawing
- */
- private void drawWithPadding(Canvas destCanvas, int padding) {
- final Rect clipRect = mTempRect;
- getDrawingRect(clipRect);
-
- // adjust the clip rect so that we don't include the text label
- clipRect.bottom =
- getExtendedPaddingTop() - (int) BubbleTextView.PADDING_V + getLayout().getLineTop(0);
-
- // Draw the View into the bitmap.
- // The translate of scrollX and scrollY is necessary when drawing TextViews, because
- // they set scrollX and scrollY to large values to achieve centered text
- destCanvas.save();
- destCanvas.scale(getScaleX(), getScaleY(),
- (getWidth() + padding) / 2, (getHeight() + padding) / 2);
- destCanvas.translate(-getScrollX() + padding / 2, -getScrollY() + padding / 2);
- destCanvas.clipRect(clipRect, Op.REPLACE);
- draw(destCanvas);
- destCanvas.restore();
- }
-
- public void setGlowColor(int color) {
- mFocusedOutlineColor = mFocusedGlowColor = mPressedOutlineColor = mPressedGlowColor = color;
- }
-
- /**
- * Returns a new bitmap to be used as the object outline, e.g. to visualize the drop location.
- * Responsibility for the bitmap is transferred to the caller.
- */
- private Bitmap createGlowingOutline(Canvas canvas, int outlineColor, int glowColor) {
- final int padding = mOutlineHelper.mMaxOuterBlurRadius;
- final Bitmap b = Bitmap.createBitmap(
- getWidth() + padding, getHeight() + padding, Bitmap.Config.ARGB_8888);
-
- canvas.setBitmap(b);
- drawWithPadding(canvas, padding);
- mOutlineHelper.applyExtraThickExpensiveOutlineWithBlur(b, canvas, glowColor, outlineColor);
- canvas.setBitmap(null);
-
- return b;
}
@Override
@@ -271,20 +201,11 @@
switch (event.getAction()) {
case MotionEvent.ACTION_DOWN:
- // So that the pressed outline is visible immediately when isPressed() is true,
+ // So that the pressed outline is visible immediately on setStayPressed(),
// we pre-create it on ACTION_DOWN (it takes a small but perceptible amount of time
// to create it)
- if (mPressedOrFocusedBackground == null) {
- mPressedOrFocusedBackground = createGlowingOutline(
- mTempCanvas, mPressedGlowColor, mPressedOutlineColor);
- }
- // Invalidate so the pressed state is visible, or set a flag so we know that we
- // have to call invalidate as soon as the state is "pressed"
- if (isPressed()) {
- mDidInvalidateForPressedState = true;
- setCellLayoutPressedOrFocusedIcon();
- } else {
- mDidInvalidateForPressedState = false;
+ if (mPressedBackground == null) {
+ mPressedBackground = mOutlineHelper.createMediumDropShadow(this);
}
mLongPressHelper.postCheckForLongPress();
@@ -294,7 +215,7 @@
// If we've touched down and up on an item, and it's still not "pressed", then
// destroy the pressed outline
if (!isPressed()) {
- mPressedOrFocusedBackground = null;
+ mPressedBackground = null;
}
mLongPressHelper.cancelLongPress();
@@ -311,34 +232,47 @@
void setStayPressed(boolean stayPressed) {
mStayPressed = stayPressed;
if (!stayPressed) {
- mPressedOrFocusedBackground = null;
+ mPressedBackground = null;
}
- setCellLayoutPressedOrFocusedIcon();
+
+ // Only show the shadow effect when persistent pressed state is set.
+ if (getParent() instanceof ShortcutAndWidgetContainer) {
+ CellLayout layout = (CellLayout) getParent().getParent();
+ layout.setPressedIcon(this, mPressedBackground, mOutlineHelper.shadowBitmapPadding);
+ }
+
+ updateIconState();
}
- void setCellLayoutPressedOrFocusedIcon() {
- // Disable pressed state when the icon is in preloader state.
- if ((getParent() instanceof ShortcutAndWidgetContainer) &&
- !(getCompoundDrawables()[1] instanceof PreloadIconDrawable)){
- ShortcutAndWidgetContainer parent = (ShortcutAndWidgetContainer) getParent();
- if (parent != null) {
- CellLayout layout = (CellLayout) parent.getParent();
- layout.setPressedOrFocusedIcon((mPressedOrFocusedBackground != null) ? this : null);
+ void clearPressedBackground() {
+ setPressed(false);
+ setStayPressed(false);
+ }
+
+ @Override
+ public boolean onKeyDown(int keyCode, KeyEvent event) {
+ if (super.onKeyDown(keyCode, event)) {
+ // Pre-create shadow so show immediately on click.
+ if (mPressedBackground == null) {
+ mPressedBackground = mOutlineHelper.createMediumDropShadow(this);
}
+ return true;
}
+ return false;
}
- void clearPressedOrFocusedBackground() {
- mPressedOrFocusedBackground = null;
- setCellLayoutPressedOrFocusedIcon();
- }
+ @Override
+ public boolean onKeyUp(int keyCode, KeyEvent event) {
+ // Unlike touch events, keypress event propagate pressed state change immediately,
+ // without waiting for onClickHandler to execute. Disable pressed state changes here
+ // to avoid flickering.
+ mIgnorePressedStateChange = true;
+ boolean result = super.onKeyUp(keyCode, event);
- Bitmap getPressedOrFocusedBackground() {
- return mPressedOrFocusedBackground;
- }
-
- int getPressedOrFocusedBackgroundPadding() {
- return mOutlineHelper.mMaxOuterBlurRadius / 2;
+ mPressedBackground = null;
+ mIgnorePressedStateChange = false;
+ updateIconState();
+ return result;
}
@Override
diff --git a/src/com/android/launcher3/CellLayout.java b/src/com/android/launcher3/CellLayout.java
index 89473c8..d0b3f43 100644
--- a/src/com/android/launcher3/CellLayout.java
+++ b/src/com/android/launcher3/CellLayout.java
@@ -123,7 +123,7 @@
private int mDragOutlineCurrent = 0;
private final Paint mDragOutlinePaint = new Paint();
- private BubbleTextView mPressedOrFocusedIcon;
+ private final FastBitmapView mTouchFeedbackView;
private HashMap<CellLayout.LayoutParams, Animator> mReorderAnimators = new
HashMap<CellLayout.LayoutParams, Animator>();
@@ -288,6 +288,9 @@
mShortcutsAndWidgets.setCellDimensions(mCellWidth, mCellHeight, mWidthGap, mHeightGap,
mCountX, mCountY);
+ mTouchFeedbackView = new FastBitmapView(context);
+ // Make the feedback view large enough to hold the blur bitmap.
+ addView(mTouchFeedbackView, (int) (grid.cellWidthPx * 1.5), (int) (grid.cellHeightPx * 1.5));
addView(mShortcutsAndWidgets);
}
@@ -334,14 +337,6 @@
return mDropPending;
}
- private void invalidateBubbleTextView(BubbleTextView icon) {
- final int padding = icon.getPressedOrFocusedBackgroundPadding();
- invalidate(icon.getLeft() + getPaddingLeft() - padding,
- icon.getTop() + getPaddingTop() - padding,
- icon.getRight() + getPaddingLeft() + padding,
- icon.getBottom() + getPaddingTop() + padding);
- }
-
void setOverScrollAmount(float r, boolean left) {
if (left && mOverScrollForegroundDrawable != mOverScrollLeft) {
mOverScrollForegroundDrawable = mOverScrollLeft;
@@ -355,16 +350,23 @@
invalidate();
}
- void setPressedOrFocusedIcon(BubbleTextView icon) {
- // We draw the pressed or focused BubbleTextView's background in CellLayout because it
- // requires an expanded clip rect (due to the glow's blur radius)
- BubbleTextView oldIcon = mPressedOrFocusedIcon;
- mPressedOrFocusedIcon = icon;
- if (oldIcon != null) {
- invalidateBubbleTextView(oldIcon);
- }
- if (mPressedOrFocusedIcon != null) {
- invalidateBubbleTextView(mPressedOrFocusedIcon);
+ void setPressedIcon(BubbleTextView icon, Bitmap background, int padding) {
+ if (icon == null || background == null) {
+ mTouchFeedbackView.setBitmap(null);
+ mTouchFeedbackView.animate().cancel();
+ } else {
+ int offset = getMeasuredWidth() - getPaddingLeft() - getPaddingRight()
+ - (mCountX * mCellWidth);
+ mTouchFeedbackView.setTranslationX(icon.getLeft() + (int) Math.ceil(offset / 2f)
+ - padding);
+ mTouchFeedbackView.setTranslationY(icon.getTop() - padding);
+ if (mTouchFeedbackView.setBitmap(background)) {
+ mTouchFeedbackView.setAlpha(0);
+ mTouchFeedbackView.animate().alpha(1)
+ .setDuration(FastBitmapDrawable.CLICK_FEEDBACK_DURATION)
+ .setInterpolator(FastBitmapDrawable.CLICK_FEEDBACK_INTERPOLATOR)
+ .start();
+ }
}
}
@@ -431,23 +433,6 @@
}
}
- // We draw the pressed or focused BubbleTextView's background in CellLayout because it
- // requires an expanded clip rect (due to the glow's blur radius)
- if (mPressedOrFocusedIcon != null) {
- final int padding = mPressedOrFocusedIcon.getPressedOrFocusedBackgroundPadding();
- final Bitmap b = mPressedOrFocusedIcon.getPressedOrFocusedBackground();
- if (b != null) {
- int offset = getMeasuredWidth() - getPaddingLeft() - getPaddingRight() -
- (mCountX * mCellWidth);
- int left = getPaddingLeft() + (int) Math.ceil(offset / 2f);
- int top = getPaddingTop();
- canvas.drawBitmap(b,
- mPressedOrFocusedIcon.getLeft() + left - padding,
- mPressedOrFocusedIcon.getTop() + top - padding,
- null);
- }
- }
-
if (DEBUG_VISUALIZE_OCCUPIED) {
int[] pt = new int[2];
ColorDrawable cd = new ColorDrawable(Color.RED);
diff --git a/src/com/android/launcher3/FastBitmapDrawable.java b/src/com/android/launcher3/FastBitmapDrawable.java
index cf7c22e..7c9e77e 100644
--- a/src/com/android/launcher3/FastBitmapDrawable.java
+++ b/src/com/android/launcher3/FastBitmapDrawable.java
@@ -16,30 +16,62 @@
package com.android.launcher3;
+import android.animation.ObjectAnimator;
+import android.animation.TimeInterpolator;
import android.graphics.Bitmap;
import android.graphics.Canvas;
+import android.graphics.Color;
import android.graphics.ColorFilter;
import android.graphics.ColorMatrix;
import android.graphics.ColorMatrixColorFilter;
import android.graphics.Paint;
import android.graphics.PixelFormat;
+import android.graphics.PorterDuff;
+import android.graphics.PorterDuffColorFilter;
import android.graphics.Rect;
import android.graphics.drawable.Drawable;
+import android.util.SparseArray;
class FastBitmapDrawable extends Drawable {
+ static final TimeInterpolator CLICK_FEEDBACK_INTERPOLATOR = new TimeInterpolator() {
+
+ @Override
+ public float getInterpolation(float input) {
+ if (input < 0.05f) {
+ return input / 0.05f;
+ } else if (input < 0.3f){
+ return 1;
+ } else {
+ return (1 - input) / 0.7f;
+ }
+ }
+ };
+ static final long CLICK_FEEDBACK_DURATION = 2000;
+
+ private static final int PRESSED_BRIGHTNESS = 100;
private static ColorMatrix sGhostModeMatrix;
private static final ColorMatrix sTempMatrix = new ColorMatrix();
+ /**
+ * Store the brightness colors filters to optimize animations during icon press. This
+ * only works for non-ghost-mode icons.
+ */
+ private static final SparseArray<ColorFilter> sCachedBrightnessFilter =
+ new SparseArray<ColorFilter>();
+
private static final int GHOST_MODE_MIN_COLOR_RANGE = 130;
private final Paint mPaint = new Paint(Paint.FILTER_BITMAP_FLAG);
- private Bitmap mBitmap;
+ private final Bitmap mBitmap;
private int mAlpha;
private int mBrightness = 0;
private boolean mGhostModeEnabled = false;
+ private boolean mPressed = false;
+ private ObjectAnimator mPressedAnimator;
+
FastBitmapDrawable(Bitmap b) {
mAlpha = 255;
mBitmap = b;
@@ -114,6 +146,23 @@
}
}
+ public void setPressed(boolean pressed) {
+ if (mPressed != pressed) {
+ mPressed = pressed;
+ if (mPressed) {
+ mPressedAnimator = ObjectAnimator
+ .ofInt(this, "brightness", PRESSED_BRIGHTNESS)
+ .setDuration(CLICK_FEEDBACK_DURATION);
+ mPressedAnimator.setInterpolator(CLICK_FEEDBACK_INTERPOLATOR);
+ mPressedAnimator.start();
+ } else if (mPressedAnimator != null) {
+ mPressedAnimator.cancel();
+ setBrightness(0);
+ }
+ }
+ invalidateSelf();
+ }
+
public boolean isGhostModeEnabled() {
return mGhostModeEnabled;
}
@@ -122,14 +171,11 @@
return mBrightness;
}
- public void addBrightness(int amount) {
- setBrightness(mBrightness + amount);
- }
-
public void setBrightness(int brightness) {
if (mBrightness != brightness) {
mBrightness = brightness;
updateFilter();
+ invalidateSelf();
}
}
@@ -157,8 +203,13 @@
mPaint.setColorFilter(new ColorMatrixColorFilter(sTempMatrix));
}
} else if (mBrightness != 0) {
- setBrightnessMatrix(sTempMatrix, mBrightness);
- mPaint.setColorFilter(new ColorMatrixColorFilter(sTempMatrix));
+ ColorFilter filter = sCachedBrightnessFilter.get(mBrightness);
+ if (filter == null) {
+ filter = new PorterDuffColorFilter(Color.argb(mBrightness, 255, 255, 255),
+ PorterDuff.Mode.SRC_ATOP);
+ sCachedBrightnessFilter.put(mBrightness, filter);
+ }
+ mPaint.setColorFilter(filter);
} else {
mPaint.setColorFilter(null);
}
diff --git a/src/com/android/launcher3/FastBitmapView.java b/src/com/android/launcher3/FastBitmapView.java
new file mode 100644
index 0000000..0937eb7
--- /dev/null
+++ b/src/com/android/launcher3/FastBitmapView.java
@@ -0,0 +1,58 @@
+/*
+ * Copyright (C) 2014 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.launcher3;
+
+import android.content.Context;
+import android.graphics.Bitmap;
+import android.graphics.Canvas;
+import android.graphics.Paint;
+import android.view.View;
+
+public class FastBitmapView extends View {
+
+ private final Paint mPaint = new Paint(Paint.FILTER_BITMAP_FLAG);
+ private Bitmap mBitmap;
+
+ public FastBitmapView(Context context) {
+ super(context);
+ }
+
+ /**
+ * Applies the new bitmap.
+ * @return true if the view was invalidated.
+ */
+ public boolean setBitmap(Bitmap b) {
+ if (b != mBitmap){
+ if (mBitmap != null) {
+ invalidate(0, 0, mBitmap.getWidth(), mBitmap.getHeight());
+ }
+ mBitmap = b;
+ if (mBitmap != null) {
+ invalidate(0, 0, mBitmap.getWidth(), mBitmap.getHeight());
+ }
+ return true;
+ }
+ return false;
+ }
+
+ @Override
+ protected void onDraw(Canvas canvas) {
+ if (mBitmap != null) {
+ canvas.drawBitmap(mBitmap, 0, 0, mPaint);
+ }
+ }
+}
diff --git a/src/com/android/launcher3/FocusHelper.java b/src/com/android/launcher3/FocusHelper.java
index df5e0fc..34e752b 100644
--- a/src/com/android/launcher3/FocusHelper.java
+++ b/src/com/android/launcher3/FocusHelper.java
@@ -22,8 +22,6 @@
import android.view.ViewGroup;
import android.view.ViewParent;
import android.widget.ScrollView;
-import android.widget.TabHost;
-import android.widget.TabWidget;
import java.util.ArrayList;
import java.util.Collections;
@@ -89,7 +87,6 @@
final PagedViewGridLayout parent = (PagedViewGridLayout) w.getParent();
final PagedView container = (PagedView) parent.getParent();
- final AppsCustomizeTabHost tabHost = findTabHostParent(container);
final int widgetIndex = parent.indexOfChild(w);
final int widgetCount = parent.getChildCount();
final int pageIndex = ((PagedView) container).indexToPage(container.indexOfChild(parent));
@@ -228,6 +225,13 @@
* Handles key events in a PageViewCellLayout containing PagedViewIcons.
*/
static boolean handleAppsCustomizeKeyEvent(View v, int keyCode, KeyEvent e) {
+ final int action = e.getAction();
+ if (((action == KeyEvent.ACTION_DOWN) && v.onKeyDown(keyCode, e))
+ || ((action == KeyEvent.ACTION_UP) && v.onKeyUp(keyCode, e))) {
+ // Let the view handle the confirmation key.
+ return true;
+ }
+
ViewGroup parentLayout;
ViewGroup itemContainer;
int countX;
@@ -246,7 +250,6 @@
// Note we have an extra parent because of the
// PagedViewCellLayout/PagedViewCellLayoutChildren relationship
final PagedView container = (PagedView) parentLayout.getParent();
- final AppsCustomizeTabHost tabHost = findTabHostParent(container);
final int iconIndex = itemContainer.indexOfChild(v);
final int itemCount = itemContainer.getChildCount();
final int pageIndex = ((PagedView) container).indexToPage(container.indexOfChild(parentLayout));
@@ -255,7 +258,6 @@
final int x = iconIndex % countX;
final int y = iconIndex / countX;
- final int action = e.getAction();
final boolean handleKeyEvent = (action != KeyEvent.ACTION_UP);
ViewGroup newParent = null;
// Side pages do not always load synchronously, so check before focusing child siblings
@@ -319,15 +321,6 @@
}
wasHandled = true;
break;
- case KeyEvent.KEYCODE_ENTER:
- case KeyEvent.KEYCODE_DPAD_CENTER:
- if (handleKeyEvent) {
- // Simulate a click on the icon
- View.OnClickListener clickListener = (View.OnClickListener) container;
- clickListener.onClick(v);
- }
- wasHandled = true;
- break;
case KeyEvent.KEYCODE_PAGE_UP:
if (handleKeyEvent) {
// Select the first icon on the previous page, or the first icon on this page
diff --git a/src/com/android/launcher3/Folder.java b/src/com/android/launcher3/Folder.java
index c548a6f..f26f87c 100644
--- a/src/com/android/launcher3/Folder.java
+++ b/src/com/android/launcher3/Folder.java
@@ -118,10 +118,6 @@
private FocusIndicatorView mFocusIndicatorHandler;
- private int DRAG_MODE_NONE = 0;
- private int DRAG_MODE_REORDER = 1;
- private int mDragMode = DRAG_MODE_NONE;
-
// We avoid measuring the scroll view with a 0 width or height, as this
// results in CellLayout being measured as UNSPECIFIED, which it does
// not support.
@@ -254,7 +250,6 @@
mLauncher.getLauncherClings().dismissFolderCling(null);
- mLauncher.getWorkspace().onDragStartedWithItem(v);
mLauncher.getWorkspace().beginDragShared(v, this);
mCurrentDragInfo = item;
@@ -783,9 +778,6 @@
mReorderAlarm.setAlarm(REORDER_DELAY);
mPreviousTargetCell[0] = mTargetCell[0];
mPreviousTargetCell[1] = mTargetCell[1];
- mDragMode = DRAG_MODE_REORDER;
- } else {
- mDragMode = DRAG_MODE_NONE;
}
}
}
@@ -841,7 +833,6 @@
mOnExitAlarm.setAlarm(ON_EXIT_CLOSE_DELAY);
}
mReorderAlarm.cancelAlarm();
- mDragMode = DRAG_MODE_NONE;
}
public void onDropCompleted(final View target, final DragObject d,
diff --git a/src/com/android/launcher3/FolderIcon.java b/src/com/android/launcher3/FolderIcon.java
index 21efd71..a359f11 100644
--- a/src/com/android/launcher3/FolderIcon.java
+++ b/src/com/android/launcher3/FolderIcon.java
@@ -583,9 +583,10 @@
d.setBounds(0, 0, mIntrinsicIconSize, mIntrinsicIconSize);
if (d instanceof FastBitmapDrawable) {
FastBitmapDrawable fd = (FastBitmapDrawable) d;
- fd.addBrightness(params.overlayAlpha);
+ int oldBrightness = fd.getBrightness();
+ fd.setBrightness(params.overlayAlpha);
d.draw(canvas);
- fd.addBrightness(-params.overlayAlpha);
+ fd.setBrightness(oldBrightness);
} else {
d.setColorFilter(Color.argb(params.overlayAlpha, 255, 255, 255),
PorterDuff.Mode.SRC_ATOP);
diff --git a/src/com/android/launcher3/HolographicOutlineHelper.java b/src/com/android/launcher3/HolographicOutlineHelper.java
index d7b960a..b1e0e68 100644
--- a/src/com/android/launcher3/HolographicOutlineHelper.java
+++ b/src/com/android/launcher3/HolographicOutlineHelper.java
@@ -20,48 +20,49 @@
import android.graphics.Bitmap;
import android.graphics.BlurMaskFilter;
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.Region.Op;
public class HolographicOutlineHelper {
- private final Paint mHolographicPaint = new Paint();
+
+ private static final Rect sTempRect = new Rect();
+
+ private final Canvas mCanvas = new Canvas();
+ private final Paint mDrawPaint = new Paint();
private final Paint mBlurPaint = new Paint();
private final Paint mErasePaint = new Paint();
- public int mMaxOuterBlurRadius;
- public int mMinOuterBlurRadius;
+ private final BlurMaskFilter mMediumOuterBlurMaskFilter;
+ private final BlurMaskFilter mThinOuterBlurMaskFilter;
+ private final BlurMaskFilter mMediumInnerBlurMaskFilter;
- private BlurMaskFilter mExtraThickOuterBlurMaskFilter;
- private BlurMaskFilter mThickOuterBlurMaskFilter;
- private BlurMaskFilter mMediumOuterBlurMaskFilter;
- private BlurMaskFilter mThinOuterBlurMaskFilter;
- private BlurMaskFilter mThickInnerBlurMaskFilter;
- private BlurMaskFilter mExtraThickInnerBlurMaskFilter;
- private BlurMaskFilter mMediumInnerBlurMaskFilter;
+ private final BlurMaskFilter mShaowBlurMaskFilter;
+ private final int mShadowOffset;
- private static final int THICK = 0;
- private static final int MEDIUM = 1;
- private static final int EXTRA_THICK = 2;
+ /**
+ * Padding used when creating shadow bitmap;
+ */
+ final int shadowBitmapPadding;
static HolographicOutlineHelper INSTANCE;
private HolographicOutlineHelper(Context context) {
final float scale = LauncherAppState.getInstance().getScreenDensity();
- mMinOuterBlurRadius = (int) (scale * 1.0f);
- mMaxOuterBlurRadius = (int) (scale * 12.0f);
-
- mExtraThickOuterBlurMaskFilter = new BlurMaskFilter(scale * 12.0f, BlurMaskFilter.Blur.OUTER);
- mThickOuterBlurMaskFilter = new BlurMaskFilter(scale * 6.0f, BlurMaskFilter.Blur.OUTER);
mMediumOuterBlurMaskFilter = new BlurMaskFilter(scale * 2.0f, BlurMaskFilter.Blur.OUTER);
mThinOuterBlurMaskFilter = new BlurMaskFilter(scale * 1.0f, BlurMaskFilter.Blur.OUTER);
- mExtraThickInnerBlurMaskFilter = new BlurMaskFilter(scale * 6.0f, BlurMaskFilter.Blur.NORMAL);
- mThickInnerBlurMaskFilter = new BlurMaskFilter(scale * 4.0f, BlurMaskFilter.Blur.NORMAL);
mMediumInnerBlurMaskFilter = new BlurMaskFilter(scale * 2.0f, BlurMaskFilter.Blur.NORMAL);
- mHolographicPaint.setFilterBitmap(true);
- mHolographicPaint.setAntiAlias(true);
+ mShaowBlurMaskFilter = new BlurMaskFilter(scale * 4.0f, BlurMaskFilter.Blur.NORMAL);
+ mShadowOffset = (int) (scale * 2.0f);
+ shadowBitmapPadding = (int) (scale * 4.0f);
+
+ mDrawPaint.setFilterBitmap(true);
+ mDrawPaint.setAntiAlias(true);
mBlurPaint.setFilterBitmap(true);
mBlurPaint.setAntiAlias(true);
mErasePaint.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.DST_OUT));
@@ -77,37 +78,15 @@
}
/**
- * Returns the interpolated holographic highlight alpha for the effect we want when scrolling
- * pages.
- */
- public static float highlightAlphaInterpolator(float r) {
- float maxAlpha = 0.6f;
- return (float) Math.pow(maxAlpha * (1.0f - r), 1.5f);
- }
-
- /**
- * Returns the interpolated view alpha for the effect we want when scrolling pages.
- */
- public static float viewAlphaInterpolator(float r) {
- final float pivot = 0.95f;
- if (r < pivot) {
- return (float) Math.pow(r / pivot, 1.5f);
- } else {
- return 1.0f;
- }
- }
-
- /**
* Applies a more expensive and accurate outline to whatever is currently drawn in a specified
* bitmap.
*/
void applyExpensiveOutlineWithBlur(Bitmap srcDst, Canvas srcDstCanvas, int color,
- int outlineColor, int thickness) {
- applyExpensiveOutlineWithBlur(srcDst, srcDstCanvas, color, outlineColor, true,
- thickness);
+ int outlineColor) {
+ applyExpensiveOutlineWithBlur(srcDst, srcDstCanvas, color, outlineColor, true);
}
void applyExpensiveOutlineWithBlur(Bitmap srcDst, Canvas srcDstCanvas, int color,
- int outlineColor, boolean clipAlpha, int thickness) {
+ int outlineColor, boolean clipAlpha) {
// We start by removing most of the alpha channel so as to ignore shadows, and
// other types of partial transparency when defining the shape of the object
@@ -127,50 +106,18 @@
Bitmap glowShape = srcDst.extractAlpha();
// calculate the outer blur first
- BlurMaskFilter outerBlurMaskFilter;
- switch (thickness) {
- case EXTRA_THICK:
- outerBlurMaskFilter = mExtraThickOuterBlurMaskFilter;
- break;
- case THICK:
- outerBlurMaskFilter = mThickOuterBlurMaskFilter;
- break;
- case MEDIUM:
- outerBlurMaskFilter = mMediumOuterBlurMaskFilter;
- break;
- default:
- throw new RuntimeException("Invalid blur thickness");
- }
- mBlurPaint.setMaskFilter(outerBlurMaskFilter);
+ mBlurPaint.setMaskFilter(mMediumOuterBlurMaskFilter);
int[] outerBlurOffset = new int[2];
Bitmap thickOuterBlur = glowShape.extractAlpha(mBlurPaint, outerBlurOffset);
- if (thickness == EXTRA_THICK) {
- mBlurPaint.setMaskFilter(mMediumOuterBlurMaskFilter);
- } else {
- mBlurPaint.setMaskFilter(mThinOuterBlurMaskFilter);
- }
+ mBlurPaint.setMaskFilter(mThinOuterBlurMaskFilter);
int[] brightOutlineOffset = new int[2];
Bitmap brightOutline = glowShape.extractAlpha(mBlurPaint, brightOutlineOffset);
// calculate the inner blur
srcDstCanvas.setBitmap(glowShape);
srcDstCanvas.drawColor(0xFF000000, PorterDuff.Mode.SRC_OUT);
- BlurMaskFilter innerBlurMaskFilter;
- switch (thickness) {
- case EXTRA_THICK:
- innerBlurMaskFilter = mExtraThickInnerBlurMaskFilter;
- break;
- case THICK:
- innerBlurMaskFilter = mThickInnerBlurMaskFilter;
- break;
- case MEDIUM:
- innerBlurMaskFilter = mMediumInnerBlurMaskFilter;
- break;
- default:
- throw new RuntimeException("Invalid blur thickness");
- }
- mBlurPaint.setMaskFilter(innerBlurMaskFilter);
+ mBlurPaint.setMaskFilter(mMediumInnerBlurMaskFilter);
int[] thickInnerBlurOffset = new int[2];
Bitmap thickInnerBlur = glowShape.extractAlpha(mBlurPaint, thickInnerBlurOffset);
@@ -186,16 +133,16 @@
// draw the inner and outer blur
srcDstCanvas.setBitmap(srcDst);
srcDstCanvas.drawColor(0, PorterDuff.Mode.CLEAR);
- mHolographicPaint.setColor(color);
+ mDrawPaint.setColor(color);
srcDstCanvas.drawBitmap(thickInnerBlur, thickInnerBlurOffset[0], thickInnerBlurOffset[1],
- mHolographicPaint);
+ mDrawPaint);
srcDstCanvas.drawBitmap(thickOuterBlur, outerBlurOffset[0], outerBlurOffset[1],
- mHolographicPaint);
+ mDrawPaint);
// draw the bright outline
- mHolographicPaint.setColor(outlineColor);
+ mDrawPaint.setColor(outlineColor);
srcDstCanvas.drawBitmap(brightOutline, brightOutlineOffset[0], brightOutlineOffset[1],
- mHolographicPaint);
+ mDrawPaint);
// cleanup
srcDstCanvas.setBitmap(null);
@@ -205,25 +152,52 @@
glowShape.recycle();
}
- void applyExtraThickExpensiveOutlineWithBlur(Bitmap srcDst, Canvas srcDstCanvas, int color,
- int outlineColor) {
- applyExpensiveOutlineWithBlur(srcDst, srcDstCanvas, color, outlineColor, EXTRA_THICK);
- }
+ Bitmap createMediumDropShadow(BubbleTextView view) {
+ final Bitmap result = Bitmap.createBitmap(
+ view.getWidth() + shadowBitmapPadding + shadowBitmapPadding,
+ view.getHeight() + shadowBitmapPadding + shadowBitmapPadding + mShadowOffset,
+ Bitmap.Config.ARGB_8888);
- void applyThickExpensiveOutlineWithBlur(Bitmap srcDst, Canvas srcDstCanvas, int color,
- int outlineColor) {
- applyExpensiveOutlineWithBlur(srcDst, srcDstCanvas, color, outlineColor, THICK);
- }
+ mCanvas.setBitmap(result);
- void applyMediumExpensiveOutlineWithBlur(Bitmap srcDst, Canvas srcDstCanvas, int color,
- int outlineColor, boolean clipAlpha) {
- applyExpensiveOutlineWithBlur(srcDst, srcDstCanvas, color, outlineColor, clipAlpha,
- MEDIUM);
- }
+ final Rect clipRect = sTempRect;
+ view.getDrawingRect(sTempRect);
+ // adjust the clip rect so that we don't include the text label
+ clipRect.bottom = view.getExtendedPaddingTop() - (int) BubbleTextView.PADDING_V
+ + view.getLayout().getLineTop(0);
- void applyMediumExpensiveOutlineWithBlur(Bitmap srcDst, Canvas srcDstCanvas, int color,
- int outlineColor) {
- applyExpensiveOutlineWithBlur(srcDst, srcDstCanvas, color, outlineColor, MEDIUM);
- }
+ // Draw the View into the bitmap.
+ // The translate of scrollX and scrollY is necessary when drawing TextViews, because
+ // they set scrollX and scrollY to large values to achieve centered text
+ mCanvas.save();
+ mCanvas.scale(view.getScaleX(), view.getScaleY(),
+ view.getWidth() / 2 + shadowBitmapPadding,
+ view.getHeight() / 2 + shadowBitmapPadding);
+ mCanvas.translate(-view.getScrollX() + shadowBitmapPadding,
+ -view.getScrollY() + shadowBitmapPadding);
+ mCanvas.clipRect(clipRect, Op.REPLACE);
+ view.draw(mCanvas);
+ mCanvas.restore();
+ int[] blurOffst = new int[2];
+ mBlurPaint.setMaskFilter(mShaowBlurMaskFilter);
+ Bitmap blurBitmap = result.extractAlpha(mBlurPaint, blurOffst);
+
+ mCanvas.save();
+ mCanvas.drawColor(Color.TRANSPARENT, PorterDuff.Mode.CLEAR);
+ mCanvas.translate(blurOffst[0], blurOffst[1]);
+
+ mDrawPaint.setColor(Color.BLACK);
+ mDrawPaint.setAlpha(30);
+ mCanvas.drawBitmap(blurBitmap, 0, 0, mDrawPaint);
+
+ mDrawPaint.setAlpha(60);
+ mCanvas.drawBitmap(blurBitmap, 0, mShadowOffset, mDrawPaint);
+ mCanvas.restore();
+
+ mCanvas.setBitmap(null);
+ blurBitmap.recycle();
+
+ return result;
+ }
}
diff --git a/src/com/android/launcher3/IconCache.java b/src/com/android/launcher3/IconCache.java
index 06b7775..76a85ca 100644
--- a/src/com/android/launcher3/IconCache.java
+++ b/src/com/android/launcher3/IconCache.java
@@ -146,6 +146,10 @@
return getFullResDefaultActivityIcon();
}
+ public int getFullResIconDpi() {
+ return mIconDpi;
+ }
+
public Drawable getFullResIcon(ResolveInfo info) {
return getFullResIcon(info.activityInfo);
}
diff --git a/src/com/android/launcher3/Launcher.java b/src/com/android/launcher3/Launcher.java
index 88a60d0..5d9ff1d 100644
--- a/src/com/android/launcher3/Launcher.java
+++ b/src/com/android/launcher3/Launcher.java
@@ -82,7 +82,6 @@
import android.view.View;
import android.view.View.OnClickListener;
import android.view.View.OnLongClickListener;
-import android.view.ViewAnimationUtils;
import android.view.ViewGroup;
import android.view.ViewTreeObserver;
import android.view.ViewTreeObserver.OnGlobalLayoutListener;
@@ -100,6 +99,7 @@
import com.android.launcher3.DropTarget.DragObject;
import com.android.launcher3.PagedView.PageSwitchListener;
+import com.android.launcher3.compat.AppWidgetManagerCompat;
import com.android.launcher3.compat.LauncherActivityInfoCompat;
import com.android.launcher3.compat.LauncherAppsCompat;
import com.android.launcher3.compat.PackageInstallerCompat;
@@ -258,7 +258,7 @@
private View mWeightWatcher;
private LauncherClings mLauncherClings;
- private AppWidgetManager mAppWidgetManager;
+ private AppWidgetManagerCompat mAppWidgetManager;
private LauncherAppWidgetHost mAppWidgetHost;
private ItemInfo mPendingAddInfo = new ItemInfo();
@@ -439,7 +439,7 @@
mStats = new Stats(this);
- mAppWidgetManager = AppWidgetManager.getInstance(this);
+ mAppWidgetManager = AppWidgetManagerCompat.getInstance(this);
mAppWidgetHost = new LauncherAppWidgetHost(this, APPWIDGET_HOST_ID);
mAppWidgetHost.startListening();
@@ -1026,10 +1026,6 @@
// Resets the previous workspace icon press state
mWaitingForResume.setStayPressed(false);
}
- if (mAppsCustomizeContent != null) {
- // Resets the previous all apps icon press state
- mAppsCustomizeContent.resetDrawableState();
- }
// It is possible that widgets can receive updates while launcher is not in the foreground.
// Consequently, the widgets will be inflated in the orientation of the foreground activity
@@ -1574,6 +1570,7 @@
launcherInfo.spanY = spanXY[1];
launcherInfo.minSpanX = mPendingAddInfo.minSpanX;
launcherInfo.minSpanY = mPendingAddInfo.minSpanY;
+ launcherInfo.user = mAppWidgetManager.getUser(appWidgetInfo);
LauncherModel.addItemToDatabase(this, launcherInfo,
container, screenId, cellXY[0], cellXY[1], false);
@@ -2199,10 +2196,9 @@
mPendingAddWidgetId = appWidgetId;
// Launch over to configure widget, if needed
- Intent intent = new Intent(AppWidgetManager.ACTION_APPWIDGET_CONFIGURE);
- intent.setComponent(appWidgetInfo.configure);
- intent.putExtra(AppWidgetManager.EXTRA_APPWIDGET_ID, appWidgetId);
- Utilities.startActivityForResultSafely(this, intent, REQUEST_CREATE_APPWIDGET);
+ mAppWidgetManager.startConfigActivity(appWidgetInfo, appWidgetId, this,
+ mAppWidgetHost, REQUEST_CREATE_APPWIDGET);
+
} else {
// Otherwise just add it
Runnable onComplete = new Runnable() {
@@ -2286,14 +2282,8 @@
appWidgetId = getAppWidgetHost().allocateAppWidgetId();
Bundle options = info.bindOptions;
- boolean success = false;
- if (options != null) {
- success = mAppWidgetManager.bindAppWidgetIdIfAllowed(appWidgetId,
- info.componentName, options);
- } else {
- success = mAppWidgetManager.bindAppWidgetIdIfAllowed(appWidgetId,
- info.componentName);
- }
+ boolean success = mAppWidgetManager.bindAppWidgetIdIfAllowed(
+ appWidgetId, info.info, options);
if (success) {
addAppWidgetImpl(appWidgetId, info, null, info.info);
} else {
@@ -2301,6 +2291,8 @@
Intent intent = new Intent(AppWidgetManager.ACTION_APPWIDGET_BIND);
intent.putExtra(AppWidgetManager.EXTRA_APPWIDGET_ID, appWidgetId);
intent.putExtra(AppWidgetManager.EXTRA_APPWIDGET_PROVIDER, info.componentName);
+ mAppWidgetManager.getUser(mPendingAddWidgetInfo)
+ .addToIntent(intent, AppWidgetManager.EXTRA_APPWIDGET_PROVIDER_PROFILE);
// TODO: we need to make sure that this accounts for the options bundle.
// intent.putExtra(AppWidgetManager.EXTRA_APPWIDGET_OPTIONS, options);
startActivityForResult(intent, REQUEST_BIND_APPWIDGET);
@@ -2451,6 +2443,8 @@
}
} else if (v == mAllAppsButton) {
onClickAllAppsButton(v);
+ } else if (tag instanceof AppInfo) {
+ startAppShortcutOrInfoActivity(v);
} else if (tag instanceof LauncherAppWidgetInfo) {
if (v instanceof PendingAppWidgetHostView) {
onClickPendingWidget((PendingAppWidgetHostView) v);
@@ -2458,6 +2452,10 @@
}
}
+ public void onClickPagedViewIcon(View v) {
+ startAppShortcutOrInfoActivity(v);
+ }
+
public boolean onTouch(View v, MotionEvent event) {
return false;
}
@@ -2475,10 +2473,8 @@
mPendingAddInfo.copyFrom(info);
mPendingAddWidgetId = widgetId;
- Intent intent = new Intent(AppWidgetManager.ACTION_APPWIDGET_CONFIGURE);
- intent.setComponent(appWidgetInfo.configure);
- intent.putExtra(AppWidgetManager.EXTRA_APPWIDGET_ID, info.appWidgetId);
- Utilities.startActivityForResultSafely(this, intent, REQUEST_RECONFIGURE_APPWIDGET);
+ AppWidgetManagerCompat.getInstance(this).startConfigActivity(appWidgetInfo,
+ info.appWidgetId, this, mAppWidgetHost, REQUEST_RECONFIGURE_APPWIDGET);
}
}
}
@@ -2539,17 +2535,6 @@
}
/**
- * Event handler for a paged view icon click.
- * @param v The view that was clicked.
- * @param appInfo The {link AppInfo} of the view.
- */
- public void onClickPagedViewIcon(View v, AppInfo appInfo) {
- if (LOGD) Log.d(TAG, "onClickPagedViewIcon");
- startActivitySafely(v, appInfo.intent, appInfo);
- getStats().recordLaunch(appInfo.intent);
- }
-
- /**
* Event handler for an app shortcut click.
*
* @param v The view that was clicked. Must be a tagged with a {@link ShortcutInfo}.
@@ -2586,7 +2571,7 @@
builder.setPositiveButton(R.string.abandoned_search,
new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int id) {
- startAppShortcutActivity(v);
+ startAppShortcutOrInfoActivity(v);
}
}
);
@@ -2603,24 +2588,29 @@
}
// Start activities
- startAppShortcutActivity(v);
+ startAppShortcutOrInfoActivity(v);
}
- private void startAppShortcutActivity(View v) {
+ private void startAppShortcutOrInfoActivity(View v) {
Object tag = v.getTag();
- if (!(tag instanceof ShortcutInfo)) {
- throw new IllegalArgumentException("Input must be a Shortcut");
- }
- final ShortcutInfo shortcut = (ShortcutInfo) tag;
- final Intent intent = shortcut.intent;
+ final ShortcutInfo shortcut;
+ final Intent intent;
+ if (tag instanceof ShortcutInfo) {
+ shortcut = (ShortcutInfo) tag;
+ intent = shortcut.intent;
+ int[] pos = new int[2];
+ v.getLocationOnScreen(pos);
+ intent.setSourceBounds(new Rect(pos[0], pos[1],
+ pos[0] + v.getWidth(), pos[1] + v.getHeight()));
- int[] pos = new int[2];
- v.getLocationOnScreen(pos);
- intent.setSourceBounds(new Rect(pos[0], pos[1],
- pos[0] + v.getWidth(), pos[1] + v.getHeight()));
+ } else if (tag instanceof AppInfo) {
+ shortcut = null;
+ intent = ((AppInfo) tag).intent;
+ } else {
+ throw new IllegalArgumentException("Input must be a Shortcut or AppInfo");
+ }
boolean success = startActivitySafely(v, intent, tag);
-
mStats.recordLaunch(intent, shortcut);
if (success && v instanceof BubbleTextView) {
@@ -4383,15 +4373,9 @@
Bundle options =
AppsCustomizePagedView.getDefaultOptionsForWidget(this, pendingInfo);
- boolean success = false;
int newWidgetId = mAppWidgetHost.allocateAppWidgetId();
- if (options != null) {
- success = mAppWidgetManager.bindAppWidgetIdIfAllowed(newWidgetId,
- appWidgetInfo.provider, options);
- } else {
- success = mAppWidgetManager.bindAppWidgetIdIfAllowed(newWidgetId,
- appWidgetInfo.provider);
- }
+ boolean success = mAppWidgetManager.bindAppWidgetIdIfAllowed(
+ newWidgetId, appWidgetInfo, options);
// TODO consider showing a permission dialog when the widget is clicked.
if (!success) {
diff --git a/src/com/android/launcher3/LauncherBackupHelper.java b/src/com/android/launcher3/LauncherBackupHelper.java
index 64e82c7..1ea562b 100644
--- a/src/com/android/launcher3/LauncherBackupHelper.java
+++ b/src/com/android/launcher3/LauncherBackupHelper.java
@@ -299,36 +299,26 @@
Set<String> savedIds = getSavedIdsByType(Key.FAVORITE, in);
if (DEBUG) Log.d(TAG, "favorite savedIds.size()=" + savedIds.size());
- // Don't backup apps in other profiles for now.
- UserHandleCompat myUserHandle = UserHandleCompat.myUserHandle();
- long userSerialNumber =
- UserManagerCompat.getInstance(mContext).getSerialNumberForUser(myUserHandle);
-
// persist things that have changed since the last backup
ContentResolver cr = mContext.getContentResolver();
+ // Don't backup apps in other profiles for now.
Cursor cursor = cr.query(Favorites.CONTENT_URI, FAVORITE_PROJECTION,
- null, null, null);
+ getUserSelectionArg(), null, null);
Set<String> currentIds = new HashSet<String>(cursor.getCount());
try {
cursor.moveToPosition(-1);
while(cursor.moveToNext()) {
final long id = cursor.getLong(ID_INDEX);
- final long profileId = cursor.getLong(PROFILE_ID_INDEX);
- if (userSerialNumber == profileId) {
- final long updateTime = cursor.getLong(ID_MODIFIED);
- Key key = getKey(Key.FAVORITE, id);
- keys.add(key);
- final String backupKey = keyToBackupKey(key);
- currentIds.add(backupKey);
- if (!savedIds.contains(backupKey) || updateTime >= in.t) {
- byte[] blob = packFavorite(cursor);
- writeRowToBackup(key, blob, out, data);
- } else {
- if (VERBOSE) Log.v(TAG, "favorite " + id + " was too old: " + updateTime);
- }
+ final long updateTime = cursor.getLong(ID_MODIFIED);
+ Key key = getKey(Key.FAVORITE, id);
+ keys.add(key);
+ final String backupKey = keyToBackupKey(key);
+ currentIds.add(backupKey);
+ if (!savedIds.contains(backupKey) || updateTime >= in.t) {
+ byte[] blob = packFavorite(cursor);
+ writeRowToBackup(key, blob, out, data);
} else {
- if (VERBOSE) Log.v(TAG, "favorite " + id + " is for other profile: "
- + profileId);
+ if (VERBOSE) Log.v(TAG, "favorite " + id + " was too old: " + updateTime);
}
}
} finally {
@@ -469,20 +459,19 @@
}
final ContentResolver cr = mContext.getContentResolver();
final int dpi = mContext.getResources().getDisplayMetrics().densityDpi;
+ final UserHandleCompat myUserHandle = UserHandleCompat.myUserHandle();
// read the old ID set
Set<String> savedIds = getSavedIdsByType(Key.ICON, in);
if (DEBUG) Log.d(TAG, "icon savedIds.size()=" + savedIds.size());
// Don't backup apps in other profiles for now.
- UserHandleCompat myUserHandle = UserHandleCompat.myUserHandle();
- long userSerialNumber =
- UserManagerCompat.getInstance(mContext).getSerialNumberForUser(myUserHandle);
int startRows = out.rows;
if (DEBUG) Log.d(TAG, "starting here: " + startRows);
+
String where = "(" + Favorites.ITEM_TYPE + "=" + Favorites.ITEM_TYPE_APPLICATION + " OR " +
Favorites.ITEM_TYPE + "=" + Favorites.ITEM_TYPE_SHORTCUT + ") AND " +
- Favorites.PROFILE_ID + "=" + userSerialNumber;
+ getUserSelectionArg();
Cursor cursor = cr.query(Favorites.CONTENT_URI, FAVORITE_PROJECTION,
where, null, null);
Set<String> currentIds = new HashSet<String>(cursor.getCount());
@@ -617,7 +606,8 @@
int startRows = out.rows;
if (DEBUG) Log.d(TAG, "starting here: " + startRows);
- String where = Favorites.ITEM_TYPE + "=" + Favorites.ITEM_TYPE_APPWIDGET;
+ String where = Favorites.ITEM_TYPE + "=" + Favorites.ITEM_TYPE_APPWIDGET + " AND "
+ + getUserSelectionArg();
Cursor cursor = cr.query(Favorites.CONTENT_URI, FAVORITE_PROJECTION,
where, null, null);
Set<String> currentIds = new HashSet<String>(cursor.getCount());
@@ -1192,6 +1182,11 @@
return true;
}
+ private String getUserSelectionArg() {
+ return Favorites.PROFILE_ID + '=' + UserManagerCompat.getInstance(mContext)
+ .getSerialNumberForUser(UserHandleCompat.myUserHandle());
+ }
+
private class KeyParsingException extends Throwable {
private KeyParsingException(Throwable cause) {
super(cause);
diff --git a/src/com/android/launcher3/LauncherModel.java b/src/com/android/launcher3/LauncherModel.java
index 4c9d1a7..bcb4501 100644
--- a/src/com/android/launcher3/LauncherModel.java
+++ b/src/com/android/launcher3/LauncherModel.java
@@ -30,7 +30,6 @@
import android.content.Intent.ShortcutIconResource;
import android.content.IntentFilter;
import android.content.SharedPreferences;
-import android.content.pm.ActivityInfo;
import android.content.pm.PackageManager;
import android.content.pm.ProviderInfo;
import android.content.pm.ResolveInfo;
@@ -52,7 +51,7 @@
import android.util.Log;
import android.util.Pair;
-import com.android.launcher3.InstallWidgetReceiver.WidgetMimeTypeHandlerData;
+import com.android.launcher3.compat.AppWidgetManagerCompat;
import com.android.launcher3.compat.LauncherActivityInfoCompat;
import com.android.launcher3.compat.LauncherAppsCompat;
import com.android.launcher3.compat.PackageInstallerCompat.PackageInstallInfo;
@@ -3040,11 +3039,11 @@
public static ArrayList<Object> getSortedWidgetsAndShortcuts(Context context) {
PackageManager packageManager = context.getPackageManager();
final ArrayList<Object> widgetsAndShortcuts = new ArrayList<Object>();
- widgetsAndShortcuts.addAll(AppWidgetManager.getInstance(context).getInstalledProviders());
+ widgetsAndShortcuts.addAll(AppWidgetManagerCompat.getInstance(context).getAllProviders());
+
Intent shortcutsIntent = new Intent(Intent.ACTION_CREATE_SHORTCUT);
widgetsAndShortcuts.addAll(packageManager.queryIntentActivities(shortcutsIntent, 0));
- Collections.sort(widgetsAndShortcuts,
- new LauncherModel.WidgetAndShortcutNameComparator(packageManager));
+ Collections.sort(widgetsAndShortcuts, new WidgetAndShortcutNameComparator(context));
return widgetsAndShortcuts;
}
@@ -3390,44 +3389,6 @@
return null;
}
- /**
- * Returns a list of all the widgets that can handle configuration with a particular mimeType.
- */
- List<WidgetMimeTypeHandlerData> resolveWidgetsForMimeType(Context context, String mimeType) {
- final PackageManager packageManager = context.getPackageManager();
- final List<WidgetMimeTypeHandlerData> supportedConfigurationActivities =
- new ArrayList<WidgetMimeTypeHandlerData>();
-
- final Intent supportsIntent =
- new Intent(InstallWidgetReceiver.ACTION_SUPPORTS_CLIPDATA_MIMETYPE);
- supportsIntent.setType(mimeType);
-
- // Create a set of widget configuration components that we can test against
- final List<AppWidgetProviderInfo> widgets =
- AppWidgetManager.getInstance(context).getInstalledProviders();
- final HashMap<ComponentName, AppWidgetProviderInfo> configurationComponentToWidget =
- new HashMap<ComponentName, AppWidgetProviderInfo>();
- for (AppWidgetProviderInfo info : widgets) {
- configurationComponentToWidget.put(info.configure, info);
- }
-
- // Run through each of the intents that can handle this type of clip data, and cross
- // reference them with the components that are actual configuration components
- final List<ResolveInfo> activities = packageManager.queryIntentActivities(supportsIntent,
- PackageManager.MATCH_DEFAULT_ONLY);
- for (ResolveInfo info : activities) {
- final ActivityInfo activityInfo = info.activityInfo;
- final ComponentName infoComponent = new ComponentName(activityInfo.packageName,
- activityInfo.name);
- if (configurationComponentToWidget.containsKey(infoComponent)) {
- supportedConfigurationActivities.add(
- new InstallWidgetReceiver.WidgetMimeTypeHandlerData(info,
- configurationComponentToWidget.get(infoComponent)));
- }
- }
- return supportedConfigurationActivities;
- }
-
ShortcutInfo infoFromShortcutIntent(Context context, Intent data, Bitmap fallbackIcon) {
Intent intent = data.getParcelableExtra(Intent.EXTRA_SHORTCUT_INTENT);
String name = data.getStringExtra(Intent.EXTRA_SHORTCUT_NAME);
@@ -3570,14 +3531,6 @@
return 0;
}
};
- public static final Comparator<AppWidgetProviderInfo> getWidgetNameComparator() {
- final Collator collator = Collator.getInstance();
- return new Comparator<AppWidgetProviderInfo>() {
- public final int compare(AppWidgetProviderInfo a, AppWidgetProviderInfo b) {
- return collator.compare(a.label.toString().trim(), b.label.toString().trim());
- }
- };
- }
static ComponentName getComponentNameFromResolveInfo(ResolveInfo info) {
if (info.activityInfo != null) {
return new ComponentName(info.activityInfo.packageName, info.activityInfo.name);
@@ -3618,11 +3571,14 @@
}
};
public static class WidgetAndShortcutNameComparator implements Comparator<Object> {
- private Collator mCollator;
- private PackageManager mPackageManager;
- private HashMap<Object, String> mLabelCache;
- WidgetAndShortcutNameComparator(PackageManager pm) {
- mPackageManager = pm;
+ private final AppWidgetManagerCompat mManager;
+ private final PackageManager mPackageManager;
+ private final HashMap<Object, String> mLabelCache;
+ private final Collator mCollator;
+
+ WidgetAndShortcutNameComparator(Context context) {
+ mManager = AppWidgetManagerCompat.getInstance(context);
+ mPackageManager = context.getPackageManager();
mLabelCache = new HashMap<Object, String>();
mCollator = Collator.getInstance();
}
@@ -3631,17 +3587,17 @@
if (mLabelCache.containsKey(a)) {
labelA = mLabelCache.get(a);
} else {
- labelA = (a instanceof AppWidgetProviderInfo) ?
- ((AppWidgetProviderInfo) a).label :
- ((ResolveInfo) a).loadLabel(mPackageManager).toString().trim();
+ labelA = (a instanceof AppWidgetProviderInfo)
+ ? mManager.loadLabel((AppWidgetProviderInfo) a)
+ : ((ResolveInfo) a).loadLabel(mPackageManager).toString().trim();
mLabelCache.put(a, labelA);
}
if (mLabelCache.containsKey(b)) {
labelB = mLabelCache.get(b);
} else {
- labelB = (b instanceof AppWidgetProviderInfo) ?
- ((AppWidgetProviderInfo) b).label :
- ((ResolveInfo) b).loadLabel(mPackageManager).toString().trim();
+ labelB = (b instanceof AppWidgetProviderInfo)
+ ? mManager.loadLabel((AppWidgetProviderInfo) b)
+ : ((ResolveInfo) b).loadLabel(mPackageManager).toString().trim();
mLabelCache.put(b, labelB);
}
return mCollator.compare(labelA, labelB);
diff --git a/src/com/android/launcher3/LauncherProvider.java b/src/com/android/launcher3/LauncherProvider.java
index af65536..842e0b0 100644
--- a/src/com/android/launcher3/LauncherProvider.java
+++ b/src/com/android/launcher3/LauncherProvider.java
@@ -1650,8 +1650,10 @@
resolved = systemApp;
}
final ActivityInfo info = resolved.activityInfo;
- final Intent intent = buildMainIntent();
- intent.setComponent(new ComponentName(info.packageName, info.name));
+ final Intent intent = mPackageManager.getLaunchIntentForPackage(info.packageName);
+ if (intent == null) {
+ return -1;
+ }
intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK |
Intent.FLAG_ACTIVITY_RESET_TASK_IF_NEEDED);
diff --git a/src/com/android/launcher3/PagedViewIcon.java b/src/com/android/launcher3/PagedViewIcon.java
deleted file mode 100644
index e819d5e..0000000
--- a/src/com/android/launcher3/PagedViewIcon.java
+++ /dev/null
@@ -1,114 +0,0 @@
-/*
- * Copyright (C) 2010 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.launcher3;
-
-import android.content.Context;
-import android.graphics.Bitmap;
-import android.graphics.Canvas;
-import android.graphics.Region;
-import android.graphics.drawable.Drawable;
-import android.util.AttributeSet;
-import android.util.TypedValue;
-import android.widget.TextView;
-
-/**
- * An icon on a PagedView, specifically for items in the launcher's paged view (with compound
- * drawables on the top).
- */
-public class PagedViewIcon extends TextView {
- /** A simple callback interface to allow a PagedViewIcon to notify when it has been pressed */
- public static interface PressedCallback {
- void iconPressed(PagedViewIcon icon);
- }
-
- @SuppressWarnings("unused")
- private static final String TAG = "PagedViewIcon";
- private static final float PRESS_ALPHA = 0.4f;
-
- private PagedViewIcon.PressedCallback mPressedCallback;
- private boolean mLockDrawableState = false;
-
- private Bitmap mIcon;
-
- public PagedViewIcon(Context context) {
- this(context, null);
- }
-
- public PagedViewIcon(Context context, AttributeSet attrs) {
- this(context, attrs, 0);
- }
-
- public PagedViewIcon(Context context, AttributeSet attrs, int defStyle) {
- super(context, attrs, defStyle);
- }
-
- public void onFinishInflate() {
- super.onFinishInflate();
-
- // Ensure we are using the right text size
- LauncherAppState app = LauncherAppState.getInstance();
- DeviceProfile grid = app.getDynamicGrid().getDeviceProfile();
- setTextSize(TypedValue.COMPLEX_UNIT_PX, grid.allAppsIconTextSizePx);
- }
-
- public void applyFromApplicationInfo(AppInfo info, boolean scaleUp,
- PagedViewIcon.PressedCallback cb) {
- LauncherAppState app = LauncherAppState.getInstance();
- DeviceProfile grid = app.getDynamicGrid().getDeviceProfile();
-
- mIcon = info.iconBitmap;
- mPressedCallback = cb;
- Drawable icon = Utilities.createIconDrawable(mIcon);
- icon.setBounds(0, 0, grid.allAppsIconSizePx, grid.allAppsIconSizePx);
- setCompoundDrawables(null, icon, null, null);
- setCompoundDrawablePadding(grid.iconDrawablePaddingPx);
- setText(info.title);
- if (info.contentDescription != null) {
- setContentDescription(info.contentDescription);
- }
- setTag(info);
- }
-
- public void lockDrawableState() {
- mLockDrawableState = true;
- }
-
- public void resetDrawableState() {
- mLockDrawableState = false;
- post(new Runnable() {
- @Override
- public void run() {
- refreshDrawableState();
- }
- });
- }
-
- protected void drawableStateChanged() {
- super.drawableStateChanged();
-
- // We keep in the pressed state until resetDrawableState() is called to reset the press
- // feedback
- if (isPressed()) {
- setAlpha(PRESS_ALPHA);
- if (mPressedCallback != null) {
- mPressedCallback.iconPressed(this);
- }
- } else if (!mLockDrawableState) {
- setAlpha(1f);
- }
- }
-}
diff --git a/src/com/android/launcher3/PagedViewWidget.java b/src/com/android/launcher3/PagedViewWidget.java
index db4aeb9..e6e11a3 100644
--- a/src/com/android/launcher3/PagedViewWidget.java
+++ b/src/com/android/launcher3/PagedViewWidget.java
@@ -30,6 +30,8 @@
import android.widget.LinearLayout;
import android.widget.TextView;
+import com.android.launcher3.compat.AppWidgetManagerCompat;
+
/**
* The linear layout used strictly for the widget/wallpaper tab of the customization tray
*/
@@ -127,7 +129,7 @@
image.setMaxWidth(maxWidth);
}
final TextView name = (TextView) findViewById(R.id.widget_name);
- name.setText(info.label);
+ name.setText(AppWidgetManagerCompat.getInstance(getContext()).loadLabel(info));
final TextView dims = (TextView) findViewById(R.id.widget_dims);
if (dims != null) {
int hSpan = Math.min(cellSpan[0], (int) grid.numColumns);
diff --git a/src/com/android/launcher3/Utilities.java b/src/com/android/launcher3/Utilities.java
index f70fc4d..f20f261 100644
--- a/src/com/android/launcher3/Utilities.java
+++ b/src/com/android/launcher3/Utilities.java
@@ -78,7 +78,7 @@
/**
* Returns a FastBitmapDrawable with the icon, accurately sized.
*/
- static FastBitmapDrawable createIconDrawable(Bitmap icon) {
+ public static FastBitmapDrawable createIconDrawable(Bitmap icon) {
FastBitmapDrawable d = new FastBitmapDrawable(icon);
d.setFilterBitmap(true);
resizeIconDrawable(d);
diff --git a/src/com/android/launcher3/WidgetPreviewLoader.java b/src/com/android/launcher3/WidgetPreviewLoader.java
index 1b37700..5aa7190 100644
--- a/src/com/android/launcher3/WidgetPreviewLoader.java
+++ b/src/com/android/launcher3/WidgetPreviewLoader.java
@@ -5,7 +5,6 @@
import android.content.ContentValues;
import android.content.Context;
import android.content.SharedPreferences;
-import android.content.pm.PackageManager;
import android.content.pm.ResolveInfo;
import android.content.res.Resources;
import android.database.Cursor;
@@ -29,6 +28,8 @@
import android.os.AsyncTask;
import android.util.Log;
+import com.android.launcher3.compat.AppWidgetManagerCompat;
+
import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.IOException;
@@ -42,124 +43,123 @@
import java.util.concurrent.Callable;
import java.util.concurrent.ExecutionException;
-abstract class SoftReferenceThreadLocal<T> {
- private ThreadLocal<SoftReference<T>> mThreadLocal;
- public SoftReferenceThreadLocal() {
- mThreadLocal = new ThreadLocal<SoftReference<T>>();
- }
+public class WidgetPreviewLoader {
- abstract T initialValue();
+ private static abstract class SoftReferenceThreadLocal<T> {
+ private ThreadLocal<SoftReference<T>> mThreadLocal;
+ public SoftReferenceThreadLocal() {
+ mThreadLocal = new ThreadLocal<SoftReference<T>>();
+ }
- public void set(T t) {
- mThreadLocal.set(new SoftReference<T>(t));
- }
+ abstract T initialValue();
- public T get() {
- SoftReference<T> reference = mThreadLocal.get();
- T obj;
- if (reference == null) {
- obj = initialValue();
- mThreadLocal.set(new SoftReference<T>(obj));
- return obj;
- } else {
- obj = reference.get();
- if (obj == null) {
+ public void set(T t) {
+ mThreadLocal.set(new SoftReference<T>(t));
+ }
+
+ public T get() {
+ SoftReference<T> reference = mThreadLocal.get();
+ T obj;
+ if (reference == null) {
obj = initialValue();
mThreadLocal.set(new SoftReference<T>(obj));
+ return obj;
+ } else {
+ obj = reference.get();
+ if (obj == null) {
+ obj = initialValue();
+ mThreadLocal.set(new SoftReference<T>(obj));
+ }
+ return obj;
}
- return obj;
}
}
-}
-class CanvasCache extends SoftReferenceThreadLocal<Canvas> {
- @Override
- protected Canvas initialValue() {
- return new Canvas();
+ private static class CanvasCache extends SoftReferenceThreadLocal<Canvas> {
+ @Override
+ protected Canvas initialValue() {
+ return new Canvas();
+ }
}
-}
-class PaintCache extends SoftReferenceThreadLocal<Paint> {
- @Override
- protected Paint initialValue() {
- return null;
+ private static class PaintCache extends SoftReferenceThreadLocal<Paint> {
+ @Override
+ protected Paint initialValue() {
+ return null;
+ }
}
-}
-class BitmapCache extends SoftReferenceThreadLocal<Bitmap> {
- @Override
- protected Bitmap initialValue() {
- return null;
+ private static class BitmapCache extends SoftReferenceThreadLocal<Bitmap> {
+ @Override
+ protected Bitmap initialValue() {
+ return null;
+ }
}
-}
-class RectCache extends SoftReferenceThreadLocal<Rect> {
- @Override
- protected Rect initialValue() {
- return new Rect();
+ private static class RectCache extends SoftReferenceThreadLocal<Rect> {
+ @Override
+ protected Rect initialValue() {
+ return new Rect();
+ }
}
-}
-class BitmapFactoryOptionsCache extends SoftReferenceThreadLocal<BitmapFactory.Options> {
- @Override
- protected BitmapFactory.Options initialValue() {
- return new BitmapFactory.Options();
+ private static class BitmapFactoryOptionsCache extends
+ SoftReferenceThreadLocal<BitmapFactory.Options> {
+ @Override
+ protected BitmapFactory.Options initialValue() {
+ return new BitmapFactory.Options();
+ }
}
-}
-public class WidgetPreviewLoader {
- static final String TAG = "WidgetPreviewLoader";
- static final String ANDROID_INCREMENTAL_VERSION_NAME_KEY = "android.incremental.version";
+ private static final String TAG = "WidgetPreviewLoader";
+ private static final String ANDROID_INCREMENTAL_VERSION_NAME_KEY = "android.incremental.version";
+
+ private static final float WIDGET_PREVIEW_ICON_PADDING_PERCENTAGE = 0.25f;
+ private static final HashSet<String> sInvalidPackages = new HashSet<String>();
+
+ // Used for drawing shortcut previews
+ private final BitmapCache mCachedShortcutPreviewBitmap = new BitmapCache();
+ private final PaintCache mCachedShortcutPreviewPaint = new PaintCache();
+ private final CanvasCache mCachedShortcutPreviewCanvas = new CanvasCache();
+
+ // Used for drawing widget previews
+ private final CanvasCache mCachedAppWidgetPreviewCanvas = new CanvasCache();
+ private final RectCache mCachedAppWidgetPreviewSrcRect = new RectCache();
+ private final RectCache mCachedAppWidgetPreviewDestRect = new RectCache();
+ private final PaintCache mCachedAppWidgetPreviewPaint = new PaintCache();
+ private final PaintCache mDefaultAppWidgetPreviewPaint = new PaintCache();
+ private final BitmapFactoryOptionsCache mCachedBitmapFactoryOptions = new BitmapFactoryOptionsCache();
+
+ private final HashMap<String, WeakReference<Bitmap>> mLoadedPreviews = new HashMap<>();
+ private final ArrayList<SoftReference<Bitmap>> mUnusedBitmaps = new ArrayList<>();
+
+ private final Context mContext;
+ private final int mAppIconSize;
+ private final IconCache mIconCache;
+ private final AppWidgetManagerCompat mManager;
private int mPreviewBitmapWidth;
private int mPreviewBitmapHeight;
private String mSize;
- private Context mContext;
- private PackageManager mPackageManager;
private PagedViewCellLayout mWidgetSpacingLayout;
- // Used for drawing shortcut previews
- private BitmapCache mCachedShortcutPreviewBitmap = new BitmapCache();
- private PaintCache mCachedShortcutPreviewPaint = new PaintCache();
- private CanvasCache mCachedShortcutPreviewCanvas = new CanvasCache();
-
- // Used for drawing widget previews
- private CanvasCache mCachedAppWidgetPreviewCanvas = new CanvasCache();
- private RectCache mCachedAppWidgetPreviewSrcRect = new RectCache();
- private RectCache mCachedAppWidgetPreviewDestRect = new RectCache();
- private PaintCache mCachedAppWidgetPreviewPaint = new PaintCache();
- private PaintCache mDefaultAppWidgetPreviewPaint = new PaintCache();
private String mCachedSelectQuery;
- private BitmapFactoryOptionsCache mCachedBitmapFactoryOptions = new BitmapFactoryOptionsCache();
- private int mAppIconSize;
- private IconCache mIconCache;
-
- private static final float sWidgetPreviewIconPaddingPercentage = 0.25f;
private CacheDb mDb;
- private final HashMap<String, WeakReference<Bitmap>> mLoadedPreviews;
- private final ArrayList<SoftReference<Bitmap>> mUnusedBitmaps;
- private final static HashSet<String> sInvalidPackages;
-
private final MainThreadExecutor mMainThreadExecutor = new MainThreadExecutor();
- static {
- sInvalidPackages = new HashSet<String>();
- }
-
public WidgetPreviewLoader(Context context) {
LauncherAppState app = LauncherAppState.getInstance();
DeviceProfile grid = app.getDynamicGrid().getDeviceProfile();
mContext = context;
- mPackageManager = mContext.getPackageManager();
mAppIconSize = grid.iconSizePx;
mIconCache = app.getIconCache();
+ mManager = AppWidgetManagerCompat.getInstance(context);
+
mDb = app.getWidgetPreviewCacheDb();
- mLoadedPreviews = new HashMap<String, WeakReference<Bitmap>>();
- mUnusedBitmaps = new ArrayList<SoftReference<Bitmap>>();
SharedPreferences sp = context.getSharedPreferences(
LauncherAppState.getSharedPreferencesKey(), Context.MODE_PRIVATE);
@@ -175,7 +175,7 @@
editor.commit();
}
}
-
+
public void recreateDb() {
LauncherAppState app = LauncherAppState.getInstance();
app.recreateWidgetPreviewDb();
@@ -328,7 +328,7 @@
String output;
if (o instanceof AppWidgetProviderInfo) {
sb.append(WIDGET_PREFIX);
- sb.append(((AppWidgetProviderInfo) o).provider.flattenToString());
+ sb.append(((AppWidgetProviderInfo) o).toString());
output = sb.toString();
sb.setLength(0);
} else {
@@ -413,7 +413,7 @@
}.executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR, (Void) null);
}
- public static void removeItemFromDb(final CacheDb cacheDb, final String objectName) {
+ private static void removeItemFromDb(final CacheDb cacheDb, final String objectName) {
new AsyncTask<Void, Void, Void>() {
public Void doInBackground(Void ... args) {
SQLiteDatabase db = cacheDb.getWritableDatabase();
@@ -473,7 +473,7 @@
}
}
- public Bitmap generatePreview(Object info, Bitmap preview) {
+ private Bitmap generatePreview(Object info, Bitmap preview) {
if (preview != null &&
(preview.getWidth() != mPreviewBitmapWidth ||
preview.getHeight() != mPreviewBitmapHeight)) {
@@ -491,8 +491,8 @@
int[] cellSpans = Launcher.getSpanForWidget(mContext, info);
int maxWidth = maxWidthForWidgetPreview(cellSpans[0]);
int maxHeight = maxHeightForWidgetPreview(cellSpans[1]);
- return generateWidgetPreview(info.provider, info.previewImage, info.icon,
- cellSpans[0], cellSpans[1], maxWidth, maxHeight, preview, null);
+ return generateWidgetPreview(info, cellSpans[0], cellSpans[1],
+ maxWidth, maxHeight, preview, null);
}
public int maxWidthForWidgetPreview(int spanX) {
@@ -505,22 +505,20 @@
mWidgetSpacingLayout.estimateCellHeight(spanY));
}
- public Bitmap generateWidgetPreview(ComponentName provider, int previewImage,
- int iconId, int cellHSpan, int cellVSpan, int maxPreviewWidth, int maxPreviewHeight,
- Bitmap preview, int[] preScaledWidthOut) {
+ public Bitmap generateWidgetPreview(AppWidgetProviderInfo info, int cellHSpan, int cellVSpan,
+ int maxPreviewWidth, int maxPreviewHeight, Bitmap preview, int[] preScaledWidthOut) {
// Load the preview image if possible
- String packageName = provider.getPackageName();
if (maxPreviewWidth < 0) maxPreviewWidth = Integer.MAX_VALUE;
if (maxPreviewHeight < 0) maxPreviewHeight = Integer.MAX_VALUE;
Drawable drawable = null;
- if (previewImage != 0) {
- drawable = mPackageManager.getDrawable(packageName, previewImage, null);
+ if (info.previewImage != 0) {
+ drawable = mManager.loadPreview(info);
if (drawable != null) {
drawable = mutateOnMainThread(drawable);
} else {
Log.w(TAG, "Can't load widget preview drawable 0x" +
- Integer.toHexString(previewImage) + " for provider: " + provider);
+ Integer.toHexString(info.previewImage) + " for provider: " + info.provider);
}
}
@@ -562,21 +560,16 @@
c.setBitmap(null);
// Draw the icon in the top left corner
- int minOffset = (int) (mAppIconSize * sWidgetPreviewIconPaddingPercentage);
+ int minOffset = (int) (mAppIconSize * WIDGET_PREVIEW_ICON_PADDING_PERCENTAGE);
int smallestSide = Math.min(previewWidth, previewHeight);
float iconScale = Math.min((float) smallestSide
/ (mAppIconSize + 2 * minOffset), 1f);
try {
- Drawable icon = null;
- int hoffset =
- (int) ((previewDrawableWidth - mAppIconSize * iconScale) / 2);
- int yoffset =
- (int) ((previewDrawableHeight - mAppIconSize * iconScale) / 2);
- if (iconId > 0) {
- icon = mIconCache.getFullResIcon(packageName, iconId);
- }
+ Drawable icon = mManager.loadIcon(info, mIconCache);
if (icon != null) {
+ int hoffset = (int) ((previewDrawableWidth - mAppIconSize * iconScale) / 2);
+ int yoffset = (int) ((previewDrawableHeight - mAppIconSize * iconScale) / 2);
icon = mutateOnMainThread(icon);
renderDrawableToBitmap(icon, defaultPreview, hoffset,
yoffset, (int) (mAppIconSize * iconScale),
@@ -627,7 +620,7 @@
c.drawBitmap(defaultPreview, src, dest, p);
c.setBitmap(null);
}
- return preview;
+ return mManager.getBadgeBitmap(info, preview);
}
private Bitmap generateShortcutPreview(
@@ -685,18 +678,10 @@
return preview;
}
-
- public static void renderDrawableToBitmap(
- Drawable d, Bitmap bitmap, int x, int y, int w, int h) {
- renderDrawableToBitmap(d, bitmap, x, y, w, h, 1f);
- }
-
private static void renderDrawableToBitmap(
- Drawable d, Bitmap bitmap, int x, int y, int w, int h,
- float scale) {
+ Drawable d, Bitmap bitmap, int x, int y, int w, int h) {
if (bitmap != null) {
Canvas c = new Canvas(bitmap);
- c.scale(scale, scale);
Rect oldBounds = d.copyBounds();
d.setBounds(x, y, x + w, y + h);
d.draw(c);
diff --git a/src/com/android/launcher3/Workspace.java b/src/com/android/launcher3/Workspace.java
index a6cce93..ace5e84 100644
--- a/src/com/android/launcher3/Workspace.java
+++ b/src/com/android/launcher3/Workspace.java
@@ -27,7 +27,6 @@
import android.animation.ValueAnimator;
import android.animation.ValueAnimator.AnimatorUpdateListener;
import android.app.WallpaperManager;
-import android.appwidget.AppWidgetHost;
import android.appwidget.AppWidgetHostView;
import android.appwidget.AppWidgetProviderInfo;
import android.content.ComponentName;
@@ -47,9 +46,7 @@
import android.net.Uri;
import android.os.AsyncTask;
import android.os.Handler;
-import android.os.Handler.Callback;
import android.os.IBinder;
-import android.os.Message;
import android.os.Parcelable;
import android.support.v4.view.ViewCompat;
import android.util.AttributeSet;
@@ -76,9 +73,7 @@
import java.util.HashSet;
import java.util.Iterator;
import java.util.Set;
-import java.util.concurrent.atomic.AtomicBoolean;
import java.util.concurrent.atomic.AtomicInteger;
-import java.util.concurrent.atomic.AtomicReference;
/**
* The workspace is a wide area with a wallpaper and a finite number of pages.
@@ -212,7 +207,7 @@
private HolographicOutlineHelper mOutlineHelper;
private Bitmap mDragOutline = null;
- private final Rect mTempRect = new Rect();
+ private static final Rect sTempRect = new Rect();
private final int[] mTempXY = new int[2];
private int[] mTempVisiblePagesRange = new int[2];
private boolean mOverscrollEffectSet;
@@ -241,6 +236,8 @@
private DropTarget.DragEnforcer mDragEnforcer;
private float mMaxDistanceForFolderCreation;
+ private final Canvas mCanvas = new Canvas();
+
// Variables relating to touch disambiguation (scrolling workspace vs. scrolling a widget)
private float mXDown;
private float mYDown;
@@ -1115,6 +1112,17 @@
return super.onInterceptTouchEvent(ev);
}
+ @Override
+ public boolean onGenericMotionEvent(MotionEvent event) {
+ // Ignore pointer scroll events if the custom content doesn't allow scrolling.
+ if ((getScreenIdForPageIndex(getCurrentPage()) == CUSTOM_CONTENT_SCREEN_ID)
+ && (mCustomContentCallbacks != null)
+ && !mCustomContentCallbacks.isScrollingAllowed()) {
+ return false;
+ }
+ return super.onGenericMotionEvent(event);
+ }
+
protected void reinflateWidgetsIfNecessary() {
final int clCount = getChildCount();
for (int i = 0; i < clCount; i++) {
@@ -1983,14 +1991,7 @@
* appearance).
*
*/
- public void onDragStartedWithItem(View v) {
- final Canvas canvas = new Canvas();
-
- // The outline is used to visualize where the item will land if dropped
- mDragOutline = createDragOutline(v, canvas, DRAG_BITMAP_PADDING);
- }
-
- private Rect getDrawableBounds(Drawable d) {
+ private static Rect getDrawableBounds(Drawable d) {
Rect bounds = new Rect();
d.copyBounds(bounds);
if (bounds.width() == 0 || bounds.height() == 0) {
@@ -2006,8 +2007,6 @@
}
public void onExternalDragStartedWithItem(View v) {
- final Canvas canvas = new Canvas();
-
// Compose a drag bitmap with the view scaled to the icon size
LauncherAppState app = LauncherAppState.getInstance();
DeviceProfile grid = app.getDynamicGrid().getDeviceProfile();
@@ -2027,22 +2026,19 @@
// Compose the bitmap to create the icon from
Bitmap b = Bitmap.createBitmap(bmpWidth, bmpHeight,
Bitmap.Config.ARGB_8888);
- Canvas c = new Canvas(b);
- drawDragView(v, c, 0);
- c.setBitmap(null);
+ mCanvas.setBitmap(b);
+ drawDragView(v, mCanvas, 0);
+ mCanvas.setBitmap(null);
// The outline is used to visualize where the item will land if dropped
- mDragOutline = createDragOutline(b, canvas, DRAG_BITMAP_PADDING, iconSize, iconSize, true);
+ mDragOutline = createDragOutline(b, DRAG_BITMAP_PADDING, iconSize, iconSize, true);
}
public void onDragStartedWithItem(PendingAddItemInfo info, Bitmap b, boolean clipAlpha) {
- final Canvas canvas = new Canvas();
-
int[] size = estimateItemSize(info.spanX, info.spanY, info, false);
// The outline is used to visualize where the item will land if dropped
- mDragOutline = createDragOutline(b, canvas, DRAG_BITMAP_PADDING, size[0],
- size[1], clipAlpha);
+ mDragOutline = createDragOutline(b, DRAG_BITMAP_PADDING, size[0], size[1], clipAlpha);
}
public void exitWidgetResizeMode() {
@@ -2540,8 +2536,8 @@
* @param destCanvas the canvas to draw on
* @param padding the horizontal and vertical padding to use when drawing
*/
- private void drawDragView(View v, Canvas destCanvas, int padding) {
- final Rect clipRect = mTempRect;
+ private static void drawDragView(View v, Canvas destCanvas, int padding) {
+ final Rect clipRect = sTempRect;
v.getDrawingRect(clipRect);
boolean textVisible = false;
@@ -2580,7 +2576,7 @@
* @param expectedPadding padding to add to the drag view. If a different padding was used
* its value will be changed
*/
- public Bitmap createDragBitmap(View v, Canvas canvas, AtomicInteger expectedPadding) {
+ public Bitmap createDragBitmap(View v, AtomicInteger expectedPadding) {
Bitmap b;
int padding = expectedPadding.get();
@@ -2595,9 +2591,9 @@
v.getWidth() + padding, v.getHeight() + padding, Bitmap.Config.ARGB_8888);
}
- canvas.setBitmap(b);
- drawDragView(v, canvas, padding);
- canvas.setBitmap(null);
+ mCanvas.setBitmap(b);
+ drawDragView(v, mCanvas, padding);
+ mCanvas.setBitmap(null);
return b;
}
@@ -2606,15 +2602,15 @@
* Returns a new bitmap to be used as the object outline, e.g. to visualize the drop location.
* Responsibility for the bitmap is transferred to the caller.
*/
- private Bitmap createDragOutline(View v, Canvas canvas, int padding) {
+ private Bitmap createDragOutline(View v, int padding) {
final int outlineColor = getResources().getColor(R.color.outline_color);
final Bitmap b = Bitmap.createBitmap(
v.getWidth() + padding, v.getHeight() + padding, Bitmap.Config.ARGB_8888);
- canvas.setBitmap(b);
- drawDragView(v, canvas, padding);
- mOutlineHelper.applyMediumExpensiveOutlineWithBlur(b, canvas, outlineColor, outlineColor);
- canvas.setBitmap(null);
+ mCanvas.setBitmap(b);
+ drawDragView(v, mCanvas, padding);
+ mOutlineHelper.applyExpensiveOutlineWithBlur(b, mCanvas, outlineColor, outlineColor);
+ mCanvas.setBitmap(null);
return b;
}
@@ -2622,11 +2618,11 @@
* Returns a new bitmap to be used as the object outline, e.g. to visualize the drop location.
* Responsibility for the bitmap is transferred to the caller.
*/
- private Bitmap createDragOutline(Bitmap orig, Canvas canvas, int padding, int w, int h,
+ private Bitmap createDragOutline(Bitmap orig, int padding, int w, int h,
boolean clipAlpha) {
final int outlineColor = getResources().getColor(R.color.outline_color);
final Bitmap b = Bitmap.createBitmap(w, h, Bitmap.Config.ARGB_8888);
- canvas.setBitmap(b);
+ mCanvas.setBitmap(b);
Rect src = new Rect(0, 0, orig.getWidth(), orig.getHeight());
float scaleFactor = Math.min((w - padding) / (float) orig.getWidth(),
@@ -2638,10 +2634,10 @@
// center the image
dst.offset((w - scaledWidth) / 2, (h - scaledHeight) / 2);
- canvas.drawBitmap(orig, src, dst, null);
- mOutlineHelper.applyMediumExpensiveOutlineWithBlur(b, canvas, outlineColor, outlineColor,
+ mCanvas.drawBitmap(orig, src, dst, null);
+ mOutlineHelper.applyExpensiveOutlineWithBlur(b, mCanvas, outlineColor, outlineColor,
clipAlpha);
- canvas.setBitmap(null);
+ mCanvas.setBitmap(null);
return b;
}
@@ -2659,21 +2655,20 @@
CellLayout layout = (CellLayout) child.getParent().getParent();
layout.prepareChildForDrag(child);
- child.clearFocus();
- child.setPressed(false);
-
- final Canvas canvas = new Canvas();
-
- // The outline is used to visualize where the item will land if dropped
- mDragOutline = createDragOutline(child, canvas, DRAG_BITMAP_PADDING);
beginDragShared(child, this);
}
public void beginDragShared(View child, DragSource source) {
+ child.clearFocus();
+ child.setPressed(false);
+
+ // The outline is used to visualize where the item will land if dropped
+ mDragOutline = createDragOutline(child, DRAG_BITMAP_PADDING);
+
mLauncher.onDragStarted(child);
// The drag bitmap follows the touch point around on the screen
AtomicInteger padding = new AtomicInteger(DRAG_BITMAP_PADDING);
- final Bitmap b = createDragBitmap(child, new Canvas(), padding);
+ final Bitmap b = createDragBitmap(child, padding);
final int bmpWidth = b.getWidth();
final int bmpHeight = b.getHeight();
@@ -2687,7 +2682,7 @@
DeviceProfile grid = app.getDynamicGrid().getDeviceProfile();
Point dragVisualizeOffset = null;
Rect dragRect = null;
- if (child instanceof BubbleTextView || child instanceof PagedViewIcon) {
+ if (child instanceof BubbleTextView) {
int iconSize = grid.iconSizePx;
int top = child.getPaddingTop();
int left = (bmpWidth - iconSize) / 2;
@@ -2706,7 +2701,7 @@
// Clear the pressed state if necessary
if (child instanceof BubbleTextView) {
BubbleTextView icon = (BubbleTextView) child;
- icon.clearPressedOrFocusedBackground();
+ icon.clearPressedBackground();
} else if (child instanceof FolderIcon) {
// The folder cling isn't flexible enough to be shown in non-default workspace positions
// Also if they are dragging it a folder, we assume they don't need to see the cling.
@@ -2741,14 +2736,14 @@
// Compose a new drag bitmap that is of the icon size
AtomicInteger padding = new AtomicInteger(DRAG_BITMAP_PADDING);
- final Bitmap tmpB = createDragBitmap(child, new Canvas(), padding);
+ final Bitmap tmpB = createDragBitmap(child, padding);
Bitmap b = Bitmap.createBitmap(iconSize, iconSize, Bitmap.Config.ARGB_8888);
Paint p = new Paint();
p.setFilterBitmap(true);
- Canvas c = new Canvas(b);
- c.drawBitmap(tmpB, new Rect(0, 0, tmpB.getWidth(), tmpB.getHeight()),
+ mCanvas.setBitmap(b);
+ mCanvas.drawBitmap(tmpB, new Rect(0, 0, tmpB.getWidth(), tmpB.getHeight()),
new Rect(0, 0, iconSize, iconSize), p);
- c.setBitmap(null);
+ mCanvas.setBitmap(null);
// Find the child's location on the screen
int bmpWidth = tmpB.getWidth();
@@ -4022,12 +4017,12 @@
int height = MeasureSpec.makeMeasureSpec(unScaledSize[1], MeasureSpec.EXACTLY);
Bitmap b = Bitmap.createBitmap(unScaledSize[0], unScaledSize[1],
Bitmap.Config.ARGB_8888);
- Canvas c = new Canvas(b);
+ mCanvas.setBitmap(b);
layout.measure(width, height);
layout.layout(0, 0, unScaledSize[0], unScaledSize[1]);
- layout.draw(c);
- c.setBitmap(null);
+ layout.draw(mCanvas);
+ mCanvas.setBitmap(null);
layout.setVisibility(visibility);
return b;
}
diff --git a/src/com/android/launcher3/compat/AppWidgetManagerCompat.java b/src/com/android/launcher3/compat/AppWidgetManagerCompat.java
new file mode 100644
index 0000000..57fac7f
--- /dev/null
+++ b/src/com/android/launcher3/compat/AppWidgetManagerCompat.java
@@ -0,0 +1,83 @@
+/*
+ * Copyright (C) 2014 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.compat;
+
+import android.app.Activity;
+import android.appwidget.AppWidgetHost;
+import android.appwidget.AppWidgetManager;
+import android.appwidget.AppWidgetProviderInfo;
+import android.content.Context;
+import android.graphics.Bitmap;
+import android.graphics.drawable.Drawable;
+import android.os.Bundle;
+
+import com.android.launcher3.IconCache;
+import com.android.launcher3.Utilities;
+
+import java.util.List;
+
+public abstract class AppWidgetManagerCompat {
+
+ private static final Object sInstanceLock = new Object();
+ private static AppWidgetManagerCompat sInstance;
+
+
+ public static AppWidgetManagerCompat getInstance(Context context) {
+ synchronized (sInstanceLock) {
+ // TODO change this to use api version once L gets an API number.
+ if (sInstance == null) {
+ if (Utilities.isLmp()) {
+ sInstance = new AppWidgetManagerCompatVL(context);
+ } else {
+ sInstance = new AppWidgetManagerCompatV16(context);
+ }
+ }
+ return sInstance;
+ }
+ }
+
+ final AppWidgetManager mAppWidgetManager;
+ final Context mContext;
+
+ AppWidgetManagerCompat(Context context) {
+ mContext = context;
+ mAppWidgetManager = AppWidgetManager.getInstance(context);
+ }
+
+ public AppWidgetProviderInfo getAppWidgetInfo(int appWidgetId) {
+ return mAppWidgetManager.getAppWidgetInfo(appWidgetId);
+ }
+
+ public abstract List<AppWidgetProviderInfo> getAllProviders();
+
+ public abstract String loadLabel(AppWidgetProviderInfo info);
+
+ public abstract boolean bindAppWidgetIdIfAllowed(
+ int appWidgetId, AppWidgetProviderInfo info, Bundle options);
+
+ public abstract UserHandleCompat getUser(AppWidgetProviderInfo info);
+
+ public abstract void startConfigActivity(AppWidgetProviderInfo info, int widgetId,
+ Activity activity, AppWidgetHost host, int requestCode);
+
+ public abstract Drawable loadPreview(AppWidgetProviderInfo info);
+
+ public abstract Drawable loadIcon(AppWidgetProviderInfo info, IconCache cache);
+
+ public abstract Bitmap getBadgeBitmap(AppWidgetProviderInfo info, Bitmap bitmap);
+
+}
diff --git a/src/com/android/launcher3/compat/AppWidgetManagerCompatV16.java b/src/com/android/launcher3/compat/AppWidgetManagerCompatV16.java
new file mode 100644
index 0000000..f599f43
--- /dev/null
+++ b/src/com/android/launcher3/compat/AppWidgetManagerCompatV16.java
@@ -0,0 +1,90 @@
+/*
+ * Copyright (C) 2014 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.compat;
+
+import android.app.Activity;
+import android.appwidget.AppWidgetHost;
+import android.appwidget.AppWidgetManager;
+import android.appwidget.AppWidgetProviderInfo;
+import android.content.Context;
+import android.content.Intent;
+import android.graphics.Bitmap;
+import android.graphics.drawable.Drawable;
+import android.os.Build;
+import android.os.Bundle;
+
+import com.android.launcher3.IconCache;
+import com.android.launcher3.Utilities;
+
+import java.util.List;
+
+class AppWidgetManagerCompatV16 extends AppWidgetManagerCompat {
+
+ AppWidgetManagerCompatV16(Context context) {
+ super(context);
+ }
+
+ @Override
+ public List<AppWidgetProviderInfo> getAllProviders() {
+ return mAppWidgetManager.getInstalledProviders();
+ }
+
+ @Override
+ public String loadLabel(AppWidgetProviderInfo info) {
+ return info.label.trim();
+ }
+
+ @Override
+ public boolean bindAppWidgetIdIfAllowed(int appWidgetId, AppWidgetProviderInfo info,
+ Bundle options) {
+ if (Build.VERSION.SDK_INT < Build.VERSION_CODES.JELLY_BEAN_MR1) {
+ return mAppWidgetManager.bindAppWidgetIdIfAllowed(appWidgetId, info.provider);
+ } else {
+ return mAppWidgetManager.bindAppWidgetIdIfAllowed(appWidgetId, info.provider, options);
+ }
+ }
+
+ @Override
+ public UserHandleCompat getUser(AppWidgetProviderInfo info) {
+ return UserHandleCompat.myUserHandle();
+ }
+
+ @Override
+ public void startConfigActivity(AppWidgetProviderInfo info, int widgetId, Activity activity,
+ AppWidgetHost host, int requestCode) {
+ Intent intent = new Intent(AppWidgetManager.ACTION_APPWIDGET_CONFIGURE);
+ intent.setComponent(info.configure);
+ intent.putExtra(AppWidgetManager.EXTRA_APPWIDGET_ID, widgetId);
+ Utilities.startActivityForResultSafely(activity, intent, requestCode);
+ }
+
+ @Override
+ public Drawable loadPreview(AppWidgetProviderInfo info) {
+ return mContext.getPackageManager().getDrawable(
+ info.provider.getPackageName(), info.previewImage, null);
+ }
+
+ @Override
+ public Drawable loadIcon(AppWidgetProviderInfo info, IconCache cache) {
+ return cache.getFullResIcon(info.provider.getPackageName(), info.icon);
+ }
+
+ @Override
+ public Bitmap getBadgeBitmap(AppWidgetProviderInfo info, Bitmap bitmap) {
+ return bitmap;
+ }
+}
diff --git a/src/com/android/launcher3/compat/AppWidgetManagerCompatVL.java b/src/com/android/launcher3/compat/AppWidgetManagerCompatVL.java
new file mode 100644
index 0000000..535c74b
--- /dev/null
+++ b/src/com/android/launcher3/compat/AppWidgetManagerCompatVL.java
@@ -0,0 +1,142 @@
+/*
+ * Copyright (C) 2014 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.compat;
+
+import android.annotation.TargetApi;
+import android.app.Activity;
+import android.appwidget.AppWidgetHost;
+import android.appwidget.AppWidgetProviderInfo;
+import android.content.ActivityNotFoundException;
+import android.content.Context;
+import android.content.pm.PackageManager;
+import android.content.res.Resources;
+import android.graphics.Bitmap;
+import android.graphics.Canvas;
+import android.graphics.Color;
+import android.graphics.Rect;
+import android.graphics.drawable.BitmapDrawable;
+import android.graphics.drawable.Drawable;
+import android.os.Build;
+import android.os.Bundle;
+import android.os.UserHandle;
+import android.os.UserManager;
+import android.view.View;
+import android.widget.Toast;
+
+import com.android.launcher3.IconCache;
+import com.android.launcher3.R;
+
+import java.util.ArrayList;
+import java.util.List;
+
+@TargetApi(Build.VERSION_CODES.L)
+class AppWidgetManagerCompatVL extends AppWidgetManagerCompat {
+
+ private final UserManager mUserManager;
+ private final PackageManager mPm;
+
+ AppWidgetManagerCompatVL(Context context) {
+ super(context);
+ mPm = context.getPackageManager();
+ mUserManager = (UserManager) context.getSystemService(Context.USER_SERVICE);
+ }
+
+ @Override
+ public List<AppWidgetProviderInfo> getAllProviders() {
+ ArrayList<AppWidgetProviderInfo> providers = new ArrayList<AppWidgetProviderInfo>();
+ for (UserHandle user : mUserManager.getUserProfiles()) {
+ providers.addAll(mAppWidgetManager.getInstalledProvidersForProfile(user));
+ }
+ return providers;
+ }
+
+ @Override
+ public String loadLabel(AppWidgetProviderInfo info) {
+ return info.loadLabel(mPm);
+ }
+
+ @Override
+ public boolean bindAppWidgetIdIfAllowed(int appWidgetId, AppWidgetProviderInfo info,
+ Bundle options) {
+ return mAppWidgetManager.bindAppWidgetIdIfAllowed(
+ appWidgetId, info.getProfile(), info.provider, options);
+ }
+
+ @Override
+ public UserHandleCompat getUser(AppWidgetProviderInfo info) {
+ return UserHandleCompat.fromUser(info.getProfile());
+ }
+
+ @Override
+ public void startConfigActivity(AppWidgetProviderInfo info, int widgetId, Activity activity,
+ AppWidgetHost host, int requestCode) {
+ try {
+ host.startAppWidgetConfigureActivityForResult(activity, widgetId, 0, requestCode, null);
+ } catch (ActivityNotFoundException e) {
+ Toast.makeText(activity, R.string.activity_not_found, Toast.LENGTH_SHORT).show();
+ } catch (SecurityException e) {
+ Toast.makeText(activity, R.string.activity_not_found, Toast.LENGTH_SHORT).show();
+ }
+ }
+
+ @Override
+ public Drawable loadPreview(AppWidgetProviderInfo info) {
+ return info.loadPreviewImage(mContext, 0);
+ }
+
+ @Override
+ public Drawable loadIcon(AppWidgetProviderInfo info, IconCache cache) {
+ return info.loadIcon(mContext, cache.getFullResIconDpi());
+ }
+
+ @Override
+ public Bitmap getBadgeBitmap(AppWidgetProviderInfo info, Bitmap bitmap) {
+ if (info.getProfile().equals(android.os.Process.myUserHandle())) {
+ return bitmap;
+ }
+
+ // Add a user badge in the bottom right of the image.
+ final Resources res = mContext.getResources();
+ final int badgeSize = res.getDimensionPixelSize(R.dimen.profile_badge_size);
+ final int badgeMargin = res.getDimensionPixelSize(R.dimen.profile_badge_margin);
+ final Rect badgeLocation = new Rect(0, 0, badgeSize, badgeSize);
+
+ final int top = bitmap.getHeight() - badgeSize - badgeMargin;
+ if (res.getConfiguration().getLayoutDirection() == View.LAYOUT_DIRECTION_RTL) {
+ badgeLocation.offset(badgeMargin, top);
+ } else {
+ badgeLocation.offset(bitmap.getWidth() - badgeSize - badgeMargin, top);
+ }
+
+ UserManager userManager = (UserManager) mContext.getSystemService(
+ Context.USER_SERVICE);
+
+ Drawable drawable = userManager.getBadgedDrawableForUser(new BitmapDrawable(res, bitmap),
+ info.getProfile(), badgeLocation, 0);
+
+ if (drawable instanceof BitmapDrawable) {
+ return ((BitmapDrawable) drawable).getBitmap();
+ }
+
+ bitmap.eraseColor(Color.TRANSPARENT);
+ Canvas c = new Canvas(bitmap);
+ drawable.setBounds(0, 0, bitmap.getWidth(), bitmap.getHeight());
+ drawable.draw(c);
+ c.setBitmap(null);
+ return bitmap;
+ }
+}