am a78bfcc9: am 8c9802ef: am dc734ef2: Merge "Fixing issue where the PagedView scroll is out of sync with the current page. (Bug 11050528)" into jb-ub-now-indigo-rose

* commit 'a78bfcc9d02da4d47598461c1549742378d27b85':
diff --git a/Android.mk b/Android.mk
index 3b1a244..3bd20a7 100644
--- a/Android.mk
+++ b/Android.mk
@@ -37,7 +37,7 @@
 LOCAL_PACKAGE_NAME := Launcher3
 #LOCAL_CERTIFICATE := shared
 
-LOCAL_OVERRIDES_PACKAGES := Home
+LOCAL_OVERRIDES_PACKAGES := Launcher2
 
 LOCAL_PROGUARD_FLAG_FILES := proguard.flags
 
diff --git a/res/layout-port/workspace_cling.xml b/res/layout-port/workspace_cling.xml
index 9c000cb..b926ca9 100644
--- a/res/layout-port/workspace_cling.xml
+++ b/res/layout-port/workspace_cling.xml
@@ -62,8 +62,8 @@
             android:id="@+id/focused_hotseat_app_bubble"
             android:layout_width="wrap_content"
             android:layout_height="wrap_content"
-            android:layout_gravity="bottom|right"
-            android:layout_marginRight="25dp"
+            android:layout_gravity="bottom|left"
+            android:layout_marginLeft="25dp"
             android:layout_marginBottom="90dp"
             android:orientation="vertical"
             android:visibility="gone">
@@ -90,8 +90,8 @@
             <ImageView
                 android:layout_width="wrap_content"
                 android:layout_height="wrap_content"
-                android:layout_gravity="right"
-                android:layout_marginRight="80dp"
+                android:layout_gravity="left"
+                android:layout_marginLeft="78dp"
                 android:src="@drawable/cling_arrow_down" />
         </LinearLayout>
     </FrameLayout>
@@ -101,7 +101,7 @@
         android:layout_width="wrap_content"
         android:layout_height="wrap_content"
         android:layout_marginBottom="15dp"
-        android:layout_marginLeft="20dp"
-        android:layout_gravity="bottom|left"
+        android:layout_marginRight="20dp"
+        android:layout_gravity="bottom|right"
         android:onClick="dismissWorkspaceCling" />
 </com.android.launcher3.Cling>
diff --git a/res/values-af/strings.xml b/res/values-af/strings.xml
index 5d19114..e167189 100644
--- a/res/values-af/strings.xml
+++ b/res/values-af/strings.xml
@@ -29,6 +29,8 @@
     <item quantity="one" msgid="142482526010824029">"%1$d gekies"</item>
     <item quantity="other" msgid="1418352074806573570">"%1$d gekies"</item>
   </plurals>
+    <string name="wallpaper_accessibility_name" msgid="1655953108132967972">"Muurpapier %1$d van %2$d"</string>
+    <string name="announce_selection" msgid="8338254712932127413">"Het <xliff:g id="LABEL">%1$s</xliff:g> gekies"</string>
     <string name="wallpaper_delete" msgid="8095005658756613921">"Vee uit"</string>
     <string name="pick_image" msgid="1272073934062909527">"Kies prent"</string>
     <string name="pick_wallpaper" msgid="8179698221502010609">"Muurpapiere"</string>
diff --git a/res/values-am/strings.xml b/res/values-am/strings.xml
index 1fb96d3..6e8aaa4 100644
--- a/res/values-am/strings.xml
+++ b/res/values-am/strings.xml
@@ -29,6 +29,8 @@
     <item quantity="one" msgid="142482526010824029">"%1$d ተመርጧል"</item>
     <item quantity="other" msgid="1418352074806573570">"%1$d ተመርጧል"</item>
   </plurals>
+    <string name="wallpaper_accessibility_name" msgid="1655953108132967972">"የግድግዳ ወረቀት %1$d ከ%2$d"</string>
+    <string name="announce_selection" msgid="8338254712932127413">"<xliff:g id="LABEL">%1$s</xliff:g> ተመርጧል"</string>
     <string name="wallpaper_delete" msgid="8095005658756613921">"ሰርዝ"</string>
     <string name="pick_image" msgid="1272073934062909527">"ምስል ምረጥ"</string>
     <string name="pick_wallpaper" msgid="8179698221502010609">"የግድግዳ ወረቀቶች"</string>
diff --git a/res/values-ar/strings.xml b/res/values-ar/strings.xml
index 330fe99..73ee690 100644
--- a/res/values-ar/strings.xml
+++ b/res/values-ar/strings.xml
@@ -29,6 +29,8 @@
     <item quantity="one" msgid="142482526010824029">"تم تحديد %1$d"</item>
     <item quantity="other" msgid="1418352074806573570">"تم تحديد %1$d"</item>
   </plurals>
+    <string name="wallpaper_accessibility_name" msgid="1655953108132967972">"الخلفية %1$d من %2$d"</string>
+    <string name="announce_selection" msgid="8338254712932127413">"تم تحديد <xliff:g id="LABEL">%1$s</xliff:g>"</string>
     <string name="wallpaper_delete" msgid="8095005658756613921">"حذف"</string>
     <string name="pick_image" msgid="1272073934062909527">"اختيار صورة"</string>
     <string name="pick_wallpaper" msgid="8179698221502010609">"الخلفيات"</string>
diff --git a/res/values-be/strings.xml b/res/values-be/strings.xml
index 1a88d4a..ddcf404 100644
--- a/res/values-be/strings.xml
+++ b/res/values-be/strings.xml
@@ -31,6 +31,10 @@
     <!-- no translation found for number_of_items_selected:zero (7464587177007785408) -->
     <!-- no translation found for number_of_items_selected:one (142482526010824029) -->
     <!-- no translation found for number_of_items_selected:other (1418352074806573570) -->
+    <!-- no translation found for wallpaper_accessibility_name (1655953108132967972) -->
+    <skip />
+    <!-- no translation found for announce_selection (8338254712932127413) -->
+    <skip />
     <!-- no translation found for wallpaper_delete (8095005658756613921) -->
     <skip />
     <!-- no translation found for pick_image (1272073934062909527) -->
diff --git a/res/values-bg/strings.xml b/res/values-bg/strings.xml
index 7bf6617..2f53fa3 100644
--- a/res/values-bg/strings.xml
+++ b/res/values-bg/strings.xml
@@ -29,6 +29,8 @@
     <item quantity="one" msgid="142482526010824029">"Избрахте %1$d"</item>
     <item quantity="other" msgid="1418352074806573570">"Избрахте %1$d"</item>
   </plurals>
+    <string name="wallpaper_accessibility_name" msgid="1655953108132967972">"Тапет %1$d от %2$d"</string>
+    <string name="announce_selection" msgid="8338254712932127413">"Избрахте <xliff:g id="LABEL">%1$s</xliff:g>"</string>
     <string name="wallpaper_delete" msgid="8095005658756613921">"Изтриване"</string>
     <string name="pick_image" msgid="1272073934062909527">"Избиране на изображение"</string>
     <string name="pick_wallpaper" msgid="8179698221502010609">"Тапети"</string>
diff --git a/res/values-ca/strings.xml b/res/values-ca/strings.xml
index acafcc4..3400482 100644
--- a/res/values-ca/strings.xml
+++ b/res/values-ca/strings.xml
@@ -29,6 +29,8 @@
     <item quantity="one" msgid="142482526010824029">"Seleccionats: %1$d"</item>
     <item quantity="other" msgid="1418352074806573570">"Seleccionats: %1$d"</item>
   </plurals>
+    <string name="wallpaper_accessibility_name" msgid="1655953108132967972">"Fons de pantalla %1$d de %2$d"</string>
+    <string name="announce_selection" msgid="8338254712932127413">"S\'ha seleccionat <xliff:g id="LABEL">%1$s</xliff:g>"</string>
     <string name="wallpaper_delete" msgid="8095005658756613921">"Suprimeix"</string>
     <string name="pick_image" msgid="1272073934062909527">"Selecciona una imatge"</string>
     <string name="pick_wallpaper" msgid="8179698221502010609">"Fons de pantalla"</string>
diff --git a/res/values-cs/strings.xml b/res/values-cs/strings.xml
index c4e920f..1061e79 100644
--- a/res/values-cs/strings.xml
+++ b/res/values-cs/strings.xml
@@ -29,6 +29,8 @@
     <item quantity="one" msgid="142482526010824029">"Vybráno: %1$d"</item>
     <item quantity="other" msgid="1418352074806573570">"Vybráno: %1$d"</item>
   </plurals>
+    <string name="wallpaper_accessibility_name" msgid="1655953108132967972">"Tapeta %1$d z %2$d"</string>
+    <string name="announce_selection" msgid="8338254712932127413">"Vybrána položka <xliff:g id="LABEL">%1$s</xliff:g>"</string>
     <string name="wallpaper_delete" msgid="8095005658756613921">"Smazat"</string>
     <string name="pick_image" msgid="1272073934062909527">"Vybrat obrázek"</string>
     <string name="pick_wallpaper" msgid="8179698221502010609">"Tapety"</string>
diff --git a/res/values-da/strings.xml b/res/values-da/strings.xml
index 446dc51..5db246e 100644
--- a/res/values-da/strings.xml
+++ b/res/values-da/strings.xml
@@ -29,6 +29,8 @@
     <item quantity="one" msgid="142482526010824029">"%1$d er valgt"</item>
     <item quantity="other" msgid="1418352074806573570">"%1$d er valgt"</item>
   </plurals>
+    <string name="wallpaper_accessibility_name" msgid="1655953108132967972">"Baggrund %1$d af %2$d"</string>
+    <string name="announce_selection" msgid="8338254712932127413">"<xliff:g id="LABEL">%1$s</xliff:g> blev valgt"</string>
     <string name="wallpaper_delete" msgid="8095005658756613921">"Slet"</string>
     <string name="pick_image" msgid="1272073934062909527">"Vælg billede"</string>
     <string name="pick_wallpaper" msgid="8179698221502010609">"Baggrunde"</string>
diff --git a/res/values-de/strings.xml b/res/values-de/strings.xml
index 1ebf08a..7a5e7e6 100644
--- a/res/values-de/strings.xml
+++ b/res/values-de/strings.xml
@@ -29,6 +29,8 @@
     <item quantity="one" msgid="142482526010824029">"%1$d ausgewählt"</item>
     <item quantity="other" msgid="1418352074806573570">"%1$d ausgewählt"</item>
   </plurals>
+    <string name="wallpaper_accessibility_name" msgid="1655953108132967972">"Hintergrund %1$d von %2$d"</string>
+    <string name="announce_selection" msgid="8338254712932127413">"<xliff:g id="LABEL">%1$s</xliff:g> ausgewählt"</string>
     <string name="wallpaper_delete" msgid="8095005658756613921">"Entfernen"</string>
     <string name="pick_image" msgid="1272073934062909527">"Bild auswählen"</string>
     <string name="pick_wallpaper" msgid="8179698221502010609">"Hintergründe"</string>
diff --git a/res/values-el/strings.xml b/res/values-el/strings.xml
index 57ade2b..74322e0 100644
--- a/res/values-el/strings.xml
+++ b/res/values-el/strings.xml
@@ -29,6 +29,8 @@
     <item quantity="one" msgid="142482526010824029">"%1$d επιλεγμένα"</item>
     <item quantity="other" msgid="1418352074806573570">"%1$d επιλεγμένα"</item>
   </plurals>
+    <string name="wallpaper_accessibility_name" msgid="1655953108132967972">"Ταπετσαρία %1$d από %2$d"</string>
+    <string name="announce_selection" msgid="8338254712932127413">"Επιλέχθηκε το <xliff:g id="LABEL">%1$s</xliff:g>"</string>
     <string name="wallpaper_delete" msgid="8095005658756613921">"Διαγραφή"</string>
     <string name="pick_image" msgid="1272073934062909527">"Επιλογή εικόνας"</string>
     <string name="pick_wallpaper" msgid="8179698221502010609">"Ταπετσαρίες"</string>
diff --git a/res/values-en-rGB/strings.xml b/res/values-en-rGB/strings.xml
index ae7d44d..316585e 100644
--- a/res/values-en-rGB/strings.xml
+++ b/res/values-en-rGB/strings.xml
@@ -29,6 +29,8 @@
     <item quantity="one" msgid="142482526010824029">"%1$d selected"</item>
     <item quantity="other" msgid="1418352074806573570">"%1$d selected"</item>
   </plurals>
+    <string name="wallpaper_accessibility_name" msgid="1655953108132967972">"Wallpaper %1$d of %2$d"</string>
+    <string name="announce_selection" msgid="8338254712932127413">"Selected <xliff:g id="LABEL">%1$s</xliff:g>"</string>
     <string name="wallpaper_delete" msgid="8095005658756613921">"Delete"</string>
     <string name="pick_image" msgid="1272073934062909527">"Pick image"</string>
     <string name="pick_wallpaper" msgid="8179698221502010609">"Wallpapers"</string>
diff --git a/res/values-en-rIN/strings.xml b/res/values-en-rIN/strings.xml
index ae7d44d..316585e 100644
--- a/res/values-en-rIN/strings.xml
+++ b/res/values-en-rIN/strings.xml
@@ -29,6 +29,8 @@
     <item quantity="one" msgid="142482526010824029">"%1$d selected"</item>
     <item quantity="other" msgid="1418352074806573570">"%1$d selected"</item>
   </plurals>
+    <string name="wallpaper_accessibility_name" msgid="1655953108132967972">"Wallpaper %1$d of %2$d"</string>
+    <string name="announce_selection" msgid="8338254712932127413">"Selected <xliff:g id="LABEL">%1$s</xliff:g>"</string>
     <string name="wallpaper_delete" msgid="8095005658756613921">"Delete"</string>
     <string name="pick_image" msgid="1272073934062909527">"Pick image"</string>
     <string name="pick_wallpaper" msgid="8179698221502010609">"Wallpapers"</string>
diff --git a/res/values-es-rUS/strings.xml b/res/values-es-rUS/strings.xml
index 3c245da..c9a44a9 100644
--- a/res/values-es-rUS/strings.xml
+++ b/res/values-es-rUS/strings.xml
@@ -29,6 +29,8 @@
     <item quantity="one" msgid="142482526010824029">"%1$d seleccionado"</item>
     <item quantity="other" msgid="1418352074806573570">"%1$d seleccionados"</item>
   </plurals>
+    <string name="wallpaper_accessibility_name" msgid="1655953108132967972">"Fondo de pantalla %1$d de %2$d"</string>
+    <string name="announce_selection" msgid="8338254712932127413">"<xliff:g id="LABEL">%1$s</xliff:g> seleccionado"</string>
     <string name="wallpaper_delete" msgid="8095005658756613921">"Eliminar"</string>
     <string name="pick_image" msgid="1272073934062909527">"Elegir imagen"</string>
     <string name="pick_wallpaper" msgid="8179698221502010609">"Fondos de pantalla"</string>
diff --git a/res/values-es/strings.xml b/res/values-es/strings.xml
index 1a0529d..193e096 100644
--- a/res/values-es/strings.xml
+++ b/res/values-es/strings.xml
@@ -29,6 +29,8 @@
     <item quantity="one" msgid="142482526010824029">"Seleccionados: %1$d"</item>
     <item quantity="other" msgid="1418352074806573570">"Seleccionados: %1$d"</item>
   </plurals>
+    <string name="wallpaper_accessibility_name" msgid="1655953108132967972">"Fondo de pantalla %1$d de %2$d"</string>
+    <string name="announce_selection" msgid="8338254712932127413">"<xliff:g id="LABEL">%1$s</xliff:g> seleccionado"</string>
     <string name="wallpaper_delete" msgid="8095005658756613921">"Eliminar"</string>
     <string name="pick_image" msgid="1272073934062909527">"Seleccionar imagen"</string>
     <string name="pick_wallpaper" msgid="8179698221502010609">"Fondos de pantalla"</string>
diff --git a/res/values-et-rEE/strings.xml b/res/values-et-rEE/strings.xml
index cc95f47..f026b08 100644
--- a/res/values-et-rEE/strings.xml
+++ b/res/values-et-rEE/strings.xml
@@ -29,6 +29,8 @@
     <item quantity="one" msgid="142482526010824029">"Valitud on %1$d"</item>
     <item quantity="other" msgid="1418352074806573570">"Valitud on %1$d"</item>
   </plurals>
+    <string name="wallpaper_accessibility_name" msgid="1655953108132967972">"%1$d/%2$d taustapildist"</string>
+    <string name="announce_selection" msgid="8338254712932127413">"Valitud on <xliff:g id="LABEL">%1$s</xliff:g>"</string>
     <string name="wallpaper_delete" msgid="8095005658756613921">"Kustuta"</string>
     <string name="pick_image" msgid="1272073934062909527">"Vali kujutis"</string>
     <string name="pick_wallpaper" msgid="8179698221502010609">"Taustapildid"</string>
diff --git a/res/values-fa/strings.xml b/res/values-fa/strings.xml
index e3787cf..3a0d0b8 100644
--- a/res/values-fa/strings.xml
+++ b/res/values-fa/strings.xml
@@ -29,6 +29,8 @@
     <item quantity="one" msgid="142482526010824029">"%1$d انتخاب شد"</item>
     <item quantity="other" msgid="1418352074806573570">"%1$d انتخاب شد"</item>
   </plurals>
+    <string name="wallpaper_accessibility_name" msgid="1655953108132967972">"کاغذ دیواری %1$d از %2$d"</string>
+    <string name="announce_selection" msgid="8338254712932127413">"<xliff:g id="LABEL">%1$s</xliff:g> انتخاب شده"</string>
     <string name="wallpaper_delete" msgid="8095005658756613921">"حذف"</string>
     <string name="pick_image" msgid="1272073934062909527">"انتخاب تصویر"</string>
     <string name="pick_wallpaper" msgid="8179698221502010609">"کاغذدیواری‌ها"</string>
diff --git a/res/values-fi/strings.xml b/res/values-fi/strings.xml
index 9b33c6b..d327250 100644
--- a/res/values-fi/strings.xml
+++ b/res/values-fi/strings.xml
@@ -29,6 +29,8 @@
     <item quantity="one" msgid="142482526010824029">"%1$d valittu"</item>
     <item quantity="other" msgid="1418352074806573570">"%1$d valittu"</item>
   </plurals>
+    <string name="wallpaper_accessibility_name" msgid="1655953108132967972">"Taustakuva %1$d/%2$d"</string>
+    <string name="announce_selection" msgid="8338254712932127413">"Valittu: <xliff:g id="LABEL">%1$s</xliff:g>"</string>
     <string name="wallpaper_delete" msgid="8095005658756613921">"Poista"</string>
     <string name="pick_image" msgid="1272073934062909527">"Valitse kuva"</string>
     <string name="pick_wallpaper" msgid="8179698221502010609">"Taustakuvat"</string>
diff --git a/res/values-fr-rCA/strings.xml b/res/values-fr-rCA/strings.xml
index e1f6644..9d8dbeb 100644
--- a/res/values-fr-rCA/strings.xml
+++ b/res/values-fr-rCA/strings.xml
@@ -29,6 +29,8 @@
     <item quantity="one" msgid="142482526010824029">"%1$d sélectionné"</item>
     <item quantity="other" msgid="1418352074806573570">"%1$d sélectionné(s)"</item>
   </plurals>
+    <string name="wallpaper_accessibility_name" msgid="1655953108132967972">"Fond d\'écran %1$d sur %2$d"</string>
+    <string name="announce_selection" msgid="8338254712932127413">"Sélection : <xliff:g id="LABEL">%1$s</xliff:g>"</string>
     <string name="wallpaper_delete" msgid="8095005658756613921">"Supprimer"</string>
     <string name="pick_image" msgid="1272073934062909527">"Sélectionner une image"</string>
     <string name="pick_wallpaper" msgid="8179698221502010609">"Fonds d\'écran"</string>
diff --git a/res/values-fr/strings.xml b/res/values-fr/strings.xml
index 5c918a5..b1b0a79 100644
--- a/res/values-fr/strings.xml
+++ b/res/values-fr/strings.xml
@@ -29,6 +29,8 @@
     <item quantity="one" msgid="142482526010824029">"%1$d fond d\'écran sélectionné"</item>
     <item quantity="other" msgid="1418352074806573570">"%1$d fonds d\'écran sélectionnés"</item>
   </plurals>
+    <string name="wallpaper_accessibility_name" msgid="1655953108132967972">"Fond d\'écran %1$d sur %2$d"</string>
+    <string name="announce_selection" msgid="8338254712932127413">"<xliff:g id="LABEL">%1$s</xliff:g> est sélectionné."</string>
     <string name="wallpaper_delete" msgid="8095005658756613921">"Supprimer"</string>
     <string name="pick_image" msgid="1272073934062909527">"Sélectionner une image"</string>
     <string name="pick_wallpaper" msgid="8179698221502010609">"Fonds d\'écran"</string>
diff --git a/res/values-hi/strings.xml b/res/values-hi/strings.xml
index ed094d2..eddd75c 100644
--- a/res/values-hi/strings.xml
+++ b/res/values-hi/strings.xml
@@ -29,6 +29,8 @@
     <item quantity="one" msgid="142482526010824029">"%1$d चयनित"</item>
     <item quantity="other" msgid="1418352074806573570">"%1$d चयनित"</item>
   </plurals>
+    <string name="wallpaper_accessibility_name" msgid="1655953108132967972">"वॉलपेपर %2$d में से %1$d"</string>
+    <string name="announce_selection" msgid="8338254712932127413">"चयनित <xliff:g id="LABEL">%1$s</xliff:g>"</string>
     <string name="wallpaper_delete" msgid="8095005658756613921">"हटाएं"</string>
     <string name="pick_image" msgid="1272073934062909527">"चित्र चुनें"</string>
     <string name="pick_wallpaper" msgid="8179698221502010609">"वॉलपेपर"</string>
diff --git a/res/values-hr/strings.xml b/res/values-hr/strings.xml
index b53713b..783946d 100644
--- a/res/values-hr/strings.xml
+++ b/res/values-hr/strings.xml
@@ -29,6 +29,8 @@
     <item quantity="one" msgid="142482526010824029">"Odabrano: %1$d"</item>
     <item quantity="other" msgid="1418352074806573570">"Odabrano: %1$d"</item>
   </plurals>
+    <string name="wallpaper_accessibility_name" msgid="1655953108132967972">"%1$d. pozadinska slika od %2$d"</string>
+    <string name="announce_selection" msgid="8338254712932127413">"Odabrana je stavka <xliff:g id="LABEL">%1$s</xliff:g>"</string>
     <string name="wallpaper_delete" msgid="8095005658756613921">"Izbriši"</string>
     <string name="pick_image" msgid="1272073934062909527">"Odaberi sliku"</string>
     <string name="pick_wallpaper" msgid="8179698221502010609">"Pozadinske slike"</string>
diff --git a/res/values-hu/strings.xml b/res/values-hu/strings.xml
index e596cd9..8876652 100644
--- a/res/values-hu/strings.xml
+++ b/res/values-hu/strings.xml
@@ -29,6 +29,8 @@
     <item quantity="one" msgid="142482526010824029">"%1$d kiválasztva"</item>
     <item quantity="other" msgid="1418352074806573570">"%1$d kiválasztva"</item>
   </plurals>
+    <string name="wallpaper_accessibility_name" msgid="1655953108132967972">"%2$d/%1$d. háttérkép"</string>
+    <string name="announce_selection" msgid="8338254712932127413">"<xliff:g id="LABEL">%1$s</xliff:g> kiválasztva"</string>
     <string name="wallpaper_delete" msgid="8095005658756613921">"Törlés"</string>
     <string name="pick_image" msgid="1272073934062909527">"Kép választása"</string>
     <string name="pick_wallpaper" msgid="8179698221502010609">"Háttérképek"</string>
diff --git a/res/values-hy-rAM/strings.xml b/res/values-hy-rAM/strings.xml
index 2abea5c..ab7388a 100644
--- a/res/values-hy-rAM/strings.xml
+++ b/res/values-hy-rAM/strings.xml
@@ -29,6 +29,8 @@
     <item quantity="one" msgid="142482526010824029">"%1$d ընտրված"</item>
     <item quantity="other" msgid="1418352074806573570">"%1$d ընտրված"</item>
   </plurals>
+    <string name="wallpaper_accessibility_name" msgid="1655953108132967972">"%1$d պաստառ՝ %2$d-ից"</string>
+    <string name="announce_selection" msgid="8338254712932127413">"Ընտրված է <xliff:g id="LABEL">%1$s</xliff:g>"</string>
     <string name="wallpaper_delete" msgid="8095005658756613921">"Ջնջել"</string>
     <string name="pick_image" msgid="1272073934062909527">"Ընտրել պատկեր"</string>
     <string name="pick_wallpaper" msgid="8179698221502010609">"Պաստառներ"</string>
diff --git a/res/values-in/strings.xml b/res/values-in/strings.xml
index c4a67af..e1e93f7 100644
--- a/res/values-in/strings.xml
+++ b/res/values-in/strings.xml
@@ -29,6 +29,8 @@
     <item quantity="one" msgid="142482526010824029">"%1$d dipilih"</item>
     <item quantity="other" msgid="1418352074806573570">"%1$d dipilih"</item>
   </plurals>
+    <string name="wallpaper_accessibility_name" msgid="1655953108132967972">"Wallpaper %1$d dari %2$d"</string>
+    <string name="announce_selection" msgid="8338254712932127413">"<xliff:g id="LABEL">%1$s</xliff:g> terpilih"</string>
     <string name="wallpaper_delete" msgid="8095005658756613921">"Hapus"</string>
     <string name="pick_image" msgid="1272073934062909527">"Pilih gambar"</string>
     <string name="pick_wallpaper" msgid="8179698221502010609">"Wallpaper"</string>
diff --git a/res/values-it/strings.xml b/res/values-it/strings.xml
index bcbec0a..d5ada8f 100644
--- a/res/values-it/strings.xml
+++ b/res/values-it/strings.xml
@@ -29,6 +29,8 @@
     <item quantity="one" msgid="142482526010824029">"%1$d selezionato"</item>
     <item quantity="other" msgid="1418352074806573570">"%1$d selezionati"</item>
   </plurals>
+    <string name="wallpaper_accessibility_name" msgid="1655953108132967972">"Sfondo %1$d di %2$d"</string>
+    <string name="announce_selection" msgid="8338254712932127413">"Elemento selezionato: <xliff:g id="LABEL">%1$s</xliff:g>"</string>
     <string name="wallpaper_delete" msgid="8095005658756613921">"Elimina"</string>
     <string name="pick_image" msgid="1272073934062909527">"Scegli immagine"</string>
     <string name="pick_wallpaper" msgid="8179698221502010609">"Sfondi"</string>
diff --git a/res/values-iw/strings.xml b/res/values-iw/strings.xml
index 9d4d9d2..603dbb5 100644
--- a/res/values-iw/strings.xml
+++ b/res/values-iw/strings.xml
@@ -29,6 +29,8 @@
     <item quantity="one" msgid="142482526010824029">"%1$d נבחרו"</item>
     <item quantity="other" msgid="1418352074806573570">"%1$d נבחרו"</item>
   </plurals>
+    <string name="wallpaper_accessibility_name" msgid="1655953108132967972">"טפט %1$d מתוך %2$d"</string>
+    <string name="announce_selection" msgid="8338254712932127413">"בחרת <xliff:g id="LABEL">%1$s</xliff:g>"</string>
     <string name="wallpaper_delete" msgid="8095005658756613921">"מחק"</string>
     <string name="pick_image" msgid="1272073934062909527">"בחר תמונה"</string>
     <string name="pick_wallpaper" msgid="8179698221502010609">"טפטים"</string>
diff --git a/res/values-ja/strings.xml b/res/values-ja/strings.xml
index 9fcdfc1..6e39c54 100644
--- a/res/values-ja/strings.xml
+++ b/res/values-ja/strings.xml
@@ -29,6 +29,8 @@
     <item quantity="one" msgid="142482526010824029">"%1$d件選択済み"</item>
     <item quantity="other" msgid="1418352074806573570">"%1$d件選択済み"</item>
   </plurals>
+    <string name="wallpaper_accessibility_name" msgid="1655953108132967972">"壁紙: %1$d/%2$d"</string>
+    <string name="announce_selection" msgid="8338254712932127413">"選択: <xliff:g id="LABEL">%1$s</xliff:g>"</string>
     <string name="wallpaper_delete" msgid="8095005658756613921">"削除"</string>
     <string name="pick_image" msgid="1272073934062909527">"画像を選択"</string>
     <string name="pick_wallpaper" msgid="8179698221502010609">"壁紙"</string>
diff --git a/res/values-ka-rGE/strings.xml b/res/values-ka-rGE/strings.xml
index b735405..a2e3374 100644
--- a/res/values-ka-rGE/strings.xml
+++ b/res/values-ka-rGE/strings.xml
@@ -29,6 +29,8 @@
     <item quantity="one" msgid="142482526010824029">"არჩეულია %1$d"</item>
     <item quantity="other" msgid="1418352074806573570">"არჩეულია %1$d"</item>
   </plurals>
+    <string name="wallpaper_accessibility_name" msgid="1655953108132967972">"ფონი %1$d %2$d-დან"</string>
+    <string name="announce_selection" msgid="8338254712932127413">"არჩეულია <xliff:g id="LABEL">%1$s</xliff:g>"</string>
     <string name="wallpaper_delete" msgid="8095005658756613921">"წაშლა"</string>
     <string name="pick_image" msgid="1272073934062909527">"სურათის ამორჩევა"</string>
     <string name="pick_wallpaper" msgid="8179698221502010609">"ფონები"</string>
diff --git a/res/values-km-rKH/strings.xml b/res/values-km-rKH/strings.xml
index fffc486..977b2dd 100644
--- a/res/values-km-rKH/strings.xml
+++ b/res/values-km-rKH/strings.xml
@@ -29,6 +29,8 @@
     <item quantity="one" msgid="142482526010824029">"បាន​ជ្រើស %1$d"</item>
     <item quantity="other" msgid="1418352074806573570">"បាន​ជ្រើស %1$d"</item>
   </plurals>
+    <string name="wallpaper_accessibility_name" msgid="1655953108132967972">"ផ្ទាំង​រូបភាព %1$d នៃ %2$d"</string>
+    <string name="announce_selection" msgid="8338254712932127413">"​បាន​ជ្រើស <xliff:g id="LABEL">%1$s</xliff:g>"</string>
     <string name="wallpaper_delete" msgid="8095005658756613921">"លុប"</string>
     <string name="pick_image" msgid="1272073934062909527">"ជ្រើស​យក​រូបភាព"</string>
     <string name="pick_wallpaper" msgid="8179698221502010609">"ផ្ទាំង​រូបភាព"</string>
diff --git a/res/values-ko/strings.xml b/res/values-ko/strings.xml
index e6c144a..31c2d69 100644
--- a/res/values-ko/strings.xml
+++ b/res/values-ko/strings.xml
@@ -29,6 +29,8 @@
     <item quantity="one" msgid="142482526010824029">"%1$d개 선택됨"</item>
     <item quantity="other" msgid="1418352074806573570">"%1$d개 선택됨"</item>
   </plurals>
+    <string name="wallpaper_accessibility_name" msgid="1655953108132967972">"배경화면 %1$d/%2$d"</string>
+    <string name="announce_selection" msgid="8338254712932127413">"<xliff:g id="LABEL">%1$s</xliff:g> 선택함"</string>
     <string name="wallpaper_delete" msgid="8095005658756613921">"삭제"</string>
     <string name="pick_image" msgid="1272073934062909527">"이미지 선택"</string>
     <string name="pick_wallpaper" msgid="8179698221502010609">"배경화면"</string>
diff --git a/res/values-lo-rLA/strings.xml b/res/values-lo-rLA/strings.xml
index 0549790..e3a95dd 100644
--- a/res/values-lo-rLA/strings.xml
+++ b/res/values-lo-rLA/strings.xml
@@ -29,6 +29,8 @@
     <item quantity="one" msgid="142482526010824029">"ເລືອກ %1$d ລາຍການແລ້ວ"</item>
     <item quantity="other" msgid="1418352074806573570">"ເລືອກ %1$d ລາຍການແລ້ວ"</item>
   </plurals>
+    <string name="wallpaper_accessibility_name" msgid="1655953108132967972">"ຮູບພືື້ນຫຼັງ %1$d ໃນ %2$d"</string>
+    <string name="announce_selection" msgid="8338254712932127413">"ເລືອກແລ້ວ <xliff:g id="LABEL">%1$s</xliff:g> ອັນ"</string>
     <string name="wallpaper_delete" msgid="8095005658756613921">"ລຶບ"</string>
     <string name="pick_image" msgid="1272073934062909527">"ເລືອກຮູບ"</string>
     <string name="pick_wallpaper" msgid="8179698221502010609">"ພາບພື້ນຫຼັງ"</string>
diff --git a/res/values-lt/strings.xml b/res/values-lt/strings.xml
index 3df47c9..80d4412 100644
--- a/res/values-lt/strings.xml
+++ b/res/values-lt/strings.xml
@@ -29,6 +29,8 @@
     <item quantity="one" msgid="142482526010824029">"Pasirinkta: %1$d"</item>
     <item quantity="other" msgid="1418352074806573570">"Pasirinkta: %1$d"</item>
   </plurals>
+    <string name="wallpaper_accessibility_name" msgid="1655953108132967972">"%1$d iš %2$d ekrano fonų"</string>
+    <string name="announce_selection" msgid="8338254712932127413">"Pasirinkta: <xliff:g id="LABEL">%1$s</xliff:g>"</string>
     <string name="wallpaper_delete" msgid="8095005658756613921">"Ištrinti"</string>
     <string name="pick_image" msgid="1272073934062909527">"Pasirinkti vaizdą"</string>
     <string name="pick_wallpaper" msgid="8179698221502010609">"Ekrano fonai"</string>
diff --git a/res/values-lv/strings.xml b/res/values-lv/strings.xml
index e622b5f..b70f5dc 100644
--- a/res/values-lv/strings.xml
+++ b/res/values-lv/strings.xml
@@ -29,6 +29,8 @@
     <item quantity="one" msgid="142482526010824029">"Atlasīti: %1$d"</item>
     <item quantity="other" msgid="1418352074806573570">"Atlasīti: %1$d"</item>
   </plurals>
+    <string name="wallpaper_accessibility_name" msgid="1655953108132967972">"%1$d. fona tapete no %2$d"</string>
+    <string name="announce_selection" msgid="8338254712932127413">"Atlasīts: <xliff:g id="LABEL">%1$s</xliff:g>"</string>
     <string name="wallpaper_delete" msgid="8095005658756613921">"Dzēst"</string>
     <string name="pick_image" msgid="1272073934062909527">"Izvēlēties attēlu"</string>
     <string name="pick_wallpaper" msgid="8179698221502010609">"Fona tapetes"</string>
diff --git a/res/values-mn-rMN/strings.xml b/res/values-mn-rMN/strings.xml
index 260f6aa..7cf7a9c 100644
--- a/res/values-mn-rMN/strings.xml
+++ b/res/values-mn-rMN/strings.xml
@@ -29,6 +29,8 @@
     <item quantity="one" msgid="142482526010824029">"%1$d сонгогдсон"</item>
     <item quantity="other" msgid="1418352074806573570">"%1$d сонгогдсон"</item>
   </plurals>
+    <string name="wallpaper_accessibility_name" msgid="1655953108132967972">"%2$d ханын цаасны %1$d нь"</string>
+    <string name="announce_selection" msgid="8338254712932127413">"<xliff:g id="LABEL">%1$s</xliff:g> сонгогдсон"</string>
     <string name="wallpaper_delete" msgid="8095005658756613921">"Устгах"</string>
     <string name="pick_image" msgid="1272073934062909527">"Зураг сонгох"</string>
     <string name="pick_wallpaper" msgid="8179698221502010609">"Ханын зураг"</string>
diff --git a/res/values-ms-rMY/strings.xml b/res/values-ms-rMY/strings.xml
index 597354e..4ee3545 100644
--- a/res/values-ms-rMY/strings.xml
+++ b/res/values-ms-rMY/strings.xml
@@ -29,6 +29,8 @@
     <item quantity="one" msgid="142482526010824029">"%1$d dipilih"</item>
     <item quantity="other" msgid="1418352074806573570">"%1$d dipilih"</item>
   </plurals>
+    <string name="wallpaper_accessibility_name" msgid="1655953108132967972">"Kertas dinding %1$d daripada %2$d"</string>
+    <string name="announce_selection" msgid="8338254712932127413">"Memilih <xliff:g id="LABEL">%1$s</xliff:g>"</string>
     <string name="wallpaper_delete" msgid="8095005658756613921">"Padam"</string>
     <string name="pick_image" msgid="1272073934062909527">"Pilih imej"</string>
     <string name="pick_wallpaper" msgid="8179698221502010609">"Kertas dinding"</string>
diff --git a/res/values-nb/strings.xml b/res/values-nb/strings.xml
index 99667af..ce50754 100644
--- a/res/values-nb/strings.xml
+++ b/res/values-nb/strings.xml
@@ -29,6 +29,8 @@
     <item quantity="one" msgid="142482526010824029">"%1$d valgt"</item>
     <item quantity="other" msgid="1418352074806573570">"%1$d valgt"</item>
   </plurals>
+    <string name="wallpaper_accessibility_name" msgid="1655953108132967972">"Bakgrunn %1$d of %2$d"</string>
+    <string name="announce_selection" msgid="8338254712932127413">"Valgt <xliff:g id="LABEL">%1$s</xliff:g>"</string>
     <string name="wallpaper_delete" msgid="8095005658756613921">"Slett"</string>
     <string name="pick_image" msgid="1272073934062909527">"Velg bilde"</string>
     <string name="pick_wallpaper" msgid="8179698221502010609">"Bakgrunner"</string>
diff --git a/res/values-nl/strings.xml b/res/values-nl/strings.xml
index 93d3330..e2a2a07 100644
--- a/res/values-nl/strings.xml
+++ b/res/values-nl/strings.xml
@@ -29,6 +29,8 @@
     <item quantity="one" msgid="142482526010824029">"%1$d geselecteerd"</item>
     <item quantity="other" msgid="1418352074806573570">"%1$d geselecteerd"</item>
   </plurals>
+    <string name="wallpaper_accessibility_name" msgid="1655953108132967972">"Achtergrond %1$d van %2$d"</string>
+    <string name="announce_selection" msgid="8338254712932127413">"<xliff:g id="LABEL">%1$s</xliff:g> is geselecteerd"</string>
     <string name="wallpaper_delete" msgid="8095005658756613921">"Verwijderen"</string>
     <string name="pick_image" msgid="1272073934062909527">"Afbeelding kiezen"</string>
     <string name="pick_wallpaper" msgid="8179698221502010609">"Achtergronden"</string>
diff --git a/res/values-pl/strings.xml b/res/values-pl/strings.xml
index fe6a4f2..b629f3d 100644
--- a/res/values-pl/strings.xml
+++ b/res/values-pl/strings.xml
@@ -29,6 +29,8 @@
     <item quantity="one" msgid="142482526010824029">"Wybrane: %1$d"</item>
     <item quantity="other" msgid="1418352074806573570">"Wybrane: %1$d"</item>
   </plurals>
+    <string name="wallpaper_accessibility_name" msgid="1655953108132967972">"Tapeta %1$d z %2$d"</string>
+    <string name="announce_selection" msgid="8338254712932127413">"Wybrano <xliff:g id="LABEL">%1$s</xliff:g>"</string>
     <string name="wallpaper_delete" msgid="8095005658756613921">"Usuń"</string>
     <string name="pick_image" msgid="1272073934062909527">"Wybierz obraz"</string>
     <string name="pick_wallpaper" msgid="8179698221502010609">"Tapety"</string>
diff --git a/res/values-pt-rPT/strings.xml b/res/values-pt-rPT/strings.xml
index 35bf77c..1ef3982 100644
--- a/res/values-pt-rPT/strings.xml
+++ b/res/values-pt-rPT/strings.xml
@@ -29,6 +29,8 @@
     <item quantity="one" msgid="142482526010824029">"%1$d selecionado(s)"</item>
     <item quantity="other" msgid="1418352074806573570">"%1$d selecionado(s)"</item>
   </plurals>
+    <string name="wallpaper_accessibility_name" msgid="1655953108132967972">"Imagem de fundo %1$d de %2$d"</string>
+    <string name="announce_selection" msgid="8338254712932127413">"<xliff:g id="LABEL">%1$s</xliff:g> selecionado"</string>
     <string name="wallpaper_delete" msgid="8095005658756613921">"Eliminar"</string>
     <string name="pick_image" msgid="1272073934062909527">"Escolher imagem"</string>
     <string name="pick_wallpaper" msgid="8179698221502010609">"Imagens de fundo"</string>
diff --git a/res/values-pt/strings.xml b/res/values-pt/strings.xml
index 78f6ecd..4d40388 100644
--- a/res/values-pt/strings.xml
+++ b/res/values-pt/strings.xml
@@ -29,6 +29,8 @@
     <item quantity="one" msgid="142482526010824029">"%1$d selecionados"</item>
     <item quantity="other" msgid="1418352074806573570">"%1$d selecionados"</item>
   </plurals>
+    <string name="wallpaper_accessibility_name" msgid="1655953108132967972">"Plano de fundo %1$d de %2$d"</string>
+    <string name="announce_selection" msgid="8338254712932127413">"<xliff:g id="LABEL">%1$s</xliff:g> selecionado"</string>
     <string name="wallpaper_delete" msgid="8095005658756613921">"Excluir"</string>
     <string name="pick_image" msgid="1272073934062909527">"Escolher imagem"</string>
     <string name="pick_wallpaper" msgid="8179698221502010609">"Planos de fundo"</string>
diff --git a/res/values-rm/strings.xml b/res/values-rm/strings.xml
index 1a88d4a..ddcf404 100644
--- a/res/values-rm/strings.xml
+++ b/res/values-rm/strings.xml
@@ -31,6 +31,10 @@
     <!-- no translation found for number_of_items_selected:zero (7464587177007785408) -->
     <!-- no translation found for number_of_items_selected:one (142482526010824029) -->
     <!-- no translation found for number_of_items_selected:other (1418352074806573570) -->
+    <!-- no translation found for wallpaper_accessibility_name (1655953108132967972) -->
+    <skip />
+    <!-- no translation found for announce_selection (8338254712932127413) -->
+    <skip />
     <!-- no translation found for wallpaper_delete (8095005658756613921) -->
     <skip />
     <!-- no translation found for pick_image (1272073934062909527) -->
diff --git a/res/values-ro/strings.xml b/res/values-ro/strings.xml
index fa4387c..78d9da4 100644
--- a/res/values-ro/strings.xml
+++ b/res/values-ro/strings.xml
@@ -29,6 +29,8 @@
     <item quantity="one" msgid="142482526010824029">"%1$d selectat"</item>
     <item quantity="other" msgid="1418352074806573570">"%1$d selectate"</item>
   </plurals>
+    <string name="wallpaper_accessibility_name" msgid="1655953108132967972">"Imaginea de fundal %1$d din %2$d"</string>
+    <string name="announce_selection" msgid="8338254712932127413">"S-a selectat <xliff:g id="LABEL">%1$s</xliff:g>"</string>
     <string name="wallpaper_delete" msgid="8095005658756613921">"Ștergeți"</string>
     <string name="pick_image" msgid="1272073934062909527">"Alegeți imaginea"</string>
     <string name="pick_wallpaper" msgid="8179698221502010609">"Imagini de fundal"</string>
diff --git a/res/values-ru/strings.xml b/res/values-ru/strings.xml
index 188a3a4..06fbd26 100644
--- a/res/values-ru/strings.xml
+++ b/res/values-ru/strings.xml
@@ -29,6 +29,8 @@
     <item quantity="one" msgid="142482526010824029">"Выбрано: %1$d"</item>
     <item quantity="other" msgid="1418352074806573570">"Выбрано: %1$d"</item>
   </plurals>
+    <string name="wallpaper_accessibility_name" msgid="1655953108132967972">"Обои %1$d из %2$d"</string>
+    <string name="announce_selection" msgid="8338254712932127413">"Выбран элемент \"<xliff:g id="LABEL">%1$s</xliff:g>\""</string>
     <string name="wallpaper_delete" msgid="8095005658756613921">"Удалить"</string>
     <string name="pick_image" msgid="1272073934062909527">"Выбрать изображение"</string>
     <string name="pick_wallpaper" msgid="8179698221502010609">"Обои"</string>
diff --git a/res/values-sk/strings.xml b/res/values-sk/strings.xml
index 8f4daf3..29de526 100644
--- a/res/values-sk/strings.xml
+++ b/res/values-sk/strings.xml
@@ -29,6 +29,8 @@
     <item quantity="one" msgid="142482526010824029">"Počet vybratých položiek: %1$d"</item>
     <item quantity="other" msgid="1418352074806573570">"Počet vybratých položiek: %1$d"</item>
   </plurals>
+    <string name="wallpaper_accessibility_name" msgid="1655953108132967972">"Tapeta %1$d z %2$d"</string>
+    <string name="announce_selection" msgid="8338254712932127413">"Vybratá položka <xliff:g id="LABEL">%1$s</xliff:g>"</string>
     <string name="wallpaper_delete" msgid="8095005658756613921">"Odstrániť"</string>
     <string name="pick_image" msgid="1272073934062909527">"Vybrať obrázok"</string>
     <string name="pick_wallpaper" msgid="8179698221502010609">"Tapety"</string>
diff --git a/res/values-sl/strings.xml b/res/values-sl/strings.xml
index 41716a0..021eca8 100644
--- a/res/values-sl/strings.xml
+++ b/res/values-sl/strings.xml
@@ -29,6 +29,8 @@
     <item quantity="one" msgid="142482526010824029">"Št. izbranih: %1$d"</item>
     <item quantity="other" msgid="1418352074806573570">"Št. izbranih: %1$d"</item>
   </plurals>
+    <string name="wallpaper_accessibility_name" msgid="1655953108132967972">"Ozadje %1$d od %2$d"</string>
+    <string name="announce_selection" msgid="8338254712932127413">"Izbrano: <xliff:g id="LABEL">%1$s</xliff:g>"</string>
     <string name="wallpaper_delete" msgid="8095005658756613921">"Izbriši"</string>
     <string name="pick_image" msgid="1272073934062909527">"Izberi sliko"</string>
     <string name="pick_wallpaper" msgid="8179698221502010609">"Ozadja"</string>
diff --git a/res/values-sr/strings.xml b/res/values-sr/strings.xml
index ae4be35..06d80ef 100644
--- a/res/values-sr/strings.xml
+++ b/res/values-sr/strings.xml
@@ -29,6 +29,8 @@
     <item quantity="one" msgid="142482526010824029">"Изабрана je %1$d"</item>
     <item quantity="other" msgid="1418352074806573570">"Изабранo je %1$d"</item>
   </plurals>
+    <string name="wallpaper_accessibility_name" msgid="1655953108132967972">"Позадина %1$d од %2$d"</string>
+    <string name="announce_selection" msgid="8338254712932127413">"Изабрано је <xliff:g id="LABEL">%1$s</xliff:g>"</string>
     <string name="wallpaper_delete" msgid="8095005658756613921">"Избриши"</string>
     <string name="pick_image" msgid="1272073934062909527">"Изабери слику"</string>
     <string name="pick_wallpaper" msgid="8179698221502010609">"Позадине"</string>
diff --git a/res/values-sv/strings.xml b/res/values-sv/strings.xml
index fbbf6b6..bf75200 100644
--- a/res/values-sv/strings.xml
+++ b/res/values-sv/strings.xml
@@ -29,6 +29,8 @@
     <item quantity="one" msgid="142482526010824029">"%1$d har valts"</item>
     <item quantity="other" msgid="1418352074806573570">"%1$d har valts"</item>
   </plurals>
+    <string name="wallpaper_accessibility_name" msgid="1655953108132967972">"Bakgrund %1$d av %2$d"</string>
+    <string name="announce_selection" msgid="8338254712932127413">"<xliff:g id="LABEL">%1$s</xliff:g> har valts"</string>
     <string name="wallpaper_delete" msgid="8095005658756613921">"Ta bort"</string>
     <string name="pick_image" msgid="1272073934062909527">"Välj bild"</string>
     <string name="pick_wallpaper" msgid="8179698221502010609">"Bakgrunder"</string>
diff --git a/res/values-sw/strings.xml b/res/values-sw/strings.xml
index 0a0a4b9..606a80d 100644
--- a/res/values-sw/strings.xml
+++ b/res/values-sw/strings.xml
@@ -29,6 +29,8 @@
     <item quantity="one" msgid="142482526010824029">"%1$d zimechaguliwa"</item>
     <item quantity="other" msgid="1418352074806573570">"%1$d zimechaguliwa"</item>
   </plurals>
+    <string name="wallpaper_accessibility_name" msgid="1655953108132967972">"Mandhari %1$d ya %2$d"</string>
+    <string name="announce_selection" msgid="8338254712932127413">"<xliff:g id="LABEL">%1$s</xliff:g> iliyochaguliwa"</string>
     <string name="wallpaper_delete" msgid="8095005658756613921">"Futa"</string>
     <string name="pick_image" msgid="1272073934062909527">"Chukua picha"</string>
     <string name="pick_wallpaper" msgid="8179698221502010609">"Mandhari"</string>
diff --git a/res/values-sw720dp/styles.xml b/res/values-sw720dp/styles.xml
index 7269e8d..9738a12 100644
--- a/res/values-sw720dp/styles.xml
+++ b/res/values-sw720dp/styles.xml
@@ -53,6 +53,8 @@
 <!-- Workspace -->
     <style name="Theme" parent="android:Theme.Holo.Wallpaper.NoTitleBar">
         <item name="android:windowActionModeOverlay">true</item>
+        <item name="android:windowTranslucentStatus">true</item>
+        <item name="android:windowTranslucentNavigation">true</item>
     </style>
 
     <style name="TabIndicator.AppsCustomize">
diff --git a/res/values-th/strings.xml b/res/values-th/strings.xml
index 4b013b0..68118a7 100644
--- a/res/values-th/strings.xml
+++ b/res/values-th/strings.xml
@@ -29,6 +29,8 @@
     <item quantity="one" msgid="142482526010824029">"เลือกไว้ %1$d"</item>
     <item quantity="other" msgid="1418352074806573570">"เลือกไว้ %1$d"</item>
   </plurals>
+    <string name="wallpaper_accessibility_name" msgid="1655953108132967972">"วอลเปเปอร์ %1$d จาก %2$d"</string>
+    <string name="announce_selection" msgid="8338254712932127413">"เลือก <xliff:g id="LABEL">%1$s</xliff:g> แล้ว"</string>
     <string name="wallpaper_delete" msgid="8095005658756613921">"ลบ"</string>
     <string name="pick_image" msgid="1272073934062909527">"เลือกภาพ"</string>
     <string name="pick_wallpaper" msgid="8179698221502010609">"วอลเปเปอร์"</string>
diff --git a/res/values-tl/strings.xml b/res/values-tl/strings.xml
index 984cd7d..56801b4 100644
--- a/res/values-tl/strings.xml
+++ b/res/values-tl/strings.xml
@@ -29,6 +29,8 @@
     <item quantity="one" msgid="142482526010824029">"%1$d ang napili"</item>
     <item quantity="other" msgid="1418352074806573570">"%1$d ang napili"</item>
   </plurals>
+    <string name="wallpaper_accessibility_name" msgid="1655953108132967972">"Wallpaper %1$d ng %2$d"</string>
+    <string name="announce_selection" msgid="8338254712932127413">"Napili ang <xliff:g id="LABEL">%1$s</xliff:g>"</string>
     <string name="wallpaper_delete" msgid="8095005658756613921">"Tanggalin"</string>
     <string name="pick_image" msgid="1272073934062909527">"Pumili ng larawan"</string>
     <string name="pick_wallpaper" msgid="8179698221502010609">"Mga Wallpaper"</string>
diff --git a/res/values-tr/strings.xml b/res/values-tr/strings.xml
index 60b8bda..dbbdee2 100644
--- a/res/values-tr/strings.xml
+++ b/res/values-tr/strings.xml
@@ -29,6 +29,8 @@
     <item quantity="one" msgid="142482526010824029">"%1$d tane seçildi"</item>
     <item quantity="other" msgid="1418352074806573570">"%1$d tane seçildi"</item>
   </plurals>
+    <string name="wallpaper_accessibility_name" msgid="1655953108132967972">"Duvar kağıdı %1$d / %2$d"</string>
+    <string name="announce_selection" msgid="8338254712932127413">"<xliff:g id="LABEL">%1$s</xliff:g> seçildi"</string>
     <string name="wallpaper_delete" msgid="8095005658756613921">"Sil"</string>
     <string name="pick_image" msgid="1272073934062909527">"Resim seç"</string>
     <string name="pick_wallpaper" msgid="8179698221502010609">"Duvar Kağıtları"</string>
diff --git a/res/values-uk/strings.xml b/res/values-uk/strings.xml
index e1fc491..e0f3211 100644
--- a/res/values-uk/strings.xml
+++ b/res/values-uk/strings.xml
@@ -29,6 +29,8 @@
     <item quantity="one" msgid="142482526010824029">"Вибрано %1$d"</item>
     <item quantity="other" msgid="1418352074806573570">"Вибрано %1$d"</item>
   </plurals>
+    <string name="wallpaper_accessibility_name" msgid="1655953108132967972">"Фоновий малюнок %1$d з %2$d"</string>
+    <string name="announce_selection" msgid="8338254712932127413">"Вибрано <xliff:g id="LABEL">%1$s</xliff:g>"</string>
     <string name="wallpaper_delete" msgid="8095005658756613921">"Видалити"</string>
     <string name="pick_image" msgid="1272073934062909527">"Вибрати зображення"</string>
     <string name="pick_wallpaper" msgid="8179698221502010609">"Фонові малюнки"</string>
diff --git a/res/values-vi/strings.xml b/res/values-vi/strings.xml
index 6be69fa..3b081d0 100644
--- a/res/values-vi/strings.xml
+++ b/res/values-vi/strings.xml
@@ -29,6 +29,8 @@
     <item quantity="one" msgid="142482526010824029">"Đã chọn %1$d"</item>
     <item quantity="other" msgid="1418352074806573570">"Đã chọn %1$d"</item>
   </plurals>
+    <string name="wallpaper_accessibility_name" msgid="1655953108132967972">"Hình nền %1$d / %2$d"</string>
+    <string name="announce_selection" msgid="8338254712932127413">"<xliff:g id="LABEL">%1$s</xliff:g> được chọn"</string>
     <string name="wallpaper_delete" msgid="8095005658756613921">"Xóa"</string>
     <string name="pick_image" msgid="1272073934062909527">"Chọn hình ảnh"</string>
     <string name="pick_wallpaper" msgid="8179698221502010609">"Hình nền"</string>
diff --git a/res/values-zh-rCN/strings.xml b/res/values-zh-rCN/strings.xml
index 163fc90..43a57c4 100644
--- a/res/values-zh-rCN/strings.xml
+++ b/res/values-zh-rCN/strings.xml
@@ -29,6 +29,8 @@
     <item quantity="one" msgid="142482526010824029">"已选择%1$d项"</item>
     <item quantity="other" msgid="1418352074806573570">"已选择%1$d项"</item>
   </plurals>
+    <string name="wallpaper_accessibility_name" msgid="1655953108132967972">"第%1$d张壁纸,共%2$d张"</string>
+    <string name="announce_selection" msgid="8338254712932127413">"已选择<xliff:g id="LABEL">%1$s</xliff:g>"</string>
     <string name="wallpaper_delete" msgid="8095005658756613921">"删除"</string>
     <string name="pick_image" msgid="1272073934062909527">"选择图片"</string>
     <string name="pick_wallpaper" msgid="8179698221502010609">"壁纸"</string>
@@ -103,7 +105,7 @@
     <string name="workspace_cling_move_item" msgid="528201129978005352">"触摸并按住背景,即可管理壁纸、小部件和设置。"</string>
     <string name="all_apps_cling_title" msgid="34929250753095858">"选择一些应用"</string>
     <string name="all_apps_cling_add_item" msgid="400866858451850784">"要将应用添加到主屏幕,请触摸并按住该应用。"</string>
-    <string name="folder_cling_title" msgid="3894908818693254164">"文件夹如下显示:"</string>
+    <string name="folder_cling_title" msgid="3894908818693254164">"这是一个文件夹"</string>
     <string name="folder_cling_create_folder" msgid="6158215559475836131">"要创建一个类似的文件夹,请触摸并按住某个应用,然后将其移至另一个应用上。"</string>
     <string name="cling_dismiss" msgid="8962359497601507581">"确定"</string>
     <string name="folder_opened" msgid="94695026776264709">"文件夹已打开,大小为<xliff:g id="WIDTH">%1$d</xliff:g>×<xliff:g id="HEIGHT">%2$d</xliff:g>"</string>
diff --git a/res/values-zh-rHK/strings.xml b/res/values-zh-rHK/strings.xml
index 007dd17..eb3def4 100644
--- a/res/values-zh-rHK/strings.xml
+++ b/res/values-zh-rHK/strings.xml
@@ -29,6 +29,8 @@
     <item quantity="one" msgid="142482526010824029">"已選取 %1$d 個"</item>
     <item quantity="other" msgid="1418352074806573570">"已選取 %1$d 個"</item>
   </plurals>
+    <string name="wallpaper_accessibility_name" msgid="1655953108132967972">"第 %1$d 張桌布,共 %2$d 張"</string>
+    <string name="announce_selection" msgid="8338254712932127413">"已選取「<xliff:g id="LABEL">%1$s</xliff:g>」"</string>
     <string name="wallpaper_delete" msgid="8095005658756613921">"刪除"</string>
     <string name="pick_image" msgid="1272073934062909527">"選擇圖片"</string>
     <string name="pick_wallpaper" msgid="8179698221502010609">"桌布"</string>
diff --git a/res/values-zh-rTW/strings.xml b/res/values-zh-rTW/strings.xml
index 899479f..a68f163 100644
--- a/res/values-zh-rTW/strings.xml
+++ b/res/values-zh-rTW/strings.xml
@@ -29,6 +29,8 @@
     <item quantity="one" msgid="142482526010824029">"已選取 %1$d 個項目"</item>
     <item quantity="other" msgid="1418352074806573570">"已選取 %1$d 個項目"</item>
   </plurals>
+    <string name="wallpaper_accessibility_name" msgid="1655953108132967972">"第 %1$d 張桌布,共 %2$d 張"</string>
+    <string name="announce_selection" msgid="8338254712932127413">"已選取<xliff:g id="LABEL">%1$s</xliff:g>"</string>
     <string name="wallpaper_delete" msgid="8095005658756613921">"刪除"</string>
     <string name="pick_image" msgid="1272073934062909527">"選擇圖片"</string>
     <string name="pick_wallpaper" msgid="8179698221502010609">"桌布"</string>
diff --git a/res/values-zu/strings.xml b/res/values-zu/strings.xml
index 1a711a8..da790e6 100644
--- a/res/values-zu/strings.xml
+++ b/res/values-zu/strings.xml
@@ -29,6 +29,8 @@
     <item quantity="one" msgid="142482526010824029">"%1$d khethiwe"</item>
     <item quantity="other" msgid="1418352074806573570">"%1$d khethiwe"</item>
   </plurals>
+    <string name="wallpaper_accessibility_name" msgid="1655953108132967972">"Isithombe sangemuva se-%1$d of %2$d"</string>
+    <string name="announce_selection" msgid="8338254712932127413">"I-<xliff:g id="LABEL">%1$s</xliff:g> ekhethiwe"</string>
     <string name="wallpaper_delete" msgid="8095005658756613921">"Susa"</string>
     <string name="pick_image" msgid="1272073934062909527">"Thatha isithombe"</string>
     <string name="pick_wallpaper" msgid="8179698221502010609">"Izithombe zangemuva"</string>
diff --git a/res/values/config.xml b/res/values/config.xml
index 0766d76..4978281 100644
--- a/res/values/config.xml
+++ b/res/values/config.xml
@@ -14,6 +14,8 @@
     <!-- The alpha of the AppsCustomize bg in spring loaded mode -->
     <integer name="config_appsCustomizeSpringLoadedBgAlpha">65</integer>
     <integer name="config_workspaceUnshrinkTime">300</integer>
+    <integer name="config_overviewTransitionTime">250</integer>
+
     <!-- Out of 100, the percent to shrink the workspace during spring loaded mode. -->
     <integer name="config_workspaceSpringLoadShrinkPercentage">80</integer>
     <!-- Out of 100, the percent to shrink the workspace during overview mode. -->
diff --git a/src/com/android/launcher3/BubbleTextView.java b/src/com/android/launcher3/BubbleTextView.java
index 287bb50..8dab943 100644
--- a/src/com/android/launcher3/BubbleTextView.java
+++ b/src/com/android/launcher3/BubbleTextView.java
@@ -109,9 +109,8 @@
         LauncherAppState app = LauncherAppState.getInstance();
         DeviceProfile grid = app.getDynamicGrid().getDeviceProfile();
 
-        setCompoundDrawablesWithIntrinsicBounds(null,
-                new FastBitmapDrawable(b),
-                null, null);
+        setCompoundDrawables(null,
+                Utilities.createIconDrawable(b), null, null);
         setCompoundDrawablePadding((int) ((grid.folderIconSizePx - grid.iconSizePx) / 2f));
         setText(info.title);
         setTag(info);
diff --git a/src/com/android/launcher3/CropView.java b/src/com/android/launcher3/CropView.java
index c8b974d..9224e3b 100644
--- a/src/com/android/launcher3/CropView.java
+++ b/src/com/android/launcher3/CropView.java
@@ -17,9 +17,11 @@
 package com.android.launcher3;
 
 import android.content.Context;
+import android.graphics.Matrix;
 import android.graphics.Point;
 import android.graphics.RectF;
 import android.util.AttributeSet;
+import android.util.FloatMath;
 import android.view.MotionEvent;
 import android.view.ScaleGestureDetector;
 import android.view.ScaleGestureDetector.OnScaleGestureListener;
@@ -36,10 +38,18 @@
     private long mTouchDownTime;
     private float mFirstX, mFirstY;
     private float mLastX, mLastY;
+    private float mCenterX, mCenterY;
     private float mMinScale;
     private boolean mTouchEnabled = true;
     private RectF mTempEdges = new RectF();
+    private float[] mTempPoint = new float[] { 0, 0 };
+    private float[] mTempCoef = new float[] { 0, 0 };
+    private float[] mTempAdjustment = new float[] { 0, 0 };
+    private float[] mTempImageDims = new float[] { 0, 0 };
+    private float[] mTempRendererCenter = new float[] { 0, 0 };
     TouchCallback mTouchCallback;
+    Matrix mRotateMatrix;
+    Matrix mInverseRotateMatrix;
 
     public interface TouchCallback {
         void onTouchDown();
@@ -54,17 +64,43 @@
     public CropView(Context context, AttributeSet attrs) {
         super(context, attrs);
         mScaleGestureDetector = new ScaleGestureDetector(context, this);
+        mRotateMatrix = new Matrix();
+        mInverseRotateMatrix = new Matrix();
+    }
+
+    private float[] getImageDims() {
+        final float imageWidth = mRenderer.source.getImageWidth();
+        final float imageHeight = mRenderer.source.getImageHeight();
+        float[] imageDims = mTempImageDims;
+        imageDims[0] = imageWidth;
+        imageDims[1] = imageHeight;
+        mRotateMatrix.mapPoints(imageDims);
+        imageDims[0] = Math.abs(imageDims[0]);
+        imageDims[1] = Math.abs(imageDims[1]);
+        return imageDims;
     }
 
     private void getEdgesHelper(RectF edgesOut) {
         final float width = getWidth();
         final float height = getHeight();
-        final float imageWidth = mRenderer.source.getImageWidth();
-        final float imageHeight = mRenderer.source.getImageHeight();
+        final float[] imageDims = getImageDims();
+        final float imageWidth = imageDims[0];
+        final float imageHeight = imageDims[1];
+
+        float initialCenterX = mRenderer.source.getImageWidth() / 2f;
+        float initialCenterY = mRenderer.source.getImageHeight() / 2f;
+
+        float[] rendererCenter = mTempRendererCenter;
+        rendererCenter[0] = mCenterX - initialCenterX;
+        rendererCenter[1] = mCenterY - initialCenterY;
+        mRotateMatrix.mapPoints(rendererCenter);
+        rendererCenter[0] += imageWidth / 2;
+        rendererCenter[1] += imageHeight / 2;
+
         final float scale = mRenderer.scale;
-        float centerX = (width / 2f - mRenderer.centerX + (imageWidth - width) / 2f)
+        float centerX = (width / 2f - rendererCenter[0] + (imageWidth - width) / 2f)
                 * scale + width / 2f;
-        float centerY = (height / 2f - mRenderer.centerY + (imageHeight - height) / 2f)
+        float centerY = (height / 2f - rendererCenter[1] + (imageHeight - height) / 2f)
                 * scale + height / 2f;
         float leftEdge = centerX - imageWidth / 2f * scale;
         float rightEdge = centerX + imageWidth / 2f * scale;
@@ -77,6 +113,10 @@
         edgesOut.bottom = bottomEdge;
     }
 
+    public int getImageRotation() {
+        return mRenderer.rotation;
+    }
+
     public RectF getCrop() {
         final RectF edges = mTempEdges;
         getEdgesHelper(edges);
@@ -96,6 +136,12 @@
 
     public void setTileSource(TileSource source, Runnable isReadyCallback) {
         super.setTileSource(source, isReadyCallback);
+        mCenterX = mRenderer.centerX;
+        mCenterY = mRenderer.centerY;
+        mRotateMatrix.reset();
+        mRotateMatrix.setRotate(mRenderer.rotation);
+        mInverseRotateMatrix.reset();
+        mInverseRotateMatrix.setRotate(-mRenderer.rotation);
         updateMinScale(getWidth(), getHeight(), source, true);
     }
 
@@ -115,8 +161,10 @@
                 mRenderer.scale = 1;
             }
             if (source != null) {
-                mMinScale = Math.max(w / (float) source.getImageWidth(),
-                        h / (float) source.getImageHeight());
+                final float[] imageDims = getImageDims();
+                final float imageWidth = imageDims[0];
+                final float imageHeight = imageDims[1];
+                mMinScale = Math.max(w / imageWidth, h / imageHeight);
                 mRenderer.scale = Math.max(mMinScale, mRenderer.scale);
             }
         }
@@ -154,7 +202,13 @@
         final RectF edges = mTempEdges;
         getEdgesHelper(edges);
         final float scale = mRenderer.scale;
-        mRenderer.centerX += Math.ceil(edges.left / scale);
+        mCenterX += Math.ceil(edges.left / scale);
+        updateCenter();
+    }
+
+    private void updateCenter() {
+        mRenderer.centerX = Math.round(mCenterX);
+        mRenderer.centerY = Math.round(mCenterY);
     }
 
     public void setTouchEnabled(boolean enabled) {
@@ -215,8 +269,13 @@
             mScaleGestureDetector.onTouchEvent(event);
             switch (action) {
                 case MotionEvent.ACTION_MOVE:
-                    mRenderer.centerX += (mLastX - x) / mRenderer.scale;
-                    mRenderer.centerY += (mLastY - y) / mRenderer.scale;
+                    float[] point = mTempPoint;
+                    point[0] = (mLastX - x) / mRenderer.scale;
+                    point[1] = (mLastY - y) / mRenderer.scale;
+                    mInverseRotateMatrix.mapPoints(point);
+                    mCenterX += point[0];
+                    mCenterY += point[1];
+                    updateCenter();
                     invalidate();
                     break;
             }
@@ -226,18 +285,32 @@
                 final RectF edges = mTempEdges;
                 getEdgesHelper(edges);
                 final float scale = mRenderer.scale;
+
+                float[] coef = mTempCoef;
+                coef[0] = 1;
+                coef[1] = 1;
+                mRotateMatrix.mapPoints(coef);
+                float[] adjustment = mTempAdjustment;
+                mTempAdjustment[0] = 0;
+                mTempAdjustment[1] = 0;
                 if (edges.left > 0) {
-                    mRenderer.centerX += Math.ceil(edges.left / scale);
-                }
-                if (edges.right < getWidth()) {
-                    mRenderer.centerX += (edges.right - getWidth()) / scale;
+                    adjustment[0] = edges.left / scale;
+                } else if (edges.right < getWidth()) {
+                    adjustment[0] = (edges.right - getWidth()) / scale;
                 }
                 if (edges.top > 0) {
-                    mRenderer.centerY += Math.ceil(edges.top / scale);
+                    adjustment[1] = FloatMath.ceil(edges.top / scale);
+                } else if (edges.bottom < getHeight()) {
+                    adjustment[1] = (edges.bottom - getHeight()) / scale;
                 }
-                if (edges.bottom < getHeight()) {
-                    mRenderer.centerY += (edges.bottom - getHeight()) / scale;
+                for (int dim = 0; dim <= 1; dim++) {
+                    if (coef[dim] > 0) adjustment[dim] = FloatMath.ceil(adjustment[dim]);
                 }
+
+                mInverseRotateMatrix.mapPoints(adjustment);
+                mCenterX += adjustment[0];
+                mCenterY += adjustment[1];
+                updateCenter();
             }
         }
 
diff --git a/src/com/android/launcher3/Folder.java b/src/com/android/launcher3/Folder.java
index 5231aac..69d9a3d 100644
--- a/src/com/android/launcher3/Folder.java
+++ b/src/com/android/launcher3/Folder.java
@@ -532,8 +532,8 @@
     protected boolean createAndAddShortcut(ShortcutInfo item) {
         final BubbleTextView textView =
             (BubbleTextView) mInflater.inflate(R.layout.application, this, false);
-        textView.setCompoundDrawablesWithIntrinsicBounds(null,
-                new FastBitmapDrawable(item.getIcon(mIconCache)), null, null);
+        textView.setCompoundDrawables(null,
+                Utilities.createIconDrawable(item.getIcon(mIconCache)), null, null);
         textView.setText(item.title);
         textView.setTag(item);
         textView.setTextColor(getResources().getColor(R.color.folder_items_text_color));
diff --git a/src/com/android/launcher3/FolderIcon.java b/src/com/android/launcher3/FolderIcon.java
index 7e1e350..cd1ff2c 100644
--- a/src/com/android/launcher3/FolderIcon.java
+++ b/src/com/android/launcher3/FolderIcon.java
@@ -98,6 +98,7 @@
     private int mPreviewOffsetY;
     private float mMaxPerspectiveShift;
     boolean mAnimating = false;
+    private Rect mOldBounds = new Rect();
 
     private PreviewItemDrawingParams mParams = new PreviewItemDrawingParams(0, 0, 0, 0);
     private PreviewItemDrawingParams mAnimParams = new PreviewItemDrawingParams(0, 0, 0, 0);
@@ -534,6 +535,7 @@
         Drawable d = params.drawable;
 
         if (d != null) {
+            mOldBounds.set(d.getBounds());
             d.setBounds(0, 0, mIntrinsicIconSize, mIntrinsicIconSize);
             d.setFilterBitmap(true);
             d.setColorFilter(Color.argb(params.overlayAlpha, 255, 255, 255),
@@ -541,6 +543,7 @@
             d.draw(canvas);
             d.clearColorFilter();
             d.setFilterBitmap(false);
+            d.setBounds(mOldBounds);
         }
         canvas.restore();
     }
diff --git a/src/com/android/launcher3/Hotseat.java b/src/com/android/launcher3/Hotseat.java
index 2aab64d..094e188 100644
--- a/src/com/android/launcher3/Hotseat.java
+++ b/src/com/android/launcher3/Hotseat.java
@@ -150,7 +150,7 @@
             TextView allAppsButton = (TextView)
                     inflater.inflate(R.layout.all_apps_button, mContent, false);
             Drawable d = context.getResources().getDrawable(R.drawable.all_apps_button_icon);
-            d.setBounds(0, 0, Utilities.sIconTextureWidth, Utilities.sIconTextureHeight);
+            Utilities.resizeIconDrawable(d);
             allAppsButton.setCompoundDrawables(null, d, null, null);
 
             allAppsButton.setContentDescription(context.getString(R.string.all_apps_button_label));
diff --git a/src/com/android/launcher3/IconCache.java b/src/com/android/launcher3/IconCache.java
index 1797826..543b8ee 100644
--- a/src/com/android/launcher3/IconCache.java
+++ b/src/com/android/launcher3/IconCache.java
@@ -29,6 +29,8 @@
 import android.graphics.drawable.Drawable;
 
 import java.util.HashMap;
+import java.util.Iterator;
+import java.util.Map.Entry;
 
 /**
  * Cache of application icons.  Icons can be made from any thread.
@@ -147,6 +149,21 @@
     }
 
     /**
+     * Empty out the cache that aren't of the correct grid size
+     */
+    public void flushInvalidIcons(DeviceProfile grid) {
+        synchronized (mCache) {
+            Iterator<Entry<ComponentName, CacheEntry>> it = mCache.entrySet().iterator();
+            while (it.hasNext()) {
+                final CacheEntry e = it.next().getValue();
+                if (e.icon.getWidth() != grid.iconSizePx || e.icon.getHeight() != grid.iconSizePx) {
+                    it.remove();
+                }
+            }
+        }
+    }
+
+    /**
      * Fill in "application" with the icon and label for "info."
      */
     public void getTitleAndIcon(AppInfo application, ResolveInfo info,
diff --git a/src/com/android/launcher3/InstallShortcutReceiver.java b/src/com/android/launcher3/InstallShortcutReceiver.java
index 821c15f..7df73b1 100644
--- a/src/com/android/launcher3/InstallShortcutReceiver.java
+++ b/src/com/android/launcher3/InstallShortcutReceiver.java
@@ -36,6 +36,9 @@
 import org.json.*;
 
 public class InstallShortcutReceiver extends BroadcastReceiver {
+    private static final String TAG = "InstallShortcutReceiver";
+    private static final boolean DBG = false;
+
     public static final String ACTION_INSTALL_SHORTCUT =
             "com.android.launcher.action.INSTALL_SHORTCUT";
 
@@ -94,10 +97,11 @@
                 }
                 json = json.endObject();
                 SharedPreferences.Editor editor = sharedPrefs.edit();
+                if (DBG) Log.d(TAG, "Adding to APPS_PENDING_INSTALL: " + json);
                 addToStringSet(sharedPrefs, editor, APPS_PENDING_INSTALL, json.toString());
                 editor.commit();
             } catch (org.json.JSONException e) {
-                Log.d("InstallShortcutReceiver", "Exception when adding shortcut: " + e);
+                Log.d(TAG, "Exception when adding shortcut: " + e);
             }
         }
     }
@@ -106,9 +110,15 @@
                                               ArrayList<String> packageNames) {
         synchronized(sLock) {
             Set<String> strings = sharedPrefs.getStringSet(APPS_PENDING_INSTALL, null);
+            if (DBG) {
+                Log.d(TAG, "APPS_PENDING_INSTALL: " + strings
+                        + ", removing packages: " + packageNames);
+            }
             if (strings != null) {
                 Set<String> newStrings = new HashSet<String>(strings);
-                for (String json : newStrings) {
+                Iterator<String> newStringsIter = newStrings.iterator();
+                while (newStringsIter.hasNext()) {
+                    String json = newStringsIter.next();
                     try {
                         JSONObject object = (JSONObject) new JSONTokener(json).nextValue();
                         Intent launchIntent = Intent.parseUri(object.getString(LAUNCH_INTENT_KEY), 0);
@@ -117,12 +127,12 @@
                             pn = launchIntent.getComponent().getPackageName();
                         }
                         if (packageNames.contains(pn)) {
-                            newStrings.remove(json);
+                            newStringsIter.remove();
                         }
                     } catch (org.json.JSONException e) {
-                        Log.d("InstallShortcutReceiver", "Exception reading shortcut to remove: " + e);
+                        Log.d(TAG, "Exception reading shortcut to remove: " + e);
                     } catch (java.net.URISyntaxException e) {
-                        Log.d("InstallShortcutReceiver", "Exception reading shortcut to remove: " + e);
+                        Log.d(TAG, "Exception reading shortcut to remove: " + e);
                     }
                 }
                 sharedPrefs.edit().putStringSet(APPS_PENDING_INSTALL,
@@ -135,6 +145,7 @@
             SharedPreferences sharedPrefs) {
         synchronized(sLock) {
             Set<String> strings = sharedPrefs.getStringSet(APPS_PENDING_INSTALL, null);
+            if (DBG) Log.d(TAG, "Getting and clearing APPS_PENDING_INSTALL: " + strings);
             if (strings == null) {
                 return new ArrayList<PendingInstallShortcutInfo>();
             }
@@ -167,11 +178,9 @@
                         new PendingInstallShortcutInfo(data, name, launchIntent);
                     infos.add(info);
                 } catch (org.json.JSONException e) {
-                    Log.d("InstallShortcutReceiver",
-                            "Exception reading shortcut to add: " + e);
+                    Log.d(TAG, "Exception reading shortcut to add: " + e);
                 } catch (java.net.URISyntaxException e) {
-                    Log.d("InstallShortcutReceiver",
-                            "Exception reading shortcut to add: " + e);
+                    Log.d(TAG, "Exception reading shortcut to add: " + e);
                 }
             }
             sharedPrefs.edit().putStringSet(APPS_PENDING_INSTALL, new HashSet<String>()).commit();
@@ -203,6 +212,8 @@
             return;
         }
 
+        if (DBG) Log.d(TAG, "Got INSTALL_SHORTCUT: " + data.toUri(0));
+
         Intent intent = data.getParcelableExtra(Intent.EXTRA_SHORTCUT_INTENT);
         if (intent == null) {
             return;
diff --git a/src/com/android/launcher3/Launcher.java b/src/com/android/launcher3/Launcher.java
index 278b13c..b0e4968 100644
--- a/src/com/android/launcher3/Launcher.java
+++ b/src/com/android/launcher3/Launcher.java
@@ -402,6 +402,7 @@
                 Context.MODE_PRIVATE);
         mModel = app.setLauncher(this);
         mIconCache = app.getIconCache();
+        mIconCache.flushInvalidIcons(grid);
         mDragController = new DragController(this);
         mInflater = getLayoutInflater();
 
@@ -736,6 +737,7 @@
                 Log.e(TAG, "Error: appWidgetId (EXTRA_APPWIDGET_ID) was not returned from the \\" +
                         "widget configuration activity.");
                 completeTwoStageWidgetDrop(RESULT_CANCELED, appWidgetId);
+                mWorkspace.stripEmptyScreens();
             } else {
                 completeTwoStageWidgetDrop(resultCode, appWidgetId);
             }
@@ -760,6 +762,8 @@
             } else {
                 delayExitSpringLoadedMode = completeAdd(args);
             }
+        } else if (resultCode == RESULT_CANCELED) {
+            mWorkspace.stripEmptyScreens();
         }
         mDragLayer.clearAnimatedView();
         // Exit spring loaded mode if necessary after cancelling the configuration of a widget
diff --git a/src/com/android/launcher3/LauncherAnimUtils.java b/src/com/android/launcher3/LauncherAnimUtils.java
index 01f72a7..5d4f9c6 100644
--- a/src/com/android/launcher3/LauncherAnimUtils.java
+++ b/src/com/android/launcher3/LauncherAnimUtils.java
@@ -30,6 +30,7 @@
     static HashSet<Animator> sAnimators = new HashSet<Animator>();
     static Animator.AnimatorListener sEndAnimListener = new Animator.AnimatorListener() {
         public void onAnimationStart(Animator animation) {
+            sAnimators.add(animation);
         }
 
         public void onAnimationRepeat(Animator animation) {
@@ -45,7 +46,6 @@
     };
 
     public static void cancelOnDestroyActivity(Animator a) {
-        sAnimators.add(a);
         a.addListener(sEndAnimListener);
     }
 
diff --git a/src/com/android/launcher3/PagedViewIcon.java b/src/com/android/launcher3/PagedViewIcon.java
index c6d5e49..8bfe42d 100644
--- a/src/com/android/launcher3/PagedViewIcon.java
+++ b/src/com/android/launcher3/PagedViewIcon.java
@@ -69,7 +69,8 @@
             PagedViewIcon.PressedCallback cb) {
         mIcon = info.iconBitmap;
         mPressedCallback = cb;
-        setCompoundDrawablesWithIntrinsicBounds(null, new FastBitmapDrawable(mIcon), null, null);
+        setCompoundDrawables(null, Utilities.createIconDrawable(mIcon),
+                null, null);
         setText(info.title);
         setTag(info);
     }
diff --git a/src/com/android/launcher3/SavedWallpaperImages.java b/src/com/android/launcher3/SavedWallpaperImages.java
index ee4888d..8d5b005 100644
--- a/src/com/android/launcher3/SavedWallpaperImages.java
+++ b/src/com/android/launcher3/SavedWallpaperImages.java
@@ -61,7 +61,9 @@
             String imageFilename = a.getSavedImages().getImageFilename(mDbId);
             File file = new File(a.getFilesDir(), imageFilename);
             CropView v = a.getCropView();
-            v.setTileSource(new BitmapRegionTileSource(a, file.getAbsolutePath(), 1024, 0), null);
+            int rotation = WallpaperCropActivity.getRotationFromExif(file.getAbsolutePath());
+            v.setTileSource(
+                    new BitmapRegionTileSource(a, file.getAbsolutePath(), 1024, rotation), null);
             v.moveToLeft();
             v.setTouchEnabled(false);
         }
diff --git a/src/com/android/launcher3/SearchDropTargetBar.java b/src/com/android/launcher3/SearchDropTargetBar.java
index e681aa1..435dbda 100644
--- a/src/com/android/launcher3/SearchDropTargetBar.java
+++ b/src/com/android/launcher3/SearchDropTargetBar.java
@@ -138,7 +138,8 @@
      * Shows and hides the search bar.
      */
     public void showSearchBar(boolean animated) {
-        if (!mIsSearchBarHidden) return;
+        boolean needToCancelOngoingAnimation = mQSBSearchBarAnim.isRunning() && !animated;
+        if (!mIsSearchBarHidden && !needToCancelOngoingAnimation) return;
         if (animated) {
             prepareStartAnimation(mQSBSearchBar);
             mQSBSearchBarAnim.reverse();
@@ -153,7 +154,8 @@
         mIsSearchBarHidden = false;
     }
     public void hideSearchBar(boolean animated) {
-        if (mIsSearchBarHidden) return;
+        boolean needToCancelOngoingAnimation = mQSBSearchBarAnim.isRunning() && !animated;
+        if (mIsSearchBarHidden && !needToCancelOngoingAnimation) return;
         if (animated) {
             prepareStartAnimation(mQSBSearchBar);
             mQSBSearchBarAnim.start();
diff --git a/src/com/android/launcher3/Utilities.java b/src/com/android/launcher3/Utilities.java
index 2cb9314..21c546d 100644
--- a/src/com/android/launcher3/Utilities.java
+++ b/src/com/android/launcher3/Utilities.java
@@ -66,6 +66,23 @@
     static int sColorIndex = 0;
 
     /**
+     * Returns a FastBitmapDrawable with the icon, accurately sized.
+     */
+    static Drawable createIconDrawable(Bitmap icon) {
+        FastBitmapDrawable d = new FastBitmapDrawable(icon);
+        d.setFilterBitmap(true);
+        resizeIconDrawable(d);
+        return d;
+    }
+
+    /**
+     * Resizes an icon drawable to the correct icon size.
+     */
+    static void resizeIconDrawable(Drawable icon) {
+        icon.setBounds(0, 0, sIconTextureWidth, sIconTextureHeight);
+    }
+
+    /**
      * Returns a bitmap suitable for the all apps view. Used to convert pre-ICS
      * icon bitmaps that are stored in the database (which were 74x74 pixels at hdpi size)
      * to the proper size (48dp)
diff --git a/src/com/android/launcher3/WallpaperCropActivity.java b/src/com/android/launcher3/WallpaperCropActivity.java
index fe09a55..30ec340 100644
--- a/src/com/android/launcher3/WallpaperCropActivity.java
+++ b/src/com/android/launcher3/WallpaperCropActivity.java
@@ -37,12 +37,14 @@
 import android.net.Uri;
 import android.os.AsyncTask;
 import android.os.Bundle;
+import android.util.FloatMath;
 import android.util.Log;
 import android.view.Display;
 import android.view.View;
 import android.view.WindowManager;
 
 import com.android.gallery3d.common.Utils;
+import com.android.gallery3d.exif.ExifInterface;
 import com.android.photos.BitmapRegionTileSource;
 
 import java.io.BufferedInputStream;
@@ -85,10 +87,17 @@
 
         mCropView = (CropView) findViewById(R.id.cropView);
 
-        Intent cropIntent = this.getIntent();
+        Intent cropIntent = getIntent();
         final Uri imageUri = cropIntent.getData();
 
-        mCropView.setTileSource(new BitmapRegionTileSource(this, imageUri, 1024, 0), null);
+        if (imageUri == null) {
+            Log.e(LOGTAG, "No URI passed in intent, exiting WallpaperCropActivity");
+            finish();
+            return;
+        }
+
+        int rotation = getRotationFromExif(this, imageUri);
+        mCropView.setTileSource(new BitmapRegionTileSource(this, imageUri, 1024, rotation), null);
         mCropView.setTouchEnabled(true);
         // Action bar
         // Show the custom action bar view
@@ -168,9 +177,47 @@
         return new Point(defaultWidth, defaultHeight);
     }
 
+    public static int getRotationFromExif(String path) {
+        return getRotationFromExifHelper(path, null, 0, null, null);
+    }
+
+    public static int getRotationFromExif(Context context, Uri uri) {
+        return getRotationFromExifHelper(null, null, 0, context, uri);
+    }
+
+    public static int getRotationFromExif(Resources res, int resId) {
+        return getRotationFromExifHelper(null, res, resId, null, null);
+    }
+
+    private static int getRotationFromExifHelper(
+            String path, Resources res, int resId, Context context, Uri uri) {
+        ExifInterface ei = new ExifInterface();
+        try {
+            if (path != null) {
+                ei.readExif(path);
+            } else if (uri != null) {
+                InputStream is = context.getContentResolver().openInputStream(uri);
+                BufferedInputStream bis = new BufferedInputStream(is);
+                ei.readExif(bis);
+            } else {
+                InputStream is = res.openRawResource(resId);
+                BufferedInputStream bis = new BufferedInputStream(is);
+                ei.readExif(bis);
+            }
+            Integer ori = ei.getTagIntValue(ExifInterface.TAG_ORIENTATION);
+            if (ori != null) {
+                return ExifInterface.getRotationForOrientationValue(ori.shortValue());
+            }
+        } catch (IOException e) {
+            Log.w(LOGTAG, "Getting exif data failed", e);
+        }
+        return 0;
+    }
+
     protected void setWallpaper(String filePath, final boolean finishActivityWhenDone) {
-        BitmapCropTask cropTask = new BitmapCropTask(this,
-                filePath, null, 0, 0, true, false, null);
+        int rotation = getRotationFromExif(filePath);
+        BitmapCropTask cropTask = new BitmapCropTask(
+                this, filePath, null, rotation, 0, 0, true, false, null);
         final Point bounds = cropTask.getImageBounds();
         Runnable onEndCrop = new Runnable() {
             public void run() {
@@ -190,6 +237,7 @@
             Resources res, int resId, final boolean finishActivityWhenDone) {
         // crop this image and scale it down to the default wallpaper size for
         // this device
+        int rotation = getRotationFromExif(res, resId);
         Point inSize = mCropView.getSourceDimensions();
         Point outSize = getDefaultWallpaperSize(getResources(),
                 getWindowManager());
@@ -207,8 +255,7 @@
             }
         };
         BitmapCropTask cropTask = new BitmapCropTask(this, res, resId,
-                crop, outSize.x, outSize.y,
-                true, false, onEndCrop);
+                crop, rotation, outSize.x, outSize.y, true, false, onEndCrop);
         cropTask.execute();
     }
 
@@ -220,8 +267,6 @@
     protected void cropImageAndSetWallpaper(Uri uri,
             OnBitmapCroppedHandler onBitmapCroppedHandler, final boolean finishActivityWhenDone) {
         // Get the crop
-        Point inSize = mCropView.getSourceDimensions();
-
         boolean ltr = mCropView.getLayoutDirection() == View.LAYOUT_DIRECTION_LTR;
 
         Point minDims = new Point();
@@ -260,12 +305,21 @@
         }
         // Get the crop
         RectF cropRect = mCropView.getCrop();
+        int cropRotation = mCropView.getImageRotation();
         float cropScale = mCropView.getWidth() / (float) cropRect.width();
 
+        Point inSize = mCropView.getSourceDimensions();
+        Matrix rotateMatrix = new Matrix();
+        rotateMatrix.setRotate(cropRotation);
+        float[] rotatedInSize = new float[] { inSize.x, inSize.y };
+        rotateMatrix.mapPoints(rotatedInSize);
+        rotatedInSize[0] = Math.abs(rotatedInSize[0]);
+        rotatedInSize[1] = Math.abs(rotatedInSize[1]);
+
         // ADJUST CROP WIDTH
         // Extend the crop all the way to the right, for parallax
         // (or all the way to the left, in RTL)
-        float extraSpace = ltr ? inSize.x - cropRect.right : cropRect.left;
+        float extraSpace = ltr ? rotatedInSize[0] - cropRect.right : cropRect.left;
         // Cap the amount of extra width
         float maxExtraSpace = defaultWallpaperWidth / cropScale - cropRect.width();
         extraSpace = Math.min(extraSpace, maxExtraSpace);
@@ -283,7 +337,7 @@
             float extraPortraitHeight =
                     portraitHeight / cropScale - cropRect.height();
             float expandHeight =
-                    Math.min(Math.min(inSize.y - cropRect.bottom, cropRect.top),
+                    Math.min(Math.min(rotatedInSize[1] - cropRect.bottom, cropRect.top),
                             extraPortraitHeight / 2);
             cropRect.top -= expandHeight;
             cropRect.bottom += expandHeight;
@@ -301,7 +355,7 @@
             }
         };
         BitmapCropTask cropTask = new BitmapCropTask(this, uri,
-                cropRect, outWidth, outHeight, true, false, onEndCrop);
+                cropRect, cropRotation, outWidth, outHeight, true, false, onEndCrop);
         if (onBitmapCroppedHandler != null) {
             cropTask.setOnBitmapCropped(onBitmapCroppedHandler);
         }
@@ -321,7 +375,7 @@
         InputStream mInStream;
         RectF mCropBounds = null;
         int mOutWidth, mOutHeight;
-        int mRotation = 0; // for now
+        int mRotation;
         String mOutputFormat = "jpg"; // for now
         boolean mSetWallpaper;
         boolean mSaveCroppedBitmap;
@@ -332,40 +386,45 @@
         boolean mNoCrop;
 
         public BitmapCropTask(Context c, String filePath,
-                RectF cropBounds, int outWidth, int outHeight,
+                RectF cropBounds, int rotation, int outWidth, int outHeight,
                 boolean setWallpaper, boolean saveCroppedBitmap, Runnable onEndRunnable) {
             mContext = c;
             mInFilePath = filePath;
-            init(cropBounds, outWidth, outHeight, setWallpaper, saveCroppedBitmap, onEndRunnable);
+            init(cropBounds, rotation,
+                    outWidth, outHeight, setWallpaper, saveCroppedBitmap, onEndRunnable);
         }
 
         public BitmapCropTask(byte[] imageBytes,
-                RectF cropBounds, int outWidth, int outHeight,
+                RectF cropBounds, int rotation, int outWidth, int outHeight,
                 boolean setWallpaper, boolean saveCroppedBitmap, Runnable onEndRunnable) {
             mInImageBytes = imageBytes;
-            init(cropBounds, outWidth, outHeight, setWallpaper, saveCroppedBitmap, onEndRunnable);
+            init(cropBounds, rotation,
+                    outWidth, outHeight, setWallpaper, saveCroppedBitmap, onEndRunnable);
         }
 
         public BitmapCropTask(Context c, Uri inUri,
-                RectF cropBounds, int outWidth, int outHeight,
+                RectF cropBounds, int rotation, int outWidth, int outHeight,
                 boolean setWallpaper, boolean saveCroppedBitmap, Runnable onEndRunnable) {
             mContext = c;
             mInUri = inUri;
-            init(cropBounds, outWidth, outHeight, setWallpaper, saveCroppedBitmap, onEndRunnable);
+            init(cropBounds, rotation,
+                    outWidth, outHeight, setWallpaper, saveCroppedBitmap, onEndRunnable);
         }
 
         public BitmapCropTask(Context c, Resources res, int inResId,
-                RectF cropBounds, int outWidth, int outHeight,
+                RectF cropBounds, int rotation, int outWidth, int outHeight,
                 boolean setWallpaper, boolean saveCroppedBitmap, Runnable onEndRunnable) {
             mContext = c;
             mInResId = inResId;
             mResources = res;
-            init(cropBounds, outWidth, outHeight, setWallpaper, saveCroppedBitmap, onEndRunnable);
+            init(cropBounds, rotation,
+                    outWidth, outHeight, setWallpaper, saveCroppedBitmap, onEndRunnable);
         }
 
-        private void init(RectF cropBounds, int outWidth, int outHeight,
+        private void init(RectF cropBounds, int rotation, int outWidth, int outHeight,
                 boolean setWallpaper, boolean saveCroppedBitmap, Runnable onEndRunnable) {
             mCropBounds = cropBounds;
+            mRotation = rotation;
             mOutWidth = outWidth;
             mOutHeight = outHeight;
             mSetWallpaper = setWallpaper;
@@ -452,6 +511,29 @@
             if (mInStream != null) {
                 // Find crop bounds (scaled to original image size)
                 Rect roundedTrueCrop = new Rect();
+                Matrix rotateMatrix = new Matrix();
+                Matrix inverseRotateMatrix = new Matrix();
+                if (mRotation > 0) {
+                    rotateMatrix.setRotate(mRotation);
+                    inverseRotateMatrix.setRotate(-mRotation);
+
+                    mCropBounds.roundOut(roundedTrueCrop);
+                    mCropBounds = new RectF(roundedTrueCrop);
+
+                    Point bounds = getImageBounds();
+
+                    float[] rotatedBounds = new float[] { bounds.x, bounds.y };
+                    rotateMatrix.mapPoints(rotatedBounds);
+                    rotatedBounds[0] = Math.abs(rotatedBounds[0]);
+                    rotatedBounds[1] = Math.abs(rotatedBounds[1]);
+
+                    mCropBounds.offset(-rotatedBounds[0]/2, -rotatedBounds[1]/2);
+                    inverseRotateMatrix.mapRect(mCropBounds);
+                    mCropBounds.offset(bounds.x/2, bounds.y/2);
+
+                    regenerateInputStream();
+                }
+
                 mCropBounds.roundOut(roundedTrueCrop);
 
                 if (roundedTrueCrop.width() <= 0 || roundedTrueCrop.height() <= 0) {
@@ -495,6 +577,12 @@
                         fullSize = BitmapFactory.decodeStream(mInStream, null, options);
                     }
                     if (fullSize != null) {
+                        mCropBounds.left /= scaleDownSampleSize;
+                        mCropBounds.top /= scaleDownSampleSize;
+                        mCropBounds.bottom /= scaleDownSampleSize;
+                        mCropBounds.right /= scaleDownSampleSize;
+                        mCropBounds.roundOut(roundedTrueCrop);
+
                         crop = Bitmap.createBitmap(fullSize, roundedTrueCrop.left,
                                 roundedTrueCrop.top, roundedTrueCrop.width(),
                                 roundedTrueCrop.height());
@@ -506,16 +594,40 @@
                     failure = true;
                     return false;
                 }
-                if (mOutWidth > 0 && mOutHeight > 0) {
-                    Matrix m = new Matrix();
-                    RectF cropRect = new RectF(0, 0, crop.getWidth(), crop.getHeight());
-                    if (mRotation > 0) {
-                        m.setRotate(mRotation);
-                        m.mapRect(cropRect);
+                if (mOutWidth > 0 && mOutHeight > 0 || mRotation > 0) {
+                    float[] dimsAfter = new float[] { crop.getWidth(), crop.getHeight() };
+                    rotateMatrix.mapPoints(dimsAfter);
+                    dimsAfter[0] = Math.abs(dimsAfter[0]);
+                    dimsAfter[1] = Math.abs(dimsAfter[1]);
+
+                    if (!(mOutWidth > 0 && mOutHeight > 0)) {
+                        mOutWidth = Math.round(dimsAfter[0]);
+                        mOutHeight = Math.round(dimsAfter[1]);
                     }
+
+                    RectF cropRect = new RectF(0, 0, dimsAfter[0], dimsAfter[1]);
                     RectF returnRect = new RectF(0, 0, mOutWidth, mOutHeight);
-                    m.setRectToRect(cropRect, returnRect, Matrix.ScaleToFit.FILL);
-                    m.preRotate(mRotation);
+
+                    Matrix m = new Matrix();
+                    if (mRotation == 0) {
+                        m.setRectToRect(cropRect, returnRect, Matrix.ScaleToFit.FILL);
+                    } else {
+                        Matrix m1 = new Matrix();
+                        m1.setTranslate(-crop.getWidth() / 2f, -crop.getHeight() / 2f);
+                        Matrix m2 = new Matrix();
+                        m2.setRotate(mRotation);
+                        Matrix m3 = new Matrix();
+                        m3.setTranslate(dimsAfter[0] / 2f, dimsAfter[1] / 2f);
+                        Matrix m4 = new Matrix();
+                        m4.setRectToRect(cropRect, returnRect, Matrix.ScaleToFit.FILL);
+
+                        Matrix c1 = new Matrix();
+                        c1.setConcat(m2, m1);
+                        Matrix c2 = new Matrix();
+                        c2.setConcat(m4, m3);
+                        m.setConcat(c2, c1);
+                    }
+
                     Bitmap tmp = Bitmap.createBitmap((int) returnRect.width(),
                             (int) returnRect.height(), Bitmap.Config.ARGB_8888);
                     if (tmp != null) {
@@ -525,14 +637,6 @@
                         c.drawBitmap(crop, m, p);
                         crop = tmp;
                     }
-                } else if (mRotation > 0) {
-                    Matrix m = new Matrix();
-                    m.setRotate(mRotation);
-                    Bitmap tmp = Bitmap.createBitmap(crop, 0, 0, crop.getWidth(),
-                            crop.getHeight(), m, true);
-                    if (tmp != null) {
-                        crop = tmp;
-                    }
                 }
 
                 if (mSaveCroppedBitmap) {
@@ -601,8 +705,7 @@
             final SharedPreferences sharedPrefs,
             WindowManager windowManager,
             final WallpaperManager wallpaperManager) {
-        final Point defaultWallpaperSize =
-                WallpaperCropActivity.getDefaultWallpaperSize(res, windowManager);
+        final Point defaultWallpaperSize = getDefaultWallpaperSize(res, windowManager);
 
         new Thread("suggestWallpaperDimension") {
             public void run() {
@@ -614,7 +717,6 @@
         }.start();
     }
 
-
     protected static RectF getMaxCropRect(
             int inWidth, int inHeight, int outWidth, int outHeight, boolean leftAligned) {
         RectF cropRect = new RectF();
diff --git a/src/com/android/launcher3/WallpaperPickerActivity.java b/src/com/android/launcher3/WallpaperPickerActivity.java
index d3e1c7b..e71a26b 100644
--- a/src/com/android/launcher3/WallpaperPickerActivity.java
+++ b/src/com/android/launcher3/WallpaperPickerActivity.java
@@ -16,6 +16,7 @@
 
 package com.android.launcher3;
 
+import android.animation.Animator;
 import android.animation.LayoutTransition;
 import android.app.ActionBar;
 import android.app.Activity;
@@ -30,6 +31,7 @@
 import android.database.DataSetObserver;
 import android.graphics.Bitmap;
 import android.graphics.BitmapFactory;
+import android.graphics.Matrix;
 import android.graphics.Point;
 import android.graphics.PorterDuff;
 import android.graphics.Rect;
@@ -53,6 +55,7 @@
 import android.view.ViewTreeObserver;
 import android.view.ViewTreeObserver.OnGlobalLayoutListener;
 import android.view.accessibility.AccessibilityEvent;
+import android.view.animation.AccelerateInterpolator;
 import android.view.animation.DecelerateInterpolator;
 import android.widget.BaseAdapter;
 import android.widget.FrameLayout;
@@ -61,11 +64,14 @@
 import android.widget.LinearLayout;
 import android.widget.ListAdapter;
 
+import com.android.gallery3d.exif.ExifInterface;
 import com.android.photos.BitmapRegionTileSource;
 
+import java.io.BufferedInputStream;
 import java.io.File;
 import java.io.FileOutputStream;
 import java.io.IOException;
+import java.io.InputStream;
 import java.util.ArrayList;
 
 public class WallpaperPickerActivity extends WallpaperCropActivity {
@@ -126,8 +132,8 @@
         @Override
         public void onClick(WallpaperPickerActivity a) {
             CropView v = a.getCropView();
-            v.setTileSource(new BitmapRegionTileSource(
-                    a, mUri, 1024, 0), null);
+            int rotation = WallpaperCropActivity.getRotationFromExif(a, mUri);
+            v.setTileSource(new BitmapRegionTileSource(a, mUri, 1024, rotation), null);
             v.setTouchEnabled(true);
         }
         @Override
@@ -136,8 +142,9 @@
             OnBitmapCroppedHandler h = new OnBitmapCroppedHandler() {
                 public void onBitmapCropped(byte[] imageBytes) {
                     Point thumbSize = getDefaultThumbnailSize(a.getResources());
-                    Bitmap thumb =
-                            createThumbnail(thumbSize, null, null, imageBytes, null, 0, true);
+                    // rotation is set to 0 since imageBytes has already been correctly rotated
+                    Bitmap thumb = createThumbnail(
+                            thumbSize, null, null, imageBytes, null, 0, 0, true);
                     a.getSavedImages().writeImage(thumb, imageBytes);
                 }
             };
@@ -165,8 +172,9 @@
         }
         @Override
         public void onClick(WallpaperPickerActivity a) {
+            int rotation = WallpaperCropActivity.getRotationFromExif(mResources, mResId);
             BitmapRegionTileSource source = new BitmapRegionTileSource(
-                    mResources, a, mResId, 1024, 0);
+                    mResources, a, mResId, 1024, rotation);
             CropView v = a.getCropView();
             v.setTileSource(source, null);
             Point wallpaperSize = WallpaperCropActivity.getDefaultWallpaperSize(
@@ -199,7 +207,6 @@
     // called by onCreate; this is subclassed to overwrite WallpaperCropActivity
     protected void init() {
         setContentView(R.layout.wallpaper_picker);
-        final WallpaperRootView root = (WallpaperRootView) findViewById(R.id.wallpaper_root);
 
         mCropView = (CropView) findViewById(R.id.cropView);
         mWallpaperStrip = findViewById(R.id.wallpaper_strip);
@@ -210,12 +217,21 @@
                 if (mAnim != null) {
                     mAnim.cancel();
                 }
-                if (mWallpaperStrip.getTranslationY() == 0) {
+                if (mWallpaperStrip.getAlpha() == 1f) {
                     mIgnoreNextTap = true;
                 }
                 mAnim = new LauncherViewPropertyAnimator(mWallpaperStrip);
-                mAnim.translationY(mWallpaperStrip.getHeight()).alpha(0f)
-                        .setInterpolator(new DecelerateInterpolator(0.75f));
+                mAnim.alpha(0f)
+                     .setDuration(150)
+                     .addListener(new Animator.AnimatorListener() {
+                         public void onAnimationStart(Animator animator) { }
+                         public void onAnimationEnd(Animator animator) {
+                             mWallpaperStrip.setVisibility(View.INVISIBLE);
+                         }
+                         public void onAnimationCancel(Animator animator) { }
+                         public void onAnimationRepeat(Animator animator) { }
+                     });
+                mAnim.setInterpolator(new AccelerateInterpolator(0.75f));
                 mAnim.start();
             }
             @Override
@@ -230,9 +246,11 @@
                     if (mAnim != null) {
                         mAnim.cancel();
                     }
+                    mWallpaperStrip.setVisibility(View.VISIBLE);
                     mAnim = new LauncherViewPropertyAnimator(mWallpaperStrip);
-                    mAnim.translationY(0f).alpha(1f)
-                            .setInterpolator(new DecelerateInterpolator(0.75f));
+                    mAnim.alpha(1f)
+                         .setDuration(150)
+                         .setInterpolator(new DecelerateInterpolator(0.75f));
                     mAnim.start();
                 }
             }
@@ -484,9 +502,9 @@
     protected void onStop() {
         super.onStop();
         mWallpaperStrip = findViewById(R.id.wallpaper_strip);
-        if (mWallpaperStrip.getTranslationY() > 0f) {
-            mWallpaperStrip.setTranslationY(0f);
+        if (mWallpaperStrip.getAlpha() < 1f) {
             mWallpaperStrip.setAlpha(1f);
+            mWallpaperStrip.setVisibility(View.VISIBLE);
         }
     }
 
@@ -522,7 +540,6 @@
     private void updateTileIndices() {
         LinearLayout masterWallpaperList = (LinearLayout) findViewById(R.id.master_wallpaper_list);
         final int childCount = masterWallpaperList.getChildCount();
-        ArrayList<WallpaperTileInfo> tiles = new ArrayList<WallpaperTileInfo>();
         final Resources res = getResources();
 
         // Do two passes; the first pass gets the total number of tiles
@@ -568,26 +585,35 @@
     }
 
     private static Bitmap createThumbnail(Point size, Context context, Uri uri, byte[] imageBytes,
-            Resources res, int resId, boolean leftAligned) {
+            Resources res, int resId, int rotation, boolean leftAligned) {
         int width = size.x;
         int height = size.y;
 
         BitmapCropTask cropTask;
         if (uri != null) {
-            cropTask = new BitmapCropTask(context, uri, null, width, height, false, true, null);
+            cropTask = new BitmapCropTask(
+                    context, uri, null, rotation, width, height, false, true, null);
         } else if (imageBytes != null) {
-            cropTask = new BitmapCropTask(imageBytes, null, width, height, false, true, null);
+            cropTask = new BitmapCropTask(
+                    imageBytes, null, rotation, width, height, false, true, null);
         }  else {
-            cropTask =
-                    new BitmapCropTask(context, res, resId, null, width, height, false, true, null);
+            cropTask = new BitmapCropTask(
+                    context, res, resId, null, rotation, width, height, false, true, null);
         }
         Point bounds = cropTask.getImageBounds();
         if (bounds == null || bounds.x == 0 || bounds.y == 0) {
             return null;
         }
 
+        Matrix rotateMatrix = new Matrix();
+        rotateMatrix.setRotate(rotation);
+        float[] rotatedBounds = new float[] { bounds.x, bounds.y };
+        rotateMatrix.mapPoints(rotatedBounds);
+        rotatedBounds[0] = Math.abs(rotatedBounds[0]);
+        rotatedBounds[1] = Math.abs(rotatedBounds[1]);
+
         RectF cropRect = WallpaperCropActivity.getMaxCropRect(
-                bounds.x, bounds.y, width, height, leftAligned);
+                (int) rotatedBounds[0], (int) rotatedBounds[1], width, height, leftAligned);
         cropTask.setCropBounds(cropRect);
 
         if (cropTask.cropBitmap()) {
@@ -607,7 +633,8 @@
         // Load the thumbnail
         ImageView image = (ImageView) pickedImageThumbnail.findViewById(R.id.wallpaper_image);
         Point defaultSize = getDefaultThumbnailSize(this.getResources());
-        Bitmap thumb = createThumbnail(defaultSize, this, uri, null, null, 0, false);
+        int rotation = WallpaperCropActivity.getRotationFromExif(this, uri);
+        Bitmap thumb = createThumbnail(defaultSize, this, uri, null, null, 0, rotation, false);
         if (thumb != null) {
             image.setImageBitmap(thumb);
             Drawable thumbDrawable = image.getDrawable();
@@ -620,6 +647,7 @@
         UriWallpaperInfo info = new UriWallpaperInfo(uri);
         pickedImageThumbnail.setTag(info);
         info.setView(pickedImageThumbnail);
+        addLongPressHandler(pickedImageThumbnail);
         updateTileIndices();
         pickedImageThumbnail.setOnClickListener(mThumbnailOnClickListener);
         mThumbnailOnClickListener.onClick(pickedImageThumbnail);
@@ -690,8 +718,11 @@
             thumb = BitmapFactory.decodeFile(defaultThumbFile.getAbsolutePath());
             defaultWallpaperExists = true;
         } else {
-            Point defaultThumbSize = getDefaultThumbnailSize(getResources());
-            thumb = createThumbnail(defaultThumbSize, this, null, null, sysRes, resId, false);
+            Resources res = getResources();
+            Point defaultThumbSize = getDefaultThumbnailSize(res);
+            int rotation = WallpaperCropActivity.getRotationFromExif(res, resId);
+            thumb = createThumbnail(
+                    defaultThumbSize, this, null, null, sysRes, resId, rotation, false);
             if (thumb != null) {
                 try {
                     defaultThumbFile.createNewFile();
diff --git a/src/com/android/launcher3/Workspace.java b/src/com/android/launcher3/Workspace.java
index 5205bef..f6416c8 100644
--- a/src/com/android/launcher3/Workspace.java
+++ b/src/com/android/launcher3/Workspace.java
@@ -1431,11 +1431,11 @@
         if (hasCustomContent()) {
             int index = mScreenOrder.indexOf(CUSTOM_CONTENT_SCREEN_ID);
 
-            int scrollDelta = getScrollForPage(index + 1) - getScrollX() +
-                    getLayoutTransitionOffsetForPage(index + 1);
-            translationX = scrollDelta;
-            progress = (1.0f * scrollDelta) /
-                    (getScrollForPage(index + 1) - getScrollForPage(index));
+            int scrollDelta = getScrollX() - getScrollForPage(index) -
+                    getLayoutTransitionOffsetForPage(index);
+            float scrollRange = getScrollForPage(index + 1) - getScrollForPage(index);
+            translationX = scrollRange - scrollDelta;
+            progress = (scrollRange - scrollDelta) / scrollRange;
 
             if (isLayoutRtl()) {
                 translationX = Math.min(0, translationX);
@@ -1446,6 +1446,12 @@
         }
 
         if (Float.compare(progress, mLastCustomContentScrollProgress) == 0) return;
+
+        CellLayout cc = mWorkspaceScreens.get(CUSTOM_CONTENT_SCREEN_ID);
+        if (progress > 0 && cc.getVisibility() != VISIBLE && !isSmall()) {
+            cc.setVisibility(VISIBLE);
+        }
+
         mLastCustomContentScrollProgress = progress;
 
         setBackgroundAlpha(progress * 0.8f);
@@ -1972,6 +1978,9 @@
 
         boolean workspaceToAllApps = (oldStateIsNormal && stateIsSmall);
         boolean allAppsToWorkspace = (oldStateIsSmall && stateIsNormal);
+        boolean workspaceToOverview = (oldStateIsNormal && stateIsOverview);
+        boolean overviewToWorkspace = (oldStateIsOverview && stateIsNormal);
+
         mNewScale = 1.0f;
 
         if (oldStateIsOverview) {
@@ -1993,9 +2002,15 @@
             }
         }
 
-        final int duration = workspaceToAllApps ?
-                getResources().getInteger(R.integer.config_workspaceUnshrinkTime) :
-                getResources().getInteger(R.integer.config_appsCustomizeWorkspaceShrinkTime);
+        final int duration;
+        if (workspaceToAllApps) {
+            duration = getResources().getInteger(R.integer.config_workspaceUnshrinkTime);
+        } else if (workspaceToOverview || overviewToWorkspace) {
+            duration = getResources().getInteger(R.integer.config_overviewTransitionTime);
+        } else {
+            duration = getResources().getInteger(R.integer.config_appsCustomizeWorkspaceShrinkTime);
+        }
+
         for (int i = 0; i < getChildCount(); i++) {
             final CellLayout cl = (CellLayout) getChildAt(i);
             boolean isCurrentPage = (i == getNextPage());
@@ -2030,6 +2045,7 @@
         final View overviewPanel = mLauncher.getOverviewPanel();
         final View hotseat = mLauncher.getHotseat();
         if (animated) {
+            anim.setDuration(duration);
             LauncherViewPropertyAnimator scale = new LauncherViewPropertyAnimator(this);
             scale.scaleX(mNewScale)
                 .scaleY(mNewScale)
@@ -2048,14 +2064,13 @@
                         LauncherViewPropertyAnimator alphaAnim =
                             new LauncherViewPropertyAnimator(cl.getShortcutsAndWidgets());
                         alphaAnim.alpha(mNewAlphas[i])
-                            .setDuration(duration)
                             .setInterpolator(mZoomInInterpolator);
                         anim.play(alphaAnim);
                     }
                     if (mOldBackgroundAlphas[i] != 0 ||
                         mNewBackgroundAlphas[i] != 0) {
                         ValueAnimator bgAnim =
-                                LauncherAnimUtils.ofFloat(cl, 0f, 1f).setDuration(duration);
+                                LauncherAnimUtils.ofFloat(cl, 0f, 1f);
                         bgAnim.setInterpolator(mZoomInInterpolator);
                         bgAnim.addUpdateListener(new LauncherAnimatorUpdateListener() {
                                 public void onAnimationUpdate(float a, float b) {
@@ -2084,6 +2099,12 @@
             hotseatAlpha.addListener(new AlphaUpdateListener(hotseat));
             searchBarAlpha.addListener(new AlphaUpdateListener(searchBar));
 
+            if (workspaceToOverview) {
+                hotseatAlpha.setInterpolator(new DecelerateInterpolator(2));
+            } else if (overviewToWorkspace) {
+                overviewPanelAlpha.setInterpolator(new DecelerateInterpolator(2));
+            }
+
             if (getPageIndicator() != null) {
                 pageIndicatorAlpha.addListener(new AlphaUpdateListener(getPageIndicator()));
             }
@@ -3031,7 +3052,9 @@
     private void cleanupFolderCreation() {
         if (mDragFolderRingAnimator != null) {
             mDragFolderRingAnimator.animateToNaturalState();
+            mDragFolderRingAnimator = null;
         }
+        mFolderCreationAlarm.setOnAlarmListener(null);
         mFolderCreationAlarm.cancelAlarm();
     }
 
@@ -3375,9 +3398,11 @@
         }
 
         public void onAlarm(Alarm alarm) {
-            if (mDragFolderRingAnimator == null) {
-                mDragFolderRingAnimator = new FolderRingAnimator(mLauncher, null);
+            if (mDragFolderRingAnimator != null) {
+                // This shouldn't happen ever, but just in case, make sure we clean up the mess.
+                mDragFolderRingAnimator.animateToNaturalState();
             }
+            mDragFolderRingAnimator = new FolderRingAnimator(mLauncher, null);
             mDragFolderRingAnimator.setCell(cellX, cellY);
             mDragFolderRingAnimator.setCellLayout(layout);
             mDragFolderRingAnimator.animateToAcceptState();
@@ -4062,6 +4087,7 @@
             }
         }
         mRestoredPages.clear();
+        mSavedStates = null;
     }
 
     @Override
diff --git a/src/com/android/photos/views/TiledImageView.java b/src/com/android/photos/views/TiledImageView.java
index 36cb438..af4199c 100644
--- a/src/com/android/photos/views/TiledImageView.java
+++ b/src/com/android/photos/views/TiledImageView.java
@@ -63,7 +63,7 @@
         // Guarded by locks
         public float scale;
         public int centerX, centerY;
-        int rotation;
+        public int rotation;
         public TileSource source;
         Runnable isReadyCallback;