am 23b816b1: (-s ours) Import translations. DO NOT MERGE
* commit '23b816b1bafee73eee28caca3e2a2915f726bbd9':
Import translations. DO NOT MERGE
diff --git a/WallpaperPicker/src/com/android/launcher3/WallpaperCropActivity.java b/WallpaperPicker/src/com/android/launcher3/WallpaperCropActivity.java
index 561c4bb..11684c3 100644
--- a/WallpaperPicker/src/com/android/launcher3/WallpaperCropActivity.java
+++ b/WallpaperPicker/src/com/android/launcher3/WallpaperCropActivity.java
@@ -141,7 +141,21 @@
final AsyncTask<Void, Void, Void> loadBitmapTask = new AsyncTask<Void, Void, Void>() {
protected Void doInBackground(Void...args) {
if (!isCancelled()) {
- bitmapSource.loadInBackground();
+ try {
+ bitmapSource.loadInBackground();
+ } catch (SecurityException securityException) {
+ if (isDestroyed()) {
+ // Temporarily granted permissions are revoked when the activity
+ // finishes, potentially resulting in a SecurityException here.
+ // Even though {@link #isDestroyed} might also return true in different
+ // situations where the configuration changes, we are fine with
+ // catching these cases here as well.
+ cancel(false);
+ } else {
+ // otherwise it had a different cause and we throw it further
+ throw securityException;
+ }
+ }
}
return null;
}
@@ -352,10 +366,13 @@
getWindowManager());
// Get the crop
RectF cropRect = mCropView.getCrop();
+
+ Point inSize = mCropView.getSourceDimensions();
+
int cropRotation = mCropView.getImageRotation();
float cropScale = mCropView.getWidth() / (float) cropRect.width();
- Point inSize = mCropView.getSourceDimensions();
+
Matrix rotateMatrix = new Matrix();
rotateMatrix.setRotate(cropRotation);
float[] rotatedInSize = new float[] { inSize.x, inSize.y };
@@ -363,6 +380,14 @@
rotatedInSize[0] = Math.abs(rotatedInSize[0]);
rotatedInSize[1] = Math.abs(rotatedInSize[1]);
+
+ // due to rounding errors in the cropview renderer the edges can be slightly offset
+ // therefore we ensure that the boundaries are sanely defined
+ cropRect.left = Math.max(0, cropRect.left);
+ cropRect.right = Math.min(rotatedInSize[0], cropRect.right);
+ cropRect.top = Math.max(0, cropRect.top);
+ cropRect.bottom = Math.min(rotatedInSize[1], cropRect.bottom);
+
// ADJUST CROP WIDTH
// Extend the crop all the way to the right, for parallax
// (or all the way to the left, in RTL)
diff --git a/res/values-af/strings.xml b/res/values-af/strings.xml
index b5c17c5..3d337db 100644
--- a/res/values-af/strings.xml
+++ b/res/values-af/strings.xml
@@ -107,4 +107,9 @@
<string name="widget_button_text" msgid="2880537293434387943">"Legstukke"</string>
<string name="wallpaper_button_text" msgid="8404103075899945851">"Muurpapiere"</string>
<string name="settings_button_text" msgid="8119458837558863227">"Instellings"</string>
+ <string name="package_state_enqueued" msgid="6227252464303085641">"Wag tans…"</string>
+ <string name="package_state_downloading" msgid="4088770468458724721">"Laai tans af…"</string>
+ <string name="package_state_installing" msgid="7588193972189849870">"Installeer tans…"</string>
+ <string name="package_state_unknown" msgid="7592128424511031410">"Onbekend"</string>
+ <string name="package_state_error" msgid="7672093962724223588">"Nie teruggestel nie"</string>
</resources>
diff --git a/res/values-am/strings.xml b/res/values-am/strings.xml
index ce9fb9b..489164c 100644
--- a/res/values-am/strings.xml
+++ b/res/values-am/strings.xml
@@ -107,4 +107,9 @@
<string name="widget_button_text" msgid="2880537293434387943">"ፍርግሞች"</string>
<string name="wallpaper_button_text" msgid="8404103075899945851">"የግድግዳ ወረቀቶች"</string>
<string name="settings_button_text" msgid="8119458837558863227">"ቅንብሮች"</string>
+ <string name="package_state_enqueued" msgid="6227252464303085641">"በመጠበቅ ላይ"</string>
+ <string name="package_state_downloading" msgid="4088770468458724721">"በማውረድ ላይ"</string>
+ <string name="package_state_installing" msgid="7588193972189849870">"በመጫን ላይ"</string>
+ <string name="package_state_unknown" msgid="7592128424511031410">"የማይታወቅ"</string>
+ <string name="package_state_error" msgid="7672093962724223588">"ወደነበረበት አልተመለሰም"</string>
</resources>
diff --git a/res/values-ar/strings.xml b/res/values-ar/strings.xml
index 7eb37d3..90eae74 100644
--- a/res/values-ar/strings.xml
+++ b/res/values-ar/strings.xml
@@ -107,4 +107,9 @@
<string name="widget_button_text" msgid="2880537293434387943">"الأدوات"</string>
<string name="wallpaper_button_text" msgid="8404103075899945851">"الخلفيات"</string>
<string name="settings_button_text" msgid="8119458837558863227">"الإعدادات"</string>
+ <string name="package_state_enqueued" msgid="6227252464303085641">"انتظار"</string>
+ <string name="package_state_downloading" msgid="4088770468458724721">"جارٍ التنزيل"</string>
+ <string name="package_state_installing" msgid="7588193972189849870">"جارٍ التثبيت"</string>
+ <string name="package_state_unknown" msgid="7592128424511031410">"غير معروفة"</string>
+ <string name="package_state_error" msgid="7672093962724223588">"استعادة مخفقة"</string>
</resources>
diff --git a/res/values-bg/strings.xml b/res/values-bg/strings.xml
index 13c0118..198cd18 100644
--- a/res/values-bg/strings.xml
+++ b/res/values-bg/strings.xml
@@ -107,4 +107,9 @@
<string name="widget_button_text" msgid="2880537293434387943">"Приспособления"</string>
<string name="wallpaper_button_text" msgid="8404103075899945851">"Тапети"</string>
<string name="settings_button_text" msgid="8119458837558863227">"Настройки"</string>
+ <string name="package_state_enqueued" msgid="6227252464303085641">"Изчаква"</string>
+ <string name="package_state_downloading" msgid="4088770468458724721">"Изтегля се"</string>
+ <string name="package_state_installing" msgid="7588193972189849870">"Инсталира се"</string>
+ <string name="package_state_unknown" msgid="7592128424511031410">"Няма информация"</string>
+ <string name="package_state_error" msgid="7672093962724223588">"Не е възстановено"</string>
</resources>
diff --git a/res/values-ca/strings.xml b/res/values-ca/strings.xml
index 3e6bedb..c187094 100644
--- a/res/values-ca/strings.xml
+++ b/res/values-ca/strings.xml
@@ -107,4 +107,9 @@
<string name="widget_button_text" msgid="2880537293434387943">"Widgets"</string>
<string name="wallpaper_button_text" msgid="8404103075899945851">"Fons de pantalla"</string>
<string name="settings_button_text" msgid="8119458837558863227">"Configuració"</string>
+ <string name="package_state_enqueued" msgid="6227252464303085641">"En espera"</string>
+ <string name="package_state_downloading" msgid="4088770468458724721">"S\'està baixant"</string>
+ <string name="package_state_installing" msgid="7588193972189849870">"Instal·lant"</string>
+ <string name="package_state_unknown" msgid="7592128424511031410">"Desconegut"</string>
+ <string name="package_state_error" msgid="7672093962724223588">"No restaurat"</string>
</resources>
diff --git a/res/values-cs/strings.xml b/res/values-cs/strings.xml
index 3a0e672..6870f89 100644
--- a/res/values-cs/strings.xml
+++ b/res/values-cs/strings.xml
@@ -107,4 +107,9 @@
<string name="widget_button_text" msgid="2880537293434387943">"Widgety"</string>
<string name="wallpaper_button_text" msgid="8404103075899945851">"Tapety"</string>
<string name="settings_button_text" msgid="8119458837558863227">"Nastavení"</string>
+ <string name="package_state_enqueued" msgid="6227252464303085641">"Čekání"</string>
+ <string name="package_state_downloading" msgid="4088770468458724721">"Stahování"</string>
+ <string name="package_state_installing" msgid="7588193972189849870">"Instalace"</string>
+ <string name="package_state_unknown" msgid="7592128424511031410">"Neznámé"</string>
+ <string name="package_state_error" msgid="7672093962724223588">"Nebylo obnoveno"</string>
</resources>
diff --git a/res/values-da/strings.xml b/res/values-da/strings.xml
index eabde3e..5d8b385 100644
--- a/res/values-da/strings.xml
+++ b/res/values-da/strings.xml
@@ -107,4 +107,9 @@
<string name="widget_button_text" msgid="2880537293434387943">"Widgets"</string>
<string name="wallpaper_button_text" msgid="8404103075899945851">"Baggrunde"</string>
<string name="settings_button_text" msgid="8119458837558863227">"Indstillinger"</string>
+ <string name="package_state_enqueued" msgid="6227252464303085641">"Afventer"</string>
+ <string name="package_state_downloading" msgid="4088770468458724721">"Downloader"</string>
+ <string name="package_state_installing" msgid="7588193972189849870">"Installerer"</string>
+ <string name="package_state_unknown" msgid="7592128424511031410">"Ukendt"</string>
+ <string name="package_state_error" msgid="7672093962724223588">"Ikke gendannet"</string>
</resources>
diff --git a/res/values-de/strings.xml b/res/values-de/strings.xml
index 27ad73a..6b09789 100644
--- a/res/values-de/strings.xml
+++ b/res/values-de/strings.xml
@@ -107,4 +107,9 @@
<string name="widget_button_text" msgid="2880537293434387943">"Widgets"</string>
<string name="wallpaper_button_text" msgid="8404103075899945851">"Hintergründe"</string>
<string name="settings_button_text" msgid="8119458837558863227">"Einstellungen"</string>
+ <string name="package_state_enqueued" msgid="6227252464303085641">"Warten"</string>
+ <string name="package_state_downloading" msgid="4088770468458724721">"Download läuft"</string>
+ <string name="package_state_installing" msgid="7588193972189849870">"Installation"</string>
+ <string name="package_state_unknown" msgid="7592128424511031410">"Unbekannt"</string>
+ <string name="package_state_error" msgid="7672093962724223588">"Nicht wiederhergestellt"</string>
</resources>
diff --git a/res/values-el/strings.xml b/res/values-el/strings.xml
index ec05ae5..66cea00 100644
--- a/res/values-el/strings.xml
+++ b/res/values-el/strings.xml
@@ -107,4 +107,9 @@
<string name="widget_button_text" msgid="2880537293434387943">"Γραφικά στοιχεία"</string>
<string name="wallpaper_button_text" msgid="8404103075899945851">"Ταπετσαρίες"</string>
<string name="settings_button_text" msgid="8119458837558863227">"Ρυθμίσεις"</string>
+ <string name="package_state_enqueued" msgid="6227252464303085641">"Αναμονή"</string>
+ <string name="package_state_downloading" msgid="4088770468458724721">"Λήψη "</string>
+ <string name="package_state_installing" msgid="7588193972189849870">"Εγκατάσταση"</string>
+ <string name="package_state_unknown" msgid="7592128424511031410">"Άγνωστο"</string>
+ <string name="package_state_error" msgid="7672093962724223588">"Δεν ανακτήθηκε"</string>
</resources>
diff --git a/res/values-en-rGB/strings.xml b/res/values-en-rGB/strings.xml
index cab1707..eed1f80 100644
--- a/res/values-en-rGB/strings.xml
+++ b/res/values-en-rGB/strings.xml
@@ -107,4 +107,9 @@
<string name="widget_button_text" msgid="2880537293434387943">"Widgets"</string>
<string name="wallpaper_button_text" msgid="8404103075899945851">"Wallpapers"</string>
<string name="settings_button_text" msgid="8119458837558863227">"Settings"</string>
+ <string name="package_state_enqueued" msgid="6227252464303085641">"Waiting"</string>
+ <string name="package_state_downloading" msgid="4088770468458724721">"Downloading"</string>
+ <string name="package_state_installing" msgid="7588193972189849870">"Installing"</string>
+ <string name="package_state_unknown" msgid="7592128424511031410">"Unknown"</string>
+ <string name="package_state_error" msgid="7672093962724223588">"Not restored"</string>
</resources>
diff --git a/res/values-en-rIN/strings.xml b/res/values-en-rIN/strings.xml
index cab1707..eed1f80 100644
--- a/res/values-en-rIN/strings.xml
+++ b/res/values-en-rIN/strings.xml
@@ -107,4 +107,9 @@
<string name="widget_button_text" msgid="2880537293434387943">"Widgets"</string>
<string name="wallpaper_button_text" msgid="8404103075899945851">"Wallpapers"</string>
<string name="settings_button_text" msgid="8119458837558863227">"Settings"</string>
+ <string name="package_state_enqueued" msgid="6227252464303085641">"Waiting"</string>
+ <string name="package_state_downloading" msgid="4088770468458724721">"Downloading"</string>
+ <string name="package_state_installing" msgid="7588193972189849870">"Installing"</string>
+ <string name="package_state_unknown" msgid="7592128424511031410">"Unknown"</string>
+ <string name="package_state_error" msgid="7672093962724223588">"Not restored"</string>
</resources>
diff --git a/res/values-es-rUS/strings.xml b/res/values-es-rUS/strings.xml
index 278f0d8..b325c35 100644
--- a/res/values-es-rUS/strings.xml
+++ b/res/values-es-rUS/strings.xml
@@ -107,4 +107,9 @@
<string name="widget_button_text" msgid="2880537293434387943">"Widgets"</string>
<string name="wallpaper_button_text" msgid="8404103075899945851">"Fondos de pantalla"</string>
<string name="settings_button_text" msgid="8119458837558863227">"Configuración"</string>
+ <string name="package_state_enqueued" msgid="6227252464303085641">"Pendiente"</string>
+ <string name="package_state_downloading" msgid="4088770468458724721">"Descargando"</string>
+ <string name="package_state_installing" msgid="7588193972189849870">"Instalando"</string>
+ <string name="package_state_unknown" msgid="7592128424511031410">"Desconocido"</string>
+ <string name="package_state_error" msgid="7672093962724223588">"No restaurado"</string>
</resources>
diff --git a/res/values-es/strings.xml b/res/values-es/strings.xml
index f9cf809..3efdf9b 100644
--- a/res/values-es/strings.xml
+++ b/res/values-es/strings.xml
@@ -107,4 +107,9 @@
<string name="widget_button_text" msgid="2880537293434387943">"Widgets"</string>
<string name="wallpaper_button_text" msgid="8404103075899945851">"Fondos de pantalla"</string>
<string name="settings_button_text" msgid="8119458837558863227">"Ajustes"</string>
+ <string name="package_state_enqueued" msgid="6227252464303085641">"Esperando"</string>
+ <string name="package_state_downloading" msgid="4088770468458724721">"Descargando"</string>
+ <string name="package_state_installing" msgid="7588193972189849870">"Instalando"</string>
+ <string name="package_state_unknown" msgid="7592128424511031410">"Desconocido"</string>
+ <string name="package_state_error" msgid="7672093962724223588">"No restaurado"</string>
</resources>
diff --git a/res/values-et-rEE/strings.xml b/res/values-et-rEE/strings.xml
index 92985d2..73e4779 100644
--- a/res/values-et-rEE/strings.xml
+++ b/res/values-et-rEE/strings.xml
@@ -107,4 +107,9 @@
<string name="widget_button_text" msgid="2880537293434387943">"Vidinad"</string>
<string name="wallpaper_button_text" msgid="8404103075899945851">"Taustapildid"</string>
<string name="settings_button_text" msgid="8119458837558863227">"Seaded"</string>
+ <string name="package_state_enqueued" msgid="6227252464303085641">"Ootamine"</string>
+ <string name="package_state_downloading" msgid="4088770468458724721">"Allalaadimine"</string>
+ <string name="package_state_installing" msgid="7588193972189849870">"Installimine"</string>
+ <string name="package_state_unknown" msgid="7592128424511031410">"Teadmata"</string>
+ <string name="package_state_error" msgid="7672093962724223588">"Ei taastatud"</string>
</resources>
diff --git a/res/values-fa/strings.xml b/res/values-fa/strings.xml
index a01ea79..d5e271b 100644
--- a/res/values-fa/strings.xml
+++ b/res/values-fa/strings.xml
@@ -107,4 +107,9 @@
<string name="widget_button_text" msgid="2880537293434387943">"ابزارکها"</string>
<string name="wallpaper_button_text" msgid="8404103075899945851">"کاغذدیواریها"</string>
<string name="settings_button_text" msgid="8119458837558863227">"تنظیمات"</string>
+ <string name="package_state_enqueued" msgid="6227252464303085641">"در حال انتظار"</string>
+ <string name="package_state_downloading" msgid="4088770468458724721">"در حال دانلود"</string>
+ <string name="package_state_installing" msgid="7588193972189849870">"در حال نصب"</string>
+ <string name="package_state_unknown" msgid="7592128424511031410">"نامشخص"</string>
+ <string name="package_state_error" msgid="7672093962724223588">"بازیابی نشد"</string>
</resources>
diff --git a/res/values-fi/strings.xml b/res/values-fi/strings.xml
index 9a48ab3..c6ffdf6 100644
--- a/res/values-fi/strings.xml
+++ b/res/values-fi/strings.xml
@@ -107,4 +107,9 @@
<string name="widget_button_text" msgid="2880537293434387943">"Widgetit"</string>
<string name="wallpaper_button_text" msgid="8404103075899945851">"Taustakuvat"</string>
<string name="settings_button_text" msgid="8119458837558863227">"Asetukset"</string>
+ <string name="package_state_enqueued" msgid="6227252464303085641">"Odottaa"</string>
+ <string name="package_state_downloading" msgid="4088770468458724721">"Ladataan"</string>
+ <string name="package_state_installing" msgid="7588193972189849870">"Asennetaan"</string>
+ <string name="package_state_unknown" msgid="7592128424511031410">"Tuntematon"</string>
+ <string name="package_state_error" msgid="7672093962724223588">"Ei palautettu"</string>
</resources>
diff --git a/res/values-fr-rCA/strings.xml b/res/values-fr-rCA/strings.xml
index 92c5cc4..0c71823 100644
--- a/res/values-fr-rCA/strings.xml
+++ b/res/values-fr-rCA/strings.xml
@@ -107,4 +107,9 @@
<string name="widget_button_text" msgid="2880537293434387943">"Widgets"</string>
<string name="wallpaper_button_text" msgid="8404103075899945851">"Fonds d\'écran"</string>
<string name="settings_button_text" msgid="8119458837558863227">"Paramètres"</string>
+ <string name="package_state_enqueued" msgid="6227252464303085641">"En attente"</string>
+ <string name="package_state_downloading" msgid="4088770468458724721">"Téléchargement..."</string>
+ <string name="package_state_installing" msgid="7588193972189849870">"Installation…"</string>
+ <string name="package_state_unknown" msgid="7592128424511031410">"Inconnu"</string>
+ <string name="package_state_error" msgid="7672093962724223588">"Non restauré"</string>
</resources>
diff --git a/res/values-fr/strings.xml b/res/values-fr/strings.xml
index 18732f8..41ea546 100644
--- a/res/values-fr/strings.xml
+++ b/res/values-fr/strings.xml
@@ -107,4 +107,9 @@
<string name="widget_button_text" msgid="2880537293434387943">"Widgets"</string>
<string name="wallpaper_button_text" msgid="8404103075899945851">"Fonds d\'écran"</string>
<string name="settings_button_text" msgid="8119458837558863227">"Paramètres"</string>
+ <string name="package_state_enqueued" msgid="6227252464303085641">"En attente"</string>
+ <string name="package_state_downloading" msgid="4088770468458724721">"Téléchargement…"</string>
+ <string name="package_state_installing" msgid="7588193972189849870">"Installation…"</string>
+ <string name="package_state_unknown" msgid="7592128424511031410">"Inconnu"</string>
+ <string name="package_state_error" msgid="7672093962724223588">"Non restauré"</string>
</resources>
diff --git a/res/values-hi/strings.xml b/res/values-hi/strings.xml
index b889625..9bbb5cb 100644
--- a/res/values-hi/strings.xml
+++ b/res/values-hi/strings.xml
@@ -107,4 +107,9 @@
<string name="widget_button_text" msgid="2880537293434387943">"विजेट"</string>
<string name="wallpaper_button_text" msgid="8404103075899945851">"वॉलपेपर"</string>
<string name="settings_button_text" msgid="8119458837558863227">"सेटिंग"</string>
+ <string name="package_state_enqueued" msgid="6227252464303085641">"प्रतीक्षा में"</string>
+ <string name="package_state_downloading" msgid="4088770468458724721">"डाउनलोड हो रहा है"</string>
+ <string name="package_state_installing" msgid="7588193972189849870">"इंस्टॉल हो रहा है"</string>
+ <string name="package_state_unknown" msgid="7592128424511031410">"अज्ञात"</string>
+ <string name="package_state_error" msgid="7672093962724223588">"पुन:स्थापित नहीं हुआ"</string>
</resources>
diff --git a/res/values-hr/strings.xml b/res/values-hr/strings.xml
index 32f3feb..8116ba4 100644
--- a/res/values-hr/strings.xml
+++ b/res/values-hr/strings.xml
@@ -107,4 +107,9 @@
<string name="widget_button_text" msgid="2880537293434387943">"Widgeti"</string>
<string name="wallpaper_button_text" msgid="8404103075899945851">"Pozadinske slike"</string>
<string name="settings_button_text" msgid="8119458837558863227">"Postavke"</string>
+ <string name="package_state_enqueued" msgid="6227252464303085641">"Čekanje"</string>
+ <string name="package_state_downloading" msgid="4088770468458724721">"Preuzimanje"</string>
+ <string name="package_state_installing" msgid="7588193972189849870">"Instaliranje"</string>
+ <string name="package_state_unknown" msgid="7592128424511031410">"Nepoznato"</string>
+ <string name="package_state_error" msgid="7672093962724223588">"Nije vraćeno"</string>
</resources>
diff --git a/res/values-hu/strings.xml b/res/values-hu/strings.xml
index 37d5059..59fc6e1 100644
--- a/res/values-hu/strings.xml
+++ b/res/values-hu/strings.xml
@@ -107,4 +107,9 @@
<string name="widget_button_text" msgid="2880537293434387943">"Modulok"</string>
<string name="wallpaper_button_text" msgid="8404103075899945851">"Háttérképek"</string>
<string name="settings_button_text" msgid="8119458837558863227">"Beállítások"</string>
+ <string name="package_state_enqueued" msgid="6227252464303085641">"Várakozik"</string>
+ <string name="package_state_downloading" msgid="4088770468458724721">"Letöltés alatt"</string>
+ <string name="package_state_installing" msgid="7588193972189849870">"Települ"</string>
+ <string name="package_state_unknown" msgid="7592128424511031410">"Ismeretlen"</string>
+ <string name="package_state_error" msgid="7672093962724223588">"Nincs visszaállítva"</string>
</resources>
diff --git a/res/values-hy-rAM/strings.xml b/res/values-hy-rAM/strings.xml
index 6e9491b..d02d48e 100644
--- a/res/values-hy-rAM/strings.xml
+++ b/res/values-hy-rAM/strings.xml
@@ -107,4 +107,9 @@
<string name="widget_button_text" msgid="2880537293434387943">"Վիջեթներ"</string>
<string name="wallpaper_button_text" msgid="8404103075899945851">"Պաստառներ"</string>
<string name="settings_button_text" msgid="8119458837558863227">"Կարգավորումներ"</string>
+ <string name="package_state_enqueued" msgid="6227252464303085641">"Առկախ է"</string>
+ <string name="package_state_downloading" msgid="4088770468458724721">"Ներբեռնվում է"</string>
+ <string name="package_state_installing" msgid="7588193972189849870">"Տեղադրվում է"</string>
+ <string name="package_state_unknown" msgid="7592128424511031410">"Անհայտ է"</string>
+ <string name="package_state_error" msgid="7672093962724223588">"Չի վերականգնվել"</string>
</resources>
diff --git a/res/values-in/strings.xml b/res/values-in/strings.xml
index d5df63b..ba85886 100644
--- a/res/values-in/strings.xml
+++ b/res/values-in/strings.xml
@@ -107,4 +107,9 @@
<string name="widget_button_text" msgid="2880537293434387943">"Widget"</string>
<string name="wallpaper_button_text" msgid="8404103075899945851">"Wallpaper"</string>
<string name="settings_button_text" msgid="8119458837558863227">"Setelan"</string>
+ <string name="package_state_enqueued" msgid="6227252464303085641">"Menunggu"</string>
+ <string name="package_state_downloading" msgid="4088770468458724721">"Mengunduh"</string>
+ <string name="package_state_installing" msgid="7588193972189849870">"Memasang"</string>
+ <string name="package_state_unknown" msgid="7592128424511031410">"Tidak dikenal"</string>
+ <string name="package_state_error" msgid="7672093962724223588">"Tak dipulihkan"</string>
</resources>
diff --git a/res/values-it/strings.xml b/res/values-it/strings.xml
index 20451d1..0d3bcc4 100644
--- a/res/values-it/strings.xml
+++ b/res/values-it/strings.xml
@@ -107,4 +107,9 @@
<string name="widget_button_text" msgid="2880537293434387943">"Widget"</string>
<string name="wallpaper_button_text" msgid="8404103075899945851">"Sfondi"</string>
<string name="settings_button_text" msgid="8119458837558863227">"Impostazioni"</string>
+ <string name="package_state_enqueued" msgid="6227252464303085641">"In attesa"</string>
+ <string name="package_state_downloading" msgid="4088770468458724721">"Download..."</string>
+ <string name="package_state_installing" msgid="7588193972189849870">"Installazione..."</string>
+ <string name="package_state_unknown" msgid="7592128424511031410">"Sconosciuto"</string>
+ <string name="package_state_error" msgid="7672093962724223588">"Non ripristinato"</string>
</resources>
diff --git a/res/values-iw/strings.xml b/res/values-iw/strings.xml
index 08d9653..cdfaf04 100644
--- a/res/values-iw/strings.xml
+++ b/res/values-iw/strings.xml
@@ -107,4 +107,9 @@
<string name="widget_button_text" msgid="2880537293434387943">"רכיבי ווידג\'ט"</string>
<string name="wallpaper_button_text" msgid="8404103075899945851">"טפטים"</string>
<string name="settings_button_text" msgid="8119458837558863227">"הגדרות"</string>
+ <string name="package_state_enqueued" msgid="6227252464303085641">"ממתין"</string>
+ <string name="package_state_downloading" msgid="4088770468458724721">"מוריד"</string>
+ <string name="package_state_installing" msgid="7588193972189849870">"מתקין"</string>
+ <string name="package_state_unknown" msgid="7592128424511031410">"לא ידוע"</string>
+ <string name="package_state_error" msgid="7672093962724223588">"לא שוחזרה"</string>
</resources>
diff --git a/res/values-ja/strings.xml b/res/values-ja/strings.xml
index ad5e8ff..e3ec47d 100644
--- a/res/values-ja/strings.xml
+++ b/res/values-ja/strings.xml
@@ -107,4 +107,9 @@
<string name="widget_button_text" msgid="2880537293434387943">"ウィジェット"</string>
<string name="wallpaper_button_text" msgid="8404103075899945851">"壁紙"</string>
<string name="settings_button_text" msgid="8119458837558863227">"設定"</string>
+ <string name="package_state_enqueued" msgid="6227252464303085641">"待機中"</string>
+ <string name="package_state_downloading" msgid="4088770468458724721">"ダウンロード中"</string>
+ <string name="package_state_installing" msgid="7588193972189849870">"インストール中"</string>
+ <string name="package_state_unknown" msgid="7592128424511031410">"不明"</string>
+ <string name="package_state_error" msgid="7672093962724223588">"復元失敗"</string>
</resources>
diff --git a/res/values-ka-rGE/strings.xml b/res/values-ka-rGE/strings.xml
index 086df72..de701ca 100644
--- a/res/values-ka-rGE/strings.xml
+++ b/res/values-ka-rGE/strings.xml
@@ -107,4 +107,9 @@
<string name="widget_button_text" msgid="2880537293434387943">"ვიჯეტები"</string>
<string name="wallpaper_button_text" msgid="8404103075899945851">"ფონები"</string>
<string name="settings_button_text" msgid="8119458837558863227">"პარამეტრები"</string>
+ <string name="package_state_enqueued" msgid="6227252464303085641">"მოცდა..."</string>
+ <string name="package_state_downloading" msgid="4088770468458724721">"ჩამოტვირთვა..."</string>
+ <string name="package_state_installing" msgid="7588193972189849870">"ინსტალაცია..."</string>
+ <string name="package_state_unknown" msgid="7592128424511031410">"უცნობი"</string>
+ <string name="package_state_error" msgid="7672093962724223588">"არ აღდგა"</string>
</resources>
diff --git a/res/values-km-rKH/strings.xml b/res/values-km-rKH/strings.xml
index 8bf26c2..7e6b799 100644
--- a/res/values-km-rKH/strings.xml
+++ b/res/values-km-rKH/strings.xml
@@ -107,4 +107,9 @@
<string name="widget_button_text" msgid="2880537293434387943">"ធាតុក្រាហ្វិក"</string>
<string name="wallpaper_button_text" msgid="8404103075899945851">"ផ្ទាំងរូបភាព"</string>
<string name="settings_button_text" msgid="8119458837558863227">"ការកំណត់"</string>
+ <string name="package_state_enqueued" msgid="6227252464303085641">"រង់ចាំ"</string>
+ <string name="package_state_downloading" msgid="4088770468458724721">"ទាញយក"</string>
+ <string name="package_state_installing" msgid="7588193972189849870">"ដំឡើង"</string>
+ <string name="package_state_unknown" msgid="7592128424511031410">"មិនស្គាល់"</string>
+ <string name="package_state_error" msgid="7672093962724223588">"មិនបានស្តារ"</string>
</resources>
diff --git a/res/values-ko/strings.xml b/res/values-ko/strings.xml
index dde4eb7..f8a06c7 100644
--- a/res/values-ko/strings.xml
+++ b/res/values-ko/strings.xml
@@ -107,4 +107,9 @@
<string name="widget_button_text" msgid="2880537293434387943">"위젯"</string>
<string name="wallpaper_button_text" msgid="8404103075899945851">"배경화면"</string>
<string name="settings_button_text" msgid="8119458837558863227">"설정"</string>
+ <string name="package_state_enqueued" msgid="6227252464303085641">"대기 중"</string>
+ <string name="package_state_downloading" msgid="4088770468458724721">"다운로드 중"</string>
+ <string name="package_state_installing" msgid="7588193972189849870">"설치 중"</string>
+ <string name="package_state_unknown" msgid="7592128424511031410">"알 수 없음"</string>
+ <string name="package_state_error" msgid="7672093962724223588">"복원되지 않음"</string>
</resources>
diff --git a/res/values-lo-rLA/strings.xml b/res/values-lo-rLA/strings.xml
index 50b5c08..a4fc842 100644
--- a/res/values-lo-rLA/strings.xml
+++ b/res/values-lo-rLA/strings.xml
@@ -107,4 +107,9 @@
<string name="widget_button_text" msgid="2880537293434387943">"ວິດເຈັດ"</string>
<string name="wallpaper_button_text" msgid="8404103075899945851">"ພາບພື້ນຫຼັງ"</string>
<string name="settings_button_text" msgid="8119458837558863227">"ການຕັ້ງຄ່າ"</string>
+ <string name="package_state_enqueued" msgid="6227252464303085641">"ກຳລັງລໍຖ້າ"</string>
+ <string name="package_state_downloading" msgid="4088770468458724721">"ກຳລັງດາວໂຫລດ"</string>
+ <string name="package_state_installing" msgid="7588193972189849870">"ກຳລັງຕິດຕັ້ງ"</string>
+ <string name="package_state_unknown" msgid="7592128424511031410">"ບໍ່ຮູ້ຈັກ"</string>
+ <string name="package_state_error" msgid="7672093962724223588">"ບໍ່ໄດ້ກູ້ຂໍ້ມູນມາເທື່ອ"</string>
</resources>
diff --git a/res/values-lt/strings.xml b/res/values-lt/strings.xml
index aba231d..471201d 100644
--- a/res/values-lt/strings.xml
+++ b/res/values-lt/strings.xml
@@ -107,4 +107,9 @@
<string name="widget_button_text" msgid="2880537293434387943">"Valdikliai"</string>
<string name="wallpaper_button_text" msgid="8404103075899945851">"Ekrano fonai"</string>
<string name="settings_button_text" msgid="8119458837558863227">"Nustatymai"</string>
+ <string name="package_state_enqueued" msgid="6227252464303085641">"Laukiama"</string>
+ <string name="package_state_downloading" msgid="4088770468458724721">"Atsisiunčiama"</string>
+ <string name="package_state_installing" msgid="7588193972189849870">"Diegiama"</string>
+ <string name="package_state_unknown" msgid="7592128424511031410">"Nežinoma"</string>
+ <string name="package_state_error" msgid="7672093962724223588">"Neatkurta"</string>
</resources>
diff --git a/res/values-lv/strings.xml b/res/values-lv/strings.xml
index 6d4888d..6fb7d60 100644
--- a/res/values-lv/strings.xml
+++ b/res/values-lv/strings.xml
@@ -107,4 +107,9 @@
<string name="widget_button_text" msgid="2880537293434387943">"Logrīki"</string>
<string name="wallpaper_button_text" msgid="8404103075899945851">"Fona tapetes"</string>
<string name="settings_button_text" msgid="8119458837558863227">"Iestatījumi"</string>
+ <string name="package_state_enqueued" msgid="6227252464303085641">"Gaida"</string>
+ <string name="package_state_downloading" msgid="4088770468458724721">"Lejupielādē"</string>
+ <string name="package_state_installing" msgid="7588193972189849870">"Instalē"</string>
+ <string name="package_state_unknown" msgid="7592128424511031410">"Nezināma"</string>
+ <string name="package_state_error" msgid="7672093962724223588">"Nav atjaunota"</string>
</resources>
diff --git a/res/values-mn-rMN/strings.xml b/res/values-mn-rMN/strings.xml
index db92a5c..a8ad568 100644
--- a/res/values-mn-rMN/strings.xml
+++ b/res/values-mn-rMN/strings.xml
@@ -107,4 +107,9 @@
<string name="widget_button_text" msgid="2880537293434387943">"Виджет"</string>
<string name="wallpaper_button_text" msgid="8404103075899945851">"Ханын зураг"</string>
<string name="settings_button_text" msgid="8119458837558863227">"Тохиргоо"</string>
+ <string name="package_state_enqueued" msgid="6227252464303085641">"Хүлээж байна"</string>
+ <string name="package_state_downloading" msgid="4088770468458724721">"Татаж авч байна"</string>
+ <string name="package_state_installing" msgid="7588193972189849870">"Суулгаж байна"</string>
+ <string name="package_state_unknown" msgid="7592128424511031410">"Тодорхойгүй"</string>
+ <string name="package_state_error" msgid="7672093962724223588">"Сэргээгээгүй"</string>
</resources>
diff --git a/res/values-ms-rMY/strings.xml b/res/values-ms-rMY/strings.xml
index 678eeb4..4c4b95f 100644
--- a/res/values-ms-rMY/strings.xml
+++ b/res/values-ms-rMY/strings.xml
@@ -107,4 +107,9 @@
<string name="widget_button_text" msgid="2880537293434387943">"Widget"</string>
<string name="wallpaper_button_text" msgid="8404103075899945851">"Kertas dinding"</string>
<string name="settings_button_text" msgid="8119458837558863227">"Tetapan"</string>
+ <string name="package_state_enqueued" msgid="6227252464303085641">"Menunggu"</string>
+ <string name="package_state_downloading" msgid="4088770468458724721">"Memuat turun"</string>
+ <string name="package_state_installing" msgid="7588193972189849870">"Memasang"</string>
+ <string name="package_state_unknown" msgid="7592128424511031410">"Tidak diketahui"</string>
+ <string name="package_state_error" msgid="7672093962724223588">"Tak dipulihkan"</string>
</resources>
diff --git a/res/values-nb/strings.xml b/res/values-nb/strings.xml
index dd89a4f..34cc488 100644
--- a/res/values-nb/strings.xml
+++ b/res/values-nb/strings.xml
@@ -107,4 +107,9 @@
<string name="widget_button_text" msgid="2880537293434387943">"Moduler"</string>
<string name="wallpaper_button_text" msgid="8404103075899945851">"Bakgrunner"</string>
<string name="settings_button_text" msgid="8119458837558863227">"Innstillinger"</string>
+ <string name="package_state_enqueued" msgid="6227252464303085641">"Venter …"</string>
+ <string name="package_state_downloading" msgid="4088770468458724721">"Laster ned …"</string>
+ <string name="package_state_installing" msgid="7588193972189849870">"Installerer …"</string>
+ <string name="package_state_unknown" msgid="7592128424511031410">"Ukjent"</string>
+ <string name="package_state_error" msgid="7672093962724223588">"Ikke gjenoppr."</string>
</resources>
diff --git a/res/values-nl/strings.xml b/res/values-nl/strings.xml
index d39c1ea..7bd3025 100644
--- a/res/values-nl/strings.xml
+++ b/res/values-nl/strings.xml
@@ -107,4 +107,9 @@
<string name="widget_button_text" msgid="2880537293434387943">"Widgets"</string>
<string name="wallpaper_button_text" msgid="8404103075899945851">"Achtergronden"</string>
<string name="settings_button_text" msgid="8119458837558863227">"Instellingen"</string>
+ <string name="package_state_enqueued" msgid="6227252464303085641">"Wachten"</string>
+ <string name="package_state_downloading" msgid="4088770468458724721">"Downloaden"</string>
+ <string name="package_state_installing" msgid="7588193972189849870">"Installeren"</string>
+ <string name="package_state_unknown" msgid="7592128424511031410">"Onbekend"</string>
+ <string name="package_state_error" msgid="7672093962724223588">"Niet hersteld"</string>
</resources>
diff --git a/res/values-pl/strings.xml b/res/values-pl/strings.xml
index b428a95..07d7465 100644
--- a/res/values-pl/strings.xml
+++ b/res/values-pl/strings.xml
@@ -107,4 +107,9 @@
<string name="widget_button_text" msgid="2880537293434387943">"Widżety"</string>
<string name="wallpaper_button_text" msgid="8404103075899945851">"Tapety"</string>
<string name="settings_button_text" msgid="8119458837558863227">"Ustawienia"</string>
+ <string name="package_state_enqueued" msgid="6227252464303085641">"Oczekiwanie"</string>
+ <string name="package_state_downloading" msgid="4088770468458724721">"Pobieranie"</string>
+ <string name="package_state_installing" msgid="7588193972189849870">"Instalowanie"</string>
+ <string name="package_state_unknown" msgid="7592128424511031410">"Brak informacji"</string>
+ <string name="package_state_error" msgid="7672093962724223588">"Nie przywrócono"</string>
</resources>
diff --git a/res/values-pt-rPT/strings.xml b/res/values-pt-rPT/strings.xml
index b8e51d6..0717c52 100644
--- a/res/values-pt-rPT/strings.xml
+++ b/res/values-pt-rPT/strings.xml
@@ -107,4 +107,9 @@
<string name="widget_button_text" msgid="2880537293434387943">"Widgets"</string>
<string name="wallpaper_button_text" msgid="8404103075899945851">"Imagens de fundo"</string>
<string name="settings_button_text" msgid="8119458837558863227">"Definições"</string>
+ <string name="package_state_enqueued" msgid="6227252464303085641">"A aguardar"</string>
+ <string name="package_state_downloading" msgid="4088770468458724721">"A transferir "</string>
+ <string name="package_state_installing" msgid="7588193972189849870">"A instalar"</string>
+ <string name="package_state_unknown" msgid="7592128424511031410">"Desconhecido"</string>
+ <string name="package_state_error" msgid="7672093962724223588">"Não restaurado"</string>
</resources>
diff --git a/res/values-pt/strings.xml b/res/values-pt/strings.xml
index 03c621a..e3f60ae 100644
--- a/res/values-pt/strings.xml
+++ b/res/values-pt/strings.xml
@@ -107,4 +107,9 @@
<string name="widget_button_text" msgid="2880537293434387943">"Widgets"</string>
<string name="wallpaper_button_text" msgid="8404103075899945851">"Planos de fundo"</string>
<string name="settings_button_text" msgid="8119458837558863227">"Configurações"</string>
+ <string name="package_state_enqueued" msgid="6227252464303085641">"Aguardando"</string>
+ <string name="package_state_downloading" msgid="4088770468458724721">"Transferindo"</string>
+ <string name="package_state_installing" msgid="7588193972189849870">"Instalando"</string>
+ <string name="package_state_unknown" msgid="7592128424511031410">"Desconhecido"</string>
+ <string name="package_state_error" msgid="7672093962724223588">"Não restaurado"</string>
</resources>
diff --git a/res/values-rm/strings.xml b/res/values-rm/strings.xml
index 3600095..be35c6b 100644
--- a/res/values-rm/strings.xml
+++ b/res/values-rm/strings.xml
@@ -192,4 +192,14 @@
<skip />
<!-- no translation found for settings_button_text (8119458837558863227) -->
<skip />
+ <!-- no translation found for package_state_enqueued (6227252464303085641) -->
+ <skip />
+ <!-- no translation found for package_state_downloading (4088770468458724721) -->
+ <skip />
+ <!-- no translation found for package_state_installing (7588193972189849870) -->
+ <skip />
+ <!-- no translation found for package_state_unknown (7592128424511031410) -->
+ <skip />
+ <!-- no translation found for package_state_error (7672093962724223588) -->
+ <skip />
</resources>
diff --git a/res/values-ro/strings.xml b/res/values-ro/strings.xml
index a667ffd..48fa11e 100644
--- a/res/values-ro/strings.xml
+++ b/res/values-ro/strings.xml
@@ -107,4 +107,9 @@
<string name="widget_button_text" msgid="2880537293434387943">"Widgeturi"</string>
<string name="wallpaper_button_text" msgid="8404103075899945851">"Imagini de fundal"</string>
<string name="settings_button_text" msgid="8119458837558863227">"Setări"</string>
+ <string name="package_state_enqueued" msgid="6227252464303085641">"În așteptare"</string>
+ <string name="package_state_downloading" msgid="4088770468458724721">"Se descarcă"</string>
+ <string name="package_state_installing" msgid="7588193972189849870">"Se instalează"</string>
+ <string name="package_state_unknown" msgid="7592128424511031410">"Necunoscut"</string>
+ <string name="package_state_error" msgid="7672093962724223588">"Nerestabilit"</string>
</resources>
diff --git a/res/values-ru/strings.xml b/res/values-ru/strings.xml
index c2e8bc7..8303350 100644
--- a/res/values-ru/strings.xml
+++ b/res/values-ru/strings.xml
@@ -107,4 +107,9 @@
<string name="widget_button_text" msgid="2880537293434387943">"Виджеты"</string>
<string name="wallpaper_button_text" msgid="8404103075899945851">"Обои"</string>
<string name="settings_button_text" msgid="8119458837558863227">"Настройки"</string>
+ <string name="package_state_enqueued" msgid="6227252464303085641">"Ожидается"</string>
+ <string name="package_state_downloading" msgid="4088770468458724721">"Скачивается"</string>
+ <string name="package_state_installing" msgid="7588193972189849870">"Устанавливается"</string>
+ <string name="package_state_unknown" msgid="7592128424511031410">"Неизвестно"</string>
+ <string name="package_state_error" msgid="7672093962724223588">"Не восстановлен"</string>
</resources>
diff --git a/res/values-sk/strings.xml b/res/values-sk/strings.xml
index acd8e05..b274926 100644
--- a/res/values-sk/strings.xml
+++ b/res/values-sk/strings.xml
@@ -107,4 +107,9 @@
<string name="widget_button_text" msgid="2880537293434387943">"Miniaplikácie"</string>
<string name="wallpaper_button_text" msgid="8404103075899945851">"Tapety"</string>
<string name="settings_button_text" msgid="8119458837558863227">"Nastavenia"</string>
+ <string name="package_state_enqueued" msgid="6227252464303085641">"Čaká sa"</string>
+ <string name="package_state_downloading" msgid="4088770468458724721">"Sťahovanie"</string>
+ <string name="package_state_installing" msgid="7588193972189849870">"Inštalácia"</string>
+ <string name="package_state_unknown" msgid="7592128424511031410">"Neznáme"</string>
+ <string name="package_state_error" msgid="7672093962724223588">"Nebolo obnovené"</string>
</resources>
diff --git a/res/values-sl/strings.xml b/res/values-sl/strings.xml
index afbd620..62d90bb 100644
--- a/res/values-sl/strings.xml
+++ b/res/values-sl/strings.xml
@@ -107,4 +107,9 @@
<string name="widget_button_text" msgid="2880537293434387943">"Pripomočki"</string>
<string name="wallpaper_button_text" msgid="8404103075899945851">"Ozadja"</string>
<string name="settings_button_text" msgid="8119458837558863227">"Nastavitve"</string>
+ <string name="package_state_enqueued" msgid="6227252464303085641">"Čakanje"</string>
+ <string name="package_state_downloading" msgid="4088770468458724721">"Prenašanje"</string>
+ <string name="package_state_installing" msgid="7588193972189849870">"Nameščanje"</string>
+ <string name="package_state_unknown" msgid="7592128424511031410">"Neznano"</string>
+ <string name="package_state_error" msgid="7672093962724223588">"Ni obnovljen"</string>
</resources>
diff --git a/res/values-sr/strings.xml b/res/values-sr/strings.xml
index bf71b28..9b30913 100644
--- a/res/values-sr/strings.xml
+++ b/res/values-sr/strings.xml
@@ -107,4 +107,9 @@
<string name="widget_button_text" msgid="2880537293434387943">"Виџети"</string>
<string name="wallpaper_button_text" msgid="8404103075899945851">"Позадине"</string>
<string name="settings_button_text" msgid="8119458837558863227">"Подешавања"</string>
+ <string name="package_state_enqueued" msgid="6227252464303085641">"Чека се"</string>
+ <string name="package_state_downloading" msgid="4088770468458724721">"Преузима се"</string>
+ <string name="package_state_installing" msgid="7588193972189849870">"Инсталира се"</string>
+ <string name="package_state_unknown" msgid="7592128424511031410">"Непознато"</string>
+ <string name="package_state_error" msgid="7672093962724223588">"Није враћено"</string>
</resources>
diff --git a/res/values-sv/strings.xml b/res/values-sv/strings.xml
index 5825eec..0469a8a 100644
--- a/res/values-sv/strings.xml
+++ b/res/values-sv/strings.xml
@@ -107,4 +107,9 @@
<string name="widget_button_text" msgid="2880537293434387943">"Widgetar"</string>
<string name="wallpaper_button_text" msgid="8404103075899945851">"Bakgrunder"</string>
<string name="settings_button_text" msgid="8119458837558863227">"Inställningar"</string>
+ <string name="package_state_enqueued" msgid="6227252464303085641">"Väntar"</string>
+ <string name="package_state_downloading" msgid="4088770468458724721">"Hämtas"</string>
+ <string name="package_state_installing" msgid="7588193972189849870">"Installerar"</string>
+ <string name="package_state_unknown" msgid="7592128424511031410">"Okänt"</string>
+ <string name="package_state_error" msgid="7672093962724223588">"Inte återställt"</string>
</resources>
diff --git a/res/values-sw/strings.xml b/res/values-sw/strings.xml
index d2a282a..81126fd 100644
--- a/res/values-sw/strings.xml
+++ b/res/values-sw/strings.xml
@@ -109,4 +109,9 @@
<string name="widget_button_text" msgid="2880537293434387943">"Wijeti"</string>
<string name="wallpaper_button_text" msgid="8404103075899945851">"Mandhari"</string>
<string name="settings_button_text" msgid="8119458837558863227">"Mipangilio"</string>
+ <string name="package_state_enqueued" msgid="6227252464303085641">"Inasubiri"</string>
+ <string name="package_state_downloading" msgid="4088770468458724721">"Inapakua"</string>
+ <string name="package_state_installing" msgid="7588193972189849870">"Inasakinisha"</string>
+ <string name="package_state_unknown" msgid="7592128424511031410">"Yasiyojulikana"</string>
+ <string name="package_state_error" msgid="7672093962724223588">"Haijarejeshwa"</string>
</resources>
diff --git a/res/values-th/strings.xml b/res/values-th/strings.xml
index beaa0ae..1d69750 100644
--- a/res/values-th/strings.xml
+++ b/res/values-th/strings.xml
@@ -107,4 +107,9 @@
<string name="widget_button_text" msgid="2880537293434387943">"วิดเจ็ต"</string>
<string name="wallpaper_button_text" msgid="8404103075899945851">"วอลเปเปอร์"</string>
<string name="settings_button_text" msgid="8119458837558863227">"การตั้งค่า"</string>
+ <string name="package_state_enqueued" msgid="6227252464303085641">"กำลังรอ"</string>
+ <string name="package_state_downloading" msgid="4088770468458724721">"กำลังดาวน์โหลด"</string>
+ <string name="package_state_installing" msgid="7588193972189849870">"กำลังติดตั้ง"</string>
+ <string name="package_state_unknown" msgid="7592128424511031410">"ไม่รู้จัก"</string>
+ <string name="package_state_error" msgid="7672093962724223588">"ไม่ได้คืนค่า"</string>
</resources>
diff --git a/res/values-tl/strings.xml b/res/values-tl/strings.xml
index 5be9d85..d30fb11 100644
--- a/res/values-tl/strings.xml
+++ b/res/values-tl/strings.xml
@@ -107,4 +107,9 @@
<string name="widget_button_text" msgid="2880537293434387943">"Mga Widget"</string>
<string name="wallpaper_button_text" msgid="8404103075899945851">"Mga Wallpaper"</string>
<string name="settings_button_text" msgid="8119458837558863227">"Mga Setting"</string>
+ <string name="package_state_enqueued" msgid="6227252464303085641">"Naghihintay"</string>
+ <string name="package_state_downloading" msgid="4088770468458724721">"Nagda-download"</string>
+ <string name="package_state_installing" msgid="7588193972189849870">"Nag-i-install"</string>
+ <string name="package_state_unknown" msgid="7592128424511031410">"Hindi kilala"</string>
+ <string name="package_state_error" msgid="7672093962724223588">"Hindi naibalik"</string>
</resources>
diff --git a/res/values-tr/strings.xml b/res/values-tr/strings.xml
index 01f79a2..bdc97df 100644
--- a/res/values-tr/strings.xml
+++ b/res/values-tr/strings.xml
@@ -107,4 +107,9 @@
<string name="widget_button_text" msgid="2880537293434387943">"Widget\'lar"</string>
<string name="wallpaper_button_text" msgid="8404103075899945851">"Duvar Kağıtları"</string>
<string name="settings_button_text" msgid="8119458837558863227">"Ayarlar"</string>
+ <string name="package_state_enqueued" msgid="6227252464303085641">"Bekliyor"</string>
+ <string name="package_state_downloading" msgid="4088770468458724721">"İndiriliyor"</string>
+ <string name="package_state_installing" msgid="7588193972189849870">"Yükleniyor"</string>
+ <string name="package_state_unknown" msgid="7592128424511031410">"Bilinmiyor"</string>
+ <string name="package_state_error" msgid="7672093962724223588">"Geri yüklenmedi"</string>
</resources>
diff --git a/res/values-uk/strings.xml b/res/values-uk/strings.xml
index f266eea..94df4f3 100644
--- a/res/values-uk/strings.xml
+++ b/res/values-uk/strings.xml
@@ -107,4 +107,9 @@
<string name="widget_button_text" msgid="2880537293434387943">"Віджети"</string>
<string name="wallpaper_button_text" msgid="8404103075899945851">"Фонові малюнки"</string>
<string name="settings_button_text" msgid="8119458837558863227">"Налаштування"</string>
+ <string name="package_state_enqueued" msgid="6227252464303085641">"Очікування"</string>
+ <string name="package_state_downloading" msgid="4088770468458724721">"Завантаження"</string>
+ <string name="package_state_installing" msgid="7588193972189849870">"Встановлення"</string>
+ <string name="package_state_unknown" msgid="7592128424511031410">"Невідомо"</string>
+ <string name="package_state_error" msgid="7672093962724223588">"Не відновлено"</string>
</resources>
diff --git a/res/values-vi/strings.xml b/res/values-vi/strings.xml
index 9d4ed41..434b556 100644
--- a/res/values-vi/strings.xml
+++ b/res/values-vi/strings.xml
@@ -107,4 +107,9 @@
<string name="widget_button_text" msgid="2880537293434387943">"Tiện ích con"</string>
<string name="wallpaper_button_text" msgid="8404103075899945851">"Hình nền"</string>
<string name="settings_button_text" msgid="8119458837558863227">"Cài đặt"</string>
+ <string name="package_state_enqueued" msgid="6227252464303085641">"Đang đợi"</string>
+ <string name="package_state_downloading" msgid="4088770468458724721">"Đang tải xuống"</string>
+ <string name="package_state_installing" msgid="7588193972189849870">"Đang cài đặt"</string>
+ <string name="package_state_unknown" msgid="7592128424511031410">"Không xác định"</string>
+ <string name="package_state_error" msgid="7672093962724223588">"Không được khôi phục"</string>
</resources>
diff --git a/res/values-zh-rCN/strings.xml b/res/values-zh-rCN/strings.xml
index 3a2638e..a771f47 100644
--- a/res/values-zh-rCN/strings.xml
+++ b/res/values-zh-rCN/strings.xml
@@ -107,4 +107,9 @@
<string name="widget_button_text" msgid="2880537293434387943">"小部件"</string>
<string name="wallpaper_button_text" msgid="8404103075899945851">"壁纸"</string>
<string name="settings_button_text" msgid="8119458837558863227">"设置"</string>
+ <string name="package_state_enqueued" msgid="6227252464303085641">"正在等待"</string>
+ <string name="package_state_downloading" msgid="4088770468458724721">"正在下载"</string>
+ <string name="package_state_installing" msgid="7588193972189849870">"正在安装"</string>
+ <string name="package_state_unknown" msgid="7592128424511031410">"未知"</string>
+ <string name="package_state_error" msgid="7672093962724223588">"无法还原"</string>
</resources>
diff --git a/res/values-zh-rHK/strings.xml b/res/values-zh-rHK/strings.xml
index cad95f2..ed19b44 100644
--- a/res/values-zh-rHK/strings.xml
+++ b/res/values-zh-rHK/strings.xml
@@ -107,4 +107,9 @@
<string name="widget_button_text" msgid="2880537293434387943">"小工具"</string>
<string name="wallpaper_button_text" msgid="8404103075899945851">"桌布"</string>
<string name="settings_button_text" msgid="8119458837558863227">"設定"</string>
+ <string name="package_state_enqueued" msgid="6227252464303085641">"等候中"</string>
+ <string name="package_state_downloading" msgid="4088770468458724721">"下載中"</string>
+ <string name="package_state_installing" msgid="7588193972189849870">"安裝中"</string>
+ <string name="package_state_unknown" msgid="7592128424511031410">"不明"</string>
+ <string name="package_state_error" msgid="7672093962724223588">"無法還原"</string>
</resources>
diff --git a/res/values-zh-rTW/strings.xml b/res/values-zh-rTW/strings.xml
index 5f48243..2449f60 100644
--- a/res/values-zh-rTW/strings.xml
+++ b/res/values-zh-rTW/strings.xml
@@ -107,4 +107,9 @@
<string name="widget_button_text" msgid="2880537293434387943">"小工具"</string>
<string name="wallpaper_button_text" msgid="8404103075899945851">"桌布"</string>
<string name="settings_button_text" msgid="8119458837558863227">"設定"</string>
+ <string name="package_state_enqueued" msgid="6227252464303085641">"等待中"</string>
+ <string name="package_state_downloading" msgid="4088770468458724721">"下載中…"</string>
+ <string name="package_state_installing" msgid="7588193972189849870">"安裝中"</string>
+ <string name="package_state_unknown" msgid="7592128424511031410">"不明"</string>
+ <string name="package_state_error" msgid="7672093962724223588">"無法還原"</string>
</resources>
diff --git a/res/values-zu/strings.xml b/res/values-zu/strings.xml
index e982eb4..209816e 100644
--- a/res/values-zu/strings.xml
+++ b/res/values-zu/strings.xml
@@ -107,4 +107,9 @@
<string name="widget_button_text" msgid="2880537293434387943">"Amawijethi"</string>
<string name="wallpaper_button_text" msgid="8404103075899945851">"Izithombe zangemuva"</string>
<string name="settings_button_text" msgid="8119458837558863227">"Izilungiselelo"</string>
+ <string name="package_state_enqueued" msgid="6227252464303085641">"Ilindile"</string>
+ <string name="package_state_downloading" msgid="4088770468458724721">"Iyalanda"</string>
+ <string name="package_state_installing" msgid="7588193972189849870">"Iyafaka"</string>
+ <string name="package_state_unknown" msgid="7592128424511031410">"Akwaziwa"</string>
+ <string name="package_state_error" msgid="7672093962724223588">"Ayibuyiselwe"</string>
</resources>
diff --git a/res/values/integers.xml b/res/values/integers.xml
new file mode 100644
index 0000000..7d26d85
--- /dev/null
+++ b/res/values/integers.xml
@@ -0,0 +1,22 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+/*
+* 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.
+*/
+-->
+
+<resources>
+ <integer name="promise_icon_alpha">127</integer>
+</resources>
\ No newline at end of file
diff --git a/res/values/strings.xml b/res/values/strings.xml
index 9cb6c29..ad3a1c4 100644
--- a/res/values/strings.xml
+++ b/res/values/strings.xml
@@ -20,6 +20,10 @@
<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
<!-- General -->
<skip />
+
+ <!-- URI used to import old favorites. [DO NOT TRANSLATE] -->
+ <string name="old_launcher_provider_uri" translatable="false">content://com.android.launcher2.settings/favorites?notify=true</string>
+
<!-- Application name -->
<string name="application_name">Launcher3</string>
<!-- Accessibility-facing application name -->
@@ -262,4 +266,15 @@
<string name="wallpaper_button_text">Wallpapers</string>
<!-- Text for settings button -->
<string name="settings_button_text">Settings</string>
+
+ <!-- Label on an icon that references an uninstalled package, that is going to be installed at some point. [CHAR_LIMIT=15] -->
+ <string name="package_state_enqueued">Waiting</string>
+ <!-- Label on an icon that references an uninstalled package, that is currently being downloaded. [CHAR_LIMIT=15] -->
+ <string name="package_state_downloading">Downloading</string>
+ <!-- Label on an icon that references an uninstalled package, that is currently being installed. [CHAR_LIMIT=15] -->
+ <string name="package_state_installing">Installing</string>
+ <!-- Label on an icon that references an uninstalled package, for which we have no information about when it might be installed. [CHAR_LIMIT=15] -->
+ <string name="package_state_unknown">Unknown</string>
+ <!-- Label on an icon that references an uninstalled package, for which restore from market has failed. [CHAR_LIMIT=15] -->
+ <string name="package_state_error">Not restored</string>
</resources>
diff --git a/res/xml-sw600dp/default_workspace.xml b/res/xml-sw600dp/default_workspace.xml
index 090c7a7..d42a93a 100644
--- a/res/xml-sw600dp/default_workspace.xml
+++ b/res/xml-sw600dp/default_workspace.xml
@@ -60,13 +60,21 @@
<!-- Far-right screen [4] -->
<!-- Hotseat (We use the screen as the position of the item in the hotseat) -->
- <favorite
- launcher:packageName="com.android.dialer"
- launcher:className="com.android.dialer.DialtactsActivity"
+ <!-- Dialer, Contacts, [All Apps], Messaging, Browser -->
+ <resolve
launcher:container="-101"
launcher:screen="1"
launcher:x="1"
- launcher:y="0" />
+ launcher:y="0" >
+ <favorite launcher:uri="#Intent;action=android.intent.action.DIAL;end" />
+ <favorite launcher:uri="tel:123" />
+ <favorite launcher:uri="#Intent;action=android.intent.action.CALL_BUTTON;end" />
+
+ <favorite
+ launcher:packageName="com.android.dialer"
+ launcher:className="com.android.dialer.DialtactsActivity" />
+ </resolve>
+
<favorite
launcher:packageName="com.android.contacts"
launcher:className="com.android.contacts.activities.PeopleActivity"
@@ -74,18 +82,34 @@
launcher:screen="2"
launcher:x="2"
launcher:y="0" />
- <favorite
- launcher:packageName="com.android.mms"
- launcher:className="com.android.mms.ui.ConversationList"
+
+ <resolve
launcher:container="-101"
launcher:screen="4"
launcher:x="4"
- launcher:y="0" />
- <favorite
- launcher:packageName="com.android.browser"
- launcher:className="com.android.browser.BrowserActivity"
+ launcher:y="0" >
+ <favorite
+ launcher:uri="#Intent;action=android.intent.action.MAIN;category=android.intent.category.APP_MESSAGING;end" />
+ <favorite launcher:uri="sms:" />
+ <favorite launcher:uri="smsto:" />
+ <favorite launcher:uri="mms:" />
+ <favorite launcher:uri="mmsto:" />
+
+ <favorite
+ launcher:packageName="com.android.mms"
+ launcher:className="com.android.mms.ui.ConversationList" />
+ </resolve>
+ <resolve
launcher:container="-101"
launcher:screen="5"
launcher:x="5"
- launcher:y="0" />
+ launcher:y="0" >
+ <favorite
+ launcher:uri="#Intent;action=android.intent.action.MAIN;category=android.intent.category.APP_BROWSER;end" />
+ <favorite launcher:uri="http://www.example.com/" />
+
+ <favorite
+ launcher:packageName="com.android.browser"
+ launcher:className="com.android.browser.BrowserActivity" />
+ </resolve>
</favorites>
diff --git a/res/xml/default_workspace.xml b/res/xml/default_workspace.xml
index 26fc504..9bec86a 100644
--- a/res/xml/default_workspace.xml
+++ b/res/xml/default_workspace.xml
@@ -60,13 +60,21 @@
<!-- Far-right screen [4] -->
<!-- Hotseat (We use the screen as the position of the item in the hotseat) -->
- <favorite
- launcher:packageName="com.android.dialer"
- launcher:className="com.android.dialer.DialtactsActivity"
+ <!-- Dialer, Contacts, [All Apps], Messaging, Browser -->
+ <resolve
launcher:container="-101"
launcher:screen="0"
launcher:x="0"
- launcher:y="0" />
+ launcher:y="0" >
+ <favorite launcher:uri="#Intent;action=android.intent.action.DIAL;end" />
+ <favorite launcher:uri="tel:123" />
+ <favorite launcher:uri="#Intent;action=android.intent.action.CALL_BUTTON;end" />
+
+ <favorite
+ launcher:packageName="com.android.dialer"
+ launcher:className="com.android.dialer.DialtactsActivity" />
+ </resolve>
+
<favorite
launcher:packageName="com.android.contacts"
launcher:className="com.android.contacts.activities.PeopleActivity"
@@ -74,18 +82,35 @@
launcher:screen="1"
launcher:x="1"
launcher:y="0" />
- <favorite
- launcher:packageName="com.android.mms"
- launcher:className="com.android.mms.ui.ConversationList"
+
+ <resolve
launcher:container="-101"
launcher:screen="3"
launcher:x="3"
- launcher:y="0" />
- <favorite
- launcher:packageName="com.android.browser"
- launcher:className="com.android.browser.BrowserActivity"
+ launcher:y="0" >
+ <favorite
+ launcher:uri="#Intent;action=android.intent.action.MAIN;category=android.intent.category.APP_MESSAGING;end" />
+ <favorite launcher:uri="sms:" />
+ <favorite launcher:uri="smsto:" />
+ <favorite launcher:uri="mms:" />
+ <favorite launcher:uri="mmsto:" />
+
+ <favorite
+ launcher:packageName="com.android.mms"
+ launcher:className="com.android.mms.ui.ConversationList" />
+ </resolve>
+ <resolve
launcher:container="-101"
launcher:screen="4"
launcher:x="4"
- launcher:y="0" />
+ launcher:y="0" >
+ <favorite
+ launcher:uri="#Intent;action=android.intent.action.MAIN;category=android.intent.category.APP_BROWSER;end" />
+ <favorite launcher:uri="http://www.example.com/" />
+
+ <favorite
+ launcher:packageName="com.android.browser"
+ launcher:className="com.android.browser.BrowserActivity" />
+ </resolve>
+
</favorites>
diff --git a/src/com/android/launcher3/AppInfo.java b/src/com/android/launcher3/AppInfo.java
index da222f1..f85f691 100644
--- a/src/com/android/launcher3/AppInfo.java
+++ b/src/com/android/launcher3/AppInfo.java
@@ -31,7 +31,7 @@
/**
* Represents an app in AllAppsView.
*/
-class AppInfo extends ItemInfo {
+public class AppInfo extends ItemInfo {
private static final String TAG = "Launcher3.AppInfo";
/**
@@ -60,7 +60,7 @@
itemType = LauncherSettings.BaseLauncherColumns.ITEM_TYPE_SHORTCUT;
}
- protected Intent getIntent() {
+ public Intent getIntent() {
return intent;
}
diff --git a/src/com/android/launcher3/AppsCustomizePagedView.java b/src/com/android/launcher3/AppsCustomizePagedView.java
index 251ae21..d6e0bb4 100644
--- a/src/com/android/launcher3/AppsCustomizePagedView.java
+++ b/src/com/android/launcher3/AppsCustomizePagedView.java
@@ -225,17 +225,6 @@
private Rect mTmpRect = new Rect();
- // Used for drawing shortcut previews
- BitmapCache mCachedShortcutPreviewBitmap = new BitmapCache();
- PaintCache mCachedShortcutPreviewPaint = new PaintCache();
- CanvasCache mCachedShortcutPreviewCanvas = new CanvasCache();
-
- // Used for drawing widget previews
- CanvasCache mCachedAppWidgetPreviewCanvas = new CanvasCache();
- RectCache mCachedAppWidgetPreviewSrcRect = new RectCache();
- RectCache mCachedAppWidgetPreviewDestRect = new RectCache();
- PaintCache mCachedAppWidgetPreviewPaint = new PaintCache();
-
WidgetPreviewLoader mWidgetPreviewLoader;
private boolean mInBulkBind;
@@ -511,8 +500,7 @@
if (mPressedIcon != null) {
mPressedIcon.lockDrawableState();
}
- mLauncher.startActivitySafely(v, appInfo.intent, appInfo);
- mLauncher.getStats().recordLaunch(appInfo.intent);
+ 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) {
diff --git a/src/com/android/launcher3/BubbleTextView.java b/src/com/android/launcher3/BubbleTextView.java
index ee42904..c180d32 100644
--- a/src/com/android/launcher3/BubbleTextView.java
+++ b/src/com/android/launcher3/BubbleTextView.java
@@ -25,6 +25,7 @@
import android.graphics.Region.Op;
import android.graphics.drawable.Drawable;
import android.util.AttributeSet;
+import android.util.Log;
import android.util.TypedValue;
import android.view.MotionEvent;
import android.widget.TextView;
@@ -43,6 +44,10 @@
static final float PADDING_H = 8.0f;
static final float PADDING_V = 3.0f;
+ private static final String TAG = "BubbleTextView";
+
+ private static final boolean DEBUG = false;
+
private int mPrevAlpha = -1;
private HolographicOutlineHelper mOutlineHelper;
@@ -64,6 +69,11 @@
private boolean mStayPressed;
private CheckLongPressHelper mLongPressHelper;
+ private int mInstallState;
+
+ private int mState;
+
+ private CharSequence mDefaultText = "";
public BubbleTextView(Context context) {
super(context);
@@ -108,11 +118,14 @@
LauncherAppState app = LauncherAppState.getInstance();
DeviceProfile grid = app.getDynamicGrid().getDeviceProfile();
- setCompoundDrawables(null,
- Utilities.createIconDrawable(b), null, null);
+ Drawable iconDrawable = Utilities.createIconDrawable(b);
+ setCompoundDrawables(null, iconDrawable, null, null);
setCompoundDrawablePadding(grid.iconDrawablePaddingPx);
setText(info.title);
setTag(info);
+ if (info.isPromise()) {
+ setState(ShortcutInfo.PACKAGE_STATE_UNKNOWN); // TODO: persist this state somewhere
+ }
}
@Override
@@ -392,4 +405,52 @@
mLongPressHelper.cancelLongPress();
}
+
+ public void setState(int state) {
+ if (mState == ShortcutInfo.PACKAGE_STATE_DEFAULT && mState != state) {
+ mDefaultText = getText();
+ }
+ mState = state;
+ applyState();
+ }
+
+ private void applyState() {
+ int alpha = getResources().getInteger(R.integer.promise_icon_alpha);
+ if (DEBUG) Log.d(TAG, "applying icon state: " + mState);
+
+ switch(mState) {
+ case ShortcutInfo.PACKAGE_STATE_DEFAULT:
+ super.setText(mDefaultText);
+ alpha = 255;
+ break;
+
+ case ShortcutInfo.PACKAGE_STATE_ENQUEUED:
+ setText(R.string.package_state_enqueued);
+ break;
+
+ case ShortcutInfo.PACKAGE_STATE_DOWNLOADING:
+ setText(R.string.package_state_downloading);
+ break;
+
+ case ShortcutInfo.PACKAGE_STATE_INSTALLING:
+ setText(R.string.package_state_installing);
+ break;
+
+ case ShortcutInfo.PACKAGE_STATE_ERROR:
+ setText(R.string.package_state_error);
+ break;
+
+ case ShortcutInfo.PACKAGE_STATE_UNKNOWN:
+ default:
+ setText(R.string.package_state_unknown);
+ break;
+ }
+ if (DEBUG) Log.d(TAG, "setting icon alpha to: " + alpha);
+ Drawable[] drawables = getCompoundDrawables();
+ for (int i = 0; i < drawables.length; i++) {
+ if (drawables[i] != null) {
+ drawables[i].setAlpha(alpha);
+ }
+ }
+ }
}
diff --git a/src/com/android/launcher3/DragLayer.java b/src/com/android/launcher3/DragLayer.java
index 862ceca..c54db01 100644
--- a/src/com/android/launcher3/DragLayer.java
+++ b/src/com/android/launcher3/DragLayer.java
@@ -73,7 +73,9 @@
private final Rect mInsets = new Rect();
- private int mDragViewIndex;
+ private View mOverlayView;
+ private int mTopViewIndex;
+ private int mChildCountOnLastUpdate = -1;
/**
* Used to create a new DragLayer from XML.
@@ -120,6 +122,20 @@
setInsets(child, mInsets, new Rect());
}
+ public void showOverlayView(View overlayView) {
+ LayoutParams lp = new LayoutParams(LayoutParams.MATCH_PARENT, LayoutParams.MATCH_PARENT);
+ mOverlayView = overlayView;
+ addView(overlayView, lp);
+
+ // ensure that the overlay view stays on top. we can't use drawing order for this
+ // because in API level 16 touch dispatch doesn't respect drawing order.
+ mOverlayView.bringToFront();
+ }
+
+ public void dismissOverlayView() {
+ removeView(mOverlayView);
+ }
+
private void setInsets(View child, Rect newInsets, Rect oldInsets) {
final FrameLayout.LayoutParams flp = (FrameLayout.LayoutParams) child.getLayoutParams();
if (child instanceof Insettable) {
@@ -762,6 +778,11 @@
@Override
public void onChildViewAdded(View parent, View child) {
+ if (mOverlayView != null) {
+ // ensure that the overlay view stays on top. we can't use drawing order for this
+ // because in API level 16 touch dispatch doesn't respect drawing order.
+ mOverlayView.bringToFront();
+ }
updateChildIndices();
}
@@ -770,27 +791,51 @@
updateChildIndices();
}
+ @Override
+ public void bringChildToFront(View child) {
+ super.bringChildToFront(child);
+ if (child != mOverlayView && mOverlayView != null) {
+ // ensure that the overlay view stays on top. we can't use drawing order for this
+ // because in API level 16 touch dispatch doesn't respect drawing order.
+ mOverlayView.bringToFront();
+ }
+ updateChildIndices();
+ }
+
private void updateChildIndices() {
- mDragViewIndex = -1;
+ mTopViewIndex = -1;
int childCount = getChildCount();
for (int i = 0; i < childCount; i++) {
if (getChildAt(i) instanceof DragView) {
- mDragViewIndex = i;
+ mTopViewIndex = i;
}
}
+ mChildCountOnLastUpdate = childCount;
}
@Override
protected int getChildDrawingOrder(int childCount, int i) {
- if (mDragViewIndex == -1) {
+ if (mChildCountOnLastUpdate != childCount) {
+ // between platform versions 17 and 18, behavior for onChildViewRemoved / Added changed.
+ // Pre-18, the child was not added / removed by the time of those callbacks. We need to
+ // force update our representation of things here to avoid crashing on pre-18 devices
+ // in certain instances.
+ updateChildIndices();
+ }
+
+ // i represents the current draw iteration
+ if (mTopViewIndex == -1) {
+ // in general we do nothing
return i;
- } else if (i == mDragViewIndex) {
- return getChildCount()-1;
- } else if (i < mDragViewIndex) {
+ } else if (i == childCount - 1) {
+ // if we have a top index, we return it when drawing last item (highest z-order)
+ return mTopViewIndex;
+ } else if (i < mTopViewIndex) {
return i;
} else {
- // i > mDragViewIndex
- return i-1;
+ // for indexes greater than the top index, we fetch one item above to shift for the
+ // displacement of the top index
+ return i + 1;
}
}
diff --git a/src/com/android/launcher3/Folder.java b/src/com/android/launcher3/Folder.java
index b4c3992..fb226e5 100644
--- a/src/com/android/launcher3/Folder.java
+++ b/src/com/android/launcher3/Folder.java
@@ -303,6 +303,10 @@
return mFolderName;
}
+ public CellLayout getContent() {
+ return mContent;
+ }
+
/**
* We need to handle touch events to prevent them from falling through to the workspace below.
*/
diff --git a/src/com/android/launcher3/FolderIcon.java b/src/com/android/launcher3/FolderIcon.java
index 78026f1..71a7461 100644
--- a/src/com/android/launcher3/FolderIcon.java
+++ b/src/com/android/launcher3/FolderIcon.java
@@ -308,7 +308,7 @@
}
}
- Folder getFolder() {
+ public Folder getFolder() {
return mFolder;
}
diff --git a/src/com/android/launcher3/FolderInfo.java b/src/com/android/launcher3/FolderInfo.java
index d45e4e4..42e2ec3 100644
--- a/src/com/android/launcher3/FolderInfo.java
+++ b/src/com/android/launcher3/FolderInfo.java
@@ -23,7 +23,7 @@
/**
* Represents a folder containing shortcuts or apps.
*/
-class FolderInfo extends ItemInfo {
+public class FolderInfo extends ItemInfo {
/**
* Whether this folder has been opened
diff --git a/src/com/android/launcher3/Hotseat.java b/src/com/android/launcher3/Hotseat.java
index 59d60e3..2ac2f00 100644
--- a/src/com/android/launcher3/Hotseat.java
+++ b/src/com/android/launcher3/Hotseat.java
@@ -156,15 +156,9 @@
allAppsButton.setContentDescription(context.getString(R.string.all_apps_button_label));
if (mLauncher != null) {
allAppsButton.setOnTouchListener(mLauncher.getHapticFeedbackTouchListener());
+ mLauncher.setAllAppsButton(allAppsButton);
+ allAppsButton.setOnClickListener(mLauncher);
}
- allAppsButton.setOnClickListener(new View.OnClickListener() {
- @Override
- public void onClick(android.view.View v) {
- if (mLauncher != null) {
- mLauncher.onClickAllAppsButton(v);
- }
- }
- });
// Note: We do this to ensure that the hotseat is always laid out in the orientation of
// the hotseat in order regardless of which orientation they were added
diff --git a/src/com/android/launcher3/IconCache.java b/src/com/android/launcher3/IconCache.java
index 827718b..ee9f4d4 100644
--- a/src/com/android/launcher3/IconCache.java
+++ b/src/com/android/launcher3/IconCache.java
@@ -387,20 +387,6 @@
}
}
- if (icon != null) {
- // TODO: handle alpha mask in the view layer
- Bitmap b = Bitmap.createBitmap(Math.max(icon.getWidth(), 1),
- Math.max(icon.getHeight(), 1),
- Bitmap.Config.ARGB_8888);
- Canvas c = new Canvas(b);
- Paint paint = new Paint();
- paint.setAlpha(127);
- c.drawBitmap(icon, 0, 0, paint);
- c.setBitmap(null);
- icon.recycle();
- icon = b;
- }
-
return icon;
}
diff --git a/src/com/android/launcher3/ItemInfo.java b/src/com/android/launcher3/ItemInfo.java
index 3dc92c9..3fe4c60 100644
--- a/src/com/android/launcher3/ItemInfo.java
+++ b/src/com/android/launcher3/ItemInfo.java
@@ -34,7 +34,7 @@
/**
* The id in the settings database for this item
*/
- long id = NO_ID;
+ public long id = NO_ID;
/**
* One of {@link LauncherSettings.Favorites#ITEM_TYPE_APPLICATION},
@@ -42,7 +42,7 @@
* {@link LauncherSettings.Favorites#ITEM_TYPE_FOLDER}, or
* {@link LauncherSettings.Favorites#ITEM_TYPE_APPWIDGET}.
*/
- int itemType;
+ public int itemType;
/**
* The id of the container that holds this item. For the desktop, this will be
@@ -50,27 +50,27 @@
* will be {@link #NO_ID} (since it is not stored in the settings DB). For user folders
* it will be the id of the folder.
*/
- long container = NO_ID;
+ public long container = NO_ID;
/**
* Iindicates the screen in which the shortcut appears.
*/
- long screenId = -1;
+ public long screenId = -1;
/**
* Indicates the X position of the associated cell.
*/
- int cellX = -1;
+ public int cellX = -1;
/**
* Indicates the Y position of the associated cell.
*/
- int cellY = -1;
+ public int cellY = -1;
/**
* Indicates the X cell span.
*/
- int spanX = 1;
+ public int spanX = 1;
/**
* Indicates the Y cell span.
@@ -80,17 +80,17 @@
/**
* Indicates the minimum X cell span.
*/
- int minSpanX = 1;
+ public int minSpanX = 1;
/**
* Indicates the minimum Y cell span.
*/
- int minSpanY = 1;
+ public int minSpanY = 1;
/**
* Indicates that this item needs to be updated in the db
*/
- boolean requiresDbUpdate = false;
+ public boolean requiresDbUpdate = false;
/**
* Title of the item
@@ -118,7 +118,7 @@
LauncherModel.checkItemInfo(this);
}
- protected Intent getIntent() {
+ public Intent getIntent() {
throw new RuntimeException("Unexpected Intent");
}
diff --git a/src/com/android/launcher3/Launcher.java b/src/com/android/launcher3/Launcher.java
index c22a6bf..ff5b1eb 100644
--- a/src/com/android/launcher3/Launcher.java
+++ b/src/com/android/launcher3/Launcher.java
@@ -96,6 +96,7 @@
import android.widget.Toast;
import com.android.launcher3.DropTarget.DragObject;
+import com.android.launcher3.PagedView.PageSwitchListener;
import java.io.DataInputStream;
import java.io.DataOutputStream;
@@ -119,7 +120,7 @@
*/
public class Launcher extends Activity
implements View.OnClickListener, OnLongClickListener, LauncherModel.Callbacks,
- View.OnTouchListener {
+ View.OnTouchListener, PageSwitchListener, LauncherProviderChangeListener {
static final String TAG = "Launcher";
static final boolean LOGD = false;
@@ -190,6 +191,7 @@
private static final String RUNTIME_STATE_VIEW_IDS = "launcher.view_ids";
+ static final String INTRO_SCREEN_DISMISSED = "launcher.intro_screen_dismissed";
static final String FIRST_RUN_ACTIVITY_DISPLAYED = "launcher.first_run_activity_displayed";
private static final String TOOLBAR_ICON_METADATA_NAME = "com.android.launcher.toolbar_icon";
@@ -212,6 +214,7 @@
public static final int EXIT_SPRINGLOADED_MODE_SHORT_TIMEOUT = 300;
public static final int EXIT_SPRINGLOADED_MODE_SHORT_TIMEOUT_FOLDER_CLOSE = 400;
private static final int ON_ACTIVITY_RESULT_ANIMATION_DELAY = 500;
+ private static final int ACTIVITY_START_DELAY = 1000;
private static final Object sLock = new Object();
private static int sScreen = DEFAULT_SCREEN;
@@ -393,7 +396,7 @@
LauncherAppState.setApplicationContext(getApplicationContext());
LauncherAppState app = LauncherAppState.getInstance();
-
+ LauncherAppState.getLauncherProvider().setLauncherProviderChangeListener(this);
// Determine the dynamic grid properties
Point smallestSize = new Point();
Point largestSize = new Point();
@@ -480,10 +483,15 @@
// On large interfaces, we want the screen to auto-rotate based on the current orientation
unlockScreenOrientation(true);
+ if (shouldShowIntroScreen()) {
+ showIntroScreen();
+ } else {
+ showFirstRunActivity();
+ }
+
// The two first run cling paths are mutually exclusive, if the launcher is preinstalled
// on the device, then we always show the first run cling experience (or if there is no
// launcher2). Otherwise, we prompt the user upon started for migration
- showFirstRunActivity();
if (mLauncherClings.shouldShowFirstRunOrMigrationClings()) {
if (mModel.canMigrateFromOldLauncherDb(this)) {
mLauncherClings.showMigrationCling();
@@ -495,6 +503,9 @@
}
}
+ @Override
+ public void onLauncherProviderChange() { }
+
protected void onUserLeaveHint() {
super.onUserLeaveHint();
sPausedFromUserAction = true;
@@ -514,21 +525,6 @@
}
/**
- * To be overridden by subclasses to indicate that there is an activity to launch
- * before showing the standard launcher experience.
- */
- protected boolean hasFirstRunActivity() {
- return false;
- }
-
- /**
- * To be overridden by subclasses to launch any first run activity
- */
- protected Intent getFirstRunActivity() {
- return null;
- }
-
- /**
* Invoked by subclasses to signal a change to the {@link #addCustomContentToLeft} value to
* ensure the custom content page is added or removed if necessary.
*/
@@ -1010,7 +1006,7 @@
// It is also poassible that onShow will instead be called slightly after first layout
// if PagedView#setRestorePage was set to the custom content page in onCreate().
if (mWorkspace.isOnOrMovingToCustomContent()) {
- mWorkspace.getCustomContentCallbacks().onShow();
+ mWorkspace.getCustomContentCallbacks().onShow(true);
}
}
mWorkspace.updateInteractionForState();
@@ -1054,8 +1050,9 @@
}
public interface CustomContentCallbacks {
- // Custom content is completely shown
- public void onShow();
+ // Custom content is completely shown. {@code fromResume} indicates whether this was caused
+ // by a onResume or by scrolling otherwise.
+ public void onShow(boolean fromResume);
// Custom content is completely hidden
public void onHide();
@@ -1068,9 +1065,6 @@
return false;
}
- protected void startSettings() {
- }
-
public interface QSBScroller {
public void setScrollY(int scrollY);
}
@@ -1233,6 +1227,7 @@
mLauncherView = findViewById(R.id.launcher);
mDragLayer = (DragLayer) findViewById(R.id.drag_layer);
mWorkspace = (Workspace) mDragLayer.findViewById(R.id.workspace);
+ mWorkspace.setPageSwitchListener(this);
mPageIndicators = mDragLayer.findViewById(R.id.page_indicator);
mLauncherView.setSystemUiVisibility(
@@ -1255,7 +1250,7 @@
@Override
public void onClick(View arg0) {
if (!mWorkspace.isSwitchingState()) {
- showAllApps(true, AppsCustomizePagedView.ContentType.Widgets, true);
+ onClickAddWidgetButton(arg0);
}
}
});
@@ -1266,7 +1261,7 @@
@Override
public void onClick(View arg0) {
if (!mWorkspace.isSwitchingState()) {
- startWallpaper();
+ onClickWallpaperPicker(arg0);
}
}
});
@@ -1278,9 +1273,9 @@
@Override
public void onClick(View arg0) {
if (!mWorkspace.isSwitchingState()) {
- startSettings();
+ onClickSettingsButton(arg0);
}
- }
+ }
});
settingsButton.setOnTouchListener(getHapticFeedbackTouchListener());
} else {
@@ -1334,6 +1329,17 @@
}
/**
+ * Sets the all apps button. This method is called from {@link Hotseat}.
+ */
+ public void setAllAppsButton(View allAppsButton) {
+ mAllAppsButton = allAppsButton;
+ }
+
+ public View getAllAppsButton() {
+ return mAllAppsButton;
+ }
+
+ /**
* Creates a view representing a shortcut.
*
* @param info The data structure describing the shortcut.
@@ -2260,12 +2266,6 @@
sFolders.remove(folder.id);
}
- protected void startWallpaper() {
- final Intent pickWallpaper = new Intent(Intent.ACTION_SET_WALLPAPER);
- pickWallpaper.setComponent(getWallpaperPickerComponent());
- startActivityForResult(pickWallpaper, REQUEST_PICK_WALLPAPER);
- }
-
protected ComponentName getWallpaperPickerComponent() {
return new ComponentName(getPackageName(), LauncherWallpaperPickerActivity.class.getName());
}
@@ -2369,51 +2369,13 @@
Object tag = v.getTag();
if (tag instanceof ShortcutInfo) {
- // Open shortcut
- final ShortcutInfo shortcut = (ShortcutInfo) tag;
- final Intent intent = shortcut.intent;
-
- // Check for special shortcuts
- if (intent.getComponent() != null) {
- final String shortcutClass = intent.getComponent().getClassName();
-
- if (shortcutClass.equals(WidgetAdder.class.getName())) {
- onClickAddWidgetButton();
- return;
- } else if (shortcutClass.equals(MemoryDumpActivity.class.getName())) {
- MemoryDumpActivity.startDump(this);
- return;
- } else if (shortcutClass.equals(ToggleWeightWatcher.class.getName())) {
- toggleShowWeightWatcher();
- return;
- }
- }
-
- // Start activities
- int[] pos = new int[2];
- v.getLocationOnScreen(pos);
- intent.setSourceBounds(new Rect(pos[0], pos[1],
- pos[0] + v.getWidth(), pos[1] + v.getHeight()));
-
- boolean success = startActivitySafely(v, intent, tag);
-
- mStats.recordLaunch(intent, shortcut);
-
- if (success && v instanceof BubbleTextView) {
- mWaitingForResume = (BubbleTextView) v;
- mWaitingForResume.setStayPressed(true);
- }
+ onClickAppShortcut(v);
} else if (tag instanceof FolderInfo) {
if (v instanceof FolderIcon) {
- FolderIcon fi = (FolderIcon) v;
- handleFolderClick(fi);
+ onClickFolderIcon(v);
}
} else if (v == mAllAppsButton) {
- if (isAllAppsVisible()) {
- showWorkspace(true);
- } else {
- onClickAllAppsButton(v);
- }
+ onClickAllAppsButton(v);
}
}
@@ -2467,18 +2429,144 @@
*
* @param v The view that was clicked.
*/
- public void onClickAllAppsButton(View v) {
- showAllApps(true, AppsCustomizePagedView.ContentType.Applications, false);
+ protected void onClickAllAppsButton(View v) {
+ if (LOGD) Log.d(TAG, "onClickAllAppsButton");
+ if (isAllAppsVisible()) {
+ showWorkspace(true);
+ } else {
+ showAllApps(true, AppsCustomizePagedView.ContentType.Applications, false);
+ }
+ }
+
+ /**
+ * 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}.
+ */
+ protected void onClickAppShortcut(View v) {
+ if (LOGD) Log.d(TAG, "onClickAppShortcut");
+ Object tag = v.getTag();
+ if (!(tag instanceof ShortcutInfo)) {
+ throw new IllegalArgumentException("Input must be a Shortcut");
+ }
+
+ // Open shortcut
+ final ShortcutInfo shortcut = (ShortcutInfo) tag;
+ final Intent intent = shortcut.intent;
+
+ // Check for special shortcuts
+ if (intent.getComponent() != null) {
+ final String shortcutClass = intent.getComponent().getClassName();
+
+ if (shortcutClass.equals(MemoryDumpActivity.class.getName())) {
+ MemoryDumpActivity.startDump(this);
+ return;
+ } else if (shortcutClass.equals(ToggleWeightWatcher.class.getName())) {
+ toggleShowWeightWatcher();
+ return;
+ }
+ }
+
+ // Start activities
+ int[] pos = new int[2];
+ v.getLocationOnScreen(pos);
+ intent.setSourceBounds(new Rect(pos[0], pos[1],
+ pos[0] + v.getWidth(), pos[1] + v.getHeight()));
+
+ boolean success = startActivitySafely(v, intent, tag);
+
+ mStats.recordLaunch(intent, shortcut);
+
+ if (success && v instanceof BubbleTextView) {
+ mWaitingForResume = (BubbleTextView) v;
+ mWaitingForResume.setStayPressed(true);
+ }
+ }
+
+ /**
+ * Event handler for a folder icon click.
+ *
+ * @param v The view that was clicked. Must be an instance of {@link FolderIcon}.
+ */
+ protected void onClickFolderIcon(View v) {
+ if (LOGD) Log.d(TAG, "onClickFolder");
+ if (!(v instanceof FolderIcon)){
+ throw new IllegalArgumentException("Input must be a FolderIcon");
+ }
+
+ FolderIcon folderIcon = (FolderIcon) v;
+ final FolderInfo info = folderIcon.getFolderInfo();
+ Folder openFolder = mWorkspace.getFolderForTag(info);
+
+ // If the folder info reports that the associated folder is open, then verify that
+ // it is actually opened. There have been a few instances where this gets out of sync.
+ if (info.opened && openFolder == null) {
+ Log.d(TAG, "Folder info marked as open, but associated folder is not open. Screen: "
+ + info.screenId + " (" + info.cellX + ", " + info.cellY + ")");
+ info.opened = false;
+ }
+
+ if (!info.opened && !folderIcon.getFolder().isDestroyed()) {
+ // Close any open folder
+ closeFolder();
+ // Open the requested folder
+ openFolder(folderIcon);
+ } else {
+ // Find the open folder...
+ int folderScreen;
+ if (openFolder != null) {
+ folderScreen = mWorkspace.getPageForView(openFolder);
+ // .. and close it
+ closeFolder(openFolder);
+ if (folderScreen != mWorkspace.getCurrentPage()) {
+ // Close any folder open on the current screen
+ closeFolder();
+ // Pull the folder onto this screen
+ openFolder(folderIcon);
+ }
+ }
+ }
}
/**
* Event handler for the (Add) Widgets button that appears after a long press
* on the home screen.
*/
- protected void onClickAddWidgetButton() {
+ protected void onClickAddWidgetButton(View view) {
+ if (LOGD) Log.d(TAG, "onClickAddWidgetButton");
showAllApps(true, AppsCustomizePagedView.ContentType.Widgets, true);
}
+ /**
+ * Event handler for the wallpaper picker button that appears after a long press
+ * on the home screen.
+ */
+ protected void onClickWallpaperPicker(View v) {
+ if (LOGD) Log.d(TAG, "onClickWallpaperPicker");
+ final Intent pickWallpaper = new Intent(Intent.ACTION_SET_WALLPAPER);
+ pickWallpaper.setComponent(getWallpaperPickerComponent());
+ startActivityForResult(pickWallpaper, REQUEST_PICK_WALLPAPER);
+ }
+
+ /**
+ * Event handler for a click on the settings button that appears after a long press
+ * on the home screen.
+ */
+ protected void onClickSettingsButton(View v) {
+ if (LOGD) Log.d(TAG, "onClickSettingsButton");
+ }
+
public void onTouchDownAllAppsButton(View v) {
// Provide the same haptic feedback that the system offers for virtual keys.
v.performHapticFeedback(HapticFeedbackConstants.VIRTUAL_KEY);
@@ -2514,6 +2602,8 @@
}
}
+ public void onDragStarted(View view) {}
+
/**
* Called when the user stops interacting with the launcher.
* This implies that the user is now on the homescreen and is not doing housekeeping.
@@ -2598,40 +2688,6 @@
return success;
}
- private void handleFolderClick(FolderIcon folderIcon) {
- final FolderInfo info = folderIcon.getFolderInfo();
- Folder openFolder = mWorkspace.getFolderForTag(info);
-
- // If the folder info reports that the associated folder is open, then verify that
- // it is actually opened. There have been a few instances where this gets out of sync.
- if (info.opened && openFolder == null) {
- Log.d(TAG, "Folder info marked as open, but associated folder is not open. Screen: "
- + info.screenId + " (" + info.cellX + ", " + info.cellY + ")");
- info.opened = false;
- }
-
- if (!info.opened && !folderIcon.getFolder().isDestroyed()) {
- // Close any open folder
- closeFolder();
- // Open the requested folder
- openFolder(folderIcon);
- } else {
- // Find the open folder...
- int folderScreen;
- if (openFolder != null) {
- folderScreen = mWorkspace.getPageForView(openFolder);
- // .. and close it
- closeFolder(openFolder);
- if (folderScreen != mWorkspace.getCurrentPage()) {
- // Close any folder open on the current screen
- closeFolder();
- // Pull the folder onto this screen
- openFolder(folderIcon);
- }
- }
- }
- }
-
/**
* This method draws the FolderIcon to an ImageView and then adds and positions that ImageView
* in the DragLayer in the exact absolute location of the original FolderIcon.
@@ -2891,7 +2947,7 @@
mWorkspaceBackgroundDrawable : null);
}
- void updateWallpaperVisibility(boolean visible) {
+ protected void changeWallpaperVisiblity(boolean visible) {
int wpflags = visible ? WindowManager.LayoutParams.FLAG_SHOW_WALLPAPER : 0;
int curflags = getWindow().getAttributes().flags
& WindowManager.LayoutParams.FLAG_SHOW_WALLPAPER;
@@ -3926,7 +3982,15 @@
if (item.container == LauncherSettings.Favorites.CONTAINER_DESKTOP) {
CellLayout cl = mWorkspace.getScreenWithId(item.screenId);
if (cl != null && cl.isOccupied(item.cellX, item.cellY)) {
- throw new RuntimeException("OCCUPIED");
+ View v = cl.getChildAt(item.cellX, item.cellY);
+ Object tag = v.getTag();
+ String desc = "Collision while binding workspace item: " + item
+ + ". Collides with " + tag;
+ if (LauncherAppState.isDogfoodBuild()) {
+ throw (new RuntimeException(desc));
+ } else {
+ Log.d(TAG, desc);
+ }
}
}
@@ -4186,6 +4250,17 @@
}
/**
+ * Update the state of a package, typically related to install state.
+ *
+ * Implementation of the method from LauncherModel.Callbacks.
+ */
+ public void updatePackageState(String pkgName, int state) {
+ if (mWorkspace != null) {
+ mWorkspace.updatePackageState(pkgName, state);
+ }
+ }
+
+ /**
* A package was uninstalled. We take both the super set of packageNames
* in addition to specific applications to remove, the reason being that
* this can be called when a package is updated as well. In that scenario,
@@ -4366,20 +4441,42 @@
mLauncherClings.dismissFolderCling(v);
}
+
+ /**
+ * To be overridden by subclasses to indicate that there is an activity to launch
+ * before showing the standard launcher experience.
+ */
+ protected boolean hasFirstRunActivity() {
+ return false;
+ }
+
+ /**
+ * To be overridden by subclasses to launch any first run activity
+ */
+ protected Intent getFirstRunActivity() {
+ return null;
+ }
+
private boolean shouldRunFirstRunActivity() {
return !ActivityManager.isRunningInTestHarness() &&
!mSharedPrefs.getBoolean(FIRST_RUN_ACTIVITY_DISPLAYED, false);
}
- public void showFirstRunActivity() {
+ protected boolean hasRunFirstRunActivity() {
+ return mSharedPrefs.getBoolean(FIRST_RUN_ACTIVITY_DISPLAYED, false);
+ }
+
+ public boolean showFirstRunActivity() {
if (shouldRunFirstRunActivity() &&
hasFirstRunActivity()) {
Intent firstRunIntent = getFirstRunActivity();
if (firstRunIntent != null) {
startActivity(firstRunIntent);
markFirstRunActivityShown();
+ return true;
}
}
+ return false;
}
private void markFirstRunActivityShown() {
@@ -4388,6 +4485,61 @@
editor.apply();
}
+ /**
+ * To be overridden by subclasses to indicate that there is an in-activity full-screen intro
+ * screen that must be displayed and dismissed.
+ */
+ protected boolean hasDismissableIntroScreen() {
+ return false;
+ }
+
+ /**
+ * Full screen intro screen to be shown and dismissed before the launcher can be used.
+ */
+ protected View getIntroScreen() {
+ return null;
+ }
+
+ /**
+ * To be overriden by subclasses to indicate whether the in-activity intro screen has been
+ * dismissed. This method is ignored if #hasDismissableIntroScreen returns false.
+ */
+ private boolean shouldShowIntroScreen() {
+ return hasDismissableIntroScreen() &&
+ !mSharedPrefs.getBoolean(INTRO_SCREEN_DISMISSED, false);
+ }
+
+ protected void showIntroScreen() {
+ View introScreen = getIntroScreen();
+ changeWallpaperVisiblity(false);
+ if (introScreen != null) {
+ mDragLayer.showOverlayView(introScreen);
+ }
+ }
+
+ public void dismissIntroScreen() {
+ markIntroScreenDismissed();
+ if (showFirstRunActivity()) {
+ // We delay hiding the intro view until the first run activity is showing. This
+ // avoids a blip.
+ mWorkspace.postDelayed(new Runnable() {
+ @Override
+ public void run() {
+ mDragLayer.dismissOverlayView();
+ }
+ }, ACTIVITY_START_DELAY);
+ } else {
+ mDragLayer.dismissOverlayView();
+ }
+ changeWallpaperVisiblity(true);
+ }
+
+ private void markIntroScreenDismissed() {
+ SharedPreferences.Editor editor = mSharedPrefs.edit();
+ editor.putBoolean(INTRO_SCREEN_DISMISSED, true);
+ editor.apply();
+ }
+
void showWorkspaceSearchAndHotseat() {
if (mWorkspace != null) mWorkspace.setAlpha(1f);
if (mHotseat != null) mHotseat.setAlpha(1f);
@@ -4402,7 +4554,6 @@
if (mSearchDropTargetBar != null) mSearchDropTargetBar.hideSearchBar(false);
}
-
public ItemInfo createAppDragInfo(Intent appLaunchIntent) {
ResolveInfo ri = getPackageManager().resolveActivity(appLaunchIntent, 0);
if (ri == null) {
@@ -4416,10 +4567,18 @@
return new ShortcutInfo(shortcutIntent, caption, icon);
}
+ protected void moveWorkspaceToDefaultScreen() {
+ mWorkspace.moveToDefaultScreen(false);
+ }
+
public void startDrag(View dragView, ItemInfo dragInfo, DragSource source) {
dragView.setTag(dragInfo);
- mWorkspace.onDragStartedWithItem(dragView);
- mWorkspace.beginDragShared(dragView, source);
+ mWorkspace.onExternalDragStartedWithItem(dragView);
+ mWorkspace.beginExternalDragShared(dragView, source);
+ }
+
+ @Override
+ public void onPageSwitch(View newPage, int newPageIndex) {
}
/**
diff --git a/src/com/android/launcher3/LauncherAppState.java b/src/com/android/launcher3/LauncherAppState.java
index 29e18f9..5ddafea 100644
--- a/src/com/android/launcher3/LauncherAppState.java
+++ b/src/com/android/launcher3/LauncherAppState.java
@@ -30,6 +30,8 @@
private static final String TAG = "LauncherAppState";
private static final String SHARED_PREFERENCES_KEY = "com.android.launcher3.prefs";
+ private static final boolean DEBUG = false;
+
private final AppFilter mAppFilter;
private final BuildInfo mBuildInfo;
private LauncherModel mModel;
@@ -249,4 +251,9 @@
public static boolean isDogfoodBuild() {
return getInstance().mBuildInfo.isDogfoodBuild();
}
+
+ public void setPackageState(String pkgName, int state) {
+ if (DEBUG) Log.d(TAG, "setPackageState(" + pkgName + ", " + state + ")");
+ mModel.setPackageState(pkgName, state);
+ }
}
diff --git a/src/com/android/launcher3/LauncherAppWidgetInfo.java b/src/com/android/launcher3/LauncherAppWidgetInfo.java
index 28df90f..950828e 100644
--- a/src/com/android/launcher3/LauncherAppWidgetInfo.java
+++ b/src/com/android/launcher3/LauncherAppWidgetInfo.java
@@ -23,7 +23,7 @@
/**
* Represents a widget (either instantiated or about to be) in the Launcher.
*/
-class LauncherAppWidgetInfo extends ItemInfo {
+public class LauncherAppWidgetInfo extends ItemInfo {
/**
* Indicates that the widget hasn't been instantiated yet.
diff --git a/src/com/android/launcher3/LauncherBackupHelper.java b/src/com/android/launcher3/LauncherBackupHelper.java
index 62e6f31..cab55c7 100644
--- a/src/com/android/launcher3/LauncherBackupHelper.java
+++ b/src/com/android/launcher3/LauncherBackupHelper.java
@@ -461,7 +461,8 @@
int startRows = out.rows;
if (DEBUG) Log.d(TAG, "starting here: " + startRows);
- String where = Favorites.ITEM_TYPE + "=" + Favorites.ITEM_TYPE_APPLICATION;
+ String where = Favorites.ITEM_TYPE + "=" + Favorites.ITEM_TYPE_APPLICATION + " OR " +
+ Favorites.ITEM_TYPE + "=" + Favorites.ITEM_TYPE_SHORTCUT;
Cursor cursor = cr.query(Favorites.CONTENT_URI, FAVORITE_PROJECTION,
where, null, null);
Set<String> currentIds = new HashSet<String>(cursor.getCount());
diff --git a/src/com/android/launcher3/LauncherClings.java b/src/com/android/launcher3/LauncherClings.java
index 952edfd..97138ee 100644
--- a/src/com/android/launcher3/LauncherClings.java
+++ b/src/com/android/launcher3/LauncherClings.java
@@ -21,8 +21,11 @@
import android.animation.Animator;
import android.animation.AnimatorListenerAdapter;
import android.app.ActivityManager;
+import android.content.ComponentName;
import android.content.Context;
import android.content.SharedPreferences;
+import android.content.pm.ApplicationInfo;
+import android.content.pm.PackageManager;
import android.graphics.Rect;
import android.os.Bundle;
import android.os.UserManager;
@@ -262,12 +265,21 @@
Cling c = initCling(R.id.workspace_cling, 0, false, true);
c.updateWorkspaceBubblePosition();
- // Set the focused hotseat app if there is one
- c.setFocusedHotseatApp(mLauncher.getFirstRunFocusedHotseatAppDrawableId(),
- mLauncher.getFirstRunFocusedHotseatAppRank(),
- mLauncher.getFirstRunFocusedHotseatAppComponentName(),
- mLauncher.getFirstRunFocusedHotseatAppBubbleTitle(),
- mLauncher.getFirstRunFocusedHotseatAppBubbleDescription());
+ try {
+ // We only enable the focused hotseat app if we are preinstalled
+ PackageManager pm = mLauncher.getPackageManager();
+ ApplicationInfo ai = pm.getApplicationInfo(mLauncher.getPackageName(), 0);
+ if ((ai.flags & ApplicationInfo.FLAG_SYSTEM) != 0) {
+ // Set the focused hotseat app
+ c.setFocusedHotseatApp(mLauncher.getFirstRunFocusedHotseatAppDrawableId(),
+ mLauncher.getFirstRunFocusedHotseatAppRank(),
+ mLauncher.getFirstRunFocusedHotseatAppComponentName(),
+ mLauncher.getFirstRunFocusedHotseatAppBubbleTitle(),
+ mLauncher.getFirstRunFocusedHotseatAppBubbleDescription());
+ }
+ } catch (PackageManager.NameNotFoundException e) {
+ e.printStackTrace();
+ }
} else {
removeCling(R.id.workspace_cling);
}
diff --git a/src/com/android/launcher3/LauncherModel.java b/src/com/android/launcher3/LauncherModel.java
index 007fd7a..d8645aa 100644
--- a/src/com/android/launcher3/LauncherModel.java
+++ b/src/com/android/launcher3/LauncherModel.java
@@ -173,6 +173,7 @@
ArrayList<ItemInfo> addAnimated,
ArrayList<AppInfo> addedApps);
public void bindAppsUpdated(ArrayList<AppInfo> apps);
+ public void updatePackageState(String pkgName, int state);
public void bindComponentsRemoved(ArrayList<String> packageNames,
ArrayList<AppInfo> appInfos);
public void bindPackagesUpdated(ArrayList<Object> widgetsAndShortcuts);
@@ -191,8 +192,12 @@
ContentResolver contentResolver = context.getContentResolver();
mAppsCanBeOnRemoveableStorage = Environment.isExternalStorageRemovable();
- mOldContentProviderExists = (contentResolver.acquireContentProviderClient(
- LauncherSettings.Favorites.OLD_CONTENT_URI) != null);
+ ContentProviderClient client = contentResolver.acquireContentProviderClient(
+ Uri.parse(context.getString(R.string.old_launcher_provider_uri)));
+ mOldContentProviderExists = (client != null);
+ if (client != null) {
+ client.release();
+ }
mApp = app;
mBgAllAppsList = new AllAppsList(iconCache, appFilter);
mIconCache = iconCache;
@@ -292,6 +297,19 @@
return null;
}
+ public void setPackageState(final String pkgName, final int state) {
+ // Process the updated package state
+ Runnable r = new Runnable() {
+ public void run() {
+ Callbacks callbacks = mCallbacks != null ? mCallbacks.get() : null;
+ if (callbacks != null) {
+ callbacks.updatePackageState(pkgName, state);
+ }
+ }
+ };
+ mHandler.post(r);
+ }
+
public void addAppsToAllApps(final Context ctx, final ArrayList<AppInfo> allAppsApps) {
final Callbacks callbacks = mCallbacks != null ? mCallbacks.get() : null;
@@ -953,6 +971,7 @@
values.put(LauncherSettings.Favorites._ID, item.id);
item.updateValuesWithCoordinates(values, item.cellX, item.cellY);
+ final StackTraceElement[] stackTrace = new Throwable().getStackTrace();
Runnable r = new Runnable() {
public void run() {
cr.insert(notify ? LauncherSettings.Favorites.CONTENT_URI :
@@ -960,7 +979,7 @@
// Lock on mBgLock *after* the db operation
synchronized (sBgLock) {
- checkItemInfoLocked(item.id, item, null);
+ checkItemInfoLocked(item.id, item, stackTrace);
sBgItemsIdMap.put(item.id, item);
switch (item.itemType) {
case LauncherSettings.Favorites.ITEM_TYPE_FOLDER:
@@ -2189,7 +2208,12 @@
line += " | ";
}
for (int x = 0; x < countX; x++) {
- line += ((occupied.get(screenId)[x][y] != null) ? "#" : ".");
+ ItemInfo[][] screen = occupied.get(screenId);
+ if (x < screen.length && y < screen[x].length) {
+ line += (screen[x][y] != null) ? "#" : ".";
+ } else {
+ line += "!";
+ }
}
}
Log.d(TAG, "[ " + line + " ]");
diff --git a/src/com/android/launcher3/LauncherProvider.java b/src/com/android/launcher3/LauncherProvider.java
index a080dd8..0e559a8 100644
--- a/src/com/android/launcher3/LauncherProvider.java
+++ b/src/com/android/launcher3/LauncherProvider.java
@@ -32,7 +32,9 @@
import android.content.OperationApplicationException;
import android.content.SharedPreferences;
import android.content.pm.ActivityInfo;
+import android.content.pm.ApplicationInfo;
import android.content.pm.PackageManager;
+import android.content.pm.ResolveInfo;
import android.content.res.Resources;
import android.content.res.TypedArray;
import android.content.res.XmlResourceParser;
@@ -72,7 +74,7 @@
private static final String DATABASE_NAME = "launcher.db";
- private static final int DATABASE_VERSION = 17;
+ private static final int DATABASE_VERSION = 18;
static final String OLD_AUTHORITY = "com.android.launcher2.settings";
static final String AUTHORITY = ProviderConfig.AUTHORITY;
@@ -93,6 +95,8 @@
private static final String ACTION_APPWIDGET_DEFAULT_WORKSPACE_CONFIGURE =
"com.android.launcher.action.APPWIDGET_DEFAULT_WORKSPACE_CONFIGURE";
+ private LauncherProviderChangeListener mListener;
+
/**
* {@link Uri} triggered at any registered {@link android.database.ContentObserver} when
* {@link AppWidgetHost#deleteHost()} is called during database creation.
@@ -116,6 +120,10 @@
return mOpenHelper.wasNewDbCreated();
}
+ public void setLauncherProviderChangeListener(LauncherProviderChangeListener listener) {
+ mListener = listener;
+ }
+
@Override
public String getType(Uri uri) {
SqlArguments args = new SqlArguments(uri, null, null);
@@ -242,6 +250,9 @@
// always notify the backup agent
LauncherBackupAgentHelper.dataChanged(getContext());
+ if (mListener != null) {
+ mListener.onLauncherProviderChange();
+ }
}
private void addModifiedTime(ContentValues values) {
@@ -318,7 +329,7 @@
public void migrateLauncher2Shortcuts() {
mOpenHelper.migrateLauncher2Shortcuts(mOpenHelper.getWritableDatabase(),
- LauncherSettings.Favorites.OLD_CONTENT_URI);
+ Uri.parse(getContext().getString(R.string.old_launcher_provider_uri)));
}
private static int getDefaultWorkspaceResourceId() {
@@ -352,6 +363,7 @@
}
private static class DatabaseHelper extends SQLiteOpenHelper {
+ private static final String TAG_RESOLVE = "resolve";
private static final String TAG_FAVORITES = "favorites";
private static final String TAG_FAVORITE = "favorite";
private static final String TAG_CLOCK = "clock";
@@ -454,7 +466,7 @@
"/old_favorites?notify=true");
if (!convertDatabase(db, uri, permuteScreensCb, true)) {
// Try and upgrade from the Launcher2 db
- uri = LauncherSettings.Favorites.OLD_CONTENT_URI;
+ uri = Uri.parse(mContext.getString(R.string.old_launcher_provider_uri));
if (!convertDatabase(db, uri, permuteScreensCb, false)) {
// If we fail, then set a flag to load the default workspace
setFlagEmptyDbCreated();
@@ -480,6 +492,13 @@
");");
}
+ private void removeOrphanedItems(SQLiteDatabase db) {
+ db.execSQL("DELETE FROM " + TABLE_FAVORITES + " WHERE " +
+ LauncherSettings.Favorites.SCREEN + " NOT IN (SELECT " +
+ LauncherSettings.WorkspaceScreens._ID + " FROM " + TABLE_WORKSPACE_SCREENS +
+ ")");
+ }
+
private void setFlagJustLoadedOldDb() {
String spKey = LauncherAppState.getSharedPreferencesKey();
SharedPreferences sp = mContext.getSharedPreferences(spKey, Context.MODE_PRIVATE);
@@ -780,6 +799,17 @@
version = 17;
}
+ if (version < 18) {
+ // Due to a data loss bug, some users may have items associated with screen ids
+ // which no longer exist. Since this can cause other problems, and since the user
+ // will never see these items anyway, we use database upgrade as an opportunity to
+ // clean things up.
+
+ // TODO: this needs to be fixed, currently causes data loss.
+ //removeOrphanedItems(db);
+ version = 18;
+ }
+
if (version != DATABASE_VERSION) {
Log.w(TAG, "Destroying all old data.");
db.execSQL("DROP TABLE IF EXISTS " + TABLE_FAVORITES);
@@ -1216,6 +1246,32 @@
} else if (TAG_SHORTCUT.equals(name)) {
long id = addUriShortcut(db, values, a);
added = id >= 0;
+ } else if (TAG_RESOLVE.equals(name)) {
+ // This looks through the contained favorites (or meta-favorites) and
+ // attempts to add them as shortcuts in the fallback group's location
+ // until one is added successfully.
+ added = false;
+ final int groupDepth = parser.getDepth();
+ while ((type = parser.next()) != XmlPullParser.END_TAG ||
+ parser.getDepth() > groupDepth) {
+ if (type != XmlPullParser.START_TAG) {
+ continue;
+ }
+ final String fallback_item_name = parser.getName();
+ final TypedArray ar = mContext.obtainStyledAttributes(attrs,
+ R.styleable.Favorite);
+ if (!added) {
+ if (TAG_FAVORITE.equals(fallback_item_name)) {
+ final long id =
+ addAppShortcut(db, values, ar, packageManager, intent);
+ added = id >= 0;
+ } else {
+ Log.e(TAG, "Fallback groups can contain only favorites "
+ + ar.toString());
+ }
+ }
+ ar.recycle();
+ }
} else if (TAG_FOLDER.equals(name)) {
String title;
int titleResId = a.getResourceId(R.styleable.Favorite_title, -1);
@@ -1298,41 +1354,137 @@
return i;
}
- private long addAppShortcut(SQLiteDatabase db, ContentValues values, TypedArray a,
+ // A meta shortcut attempts to resolve an intent specified as a URI in the XML, if a
+ // logical choice for what shortcut should be used for that intent exists, then it is
+ // added. Otherwise add nothing.
+ private long addAppShortcutByUri(SQLiteDatabase db, ContentValues values, TypedArray a,
PackageManager packageManager, Intent intent) {
- long id = -1;
- ActivityInfo info;
- String packageName = a.getString(R.styleable.Favorite_packageName);
- String className = a.getString(R.styleable.Favorite_className);
+ final String intentUri = a.getString(R.styleable.Favorite_uri);
+
+ Intent metaIntent;
try {
- ComponentName cn;
- try {
- cn = new ComponentName(packageName, className);
- info = packageManager.getActivityInfo(cn, 0);
- } catch (PackageManager.NameNotFoundException nnfe) {
- String[] packages = packageManager.currentToCanonicalPackageNames(
- new String[] { packageName });
- cn = new ComponentName(packages[0], className);
- info = packageManager.getActivityInfo(cn, 0);
- }
- id = generateNewItemId();
- intent.setComponent(cn);
- intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK |
- Intent.FLAG_ACTIVITY_RESET_TASK_IF_NEEDED);
- values.put(Favorites.INTENT, intent.toUri(0));
- values.put(Favorites.TITLE, info.loadLabel(packageManager).toString());
- values.put(Favorites.ITEM_TYPE, Favorites.ITEM_TYPE_APPLICATION);
- values.put(Favorites.SPANX, 1);
- values.put(Favorites.SPANY, 1);
- values.put(Favorites._ID, generateNewItemId());
- if (dbInsertAndCheck(this, db, TABLE_FAVORITES, null, values) < 0) {
+ metaIntent = Intent.parseUri(intentUri, 0);
+ } catch (URISyntaxException e) {
+ Log.e(TAG, "Unable to add meta-favorite: " + intentUri, e);
+ return -1;
+ }
+
+ ResolveInfo resolved = packageManager.resolveActivity(metaIntent,
+ PackageManager.MATCH_DEFAULT_ONLY);
+ final List<ResolveInfo> appList = packageManager.queryIntentActivities(
+ metaIntent, PackageManager.MATCH_DEFAULT_ONLY);
+
+ // Verify that the result is an app and not just the resolver dialog asking which
+ // app to use.
+ if (wouldLaunchResolverActivity(resolved, appList)) {
+ // If only one of the results is a system app then choose that as the default.
+ final ResolveInfo systemApp = getSingleSystemActivity(appList, packageManager);
+ if (systemApp == null) {
+ // There is no logical choice for this meta-favorite, so rather than making
+ // a bad choice just add nothing.
+ Log.w(TAG, "No preference or single system activity found for "
+ + metaIntent.toString());
return -1;
}
- } catch (PackageManager.NameNotFoundException e) {
- Log.w(TAG, "Unable to add favorite: " + packageName +
- "/" + className, e);
+ resolved = systemApp;
}
- return id;
+ final ActivityInfo info = resolved.activityInfo;
+ intent.setComponent(new ComponentName(info.packageName, info.name));
+ intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK |
+ Intent.FLAG_ACTIVITY_RESET_TASK_IF_NEEDED);
+
+ return addAppShortcut(db, values, info.loadLabel(packageManager).toString(), intent);
+ }
+
+ private ResolveInfo getSingleSystemActivity(List<ResolveInfo> appList,
+ PackageManager packageManager) {
+ ResolveInfo systemResolve = null;
+ final int N = appList.size();
+ for (int i = 0; i < N; ++i) {
+ try {
+ ApplicationInfo info = packageManager.getApplicationInfo(
+ appList.get(i).activityInfo.packageName, 0);
+ if ((info.flags & ApplicationInfo.FLAG_SYSTEM) != 0) {
+ if (systemResolve != null) {
+ return null;
+ } else {
+ systemResolve = appList.get(i);
+ }
+ }
+ } catch (PackageManager.NameNotFoundException e) {
+ Log.w(TAG, "Unable to get info about resolve results", e);
+ return null;
+ }
+ }
+ return systemResolve;
+ }
+
+ private boolean wouldLaunchResolverActivity(ResolveInfo resolved,
+ List<ResolveInfo> appList) {
+ // If the list contains the above resolved activity, then it can't be
+ // ResolverActivity itself.
+ for (int i = 0; i < appList.size(); ++i) {
+ ResolveInfo tmp = appList.get(i);
+ if (tmp.activityInfo.name.equals(resolved.activityInfo.name)
+ && tmp.activityInfo.packageName.equals(resolved.activityInfo.packageName)) {
+ return false;
+ }
+ }
+ return true;
+ }
+
+ private long addAppShortcut(SQLiteDatabase db, ContentValues values, TypedArray a,
+ PackageManager packageManager, Intent intent) {
+ if (a.hasValue(R.styleable.Favorite_packageName)
+ && a.hasValue(R.styleable.Favorite_className)) {
+ ActivityInfo info;
+ String packageName = a.getString(R.styleable.Favorite_packageName);
+ String className = a.getString(R.styleable.Favorite_className);
+ try {
+ ComponentName cn;
+ try {
+ cn = new ComponentName(packageName, className);
+ info = packageManager.getActivityInfo(cn, 0);
+ } catch (PackageManager.NameNotFoundException nnfe) {
+ String[] packages = packageManager.currentToCanonicalPackageNames(
+ new String[] { packageName });
+ cn = new ComponentName(packages[0], className);
+ info = packageManager.getActivityInfo(cn, 0);
+ }
+ intent.setComponent(cn);
+ intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK |
+ Intent.FLAG_ACTIVITY_RESET_TASK_IF_NEEDED);
+
+ return addAppShortcut(db, values, info.loadLabel(packageManager).toString(),
+ intent);
+ } catch (PackageManager.NameNotFoundException e) {
+ Log.w(TAG, "Unable to add favorite: " + packageName +
+ "/" + className, e);
+ }
+ return -1;
+ } else if (a.hasValue(R.styleable.Favorite_uri)) {
+ // If no component specified try to find a shortcut to add from the URI.
+ return addAppShortcutByUri(db, values, a, packageManager, intent);
+ } else {
+ Log.e(TAG, "Skipping invalid <favorite> with no component or uri");
+ return -1;
+ }
+ }
+
+ private long addAppShortcut(SQLiteDatabase db, ContentValues values, String title,
+ Intent intent) {
+ long id = generateNewItemId();
+ values.put(Favorites.INTENT, intent.toUri(0));
+ values.put(Favorites.TITLE, title);
+ values.put(Favorites.ITEM_TYPE, Favorites.ITEM_TYPE_APPLICATION);
+ values.put(Favorites.SPANX, 1);
+ values.put(Favorites.SPANY, 1);
+ values.put(Favorites._ID, id);
+ if (dbInsertAndCheck(this, db, TABLE_FAVORITES, null, values) < 0) {
+ return -1;
+ } else {
+ return id;
+ }
}
private long addFolder(SQLiteDatabase db, ContentValues values) {
diff --git a/src/com/android/launcher3/LauncherProviderChangeListener.java b/src/com/android/launcher3/LauncherProviderChangeListener.java
new file mode 100644
index 0000000..0de96fb
--- /dev/null
+++ b/src/com/android/launcher3/LauncherProviderChangeListener.java
@@ -0,0 +1,11 @@
+package com.android.launcher3;
+
+/**
+ * This class is a listener for {@link LauncherProvider} changes. It gets notified in the
+ * sendNotify method. This listener is needed because by default the Launcher suppresses
+ * standard data change callbacks.
+ */
+public interface LauncherProviderChangeListener {
+
+ public void onLauncherProviderChange();
+}
diff --git a/src/com/android/launcher3/PagedViewIconCache.java b/src/com/android/launcher3/PagedViewIconCache.java
deleted file mode 100644
index 93887ea..0000000
--- a/src/com/android/launcher3/PagedViewIconCache.java
+++ /dev/null
@@ -1,133 +0,0 @@
-/*
- * Copyright (C) 2011 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.appwidget.AppWidgetProviderInfo;
-import android.content.ComponentName;
-import android.content.pm.ComponentInfo;
-import android.content.pm.ResolveInfo;
-import android.graphics.Bitmap;
-
-import java.util.ArrayList;
-import java.util.HashMap;
-import java.util.HashSet;
-import java.util.List;
-
-/**
- * Simple cache mechanism for PagedView outlines.
- */
-public class PagedViewIconCache {
- public static class Key {
- public enum Type {
- ApplicationInfoKey,
- AppWidgetProviderInfoKey,
- ResolveInfoKey
- }
- private final ComponentName mComponentName;
- private final Type mType;
-
- public Key(AppInfo info) {
- mComponentName = info.componentName;
- mType = Type.ApplicationInfoKey;
- }
- public Key(ResolveInfo info) {
- final ComponentInfo ci = info.activityInfo != null ? info.activityInfo :
- info.serviceInfo;
- mComponentName = new ComponentName(ci.packageName, ci.name);
- mType = Type.ResolveInfoKey;
- }
- public Key(AppWidgetProviderInfo info) {
- mComponentName = info.provider;
- mType = Type.AppWidgetProviderInfoKey;
- }
-
- private ComponentName getComponentName() {
- return mComponentName;
- }
- public boolean isKeyType(Type t) {
- return (mType == t);
- }
-
- @Override
- public boolean equals(Object o) {
- if (o instanceof Key) {
- Key k = (Key) o;
- return mComponentName.equals(k.mComponentName);
- }
- return super.equals(o);
- }
- @Override
- public int hashCode() {
- return getComponentName().hashCode();
- }
- }
-
- private final HashMap<Key, Bitmap> mIconOutlineCache = new HashMap<Key, Bitmap>();
-
- public void clear() {
- for (Key key : mIconOutlineCache.keySet()) {
- mIconOutlineCache.get(key).recycle();
- }
- mIconOutlineCache.clear();
- }
- private void retainAll(HashSet<Key> keysToKeep, Key.Type t) {
- HashSet<Key> keysToRemove = new HashSet<Key>(mIconOutlineCache.keySet());
- keysToRemove.removeAll(keysToKeep);
- for (Key key : keysToRemove) {
- if (key.isKeyType(t)) {
- mIconOutlineCache.get(key).recycle();
- mIconOutlineCache.remove(key);
- }
- }
- }
- /** Removes all the keys to applications that aren't in the passed in collection */
- public void retainAllApps(ArrayList<AppInfo> keys) {
- HashSet<Key> keysSet = new HashSet<Key>();
- for (AppInfo info : keys) {
- keysSet.add(new Key(info));
- }
- retainAll(keysSet, Key.Type.ApplicationInfoKey);
- }
- /** Removes all the keys to shortcuts that aren't in the passed in collection */
- public void retainAllShortcuts(List<ResolveInfo> keys) {
- HashSet<Key> keysSet = new HashSet<Key>();
- for (ResolveInfo info : keys) {
- keysSet.add(new Key(info));
- }
- retainAll(keysSet, Key.Type.ResolveInfoKey);
- }
- /** Removes all the keys to widgets that aren't in the passed in collection */
- public void retainAllAppWidgets(List<AppWidgetProviderInfo> keys) {
- HashSet<Key> keysSet = new HashSet<Key>();
- for (AppWidgetProviderInfo info : keys) {
- keysSet.add(new Key(info));
- }
- retainAll(keysSet, Key.Type.AppWidgetProviderInfoKey);
- }
- public void addOutline(Key key, Bitmap b) {
- mIconOutlineCache.put(key, b);
- }
- public void removeOutline(Key key) {
- if (mIconOutlineCache.containsKey(key)) {
- mIconOutlineCache.get(key).recycle();
- mIconOutlineCache.remove(key);
- }
- }
- public Bitmap getOutline(Key key) {
- return mIconOutlineCache.get(key);
- }
-}
diff --git a/src/com/android/launcher3/ShortcutInfo.java b/src/com/android/launcher3/ShortcutInfo.java
index 79d114c..5afa784 100644
--- a/src/com/android/launcher3/ShortcutInfo.java
+++ b/src/com/android/launcher3/ShortcutInfo.java
@@ -31,7 +31,25 @@
/**
* Represents a launchable icon on the workspaces and in folders.
*/
-class ShortcutInfo extends ItemInfo {
+public class ShortcutInfo extends ItemInfo {
+
+ /** This package is not installed, and there is no other information available. */
+ public static final int PACKAGE_STATE_UNKNOWN = -2;
+
+ /** This package is not installed, because installation failed. */
+ public static final int PACKAGE_STATE_ERROR = -1;
+
+ /** This package is installed. This is the typical case */
+ public static final int PACKAGE_STATE_DEFAULT = 0;
+
+ /** This package is not installed, but some external entity has promised to install it. */
+ public static final int PACKAGE_STATE_ENQUEUED = 1;
+
+ /** This package is not installed, but some external entity is downloading it. */
+ public static final int PACKAGE_STATE_DOWNLOADING = 2;
+
+ /** This package is not installed, but some external entity is installing it. */
+ public static final int PACKAGE_STATE_INSTALLING = 3;
/**
* The intent used to start the application.
@@ -74,7 +92,7 @@
itemType = LauncherSettings.BaseLauncherColumns.ITEM_TYPE_SHORTCUT;
}
- protected Intent getIntent() {
+ public Intent getIntent() {
return intent;
}
@@ -219,5 +237,15 @@
+ " customIcon=" + info.customIcon);
}
}
+
+ public boolean isPromise() {
+ return restoredIntent != null;
+ }
+
+ public boolean isPromiseFor(String pkgName) {
+ return restoredIntent != null
+ && pkgName != null
+ && pkgName.equals(restoredIntent.getComponent().getPackageName());
+ }
}
diff --git a/src/com/android/launcher3/WidgetAdder.java b/src/com/android/launcher3/WidgetAdder.java
deleted file mode 100644
index 79ac504..0000000
--- a/src/com/android/launcher3/WidgetAdder.java
+++ /dev/null
@@ -1,7 +0,0 @@
-package com.android.launcher3;
-
-import android.app.Activity;
-
-public class WidgetAdder extends Activity {
-
-}
diff --git a/src/com/android/launcher3/WidgetPreviewLoader.java b/src/com/android/launcher3/WidgetPreviewLoader.java
index 3db0b51..36152f8 100644
--- a/src/com/android/launcher3/WidgetPreviewLoader.java
+++ b/src/com/android/launcher3/WidgetPreviewLoader.java
@@ -15,6 +15,7 @@
import android.graphics.Bitmap;
import android.graphics.Bitmap.Config;
import android.graphics.BitmapFactory;
+import android.graphics.BitmapShader;
import android.graphics.Canvas;
import android.graphics.ColorMatrix;
import android.graphics.ColorMatrixColorFilter;
@@ -121,19 +122,20 @@
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 final float sWidgetPreviewIconPaddingPercentage = 0.25f;
+ private static final float sWidgetPreviewIconPaddingPercentage = 0.25f;
private CacheDb mDb;
- private HashMap<String, WeakReference<Bitmap>> mLoadedPreviews;
- private ArrayList<SoftReference<Bitmap>> mUnusedBitmaps;
- private static HashSet<String> sInvalidPackages;
+ private final HashMap<String, WeakReference<Bitmap>> mLoadedPreviews;
+ private final ArrayList<SoftReference<Bitmap>> mUnusedBitmaps;
+ private final static HashSet<String> sInvalidPackages;
static {
sInvalidPackages = new HashSet<String>();
@@ -184,18 +186,19 @@
final String name = getObjectName(o);
final String packageName = getObjectPackage(o);
// check if the package is valid
- boolean packageValid = true;
synchronized(sInvalidPackages) {
- packageValid = !sInvalidPackages.contains(packageName);
+ boolean packageValid = !sInvalidPackages.contains(packageName);
+ if (!packageValid) {
+ return null;
+ }
}
- if (!packageValid) {
- return null;
- }
- if (packageValid) {
- synchronized(mLoadedPreviews) {
- // check if it exists in our existing cache
- if (mLoadedPreviews.containsKey(name) && mLoadedPreviews.get(name).get() != null) {
- return mLoadedPreviews.get(name).get();
+ synchronized(mLoadedPreviews) {
+ // check if it exists in our existing cache
+ if (mLoadedPreviews.containsKey(name)) {
+ WeakReference<Bitmap> bitmapReference = mLoadedPreviews.get(name);
+ Bitmap bitmap = bitmapReference.get();
+ if (bitmap != null) {
+ return bitmap;
}
}
}
@@ -203,11 +206,13 @@
Bitmap unusedBitmap = null;
synchronized(mUnusedBitmaps) {
// not in cache; we need to load it from the db
- while ((unusedBitmap == null || !unusedBitmap.isMutable() ||
- unusedBitmap.getWidth() != mPreviewBitmapWidth ||
- unusedBitmap.getHeight() != mPreviewBitmapHeight)
- && mUnusedBitmaps.size() > 0) {
- unusedBitmap = mUnusedBitmaps.remove(0).get();
+ while (unusedBitmap == null && mUnusedBitmaps.size() > 0) {
+ Bitmap candidate = mUnusedBitmaps.remove(0).get();
+ if (candidate != null && candidate.isMutable() &&
+ candidate.getWidth() == mPreviewBitmapWidth &&
+ candidate.getHeight() == mPreviewBitmapHeight) {
+ unusedBitmap = candidate;
+ }
}
if (unusedBitmap != null) {
final Canvas c = mCachedAppWidgetPreviewCanvas.get();
@@ -221,12 +226,7 @@
unusedBitmap = Bitmap.createBitmap(mPreviewBitmapWidth, mPreviewBitmapHeight,
Bitmap.Config.ARGB_8888);
}
-
- Bitmap preview = null;
-
- if (packageValid) {
- preview = readFromDb(name, unusedBitmap);
- }
+ Bitmap preview = readFromDb(name, unusedBitmap);
if (preview != null) {
synchronized(mLoadedPreviews) {
@@ -520,14 +520,19 @@
previewWidth = previewDrawableWidth * cellHSpan;
previewHeight = previewDrawableHeight * cellVSpan;
- defaultPreview = Bitmap.createBitmap(previewWidth, previewHeight,
- Config.ARGB_8888);
+ defaultPreview = Bitmap.createBitmap(previewWidth, previewHeight, Config.ARGB_8888);
final Canvas c = mCachedAppWidgetPreviewCanvas.get();
c.setBitmap(defaultPreview);
- previewDrawable.setBounds(0, 0, previewWidth, previewHeight);
- previewDrawable.setTileModeXY(Shader.TileMode.REPEAT,
- Shader.TileMode.REPEAT);
- previewDrawable.draw(c);
+ Paint p = mDefaultAppWidgetPreviewPaint.get();
+ if (p == null) {
+ p = new Paint();
+ p.setShader(new BitmapShader(previewDrawable.getBitmap(),
+ Shader.TileMode.REPEAT, Shader.TileMode.REPEAT));
+ mDefaultAppWidgetPreviewPaint.set(p);
+ }
+ final Rect dest = mCachedAppWidgetPreviewDestRect.get();
+ dest.set(0, 0, previewWidth, previewHeight);
+ c.drawRect(dest, p);
c.setBitmap(null);
// Draw the icon in the top left corner
diff --git a/src/com/android/launcher3/Workspace.java b/src/com/android/launcher3/Workspace.java
index 567abfa..9800cf3 100644
--- a/src/com/android/launcher3/Workspace.java
+++ b/src/com/android/launcher3/Workspace.java
@@ -37,6 +37,7 @@
import android.graphics.Bitmap;
import android.graphics.Canvas;
import android.graphics.Matrix;
+import android.graphics.Paint;
import android.graphics.Point;
import android.graphics.PointF;
import android.graphics.Rect;
@@ -59,7 +60,6 @@
import android.view.animation.DecelerateInterpolator;
import android.view.animation.Interpolator;
import android.widget.TextView;
-
import com.android.launcher3.FolderIcon.FolderRingAnimator;
import com.android.launcher3.Launcher.CustomContentCallbacks;
import com.android.launcher3.LauncherSettings.Favorites;
@@ -96,6 +96,9 @@
private static final float ALPHA_CUTOFF_THRESHOLD = 0.01f;
+ private static final boolean MAP_NO_RECURSE = false;
+ private static final boolean MAP_RECURSE = true;
+
// These animators are used to fade the children's outlines
private ObjectAnimator mChildrenOutlineFadeInAnimation;
private ObjectAnimator mChildrenOutlineFadeOutAnimation;
@@ -693,6 +696,12 @@
// Log to disk
Launcher.addDumpLog(TAG, "11683562 - convertFinalScreenToEmptyScreenIfNecessary()", true);
+ if (mLauncher.isWorkspaceLoading()) {
+ // Invalid and dangerous operation if workspace is loading
+ Launcher.addDumpLog(TAG, " - workspace loading, skip", true);
+ return;
+ }
+
if (hasExtraEmptyScreen() || mScreenOrder.size() == 0) return;
long finalScreenId = mScreenOrder.get(mScreenOrder.size() - 1);
@@ -723,6 +732,12 @@
final int delay, final boolean stripEmptyScreens) {
// Log to disk
Launcher.addDumpLog(TAG, "11683562 - removeExtraEmptyScreen()", true);
+ if (mLauncher.isWorkspaceLoading()) {
+ // Don't strip empty screens if the workspace is still loading
+ Launcher.addDumpLog(TAG, " - workspace loading, skip", true);
+ return;
+ }
+
if (delay > 0) {
postDelayed(new Runnable() {
@Override
@@ -807,6 +822,11 @@
public long commitExtraEmptyScreen() {
// Log to disk
Launcher.addDumpLog(TAG, "11683562 - commitExtraEmptyScreen()", true);
+ if (mLauncher.isWorkspaceLoading()) {
+ // Invalid and dangerous operation if workspace is loading
+ Launcher.addDumpLog(TAG, " - workspace loading, skip", true);
+ return -1;
+ }
int index = getPageIndexForScreenId(EXTRA_EMPTY_SCREEN_ID);
CellLayout cl = mWorkspaceScreens.get(EXTRA_EMPTY_SCREEN_ID);
@@ -864,7 +884,8 @@
Launcher.addDumpLog(TAG, "11683562 - stripEmptyScreens()", true);
if (mLauncher.isWorkspaceLoading()) {
- // Don't strip empty screens if the workspace is still loading
+ // Don't strip empty screens if the workspace is still loading.
+ // This is dangerous and can result in data loss.
Launcher.addDumpLog(TAG, " - workspace loading, skip", true);
return;
}
@@ -1215,7 +1236,7 @@
if (hasCustomContent() && getNextPage() == 0 && !mCustomContentShowing) {
mCustomContentShowing = true;
if (mCustomContentCallbacks != null) {
- mCustomContentCallbacks.onShow();
+ mCustomContentCallbacks.onShow(false);
mCustomContentShowTime = System.currentTimeMillis();
mLauncher.updateVoiceButtonProxyVisible(false);
}
@@ -1971,6 +1992,45 @@
mDragOutline = createDragOutline(v, canvas, DRAG_BITMAP_PADDING);
}
+ private Rect getDrawableBounds(Drawable d) {
+ Rect bounds = new Rect();
+ d.copyBounds(bounds);
+ if (bounds.width() == 0 || bounds.height() == 0) {
+ bounds.set(0, 0, d.getIntrinsicWidth(), d.getIntrinsicHeight());
+ }
+ return bounds;
+ }
+
+ 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();
+ int iconSize = grid.iconSizePx;
+ int bmpWidth = v.getMeasuredWidth();
+ int bmpHeight = v.getMeasuredHeight();
+
+ // If this is a text view, use its drawable instead
+ if (v instanceof TextView) {
+ TextView tv = (TextView) v;
+ Drawable d = tv.getCompoundDrawables()[1];
+ Rect bounds = getDrawableBounds(d);
+ bmpWidth = bounds.width();
+ bmpHeight = bounds.height();
+ }
+
+ // 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, true);
+ c.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);
+ }
+
public void onDragStartedWithItem(PendingAddItemInfo info, Bitmap b, boolean clipAlpha) {
final Canvas canvas = new Canvas();
@@ -2019,6 +2079,11 @@
protected void onEndReordering() {
super.onEndReordering();
+ if (mLauncher.isWorkspaceLoading()) {
+ // Invalid and dangerous operation if workspace is loading
+ return;
+ }
+
hideOutlines();
mScreenOrder.clear();
int count = getChildCount();
@@ -2472,7 +2537,8 @@
destCanvas.save();
if (v instanceof TextView && pruneToDrawable) {
Drawable d = ((TextView) v).getCompoundDrawables()[1];
- clipRect.set(0, 0, d.getIntrinsicWidth() + padding, d.getIntrinsicHeight() + padding);
+ Rect bounds = getDrawableBounds(d);
+ clipRect.set(0, 0, bounds.width() + padding, bounds.height() + padding);
destCanvas.translate(padding / 2, padding / 2);
d.draw(destCanvas);
} else {
@@ -2513,8 +2579,9 @@
if (v instanceof TextView) {
Drawable d = ((TextView) v).getCompoundDrawables()[1];
- b = Bitmap.createBitmap(d.getIntrinsicWidth() + padding,
- d.getIntrinsicHeight() + padding, Bitmap.Config.ARGB_8888);
+ Rect bounds = getDrawableBounds(d);
+ b = Bitmap.createBitmap(bounds.width() + padding,
+ bounds.height() + padding, Bitmap.Config.ARGB_8888);
} else {
b = Bitmap.createBitmap(
v.getWidth() + padding, v.getHeight() + padding, Bitmap.Config.ARGB_8888);
@@ -2595,6 +2662,7 @@
}
public void beginDragShared(View child, DragSource source) {
+ mLauncher.onDragStarted(child);
// The drag bitmap follows the touch point around on the screen
final Bitmap b = createDragBitmap(child, new Canvas(), DRAG_BITMAP_PADDING);
@@ -2602,10 +2670,8 @@
final int bmpHeight = b.getHeight();
float scale = mLauncher.getDragLayer().getLocationInDragLayer(child, mTempXY);
- int dragLayerX =
- Math.round(mTempXY[0] - (bmpWidth - scale * child.getWidth()) / 2);
- int dragLayerY =
- Math.round(mTempXY[1] - (bmpHeight - scale * bmpHeight) / 2
+ int dragLayerX = Math.round(mTempXY[0] - (bmpWidth - scale * child.getWidth()) / 2);
+ int dragLayerY = Math.round(mTempXY[1] - (bmpHeight - scale * bmpHeight) / 2
- DRAG_BITMAP_PADDING / 2);
LauncherAppState app = LauncherAppState.getInstance();
@@ -2655,6 +2721,52 @@
b.recycle();
}
+ public void beginExternalDragShared(View child, DragSource source) {
+ LauncherAppState app = LauncherAppState.getInstance();
+ DeviceProfile grid = app.getDynamicGrid().getDeviceProfile();
+ int iconSize = grid.iconSizePx;
+
+ // Notify launcher of drag start
+ mLauncher.onDragStarted(child);
+
+ // Compose a new drag bitmap that is of the icon size
+ final Bitmap tmpB = createDragBitmap(child, new Canvas(), DRAG_BITMAP_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()),
+ new Rect(0, 0, iconSize, iconSize), p);
+ c.setBitmap(null);
+
+ // Find the child's location on the screen
+ int bmpWidth = tmpB.getWidth();
+ float iconScale = (float) bmpWidth / iconSize;
+ float scale = mLauncher.getDragLayer().getLocationInDragLayer(child, mTempXY) * iconScale;
+ int dragLayerX = Math.round(mTempXY[0] - (bmpWidth - scale * child.getWidth()) / 2);
+ int dragLayerY = Math.round(mTempXY[1]);
+
+ // Note: The drag region is used to calculate drag layer offsets, but the
+ // dragVisualizeOffset in addition to the dragRect (the size) to position the outline.
+ Point dragVisualizeOffset = new Point(-DRAG_BITMAP_PADDING / 2, DRAG_BITMAP_PADDING / 2);
+ Rect dragRect = new Rect(0, 0, iconSize, iconSize);
+
+ if (child.getTag() == null || !(child.getTag() instanceof ItemInfo)) {
+ String msg = "Drag started with a view that has no tag set. This "
+ + "will cause a crash (issue 11627249) down the line. "
+ + "View: " + child + " tag: " + child.getTag();
+ throw new IllegalStateException(msg);
+ }
+
+ // Start the drag
+ DragView dv = mDragController.startDrag(b, dragLayerX, dragLayerY, source, child.getTag(),
+ DragController.DRAG_ACTION_MOVE, dragVisualizeOffset, dragRect, scale);
+ dv.setIntrinsicIconScaleFactor(source.getIntrinsicIconScaleFactor());
+
+ // Recycle temporary bitmaps
+ tmpB.recycle();
+ }
+
void addApplicationShortcut(ShortcutInfo info, CellLayout target, long container, long screenId,
int cellX, int cellY, boolean insertAtFirst, int intersectX, int intersectY) {
View view = mLauncher.createShortcut(R.layout.application, target, (ShortcutInfo) info);
@@ -4452,51 +4564,50 @@
return childrenLayouts;
}
- public Folder getFolderForTag(Object tag) {
- ArrayList<ShortcutAndWidgetContainer> childrenLayouts =
- getAllShortcutAndWidgetContainers();
- for (ShortcutAndWidgetContainer layout: childrenLayouts) {
- int count = layout.getChildCount();
- for (int i = 0; i < count; i++) {
- View child = layout.getChildAt(i);
- if (child instanceof Folder) {
- Folder f = (Folder) child;
+ public Folder getFolderForTag(final Object tag) {
+ final Folder[] value = new Folder[1];
+ mapOverShortcuts(MAP_NO_RECURSE, new ShortcutOperator() {
+ @Override
+ public boolean evaluate(ItemInfo info, View v, View parent) {
+ if (v instanceof Folder) {
+ Folder f = (Folder) v;
if (f.getInfo() == tag && f.getInfo().opened) {
- return f;
+ value[0] = f;
+ return true;
}
}
+ return false;
}
- }
- return null;
+ });
+ return value[0];
}
- public View getViewForTag(Object tag) {
- ArrayList<ShortcutAndWidgetContainer> childrenLayouts =
- getAllShortcutAndWidgetContainers();
- for (ShortcutAndWidgetContainer layout: childrenLayouts) {
- int count = layout.getChildCount();
- for (int i = 0; i < count; i++) {
- View child = layout.getChildAt(i);
- if (child.getTag() == tag) {
- return child;
+ public View getViewForTag(final Object tag) {
+ final View[] value = new View[1];
+ mapOverShortcuts(MAP_NO_RECURSE, new ShortcutOperator() {
+ @Override
+ public boolean evaluate(ItemInfo info, View v, View parent) {
+ if (v.getTag() == tag) {
+ value[0] = v;
+ return true;
}
+ return false;
}
- }
- return null;
+ });
+ return value[0];
}
void clearDropTargets() {
- ArrayList<ShortcutAndWidgetContainer> childrenLayouts =
- getAllShortcutAndWidgetContainers();
- for (ShortcutAndWidgetContainer layout: childrenLayouts) {
- int childCount = layout.getChildCount();
- for (int j = 0; j < childCount; j++) {
- View v = layout.getChildAt(j);
+ mapOverShortcuts(MAP_NO_RECURSE, new ShortcutOperator() {
+ @Override
+ public boolean evaluate(ItemInfo info, View v, View parent) {
if (v instanceof DropTarget) {
mDragController.removeDropTarget((DropTarget) v);
}
+ // not done, process all the shortcuts
+ return false;
}
- }
+ });
}
// Removes ALL items that match a given package name, this is usually called when a package
@@ -4638,6 +4749,55 @@
}
}
+ interface ShortcutOperator {
+ /**
+ * Process the next shortcut, possibly with side-effect on {@link ShortcutOperator#value}.
+ *
+ * @param info info for the shortcut
+ * @param view view for the shortcut
+ * @param parent containing folder, or null
+ * @return true if done, false to continue the map
+ */
+ public boolean evaluate(ItemInfo info, View view, View parent);
+ }
+
+ /**
+ * Map the operator over the shortcuts, return the first-non-null value.
+ *
+ * @param recurse true: iterate over folder children. false: op get the folders themselves.
+ * @param op the operator to map over the shortcuts
+ */
+ void mapOverShortcuts(boolean recurse, ShortcutOperator op) {
+ ArrayList<ShortcutAndWidgetContainer> containers = getAllShortcutAndWidgetContainers();
+ final int containerCount = containers.size();
+ for (int containerIdx = 0; containerIdx < containerCount; containerIdx++) {
+ ShortcutAndWidgetContainer container = containers.get(containerIdx);
+ // map over all the shortcuts on the workspace
+ final int itemCount = container.getChildCount();
+ for (int itemIdx = 0; itemIdx < itemCount; itemIdx++) {
+ View item = container.getChildAt(itemIdx);
+ ItemInfo info = (ItemInfo) item.getTag();
+ if (recurse && info instanceof FolderInfo && item instanceof FolderIcon) {
+ FolderIcon folder = (FolderIcon) item;
+ ArrayList<View> folderChildren = folder.getFolder().getItemsInReadingOrder();
+ // map over all the children in the folder
+ final int childCount = folderChildren.size();
+ for (int childIdx = 0; childIdx < childCount; childIdx++) {
+ View child = folderChildren.get(childIdx);
+ info = (ItemInfo) child.getTag();
+ if (op.evaluate(info, child, folder)) {
+ return;
+ }
+ }
+ } else {
+ if (op.evaluate(info, item, null)) {
+ return;
+ }
+ }
+ }
+ }
+ }
+
void updateShortcuts(ArrayList<AppInfo> apps) {
// Create a map of the apps to test against
final HashMap<ComponentName, AppInfo> appsMap = new HashMap<ComponentName, AppInfo>();
@@ -4645,26 +4805,34 @@
appsMap.put(ai.componentName, ai);
}
- ArrayList<ShortcutAndWidgetContainer> childrenLayouts = getAllShortcutAndWidgetContainers();
- for (ShortcutAndWidgetContainer layout: childrenLayouts) {
- // Update all the children shortcuts
- final HashMap<ItemInfo, View> children = new HashMap<ItemInfo, View>();
- for (int j = 0; j < layout.getChildCount(); j++) {
- View v = layout.getChildAt(j);
- ItemInfo info = (ItemInfo) v.getTag();
- if (info instanceof FolderInfo && v instanceof FolderIcon) {
- FolderIcon folder = (FolderIcon) v;
- ArrayList<View> folderChildren = folder.getFolder().getItemsInReadingOrder();
- for (View fv : folderChildren) {
- info = (ItemInfo) fv.getTag();
- updateShortcut(appsMap, info, fv);
- }
- folder.invalidate();
- } else if (info instanceof ShortcutInfo) {
+ mapOverShortcuts(MAP_RECURSE, new ShortcutOperator() {
+ @Override
+ public boolean evaluate(ItemInfo info, View v, View parent) {
+ if (info instanceof ShortcutInfo) {
updateShortcut(appsMap, info, v);
+ if (parent != null) {
+ parent.invalidate();
+ }
}
+ // process all the shortcuts
+ return false;
}
- }
+ });
+ }
+
+ public void updatePackageState(final String pkgName, final int state) {
+ mapOverShortcuts(MAP_RECURSE, new ShortcutOperator() {
+ @Override
+ public boolean evaluate(ItemInfo info, View v, View parent) {
+ if (info instanceof ShortcutInfo
+ && ((ShortcutInfo) info).isPromiseFor(pkgName)
+ && v instanceof BubbleTextView) {
+ ((BubbleTextView)v).setState(state);
+ }
+ // process all the shortcuts
+ return false;
+ }
+ });
}
private void moveToScreen(int page, boolean animate) {