am 441874b1: (-s ours) Import translations. DO NOT MERGE

* commit '441874b19d79db51ea3488983f13b6e11b0cf796':
  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..bbbd910 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;
             }
diff --git a/res/values-af/strings.xml b/res/values-af/strings.xml
index b5c17c5..dfd11f1 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="6858560020210815018">"Fout"</string>
 </resources>
diff --git a/res/values-am/strings.xml b/res/values-am/strings.xml
index ea64f6f..aa8902f 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="6858560020210815018">"ስህተት"</string>
 </resources>
diff --git a/res/values-ar/strings.xml b/res/values-ar/strings.xml
index 7eb37d3..3daa2c9 100644
--- a/res/values-ar/strings.xml
+++ b/res/values-ar/strings.xml
@@ -107,4 +107,14 @@
     <string name="widget_button_text" msgid="2880537293434387943">"الأدوات"</string>
     <string name="wallpaper_button_text" msgid="8404103075899945851">"الخلفيات"</string>
     <string name="settings_button_text" msgid="8119458837558863227">"الإعدادات"</string>
+    <!-- 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 (6858560020210815018) -->
+    <skip />
 </resources>
diff --git a/res/values-bg/strings.xml b/res/values-bg/strings.xml
index 13c0118..d50c59b 100644
--- a/res/values-bg/strings.xml
+++ b/res/values-bg/strings.xml
@@ -107,4 +107,14 @@
     <string name="widget_button_text" msgid="2880537293434387943">"Приспособления"</string>
     <string name="wallpaper_button_text" msgid="8404103075899945851">"Тапети"</string>
     <string name="settings_button_text" msgid="8119458837558863227">"Настройки"</string>
+    <!-- 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 (6858560020210815018) -->
+    <skip />
 </resources>
diff --git a/res/values-ca/strings.xml b/res/values-ca/strings.xml
index 3e6bedb..6ff3b4f 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="6858560020210815018">"Error"</string>
 </resources>
diff --git a/res/values-cs/strings.xml b/res/values-cs/strings.xml
index 3a0e672..59400ca 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="6858560020210815018">"Chyba"</string>
 </resources>
diff --git a/res/values-da/strings.xml b/res/values-da/strings.xml
index 7d41489..b965964 100644
--- a/res/values-da/strings.xml
+++ b/res/values-da/strings.xml
@@ -107,4 +107,14 @@
     <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>
+    <!-- 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 (6858560020210815018) -->
+    <skip />
 </resources>
diff --git a/res/values-de/strings.xml b/res/values-de/strings.xml
index ff6d114..b4f189d 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="6858560020210815018">"Fehler"</string>
 </resources>
diff --git a/res/values-el/strings.xml b/res/values-el/strings.xml
index ec05ae5..096c1d2 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="6858560020210815018">"Σφάλμα"</string>
 </resources>
diff --git a/res/values-en-rGB/strings.xml b/res/values-en-rGB/strings.xml
index cab1707..ff83b1b 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="6858560020210815018">"Error"</string>
 </resources>
diff --git a/res/values-en-rIN/strings.xml b/res/values-en-rIN/strings.xml
index cab1707..ff83b1b 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="6858560020210815018">"Error"</string>
 </resources>
diff --git a/res/values-es-rUS/strings.xml b/res/values-es-rUS/strings.xml
index 278f0d8..7f5f06c 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="6858560020210815018">"Error"</string>
 </resources>
diff --git a/res/values-es/strings.xml b/res/values-es/strings.xml
index f9cf809..da36650 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="6858560020210815018">"Error"</string>
 </resources>
diff --git a/res/values-et-rEE/strings.xml b/res/values-et-rEE/strings.xml
index 92985d2..185ddea 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="6858560020210815018">"Viga"</string>
 </resources>
diff --git a/res/values-fa/strings.xml b/res/values-fa/strings.xml
index a01ea79..12de7fb 100644
--- a/res/values-fa/strings.xml
+++ b/res/values-fa/strings.xml
@@ -107,4 +107,14 @@
     <string name="widget_button_text" msgid="2880537293434387943">"ابزارک‌ها"</string>
     <string name="wallpaper_button_text" msgid="8404103075899945851">"کاغذدیواری‌ها"</string>
     <string name="settings_button_text" msgid="8119458837558863227">"تنظیمات"</string>
+    <!-- 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 (6858560020210815018) -->
+    <skip />
 </resources>
diff --git a/res/values-fi/strings.xml b/res/values-fi/strings.xml
index 9a48ab3..8fcb221 100644
--- a/res/values-fi/strings.xml
+++ b/res/values-fi/strings.xml
@@ -107,4 +107,14 @@
     <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>
+    <!-- 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 (6858560020210815018) -->
+    <skip />
 </resources>
diff --git a/res/values-fr-rCA/strings.xml b/res/values-fr-rCA/strings.xml
index 92c5cc4..27fcba4 100644
--- a/res/values-fr-rCA/strings.xml
+++ b/res/values-fr-rCA/strings.xml
@@ -107,4 +107,14 @@
     <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>
+    <!-- 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 (6858560020210815018) -->
+    <skip />
 </resources>
diff --git a/res/values-fr/strings.xml b/res/values-fr/strings.xml
index 18732f8..c69b805 100644
--- a/res/values-fr/strings.xml
+++ b/res/values-fr/strings.xml
@@ -107,4 +107,14 @@
     <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>
+    <!-- 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 (6858560020210815018) -->
+    <skip />
 </resources>
diff --git a/res/values-hi/strings.xml b/res/values-hi/strings.xml
index a5481a1..c79125a 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="6858560020210815018">"त्रुटि"</string>
 </resources>
diff --git a/res/values-hr/strings.xml b/res/values-hr/strings.xml
index 32f3feb..59ad94c 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="6858560020210815018">"Pogreška"</string>
 </resources>
diff --git a/res/values-hu/strings.xml b/res/values-hu/strings.xml
index 37d5059..b9ffbb5 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"</string>
+    <string name="package_state_installing" msgid="7588193972189849870">"Telepítése"</string>
+    <string name="package_state_unknown" msgid="7592128424511031410">"Ismeretlen"</string>
+    <string name="package_state_error" msgid="6858560020210815018">"Hiba"</string>
 </resources>
diff --git a/res/values-hy-rAM/strings.xml b/res/values-hy-rAM/strings.xml
index 6e9491b..bf7afd2 100644
--- a/res/values-hy-rAM/strings.xml
+++ b/res/values-hy-rAM/strings.xml
@@ -107,4 +107,14 @@
     <string name="widget_button_text" msgid="2880537293434387943">"Վիջեթներ"</string>
     <string name="wallpaper_button_text" msgid="8404103075899945851">"Պաստառներ"</string>
     <string name="settings_button_text" msgid="8119458837558863227">"Կարգավորումներ"</string>
+    <!-- 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 (6858560020210815018) -->
+    <skip />
 </resources>
diff --git a/res/values-in/strings.xml b/res/values-in/strings.xml
index d5df63b..eb3d287 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="6858560020210815018">"Kesalahan"</string>
 </resources>
diff --git a/res/values-it/strings.xml b/res/values-it/strings.xml
index 20451d1..c71a14f 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="6858560020210815018">"Errore"</string>
 </resources>
diff --git a/res/values-iw/strings.xml b/res/values-iw/strings.xml
index 08d9653..3a79a1f 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="6858560020210815018">"שגיאה"</string>
 </resources>
diff --git a/res/values-ja/strings.xml b/res/values-ja/strings.xml
index ad5e8ff..a3c4d53 100644
--- a/res/values-ja/strings.xml
+++ b/res/values-ja/strings.xml
@@ -107,4 +107,14 @@
     <string name="widget_button_text" msgid="2880537293434387943">"ウィジェット"</string>
     <string name="wallpaper_button_text" msgid="8404103075899945851">"壁紙"</string>
     <string name="settings_button_text" msgid="8119458837558863227">"設定"</string>
+    <!-- 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 (6858560020210815018) -->
+    <skip />
 </resources>
diff --git a/res/values-ka-rGE/strings.xml b/res/values-ka-rGE/strings.xml
index 086df72..1e11b6a 100644
--- a/res/values-ka-rGE/strings.xml
+++ b/res/values-ka-rGE/strings.xml
@@ -107,4 +107,14 @@
     <string name="widget_button_text" msgid="2880537293434387943">"ვიჯეტები"</string>
     <string name="wallpaper_button_text" msgid="8404103075899945851">"ფონები"</string>
     <string name="settings_button_text" msgid="8119458837558863227">"პარამეტრები"</string>
+    <!-- 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 (6858560020210815018) -->
+    <skip />
 </resources>
diff --git a/res/values-km-rKH/strings.xml b/res/values-km-rKH/strings.xml
index bf2f01c..fc8d32b 100644
--- a/res/values-km-rKH/strings.xml
+++ b/res/values-km-rKH/strings.xml
@@ -107,4 +107,14 @@
     <string name="widget_button_text" msgid="2880537293434387943">"ធាតុ​ក្រាហ្វិក"</string>
     <string name="wallpaper_button_text" msgid="8404103075899945851">"ផ្ទាំង​រូបភាព"</string>
     <string name="settings_button_text" msgid="8119458837558863227">"ការកំណត់"</string>
+    <!-- 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 (6858560020210815018) -->
+    <skip />
 </resources>
diff --git a/res/values-ko/strings.xml b/res/values-ko/strings.xml
index dde4eb7..b5ca25f 100644
--- a/res/values-ko/strings.xml
+++ b/res/values-ko/strings.xml
@@ -107,4 +107,14 @@
     <string name="widget_button_text" msgid="2880537293434387943">"위젯"</string>
     <string name="wallpaper_button_text" msgid="8404103075899945851">"배경화면"</string>
     <string name="settings_button_text" msgid="8119458837558863227">"설정"</string>
+    <!-- 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 (6858560020210815018) -->
+    <skip />
 </resources>
diff --git a/res/values-lo-rLA/strings.xml b/res/values-lo-rLA/strings.xml
index 092098b..ec7316a 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="6858560020210815018">"ຜິດພາດ"</string>
 </resources>
diff --git a/res/values-lt/strings.xml b/res/values-lt/strings.xml
index aba231d..631508d 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="6858560020210815018">"Klaida"</string>
 </resources>
diff --git a/res/values-lv/strings.xml b/res/values-lv/strings.xml
index 6d4888d..0ea54a4 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="6858560020210815018">"Kļūda"</string>
 </resources>
diff --git a/res/values-mn-rMN/strings.xml b/res/values-mn-rMN/strings.xml
index db92a5c..2b60612 100644
--- a/res/values-mn-rMN/strings.xml
+++ b/res/values-mn-rMN/strings.xml
@@ -107,4 +107,14 @@
     <string name="widget_button_text" msgid="2880537293434387943">"Виджет"</string>
     <string name="wallpaper_button_text" msgid="8404103075899945851">"Ханын зураг"</string>
     <string name="settings_button_text" msgid="8119458837558863227">"Тохиргоо"</string>
+    <!-- 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 (6858560020210815018) -->
+    <skip />
 </resources>
diff --git a/res/values-ms-rMY/strings.xml b/res/values-ms-rMY/strings.xml
index 678eeb4..5152461 100644
--- a/res/values-ms-rMY/strings.xml
+++ b/res/values-ms-rMY/strings.xml
@@ -107,4 +107,14 @@
     <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>
+    <!-- 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 (6858560020210815018) -->
+    <skip />
 </resources>
diff --git a/res/values-nb/strings.xml b/res/values-nb/strings.xml
index dd89a4f..e88ff22 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="6858560020210815018">"Feil"</string>
 </resources>
diff --git a/res/values-nl/strings.xml b/res/values-nl/strings.xml
index d39c1ea..b2bb5e9 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="6858560020210815018">"Fout"</string>
 </resources>
diff --git a/res/values-pl/strings.xml b/res/values-pl/strings.xml
index b428a95..c408a32 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="6858560020210815018">"Błąd"</string>
 </resources>
diff --git a/res/values-pt-rPT/strings.xml b/res/values-pt-rPT/strings.xml
index b8e51d6..7fdd23e 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="6858560020210815018">"Erro"</string>
 </resources>
diff --git a/res/values-pt/strings.xml b/res/values-pt/strings.xml
index 03c621a..9a9ff34 100644
--- a/res/values-pt/strings.xml
+++ b/res/values-pt/strings.xml
@@ -107,4 +107,14 @@
     <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>
+    <!-- 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 (6858560020210815018) -->
+    <skip />
 </resources>
diff --git a/res/values-rm/strings.xml b/res/values-rm/strings.xml
index 3600095..68d6dbf 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 (6858560020210815018) -->
+    <skip />
 </resources>
diff --git a/res/values-ro/strings.xml b/res/values-ro/strings.xml
index a667ffd..62ebed3 100644
--- a/res/values-ro/strings.xml
+++ b/res/values-ro/strings.xml
@@ -107,4 +107,14 @@
     <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>
+    <!-- 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 (6858560020210815018) -->
+    <skip />
 </resources>
diff --git a/res/values-ru/strings.xml b/res/values-ru/strings.xml
index c2e8bc7..cf39d3b 100644
--- a/res/values-ru/strings.xml
+++ b/res/values-ru/strings.xml
@@ -107,4 +107,14 @@
     <string name="widget_button_text" msgid="2880537293434387943">"Виджеты"</string>
     <string name="wallpaper_button_text" msgid="8404103075899945851">"Обои"</string>
     <string name="settings_button_text" msgid="8119458837558863227">"Настройки"</string>
+    <!-- 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 (6858560020210815018) -->
+    <skip />
 </resources>
diff --git a/res/values-sk/strings.xml b/res/values-sk/strings.xml
index acd8e05..1c54589 100644
--- a/res/values-sk/strings.xml
+++ b/res/values-sk/strings.xml
@@ -107,4 +107,14 @@
     <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>
+    <!-- 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 (6858560020210815018) -->
+    <skip />
 </resources>
diff --git a/res/values-sl/strings.xml b/res/values-sl/strings.xml
index afbd620..c3eb85d 100644
--- a/res/values-sl/strings.xml
+++ b/res/values-sl/strings.xml
@@ -107,4 +107,14 @@
     <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>
+    <!-- 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 (6858560020210815018) -->
+    <skip />
 </resources>
diff --git a/res/values-sr/strings.xml b/res/values-sr/strings.xml
index bf71b28..ce4e749 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="6858560020210815018">"Грешка"</string>
 </resources>
diff --git a/res/values-sv/strings.xml b/res/values-sv/strings.xml
index 5825eec..b154a3a 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="6858560020210815018">"Fel"</string>
 </resources>
diff --git a/res/values-sw/strings.xml b/res/values-sw/strings.xml
index 37d0708..8dfcff7 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="6858560020210815018">"Hitilafu"</string>
 </resources>
diff --git a/res/values-th/strings.xml b/res/values-th/strings.xml
index 87e8237..5b820d0 100644
--- a/res/values-th/strings.xml
+++ b/res/values-th/strings.xml
@@ -107,4 +107,14 @@
     <string name="widget_button_text" msgid="2880537293434387943">"วิดเจ็ต"</string>
     <string name="wallpaper_button_text" msgid="8404103075899945851">"วอลเปเปอร์"</string>
     <string name="settings_button_text" msgid="8119458837558863227">"การตั้งค่า"</string>
+    <!-- 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 (6858560020210815018) -->
+    <skip />
 </resources>
diff --git a/res/values-tl/strings.xml b/res/values-tl/strings.xml
index 5be9d85..5fb2d62 100644
--- a/res/values-tl/strings.xml
+++ b/res/values-tl/strings.xml
@@ -107,4 +107,14 @@
     <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>
+    <!-- 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 (6858560020210815018) -->
+    <skip />
 </resources>
diff --git a/res/values-tr/strings.xml b/res/values-tr/strings.xml
index 01f79a2..75fda78 100644
--- a/res/values-tr/strings.xml
+++ b/res/values-tr/strings.xml
@@ -107,4 +107,14 @@
     <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>
+    <!-- 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 (6858560020210815018) -->
+    <skip />
 </resources>
diff --git a/res/values-uk/strings.xml b/res/values-uk/strings.xml
index f266eea..acf8e27 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="6858560020210815018">"Помилка"</string>
 </resources>
diff --git a/res/values-vi/strings.xml b/res/values-vi/strings.xml
index 9d4ed41..ab99442 100644
--- a/res/values-vi/strings.xml
+++ b/res/values-vi/strings.xml
@@ -107,4 +107,14 @@
     <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>
+    <!-- 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 (6858560020210815018) -->
+    <skip />
 </resources>
diff --git a/res/values-zh-rCN/strings.xml b/res/values-zh-rCN/strings.xml
index 3a2638e..593bac0 100644
--- a/res/values-zh-rCN/strings.xml
+++ b/res/values-zh-rCN/strings.xml
@@ -107,4 +107,14 @@
     <string name="widget_button_text" msgid="2880537293434387943">"小部件"</string>
     <string name="wallpaper_button_text" msgid="8404103075899945851">"壁纸"</string>
     <string name="settings_button_text" msgid="8119458837558863227">"设置"</string>
+    <!-- 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 (6858560020210815018) -->
+    <skip />
 </resources>
diff --git a/res/values-zh-rHK/strings.xml b/res/values-zh-rHK/strings.xml
index cad95f2..2525798 100644
--- a/res/values-zh-rHK/strings.xml
+++ b/res/values-zh-rHK/strings.xml
@@ -107,4 +107,14 @@
     <string name="widget_button_text" msgid="2880537293434387943">"小工具"</string>
     <string name="wallpaper_button_text" msgid="8404103075899945851">"桌布"</string>
     <string name="settings_button_text" msgid="8119458837558863227">"設定"</string>
+    <!-- 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 (6858560020210815018) -->
+    <skip />
 </resources>
diff --git a/res/values-zh-rTW/strings.xml b/res/values-zh-rTW/strings.xml
index 5f48243..36e0d0b 100644
--- a/res/values-zh-rTW/strings.xml
+++ b/res/values-zh-rTW/strings.xml
@@ -107,4 +107,14 @@
     <string name="widget_button_text" msgid="2880537293434387943">"小工具"</string>
     <string name="wallpaper_button_text" msgid="8404103075899945851">"桌布"</string>
     <string name="settings_button_text" msgid="8119458837558863227">"設定"</string>
+    <!-- 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 (6858560020210815018) -->
+    <skip />
 </resources>
diff --git a/res/values-zu/strings.xml b/res/values-zu/strings.xml
index e982eb4..7401bfb 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="6858560020210815018">"Iphutha"</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..8ba58e5 100644
--- a/res/values/strings.xml
+++ b/res/values/strings.xml
@@ -262,4 +262,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">Error</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..5e8cca8 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";
 
     /**
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/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/Launcher.java b/src/com/android/launcher3/Launcher.java
index c22a6bf..f1ce235 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 {
     static final String TAG = "Launcher";
     static final boolean LOGD = false;
 
@@ -1010,7 +1011,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 +1055,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 +1070,6 @@
         return false;
     }
 
-    protected void startSettings() {
-    }
-
     public interface QSBScroller {
         public void setScrollY(int scrollY);
     }
@@ -1233,6 +1232,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 +1255,7 @@
             @Override
             public void onClick(View arg0) {
                 if (!mWorkspace.isSwitchingState()) {
-                    showAllApps(true, AppsCustomizePagedView.ContentType.Widgets, true);
+                    onClickAddWidgetButton(arg0);
                 }
             }
         });
@@ -1266,7 +1266,7 @@
             @Override
             public void onClick(View arg0) {
                 if (!mWorkspace.isSwitchingState()) {
-                    startWallpaper();
+                    onClickWallpaperPicker(arg0);
                 }
             }
         });
@@ -1278,9 +1278,9 @@
                 @Override
                 public void onClick(View arg0) {
                     if (!mWorkspace.isSwitchingState()) {
-                        startSettings();
+                        onClickSettingsButton(arg0);
                     }
-                    }
+                }
             });
             settingsButton.setOnTouchListener(getHapticFeedbackTouchListener());
         } else {
@@ -1334,6 +1334,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 +2271,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 +2374,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 +2434,133 @@
      *
      * @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 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);
@@ -2598,40 +2680,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 +2939,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;
@@ -4186,6 +4234,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,
@@ -4422,6 +4481,10 @@
         mWorkspace.beginDragShared(dragView, source);
     }
 
+    @Override
+    public void onPageSwitch(View newPage, int newPageIndex) {
+    }
+
     /**
      * Prints out out state for debugging.
      */
diff --git a/src/com/android/launcher3/LauncherAppState.java b/src/com/android/launcher3/LauncherAppState.java
index 29e18f9..ba10f51 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 = true; // TODO STOPSHIP: set this to 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/LauncherBackupAgentHelper.java b/src/com/android/launcher3/LauncherBackupAgentHelper.java
index de6aedd..7dd8cde 100644
--- a/src/com/android/launcher3/LauncherBackupAgentHelper.java
+++ b/src/com/android/launcher3/LauncherBackupAgentHelper.java
@@ -61,7 +61,7 @@
     @Override
     public void onCreate() {
         boolean restoreEnabled = 0 != Settings.Secure.getInt(
-                getContentResolver(), SETTING_RESTORE_ENABLED, 0);
+                getContentResolver(), SETTING_RESTORE_ENABLED, 1);
         if (VERBOSE) Log.v(TAG, "restore is " + (restoreEnabled ? "enabled" : "disabled"));
 
         addHelper(LauncherBackupHelper.LAUNCHER_PREFS_PREFIX,
diff --git a/src/com/android/launcher3/LauncherModel.java b/src/com/android/launcher3/LauncherModel.java
index 007fd7a..145d225 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(
+                LauncherSettings.Favorites.OLD_CONTENT_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;
 
@@ -2189,7 +2207,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..e9e3595 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;
@@ -352,6 +354,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";
@@ -1216,6 +1219,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 +1327,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/ShortcutInfo.java b/src/com/android/launcher3/ShortcutInfo.java
index 79d114c..ede3175 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.
@@ -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/Workspace.java b/src/com/android/launcher3/Workspace.java
index 567abfa..a22b025 100644
--- a/src/com/android/launcher3/Workspace.java
+++ b/src/com/android/launcher3/Workspace.java
@@ -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;
@@ -1215,7 +1218,7 @@
         if (hasCustomContent() && getNextPage() == 0 && !mCustomContentShowing) {
             mCustomContentShowing = true;
             if (mCustomContentCallbacks != null) {
-                mCustomContentCallbacks.onShow();
+                mCustomContentCallbacks.onShow(false);
                 mCustomContentShowTime = System.currentTimeMillis();
                 mLauncher.updateVoiceButtonProxyVisible(false);
             }
@@ -4452,51 +4455,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 +4640,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 +4696,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) {