keep history after reset to git reset to 279b0385d04427d039c10bc22df2a2aaafd99a4a
diff --git a/Android.mk b/Android.mk
index 3bd20a7..dbce33f 100644
--- a/Android.mk
+++ b/Android.mk
@@ -26,8 +26,12 @@
 LOCAL_STATIC_JAVA_LIBRARIES := android-support-v13
 
 LOCAL_SRC_FILES := $(call all-java-files-under, src) \
+    $(call all-java-files-under, WallpaperPicker/src) \
     $(call all-renderscript-files-under, src) \
     $(call all-proto-files-under, protos)
+LOCAL_RESOURCE_DIR := $(LOCAL_PATH)/WallpaperPicker/res $(LOCAL_PATH)/res
+
+LOCAL_AAPT_FLAGS := --auto-add-overlay
 
 LOCAL_PROTOC_OPTIMIZE_TYPE := nano
 LOCAL_PROTOC_FLAGS := --proto_path=$(LOCAL_PATH)/protos/
@@ -57,6 +61,28 @@
 LOCAL_PROTOC_FLAGS := --proto_path=$(LOCAL_PATH)/protos/
 
 LOCAL_MODULE_TAGS := optional
-LOCAL_MODULE := protoutil
+LOCAL_MODULE := launcher_protoutil_lib
+LOCAL_IS_HOST_MODULE := true
+LOCAL_JAR_MANIFEST := util/etc/manifest.txt
+LOCAL_STATIC_JAVA_LIBRARIES := host-libprotobuf-java-2.3.0-nano
 
 include $(BUILD_HOST_JAVA_LIBRARY)
+
+#
+# Protocol Buffer Debug Utility Wrapper Script
+#
+include $(CLEAR_VARS)
+LOCAL_IS_HOST_MODULE := true
+LOCAL_MODULE_CLASS := EXECUTABLES
+LOCAL_MODULE_TAGS := optional
+LOCAL_MODULE := launcher_protoutil
+
+include $(BUILD_SYSTEM)/base_rules.mk
+
+$(LOCAL_BUILT_MODULE): launcher_protoutil_lib
+$(LOCAL_BUILT_MODULE): $(LOCAL_PATH)/util/etc/launcher_protoutil | $(ACP)
+	@echo "Copy: $(PRIVATE_MODULE) ($@)"
+	$(copy-file-to-new-target)
+	$(hide) chmod 755 $@
+
+INTERNAL_DALVIK_MODULES += $(LOCAL_INSTALLED_MODULE)
diff --git a/AndroidManifest.xml b/AndroidManifest.xml
index 901b638..36fa4c1 100644
--- a/AndroidManifest.xml
+++ b/AndroidManifest.xml
@@ -20,6 +20,7 @@
 <manifest
     xmlns:android="http://schemas.android.com/apk/res/android"
     package="com.android.launcher3">
+    <uses-sdk android:targetSdkVersion="19" android:minSdkVersion="16"/>
 
     <permission
         android:name="com.android.launcher3.permission.PRELOAD_WORKSPACE"
@@ -104,7 +105,7 @@
         </activity>
 
         <activity
-            android:name="com.android.launcher3.WallpaperPickerActivity"
+            android:name="com.android.launcher3.LauncherWallpaperPickerActivity"
             android:theme="@style/Theme.WallpaperCropper"
             android:label="@string/pick_wallpaper"
             android:icon="@mipmap/ic_launcher_wallpaper"
@@ -160,6 +161,13 @@
             </intent-filter>
         </receiver>
 
+        <receiver
+            android:name="com.android.launcher3.WallpaperChangedReceiver">
+            <intent-filter>
+                <action android:name="android.intent.action.WALLPAPER_CHANGED" />
+            </intent-filter>
+        </receiver>
+
         <!-- Intent received used to install shortcuts from other applications -->
         <receiver
             android:name="com.android.launcher3.InstallShortcutReceiver"
diff --git a/CleanSpec.mk b/CleanSpec.mk
index c132395..b2c5266 100644
--- a/CleanSpec.mk
+++ b/CleanSpec.mk
@@ -50,6 +50,8 @@
 $(call add-clean-step, rm -rf $(OUT_DIR)/target/common/obj/APPS/Launcher2_intermediates)
 $(call add-clean-step, rm -rf $(OUT_DIR)/target/common/obj/APPS/Launcher2_intermediates)
 $(call add-clean-step, rm -rf $(PRODUCT_OUT)/system/app/Launcher2.apk)
+$(call add-clean-step, rm -rf $(OUT_DIR)/target/common/obj/APPS/Launcher2_intermediates)
+$(call add-clean-step, rm -rf $(PRODUCT_OUT)/system/app/Launcher2.apk)
 
 # ************************************************
 # NEWER CLEAN STEPS MUST BE AT THE END OF THE LIST
diff --git a/WallpaperPicker/AndroidManifest.xml b/WallpaperPicker/AndroidManifest.xml
new file mode 100644
index 0000000..86a94d0
--- /dev/null
+++ b/WallpaperPicker/AndroidManifest.xml
@@ -0,0 +1,10 @@
+<?xml version="1.0" encoding="utf-8"?>
+<manifest xmlns:android="http://schemas.android.com/apk/res/android"
+        package="com.android.launcher3"
+        android:versionCode="1"
+        android:versionName="1.0"
+        >
+
+    <uses-sdk android:minSdkVersion="15" android:targetSdkVersion="19" />
+
+</manifest>
diff --git a/WallpaperPicker/README b/WallpaperPicker/README
new file mode 100644
index 0000000..d8efb07
--- /dev/null
+++ b/WallpaperPicker/README
@@ -0,0 +1,4 @@
+This project contains the wallpaper picker for Launcher3. It's in a separate
+folder to organize the code separately from the rest of the launcher, and has
+a manifest so that a separate Eclipse project can exist for the wallpaper
+picker (necessary to have the Eclipse build work)
\ No newline at end of file
diff --git a/res/drawable-hdpi/ic_actionbar_accept.png b/WallpaperPicker/res/drawable-hdpi/ic_actionbar_accept.png
similarity index 100%
rename from res/drawable-hdpi/ic_actionbar_accept.png
rename to WallpaperPicker/res/drawable-hdpi/ic_actionbar_accept.png
Binary files differ
diff --git a/res/drawable-hdpi/ic_images.png b/WallpaperPicker/res/drawable-hdpi/ic_images.png
similarity index 100%
rename from res/drawable-hdpi/ic_images.png
rename to WallpaperPicker/res/drawable-hdpi/ic_images.png
Binary files differ
diff --git a/res/drawable-hdpi/tile_picker_focused.9.png b/WallpaperPicker/res/drawable-hdpi/tile_picker_focused.9.png
similarity index 100%
rename from res/drawable-hdpi/tile_picker_focused.9.png
rename to WallpaperPicker/res/drawable-hdpi/tile_picker_focused.9.png
Binary files differ
diff --git a/res/drawable-hdpi/tile_picker_pressed.9.png b/WallpaperPicker/res/drawable-hdpi/tile_picker_pressed.9.png
similarity index 100%
rename from res/drawable-hdpi/tile_picker_pressed.9.png
rename to WallpaperPicker/res/drawable-hdpi/tile_picker_pressed.9.png
Binary files differ
diff --git a/res/drawable-hdpi/tile_picker_selected.9.png b/WallpaperPicker/res/drawable-hdpi/tile_picker_selected.9.png
similarity index 100%
rename from res/drawable-hdpi/tile_picker_selected.9.png
rename to WallpaperPicker/res/drawable-hdpi/tile_picker_selected.9.png
Binary files differ
diff --git a/res/drawable-hdpi/tile_shadow_bottom.9.png b/WallpaperPicker/res/drawable-hdpi/tile_shadow_bottom.9.png
similarity index 100%
rename from res/drawable-hdpi/tile_shadow_bottom.9.png
rename to WallpaperPicker/res/drawable-hdpi/tile_shadow_bottom.9.png
Binary files differ
diff --git a/res/drawable-hdpi/tile_shadow_top.9.png b/WallpaperPicker/res/drawable-hdpi/tile_shadow_top.9.png
similarity index 100%
rename from res/drawable-hdpi/tile_shadow_top.9.png
rename to WallpaperPicker/res/drawable-hdpi/tile_shadow_top.9.png
Binary files differ
diff --git a/res/drawable-mdpi/ic_actionbar_accept.png b/WallpaperPicker/res/drawable-mdpi/ic_actionbar_accept.png
similarity index 100%
rename from res/drawable-mdpi/ic_actionbar_accept.png
rename to WallpaperPicker/res/drawable-mdpi/ic_actionbar_accept.png
Binary files differ
diff --git a/res/drawable-mdpi/ic_images.png b/WallpaperPicker/res/drawable-mdpi/ic_images.png
similarity index 100%
rename from res/drawable-mdpi/ic_images.png
rename to WallpaperPicker/res/drawable-mdpi/ic_images.png
Binary files differ
diff --git a/res/drawable-mdpi/tile_picker_focused.9.png b/WallpaperPicker/res/drawable-mdpi/tile_picker_focused.9.png
similarity index 100%
rename from res/drawable-mdpi/tile_picker_focused.9.png
rename to WallpaperPicker/res/drawable-mdpi/tile_picker_focused.9.png
Binary files differ
diff --git a/res/drawable-mdpi/tile_picker_pressed.9.png b/WallpaperPicker/res/drawable-mdpi/tile_picker_pressed.9.png
similarity index 100%
rename from res/drawable-mdpi/tile_picker_pressed.9.png
rename to WallpaperPicker/res/drawable-mdpi/tile_picker_pressed.9.png
Binary files differ
diff --git a/res/drawable-mdpi/tile_picker_selected.9.png b/WallpaperPicker/res/drawable-mdpi/tile_picker_selected.9.png
similarity index 100%
rename from res/drawable-mdpi/tile_picker_selected.9.png
rename to WallpaperPicker/res/drawable-mdpi/tile_picker_selected.9.png
Binary files differ
diff --git a/res/drawable-mdpi/tile_shadow_bottom.9.png b/WallpaperPicker/res/drawable-mdpi/tile_shadow_bottom.9.png
similarity index 100%
rename from res/drawable-mdpi/tile_shadow_bottom.9.png
rename to WallpaperPicker/res/drawable-mdpi/tile_shadow_bottom.9.png
Binary files differ
diff --git a/res/drawable-mdpi/tile_shadow_top.9.png b/WallpaperPicker/res/drawable-mdpi/tile_shadow_top.9.png
similarity index 100%
rename from res/drawable-mdpi/tile_shadow_top.9.png
rename to WallpaperPicker/res/drawable-mdpi/tile_shadow_top.9.png
Binary files differ
diff --git a/res/drawable-xhdpi/ic_actionbar_accept.png b/WallpaperPicker/res/drawable-xhdpi/ic_actionbar_accept.png
similarity index 100%
rename from res/drawable-xhdpi/ic_actionbar_accept.png
rename to WallpaperPicker/res/drawable-xhdpi/ic_actionbar_accept.png
Binary files differ
diff --git a/res/drawable-xhdpi/ic_images.png b/WallpaperPicker/res/drawable-xhdpi/ic_images.png
similarity index 100%
rename from res/drawable-xhdpi/ic_images.png
rename to WallpaperPicker/res/drawable-xhdpi/ic_images.png
Binary files differ
diff --git a/res/drawable-xhdpi/tile_picker_focused.9.png b/WallpaperPicker/res/drawable-xhdpi/tile_picker_focused.9.png
similarity index 100%
rename from res/drawable-xhdpi/tile_picker_focused.9.png
rename to WallpaperPicker/res/drawable-xhdpi/tile_picker_focused.9.png
Binary files differ
diff --git a/res/drawable-xhdpi/tile_picker_pressed.9.png b/WallpaperPicker/res/drawable-xhdpi/tile_picker_pressed.9.png
similarity index 100%
rename from res/drawable-xhdpi/tile_picker_pressed.9.png
rename to WallpaperPicker/res/drawable-xhdpi/tile_picker_pressed.9.png
Binary files differ
diff --git a/res/drawable-xhdpi/tile_picker_selected.9.png b/WallpaperPicker/res/drawable-xhdpi/tile_picker_selected.9.png
similarity index 100%
rename from res/drawable-xhdpi/tile_picker_selected.9.png
rename to WallpaperPicker/res/drawable-xhdpi/tile_picker_selected.9.png
Binary files differ
diff --git a/res/drawable-xhdpi/tile_shadow_bottom.9.png b/WallpaperPicker/res/drawable-xhdpi/tile_shadow_bottom.9.png
similarity index 100%
rename from res/drawable-xhdpi/tile_shadow_bottom.9.png
rename to WallpaperPicker/res/drawable-xhdpi/tile_shadow_bottom.9.png
Binary files differ
diff --git a/res/drawable-xhdpi/tile_shadow_top.9.png b/WallpaperPicker/res/drawable-xhdpi/tile_shadow_top.9.png
similarity index 100%
rename from res/drawable-xhdpi/tile_shadow_top.9.png
rename to WallpaperPicker/res/drawable-xhdpi/tile_shadow_top.9.png
Binary files differ
diff --git a/res/drawable-xxhdpi/ic_images.png b/WallpaperPicker/res/drawable-xxhdpi/ic_images.png
similarity index 100%
rename from res/drawable-xxhdpi/ic_images.png
rename to WallpaperPicker/res/drawable-xxhdpi/ic_images.png
Binary files differ
diff --git a/res/drawable-xxhdpi/tile_picker_focused.9.png b/WallpaperPicker/res/drawable-xxhdpi/tile_picker_focused.9.png
similarity index 100%
rename from res/drawable-xxhdpi/tile_picker_focused.9.png
rename to WallpaperPicker/res/drawable-xxhdpi/tile_picker_focused.9.png
Binary files differ
diff --git a/res/drawable-xxhdpi/tile_picker_pressed.9.png b/WallpaperPicker/res/drawable-xxhdpi/tile_picker_pressed.9.png
similarity index 100%
rename from res/drawable-xxhdpi/tile_picker_pressed.9.png
rename to WallpaperPicker/res/drawable-xxhdpi/tile_picker_pressed.9.png
Binary files differ
diff --git a/res/drawable-xxhdpi/tile_picker_selected.9.png b/WallpaperPicker/res/drawable-xxhdpi/tile_picker_selected.9.png
similarity index 100%
rename from res/drawable-xxhdpi/tile_picker_selected.9.png
rename to WallpaperPicker/res/drawable-xxhdpi/tile_picker_selected.9.png
Binary files differ
diff --git a/res/drawable-xxhdpi/tile_shadow_bottom.9.png b/WallpaperPicker/res/drawable-xxhdpi/tile_shadow_bottom.9.png
similarity index 100%
rename from res/drawable-xxhdpi/tile_shadow_bottom.9.png
rename to WallpaperPicker/res/drawable-xxhdpi/tile_shadow_bottom.9.png
Binary files differ
diff --git a/res/drawable-xxhdpi/tile_shadow_top.9.png b/WallpaperPicker/res/drawable-xxhdpi/tile_shadow_top.9.png
similarity index 100%
rename from res/drawable-xxhdpi/tile_shadow_top.9.png
rename to WallpaperPicker/res/drawable-xxhdpi/tile_shadow_top.9.png
Binary files differ
diff --git a/res/drawable/wallpaper_tile_fg.xml b/WallpaperPicker/res/drawable/wallpaper_tile_fg.xml
similarity index 100%
rename from res/drawable/wallpaper_tile_fg.xml
rename to WallpaperPicker/res/drawable/wallpaper_tile_fg.xml
diff --git a/res/layout/actionbar_set_wallpaper.xml b/WallpaperPicker/res/layout/actionbar_set_wallpaper.xml
similarity index 100%
rename from res/layout/actionbar_set_wallpaper.xml
rename to WallpaperPicker/res/layout/actionbar_set_wallpaper.xml
diff --git a/res/layout/wallpaper_cropper.xml b/WallpaperPicker/res/layout/wallpaper_cropper.xml
similarity index 96%
rename from res/layout/wallpaper_cropper.xml
rename to WallpaperPicker/res/layout/wallpaper_cropper.xml
index 3a3d98a..abb8608 100644
--- a/res/layout/wallpaper_cropper.xml
+++ b/WallpaperPicker/res/layout/wallpaper_cropper.xml
@@ -32,7 +32,7 @@
         android:visibility="invisible"
         android:layout_width="wrap_content"
         android:layout_height="wrap_content"
-        android:layout_gravity="center"
+        android:layout_centerInParent="true"
         android:indeterminate="true"
         android:indeterminateOnly="true"
         android:background="@android:color/transparent" />
diff --git a/res/layout/wallpaper_picker.xml b/WallpaperPicker/res/layout/wallpaper_picker.xml
similarity index 98%
rename from res/layout/wallpaper_picker.xml
rename to WallpaperPicker/res/layout/wallpaper_picker.xml
index c91cc7e..c36493d 100644
--- a/res/layout/wallpaper_picker.xml
+++ b/WallpaperPicker/res/layout/wallpaper_picker.xml
@@ -33,7 +33,7 @@
         android:visibility="invisible"
         android:layout_width="wrap_content"
         android:layout_height="wrap_content"
-        android:layout_gravity="center"
+        android:layout_centerInParent="true"
         android:indeterminate="true"
         android:indeterminateOnly="true"
         android:background="@android:color/transparent" />
diff --git a/res/layout/wallpaper_picker_image_picker_item.xml b/WallpaperPicker/res/layout/wallpaper_picker_image_picker_item.xml
similarity index 100%
rename from res/layout/wallpaper_picker_image_picker_item.xml
rename to WallpaperPicker/res/layout/wallpaper_picker_image_picker_item.xml
diff --git a/res/layout/wallpaper_picker_item.xml b/WallpaperPicker/res/layout/wallpaper_picker_item.xml
similarity index 100%
rename from res/layout/wallpaper_picker_item.xml
rename to WallpaperPicker/res/layout/wallpaper_picker_item.xml
diff --git a/res/layout/wallpaper_picker_live_wallpaper_item.xml b/WallpaperPicker/res/layout/wallpaper_picker_live_wallpaper_item.xml
similarity index 100%
rename from res/layout/wallpaper_picker_live_wallpaper_item.xml
rename to WallpaperPicker/res/layout/wallpaper_picker_live_wallpaper_item.xml
diff --git a/res/layout/wallpaper_picker_third_party_item.xml b/WallpaperPicker/res/layout/wallpaper_picker_third_party_item.xml
similarity index 100%
rename from res/layout/wallpaper_picker_third_party_item.xml
rename to WallpaperPicker/res/layout/wallpaper_picker_third_party_item.xml
diff --git a/res/menu/cab_delete_wallpapers.xml b/WallpaperPicker/res/menu/cab_delete_wallpapers.xml
similarity index 100%
rename from res/menu/cab_delete_wallpapers.xml
rename to WallpaperPicker/res/menu/cab_delete_wallpapers.xml
diff --git a/res/mipmap-hdpi/ic_launcher_wallpaper.png b/WallpaperPicker/res/mipmap-hdpi/ic_launcher_wallpaper.png
similarity index 100%
rename from res/mipmap-hdpi/ic_launcher_wallpaper.png
rename to WallpaperPicker/res/mipmap-hdpi/ic_launcher_wallpaper.png
Binary files differ
diff --git a/res/mipmap-mdpi/ic_launcher_wallpaper.png b/WallpaperPicker/res/mipmap-mdpi/ic_launcher_wallpaper.png
similarity index 100%
rename from res/mipmap-mdpi/ic_launcher_wallpaper.png
rename to WallpaperPicker/res/mipmap-mdpi/ic_launcher_wallpaper.png
Binary files differ
diff --git a/res/mipmap-xhdpi/ic_launcher_wallpaper.png b/WallpaperPicker/res/mipmap-xhdpi/ic_launcher_wallpaper.png
similarity index 100%
rename from res/mipmap-xhdpi/ic_launcher_wallpaper.png
rename to WallpaperPicker/res/mipmap-xhdpi/ic_launcher_wallpaper.png
Binary files differ
diff --git a/res/mipmap-xxhdpi/ic_launcher_wallpaper.png b/WallpaperPicker/res/mipmap-xxhdpi/ic_launcher_wallpaper.png
similarity index 100%
rename from res/mipmap-xxhdpi/ic_launcher_wallpaper.png
rename to WallpaperPicker/res/mipmap-xxhdpi/ic_launcher_wallpaper.png
Binary files differ
diff --git a/WallpaperPicker/res/values-af/strings.xml b/WallpaperPicker/res/values-af/strings.xml
new file mode 100644
index 0000000..c17d26b
--- /dev/null
+++ b/WallpaperPicker/res/values-af/strings.xml
@@ -0,0 +1,36 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/*
+* Copyright (C) 2013 The Android Open Source Project
+*
+* Licensed under the Apache License, Version 2.0 (the "License");
+* you may not use this file except in compliance with the License.
+* You may obtain a copy of the License at
+*
+*      http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.
+*/
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="wallpaper_instructions" msgid="3524143401182707094">"Stel muurpapier"</string>
+    <string name="image_load_fail" msgid="7538534580694411837">"Kon nie prent laai nie"</string>
+    <string name="wallpaper_load_fail" msgid="4800700444605404650">"Kon nie prent as muurpapier laai nie"</string>
+  <plurals name="number_of_items_selected">
+    <item quantity="zero" msgid="9015111147509924344">"%1$d gekies"</item>
+    <item quantity="one" msgid="8409622005831789373">"%1$d gekies"</item>
+    <item quantity="other" msgid="479468347731745357">"%1$d gekies"</item>
+  </plurals>
+    <string name="wallpaper_accessibility_name" msgid="4093221025304876354">"Muurpapier %1$d van %2$d"</string>
+    <string name="announce_selection" msgid="123723511662250539">"Het <xliff:g id="LABEL">%1$s</xliff:g> gekies"</string>
+    <string name="wallpaper_delete" msgid="1459353972739215344">"Vee uit"</string>
+    <string name="pick_image" msgid="6704438906027442697">"Kies prent"</string>
+    <string name="pick_wallpaper" msgid="4628969645948454559">"Muurpapiere"</string>
+    <string name="crop_wallpaper" msgid="4882870800623585836">"Snoei muurpapier"</string>
+</resources>
diff --git a/WallpaperPicker/res/values-am/strings.xml b/WallpaperPicker/res/values-am/strings.xml
new file mode 100644
index 0000000..3941616
--- /dev/null
+++ b/WallpaperPicker/res/values-am/strings.xml
@@ -0,0 +1,36 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/*
+* Copyright (C) 2013 The Android Open Source Project
+*
+* Licensed under the Apache License, Version 2.0 (the "License");
+* you may not use this file except in compliance with the License.
+* You may obtain a copy of the License at
+*
+*      http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.
+*/
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="wallpaper_instructions" msgid="3524143401182707094">"የግድግዳ ወረቀት አዘጋጅ"</string>
+    <string name="image_load_fail" msgid="7538534580694411837">"ምስሉን መጫን አልተቻለም"</string>
+    <string name="wallpaper_load_fail" msgid="4800700444605404650">"ምስሉን እንደ ግድግዳ ወረቀት መጫን አልተቻለም"</string>
+  <plurals name="number_of_items_selected">
+    <item quantity="zero" msgid="9015111147509924344">"%1$d ተመርጧል"</item>
+    <item quantity="one" msgid="8409622005831789373">"%1$d ተመርጧል"</item>
+    <item quantity="other" msgid="479468347731745357">"%1$d ተመርጧል"</item>
+  </plurals>
+    <string name="wallpaper_accessibility_name" msgid="4093221025304876354">"የግድግዳ ወረቀት %1$d የ%2$d"</string>
+    <string name="announce_selection" msgid="123723511662250539">"<xliff:g id="LABEL">%1$s</xliff:g> ተመርጧል"</string>
+    <string name="wallpaper_delete" msgid="1459353972739215344">"ሰርዝ"</string>
+    <string name="pick_image" msgid="6704438906027442697">"ምስል ይምረጡ"</string>
+    <string name="pick_wallpaper" msgid="4628969645948454559">"የግድግዳ ወረቀቶች"</string>
+    <string name="crop_wallpaper" msgid="4882870800623585836">"የግድግዳ ወረቀት ይከርክሙ"</string>
+</resources>
diff --git a/WallpaperPicker/res/values-ar/strings.xml b/WallpaperPicker/res/values-ar/strings.xml
new file mode 100644
index 0000000..2075cc8
--- /dev/null
+++ b/WallpaperPicker/res/values-ar/strings.xml
@@ -0,0 +1,36 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/*
+* Copyright (C) 2013 The Android Open Source Project
+*
+* Licensed under the Apache License, Version 2.0 (the "License");
+* you may not use this file except in compliance with the License.
+* You may obtain a copy of the License at
+*
+*      http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.
+*/
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="wallpaper_instructions" msgid="3524143401182707094">"تعيين الخلفية"</string>
+    <string name="image_load_fail" msgid="7538534580694411837">"تعذر تحميل الصورة"</string>
+    <string name="wallpaper_load_fail" msgid="4800700444605404650">"تعذر تحميل الصورة كخلفية"</string>
+  <plurals name="number_of_items_selected">
+    <item quantity="zero" msgid="9015111147509924344">"‏تم تحديد %1$d"</item>
+    <item quantity="one" msgid="8409622005831789373">"‏تم تحديد %1$d"</item>
+    <item quantity="other" msgid="479468347731745357">"‏تم تحديد %1$d"</item>
+  </plurals>
+    <string name="wallpaper_accessibility_name" msgid="4093221025304876354">"‏الخلفية %1$d من %2$d"</string>
+    <string name="announce_selection" msgid="123723511662250539">"تم تحديد <xliff:g id="LABEL">%1$s</xliff:g>"</string>
+    <string name="wallpaper_delete" msgid="1459353972739215344">"حذف"</string>
+    <string name="pick_image" msgid="6704438906027442697">"اختيار صورة"</string>
+    <string name="pick_wallpaper" msgid="4628969645948454559">"الخلفيات"</string>
+    <string name="crop_wallpaper" msgid="4882870800623585836">"اقتصاص الخلفية"</string>
+</resources>
diff --git a/WallpaperPicker/res/values-bg/strings.xml b/WallpaperPicker/res/values-bg/strings.xml
new file mode 100644
index 0000000..ce4fc65
--- /dev/null
+++ b/WallpaperPicker/res/values-bg/strings.xml
@@ -0,0 +1,36 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/*
+* Copyright (C) 2013 The Android Open Source Project
+*
+* Licensed under the Apache License, Version 2.0 (the "License");
+* you may not use this file except in compliance with the License.
+* You may obtain a copy of the License at
+*
+*      http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.
+*/
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="wallpaper_instructions" msgid="3524143401182707094">"Задаване на тапета"</string>
+    <string name="image_load_fail" msgid="7538534580694411837">"Изображението не можа да бъде заредено"</string>
+    <string name="wallpaper_load_fail" msgid="4800700444605404650">"Изображението не можа да бъде заредено като тапет"</string>
+  <plurals name="number_of_items_selected">
+    <item quantity="zero" msgid="9015111147509924344">"Избрахте %1$d"</item>
+    <item quantity="one" msgid="8409622005831789373">"Избрахте %1$d"</item>
+    <item quantity="other" msgid="479468347731745357">"Избрахте %1$d"</item>
+  </plurals>
+    <string name="wallpaper_accessibility_name" msgid="4093221025304876354">"Тапет %1$d от %2$d"</string>
+    <string name="announce_selection" msgid="123723511662250539">"Избрахте <xliff:g id="LABEL">%1$s</xliff:g>"</string>
+    <string name="wallpaper_delete" msgid="1459353972739215344">"Изтриване"</string>
+    <string name="pick_image" msgid="6704438906027442697">"Избиране на изображение"</string>
+    <string name="pick_wallpaper" msgid="4628969645948454559">"Тапети"</string>
+    <string name="crop_wallpaper" msgid="4882870800623585836">"Подрязване на тапета"</string>
+</resources>
diff --git a/WallpaperPicker/res/values-ca/strings.xml b/WallpaperPicker/res/values-ca/strings.xml
new file mode 100644
index 0000000..89de81c
--- /dev/null
+++ b/WallpaperPicker/res/values-ca/strings.xml
@@ -0,0 +1,36 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/*
+* Copyright (C) 2013 The Android Open Source Project
+*
+* Licensed under the Apache License, Version 2.0 (the "License");
+* you may not use this file except in compliance with the License.
+* You may obtain a copy of the License at
+*
+*      http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.
+*/
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="wallpaper_instructions" msgid="3524143401182707094">"Estableix el fons de pantalla"</string>
+    <string name="image_load_fail" msgid="7538534580694411837">"No s\'ha pogut carregar la imatge."</string>
+    <string name="wallpaper_load_fail" msgid="4800700444605404650">"No s\'ha pogut carregar la imatge com a fons de pantalla."</string>
+  <plurals name="number_of_items_selected">
+    <item quantity="zero" msgid="9015111147509924344">"Seleccionats: %1$d"</item>
+    <item quantity="one" msgid="8409622005831789373">"Seleccionats: %1$d"</item>
+    <item quantity="other" msgid="479468347731745357">"Seleccionats: %1$d"</item>
+  </plurals>
+    <string name="wallpaper_accessibility_name" msgid="4093221025304876354">"Fons de pantalla %1$d de %2$d"</string>
+    <string name="announce_selection" msgid="123723511662250539">"S\'ha seleccionat <xliff:g id="LABEL">%1$s</xliff:g>."</string>
+    <string name="wallpaper_delete" msgid="1459353972739215344">"Suprimeix"</string>
+    <string name="pick_image" msgid="6704438906027442697">"Tria una imatge"</string>
+    <string name="pick_wallpaper" msgid="4628969645948454559">"Fons de pantalla"</string>
+    <string name="crop_wallpaper" msgid="4882870800623585836">"Retallar fons de pantalla"</string>
+</resources>
diff --git a/WallpaperPicker/res/values-cs/strings.xml b/WallpaperPicker/res/values-cs/strings.xml
new file mode 100644
index 0000000..a07b9ed
--- /dev/null
+++ b/WallpaperPicker/res/values-cs/strings.xml
@@ -0,0 +1,36 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/*
+* Copyright (C) 2013 The Android Open Source Project
+*
+* Licensed under the Apache License, Version 2.0 (the "License");
+* you may not use this file except in compliance with the License.
+* You may obtain a copy of the License at
+*
+*      http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.
+*/
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="wallpaper_instructions" msgid="3524143401182707094">"Nastavit jako tapetu"</string>
+    <string name="image_load_fail" msgid="7538534580694411837">"Obrázek nelze načíst."</string>
+    <string name="wallpaper_load_fail" msgid="4800700444605404650">"Obrázek nelze načíst jako tapetu."</string>
+  <plurals name="number_of_items_selected">
+    <item quantity="zero" msgid="9015111147509924344">"Vybráno: %1$d"</item>
+    <item quantity="one" msgid="8409622005831789373">"Vybráno: %1$d"</item>
+    <item quantity="other" msgid="479468347731745357">"Vybráno: %1$d"</item>
+  </plurals>
+    <string name="wallpaper_accessibility_name" msgid="4093221025304876354">"Tapeta %1$d z %2$d"</string>
+    <string name="announce_selection" msgid="123723511662250539">"Vybrána položka <xliff:g id="LABEL">%1$s</xliff:g>"</string>
+    <string name="wallpaper_delete" msgid="1459353972739215344">"Smazat"</string>
+    <string name="pick_image" msgid="6704438906027442697">"Vybrat obrázek"</string>
+    <string name="pick_wallpaper" msgid="4628969645948454559">"Tapety"</string>
+    <string name="crop_wallpaper" msgid="4882870800623585836">"Oříznutí tapety"</string>
+</resources>
diff --git a/WallpaperPicker/res/values-da/strings.xml b/WallpaperPicker/res/values-da/strings.xml
new file mode 100644
index 0000000..5b233e1
--- /dev/null
+++ b/WallpaperPicker/res/values-da/strings.xml
@@ -0,0 +1,36 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/*
+* Copyright (C) 2013 The Android Open Source Project
+*
+* Licensed under the Apache License, Version 2.0 (the "License");
+* you may not use this file except in compliance with the License.
+* You may obtain a copy of the License at
+*
+*      http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.
+*/
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="wallpaper_instructions" msgid="3524143401182707094">"Angiv baggrund"</string>
+    <string name="image_load_fail" msgid="7538534580694411837">"Billedet kunne ikke indlæses"</string>
+    <string name="wallpaper_load_fail" msgid="4800700444605404650">"Billedet kunne ikke indlæses som baggrund"</string>
+  <plurals name="number_of_items_selected">
+    <item quantity="zero" msgid="9015111147509924344">"%1$d er valgt"</item>
+    <item quantity="one" msgid="8409622005831789373">"%1$d er valgt"</item>
+    <item quantity="other" msgid="479468347731745357">"%1$d er valgt"</item>
+  </plurals>
+    <string name="wallpaper_accessibility_name" msgid="4093221025304876354">"Baggrund %1$d af %2$d"</string>
+    <string name="announce_selection" msgid="123723511662250539">"<xliff:g id="LABEL">%1$s</xliff:g> blev valgt"</string>
+    <string name="wallpaper_delete" msgid="1459353972739215344">"Slet"</string>
+    <string name="pick_image" msgid="6704438906027442697">"Vælg et billede"</string>
+    <string name="pick_wallpaper" msgid="4628969645948454559">"Baggrunde"</string>
+    <string name="crop_wallpaper" msgid="4882870800623585836">"Beskær baggrunden"</string>
+</resources>
diff --git a/WallpaperPicker/res/values-de/strings.xml b/WallpaperPicker/res/values-de/strings.xml
new file mode 100644
index 0000000..11c1cac
--- /dev/null
+++ b/WallpaperPicker/res/values-de/strings.xml
@@ -0,0 +1,36 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/*
+* Copyright (C) 2013 The Android Open Source Project
+*
+* Licensed under the Apache License, Version 2.0 (the "License");
+* you may not use this file except in compliance with the License.
+* You may obtain a copy of the License at
+*
+*      http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.
+*/
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="wallpaper_instructions" msgid="3524143401182707094">"Hintergrund auswählen"</string>
+    <string name="image_load_fail" msgid="7538534580694411837">"Bild konnte nicht geladen werden."</string>
+    <string name="wallpaper_load_fail" msgid="4800700444605404650">"Bild konnte nicht als Hintergrund geladen werden."</string>
+  <plurals name="number_of_items_selected">
+    <item quantity="zero" msgid="9015111147509924344">"%1$d ausgewählt"</item>
+    <item quantity="one" msgid="8409622005831789373">"%1$d ausgewählt"</item>
+    <item quantity="other" msgid="479468347731745357">"%1$d ausgewählt"</item>
+  </plurals>
+    <string name="wallpaper_accessibility_name" msgid="4093221025304876354">"Hintergrund %1$d von %2$d"</string>
+    <string name="announce_selection" msgid="123723511662250539">"<xliff:g id="LABEL">%1$s</xliff:g> ausgewählt"</string>
+    <string name="wallpaper_delete" msgid="1459353972739215344">"Löschen"</string>
+    <string name="pick_image" msgid="6704438906027442697">"Bild auswählen"</string>
+    <string name="pick_wallpaper" msgid="4628969645948454559">"Hintergründe"</string>
+    <string name="crop_wallpaper" msgid="4882870800623585836">"Hintergrund zuschneiden"</string>
+</resources>
diff --git a/WallpaperPicker/res/values-el/strings.xml b/WallpaperPicker/res/values-el/strings.xml
new file mode 100644
index 0000000..8e1e78f
--- /dev/null
+++ b/WallpaperPicker/res/values-el/strings.xml
@@ -0,0 +1,36 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/*
+* Copyright (C) 2013 The Android Open Source Project
+*
+* Licensed under the Apache License, Version 2.0 (the "License");
+* you may not use this file except in compliance with the License.
+* You may obtain a copy of the License at
+*
+*      http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.
+*/
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="wallpaper_instructions" msgid="3524143401182707094">"Ορισμός ταπετσαρίας"</string>
+    <string name="image_load_fail" msgid="7538534580694411837">"Δεν ήταν δυνατή η φόρτωση της εικόνας"</string>
+    <string name="wallpaper_load_fail" msgid="4800700444605404650">"Δεν ήταν δυνατή η φόρτωση της εικόνας ως ταπετσαρία"</string>
+  <plurals name="number_of_items_selected">
+    <item quantity="zero" msgid="9015111147509924344">"%1$d επιλεγμένα"</item>
+    <item quantity="one" msgid="8409622005831789373">"%1$d επιλεγμένα"</item>
+    <item quantity="other" msgid="479468347731745357">"%1$d επιλεγμένα"</item>
+  </plurals>
+    <string name="wallpaper_accessibility_name" msgid="4093221025304876354">"Ταπετσαρία %1$d από %2$d"</string>
+    <string name="announce_selection" msgid="123723511662250539">"Επιλέχθηκε το <xliff:g id="LABEL">%1$s</xliff:g>"</string>
+    <string name="wallpaper_delete" msgid="1459353972739215344">"Διαγραφή"</string>
+    <string name="pick_image" msgid="6704438906027442697">"Επιλογή εικόνας"</string>
+    <string name="pick_wallpaper" msgid="4628969645948454559">"Ταπετσαρίες"</string>
+    <string name="crop_wallpaper" msgid="4882870800623585836">"Περικοπή ταπετσαρίας"</string>
+</resources>
diff --git a/WallpaperPicker/res/values-en-rGB/strings.xml b/WallpaperPicker/res/values-en-rGB/strings.xml
new file mode 100644
index 0000000..c057c0c
--- /dev/null
+++ b/WallpaperPicker/res/values-en-rGB/strings.xml
@@ -0,0 +1,36 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/*
+* Copyright (C) 2013 The Android Open Source Project
+*
+* Licensed under the Apache License, Version 2.0 (the "License");
+* you may not use this file except in compliance with the License.
+* You may obtain a copy of the License at
+*
+*      http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.
+*/
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="wallpaper_instructions" msgid="3524143401182707094">"Set wallpaper"</string>
+    <string name="image_load_fail" msgid="7538534580694411837">"Couldn\'t load image"</string>
+    <string name="wallpaper_load_fail" msgid="4800700444605404650">"Couldn\'t load image as wallpaper"</string>
+  <plurals name="number_of_items_selected">
+    <item quantity="zero" msgid="9015111147509924344">"%1$d selected"</item>
+    <item quantity="one" msgid="8409622005831789373">"%1$d selected"</item>
+    <item quantity="other" msgid="479468347731745357">"%1$d selected"</item>
+  </plurals>
+    <string name="wallpaper_accessibility_name" msgid="4093221025304876354">"Wallpaper %1$d of %2$d"</string>
+    <string name="announce_selection" msgid="123723511662250539">"Selected <xliff:g id="LABEL">%1$s</xliff:g>"</string>
+    <string name="wallpaper_delete" msgid="1459353972739215344">"Delete"</string>
+    <string name="pick_image" msgid="6704438906027442697">"Pick image"</string>
+    <string name="pick_wallpaper" msgid="4628969645948454559">"Wallpapers"</string>
+    <string name="crop_wallpaper" msgid="4882870800623585836">"Crop wallpaper"</string>
+</resources>
diff --git a/WallpaperPicker/res/values-en-rIN/strings.xml b/WallpaperPicker/res/values-en-rIN/strings.xml
new file mode 100644
index 0000000..c057c0c
--- /dev/null
+++ b/WallpaperPicker/res/values-en-rIN/strings.xml
@@ -0,0 +1,36 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/*
+* Copyright (C) 2013 The Android Open Source Project
+*
+* Licensed under the Apache License, Version 2.0 (the "License");
+* you may not use this file except in compliance with the License.
+* You may obtain a copy of the License at
+*
+*      http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.
+*/
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="wallpaper_instructions" msgid="3524143401182707094">"Set wallpaper"</string>
+    <string name="image_load_fail" msgid="7538534580694411837">"Couldn\'t load image"</string>
+    <string name="wallpaper_load_fail" msgid="4800700444605404650">"Couldn\'t load image as wallpaper"</string>
+  <plurals name="number_of_items_selected">
+    <item quantity="zero" msgid="9015111147509924344">"%1$d selected"</item>
+    <item quantity="one" msgid="8409622005831789373">"%1$d selected"</item>
+    <item quantity="other" msgid="479468347731745357">"%1$d selected"</item>
+  </plurals>
+    <string name="wallpaper_accessibility_name" msgid="4093221025304876354">"Wallpaper %1$d of %2$d"</string>
+    <string name="announce_selection" msgid="123723511662250539">"Selected <xliff:g id="LABEL">%1$s</xliff:g>"</string>
+    <string name="wallpaper_delete" msgid="1459353972739215344">"Delete"</string>
+    <string name="pick_image" msgid="6704438906027442697">"Pick image"</string>
+    <string name="pick_wallpaper" msgid="4628969645948454559">"Wallpapers"</string>
+    <string name="crop_wallpaper" msgid="4882870800623585836">"Crop wallpaper"</string>
+</resources>
diff --git a/WallpaperPicker/res/values-es-rUS/strings.xml b/WallpaperPicker/res/values-es-rUS/strings.xml
new file mode 100644
index 0000000..768385b
--- /dev/null
+++ b/WallpaperPicker/res/values-es-rUS/strings.xml
@@ -0,0 +1,36 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/*
+* Copyright (C) 2013 The Android Open Source Project
+*
+* Licensed under the Apache License, Version 2.0 (the "License");
+* you may not use this file except in compliance with the License.
+* You may obtain a copy of the License at
+*
+*      http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.
+*/
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="wallpaper_instructions" msgid="3524143401182707094">"Establecer como fondo de pantalla"</string>
+    <string name="image_load_fail" msgid="7538534580694411837">"No se pudo cargar la imagen."</string>
+    <string name="wallpaper_load_fail" msgid="4800700444605404650">"No se pudo cargar la imagen como fondo de pantalla."</string>
+  <plurals name="number_of_items_selected">
+    <item quantity="zero" msgid="9015111147509924344">"%1$d seleccionado"</item>
+    <item quantity="one" msgid="8409622005831789373">"%1$d seleccionado"</item>
+    <item quantity="other" msgid="479468347731745357">"%1$d seleccionados"</item>
+  </plurals>
+    <string name="wallpaper_accessibility_name" msgid="4093221025304876354">"Fondo de pantalla %1$d de %2$d"</string>
+    <string name="announce_selection" msgid="123723511662250539">"<xliff:g id="LABEL">%1$s</xliff:g> seleccionado"</string>
+    <string name="wallpaper_delete" msgid="1459353972739215344">"Eliminar"</string>
+    <string name="pick_image" msgid="6704438906027442697">"Elegir imagen"</string>
+    <string name="pick_wallpaper" msgid="4628969645948454559">"Fondos de pantalla"</string>
+    <string name="crop_wallpaper" msgid="4882870800623585836">"Recortar fondo de pantalla"</string>
+</resources>
diff --git a/WallpaperPicker/res/values-es/strings.xml b/WallpaperPicker/res/values-es/strings.xml
new file mode 100644
index 0000000..702b6d4
--- /dev/null
+++ b/WallpaperPicker/res/values-es/strings.xml
@@ -0,0 +1,36 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/*
+* Copyright (C) 2013 The Android Open Source Project
+*
+* Licensed under the Apache License, Version 2.0 (the "License");
+* you may not use this file except in compliance with the License.
+* You may obtain a copy of the License at
+*
+*      http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.
+*/
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="wallpaper_instructions" msgid="3524143401182707094">"Establecer fondo"</string>
+    <string name="image_load_fail" msgid="7538534580694411837">"No se ha podido cargar la imagen"</string>
+    <string name="wallpaper_load_fail" msgid="4800700444605404650">"No se ha podido cargar la imagen como fondo de pantalla"</string>
+  <plurals name="number_of_items_selected">
+    <item quantity="zero" msgid="9015111147509924344">"Seleccionados: %1$d"</item>
+    <item quantity="one" msgid="8409622005831789373">"Seleccionados: %1$d"</item>
+    <item quantity="other" msgid="479468347731745357">"Seleccionados: %1$d"</item>
+  </plurals>
+    <string name="wallpaper_accessibility_name" msgid="4093221025304876354">"Fondo de pantalla %1$d de %2$d"</string>
+    <string name="announce_selection" msgid="123723511662250539">"<xliff:g id="LABEL">%1$s</xliff:g> seleccionado"</string>
+    <string name="wallpaper_delete" msgid="1459353972739215344">"Eliminar"</string>
+    <string name="pick_image" msgid="6704438906027442697">"Seleccionar imagen"</string>
+    <string name="pick_wallpaper" msgid="4628969645948454559">"Fondos de pantalla"</string>
+    <string name="crop_wallpaper" msgid="4882870800623585836">"Recortar fondo de pantalla"</string>
+</resources>
diff --git a/WallpaperPicker/res/values-et-rEE/strings.xml b/WallpaperPicker/res/values-et-rEE/strings.xml
new file mode 100644
index 0000000..c09e223
--- /dev/null
+++ b/WallpaperPicker/res/values-et-rEE/strings.xml
@@ -0,0 +1,36 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/*
+* Copyright (C) 2013 The Android Open Source Project
+*
+* Licensed under the Apache License, Version 2.0 (the "License");
+* you may not use this file except in compliance with the License.
+* You may obtain a copy of the License at
+*
+*      http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.
+*/
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="wallpaper_instructions" msgid="3524143401182707094">"Määra taustapilt"</string>
+    <string name="image_load_fail" msgid="7538534580694411837">"Kujutist ei õnnestunud laadida"</string>
+    <string name="wallpaper_load_fail" msgid="4800700444605404650">"Kujutist ei õnnestunud taustapildina laadida"</string>
+  <plurals name="number_of_items_selected">
+    <item quantity="zero" msgid="9015111147509924344">"Valitud on %1$d"</item>
+    <item quantity="one" msgid="8409622005831789373">"Valitud on %1$d"</item>
+    <item quantity="other" msgid="479468347731745357">"Valitud on %1$d"</item>
+  </plurals>
+    <string name="wallpaper_accessibility_name" msgid="4093221025304876354">"%1$d/%2$d taustapildist"</string>
+    <string name="announce_selection" msgid="123723511662250539">"Valitud on <xliff:g id="LABEL">%1$s</xliff:g>"</string>
+    <string name="wallpaper_delete" msgid="1459353972739215344">"Kustuta"</string>
+    <string name="pick_image" msgid="6704438906027442697">"Vali kujutis"</string>
+    <string name="pick_wallpaper" msgid="4628969645948454559">"Taustapildid"</string>
+    <string name="crop_wallpaper" msgid="4882870800623585836">"Taustapildi kärpimine"</string>
+</resources>
diff --git a/WallpaperPicker/res/values-fa/strings.xml b/WallpaperPicker/res/values-fa/strings.xml
new file mode 100644
index 0000000..eb330b5
--- /dev/null
+++ b/WallpaperPicker/res/values-fa/strings.xml
@@ -0,0 +1,36 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/*
+* Copyright (C) 2013 The Android Open Source Project
+*
+* Licensed under the Apache License, Version 2.0 (the "License");
+* you may not use this file except in compliance with the License.
+* You may obtain a copy of the License at
+*
+*      http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.
+*/
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="wallpaper_instructions" msgid="3524143401182707094">"تنظیم کاغذدیواری"</string>
+    <string name="image_load_fail" msgid="7538534580694411837">"تصویر بارگیری نشد"</string>
+    <string name="wallpaper_load_fail" msgid="4800700444605404650">"تصویر به عنوان کاغذدیواری بارگیری نشد"</string>
+  <plurals name="number_of_items_selected">
+    <item quantity="zero" msgid="9015111147509924344">"‏%1$d انتخاب شد"</item>
+    <item quantity="one" msgid="8409622005831789373">"‏%1$d انتخاب شد"</item>
+    <item quantity="other" msgid="479468347731745357">"‏%1$d انتخاب شد"</item>
+  </plurals>
+    <string name="wallpaper_accessibility_name" msgid="4093221025304876354">"‏کاغذدیواری %1$d از %2$d"</string>
+    <string name="announce_selection" msgid="123723511662250539">"<xliff:g id="LABEL">%1$s</xliff:g> انتخاب شده است"</string>
+    <string name="wallpaper_delete" msgid="1459353972739215344">"حذف"</string>
+    <string name="pick_image" msgid="6704438906027442697">"انتخاب تصویر"</string>
+    <string name="pick_wallpaper" msgid="4628969645948454559">"کاغذدیواری‌ها"</string>
+    <string name="crop_wallpaper" msgid="4882870800623585836">"برش کاغذدیواری"</string>
+</resources>
diff --git a/WallpaperPicker/res/values-fi/strings.xml b/WallpaperPicker/res/values-fi/strings.xml
new file mode 100644
index 0000000..0fa4b7b
--- /dev/null
+++ b/WallpaperPicker/res/values-fi/strings.xml
@@ -0,0 +1,36 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/*
+* Copyright (C) 2013 The Android Open Source Project
+*
+* Licensed under the Apache License, Version 2.0 (the "License");
+* you may not use this file except in compliance with the License.
+* You may obtain a copy of the License at
+*
+*      http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.
+*/
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="wallpaper_instructions" msgid="3524143401182707094">"Aseta taustakuva"</string>
+    <string name="image_load_fail" msgid="7538534580694411837">"Kuvan lataus epäonnistui"</string>
+    <string name="wallpaper_load_fail" msgid="4800700444605404650">"Kuvaa ei voitu ladata taustakuvaksi"</string>
+  <plurals name="number_of_items_selected">
+    <item quantity="zero" msgid="9015111147509924344">"%1$d valittu"</item>
+    <item quantity="one" msgid="8409622005831789373">"%1$d valittu"</item>
+    <item quantity="other" msgid="479468347731745357">"%1$d valittu"</item>
+  </plurals>
+    <string name="wallpaper_accessibility_name" msgid="4093221025304876354">"Taustakuva %1$d/%2$d"</string>
+    <string name="announce_selection" msgid="123723511662250539">"Valittu: <xliff:g id="LABEL">%1$s</xliff:g>"</string>
+    <string name="wallpaper_delete" msgid="1459353972739215344">"Poista"</string>
+    <string name="pick_image" msgid="6704438906027442697">"Valitse kuva"</string>
+    <string name="pick_wallpaper" msgid="4628969645948454559">"Taustakuvat"</string>
+    <string name="crop_wallpaper" msgid="4882870800623585836">"Rajaa taustakuva"</string>
+</resources>
diff --git a/WallpaperPicker/res/values-fr-rCA/strings.xml b/WallpaperPicker/res/values-fr-rCA/strings.xml
new file mode 100644
index 0000000..e956706
--- /dev/null
+++ b/WallpaperPicker/res/values-fr-rCA/strings.xml
@@ -0,0 +1,36 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/*
+* Copyright (C) 2013 The Android Open Source Project
+*
+* Licensed under the Apache License, Version 2.0 (the "License");
+* you may not use this file except in compliance with the License.
+* You may obtain a copy of the License at
+*
+*      http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.
+*/
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="wallpaper_instructions" msgid="3524143401182707094">"Définir le fond d\'écran"</string>
+    <string name="image_load_fail" msgid="7538534580694411837">"Impossible de charger l\'image"</string>
+    <string name="wallpaper_load_fail" msgid="4800700444605404650">"Impossible de charger l\'image comme fond d\'écran"</string>
+  <plurals name="number_of_items_selected">
+    <item quantity="zero" msgid="9015111147509924344">"%1$d sélectionné"</item>
+    <item quantity="one" msgid="8409622005831789373">"%1$d sélectionné"</item>
+    <item quantity="other" msgid="479468347731745357">"%1$d sélectionné(s)"</item>
+  </plurals>
+    <string name="wallpaper_accessibility_name" msgid="4093221025304876354">"Fond d\'écran %1$d de %2$d"</string>
+    <string name="announce_selection" msgid="123723511662250539">"Sélection : <xliff:g id="LABEL">%1$s</xliff:g>"</string>
+    <string name="wallpaper_delete" msgid="1459353972739215344">"Supprimer"</string>
+    <string name="pick_image" msgid="6704438906027442697">"Choisir une image"</string>
+    <string name="pick_wallpaper" msgid="4628969645948454559">"Fonds d\'écran"</string>
+    <string name="crop_wallpaper" msgid="4882870800623585836">"Rogner le fond d\'écran"</string>
+</resources>
diff --git a/WallpaperPicker/res/values-fr/strings.xml b/WallpaperPicker/res/values-fr/strings.xml
new file mode 100644
index 0000000..ea07db1
--- /dev/null
+++ b/WallpaperPicker/res/values-fr/strings.xml
@@ -0,0 +1,36 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/*
+* Copyright (C) 2013 The Android Open Source Project
+*
+* Licensed under the Apache License, Version 2.0 (the "License");
+* you may not use this file except in compliance with the License.
+* You may obtain a copy of the License at
+*
+*      http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.
+*/
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="wallpaper_instructions" msgid="3524143401182707094">"Définir comme fond d\'écran"</string>
+    <string name="image_load_fail" msgid="7538534580694411837">"Impossible de charger l\'image."</string>
+    <string name="wallpaper_load_fail" msgid="4800700444605404650">"Impossible de charger l\'image comme fond d\'écran."</string>
+  <plurals name="number_of_items_selected">
+    <item quantity="zero" msgid="9015111147509924344">"%1$d élément sélectionné"</item>
+    <item quantity="one" msgid="8409622005831789373">"%1$d élément sélectionné"</item>
+    <item quantity="other" msgid="479468347731745357">"%1$d éléments sélectionnés"</item>
+  </plurals>
+    <string name="wallpaper_accessibility_name" msgid="4093221025304876354">"Fond d\'écran %1$d sur %2$d"</string>
+    <string name="announce_selection" msgid="123723511662250539">"<xliff:g id="LABEL">%1$s</xliff:g> sélectionné"</string>
+    <string name="wallpaper_delete" msgid="1459353972739215344">"Supprimer"</string>
+    <string name="pick_image" msgid="6704438906027442697">"Sélectionner une image"</string>
+    <string name="pick_wallpaper" msgid="4628969645948454559">"Fonds d\'écran"</string>
+    <string name="crop_wallpaper" msgid="4882870800623585836">"Rogner le fond d\'écran"</string>
+</resources>
diff --git a/WallpaperPicker/res/values-hi/strings.xml b/WallpaperPicker/res/values-hi/strings.xml
new file mode 100644
index 0000000..fcb252e
--- /dev/null
+++ b/WallpaperPicker/res/values-hi/strings.xml
@@ -0,0 +1,36 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/*
+* Copyright (C) 2013 The Android Open Source Project
+*
+* Licensed under the Apache License, Version 2.0 (the "License");
+* you may not use this file except in compliance with the License.
+* You may obtain a copy of the License at
+*
+*      http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.
+*/
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="wallpaper_instructions" msgid="3524143401182707094">"वॉलपेपर सेट करें"</string>
+    <string name="image_load_fail" msgid="7538534580694411837">"चित्र लोड नहीं किया जा सका"</string>
+    <string name="wallpaper_load_fail" msgid="4800700444605404650">"चित्र को वॉलपेपर के रूप में लोड नहीं किया जा सका"</string>
+  <plurals name="number_of_items_selected">
+    <item quantity="zero" msgid="9015111147509924344">"%1$d चयनित"</item>
+    <item quantity="one" msgid="8409622005831789373">"%1$d चयनित"</item>
+    <item quantity="other" msgid="479468347731745357">"%1$d चयनित"</item>
+  </plurals>
+    <string name="wallpaper_accessibility_name" msgid="4093221025304876354">"वॉलपेपर %2$d में से %1$d"</string>
+    <string name="announce_selection" msgid="123723511662250539">"चयनित <xliff:g id="LABEL">%1$s</xliff:g>"</string>
+    <string name="wallpaper_delete" msgid="1459353972739215344">"हटाएं"</string>
+    <string name="pick_image" msgid="6704438906027442697">"चित्र चुनें"</string>
+    <string name="pick_wallpaper" msgid="4628969645948454559">"वॉलपेपर"</string>
+    <string name="crop_wallpaper" msgid="4882870800623585836">"वॉलपेपर काटें"</string>
+</resources>
diff --git a/WallpaperPicker/res/values-hr/strings.xml b/WallpaperPicker/res/values-hr/strings.xml
new file mode 100644
index 0000000..ff2eed2
--- /dev/null
+++ b/WallpaperPicker/res/values-hr/strings.xml
@@ -0,0 +1,36 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/*
+* Copyright (C) 2013 The Android Open Source Project
+*
+* Licensed under the Apache License, Version 2.0 (the "License");
+* you may not use this file except in compliance with the License.
+* You may obtain a copy of the License at
+*
+*      http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.
+*/
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="wallpaper_instructions" msgid="3524143401182707094">"Postavi pozadinsku sliku"</string>
+    <string name="image_load_fail" msgid="7538534580694411837">"Nije moguće učitati sliku"</string>
+    <string name="wallpaper_load_fail" msgid="4800700444605404650">"Nije moguće učitati sliku kao pozadinsku sliku"</string>
+  <plurals name="number_of_items_selected">
+    <item quantity="zero" msgid="9015111147509924344">"Odabrano je %1$d stavki"</item>
+    <item quantity="one" msgid="8409622005831789373">"Odabrana je %1$d stavka"</item>
+    <item quantity="other" msgid="479468347731745357">"Odabrano stavki: %1$d"</item>
+  </plurals>
+    <string name="wallpaper_accessibility_name" msgid="4093221025304876354">"%1$d. pozadinska slika od %2$d"</string>
+    <string name="announce_selection" msgid="123723511662250539">"Odabrana je <xliff:g id="LABEL">%1$s</xliff:g>"</string>
+    <string name="wallpaper_delete" msgid="1459353972739215344">"Izbriši"</string>
+    <string name="pick_image" msgid="6704438906027442697">"Odaberi sliku"</string>
+    <string name="pick_wallpaper" msgid="4628969645948454559">"Pozadinske slike"</string>
+    <string name="crop_wallpaper" msgid="4882870800623585836">"Obrezivanje pozadinske slike"</string>
+</resources>
diff --git a/WallpaperPicker/res/values-hu/strings.xml b/WallpaperPicker/res/values-hu/strings.xml
new file mode 100644
index 0000000..703aa12
--- /dev/null
+++ b/WallpaperPicker/res/values-hu/strings.xml
@@ -0,0 +1,36 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/*
+* Copyright (C) 2013 The Android Open Source Project
+*
+* Licensed under the Apache License, Version 2.0 (the "License");
+* you may not use this file except in compliance with the License.
+* You may obtain a copy of the License at
+*
+*      http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.
+*/
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="wallpaper_instructions" msgid="3524143401182707094">"Háttérkép beállítása"</string>
+    <string name="image_load_fail" msgid="7538534580694411837">"A kép betöltése nem sikerült"</string>
+    <string name="wallpaper_load_fail" msgid="4800700444605404650">"A kép betöltése háttérképként nem sikerült"</string>
+  <plurals name="number_of_items_selected">
+    <item quantity="zero" msgid="9015111147509924344">"%1$d kiválasztva"</item>
+    <item quantity="one" msgid="8409622005831789373">"%1$d kiválasztva"</item>
+    <item quantity="other" msgid="479468347731745357">"%1$d kiválasztva"</item>
+  </plurals>
+    <string name="wallpaper_accessibility_name" msgid="4093221025304876354">"%1$d/%2$d. háttérkép"</string>
+    <string name="announce_selection" msgid="123723511662250539">"<xliff:g id="LABEL">%1$s</xliff:g> kiválasztva"</string>
+    <string name="wallpaper_delete" msgid="1459353972739215344">"Törlés"</string>
+    <string name="pick_image" msgid="6704438906027442697">"Kép kiválasztása"</string>
+    <string name="pick_wallpaper" msgid="4628969645948454559">"Háttérképek"</string>
+    <string name="crop_wallpaper" msgid="4882870800623585836">"Háttérkép körbevágása"</string>
+</resources>
diff --git a/WallpaperPicker/res/values-hy-rAM/strings.xml b/WallpaperPicker/res/values-hy-rAM/strings.xml
new file mode 100644
index 0000000..f3891dd
--- /dev/null
+++ b/WallpaperPicker/res/values-hy-rAM/strings.xml
@@ -0,0 +1,36 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/*
+* Copyright (C) 2013 The Android Open Source Project
+*
+* Licensed under the Apache License, Version 2.0 (the "License");
+* you may not use this file except in compliance with the License.
+* You may obtain a copy of the License at
+*
+*      http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.
+*/
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="wallpaper_instructions" msgid="3524143401182707094">"Սահմանել պաստառը"</string>
+    <string name="image_load_fail" msgid="7538534580694411837">"Չհաջողվեց բեռնել նկարը"</string>
+    <string name="wallpaper_load_fail" msgid="4800700444605404650">"Չհաջողվեց նկարը սահմանել որպես պաստառ"</string>
+  <plurals name="number_of_items_selected">
+    <item quantity="zero" msgid="9015111147509924344">"%1$d ընտրված"</item>
+    <item quantity="one" msgid="8409622005831789373">"%1$d ընտրված"</item>
+    <item quantity="other" msgid="479468347731745357">"%1$d ընտրված"</item>
+  </plurals>
+    <string name="wallpaper_accessibility_name" msgid="4093221025304876354">"%1$d պաստառ՝ %2$d-ից"</string>
+    <string name="announce_selection" msgid="123723511662250539">"Ընտրված է <xliff:g id="LABEL">%1$s</xliff:g>"</string>
+    <string name="wallpaper_delete" msgid="1459353972739215344">"Ջնջել"</string>
+    <string name="pick_image" msgid="6704438906027442697">"Ընտրել պատկեր"</string>
+    <string name="pick_wallpaper" msgid="4628969645948454559">"Պաստառներ"</string>
+    <string name="crop_wallpaper" msgid="4882870800623585836">"Եզրատել պաստառը"</string>
+</resources>
diff --git a/WallpaperPicker/res/values-in/strings.xml b/WallpaperPicker/res/values-in/strings.xml
new file mode 100644
index 0000000..f216cf3
--- /dev/null
+++ b/WallpaperPicker/res/values-in/strings.xml
@@ -0,0 +1,36 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/*
+* Copyright (C) 2013 The Android Open Source Project
+*
+* Licensed under the Apache License, Version 2.0 (the "License");
+* you may not use this file except in compliance with the License.
+* You may obtain a copy of the License at
+*
+*      http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.
+*/
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="wallpaper_instructions" msgid="3524143401182707094">"Setel wallpaper"</string>
+    <string name="image_load_fail" msgid="7538534580694411837">"Tidak dapat memuat gambar"</string>
+    <string name="wallpaper_load_fail" msgid="4800700444605404650">"Tidak dapat memuat gambar sebagai wallpaper"</string>
+  <plurals name="number_of_items_selected">
+    <item quantity="zero" msgid="9015111147509924344">"%1$d dipilih"</item>
+    <item quantity="one" msgid="8409622005831789373">"%1$d dipilih"</item>
+    <item quantity="other" msgid="479468347731745357">"%1$d dipilih"</item>
+  </plurals>
+    <string name="wallpaper_accessibility_name" msgid="4093221025304876354">"Wallpaper %1$d dari %2$d"</string>
+    <string name="announce_selection" msgid="123723511662250539">"<xliff:g id="LABEL">%1$s</xliff:g> terpilih"</string>
+    <string name="wallpaper_delete" msgid="1459353972739215344">"Hapus"</string>
+    <string name="pick_image" msgid="6704438906027442697">"Pilih gambar"</string>
+    <string name="pick_wallpaper" msgid="4628969645948454559">"Wallpaper"</string>
+    <string name="crop_wallpaper" msgid="4882870800623585836">"Pangkas wallpaper"</string>
+</resources>
diff --git a/WallpaperPicker/res/values-it/strings.xml b/WallpaperPicker/res/values-it/strings.xml
new file mode 100644
index 0000000..c29946f
--- /dev/null
+++ b/WallpaperPicker/res/values-it/strings.xml
@@ -0,0 +1,36 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/*
+* Copyright (C) 2013 The Android Open Source Project
+*
+* Licensed under the Apache License, Version 2.0 (the "License");
+* you may not use this file except in compliance with the License.
+* You may obtain a copy of the License at
+*
+*      http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.
+*/
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="wallpaper_instructions" msgid="3524143401182707094">"Imposta sfondo"</string>
+    <string name="image_load_fail" msgid="7538534580694411837">"Impossibile caricare l\'immagine"</string>
+    <string name="wallpaper_load_fail" msgid="4800700444605404650">"Impossibile caricare l\'immagine come sfondo"</string>
+  <plurals name="number_of_items_selected">
+    <item quantity="zero" msgid="9015111147509924344">"%1$d selezionati"</item>
+    <item quantity="one" msgid="8409622005831789373">"%1$d selezionato"</item>
+    <item quantity="other" msgid="479468347731745357">"%1$d selezionati"</item>
+  </plurals>
+    <string name="wallpaper_accessibility_name" msgid="4093221025304876354">"Sfondo %1$d di %2$d"</string>
+    <string name="announce_selection" msgid="123723511662250539">"Elemento selezionato: <xliff:g id="LABEL">%1$s</xliff:g>"</string>
+    <string name="wallpaper_delete" msgid="1459353972739215344">"Elimina"</string>
+    <string name="pick_image" msgid="6704438906027442697">"Scegli l\'immagine"</string>
+    <string name="pick_wallpaper" msgid="4628969645948454559">"Sfondi"</string>
+    <string name="crop_wallpaper" msgid="4882870800623585836">"Ritaglia sfondo"</string>
+</resources>
diff --git a/WallpaperPicker/res/values-iw/strings.xml b/WallpaperPicker/res/values-iw/strings.xml
new file mode 100644
index 0000000..ddc96e9
--- /dev/null
+++ b/WallpaperPicker/res/values-iw/strings.xml
@@ -0,0 +1,36 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/*
+* Copyright (C) 2013 The Android Open Source Project
+*
+* Licensed under the Apache License, Version 2.0 (the "License");
+* you may not use this file except in compliance with the License.
+* You may obtain a copy of the License at
+*
+*      http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.
+*/
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="wallpaper_instructions" msgid="3524143401182707094">"הגדר טפט"</string>
+    <string name="image_load_fail" msgid="7538534580694411837">"לא ניתן היה לטעון את התמונה"</string>
+    <string name="wallpaper_load_fail" msgid="4800700444605404650">"לא ניתן היה לטעון את התמונה כטפט"</string>
+  <plurals name="number_of_items_selected">
+    <item quantity="zero" msgid="9015111147509924344">"‏%1$d נבחרו"</item>
+    <item quantity="one" msgid="8409622005831789373">"‏%1$d נבחרו"</item>
+    <item quantity="other" msgid="479468347731745357">"‏%1$d נבחרו"</item>
+  </plurals>
+    <string name="wallpaper_accessibility_name" msgid="4093221025304876354">"‏טפט %1$d מתוך %2$d"</string>
+    <string name="announce_selection" msgid="123723511662250539">"בחרת <xliff:g id="LABEL">%1$s</xliff:g>"</string>
+    <string name="wallpaper_delete" msgid="1459353972739215344">"מחק"</string>
+    <string name="pick_image" msgid="6704438906027442697">"בחר תמונה"</string>
+    <string name="pick_wallpaper" msgid="4628969645948454559">"טפטים"</string>
+    <string name="crop_wallpaper" msgid="4882870800623585836">"חתוך את הטפט"</string>
+</resources>
diff --git a/WallpaperPicker/res/values-ja/strings.xml b/WallpaperPicker/res/values-ja/strings.xml
new file mode 100644
index 0000000..80b0944
--- /dev/null
+++ b/WallpaperPicker/res/values-ja/strings.xml
@@ -0,0 +1,36 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/*
+* Copyright (C) 2013 The Android Open Source Project
+*
+* Licensed under the Apache License, Version 2.0 (the "License");
+* you may not use this file except in compliance with the License.
+* You may obtain a copy of the License at
+*
+*      http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.
+*/
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="wallpaper_instructions" msgid="3524143401182707094">"壁紙を設定"</string>
+    <string name="image_load_fail" msgid="7538534580694411837">"画像を読み込めませんでした"</string>
+    <string name="wallpaper_load_fail" msgid="4800700444605404650">"画像を壁紙として読み込めませんでした"</string>
+  <plurals name="number_of_items_selected">
+    <item quantity="zero" msgid="9015111147509924344">"%1$d個選択済み"</item>
+    <item quantity="one" msgid="8409622005831789373">"%1$d個選択済み"</item>
+    <item quantity="other" msgid="479468347731745357">"%1$d個選択済み"</item>
+  </plurals>
+    <string name="wallpaper_accessibility_name" msgid="4093221025304876354">"壁紙: %1$d/%2$d"</string>
+    <string name="announce_selection" msgid="123723511662250539">"選択: <xliff:g id="LABEL">%1$s</xliff:g>"</string>
+    <string name="wallpaper_delete" msgid="1459353972739215344">"削除"</string>
+    <string name="pick_image" msgid="6704438906027442697">"画像を選択"</string>
+    <string name="pick_wallpaper" msgid="4628969645948454559">"壁紙"</string>
+    <string name="crop_wallpaper" msgid="4882870800623585836">"壁紙のトリミング"</string>
+</resources>
diff --git a/WallpaperPicker/res/values-ka-rGE/strings.xml b/WallpaperPicker/res/values-ka-rGE/strings.xml
new file mode 100644
index 0000000..2f59712
--- /dev/null
+++ b/WallpaperPicker/res/values-ka-rGE/strings.xml
@@ -0,0 +1,36 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/*
+* Copyright (C) 2013 The Android Open Source Project
+*
+* Licensed under the Apache License, Version 2.0 (the "License");
+* you may not use this file except in compliance with the License.
+* You may obtain a copy of the License at
+*
+*      http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.
+*/
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="wallpaper_instructions" msgid="3524143401182707094">"ფონის დაყენება"</string>
+    <string name="image_load_fail" msgid="7538534580694411837">"სურათი ვერ ჩაიტვირთა."</string>
+    <string name="wallpaper_load_fail" msgid="4800700444605404650">"სურათი ფონად ვერ ჩაიტვირთა."</string>
+  <plurals name="number_of_items_selected">
+    <item quantity="zero" msgid="9015111147509924344">"არჩეულია %1$d"</item>
+    <item quantity="one" msgid="8409622005831789373">"არჩეულია %1$d"</item>
+    <item quantity="other" msgid="479468347731745357">"არჩეულია %1$d"</item>
+  </plurals>
+    <string name="wallpaper_accessibility_name" msgid="4093221025304876354">"ფონი %1$d %2$d-დან"</string>
+    <string name="announce_selection" msgid="123723511662250539">"არჩეული <xliff:g id="LABEL">%1$s</xliff:g>"</string>
+    <string name="wallpaper_delete" msgid="1459353972739215344">"წაშლა"</string>
+    <string name="pick_image" msgid="6704438906027442697">"სურათის ამორჩევა"</string>
+    <string name="pick_wallpaper" msgid="4628969645948454559">"ფონები"</string>
+    <string name="crop_wallpaper" msgid="4882870800623585836">"ფონის ჩამოჭრა"</string>
+</resources>
diff --git a/WallpaperPicker/res/values-km-rKH/strings.xml b/WallpaperPicker/res/values-km-rKH/strings.xml
new file mode 100644
index 0000000..4172235
--- /dev/null
+++ b/WallpaperPicker/res/values-km-rKH/strings.xml
@@ -0,0 +1,36 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/*
+* Copyright (C) 2013 The Android Open Source Project
+*
+* Licensed under the Apache License, Version 2.0 (the "License");
+* you may not use this file except in compliance with the License.
+* You may obtain a copy of the License at
+*
+*      http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.
+*/
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="wallpaper_instructions" msgid="3524143401182707094">"កំណត់​ផ្ទាំង​រូបភាព"</string>
+    <string name="image_load_fail" msgid="7538534580694411837">"មិន​អាច​ផ្ទុក​រូបភាព"</string>
+    <string name="wallpaper_load_fail" msgid="4800700444605404650">"មិន​អាច​ផ្ទុក​រូបភាព​ជា​ផ្ទាំង​រូបភាព"</string>
+  <plurals name="number_of_items_selected">
+    <item quantity="zero" msgid="9015111147509924344">"បាន​ជ្រើស %1$d"</item>
+    <item quantity="one" msgid="8409622005831789373">"បាន​ជ្រើស %1$d"</item>
+    <item quantity="other" msgid="479468347731745357">"បាន​ជ្រើស %1$d"</item>
+  </plurals>
+    <string name="wallpaper_accessibility_name" msgid="4093221025304876354">"ផ្ទាំង​រូបភាព %1$d នៃ %2$d"</string>
+    <string name="announce_selection" msgid="123723511662250539">"បាន​ជ្រើស <xliff:g id="LABEL">%1$s</xliff:g>"</string>
+    <string name="wallpaper_delete" msgid="1459353972739215344">"លុប"</string>
+    <string name="pick_image" msgid="6704438906027442697">"ជ្រើស​យក​រូបភាព"</string>
+    <string name="pick_wallpaper" msgid="4628969645948454559">"ផ្ទាំង​រូបភាព"</string>
+    <string name="crop_wallpaper" msgid="4882870800623585836">"ច្រឹប​ផ្ទាំង​រូបភាព"</string>
+</resources>
diff --git a/WallpaperPicker/res/values-ko/strings.xml b/WallpaperPicker/res/values-ko/strings.xml
new file mode 100644
index 0000000..a5a85b7
--- /dev/null
+++ b/WallpaperPicker/res/values-ko/strings.xml
@@ -0,0 +1,36 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/*
+* Copyright (C) 2013 The Android Open Source Project
+*
+* Licensed under the Apache License, Version 2.0 (the "License");
+* you may not use this file except in compliance with the License.
+* You may obtain a copy of the License at
+*
+*      http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.
+*/
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="wallpaper_instructions" msgid="3524143401182707094">"배경화면 설정"</string>
+    <string name="image_load_fail" msgid="7538534580694411837">"이미지를 로드할 수 없습니다."</string>
+    <string name="wallpaper_load_fail" msgid="4800700444605404650">"이미지를 배경화면으로 로드할 수 없습니다."</string>
+  <plurals name="number_of_items_selected">
+    <item quantity="zero" msgid="9015111147509924344">"%1$d개 선택됨"</item>
+    <item quantity="one" msgid="8409622005831789373">"%1$d개 선택됨"</item>
+    <item quantity="other" msgid="479468347731745357">"%1$d개 선택됨"</item>
+  </plurals>
+    <string name="wallpaper_accessibility_name" msgid="4093221025304876354">"배경화면 %1$d/%2$d"</string>
+    <string name="announce_selection" msgid="123723511662250539">"<xliff:g id="LABEL">%1$s</xliff:g> 선택함"</string>
+    <string name="wallpaper_delete" msgid="1459353972739215344">"삭제"</string>
+    <string name="pick_image" msgid="6704438906027442697">"이미지 선택"</string>
+    <string name="pick_wallpaper" msgid="4628969645948454559">"배경화면"</string>
+    <string name="crop_wallpaper" msgid="4882870800623585836">"배경화면 잘라내기"</string>
+</resources>
diff --git a/WallpaperPicker/res/values-lo-rLA/strings.xml b/WallpaperPicker/res/values-lo-rLA/strings.xml
new file mode 100644
index 0000000..e468591
--- /dev/null
+++ b/WallpaperPicker/res/values-lo-rLA/strings.xml
@@ -0,0 +1,36 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/*
+* Copyright (C) 2013 The Android Open Source Project
+*
+* Licensed under the Apache License, Version 2.0 (the "License");
+* you may not use this file except in compliance with the License.
+* You may obtain a copy of the License at
+*
+*      http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.
+*/
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="wallpaper_instructions" msgid="3524143401182707094">"ຕັ້ງເປັນພາບພື້ນຫຼັງ"</string>
+    <string name="image_load_fail" msgid="7538534580694411837">"ບໍ່ສາມາດໂຫຼດຮູບໄດ້"</string>
+    <string name="wallpaper_load_fail" msgid="4800700444605404650">"ບໍ່ສາມາດໂຫຼດຮູບເປັນພາບພື້ນຫຼັງໄດ້"</string>
+  <plurals name="number_of_items_selected">
+    <item quantity="zero" msgid="9015111147509924344">"ເລືອກ %1$d"</item>
+    <item quantity="one" msgid="8409622005831789373">"ເລືອກ %1$d"</item>
+    <item quantity="other" msgid="479468347731745357">"ເລືອກ %1$d"</item>
+  </plurals>
+    <string name="wallpaper_accessibility_name" msgid="4093221025304876354">"ພາບພື້ນຫຼັງ %1$d ໃນ %2$d"</string>
+    <string name="announce_selection" msgid="123723511662250539">"ເລືອກ <xliff:g id="LABEL">%1$s</xliff:g>"</string>
+    <string name="wallpaper_delete" msgid="1459353972739215344">"ລຶບ"</string>
+    <string name="pick_image" msgid="6704438906027442697">"ເລືອກ​ຮູບ​ພາບ"</string>
+    <string name="pick_wallpaper" msgid="4628969645948454559">"ພາບພື້ນຫຼັງ"</string>
+    <string name="crop_wallpaper" msgid="4882870800623585836">"ຕັດພາບພື້ນຫຼັງ"</string>
+</resources>
diff --git a/WallpaperPicker/res/values-lt/strings.xml b/WallpaperPicker/res/values-lt/strings.xml
new file mode 100644
index 0000000..86035b8
--- /dev/null
+++ b/WallpaperPicker/res/values-lt/strings.xml
@@ -0,0 +1,36 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/*
+* Copyright (C) 2013 The Android Open Source Project
+*
+* Licensed under the Apache License, Version 2.0 (the "License");
+* you may not use this file except in compliance with the License.
+* You may obtain a copy of the License at
+*
+*      http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.
+*/
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="wallpaper_instructions" msgid="3524143401182707094">"Nustatyti ekrano foną"</string>
+    <string name="image_load_fail" msgid="7538534580694411837">"Nepavyko įkelti vaizdo"</string>
+    <string name="wallpaper_load_fail" msgid="4800700444605404650">"Nepavyko įkelti vaizdo kaip ekrano fono"</string>
+  <plurals name="number_of_items_selected">
+    <item quantity="zero" msgid="9015111147509924344">"Pasirinkta: %1$d"</item>
+    <item quantity="one" msgid="8409622005831789373">"Pasirinkta: %1$d"</item>
+    <item quantity="other" msgid="479468347731745357">"Pasirinkta: %1$d"</item>
+  </plurals>
+    <string name="wallpaper_accessibility_name" msgid="4093221025304876354">"%1$d ekrano fonas iš %2$d"</string>
+    <string name="announce_selection" msgid="123723511662250539">"Pasirinkta: <xliff:g id="LABEL">%1$s</xliff:g>"</string>
+    <string name="wallpaper_delete" msgid="1459353972739215344">"Ištrinti"</string>
+    <string name="pick_image" msgid="6704438906027442697">"Pasirinkti vaizdą"</string>
+    <string name="pick_wallpaper" msgid="4628969645948454559">"Ekrano fonai"</string>
+    <string name="crop_wallpaper" msgid="4882870800623585836">"Apkirpti ekrano foną"</string>
+</resources>
diff --git a/WallpaperPicker/res/values-lv/strings.xml b/WallpaperPicker/res/values-lv/strings.xml
new file mode 100644
index 0000000..02e5cfb
--- /dev/null
+++ b/WallpaperPicker/res/values-lv/strings.xml
@@ -0,0 +1,36 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/*
+* Copyright (C) 2013 The Android Open Source Project
+*
+* Licensed under the Apache License, Version 2.0 (the "License");
+* you may not use this file except in compliance with the License.
+* You may obtain a copy of the License at
+*
+*      http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.
+*/
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="wallpaper_instructions" msgid="3524143401182707094">"Iestatīt fona tapeti"</string>
+    <string name="image_load_fail" msgid="7538534580694411837">"Nevarēja ielādēt attēlu."</string>
+    <string name="wallpaper_load_fail" msgid="4800700444605404650">"Nevarēja ielādēt attēlu kā fona tapeti."</string>
+  <plurals name="number_of_items_selected">
+    <item quantity="zero" msgid="9015111147509924344">"Atlasīts: %1$d"</item>
+    <item quantity="one" msgid="8409622005831789373">"Atlasīta: %1$d"</item>
+    <item quantity="other" msgid="479468347731745357">"Atlasītas: %1$d"</item>
+  </plurals>
+    <string name="wallpaper_accessibility_name" msgid="4093221025304876354">"%1$d. fona tapete no %2$d"</string>
+    <string name="announce_selection" msgid="123723511662250539">"Atlasīta: <xliff:g id="LABEL">%1$s</xliff:g>"</string>
+    <string name="wallpaper_delete" msgid="1459353972739215344">"Dzēst"</string>
+    <string name="pick_image" msgid="6704438906027442697">"Izvēlēties attēlu"</string>
+    <string name="pick_wallpaper" msgid="4628969645948454559">"Fona tapetes"</string>
+    <string name="crop_wallpaper" msgid="4882870800623585836">"Apgriezt fona tapeti"</string>
+</resources>
diff --git a/WallpaperPicker/res/values-mn-rMN/strings.xml b/WallpaperPicker/res/values-mn-rMN/strings.xml
new file mode 100644
index 0000000..71ff9e0
--- /dev/null
+++ b/WallpaperPicker/res/values-mn-rMN/strings.xml
@@ -0,0 +1,36 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/*
+* Copyright (C) 2013 The Android Open Source Project
+*
+* Licensed under the Apache License, Version 2.0 (the "License");
+* you may not use this file except in compliance with the License.
+* You may obtain a copy of the License at
+*
+*      http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.
+*/
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="wallpaper_instructions" msgid="3524143401182707094">"Ханын зургийг тохируулах"</string>
+    <string name="image_load_fail" msgid="7538534580694411837">"Зургийг ачаалж чадсангүй"</string>
+    <string name="wallpaper_load_fail" msgid="4800700444605404650">"Зургийг ханын зураг болгож ачаалж чадсангүй"</string>
+  <plurals name="number_of_items_selected">
+    <item quantity="zero" msgid="9015111147509924344">"%1$d сонгогдсон"</item>
+    <item quantity="one" msgid="8409622005831789373">"%1$d сонгогдсон"</item>
+    <item quantity="other" msgid="479468347731745357">"%1$d сонгогдсон"</item>
+  </plurals>
+    <string name="wallpaper_accessibility_name" msgid="4093221025304876354">"%2$d ханын цаасны %1$d нь"</string>
+    <string name="announce_selection" msgid="123723511662250539">"<xliff:g id="LABEL">%1$s</xliff:g> сонгогдсон"</string>
+    <string name="wallpaper_delete" msgid="1459353972739215344">"Устгах"</string>
+    <string name="pick_image" msgid="6704438906027442697">"Зураг сонгох"</string>
+    <string name="pick_wallpaper" msgid="4628969645948454559">"Ханын зураг"</string>
+    <string name="crop_wallpaper" msgid="4882870800623585836">"Ханын зургийг тайрах"</string>
+</resources>
diff --git a/WallpaperPicker/res/values-ms-rMY/strings.xml b/WallpaperPicker/res/values-ms-rMY/strings.xml
new file mode 100644
index 0000000..950f4d0
--- /dev/null
+++ b/WallpaperPicker/res/values-ms-rMY/strings.xml
@@ -0,0 +1,36 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/*
+* Copyright (C) 2013 The Android Open Source Project
+*
+* Licensed under the Apache License, Version 2.0 (the "License");
+* you may not use this file except in compliance with the License.
+* You may obtain a copy of the License at
+*
+*      http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.
+*/
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="wallpaper_instructions" msgid="3524143401182707094">"Tetapkan kertas dinding"</string>
+    <string name="image_load_fail" msgid="7538534580694411837">"Tidak dapat memuatkan imej"</string>
+    <string name="wallpaper_load_fail" msgid="4800700444605404650">"Tidak dapat memuatkan imej sebagai kertas dinding"</string>
+  <plurals name="number_of_items_selected">
+    <item quantity="zero" msgid="9015111147509924344">"%1$d dipilih"</item>
+    <item quantity="one" msgid="8409622005831789373">"%1$d dipilih"</item>
+    <item quantity="other" msgid="479468347731745357">"%1$d dipilih"</item>
+  </plurals>
+    <string name="wallpaper_accessibility_name" msgid="4093221025304876354">"Kertas dinding %1$d daripada %2$d"</string>
+    <string name="announce_selection" msgid="123723511662250539">"Memilih <xliff:g id="LABEL">%1$s</xliff:g>"</string>
+    <string name="wallpaper_delete" msgid="1459353972739215344">"Padam"</string>
+    <string name="pick_image" msgid="6704438906027442697">"Pilih imej"</string>
+    <string name="pick_wallpaper" msgid="4628969645948454559">"Kertas dinding"</string>
+    <string name="crop_wallpaper" msgid="4882870800623585836">"Pangkas kertas dinding"</string>
+</resources>
diff --git a/WallpaperPicker/res/values-nb/strings.xml b/WallpaperPicker/res/values-nb/strings.xml
new file mode 100644
index 0000000..3589e4b
--- /dev/null
+++ b/WallpaperPicker/res/values-nb/strings.xml
@@ -0,0 +1,36 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/*
+* Copyright (C) 2013 The Android Open Source Project
+*
+* Licensed under the Apache License, Version 2.0 (the "License");
+* you may not use this file except in compliance with the License.
+* You may obtain a copy of the License at
+*
+*      http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.
+*/
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="wallpaper_instructions" msgid="3524143401182707094">"Angi bakgrunn"</string>
+    <string name="image_load_fail" msgid="7538534580694411837">"Kunne ikke laste inn bildet"</string>
+    <string name="wallpaper_load_fail" msgid="4800700444605404650">"Kunne ikke laste inn bildet som bakgrunn"</string>
+  <plurals name="number_of_items_selected">
+    <item quantity="zero" msgid="9015111147509924344">"%1$d valgt"</item>
+    <item quantity="one" msgid="8409622005831789373">"%1$d valgt"</item>
+    <item quantity="other" msgid="479468347731745357">"%1$d valgt"</item>
+  </plurals>
+    <string name="wallpaper_accessibility_name" msgid="4093221025304876354">"Bakgrunn %1$d av %2$d"</string>
+    <string name="announce_selection" msgid="123723511662250539">"Valgt <xliff:g id="LABEL">%1$s</xliff:g>"</string>
+    <string name="wallpaper_delete" msgid="1459353972739215344">"Slett"</string>
+    <string name="pick_image" msgid="6704438906027442697">"Velg bilde"</string>
+    <string name="pick_wallpaper" msgid="4628969645948454559">"Bakgrunner"</string>
+    <string name="crop_wallpaper" msgid="4882870800623585836">"Beskjær bakgrunnen"</string>
+</resources>
diff --git a/WallpaperPicker/res/values-nl/strings.xml b/WallpaperPicker/res/values-nl/strings.xml
new file mode 100644
index 0000000..7dd4f22
--- /dev/null
+++ b/WallpaperPicker/res/values-nl/strings.xml
@@ -0,0 +1,36 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/*
+* Copyright (C) 2013 The Android Open Source Project
+*
+* Licensed under the Apache License, Version 2.0 (the "License");
+* you may not use this file except in compliance with the License.
+* You may obtain a copy of the License at
+*
+*      http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.
+*/
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="wallpaper_instructions" msgid="3524143401182707094">"Achtergrond instellen"</string>
+    <string name="image_load_fail" msgid="7538534580694411837">"Kan afbeelding niet laden"</string>
+    <string name="wallpaper_load_fail" msgid="4800700444605404650">"Kan afbeelding niet laden als achtergrond"</string>
+  <plurals name="number_of_items_selected">
+    <item quantity="zero" msgid="9015111147509924344">"%1$d geselecteerd"</item>
+    <item quantity="one" msgid="8409622005831789373">"%1$d geselecteerd"</item>
+    <item quantity="other" msgid="479468347731745357">"%1$d geselecteerd"</item>
+  </plurals>
+    <string name="wallpaper_accessibility_name" msgid="4093221025304876354">"Achtergrond %1$d van %2$d"</string>
+    <string name="announce_selection" msgid="123723511662250539">"<xliff:g id="LABEL">%1$s</xliff:g> is geselecteerd"</string>
+    <string name="wallpaper_delete" msgid="1459353972739215344">"Verwijderen"</string>
+    <string name="pick_image" msgid="6704438906027442697">"Afbeelding kiezen"</string>
+    <string name="pick_wallpaper" msgid="4628969645948454559">"Achtergronden"</string>
+    <string name="crop_wallpaper" msgid="4882870800623585836">"Achtergrond bijsnijden"</string>
+</resources>
diff --git a/res/values-nodpi/wallpapers.xml b/WallpaperPicker/res/values-nodpi/wallpapers.xml
similarity index 100%
rename from res/values-nodpi/wallpapers.xml
rename to WallpaperPicker/res/values-nodpi/wallpapers.xml
diff --git a/WallpaperPicker/res/values-pl/strings.xml b/WallpaperPicker/res/values-pl/strings.xml
new file mode 100644
index 0000000..bcdbb3d
--- /dev/null
+++ b/WallpaperPicker/res/values-pl/strings.xml
@@ -0,0 +1,36 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/*
+* Copyright (C) 2013 The Android Open Source Project
+*
+* Licensed under the Apache License, Version 2.0 (the "License");
+* you may not use this file except in compliance with the License.
+* You may obtain a copy of the License at
+*
+*      http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.
+*/
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="wallpaper_instructions" msgid="3524143401182707094">"Ustaw tapetę"</string>
+    <string name="image_load_fail" msgid="7538534580694411837">"Nie udało się załadować obrazu"</string>
+    <string name="wallpaper_load_fail" msgid="4800700444605404650">"Nie udało się załadować obrazu jako tapety"</string>
+  <plurals name="number_of_items_selected">
+    <item quantity="zero" msgid="9015111147509924344">"Wybranych %1$d"</item>
+    <item quantity="one" msgid="8409622005831789373">"Wybrana %1$d"</item>
+    <item quantity="other" msgid="479468347731745357">"Wybrane: %1$d"</item>
+  </plurals>
+    <string name="wallpaper_accessibility_name" msgid="4093221025304876354">"Tapeta %1$d z %2$d"</string>
+    <string name="announce_selection" msgid="123723511662250539">"Wybrano <xliff:g id="LABEL">%1$s</xliff:g>"</string>
+    <string name="wallpaper_delete" msgid="1459353972739215344">"Usuń"</string>
+    <string name="pick_image" msgid="6704438906027442697">"Wybierz obraz"</string>
+    <string name="pick_wallpaper" msgid="4628969645948454559">"Tapety"</string>
+    <string name="crop_wallpaper" msgid="4882870800623585836">"Przytnij tapetę"</string>
+</resources>
diff --git a/WallpaperPicker/res/values-pt-rPT/strings.xml b/WallpaperPicker/res/values-pt-rPT/strings.xml
new file mode 100644
index 0000000..8349232
--- /dev/null
+++ b/WallpaperPicker/res/values-pt-rPT/strings.xml
@@ -0,0 +1,36 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/*
+* Copyright (C) 2013 The Android Open Source Project
+*
+* Licensed under the Apache License, Version 2.0 (the "License");
+* you may not use this file except in compliance with the License.
+* You may obtain a copy of the License at
+*
+*      http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.
+*/
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="wallpaper_instructions" msgid="3524143401182707094">"Definir imagem fundo"</string>
+    <string name="image_load_fail" msgid="7538534580694411837">"Não foi possível carregar a imagem"</string>
+    <string name="wallpaper_load_fail" msgid="4800700444605404650">"Não foi possível carregar a imagem como imagem de fundo"</string>
+  <plurals name="number_of_items_selected">
+    <item quantity="zero" msgid="9015111147509924344">"%1$d selecionadas"</item>
+    <item quantity="one" msgid="8409622005831789373">"%1$d selecionada"</item>
+    <item quantity="other" msgid="479468347731745357">"%1$d selecionadas"</item>
+  </plurals>
+    <string name="wallpaper_accessibility_name" msgid="4093221025304876354">"Imagem de fundo %1$d de %2$d"</string>
+    <string name="announce_selection" msgid="123723511662250539">"<xliff:g id="LABEL">%1$s</xliff:g> selecionada"</string>
+    <string name="wallpaper_delete" msgid="1459353972739215344">"Eliminar"</string>
+    <string name="pick_image" msgid="6704438906027442697">"Escolher imagem"</string>
+    <string name="pick_wallpaper" msgid="4628969645948454559">"Imagens de fundo"</string>
+    <string name="crop_wallpaper" msgid="4882870800623585836">"Recortar imagem de fundo"</string>
+</resources>
diff --git a/WallpaperPicker/res/values-pt/strings.xml b/WallpaperPicker/res/values-pt/strings.xml
new file mode 100644
index 0000000..2332fcb
--- /dev/null
+++ b/WallpaperPicker/res/values-pt/strings.xml
@@ -0,0 +1,36 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/*
+* Copyright (C) 2013 The Android Open Source Project
+*
+* Licensed under the Apache License, Version 2.0 (the "License");
+* you may not use this file except in compliance with the License.
+* You may obtain a copy of the License at
+*
+*      http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.
+*/
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="wallpaper_instructions" msgid="3524143401182707094">"Definir plano de fundo"</string>
+    <string name="image_load_fail" msgid="7538534580694411837">"Não foi possível carregar a imagem"</string>
+    <string name="wallpaper_load_fail" msgid="4800700444605404650">"Não foi possível carregar a imagem como plano de fundo"</string>
+  <plurals name="number_of_items_selected">
+    <item quantity="zero" msgid="9015111147509924344">"%1$d selecionados"</item>
+    <item quantity="one" msgid="8409622005831789373">"%1$d selecionado"</item>
+    <item quantity="other" msgid="479468347731745357">"%1$d selecionados"</item>
+  </plurals>
+    <string name="wallpaper_accessibility_name" msgid="4093221025304876354">"Plano de fundo %1$d de %2$d"</string>
+    <string name="announce_selection" msgid="123723511662250539">"<xliff:g id="LABEL">%1$s</xliff:g> selecionado"</string>
+    <string name="wallpaper_delete" msgid="1459353972739215344">"Excluir"</string>
+    <string name="pick_image" msgid="6704438906027442697">"Escolher imagem"</string>
+    <string name="pick_wallpaper" msgid="4628969645948454559">"Planos de fundo"</string>
+    <string name="crop_wallpaper" msgid="4882870800623585836">"Cortar plano de fundo"</string>
+</resources>
diff --git a/WallpaperPicker/res/values-ro/strings.xml b/WallpaperPicker/res/values-ro/strings.xml
new file mode 100644
index 0000000..8ee1a5a
--- /dev/null
+++ b/WallpaperPicker/res/values-ro/strings.xml
@@ -0,0 +1,36 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/*
+* Copyright (C) 2013 The Android Open Source Project
+*
+* Licensed under the Apache License, Version 2.0 (the "License");
+* you may not use this file except in compliance with the License.
+* You may obtain a copy of the License at
+*
+*      http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.
+*/
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="wallpaper_instructions" msgid="3524143401182707094">"Setați imaginea de fundal"</string>
+    <string name="image_load_fail" msgid="7538534580694411837">"Nu s-a putut încărca imaginea"</string>
+    <string name="wallpaper_load_fail" msgid="4800700444605404650">"Nu s-a putut încărca imaginea ca fundal"</string>
+  <plurals name="number_of_items_selected">
+    <item quantity="zero" msgid="9015111147509924344">"%1$d selectate"</item>
+    <item quantity="one" msgid="8409622005831789373">"%1$d selectată"</item>
+    <item quantity="other" msgid="479468347731745357">"%1$d selectate"</item>
+  </plurals>
+    <string name="wallpaper_accessibility_name" msgid="4093221025304876354">"Imaginea de fundal %1$d din %2$d"</string>
+    <string name="announce_selection" msgid="123723511662250539">"S-a selectat <xliff:g id="LABEL">%1$s</xliff:g>"</string>
+    <string name="wallpaper_delete" msgid="1459353972739215344">"Ștergeți"</string>
+    <string name="pick_image" msgid="6704438906027442697">"Alegeți imaginea"</string>
+    <string name="pick_wallpaper" msgid="4628969645948454559">"Imagini de fundal"</string>
+    <string name="crop_wallpaper" msgid="4882870800623585836">"Decupați imaginea de fundal"</string>
+</resources>
diff --git a/WallpaperPicker/res/values-ru/strings.xml b/WallpaperPicker/res/values-ru/strings.xml
new file mode 100644
index 0000000..ff43ce8
--- /dev/null
+++ b/WallpaperPicker/res/values-ru/strings.xml
@@ -0,0 +1,36 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/*
+* Copyright (C) 2013 The Android Open Source Project
+*
+* Licensed under the Apache License, Version 2.0 (the "License");
+* you may not use this file except in compliance with the License.
+* You may obtain a copy of the License at
+*
+*      http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.
+*/
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="wallpaper_instructions" msgid="3524143401182707094">"Установить как обои"</string>
+    <string name="image_load_fail" msgid="7538534580694411837">"Не удалось загрузить изображение"</string>
+    <string name="wallpaper_load_fail" msgid="4800700444605404650">"Не удалось загрузить изображение"</string>
+  <plurals name="number_of_items_selected">
+    <item quantity="zero" msgid="9015111147509924344">"Выбрано: %1$d"</item>
+    <item quantity="one" msgid="8409622005831789373">"Выбрано: %1$d"</item>
+    <item quantity="other" msgid="479468347731745357">"Выбрано: %1$d"</item>
+  </plurals>
+    <string name="wallpaper_accessibility_name" msgid="4093221025304876354">"Обои %1$d из %2$d"</string>
+    <string name="announce_selection" msgid="123723511662250539">"Выбран элемент \"<xliff:g id="LABEL">%1$s</xliff:g>\""</string>
+    <string name="wallpaper_delete" msgid="1459353972739215344">"Удалить"</string>
+    <string name="pick_image" msgid="6704438906027442697">"Выбрать обои"</string>
+    <string name="pick_wallpaper" msgid="4628969645948454559">"Обои"</string>
+    <string name="crop_wallpaper" msgid="4882870800623585836">"Кадрировать обои"</string>
+</resources>
diff --git a/WallpaperPicker/res/values-sk/strings.xml b/WallpaperPicker/res/values-sk/strings.xml
new file mode 100644
index 0000000..33477a1
--- /dev/null
+++ b/WallpaperPicker/res/values-sk/strings.xml
@@ -0,0 +1,36 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/*
+* Copyright (C) 2013 The Android Open Source Project
+*
+* Licensed under the Apache License, Version 2.0 (the "License");
+* you may not use this file except in compliance with the License.
+* You may obtain a copy of the License at
+*
+*      http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.
+*/
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="wallpaper_instructions" msgid="3524143401182707094">"Nastaviť tapetu"</string>
+    <string name="image_load_fail" msgid="7538534580694411837">"Obrázok nie je možné načítať"</string>
+    <string name="wallpaper_load_fail" msgid="4800700444605404650">"Obrázok nie je možné načítať ako tapetu"</string>
+  <plurals name="number_of_items_selected">
+    <item quantity="zero" msgid="9015111147509924344">"Počet vybratých položiek: %1$d"</item>
+    <item quantity="one" msgid="8409622005831789373">"Počet vybratých položiek: %1$d"</item>
+    <item quantity="other" msgid="479468347731745357">"Počet vybratých položiek: %1$d"</item>
+  </plurals>
+    <string name="wallpaper_accessibility_name" msgid="4093221025304876354">"Tapeta %1$d z %2$d"</string>
+    <string name="announce_selection" msgid="123723511662250539">"Vybratá položka <xliff:g id="LABEL">%1$s</xliff:g>"</string>
+    <string name="wallpaper_delete" msgid="1459353972739215344">"Odstrániť"</string>
+    <string name="pick_image" msgid="6704438906027442697">"Vybrať obrázok"</string>
+    <string name="pick_wallpaper" msgid="4628969645948454559">"Tapety"</string>
+    <string name="crop_wallpaper" msgid="4882870800623585836">"Orezanie tapety"</string>
+</resources>
diff --git a/WallpaperPicker/res/values-sl/strings.xml b/WallpaperPicker/res/values-sl/strings.xml
new file mode 100644
index 0000000..06a508a
--- /dev/null
+++ b/WallpaperPicker/res/values-sl/strings.xml
@@ -0,0 +1,36 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/*
+* Copyright (C) 2013 The Android Open Source Project
+*
+* Licensed under the Apache License, Version 2.0 (the "License");
+* you may not use this file except in compliance with the License.
+* You may obtain a copy of the License at
+*
+*      http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.
+*/
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="wallpaper_instructions" msgid="3524143401182707094">"Nastavi ozadje"</string>
+    <string name="image_load_fail" msgid="7538534580694411837">"Slike ni bilo mogoče naložiti"</string>
+    <string name="wallpaper_load_fail" msgid="4800700444605404650">"Slike ni bilo mogoče naložiti kot ozadje"</string>
+  <plurals name="number_of_items_selected">
+    <item quantity="zero" msgid="9015111147509924344">"Št. izbranih: %1$d"</item>
+    <item quantity="one" msgid="8409622005831789373">"Št. izbranih: %1$d"</item>
+    <item quantity="other" msgid="479468347731745357">"Št. izbranih: %1$d"</item>
+  </plurals>
+    <string name="wallpaper_accessibility_name" msgid="4093221025304876354">"%1$d. ozadje od %2$d"</string>
+    <string name="announce_selection" msgid="123723511662250539">"Izbrano: <xliff:g id="LABEL">%1$s</xliff:g>"</string>
+    <string name="wallpaper_delete" msgid="1459353972739215344">"Izbriši"</string>
+    <string name="pick_image" msgid="6704438906027442697">"Izberi sliko"</string>
+    <string name="pick_wallpaper" msgid="4628969645948454559">"Ozadja"</string>
+    <string name="crop_wallpaper" msgid="4882870800623585836">"Obrezovanje ozadja"</string>
+</resources>
diff --git a/WallpaperPicker/res/values-sr/strings.xml b/WallpaperPicker/res/values-sr/strings.xml
new file mode 100644
index 0000000..fdfaaf6
--- /dev/null
+++ b/WallpaperPicker/res/values-sr/strings.xml
@@ -0,0 +1,36 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/*
+* Copyright (C) 2013 The Android Open Source Project
+*
+* Licensed under the Apache License, Version 2.0 (the "License");
+* you may not use this file except in compliance with the License.
+* You may obtain a copy of the License at
+*
+*      http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.
+*/
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="wallpaper_instructions" msgid="3524143401182707094">"Подеси позадину"</string>
+    <string name="image_load_fail" msgid="7538534580694411837">"Није могуће учитати слику"</string>
+    <string name="wallpaper_load_fail" msgid="4800700444605404650">"Није могуће учитати слику као позадину"</string>
+  <plurals name="number_of_items_selected">
+    <item quantity="zero" msgid="9015111147509924344">"Изабрано је %1$d"</item>
+    <item quantity="one" msgid="8409622005831789373">"Изабрана је %1$d"</item>
+    <item quantity="other" msgid="479468347731745357">"Изабраних: %1$d"</item>
+  </plurals>
+    <string name="wallpaper_accessibility_name" msgid="4093221025304876354">"Позадина %1$d од %2$d"</string>
+    <string name="announce_selection" msgid="123723511662250539">"Изабрана је <xliff:g id="LABEL">%1$s</xliff:g>"</string>
+    <string name="wallpaper_delete" msgid="1459353972739215344">"Избриши"</string>
+    <string name="pick_image" msgid="6704438906027442697">"Изабери слику"</string>
+    <string name="pick_wallpaper" msgid="4628969645948454559">"Позадине"</string>
+    <string name="crop_wallpaper" msgid="4882870800623585836">"Опсеци позадину"</string>
+</resources>
diff --git a/WallpaperPicker/res/values-sv/strings.xml b/WallpaperPicker/res/values-sv/strings.xml
new file mode 100644
index 0000000..57db3a6
--- /dev/null
+++ b/WallpaperPicker/res/values-sv/strings.xml
@@ -0,0 +1,36 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/*
+* Copyright (C) 2013 The Android Open Source Project
+*
+* Licensed under the Apache License, Version 2.0 (the "License");
+* you may not use this file except in compliance with the License.
+* You may obtain a copy of the License at
+*
+*      http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.
+*/
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="wallpaper_instructions" msgid="3524143401182707094">"Ange bakgrund"</string>
+    <string name="image_load_fail" msgid="7538534580694411837">"Det gick inte att läsa in bilden"</string>
+    <string name="wallpaper_load_fail" msgid="4800700444605404650">"Det gick inte att läsa in bilden som bakgrund"</string>
+  <plurals name="number_of_items_selected">
+    <item quantity="zero" msgid="9015111147509924344">"%1$d har valts"</item>
+    <item quantity="one" msgid="8409622005831789373">"%1$d har valts"</item>
+    <item quantity="other" msgid="479468347731745357">"%1$d har valts"</item>
+  </plurals>
+    <string name="wallpaper_accessibility_name" msgid="4093221025304876354">"Bakgrund %1$d av %2$d"</string>
+    <string name="announce_selection" msgid="123723511662250539">"<xliff:g id="LABEL">%1$s</xliff:g> har valts"</string>
+    <string name="wallpaper_delete" msgid="1459353972739215344">"Ta bort"</string>
+    <string name="pick_image" msgid="6704438906027442697">"Välj bild"</string>
+    <string name="pick_wallpaper" msgid="4628969645948454559">"Bakgrunder"</string>
+    <string name="crop_wallpaper" msgid="4882870800623585836">"Beskär bakgrund"</string>
+</resources>
diff --git a/WallpaperPicker/res/values-sw/strings.xml b/WallpaperPicker/res/values-sw/strings.xml
new file mode 100644
index 0000000..edea3de
--- /dev/null
+++ b/WallpaperPicker/res/values-sw/strings.xml
@@ -0,0 +1,36 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/*
+* Copyright (C) 2013 The Android Open Source Project
+*
+* Licensed under the Apache License, Version 2.0 (the "License");
+* you may not use this file except in compliance with the License.
+* You may obtain a copy of the License at
+*
+*      http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.
+*/
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="wallpaper_instructions" msgid="3524143401182707094">"Weka mandhari"</string>
+    <string name="image_load_fail" msgid="7538534580694411837">"Haikuweza kupakia picha"</string>
+    <string name="wallpaper_load_fail" msgid="4800700444605404650">"Haikuweza kupakia picha iwe mandhari"</string>
+  <plurals name="number_of_items_selected">
+    <item quantity="zero" msgid="9015111147509924344">"%1$d zimechaguliwa"</item>
+    <item quantity="one" msgid="8409622005831789373">"%1$d zimechaguliwa"</item>
+    <item quantity="other" msgid="479468347731745357">"%1$d zimechaguliwa"</item>
+  </plurals>
+    <string name="wallpaper_accessibility_name" msgid="4093221025304876354">"Mandhari %1$d ya %2$d"</string>
+    <string name="announce_selection" msgid="123723511662250539">"<xliff:g id="LABEL">%1$s</xliff:g> iliyochaguliwa"</string>
+    <string name="wallpaper_delete" msgid="1459353972739215344">"Futa"</string>
+    <string name="pick_image" msgid="6704438906027442697">"Chagua picha"</string>
+    <string name="pick_wallpaper" msgid="4628969645948454559">"Mandhari"</string>
+    <string name="crop_wallpaper" msgid="4882870800623585836">"Punguza mandhari"</string>
+</resources>
diff --git a/WallpaperPicker/res/values-sw600dp/config.xml b/WallpaperPicker/res/values-sw600dp/config.xml
new file mode 100644
index 0000000..62342dc
--- /dev/null
+++ b/WallpaperPicker/res/values-sw600dp/config.xml
@@ -0,0 +1,18 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2013 The Android Open Source Project
+
+     Licensed under the Apache License, Version 2.0 (the "License");
+     you may not use this file except in compliance with the License.
+     You may obtain a copy of the License at
+
+          http://www.apache.org/licenses/LICENSE-2.0
+
+     Unless required by applicable law or agreed to in writing, software
+     distributed under the License is distributed on an "AS IS" BASIS,
+     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+     See the License for the specific language governing permissions and
+     limitations under the License.
+-->
+<resources>
+    <bool name="allow_rotation">true</bool>
+</resources>
diff --git a/WallpaperPicker/res/values-sw720dp/dimens.xml b/WallpaperPicker/res/values-sw720dp/dimens.xml
new file mode 100644
index 0000000..9ae155b
--- /dev/null
+++ b/WallpaperPicker/res/values-sw720dp/dimens.xml
@@ -0,0 +1,28 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2011 The Android Open Source Project
+
+     Licensed under the Apache License, Version 2.0 (the "License");
+     you may not use this file except in compliance with the License.
+     You may obtain a copy of the License at
+
+          http://www.apache.org/licenses/LICENSE-2.0
+
+     Unless required by applicable law or agreed to in writing, software
+     distributed under the License is distributed on an "AS IS" BASIS,
+     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+     See the License for the specific language governing permissions and
+     limitations under the License.
+-->
+
+<resources>
+    <dimen name="app_icon_size">72dp</dimen>
+
+<!-- QSB -->
+    <dimen name="toolbar_button_vertical_padding">8dip</dimen>
+    <dimen name="toolbar_button_horizontal_padding">8dip</dimen>
+
+    <!-- When dragging items on the workspace, the number of dps by which the position of
+     the drag view should be offset from the position of the original view. -->
+    <dimen name="dragViewOffsetX">0dp</dimen>
+    <dimen name="dragViewOffsetY">0dp</dimen>
+</resources>
diff --git a/WallpaperPicker/res/values-sw720dp/styles.xml b/WallpaperPicker/res/values-sw720dp/styles.xml
new file mode 100644
index 0000000..9107851
--- /dev/null
+++ b/WallpaperPicker/res/values-sw720dp/styles.xml
@@ -0,0 +1,26 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+/*
+* Copyright (C) 2013 The Android Open Source Project
+*
+* Licensed under the Apache License, Version 2.0 (the "License");
+* you may not use this file except in compliance with the License.
+* You may obtain a copy of the License at
+*
+*      http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.
+*/
+-->
+
+<resources>
+    <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>
+</resources>
diff --git a/WallpaperPicker/res/values-th/strings.xml b/WallpaperPicker/res/values-th/strings.xml
new file mode 100644
index 0000000..6b4c235
--- /dev/null
+++ b/WallpaperPicker/res/values-th/strings.xml
@@ -0,0 +1,36 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/*
+* Copyright (C) 2013 The Android Open Source Project
+*
+* Licensed under the Apache License, Version 2.0 (the "License");
+* you may not use this file except in compliance with the License.
+* You may obtain a copy of the License at
+*
+*      http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.
+*/
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="wallpaper_instructions" msgid="3524143401182707094">"ตั้งวอลเปเปอร์"</string>
+    <string name="image_load_fail" msgid="7538534580694411837">"ไม่สามารถโหลดรูปภาพ"</string>
+    <string name="wallpaper_load_fail" msgid="4800700444605404650">"ไม่สามารถโหลดรูปภาพเป็นวอลเปเปอร์"</string>
+  <plurals name="number_of_items_selected">
+    <item quantity="zero" msgid="9015111147509924344">"เลือกไว้ %1$d"</item>
+    <item quantity="one" msgid="8409622005831789373">"เลือกไว้ %1$d"</item>
+    <item quantity="other" msgid="479468347731745357">"เลือกไว้ %1$d"</item>
+  </plurals>
+    <string name="wallpaper_accessibility_name" msgid="4093221025304876354">"วอลเปเปอร์ %1$d จาก %2$d"</string>
+    <string name="announce_selection" msgid="123723511662250539">"เลือก <xliff:g id="LABEL">%1$s</xliff:g> แล้ว"</string>
+    <string name="wallpaper_delete" msgid="1459353972739215344">"ลบ"</string>
+    <string name="pick_image" msgid="6704438906027442697">"เลือกรูปภาพ"</string>
+    <string name="pick_wallpaper" msgid="4628969645948454559">"วอลเปเปอร์"</string>
+    <string name="crop_wallpaper" msgid="4882870800623585836">"ครอบตัดวอลเปเปอร์"</string>
+</resources>
diff --git a/WallpaperPicker/res/values-tl/strings.xml b/WallpaperPicker/res/values-tl/strings.xml
new file mode 100644
index 0000000..c9fe338
--- /dev/null
+++ b/WallpaperPicker/res/values-tl/strings.xml
@@ -0,0 +1,36 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/*
+* Copyright (C) 2013 The Android Open Source Project
+*
+* Licensed under the Apache License, Version 2.0 (the "License");
+* you may not use this file except in compliance with the License.
+* You may obtain a copy of the License at
+*
+*      http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.
+*/
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="wallpaper_instructions" msgid="3524143401182707094">"Itakda ang wallpaper"</string>
+    <string name="image_load_fail" msgid="7538534580694411837">"Hindi ma-load ang larawan"</string>
+    <string name="wallpaper_load_fail" msgid="4800700444605404650">"Hindi ma-load ang larawan bilang wallpaper"</string>
+  <plurals name="number_of_items_selected">
+    <item quantity="zero" msgid="9015111147509924344">"%1$d ang napili"</item>
+    <item quantity="one" msgid="8409622005831789373">"%1$d ang napili"</item>
+    <item quantity="other" msgid="479468347731745357">"%1$d ang napili"</item>
+  </plurals>
+    <string name="wallpaper_accessibility_name" msgid="4093221025304876354">"Wallpaper %1$d ng %2$d"</string>
+    <string name="announce_selection" msgid="123723511662250539">"Napili ang <xliff:g id="LABEL">%1$s</xliff:g>"</string>
+    <string name="wallpaper_delete" msgid="1459353972739215344">"Tanggalin"</string>
+    <string name="pick_image" msgid="6704438906027442697">"Pumili ng larawan"</string>
+    <string name="pick_wallpaper" msgid="4628969645948454559">"Mga Wallpaper"</string>
+    <string name="crop_wallpaper" msgid="4882870800623585836">"I-crop ang wallpaper"</string>
+</resources>
diff --git a/WallpaperPicker/res/values-tr/strings.xml b/WallpaperPicker/res/values-tr/strings.xml
new file mode 100644
index 0000000..3d03c6b
--- /dev/null
+++ b/WallpaperPicker/res/values-tr/strings.xml
@@ -0,0 +1,36 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/*
+* Copyright (C) 2013 The Android Open Source Project
+*
+* Licensed under the Apache License, Version 2.0 (the "License");
+* you may not use this file except in compliance with the License.
+* You may obtain a copy of the License at
+*
+*      http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.
+*/
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="wallpaper_instructions" msgid="3524143401182707094">"Duvar kağıdını ayarla"</string>
+    <string name="image_load_fail" msgid="7538534580694411837">"Resim yüklenemedi"</string>
+    <string name="wallpaper_load_fail" msgid="4800700444605404650">"Resim duvar kağıdı olarak yüklenemedi"</string>
+  <plurals name="number_of_items_selected">
+    <item quantity="zero" msgid="9015111147509924344">"%1$d tane seçildi"</item>
+    <item quantity="one" msgid="8409622005831789373">"%1$d tane seçildi"</item>
+    <item quantity="other" msgid="479468347731745357">"%1$d tane seçildi"</item>
+  </plurals>
+    <string name="wallpaper_accessibility_name" msgid="4093221025304876354">"%2$d duvar kağıdı arasından duvar kağıdı %1$d"</string>
+    <string name="announce_selection" msgid="123723511662250539">"<xliff:g id="LABEL">%1$s</xliff:g> seçildi"</string>
+    <string name="wallpaper_delete" msgid="1459353972739215344">"Sil"</string>
+    <string name="pick_image" msgid="6704438906027442697">"Resim seç"</string>
+    <string name="pick_wallpaper" msgid="4628969645948454559">"Duvar kağıtları"</string>
+    <string name="crop_wallpaper" msgid="4882870800623585836">"Duvar kağıdını kırp"</string>
+</resources>
diff --git a/WallpaperPicker/res/values-uk/strings.xml b/WallpaperPicker/res/values-uk/strings.xml
new file mode 100644
index 0000000..076c882
--- /dev/null
+++ b/WallpaperPicker/res/values-uk/strings.xml
@@ -0,0 +1,36 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/*
+* Copyright (C) 2013 The Android Open Source Project
+*
+* Licensed under the Apache License, Version 2.0 (the "License");
+* you may not use this file except in compliance with the License.
+* You may obtain a copy of the License at
+*
+*      http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.
+*/
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="wallpaper_instructions" msgid="3524143401182707094">"Установити фон"</string>
+    <string name="image_load_fail" msgid="7538534580694411837">"Не вдалося завантажити зображення"</string>
+    <string name="wallpaper_load_fail" msgid="4800700444605404650">"Не вдалося завантажити зображення як фоновий малюнок"</string>
+  <plurals name="number_of_items_selected">
+    <item quantity="zero" msgid="9015111147509924344">"Вибрано %1$d"</item>
+    <item quantity="one" msgid="8409622005831789373">"Вибрано %1$d"</item>
+    <item quantity="other" msgid="479468347731745357">"Вибрано %1$d"</item>
+  </plurals>
+    <string name="wallpaper_accessibility_name" msgid="4093221025304876354">"Фоновий малюнок %1$d з %2$d"</string>
+    <string name="announce_selection" msgid="123723511662250539">"Вибрано <xliff:g id="LABEL">%1$s</xliff:g>"</string>
+    <string name="wallpaper_delete" msgid="1459353972739215344">"Видалити"</string>
+    <string name="pick_image" msgid="6704438906027442697">"Вибрати зображення"</string>
+    <string name="pick_wallpaper" msgid="4628969645948454559">"Фонові малюнки"</string>
+    <string name="crop_wallpaper" msgid="4882870800623585836">"Обрізати фоновий малюнок"</string>
+</resources>
diff --git a/WallpaperPicker/res/values-vi/strings.xml b/WallpaperPicker/res/values-vi/strings.xml
new file mode 100644
index 0000000..d1efbe9
--- /dev/null
+++ b/WallpaperPicker/res/values-vi/strings.xml
@@ -0,0 +1,36 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/*
+* Copyright (C) 2013 The Android Open Source Project
+*
+* Licensed under the Apache License, Version 2.0 (the "License");
+* you may not use this file except in compliance with the License.
+* You may obtain a copy of the License at
+*
+*      http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.
+*/
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="wallpaper_instructions" msgid="3524143401182707094">"Đặt hình nền"</string>
+    <string name="image_load_fail" msgid="7538534580694411837">"Không thể tải hình ảnh"</string>
+    <string name="wallpaper_load_fail" msgid="4800700444605404650">"Không thể tải hình ảnh làm hình nền"</string>
+  <plurals name="number_of_items_selected">
+    <item quantity="zero" msgid="9015111147509924344">"Đã chọn %1$d"</item>
+    <item quantity="one" msgid="8409622005831789373">"Đã chọn %1$d"</item>
+    <item quantity="other" msgid="479468347731745357">"Đã chọn %1$d"</item>
+  </plurals>
+    <string name="wallpaper_accessibility_name" msgid="4093221025304876354">"Hình nền %1$d / %2$d"</string>
+    <string name="announce_selection" msgid="123723511662250539">"<xliff:g id="LABEL">%1$s</xliff:g> được chọn"</string>
+    <string name="wallpaper_delete" msgid="1459353972739215344">"Xóa"</string>
+    <string name="pick_image" msgid="6704438906027442697">"Chọn hình ảnh"</string>
+    <string name="pick_wallpaper" msgid="4628969645948454559">"Hình nền"</string>
+    <string name="crop_wallpaper" msgid="4882870800623585836">"Cắt hình nền"</string>
+</resources>
diff --git a/WallpaperPicker/res/values-zh-rCN/strings.xml b/WallpaperPicker/res/values-zh-rCN/strings.xml
new file mode 100644
index 0000000..1def9ed
--- /dev/null
+++ b/WallpaperPicker/res/values-zh-rCN/strings.xml
@@ -0,0 +1,36 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/*
+* Copyright (C) 2013 The Android Open Source Project
+*
+* Licensed under the Apache License, Version 2.0 (the "License");
+* you may not use this file except in compliance with the License.
+* You may obtain a copy of the License at
+*
+*      http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.
+*/
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="wallpaper_instructions" msgid="3524143401182707094">"设置壁纸"</string>
+    <string name="image_load_fail" msgid="7538534580694411837">"无法加载图片"</string>
+    <string name="wallpaper_load_fail" msgid="4800700444605404650">"无法加载要设为壁纸的图片"</string>
+  <plurals name="number_of_items_selected">
+    <item quantity="zero" msgid="9015111147509924344">"已选择%1$d项"</item>
+    <item quantity="one" msgid="8409622005831789373">"已选择%1$d项"</item>
+    <item quantity="other" msgid="479468347731745357">"已选择%1$d项"</item>
+  </plurals>
+    <string name="wallpaper_accessibility_name" msgid="4093221025304876354">"第%1$d张壁纸,共%2$d张"</string>
+    <string name="announce_selection" msgid="123723511662250539">"已选择<xliff:g id="LABEL">%1$s</xliff:g>"</string>
+    <string name="wallpaper_delete" msgid="1459353972739215344">"删除"</string>
+    <string name="pick_image" msgid="6704438906027442697">"选择图片"</string>
+    <string name="pick_wallpaper" msgid="4628969645948454559">"壁纸"</string>
+    <string name="crop_wallpaper" msgid="4882870800623585836">"剪裁壁纸"</string>
+</resources>
diff --git a/WallpaperPicker/res/values-zh-rHK/strings.xml b/WallpaperPicker/res/values-zh-rHK/strings.xml
new file mode 100644
index 0000000..66ba0af
--- /dev/null
+++ b/WallpaperPicker/res/values-zh-rHK/strings.xml
@@ -0,0 +1,36 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/*
+* Copyright (C) 2013 The Android Open Source Project
+*
+* Licensed under the Apache License, Version 2.0 (the "License");
+* you may not use this file except in compliance with the License.
+* You may obtain a copy of the License at
+*
+*      http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.
+*/
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="wallpaper_instructions" msgid="3524143401182707094">"設定桌布"</string>
+    <string name="image_load_fail" msgid="7538534580694411837">"無法載入圖片"</string>
+    <string name="wallpaper_load_fail" msgid="4800700444605404650">"無法載入圖片設為桌布"</string>
+  <plurals name="number_of_items_selected">
+    <item quantity="zero" msgid="9015111147509924344">"已選取 %1$d 張"</item>
+    <item quantity="one" msgid="8409622005831789373">"已選取 %1$d 張"</item>
+    <item quantity="other" msgid="479468347731745357">"已選取 %1$d 張"</item>
+  </plurals>
+    <string name="wallpaper_accessibility_name" msgid="4093221025304876354">"第 %1$d 張桌布,共 %2$d 張"</string>
+    <string name="announce_selection" msgid="123723511662250539">"已選取<xliff:g id="LABEL">%1$s</xliff:g>"</string>
+    <string name="wallpaper_delete" msgid="1459353972739215344">"刪除"</string>
+    <string name="pick_image" msgid="6704438906027442697">"選擇圖片"</string>
+    <string name="pick_wallpaper" msgid="4628969645948454559">"桌布"</string>
+    <string name="crop_wallpaper" msgid="4882870800623585836">"裁剪桌布"</string>
+</resources>
diff --git a/WallpaperPicker/res/values-zh-rTW/strings.xml b/WallpaperPicker/res/values-zh-rTW/strings.xml
new file mode 100644
index 0000000..4184976
--- /dev/null
+++ b/WallpaperPicker/res/values-zh-rTW/strings.xml
@@ -0,0 +1,36 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/*
+* Copyright (C) 2013 The Android Open Source Project
+*
+* Licensed under the Apache License, Version 2.0 (the "License");
+* you may not use this file except in compliance with the License.
+* You may obtain a copy of the License at
+*
+*      http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.
+*/
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="wallpaper_instructions" msgid="3524143401182707094">"設定桌布"</string>
+    <string name="image_load_fail" msgid="7538534580694411837">"無法載入圖片"</string>
+    <string name="wallpaper_load_fail" msgid="4800700444605404650">"無法載入您要設為桌布的圖片"</string>
+  <plurals name="number_of_items_selected">
+    <item quantity="zero" msgid="9015111147509924344">"已選取 %1$d 個"</item>
+    <item quantity="one" msgid="8409622005831789373">"已選取 %1$d 個"</item>
+    <item quantity="other" msgid="479468347731745357">"已選取 %1$d 個"</item>
+  </plurals>
+    <string name="wallpaper_accessibility_name" msgid="4093221025304876354">"第 %1$d 張桌布,共 %2$d 張"</string>
+    <string name="announce_selection" msgid="123723511662250539">"已選取<xliff:g id="LABEL">%1$s</xliff:g>"</string>
+    <string name="wallpaper_delete" msgid="1459353972739215344">"刪除"</string>
+    <string name="pick_image" msgid="6704438906027442697">"選擇圖片"</string>
+    <string name="pick_wallpaper" msgid="4628969645948454559">"桌布"</string>
+    <string name="crop_wallpaper" msgid="4882870800623585836">"裁剪桌布"</string>
+</resources>
diff --git a/WallpaperPicker/res/values-zu/strings.xml b/WallpaperPicker/res/values-zu/strings.xml
new file mode 100644
index 0000000..c7d3f33
--- /dev/null
+++ b/WallpaperPicker/res/values-zu/strings.xml
@@ -0,0 +1,36 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/*
+* Copyright (C) 2013 The Android Open Source Project
+*
+* Licensed under the Apache License, Version 2.0 (the "License");
+* you may not use this file except in compliance with the License.
+* You may obtain a copy of the License at
+*
+*      http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.
+*/
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="wallpaper_instructions" msgid="3524143401182707094">"Setha isithombe sangemuva"</string>
+    <string name="image_load_fail" msgid="7538534580694411837">"Ayikwazanga ukulayisha isithombe"</string>
+    <string name="wallpaper_load_fail" msgid="4800700444605404650">"Ayikwazanga ukulayisha isithombe njengesithombe sangemuva"</string>
+  <plurals name="number_of_items_selected">
+    <item quantity="zero" msgid="9015111147509924344">"%1$d khethiwe"</item>
+    <item quantity="one" msgid="8409622005831789373">"%1$d khethiwe"</item>
+    <item quantity="other" msgid="479468347731745357">"%1$d khethiwe"</item>
+  </plurals>
+    <string name="wallpaper_accessibility_name" msgid="4093221025304876354">"Isithombe sangemuva esingu-%1$d kwezingu-%2$d"</string>
+    <string name="announce_selection" msgid="123723511662250539">"I-<xliff:g id="LABEL">%1$s</xliff:g> ekhethiwe"</string>
+    <string name="wallpaper_delete" msgid="1459353972739215344">"Susa"</string>
+    <string name="pick_image" msgid="6704438906027442697">"Khetha isithombe"</string>
+    <string name="pick_wallpaper" msgid="4628969645948454559">"Izithombe zangemuva"</string>
+    <string name="crop_wallpaper" msgid="4882870800623585836">"Nqampuna isithombe sangemuva"</string>
+</resources>
diff --git a/WallpaperPicker/res/values/colors.xml b/WallpaperPicker/res/values/colors.xml
new file mode 100644
index 0000000..adae7cf
--- /dev/null
+++ b/WallpaperPicker/res/values/colors.xml
@@ -0,0 +1,22 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+/* //device/apps/common/assets/res/any/colors.xml
+**
+** Copyright 2013, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License"); 
+** you may not use this file except in compliance with the License. 
+** You may obtain a copy of the License at 
+**
+**     http://www.apache.org/licenses/LICENSE-2.0 
+**
+** Unless required by applicable law or agreed to in writing, software 
+** distributed under the License is distributed on an "AS IS" BASIS, 
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 
+** See the License for the specific language governing permissions and 
+** limitations under the License.
+*/
+-->
+<resources>
+    <color name="wallpaper_picker_translucent_gray">#66000000</color>
+</resources>
diff --git a/WallpaperPicker/res/values/config.xml b/WallpaperPicker/res/values/config.xml
new file mode 100644
index 0000000..71580b5
--- /dev/null
+++ b/WallpaperPicker/res/values/config.xml
@@ -0,0 +1,21 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2013 The Android Open Source Project
+
+     Licensed under the Apache License, Version 2.0 (the "License");
+     you may not use this file except in compliance with the License.
+     You may obtain a copy of the License at
+
+          http://www.apache.org/licenses/LICENSE-2.0
+
+     Unless required by applicable law or agreed to in writing, software
+     distributed under the License is distributed on an "AS IS" BASIS,
+     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+     See the License for the specific language governing permissions and
+     limitations under the License.
+-->
+<resources>
+    <bool name="allow_rotation">false</bool>
+    <!-- Specifies whether to expand the cropped area on both sides (rather
+         than just to one side) -->
+    <bool name="center_crop">false</bool>
+</resources>
diff --git a/WallpaperPicker/res/values/dimens.xml b/WallpaperPicker/res/values/dimens.xml
new file mode 100644
index 0000000..0447c6d
--- /dev/null
+++ b/WallpaperPicker/res/values/dimens.xml
@@ -0,0 +1,22 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2013 The Android Open Source Project
+
+     Licensed under the Apache License, Version 2.0 (the "License");
+     you may not use this file except in compliance with the License.
+     You may obtain a copy of the License at
+  
+          http://www.apache.org/licenses/LICENSE-2.0
+  
+     Unless required by applicable law or agreed to in writing, software
+     distributed under the License is distributed on an "AS IS" BASIS,
+     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+     See the License for the specific language governing permissions and
+     limitations under the License.
+-->
+
+<resources>
+<!-- Wallpaper picker -->
+    <dimen name="wallpaperThumbnailWidth">106.5dp</dimen>
+    <dimen name="wallpaperThumbnailHeight">94.5dp</dimen>
+    <dimen name="wallpaperItemIconSize">32dp</dimen>
+</resources>
diff --git a/WallpaperPicker/res/values/strings.xml b/WallpaperPicker/res/values/strings.xml
new file mode 100644
index 0000000..1ee3513
--- /dev/null
+++ b/WallpaperPicker/res/values/strings.xml
@@ -0,0 +1,53 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+/*
+* Copyright (C) 2013 The Android Open Source Project
+*
+* Licensed under the Apache License, Version 2.0 (the "License");
+* you may not use this file except in compliance with the License.
+* You may obtain a copy of the License at
+*
+*      http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.
+*/
+-->
+
+<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <!-- Button label on Wallpaper picker screen; user selects this button to set a specific wallpaper -->
+    <string name="wallpaper_instructions">Set wallpaper</string>
+    <!-- Error message when an image is selected as a wallpaper,
+         but the wallpaper picker cannot load it -->
+    <string name="image_load_fail">Coudn\'t load image</string>
+    <!-- Error message when an image is selected as a wallpaper,
+         but the wallpaper cropper cannot load it. The user will
+         usually see this when using another app and trying to set
+         an image as the wallpaper -->
+    <string name="wallpaper_load_fail">Couldn\'t load image as wallpaper</string>
+    <!-- Shown when wallpapers are selected in Wallpaper picker -->
+    <!-- String indicating how many media item(s) is(are) selected
+            eg. 1 selected [CHAR LIMIT=30] -->
+    <plurals name="number_of_items_selected">
+        <item quantity="zero">%1$d selected</item>
+        <item quantity="one">%1$d selected</item>
+        <item quantity="other">%1$d selected</item>
+    </plurals>
+    <!-- Accessibility string used as a label for a particular wallpaper in the Wallpaper Picker list.
+         e.g. "Wallpaper 3 of 10" -->
+    <string name="wallpaper_accessibility_name">Wallpaper %1$d of %2$d</string>
+    <!-- Accessibility string used to announce that a wallpaper has been selected. -->
+    <string name="announce_selection">Selected <xliff:g id="label" example="Wallpaper 3 of 10">%1$s</xliff:g></string>
+
+    <!-- Label on button to delete wallpaper(s) -->
+    <string name="wallpaper_delete">Delete</string>
+    <!-- Label on button in Wallpaper Picker to pick an image -->
+    <string name="pick_image">Pick image</string>
+    <!-- Option in "Select wallpaper from" dialog box -->
+    <string name="pick_wallpaper">Wallpapers</string>
+    <!-- Title of activity for cropping wallpapers -->
+    <string name="crop_wallpaper">Crop wallpaper</string>
+</resources>
diff --git a/WallpaperPicker/res/values/styles.xml b/WallpaperPicker/res/values/styles.xml
new file mode 100644
index 0000000..0e48dda
--- /dev/null
+++ b/WallpaperPicker/res/values/styles.xml
@@ -0,0 +1,37 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+/*
+* Copyright (C) 2013 The Android Open Source Project
+*
+* Licensed under the Apache License, Version 2.0 (the "License");
+* you may not use this file except in compliance with the License.
+* You may obtain a copy of the License at
+*
+*      http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.
+*/
+-->
+
+<resources>
+    <style name="Theme.WallpaperCropper" parent="@android:style/Theme.Holo">
+        <item name="android:actionBarStyle">@style/WallpaperCropperActionBar</item>
+        <item name="android:windowFullscreen">true</item>
+        <item name="android:windowActionBarOverlay">true</item>
+        <item name="android:windowTranslucentNavigation">true</item>
+    </style>
+
+    <style name="WallpaperCropperActionBar" parent="android:style/Widget.Holo.ActionBar">
+        <item name="android:displayOptions">showCustom</item>
+        <item name="android:background">#88000000</item>
+    </style>
+
+    <style name="Theme" parent="@android:style/Theme.Holo.Wallpaper.NoTitleBar">
+        <item name="android:windowTranslucentStatus">true</item>
+        <item name="android:windowTranslucentNavigation">true</item>
+    </style>
+</resources>
diff --git a/src/android/util/Pools.java b/WallpaperPicker/src/android/util/Pools.java
similarity index 100%
rename from src/android/util/Pools.java
rename to WallpaperPicker/src/android/util/Pools.java
diff --git a/src/com/android/gallery3d/common/BitmapUtils.java b/WallpaperPicker/src/com/android/gallery3d/common/BitmapUtils.java
similarity index 100%
rename from src/com/android/gallery3d/common/BitmapUtils.java
rename to WallpaperPicker/src/com/android/gallery3d/common/BitmapUtils.java
diff --git a/src/com/android/gallery3d/common/Utils.java b/WallpaperPicker/src/com/android/gallery3d/common/Utils.java
similarity index 100%
rename from src/com/android/gallery3d/common/Utils.java
rename to WallpaperPicker/src/com/android/gallery3d/common/Utils.java
diff --git a/src/com/android/gallery3d/exif/ByteBufferInputStream.java b/WallpaperPicker/src/com/android/gallery3d/exif/ByteBufferInputStream.java
similarity index 100%
rename from src/com/android/gallery3d/exif/ByteBufferInputStream.java
rename to WallpaperPicker/src/com/android/gallery3d/exif/ByteBufferInputStream.java
diff --git a/src/com/android/gallery3d/exif/CountedDataInputStream.java b/WallpaperPicker/src/com/android/gallery3d/exif/CountedDataInputStream.java
similarity index 100%
rename from src/com/android/gallery3d/exif/CountedDataInputStream.java
rename to WallpaperPicker/src/com/android/gallery3d/exif/CountedDataInputStream.java
diff --git a/src/com/android/gallery3d/exif/ExifData.java b/WallpaperPicker/src/com/android/gallery3d/exif/ExifData.java
similarity index 100%
rename from src/com/android/gallery3d/exif/ExifData.java
rename to WallpaperPicker/src/com/android/gallery3d/exif/ExifData.java
diff --git a/src/com/android/gallery3d/exif/ExifInterface.java b/WallpaperPicker/src/com/android/gallery3d/exif/ExifInterface.java
similarity index 100%
rename from src/com/android/gallery3d/exif/ExifInterface.java
rename to WallpaperPicker/src/com/android/gallery3d/exif/ExifInterface.java
diff --git a/src/com/android/gallery3d/exif/ExifInvalidFormatException.java b/WallpaperPicker/src/com/android/gallery3d/exif/ExifInvalidFormatException.java
similarity index 100%
rename from src/com/android/gallery3d/exif/ExifInvalidFormatException.java
rename to WallpaperPicker/src/com/android/gallery3d/exif/ExifInvalidFormatException.java
diff --git a/src/com/android/gallery3d/exif/ExifModifier.java b/WallpaperPicker/src/com/android/gallery3d/exif/ExifModifier.java
similarity index 99%
rename from src/com/android/gallery3d/exif/ExifModifier.java
rename to WallpaperPicker/src/com/android/gallery3d/exif/ExifModifier.java
index f00362b..0531cba 100644
--- a/src/com/android/gallery3d/exif/ExifModifier.java
+++ b/WallpaperPicker/src/com/android/gallery3d/exif/ExifModifier.java
@@ -18,7 +18,6 @@
 
 import android.util.Log;
 
-import java.io.Closeable;
 import java.io.IOException;
 import java.io.InputStream;
 import java.nio.ByteBuffer;
diff --git a/src/com/android/gallery3d/exif/ExifOutputStream.java b/WallpaperPicker/src/com/android/gallery3d/exif/ExifOutputStream.java
similarity index 100%
rename from src/com/android/gallery3d/exif/ExifOutputStream.java
rename to WallpaperPicker/src/com/android/gallery3d/exif/ExifOutputStream.java
diff --git a/src/com/android/gallery3d/exif/ExifParser.java b/WallpaperPicker/src/com/android/gallery3d/exif/ExifParser.java
similarity index 100%
rename from src/com/android/gallery3d/exif/ExifParser.java
rename to WallpaperPicker/src/com/android/gallery3d/exif/ExifParser.java
diff --git a/src/com/android/gallery3d/exif/ExifReader.java b/WallpaperPicker/src/com/android/gallery3d/exif/ExifReader.java
similarity index 100%
rename from src/com/android/gallery3d/exif/ExifReader.java
rename to WallpaperPicker/src/com/android/gallery3d/exif/ExifReader.java
diff --git a/src/com/android/gallery3d/exif/ExifTag.java b/WallpaperPicker/src/com/android/gallery3d/exif/ExifTag.java
similarity index 100%
rename from src/com/android/gallery3d/exif/ExifTag.java
rename to WallpaperPicker/src/com/android/gallery3d/exif/ExifTag.java
diff --git a/src/com/android/gallery3d/exif/IfdData.java b/WallpaperPicker/src/com/android/gallery3d/exif/IfdData.java
similarity index 100%
rename from src/com/android/gallery3d/exif/IfdData.java
rename to WallpaperPicker/src/com/android/gallery3d/exif/IfdData.java
diff --git a/src/com/android/gallery3d/exif/IfdId.java b/WallpaperPicker/src/com/android/gallery3d/exif/IfdId.java
similarity index 100%
rename from src/com/android/gallery3d/exif/IfdId.java
rename to WallpaperPicker/src/com/android/gallery3d/exif/IfdId.java
diff --git a/src/com/android/gallery3d/exif/JpegHeader.java b/WallpaperPicker/src/com/android/gallery3d/exif/JpegHeader.java
similarity index 100%
rename from src/com/android/gallery3d/exif/JpegHeader.java
rename to WallpaperPicker/src/com/android/gallery3d/exif/JpegHeader.java
diff --git a/src/com/android/gallery3d/exif/OrderedDataOutputStream.java b/WallpaperPicker/src/com/android/gallery3d/exif/OrderedDataOutputStream.java
similarity index 100%
rename from src/com/android/gallery3d/exif/OrderedDataOutputStream.java
rename to WallpaperPicker/src/com/android/gallery3d/exif/OrderedDataOutputStream.java
diff --git a/src/com/android/gallery3d/exif/Rational.java b/WallpaperPicker/src/com/android/gallery3d/exif/Rational.java
similarity index 100%
rename from src/com/android/gallery3d/exif/Rational.java
rename to WallpaperPicker/src/com/android/gallery3d/exif/Rational.java
diff --git a/src/com/android/gallery3d/glrenderer/BasicTexture.java b/WallpaperPicker/src/com/android/gallery3d/glrenderer/BasicTexture.java
similarity index 100%
rename from src/com/android/gallery3d/glrenderer/BasicTexture.java
rename to WallpaperPicker/src/com/android/gallery3d/glrenderer/BasicTexture.java
diff --git a/src/com/android/gallery3d/glrenderer/BitmapTexture.java b/WallpaperPicker/src/com/android/gallery3d/glrenderer/BitmapTexture.java
similarity index 100%
rename from src/com/android/gallery3d/glrenderer/BitmapTexture.java
rename to WallpaperPicker/src/com/android/gallery3d/glrenderer/BitmapTexture.java
diff --git a/src/com/android/gallery3d/glrenderer/GLCanvas.java b/WallpaperPicker/src/com/android/gallery3d/glrenderer/GLCanvas.java
similarity index 99%
rename from src/com/android/gallery3d/glrenderer/GLCanvas.java
rename to WallpaperPicker/src/com/android/gallery3d/glrenderer/GLCanvas.java
index 305e905..5b07477 100644
--- a/src/com/android/gallery3d/glrenderer/GLCanvas.java
+++ b/WallpaperPicker/src/com/android/gallery3d/glrenderer/GLCanvas.java
@@ -20,8 +20,6 @@
 import android.graphics.Rect;
 import android.graphics.RectF;
 
-import javax.microedition.khronos.opengles.GL11;
-
 //
 // GLCanvas gives a convenient interface to draw using OpenGL.
 //
diff --git a/src/com/android/gallery3d/glrenderer/GLES20Canvas.java b/WallpaperPicker/src/com/android/gallery3d/glrenderer/GLES20Canvas.java
similarity index 100%
rename from src/com/android/gallery3d/glrenderer/GLES20Canvas.java
rename to WallpaperPicker/src/com/android/gallery3d/glrenderer/GLES20Canvas.java
diff --git a/src/com/android/gallery3d/glrenderer/GLES20IdImpl.java b/WallpaperPicker/src/com/android/gallery3d/glrenderer/GLES20IdImpl.java
similarity index 100%
rename from src/com/android/gallery3d/glrenderer/GLES20IdImpl.java
rename to WallpaperPicker/src/com/android/gallery3d/glrenderer/GLES20IdImpl.java
diff --git a/src/com/android/gallery3d/glrenderer/GLId.java b/WallpaperPicker/src/com/android/gallery3d/glrenderer/GLId.java
similarity index 100%
rename from src/com/android/gallery3d/glrenderer/GLId.java
rename to WallpaperPicker/src/com/android/gallery3d/glrenderer/GLId.java
diff --git a/src/com/android/gallery3d/glrenderer/GLPaint.java b/WallpaperPicker/src/com/android/gallery3d/glrenderer/GLPaint.java
similarity index 100%
rename from src/com/android/gallery3d/glrenderer/GLPaint.java
rename to WallpaperPicker/src/com/android/gallery3d/glrenderer/GLPaint.java
diff --git a/src/com/android/gallery3d/glrenderer/RawTexture.java b/WallpaperPicker/src/com/android/gallery3d/glrenderer/RawTexture.java
similarity index 100%
rename from src/com/android/gallery3d/glrenderer/RawTexture.java
rename to WallpaperPicker/src/com/android/gallery3d/glrenderer/RawTexture.java
diff --git a/src/com/android/gallery3d/glrenderer/Texture.java b/WallpaperPicker/src/com/android/gallery3d/glrenderer/Texture.java
similarity index 100%
rename from src/com/android/gallery3d/glrenderer/Texture.java
rename to WallpaperPicker/src/com/android/gallery3d/glrenderer/Texture.java
diff --git a/src/com/android/gallery3d/glrenderer/UploadedTexture.java b/WallpaperPicker/src/com/android/gallery3d/glrenderer/UploadedTexture.java
similarity index 100%
rename from src/com/android/gallery3d/glrenderer/UploadedTexture.java
rename to WallpaperPicker/src/com/android/gallery3d/glrenderer/UploadedTexture.java
diff --git a/src/com/android/gallery3d/util/IntArray.java b/WallpaperPicker/src/com/android/gallery3d/util/IntArray.java
similarity index 100%
rename from src/com/android/gallery3d/util/IntArray.java
rename to WallpaperPicker/src/com/android/gallery3d/util/IntArray.java
diff --git a/src/com/android/launcher3/CheckableFrameLayout.java b/WallpaperPicker/src/com/android/launcher3/CheckableFrameLayout.java
similarity index 100%
rename from src/com/android/launcher3/CheckableFrameLayout.java
rename to WallpaperPicker/src/com/android/launcher3/CheckableFrameLayout.java
diff --git a/src/com/android/launcher3/CropView.java b/WallpaperPicker/src/com/android/launcher3/CropView.java
similarity index 98%
rename from src/com/android/launcher3/CropView.java
rename to WallpaperPicker/src/com/android/launcher3/CropView.java
index 9224e3b..578b8ea 100644
--- a/src/com/android/launcher3/CropView.java
+++ b/WallpaperPicker/src/com/android/launcher3/CropView.java
@@ -165,7 +165,8 @@
                 final float imageWidth = imageDims[0];
                 final float imageHeight = imageDims[1];
                 mMinScale = Math.max(w / imageWidth, h / imageHeight);
-                mRenderer.scale = Math.max(mMinScale, mRenderer.scale);
+                mRenderer.scale =
+                        Math.max(mMinScale, resetScale ? Float.MIN_VALUE : mRenderer.scale);
             }
         }
     }
diff --git a/WallpaperPicker/src/com/android/launcher3/DrawableTileSource.java b/WallpaperPicker/src/com/android/launcher3/DrawableTileSource.java
new file mode 100644
index 0000000..c1f2eff
--- /dev/null
+++ b/WallpaperPicker/src/com/android/launcher3/DrawableTileSource.java
@@ -0,0 +1,102 @@
+/*
+ * Copyright (C) 2013 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.launcher3;
+
+import android.content.Context;
+import android.graphics.Bitmap;
+import android.graphics.Canvas;
+import android.graphics.Rect;
+import android.graphics.drawable.Drawable;
+
+import com.android.gallery3d.glrenderer.BasicTexture;
+import com.android.gallery3d.glrenderer.BitmapTexture;
+import com.android.photos.views.TiledImageRenderer;
+
+public class DrawableTileSource implements TiledImageRenderer.TileSource {
+    private static final int GL_SIZE_LIMIT = 2048;
+    // This must be no larger than half the size of the GL_SIZE_LIMIT
+    // due to decodePreview being allowed to be up to 2x the size of the target
+    public static final int MAX_PREVIEW_SIZE = GL_SIZE_LIMIT / 2;
+
+    private int mTileSize;
+    private int mPreviewSize;
+    private Drawable mDrawable;
+    private BitmapTexture mPreview;
+
+    public DrawableTileSource(Context context, Drawable d, int previewSize) {
+        mTileSize = TiledImageRenderer.suggestedTileSize(context);
+        mDrawable = d;
+        mPreviewSize = Math.min(previewSize, MAX_PREVIEW_SIZE);
+    }
+
+    @Override
+    public int getTileSize() {
+        return mTileSize;
+    }
+
+    @Override
+    public int getImageWidth() {
+        return mDrawable.getIntrinsicWidth();
+    }
+
+    @Override
+    public int getImageHeight() {
+        return mDrawable.getIntrinsicHeight();
+    }
+
+    @Override
+    public int getRotation() {
+        return 0;
+    }
+
+    @Override
+    public BasicTexture getPreview() {
+        if (mPreviewSize == 0) {
+            return null;
+        }
+        if (mPreview == null){
+            float width = getImageWidth();
+            float height = getImageHeight();
+            while (width > MAX_PREVIEW_SIZE || height > MAX_PREVIEW_SIZE) {
+                width /= 2;
+                height /= 2;
+            }
+            Bitmap b = Bitmap.createBitmap((int) width, (int) height, Bitmap.Config.ARGB_8888);
+            Canvas c = new Canvas(b);
+            mDrawable.setBounds(new Rect(0, 0, (int) width, (int) height));
+            mDrawable.draw(c);
+            c.setBitmap(null);
+            mPreview = new BitmapTexture(b);
+        }
+        return mPreview;
+    }
+
+    @Override
+    public Bitmap getTile(int level, int x, int y, Bitmap bitmap) {
+        int tileSize = getTileSize();
+        if (bitmap == null) {
+            bitmap = Bitmap.createBitmap(tileSize, tileSize, Bitmap.Config.ARGB_8888);
+        }
+        Canvas c = new Canvas(bitmap);
+        Rect bounds = new Rect(0, 0, getImageWidth(), getImageHeight());
+        bounds.offset(-x, -y);
+        mDrawable.setBounds(bounds);
+        mDrawable.draw(c);
+        c.setBitmap(null);
+        return bitmap;
+    }
+}
diff --git a/src/com/android/launcher3/LiveWallpaperListAdapter.java b/WallpaperPicker/src/com/android/launcher3/LiveWallpaperListAdapter.java
similarity index 96%
rename from src/com/android/launcher3/LiveWallpaperListAdapter.java
rename to WallpaperPicker/src/com/android/launcher3/LiveWallpaperListAdapter.java
index 54e0af7..60b2537 100644
--- a/src/com/android/launcher3/LiveWallpaperListAdapter.java
+++ b/WallpaperPicker/src/com/android/launcher3/LiveWallpaperListAdapter.java
@@ -123,8 +123,7 @@
             preview.putExtra(WallpaperManager.EXTRA_LIVE_WALLPAPER_COMPONENT,
                     mInfo.getComponent());
             a.onLiveWallpaperPickerLaunch();
-            Utilities.startActivityForResultSafely(
-                    a, preview, WallpaperPickerActivity.PICK_LIVE_WALLPAPER);
+            a.startActivityForResultSafely(preview, WallpaperPickerActivity.PICK_LIVE_WALLPAPER);
         }
     }
 
@@ -190,7 +189,9 @@
                     LiveWallpaperListAdapter.this.notifyDataSetChanged();
                     break;
                 }
-                info.mThumbnail.setDither(true);
+                if (info.mThumbnail != null) {
+                    info.mThumbnail.setDither(true);
+                }
                 if (mWallpaperPosition < mWallpapers.size()) {
                     mWallpapers.set(mWallpaperPosition, info);
                 } else {
diff --git a/src/com/android/launcher3/SavedWallpaperImages.java b/WallpaperPicker/src/com/android/launcher3/SavedWallpaperImages.java
similarity index 88%
rename from src/com/android/launcher3/SavedWallpaperImages.java
rename to WallpaperPicker/src/com/android/launcher3/SavedWallpaperImages.java
index 8d5b005..44bfdf1 100644
--- a/src/com/android/launcher3/SavedWallpaperImages.java
+++ b/WallpaperPicker/src/com/android/launcher3/SavedWallpaperImages.java
@@ -60,12 +60,9 @@
         public void onClick(WallpaperPickerActivity a) {
             String imageFilename = a.getSavedImages().getImageFilename(mDbId);
             File file = new File(a.getFilesDir(), imageFilename);
-            CropView v = a.getCropView();
-            int rotation = WallpaperCropActivity.getRotationFromExif(file.getAbsolutePath());
-            v.setTileSource(
-                    new BitmapRegionTileSource(a, file.getAbsolutePath(), 1024, rotation), null);
-            v.moveToLeft();
-            v.setTouchEnabled(false);
+            BitmapRegionTileSource.FilePathBitmapSource bitmapSource =
+                    new BitmapRegionTileSource.FilePathBitmapSource(file.getAbsolutePath(), 1024);
+            a.setCropViewTileSource(bitmapSource, false, true, null);
         }
         @Override
         public void onSave(WallpaperPickerActivity a) {
@@ -88,6 +85,9 @@
     }
 
     public SavedWallpaperImages(Activity context) {
+        // We used to store the saved images in the cache directory, but that meant they'd get
+        // deleted sometimes-- move them to the data directory
+        ImageDb.moveFromCacheDirectoryIfNecessary(context);
         mDb = new ImageDb(context);
         mContext = context;
         mLayoutInflater = context.getLayoutInflater();
@@ -218,11 +218,20 @@
         Context mContext;
 
         public ImageDb(Context context) {
-            super(context, new File(context.getCacheDir(), DB_NAME).getPath(), null, DB_VERSION);
+            super(context, context.getDatabasePath(DB_NAME).getPath(), null, DB_VERSION);
             // Store the context for later use
             mContext = context;
         }
 
+        public static void moveFromCacheDirectoryIfNecessary(Context context) {
+            // We used to store the saved images in the cache directory, but that meant they'd get
+            // deleted sometimes-- move them to the data directory
+            File oldSavedImagesFile = new File(context.getCacheDir(), ImageDb.DB_NAME);
+            File savedImagesFile = context.getDatabasePath(ImageDb.DB_NAME);
+            if (oldSavedImagesFile.exists()) {
+                oldSavedImagesFile.renameTo(savedImagesFile);
+            }
+        }
         @Override
         public void onCreate(SQLiteDatabase database) {
             database.execSQL("CREATE TABLE IF NOT EXISTS " + TABLE_NAME + " (" +
diff --git a/src/com/android/launcher3/ThirdPartyWallpaperPickerListAdapter.java b/WallpaperPicker/src/com/android/launcher3/ThirdPartyWallpaperPickerListAdapter.java
similarity index 97%
rename from src/com/android/launcher3/ThirdPartyWallpaperPickerListAdapter.java
rename to WallpaperPicker/src/com/android/launcher3/ThirdPartyWallpaperPickerListAdapter.java
index 494694c..7a4d48c 100644
--- a/src/com/android/launcher3/ThirdPartyWallpaperPickerListAdapter.java
+++ b/WallpaperPicker/src/com/android/launcher3/ThirdPartyWallpaperPickerListAdapter.java
@@ -56,8 +56,8 @@
                     mResolveInfo.activityInfo.packageName, mResolveInfo.activityInfo.name);
             Intent launchIntent = new Intent(Intent.ACTION_SET_WALLPAPER);
             launchIntent.setComponent(itemComponentName);
-            Utilities.startActivityForResultSafely(
-                    a, launchIntent, WallpaperPickerActivity.PICK_WALLPAPER_THIRD_PARTY_ACTIVITY);
+            a.startActivityForResultSafely(
+                    launchIntent, WallpaperPickerActivity.PICK_WALLPAPER_THIRD_PARTY_ACTIVITY);
         }
     }
 
diff --git a/src/com/android/launcher3/WallpaperCropActivity.java b/WallpaperPicker/src/com/android/launcher3/WallpaperCropActivity.java
similarity index 73%
rename from src/com/android/launcher3/WallpaperCropActivity.java
rename to WallpaperPicker/src/com/android/launcher3/WallpaperCropActivity.java
index 30ec340..ee7b819 100644
--- a/src/com/android/launcher3/WallpaperCropActivity.java
+++ b/WallpaperPicker/src/com/android/launcher3/WallpaperCropActivity.java
@@ -37,15 +37,16 @@
 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 android.widget.Toast;
 
 import com.android.gallery3d.common.Utils;
 import com.android.gallery3d.exif.ExifInterface;
 import com.android.photos.BitmapRegionTileSource;
+import com.android.photos.BitmapRegionTileSource.BitmapSource;
 
 import java.io.BufferedInputStream;
 import java.io.ByteArrayInputStream;
@@ -70,6 +71,8 @@
     public static final int MAX_BMAP_IN_INTENT = 750000;
     private static final float WALLPAPER_SCREENS_SPAN = 2f;
 
+    protected static Point sDefaultWallpaperSize;
+
     protected CropView mCropView;
     protected Uri mUri;
 
@@ -96,9 +99,6 @@
             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
         final ActionBar actionBar = getActionBar();
@@ -111,6 +111,63 @@
                         cropImageAndSetWallpaper(imageUri, null, finishActivityWhenDone);
                     }
                 });
+
+        // Load image in background
+        final BitmapRegionTileSource.UriBitmapSource bitmapSource =
+                new BitmapRegionTileSource.UriBitmapSource(this, imageUri, 1024);
+        Runnable onLoad = new Runnable() {
+            public void run() {
+                if (bitmapSource.getLoadingState() != BitmapSource.State.LOADED) {
+                    Toast.makeText(WallpaperCropActivity.this,
+                            getString(R.string.wallpaper_load_fail),
+                            Toast.LENGTH_LONG).show();
+                    finish();
+                }
+            }
+        };
+        setCropViewTileSource(bitmapSource, true, false, onLoad);
+    }
+
+    public void setCropViewTileSource(
+            final BitmapRegionTileSource.BitmapSource bitmapSource, final boolean touchEnabled,
+            final boolean moveToLeft, final Runnable postExecute) {
+        final Context context = WallpaperCropActivity.this;
+        final View progressView = findViewById(R.id.loading);
+        final AsyncTask<Void, Void, Void> loadBitmapTask = new AsyncTask<Void, Void, Void>() {
+            protected Void doInBackground(Void...args) {
+                if (!isCancelled()) {
+                    bitmapSource.loadInBackground();
+                }
+                return null;
+            }
+            protected void onPostExecute(Void arg) {
+                if (!isCancelled()) {
+                    progressView.setVisibility(View.INVISIBLE);
+                    if (bitmapSource.getLoadingState() == BitmapSource.State.LOADED) {
+                        mCropView.setTileSource(
+                                new BitmapRegionTileSource(context, bitmapSource), null);
+                        mCropView.setTouchEnabled(touchEnabled);
+                        if (moveToLeft) {
+                            mCropView.moveToLeft();
+                        }
+                    }
+                }
+                if (postExecute != null) {
+                    postExecute.run();
+                }
+            }
+        };
+        // We don't want to show the spinner every time we load an image, because that would be
+        // annoying; instead, only start showing the spinner if loading the image has taken
+        // longer than 1 sec (ie 1000 ms)
+        progressView.postDelayed(new Runnable() {
+            public void run() {
+                if (loadBitmapTask.getStatus() != AsyncTask.Status.FINISHED) {
+                    progressView.setVisibility(View.VISIBLE);
+                }
+            }
+        }, 1000);
+        loadBitmapTask.execute();
     }
 
     public boolean enableRotation() {
@@ -149,32 +206,34 @@
     }
 
     static protected Point getDefaultWallpaperSize(Resources res, WindowManager windowManager) {
-        Point minDims = new Point();
-        Point maxDims = new Point();
-        windowManager.getDefaultDisplay().getCurrentSizeRange(minDims, maxDims);
+        if (sDefaultWallpaperSize == null) {
+            Point minDims = new Point();
+            Point maxDims = new Point();
+            windowManager.getDefaultDisplay().getCurrentSizeRange(minDims, maxDims);
 
-        int maxDim = Math.max(maxDims.x, maxDims.y);
-        int minDim = Math.max(minDims.x, minDims.y);
+            int maxDim = Math.max(maxDims.x, maxDims.y);
+            int minDim = Math.max(minDims.x, minDims.y);
 
-        if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.JELLY_BEAN_MR1) {
-            Point realSize = new Point();
-            windowManager.getDefaultDisplay().getRealSize(realSize);
-            maxDim = Math.max(realSize.x, realSize.y);
-            minDim = Math.min(realSize.x, realSize.y);
+            if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.JELLY_BEAN_MR1) {
+                Point realSize = new Point();
+                windowManager.getDefaultDisplay().getRealSize(realSize);
+                maxDim = Math.max(realSize.x, realSize.y);
+                minDim = Math.min(realSize.x, realSize.y);
+            }
+
+            // We need to ensure that there is enough extra space in the wallpaper
+            // for the intended parallax effects
+            final int defaultWidth, defaultHeight;
+            if (isScreenLarge(res)) {
+                defaultWidth = (int) (maxDim * wallpaperTravelToScreenWidthRatio(maxDim, minDim));
+                defaultHeight = maxDim;
+            } else {
+                defaultWidth = Math.max((int) (minDim * WALLPAPER_SCREENS_SPAN), maxDim);
+                defaultHeight = maxDim;
+            }
+            sDefaultWallpaperSize = new Point(defaultWidth, defaultHeight);
         }
-
-        // We need to ensure that there is enough extra space in the wallpaper
-        // for the intended
-        // parallax effects
-        final int defaultWidth, defaultHeight;
-        if (isScreenLarge(res)) {
-            defaultWidth = (int) (maxDim * wallpaperTravelToScreenWidthRatio(maxDim, minDim));
-            defaultHeight = maxDim;
-        } else {
-            defaultWidth = Math.max((int) (minDim * WALLPAPER_SCREENS_SPAN), maxDim);
-            defaultHeight = maxDim;
-        }
-        return new Point(defaultWidth, defaultHeight);
+        return sDefaultWallpaperSize;
     }
 
     public static int getRotationFromExif(String path) {
@@ -192,16 +251,18 @@
     private static int getRotationFromExifHelper(
             String path, Resources res, int resId, Context context, Uri uri) {
         ExifInterface ei = new ExifInterface();
+        InputStream is = null;
+        BufferedInputStream bis = null;
         try {
             if (path != null) {
                 ei.readExif(path);
             } else if (uri != null) {
-                InputStream is = context.getContentResolver().openInputStream(uri);
-                BufferedInputStream bis = new BufferedInputStream(is);
+                is = context.getContentResolver().openInputStream(uri);
+                bis = new BufferedInputStream(is);
                 ei.readExif(bis);
             } else {
-                InputStream is = res.openRawResource(resId);
-                BufferedInputStream bis = new BufferedInputStream(is);
+                is = res.openRawResource(resId);
+                bis = new BufferedInputStream(is);
                 ei.readExif(bis);
             }
             Integer ori = ei.getTagIntValue(ExifInterface.TAG_ORIENTATION);
@@ -210,6 +271,9 @@
             }
         } catch (IOException e) {
             Log.w(LOGTAG, "Getting exif data failed", e);
+        } finally {
+            Utils.closeSilently(bis);
+            Utils.closeSilently(is);
         }
         return 0;
     }
@@ -266,43 +330,18 @@
 
     protected void cropImageAndSetWallpaper(Uri uri,
             OnBitmapCroppedHandler onBitmapCroppedHandler, final boolean finishActivityWhenDone) {
+        boolean centerCrop = getResources().getBoolean(R.bool.center_crop);
         // Get the crop
         boolean ltr = mCropView.getLayoutDirection() == View.LAYOUT_DIRECTION_LTR;
 
-        Point minDims = new Point();
-        Point maxDims = new Point();
         Display d = getWindowManager().getDefaultDisplay();
-        d.getCurrentSizeRange(minDims, maxDims);
 
         Point displaySize = new Point();
         d.getSize(displaySize);
-
-        int maxDim = Math.max(maxDims.x, maxDims.y);
-        final int minDim = Math.min(minDims.x, minDims.y);
-        int defaultWallpaperWidth;
-        if (isScreenLarge(getResources())) {
-            defaultWallpaperWidth = (int) (maxDim *
-                    wallpaperTravelToScreenWidthRatio(maxDim, minDim));
-        } else {
-            defaultWallpaperWidth = Math.max((int)
-                    (minDim * WALLPAPER_SCREENS_SPAN), maxDim);
-        }
-
         boolean isPortrait = displaySize.x < displaySize.y;
-        int portraitHeight;
-        if (isPortrait) {
-            portraitHeight = mCropView.getHeight();
-        } else {
-            // TODO: how to actually get the proper portrait height?
-            // This is not quite right:
-            portraitHeight = Math.max(maxDims.x, maxDims.y);
-        }
-        if (android.os.Build.VERSION.SDK_INT >=
-                android.os.Build.VERSION_CODES.JELLY_BEAN_MR1) {
-            Point realSize = new Point();
-            d.getRealSize(realSize);
-            portraitHeight = Math.max(realSize.x, realSize.y);
-        }
+
+        Point defaultWallpaperSize = getDefaultWallpaperSize(getResources(),
+                getWindowManager());
         // Get the crop
         RectF cropRect = mCropView.getCrop();
         int cropRotation = mCropView.getImageRotation();
@@ -319,23 +358,33 @@
         // 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 ? rotatedInSize[0] - cropRect.right : cropRect.left;
+        float extraSpace;
+        if (centerCrop) {
+            extraSpace = 2f * Math.min(rotatedInSize[0] - cropRect.right, cropRect.left);
+        } else {
+            extraSpace = ltr ? rotatedInSize[0] - cropRect.right : cropRect.left;
+        }
         // Cap the amount of extra width
-        float maxExtraSpace = defaultWallpaperWidth / cropScale - cropRect.width();
+        float maxExtraSpace = defaultWallpaperSize.x / cropScale - cropRect.width();
         extraSpace = Math.min(extraSpace, maxExtraSpace);
 
-        if (ltr) {
-            cropRect.right += extraSpace;
+        if (centerCrop) {
+            cropRect.left -= extraSpace / 2f;
+            cropRect.right += extraSpace / 2f;
         } else {
-            cropRect.left -= extraSpace;
+            if (ltr) {
+                cropRect.right += extraSpace;
+            } else {
+                cropRect.left -= extraSpace;
+            }
         }
 
         // ADJUST CROP HEIGHT
         if (isPortrait) {
-            cropRect.bottom = cropRect.top + portraitHeight / cropScale;
+            cropRect.bottom = cropRect.top + defaultWallpaperSize.y / cropScale;
         } else { // LANDSCAPE
             float extraPortraitHeight =
-                    portraitHeight / cropScale - cropRect.height();
+                    defaultWallpaperSize.y / cropScale - cropRect.height();
             float expandHeight =
                     Math.min(Math.min(rotatedInSize[1] - cropRect.bottom, cropRect.top),
                             extraPortraitHeight / 2);
@@ -372,7 +421,6 @@
         String mInFilePath;
         byte[] mInImageBytes;
         int mInResId = 0;
-        InputStream mInStream;
         RectF mCropBounds = null;
         int mOutWidth, mOutHeight;
         int mRotation;
@@ -445,37 +493,36 @@
         }
 
         // Helper to setup input stream
-        private void regenerateInputStream() {
+        private InputStream regenerateInputStream() {
             if (mInUri == null && mInResId == 0 && mInFilePath == null && mInImageBytes == null) {
                 Log.w(LOGTAG, "cannot read original file, no input URI, resource ID, or " +
                         "image byte array given");
             } else {
-                Utils.closeSilently(mInStream);
                 try {
                     if (mInUri != null) {
-                        mInStream = new BufferedInputStream(
+                        return new BufferedInputStream(
                                 mContext.getContentResolver().openInputStream(mInUri));
                     } else if (mInFilePath != null) {
-                        mInStream = mContext.openFileInput(mInFilePath);
+                        return mContext.openFileInput(mInFilePath);
                     } else if (mInImageBytes != null) {
-                        mInStream = new BufferedInputStream(
-                                new ByteArrayInputStream(mInImageBytes));
+                        return new BufferedInputStream(new ByteArrayInputStream(mInImageBytes));
                     } else {
-                        mInStream = new BufferedInputStream(
-                                mResources.openRawResource(mInResId));
+                        return new BufferedInputStream(mResources.openRawResource(mInResId));
                     }
                 } catch (FileNotFoundException e) {
                     Log.w(LOGTAG, "cannot read file: " + mInUri.toString(), e);
                 }
             }
+            return null;
         }
 
         public Point getImageBounds() {
-            regenerateInputStream();
-            if (mInStream != null) {
+            InputStream is = regenerateInputStream();
+            if (is != null) {
                 BitmapFactory.Options options = new BitmapFactory.Options();
                 options.inJustDecodeBounds = true;
-                BitmapFactory.decodeStream(mInStream, null, options);
+                BitmapFactory.decodeStream(is, null, options);
+                Utils.closeSilently(is);
                 if (options.outWidth != 0 && options.outHeight != 0) {
                     return new Point(options.outWidth, options.outHeight);
                 }
@@ -493,26 +540,32 @@
         public boolean cropBitmap() {
             boolean failure = false;
 
-            regenerateInputStream();
 
             WallpaperManager wallpaperManager = null;
             if (mSetWallpaper) {
                 wallpaperManager = WallpaperManager.getInstance(mContext.getApplicationContext());
             }
-            if (mSetWallpaper && mNoCrop && mInStream != null) {
+
+
+            if (mSetWallpaper && mNoCrop) {
                 try {
-                    wallpaperManager.setStream(mInStream);
+                    InputStream is = regenerateInputStream();
+                    if (is != null) {
+                        wallpaperManager.setStream(is);
+                        Utils.closeSilently(is);
+                    }
                 } catch (IOException e) {
                     Log.w(LOGTAG, "cannot write stream to wallpaper", e);
                     failure = true;
                 }
                 return !failure;
-            }
-            if (mInStream != null) {
+            } else {
                 // Find crop bounds (scaled to original image size)
                 Rect roundedTrueCrop = new Rect();
                 Matrix rotateMatrix = new Matrix();
                 Matrix inverseRotateMatrix = new Matrix();
+
+                Point bounds = getImageBounds();
                 if (mRotation > 0) {
                     rotateMatrix.setRotate(mRotation);
                     inverseRotateMatrix.setRotate(-mRotation);
@@ -520,7 +573,11 @@
                     mCropBounds.roundOut(roundedTrueCrop);
                     mCropBounds = new RectF(roundedTrueCrop);
 
-                    Point bounds = getImageBounds();
+                    if (bounds == null) {
+                        Log.w(LOGTAG, "cannot get bounds for image");
+                        failure = true;
+                        return false;
+                    }
 
                     float[] rotatedBounds = new float[] { bounds.x, bounds.y };
                     rotateMatrix.mapPoints(rotatedBounds);
@@ -531,7 +588,6 @@
                     inverseRotateMatrix.mapRect(mCropBounds);
                     mCropBounds.offset(bounds.x/2, bounds.y/2);
 
-                    regenerateInputStream();
                 }
 
                 mCropBounds.roundOut(roundedTrueCrop);
@@ -543,15 +599,25 @@
                 }
 
                 // See how much we're reducing the size of the image
-                int scaleDownSampleSize = Math.min(roundedTrueCrop.width() / mOutWidth,
-                        roundedTrueCrop.height() / mOutHeight);
-
+                int scaleDownSampleSize = Math.max(1, Math.min(roundedTrueCrop.width() / mOutWidth,
+                        roundedTrueCrop.height() / mOutHeight));
                 // Attempt to open a region decoder
                 BitmapRegionDecoder decoder = null;
+                InputStream is = null;
                 try {
-                    decoder = BitmapRegionDecoder.newInstance(mInStream, true);
+                    is = regenerateInputStream();
+                    if (is == null) {
+                        Log.w(LOGTAG, "cannot get input stream for uri=" + mInUri.toString());
+                        failure = true;
+                        return false;
+                    }
+                    decoder = BitmapRegionDecoder.newInstance(is, false);
+                    Utils.closeSilently(is);
                 } catch (IOException e) {
                     Log.w(LOGTAG, "cannot open region decoder for file: " + mInUri.toString(), e);
+                } finally {
+                   Utils.closeSilently(is);
+                   is = null;
                 }
 
                 Bitmap crop = null;
@@ -567,22 +633,49 @@
 
                 if (crop == null) {
                     // BitmapRegionDecoder has failed, try to crop in-memory
-                    regenerateInputStream();
+                    is = regenerateInputStream();
                     Bitmap fullSize = null;
-                    if (mInStream != null) {
+                    if (is != null) {
                         BitmapFactory.Options options = new BitmapFactory.Options();
                         if (scaleDownSampleSize > 1) {
                             options.inSampleSize = scaleDownSampleSize;
                         }
-                        fullSize = BitmapFactory.decodeStream(mInStream, null, options);
+                        fullSize = BitmapFactory.decodeStream(is, null, options);
+                        Utils.closeSilently(is);
                     }
                     if (fullSize != null) {
+                        // Find out the true sample size that was used by the decoder
+                        scaleDownSampleSize = bounds.x / fullSize.getWidth();
                         mCropBounds.left /= scaleDownSampleSize;
                         mCropBounds.top /= scaleDownSampleSize;
                         mCropBounds.bottom /= scaleDownSampleSize;
                         mCropBounds.right /= scaleDownSampleSize;
                         mCropBounds.roundOut(roundedTrueCrop);
 
+                        // Adjust values to account for issues related to rounding
+                        if (roundedTrueCrop.width() > fullSize.getWidth()) {
+                            // Adjust the width
+                            roundedTrueCrop.right = roundedTrueCrop.left + fullSize.getWidth();
+                        }
+                        if (roundedTrueCrop.right > fullSize.getWidth()) {
+                            // Adjust the left value
+                            int adjustment = roundedTrueCrop.left -
+                                    Math.max(0, roundedTrueCrop.right - roundedTrueCrop.width());
+                            roundedTrueCrop.left -= adjustment;
+                            roundedTrueCrop.right -= adjustment;
+                        }
+                        if (roundedTrueCrop.height() > fullSize.getHeight()) {
+                            // Adjust the height
+                            roundedTrueCrop.bottom = roundedTrueCrop.top + fullSize.getHeight();
+                        }
+                        if (roundedTrueCrop.bottom > fullSize.getHeight()) {
+                            // Adjust the top value
+                            int adjustment = roundedTrueCrop.top -
+                                    Math.max(0, roundedTrueCrop.bottom - roundedTrueCrop.height());
+                            roundedTrueCrop.top -= adjustment;
+                            roundedTrueCrop.bottom -= adjustment;
+                        }
+
                         crop = Bitmap.createBitmap(fullSize, roundedTrueCrop.left,
                                 roundedTrueCrop.top, roundedTrueCrop.width(),
                                 roundedTrueCrop.height());
@@ -686,7 +779,7 @@
 
     protected void updateWallpaperDimensions(int width, int height) {
         String spKey = getSharedPreferencesKey();
-        SharedPreferences sp = getSharedPreferences(spKey, Context.MODE_PRIVATE);
+        SharedPreferences sp = getSharedPreferences(spKey, Context.MODE_MULTI_PROCESS);
         SharedPreferences.Editor editor = sp.edit();
         if (width != 0 && height != 0) {
             editor.putInt(WALLPAPER_WIDTH_KEY, width);
@@ -706,15 +799,13 @@
             WindowManager windowManager,
             final WallpaperManager wallpaperManager) {
         final Point defaultWallpaperSize = getDefaultWallpaperSize(res, windowManager);
-
-        new Thread("suggestWallpaperDimension") {
-            public void run() {
-                // If we have saved a wallpaper width/height, use that instead
-                int savedWidth = sharedPrefs.getInt(WALLPAPER_WIDTH_KEY, defaultWallpaperSize.x);
-                int savedHeight = sharedPrefs.getInt(WALLPAPER_HEIGHT_KEY, defaultWallpaperSize.y);
-                wallpaperManager.suggestDesiredDimensions(savedWidth, savedHeight);
-            }
-        }.start();
+        // If we have saved a wallpaper width/height, use that instead
+        int savedWidth = sharedPrefs.getInt(WALLPAPER_WIDTH_KEY, defaultWallpaperSize.x);
+        int savedHeight = sharedPrefs.getInt(WALLPAPER_HEIGHT_KEY, defaultWallpaperSize.y);
+        if (savedWidth != wallpaperManager.getDesiredMinimumWidth() ||
+                savedHeight != wallpaperManager.getDesiredMinimumHeight()) {
+            wallpaperManager.suggestDesiredDimensions(savedWidth, savedHeight);
+        }
     }
 
     protected static RectF getMaxCropRect(
diff --git a/src/com/android/launcher3/WallpaperPickerActivity.java b/WallpaperPicker/src/com/android/launcher3/WallpaperPickerActivity.java
similarity index 74%
rename from src/com/android/launcher3/WallpaperPickerActivity.java
rename to WallpaperPicker/src/com/android/launcher3/WallpaperPickerActivity.java
index e71a26b..c54e477 100644
--- a/src/com/android/launcher3/WallpaperPickerActivity.java
+++ b/WallpaperPicker/src/com/android/launcher3/WallpaperPickerActivity.java
@@ -31,7 +31,9 @@
 import android.database.DataSetObserver;
 import android.graphics.Bitmap;
 import android.graphics.BitmapFactory;
+import android.graphics.Canvas;
 import android.graphics.Matrix;
+import android.graphics.Paint;
 import android.graphics.Point;
 import android.graphics.PorterDuff;
 import android.graphics.Rect;
@@ -40,6 +42,8 @@
 import android.graphics.drawable.Drawable;
 import android.graphics.drawable.LevelListDrawable;
 import android.net.Uri;
+import android.os.AsyncTask;
+import android.os.Build;
 import android.os.Bundle;
 import android.provider.MediaStore;
 import android.util.Log;
@@ -51,10 +55,11 @@
 import android.view.MenuItem;
 import android.view.View;
 import android.view.View.OnClickListener;
+import android.view.View.OnLayoutChangeListener;
 import android.view.ViewGroup;
+import android.view.ViewPropertyAnimator;
 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;
@@ -63,15 +68,14 @@
 import android.widget.ImageView;
 import android.widget.LinearLayout;
 import android.widget.ListAdapter;
+import android.widget.Toast;
 
-import com.android.gallery3d.exif.ExifInterface;
 import com.android.photos.BitmapRegionTileSource;
+import com.android.photos.BitmapRegionTileSource.BitmapSource;
 
-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 {
@@ -81,8 +85,11 @@
     public static final int PICK_WALLPAPER_THIRD_PARTY_ACTIVITY = 6;
     public static final int PICK_LIVE_WALLPAPER = 7;
     private static final String TEMP_WALLPAPER_TILES = "TEMP_WALLPAPER_TILES";
+    private static final String SELECTED_INDEX = "SELECTED_INDEX";
+    private static final String OLD_DEFAULT_WALLPAPER_THUMBNAIL_FILENAME = "default_thumb.jpg";
+    private static final String DEFAULT_WALLPAPER_THUMBNAIL_FILENAME = "default_thumb2.jpg";
 
-    private View mSelectedThumb;
+    private View mSelectedTile;
     private boolean mIgnoreNextTap;
     private OnClickListener mThumbnailOnClickListener;
 
@@ -97,6 +104,7 @@
     ArrayList<Uri> mTempWallpaperTiles = new ArrayList<Uri>();
     private SavedWallpaperImages mSavedImages;
     private WallpaperInfo mLiveWallpaperInfoOnPickerLaunch;
+    private int mSelectedIndex;
 
     public static abstract class WallpaperTileInfo {
         protected View mView;
@@ -120,21 +128,44 @@
         public void onClick(WallpaperPickerActivity a) {
             Intent intent = new Intent(Intent.ACTION_GET_CONTENT);
             intent.setType("image/*");
-            Utilities.startActivityForResultSafely(a, intent, IMAGE_PICK);
+            a.startActivityForResultSafely(intent, IMAGE_PICK);
         }
     }
 
     public static class UriWallpaperInfo extends WallpaperTileInfo {
         private Uri mUri;
+        private boolean mFirstClick = true;
+        private BitmapRegionTileSource.UriBitmapSource mBitmapSource;
         public UriWallpaperInfo(Uri uri) {
             mUri = uri;
         }
         @Override
-        public void onClick(WallpaperPickerActivity a) {
-            CropView v = a.getCropView();
-            int rotation = WallpaperCropActivity.getRotationFromExif(a, mUri);
-            v.setTileSource(new BitmapRegionTileSource(a, mUri, 1024, rotation), null);
-            v.setTouchEnabled(true);
+        public void onClick(final WallpaperPickerActivity a) {
+            final Runnable onLoad;
+            if (!mFirstClick) {
+                onLoad = null;
+            } else {
+                mFirstClick = false;
+                onLoad = new Runnable() {
+                    public void run() {
+                        if (mBitmapSource != null &&
+                                mBitmapSource.getLoadingState() == BitmapSource.State.LOADED) {
+                            a.selectTile(mView);
+                        } else {
+                            ViewGroup parent = (ViewGroup) mView.getParent();
+                            if (parent != null) {
+                                parent.removeView(mView);
+                                Toast.makeText(a,
+                                        a.getString(R.string.image_load_fail),
+                                        Toast.LENGTH_SHORT).show();
+                            }
+                        }
+                    }
+                };
+            }
+            mBitmapSource = new BitmapRegionTileSource.UriBitmapSource(
+                    a, mUri, BitmapRegionTileSource.MAX_PREVIEW_SIZE);
+            a.setCropViewTileSource(mBitmapSource, true, false, onLoad);
         }
         @Override
         public void onSave(final WallpaperPickerActivity a) {
@@ -172,9 +203,11 @@
         }
         @Override
         public void onClick(WallpaperPickerActivity a) {
-            int rotation = WallpaperCropActivity.getRotationFromExif(mResources, mResId);
-            BitmapRegionTileSource source = new BitmapRegionTileSource(
-                    mResources, a, mResId, 1024, rotation);
+            BitmapRegionTileSource.ResourceBitmapSource bitmapSource =
+                    new BitmapRegionTileSource.ResourceBitmapSource(
+                            mResources, mResId, BitmapRegionTileSource.MAX_PREVIEW_SIZE);
+            bitmapSource.loadInBackground();
+            BitmapRegionTileSource source = new BitmapRegionTileSource(a, bitmapSource);
             CropView v = a.getCropView();
             v.setTileSource(source, null);
             Point wallpaperSize = WallpaperCropActivity.getDefaultWallpaperSize(
@@ -200,6 +233,42 @@
         }
     }
 
+    public static class DefaultWallpaperInfo extends WallpaperTileInfo {
+        public Drawable mThumb;
+        public DefaultWallpaperInfo(Drawable thumb) {
+            mThumb = thumb;
+        }
+        @Override
+        public void onClick(WallpaperPickerActivity a) {
+            CropView c = a.getCropView();
+
+            Drawable defaultWallpaper = WallpaperManager.getInstance(a).getBuiltInDrawable(
+                    c.getWidth(), c.getHeight(), false, 0.5f, 0.5f);
+
+            c.setTileSource(
+                    new DrawableTileSource(a, defaultWallpaper, DrawableTileSource.MAX_PREVIEW_SIZE), null);
+            c.setScale(1f);
+            c.setTouchEnabled(false);
+        }
+        @Override
+        public void onSave(WallpaperPickerActivity a) {
+            try {
+                WallpaperManager.getInstance(a).clear();
+            } catch (IOException e) {
+                Log.w("Setting wallpaper to default threw exception", e);
+            }
+            a.finish();
+        }
+        @Override
+        public boolean isSelectable() {
+            return true;
+        }
+        @Override
+        public boolean isNamelessWallpaper() {
+            return true;
+        }
+    }
+
     public void setWallpaperStripYOffset(float offset) {
         mWallpaperStrip.setPadding(0, 0, 0, (int) offset);
     }
@@ -211,7 +280,7 @@
         mCropView = (CropView) findViewById(R.id.cropView);
         mWallpaperStrip = findViewById(R.id.wallpaper_strip);
         mCropView.setTouchCallback(new CropView.TouchCallback() {
-            LauncherViewPropertyAnimator mAnim;
+            ViewPropertyAnimator mAnim;
             @Override
             public void onTouchDown() {
                 if (mAnim != null) {
@@ -220,17 +289,14 @@
                 if (mWallpaperStrip.getAlpha() == 1f) {
                     mIgnoreNextTap = true;
                 }
-                mAnim = new LauncherViewPropertyAnimator(mWallpaperStrip);
+                mAnim = mWallpaperStrip.animate();
                 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) { }
-                     });
+                    .setDuration(150)
+                    .withEndAction(new Runnable() {
+                        public void run() {
+                            mWallpaperStrip.setVisibility(View.INVISIBLE);
+                        }
+                    });
                 mAnim.setInterpolator(new AccelerateInterpolator(0.75f));
                 mAnim.start();
             }
@@ -247,7 +313,7 @@
                         mAnim.cancel();
                     }
                     mWallpaperStrip.setVisibility(View.VISIBLE);
-                    mAnim = new LauncherViewPropertyAnimator(mWallpaperStrip);
+                    mAnim = mWallpaperStrip.animate();
                     mAnim.alpha(1f)
                          .setDuration(150)
                          .setInterpolator(new DecelerateInterpolator(0.75f));
@@ -266,17 +332,8 @@
                     return;
                 }
                 WallpaperTileInfo info = (WallpaperTileInfo) v.getTag();
-                if (info.isSelectable()) {
-                    if (mSelectedThumb != null) {
-                        mSelectedThumb.setSelected(false);
-                        mSelectedThumb = null;
-                    }
-                    mSelectedThumb = v;
-                    v.setSelected(true);
-                    // TODO: Remove this once the accessibility framework and
-                    // services have better support for selection state.
-                    v.announceForAccessibility(
-                            getString(R.string.announce_selection, v.getContentDescription()));
+                if (info.isSelectable() && v.getVisibility() == View.VISIBLE) {
+                    selectTile(v);
                 }
                 info.onClick(WallpaperPickerActivity.this);
             }
@@ -305,12 +362,12 @@
         ArrayList<ResourceWallpaperInfo> wallpapers = findBundledWallpapers();
         mWallpapersView = (LinearLayout) findViewById(R.id.wallpaper_list);
         BuiltInWallpapersAdapter ia = new BuiltInWallpapersAdapter(this, wallpapers);
-        populateWallpapersFromAdapter(mWallpapersView, ia, false, true);
+        populateWallpapersFromAdapter(mWallpapersView, ia, false);
 
         // Populate the saved wallpapers
         mSavedImages = new SavedWallpaperImages(this);
         mSavedImages.loadThumbnailsAndImageIdList();
-        populateWallpapersFromAdapter(mWallpapersView, mSavedImages, true, true);
+        populateWallpapersFromAdapter(mWallpapersView, mSavedImages, true);
 
         // Populate the live wallpapers
         final LinearLayout liveWallpapersView =
@@ -319,7 +376,7 @@
         a.registerDataSetObserver(new DataSetObserver() {
             public void onChanged() {
                 liveWallpapersView.removeAllViews();
-                populateWallpapersFromAdapter(liveWallpapersView, a, false, false);
+                populateWallpapersFromAdapter(liveWallpapersView, a, false);
                 initializeScrollForRtl();
                 updateTileIndices();
             }
@@ -330,7 +387,7 @@
                 (LinearLayout) findViewById(R.id.third_party_wallpaper_list);
         final ThirdPartyWallpaperPickerListAdapter ta =
                 new ThirdPartyWallpaperPickerListAdapter(this);
-        populateWallpapersFromAdapter(thirdPartyWallpapersView, ta, false, false);
+        populateWallpapersFromAdapter(thirdPartyWallpapersView, ta, false);
 
         // Add a tile for the Gallery
         LinearLayout masterWallpaperList = (LinearLayout) findViewById(R.id.master_wallpaper_list);
@@ -354,7 +411,34 @@
         pickImageTile.setTag(pickImageInfo);
         pickImageInfo.setView(pickImageTile);
         pickImageTile.setOnClickListener(mThumbnailOnClickListener);
-        pickImageInfo.setView(pickImageTile);
+
+        // Add a tile for the default wallpaper
+        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) {
+            DefaultWallpaperInfo defaultWallpaperInfo = getDefaultWallpaper();
+            FrameLayout defaultWallpaperTile = (FrameLayout) createImageTileView(
+                    getLayoutInflater(), 0, null, mWallpapersView, defaultWallpaperInfo.mThumb);
+            setWallpaperItemPaddingToZero(defaultWallpaperTile);
+            defaultWallpaperTile.setTag(defaultWallpaperInfo);
+            mWallpapersView.addView(defaultWallpaperTile, 0);
+            defaultWallpaperTile.setOnClickListener(mThumbnailOnClickListener);
+            defaultWallpaperInfo.setView(defaultWallpaperTile);
+        }
+
+        // Select the first item; wait for a layout pass so that we initialize the dimensions of
+        // cropView or the defaultWallpaperView first
+        mCropView.addOnLayoutChangeListener(new OnLayoutChangeListener() {
+            @Override
+            public void onLayoutChange(View v, int left, int top, int right, int bottom,
+                    int oldLeft, int oldTop, int oldRight, int oldBottom) {
+                if ((right - left) > 0 && (bottom - top) > 0) {
+                    if (mSelectedIndex >= 0 && mSelectedIndex < mWallpapersView.getChildCount()) {
+                        mThumbnailOnClickListener.onClick(
+                                mWallpapersView.getChildAt(mSelectedIndex));
+                    }
+                    v.removeOnLayoutChangeListener(this);
+                }
+            }
+        });
 
         updateTileIndices();
 
@@ -376,8 +460,8 @@
                 new View.OnClickListener() {
                     @Override
                     public void onClick(View v) {
-                        if (mSelectedThumb != null) {
-                            WallpaperTileInfo info = (WallpaperTileInfo) mSelectedThumb.getTag();
+                        if (mSelectedTile != null) {
+                            WallpaperTileInfo info = (WallpaperTileInfo) mSelectedTile.getTag();
                             info.onSave(WallpaperPickerActivity.this);
                         }
                     }
@@ -456,12 +540,26 @@
                     CheckableFrameLayout c = (CheckableFrameLayout) mWallpapersView.getChildAt(i);
                     c.setChecked(false);
                 }
-                mSelectedThumb.setSelected(true);
+                mSelectedTile.setSelected(true);
                 mActionMode = null;
             }
         };
     }
 
+    private void selectTile(View v) {
+        if (mSelectedTile != null) {
+            mSelectedTile.setSelected(false);
+            mSelectedTile = null;
+        }
+        mSelectedTile = v;
+        v.setSelected(true);
+        mSelectedIndex = mWallpapersView.indexOfChild(v);
+        // TODO: Remove this once the accessibility framework and
+        // services have better support for selection state.
+        v.announceForAccessibility(
+                getString(R.string.announce_selection, v.getContentDescription()));
+    }
+
     private void initializeScrollForRtl() {
         final HorizontalScrollView scroll =
                 (HorizontalScrollView) findViewById(R.id.wallpaper_scroll_container);
@@ -479,10 +577,6 @@
         }
     }
 
-    public boolean enableRotation() {
-        return super.enableRotation() || Launcher.sForceEnableRotation;
-    }
-
     protected Bitmap getThumbnailOfLastPhoto() {
         Cursor cursor = MediaStore.Images.Media.query(getContentResolver(),
                 MediaStore.Images.Media.EXTERNAL_CONTENT_URI,
@@ -510,17 +604,19 @@
 
     protected void onSaveInstanceState(Bundle outState) {
         outState.putParcelableArrayList(TEMP_WALLPAPER_TILES, mTempWallpaperTiles);
+        outState.putInt(SELECTED_INDEX, mSelectedIndex);
     }
 
     protected void onRestoreInstanceState(Bundle savedInstanceState) {
         ArrayList<Uri> uris = savedInstanceState.getParcelableArrayList(TEMP_WALLPAPER_TILES);
         for (Uri uri : uris) {
-            addTemporaryWallpaperTile(uri);
+            addTemporaryWallpaperTile(uri, true);
         }
+        mSelectedIndex = savedInstanceState.getInt(SELECTED_INDEX, 0);
     }
 
     private void populateWallpapersFromAdapter(ViewGroup parent, BaseAdapter adapter,
-            boolean addLongPressHandler, boolean selectFirstTile) {
+            boolean addLongPressHandler) {
         for (int i = 0; i < adapter.getCount(); i++) {
             FrameLayout thumbnail = (FrameLayout) adapter.getView(i, null, parent);
             parent.addView(thumbnail, i);
@@ -531,9 +627,6 @@
                 addLongPressHandler(thumbnail);
             }
             thumbnail.setOnClickListener(mThumbnailOnClickListener);
-            if (i == 0 && selectFirstTile) {
-                mThumbnailOnClickListener.onClick(thumbnail);
-            }
         }
     }
 
@@ -623,26 +716,36 @@
         }
     }
 
-    private void addTemporaryWallpaperTile(Uri uri) {
+    private void addTemporaryWallpaperTile(final Uri uri, boolean fromRestore) {
         mTempWallpaperTiles.add(uri);
         // Add a tile for the image picked from Gallery
-        FrameLayout pickedImageThumbnail = (FrameLayout) getLayoutInflater().
+        final FrameLayout pickedImageThumbnail = (FrameLayout) getLayoutInflater().
                 inflate(R.layout.wallpaper_picker_item, mWallpapersView, false);
+        pickedImageThumbnail.setVisibility(View.GONE);
         setWallpaperItemPaddingToZero(pickedImageThumbnail);
+        mWallpapersView.addView(pickedImageThumbnail, 0);
 
         // Load the thumbnail
-        ImageView image = (ImageView) pickedImageThumbnail.findViewById(R.id.wallpaper_image);
-        Point defaultSize = getDefaultThumbnailSize(this.getResources());
-        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();
-            thumbDrawable.setDither(true);
-        } else {
-            Log.e(TAG, "Error loading thumbnail for uri=" + uri);
-        }
-        mWallpapersView.addView(pickedImageThumbnail, 0);
+        final ImageView image = (ImageView) pickedImageThumbnail.findViewById(R.id.wallpaper_image);
+        final Point defaultSize = getDefaultThumbnailSize(this.getResources());
+        final Context context = this;
+        new AsyncTask<Void, Bitmap, Bitmap>() {
+            protected Bitmap doInBackground(Void...args) {
+                int rotation = WallpaperCropActivity.getRotationFromExif(context, uri);
+                return createThumbnail(defaultSize, context, uri, null, null, 0, rotation, false);
+
+            }
+            protected void onPostExecute(Bitmap thumb) {
+                if (thumb != null) {
+                    image.setImageBitmap(thumb);
+                    Drawable thumbDrawable = image.getDrawable();
+                    thumbDrawable.setDither(true);
+                    pickedImageThumbnail.setVisibility(View.VISIBLE);
+                } else {
+                    Log.e(TAG, "Error loading thumbnail for uri=" + uri);
+                }
+            }
+        }.execute();
 
         UriWallpaperInfo info = new UriWallpaperInfo(uri);
         pickedImageThumbnail.setTag(info);
@@ -650,14 +753,16 @@
         addLongPressHandler(pickedImageThumbnail);
         updateTileIndices();
         pickedImageThumbnail.setOnClickListener(mThumbnailOnClickListener);
-        mThumbnailOnClickListener.onClick(pickedImageThumbnail);
+        if (!fromRestore) {
+            mThumbnailOnClickListener.onClick(pickedImageThumbnail);
+        }
     }
 
     protected void onActivityResult(int requestCode, int resultCode, Intent data) {
         if (requestCode == IMAGE_PICK && resultCode == RESULT_OK) {
             if (data != null && data.getData() != null) {
                 Uri uri = data.getData();
-                addTemporaryWallpaperTile(uri);
+                addTemporaryWallpaperTile(uri, false);
             }
         } else if (requestCode == PICK_WALLPAPER_THIRD_PARTY_ACTIVITY) {
             setResult(RESULT_OK);
@@ -700,18 +805,35 @@
         }
 
         // Add an entry for the default wallpaper (stored in system resources)
-        ResourceWallpaperInfo defaultWallpaperInfo = getDefaultWallpaperInfo();
-        if (defaultWallpaperInfo != null) {
-            bundledWallpapers.add(0, defaultWallpaperInfo);
+        if (Build.VERSION.SDK_INT < Build.VERSION_CODES.KITKAT) {
+            ResourceWallpaperInfo defaultWallpaperInfo = getPreKKDefaultWallpaperInfo();
+            if (defaultWallpaperInfo != null) {
+                bundledWallpapers.add(0, defaultWallpaperInfo);
+            }
         }
         return bundledWallpapers;
     }
 
-    private ResourceWallpaperInfo getDefaultWallpaperInfo() {
+    private boolean writeImageToFileAsJpeg(File f, Bitmap b) {
+        try {
+            f.createNewFile();
+            FileOutputStream thumbFileStream =
+                    openFileOutput(f.getName(), Context.MODE_PRIVATE);
+            b.compress(Bitmap.CompressFormat.JPEG, 95, thumbFileStream);
+            thumbFileStream.close();
+            return true;
+        } catch (IOException e) {
+            Log.e(TAG, "Error while writing bitmap to file " + e);
+            f.delete();
+        }
+        return false;
+    }
+
+    private ResourceWallpaperInfo getPreKKDefaultWallpaperInfo() {
         Resources sysRes = Resources.getSystem();
         int resId = sysRes.getIdentifier("default_wallpaper", "drawable", "android");
 
-        File defaultThumbFile = new File(getFilesDir(), "default_thumb.jpg");
+        File defaultThumbFile = new File(getFilesDir(), DEFAULT_WALLPAPER_THUMBNAIL_FILENAME);
         Bitmap thumb = null;
         boolean defaultWallpaperExists = false;
         if (defaultThumbFile.exists()) {
@@ -724,17 +846,7 @@
             thumb = createThumbnail(
                     defaultThumbSize, this, null, null, sysRes, resId, rotation, false);
             if (thumb != null) {
-                try {
-                    defaultThumbFile.createNewFile();
-                    FileOutputStream thumbFileStream =
-                            openFileOutput(defaultThumbFile.getName(), Context.MODE_PRIVATE);
-                    thumb.compress(Bitmap.CompressFormat.JPEG, 95, thumbFileStream);
-                    thumbFileStream.close();
-                    defaultWallpaperExists = true;
-                } catch (IOException e) {
-                    Log.e(TAG, "Error while writing default wallpaper thumbnail to file " + e);
-                    defaultThumbFile.delete();
-                }
+                defaultWallpaperExists = writeImageToFileAsJpeg(defaultThumbFile, thumb);
             }
         }
         if (defaultWallpaperExists) {
@@ -743,6 +855,40 @@
         return null;
     }
 
+    private DefaultWallpaperInfo getDefaultWallpaper() {
+        File defaultThumbFile = new File(getFilesDir(), DEFAULT_WALLPAPER_THUMBNAIL_FILENAME);
+        Bitmap thumb = null;
+        boolean defaultWallpaperExists = false;
+        if (defaultThumbFile.exists()) {
+            thumb = BitmapFactory.decodeFile(defaultThumbFile.getAbsolutePath());
+            defaultWallpaperExists = true;
+        } else {
+            // Delete old thumbnail file, since we had a bug where the thumbnail wasn't being drawn
+            // before
+            new File(getFilesDir(), OLD_DEFAULT_WALLPAPER_THUMBNAIL_FILENAME).delete();
+
+            Resources res = getResources();
+            Point defaultThumbSize = getDefaultThumbnailSize(res);
+            Drawable wallpaperDrawable = WallpaperManager.getInstance(this).getBuiltInDrawable(
+                    defaultThumbSize.x, defaultThumbSize.y, true, 0.5f, 0.5f);
+            if (wallpaperDrawable != null) {
+                thumb = Bitmap.createBitmap(
+                        defaultThumbSize.x, defaultThumbSize.y, Bitmap.Config.ARGB_8888);
+                Canvas c = new Canvas(thumb);
+                wallpaperDrawable.setBounds(0, 0, defaultThumbSize.x, defaultThumbSize.y);
+                wallpaperDrawable.draw(c);
+                c.setBitmap(null);
+            }
+            if (thumb != null) {
+                defaultWallpaperExists = writeImageToFileAsJpeg(defaultThumbFile, thumb);
+            }
+        }
+        if (defaultWallpaperExists) {
+            return new DefaultWallpaperInfo(new BitmapDrawable(thumb));
+        }
+        return null;
+    }
+
     public Pair<ApplicationInfo, Integer> getWallpaperArrayResourceId() {
         // Context.getPackageName() may return the "original" package name,
         // com.android.launcher3; Resources needs the real package name,
@@ -857,4 +1003,10 @@
 
         return view;
     }
+
+    // In Launcher3, we override this with a method that catches exceptions
+    // from starting activities; didn't want to copy and paste code into here
+    public void startActivityForResultSafely(Intent intent, int requestCode) {
+        startActivityForResult(intent, requestCode);
+    }
 }
diff --git a/src/com/android/launcher3/WallpaperRootView.java b/WallpaperPicker/src/com/android/launcher3/WallpaperRootView.java
similarity index 100%
rename from src/com/android/launcher3/WallpaperRootView.java
rename to WallpaperPicker/src/com/android/launcher3/WallpaperRootView.java
diff --git a/WallpaperPicker/src/com/android/photos/BitmapRegionTileSource.java b/WallpaperPicker/src/com/android/photos/BitmapRegionTileSource.java
new file mode 100644
index 0000000..cdc5cdc
--- /dev/null
+++ b/WallpaperPicker/src/com/android/photos/BitmapRegionTileSource.java
@@ -0,0 +1,522 @@
+/*
+ * Copyright (C) 2013 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.photos;
+
+import android.annotation.TargetApi;
+import android.content.Context;
+import android.content.res.Resources;
+import android.graphics.Bitmap;
+import android.graphics.Bitmap.Config;
+import android.graphics.BitmapFactory;
+import android.graphics.BitmapRegionDecoder;
+import android.graphics.Canvas;
+import android.graphics.Paint;
+import android.graphics.Rect;
+import android.net.Uri;
+import android.os.Build;
+import android.os.Build.VERSION_CODES;
+import android.util.Log;
+
+import com.android.gallery3d.common.BitmapUtils;
+import com.android.gallery3d.common.Utils;
+import com.android.gallery3d.exif.ExifInterface;
+import com.android.gallery3d.glrenderer.BasicTexture;
+import com.android.gallery3d.glrenderer.BitmapTexture;
+import com.android.photos.views.TiledImageRenderer;
+
+import java.io.BufferedInputStream;
+import java.io.FileNotFoundException;
+import java.io.IOException;
+import java.io.InputStream;
+
+interface SimpleBitmapRegionDecoder {
+    int getWidth();
+    int getHeight();
+    Bitmap decodeRegion(Rect wantRegion, BitmapFactory.Options options);
+}
+
+class SimpleBitmapRegionDecoderWrapper implements SimpleBitmapRegionDecoder {
+    BitmapRegionDecoder mDecoder;
+    private SimpleBitmapRegionDecoderWrapper(BitmapRegionDecoder decoder) {
+        mDecoder = decoder;
+    }
+    public static SimpleBitmapRegionDecoderWrapper newInstance(
+            String pathName, boolean isShareable) {
+        try {
+            BitmapRegionDecoder d = BitmapRegionDecoder.newInstance(pathName, isShareable);
+            if (d != null) {
+                return new SimpleBitmapRegionDecoderWrapper(d);
+            }
+        } catch (IOException e) {
+            Log.w("BitmapRegionTileSource", "getting decoder failed for path " + pathName, e);
+            return null;
+        }
+        return null;
+    }
+    public static SimpleBitmapRegionDecoderWrapper newInstance(
+            InputStream is, boolean isShareable) {
+        try {
+            BitmapRegionDecoder d = BitmapRegionDecoder.newInstance(is, isShareable);
+            if (d != null) {
+                return new SimpleBitmapRegionDecoderWrapper(d);
+            }
+        } catch (IOException e) {
+            Log.w("BitmapRegionTileSource", "getting decoder failed", e);
+            return null;
+        }
+        return null;
+    }
+    public int getWidth() {
+        return mDecoder.getWidth();
+    }
+    public int getHeight() {
+        return mDecoder.getHeight();
+    }
+    public Bitmap decodeRegion(Rect wantRegion, BitmapFactory.Options options) {
+        return mDecoder.decodeRegion(wantRegion, options);
+    }
+}
+
+class DumbBitmapRegionDecoder implements SimpleBitmapRegionDecoder {
+    Bitmap mBuffer;
+    Canvas mTempCanvas;
+    Paint mTempPaint;
+    private DumbBitmapRegionDecoder(Bitmap b) {
+        mBuffer = b;
+    }
+    public static DumbBitmapRegionDecoder newInstance(String pathName) {
+        Bitmap b = BitmapFactory.decodeFile(pathName);
+        if (b != null) {
+            return new DumbBitmapRegionDecoder(b);
+        }
+        return null;
+    }
+    public static DumbBitmapRegionDecoder newInstance(InputStream is) {
+        Bitmap b = BitmapFactory.decodeStream(is);
+        if (b != null) {
+            return new DumbBitmapRegionDecoder(b);
+        }
+        return null;
+    }
+    public int getWidth() {
+        return mBuffer.getWidth();
+    }
+    public int getHeight() {
+        return mBuffer.getHeight();
+    }
+    public Bitmap decodeRegion(Rect wantRegion, BitmapFactory.Options options) {
+        if (mTempCanvas == null) {
+            mTempCanvas = new Canvas();
+            mTempPaint = new Paint();
+            mTempPaint.setFilterBitmap(true);
+        }
+        int sampleSize = Math.max(options.inSampleSize, 1);
+        Bitmap newBitmap = Bitmap.createBitmap(
+                wantRegion.width() / sampleSize,
+                wantRegion.height() / sampleSize,
+                Bitmap.Config.ARGB_8888);
+        mTempCanvas.setBitmap(newBitmap);
+        mTempCanvas.save();
+        mTempCanvas.scale(1f / sampleSize, 1f / sampleSize);
+        mTempCanvas.drawBitmap(mBuffer, -wantRegion.left, -wantRegion.top, mTempPaint);
+        mTempCanvas.restore();
+        mTempCanvas.setBitmap(null);
+        return newBitmap;
+    }
+}
+
+/**
+ * A {@link com.android.photos.views.TiledImageRenderer.TileSource} using
+ * {@link BitmapRegionDecoder} to wrap a local file
+ */
+@TargetApi(Build.VERSION_CODES.ICE_CREAM_SANDWICH_MR1)
+public class BitmapRegionTileSource implements TiledImageRenderer.TileSource {
+
+    private static final String TAG = "BitmapRegionTileSource";
+
+    private static final boolean REUSE_BITMAP =
+            Build.VERSION.SDK_INT >= VERSION_CODES.JELLY_BEAN;
+    private static final int GL_SIZE_LIMIT = 2048;
+    // This must be no larger than half the size of the GL_SIZE_LIMIT
+    // due to decodePreview being allowed to be up to 2x the size of the target
+    public static final int MAX_PREVIEW_SIZE = GL_SIZE_LIMIT / 2;
+
+    public static abstract class BitmapSource {
+        private SimpleBitmapRegionDecoder mDecoder;
+        private Bitmap mPreview;
+        private int mPreviewSize;
+        private int mRotation;
+        public enum State { NOT_LOADED, LOADED, ERROR_LOADING };
+        private State mState = State.NOT_LOADED;
+        public BitmapSource(int previewSize) {
+            mPreviewSize = previewSize;
+        }
+        public boolean loadInBackground() {
+            ExifInterface ei = new ExifInterface();
+            if (readExif(ei)) {
+                Integer ori = ei.getTagIntValue(ExifInterface.TAG_ORIENTATION);
+                if (ori != null) {
+                    mRotation = ExifInterface.getRotationForOrientationValue(ori.shortValue());
+                }
+            }
+            mDecoder = loadBitmapRegionDecoder();
+            if (mDecoder == null) {
+                mState = State.ERROR_LOADING;
+                return false;
+            } else {
+                int width = mDecoder.getWidth();
+                int height = mDecoder.getHeight();
+                if (mPreviewSize != 0) {
+                    int previewSize = Math.min(mPreviewSize, MAX_PREVIEW_SIZE);
+                    BitmapFactory.Options opts = new BitmapFactory.Options();
+                    opts.inPreferredConfig = Bitmap.Config.ARGB_8888;
+                    opts.inPreferQualityOverSpeed = true;
+
+                    float scale = (float) previewSize / Math.max(width, height);
+                    opts.inSampleSize = BitmapUtils.computeSampleSizeLarger(scale);
+                    opts.inJustDecodeBounds = false;
+                    mPreview = loadPreviewBitmap(opts);
+                }
+                mState = State.LOADED;
+                return true;
+            }
+        }
+
+        public State getLoadingState() {
+            return mState;
+        }
+
+        public SimpleBitmapRegionDecoder getBitmapRegionDecoder() {
+            return mDecoder;
+        }
+
+        public Bitmap getPreviewBitmap() {
+            return mPreview;
+        }
+
+        public int getPreviewSize() {
+            return mPreviewSize;
+        }
+
+        public int getRotation() {
+            return mRotation;
+        }
+
+        public abstract boolean readExif(ExifInterface ei);
+        public abstract SimpleBitmapRegionDecoder loadBitmapRegionDecoder();
+        public abstract Bitmap loadPreviewBitmap(BitmapFactory.Options options);
+    }
+
+    public static class FilePathBitmapSource extends BitmapSource {
+        private String mPath;
+        public FilePathBitmapSource(String path, int previewSize) {
+            super(previewSize);
+            mPath = path;
+        }
+        @Override
+        public SimpleBitmapRegionDecoder loadBitmapRegionDecoder() {
+            SimpleBitmapRegionDecoder d;
+            d = SimpleBitmapRegionDecoderWrapper.newInstance(mPath, true);
+            if (d == null) {
+                d = DumbBitmapRegionDecoder.newInstance(mPath);
+            }
+            return d;
+        }
+        @Override
+        public Bitmap loadPreviewBitmap(BitmapFactory.Options options) {
+            return BitmapFactory.decodeFile(mPath, options);
+        }
+        @Override
+        public boolean readExif(ExifInterface ei) {
+            try {
+                ei.readExif(mPath);
+                return true;
+            } catch (IOException e) {
+                Log.w("BitmapRegionTileSource", "getting decoder failed", e);
+                return false;
+            }
+        }
+    }
+
+    public static class UriBitmapSource extends BitmapSource {
+        private Context mContext;
+        private Uri mUri;
+        public UriBitmapSource(Context context, Uri uri, int previewSize) {
+            super(previewSize);
+            mContext = context;
+            mUri = uri;
+        }
+        private InputStream regenerateInputStream() throws FileNotFoundException {
+            InputStream is = mContext.getContentResolver().openInputStream(mUri);
+            return new BufferedInputStream(is);
+        }
+        @Override
+        public SimpleBitmapRegionDecoder loadBitmapRegionDecoder() {
+            try {
+                InputStream is = regenerateInputStream();
+                SimpleBitmapRegionDecoder regionDecoder =
+                        SimpleBitmapRegionDecoderWrapper.newInstance(is, false);
+                Utils.closeSilently(is);
+                if (regionDecoder == null) {
+                    is = regenerateInputStream();
+                    regionDecoder = DumbBitmapRegionDecoder.newInstance(is);
+                    Utils.closeSilently(is);
+                }
+                return regionDecoder;
+            } catch (FileNotFoundException e) {
+                Log.e("BitmapRegionTileSource", "Failed to load URI " + mUri, e);
+                return null;
+            } catch (IOException e) {
+                Log.e("BitmapRegionTileSource", "Failure while reading URI " + mUri, e);
+                return null;
+            }
+        }
+        @Override
+        public Bitmap loadPreviewBitmap(BitmapFactory.Options options) {
+            try {
+                InputStream is = regenerateInputStream();
+                Bitmap b = BitmapFactory.decodeStream(is, null, options);
+                Utils.closeSilently(is);
+                return b;
+            } catch (FileNotFoundException e) {
+                Log.e("BitmapRegionTileSource", "Failed to load URI " + mUri, e);
+                return null;
+            }
+        }
+        @Override
+        public boolean readExif(ExifInterface ei) {
+            InputStream is = null;
+            try {
+                is = regenerateInputStream();
+                ei.readExif(is);
+                Utils.closeSilently(is);
+                return true;
+            } catch (FileNotFoundException e) {
+                Log.e("BitmapRegionTileSource", "Failed to load URI " + mUri, e);
+                return false;
+            } catch (IOException e) {
+                Log.e("BitmapRegionTileSource", "Failed to load URI " + mUri, e);
+                return false;
+            } finally {
+                Utils.closeSilently(is);
+            }
+        }
+    }
+
+    public static class ResourceBitmapSource extends BitmapSource {
+        private Resources mRes;
+        private int mResId;
+        public ResourceBitmapSource(Resources res, int resId, int previewSize) {
+            super(previewSize);
+            mRes = res;
+            mResId = resId;
+        }
+        private InputStream regenerateInputStream() {
+            InputStream is = mRes.openRawResource(mResId);
+            return new BufferedInputStream(is);
+        }
+        @Override
+        public SimpleBitmapRegionDecoder loadBitmapRegionDecoder() {
+            InputStream is = regenerateInputStream();
+            SimpleBitmapRegionDecoder regionDecoder =
+                    SimpleBitmapRegionDecoderWrapper.newInstance(is, false);
+            Utils.closeSilently(is);
+            if (regionDecoder == null) {
+                is = regenerateInputStream();
+                regionDecoder = DumbBitmapRegionDecoder.newInstance(is);
+                Utils.closeSilently(is);
+            }
+            return regionDecoder;
+        }
+        @Override
+        public Bitmap loadPreviewBitmap(BitmapFactory.Options options) {
+            return BitmapFactory.decodeResource(mRes, mResId, options);
+        }
+        @Override
+        public boolean readExif(ExifInterface ei) {
+            try {
+                InputStream is = regenerateInputStream();
+                ei.readExif(is);
+                Utils.closeSilently(is);
+                return true;
+            } catch (IOException e) {
+                Log.e("BitmapRegionTileSource", "Error reading resource", e);
+                return false;
+            }
+        }
+    }
+
+    SimpleBitmapRegionDecoder mDecoder;
+    int mWidth;
+    int mHeight;
+    int mTileSize;
+    private BasicTexture mPreview;
+    private final int mRotation;
+
+    // For use only by getTile
+    private Rect mWantRegion = new Rect();
+    private Rect mOverlapRegion = new Rect();
+    private BitmapFactory.Options mOptions;
+    private Canvas mCanvas;
+
+    public BitmapRegionTileSource(Context context, BitmapSource source) {
+        mTileSize = TiledImageRenderer.suggestedTileSize(context);
+        mRotation = source.getRotation();
+        mDecoder = source.getBitmapRegionDecoder();
+        if (mDecoder != null) {
+            mWidth = mDecoder.getWidth();
+            mHeight = mDecoder.getHeight();
+            mOptions = new BitmapFactory.Options();
+            mOptions.inPreferredConfig = Bitmap.Config.ARGB_8888;
+            mOptions.inPreferQualityOverSpeed = true;
+            mOptions.inTempStorage = new byte[16 * 1024];
+            int previewSize = source.getPreviewSize();
+            if (previewSize != 0) {
+                previewSize = Math.min(previewSize, MAX_PREVIEW_SIZE);
+                // Although this is the same size as the Bitmap that is likely already
+                // loaded, the lifecycle is different and interactions are on a different
+                // thread. Thus to simplify, this source will decode its own bitmap.
+                Bitmap preview = decodePreview(source, previewSize);
+                if (preview.getWidth() <= GL_SIZE_LIMIT && preview.getHeight() <= GL_SIZE_LIMIT) {
+                    mPreview = new BitmapTexture(preview);
+                } else {
+                    Log.w(TAG, String.format(
+                            "Failed to create preview of apropriate size! "
+                            + " in: %dx%d, out: %dx%d",
+                            mWidth, mHeight,
+                            preview.getWidth(), preview.getHeight()));
+                }
+            }
+        }
+    }
+
+    @Override
+    public int getTileSize() {
+        return mTileSize;
+    }
+
+    @Override
+    public int getImageWidth() {
+        return mWidth;
+    }
+
+    @Override
+    public int getImageHeight() {
+        return mHeight;
+    }
+
+    @Override
+    public BasicTexture getPreview() {
+        return mPreview;
+    }
+
+    @Override
+    public int getRotation() {
+        return mRotation;
+    }
+
+    @Override
+    public Bitmap getTile(int level, int x, int y, Bitmap bitmap) {
+        int tileSize = getTileSize();
+        if (!REUSE_BITMAP) {
+            return getTileWithoutReusingBitmap(level, x, y, tileSize);
+        }
+
+        int t = tileSize << level;
+        mWantRegion.set(x, y, x + t, y + t);
+
+        if (bitmap == null) {
+            bitmap = Bitmap.createBitmap(tileSize, tileSize, Bitmap.Config.ARGB_8888);
+        }
+
+        mOptions.inSampleSize = (1 << level);
+        mOptions.inBitmap = bitmap;
+
+        try {
+            bitmap = mDecoder.decodeRegion(mWantRegion, mOptions);
+        } finally {
+            if (mOptions.inBitmap != bitmap && mOptions.inBitmap != null) {
+                mOptions.inBitmap = null;
+            }
+        }
+
+        if (bitmap == null) {
+            Log.w("BitmapRegionTileSource", "fail in decoding region");
+        }
+        return bitmap;
+    }
+
+    private Bitmap getTileWithoutReusingBitmap(
+            int level, int x, int y, int tileSize) {
+
+        int t = tileSize << level;
+        mWantRegion.set(x, y, x + t, y + t);
+
+        mOverlapRegion.set(0, 0, mWidth, mHeight);
+
+        mOptions.inSampleSize = (1 << level);
+        Bitmap bitmap = mDecoder.decodeRegion(mOverlapRegion, mOptions);
+
+        if (bitmap == null) {
+            Log.w(TAG, "fail in decoding region");
+        }
+
+        if (mWantRegion.equals(mOverlapRegion)) {
+            return bitmap;
+        }
+
+        Bitmap result = Bitmap.createBitmap(tileSize, tileSize, Config.ARGB_8888);
+        if (mCanvas == null) {
+            mCanvas = new Canvas();
+        }
+        mCanvas.setBitmap(result);
+        mCanvas.drawBitmap(bitmap,
+                (mOverlapRegion.left - mWantRegion.left) >> level,
+                (mOverlapRegion.top - mWantRegion.top) >> level, null);
+        mCanvas.setBitmap(null);
+        return result;
+    }
+
+    /**
+     * Note that the returned bitmap may have a long edge that's longer
+     * than the targetSize, but it will always be less than 2x the targetSize
+     */
+    private Bitmap decodePreview(BitmapSource source, int targetSize) {
+        Bitmap result = source.getPreviewBitmap();
+        if (result == null) {
+            return null;
+        }
+
+        // We need to resize down if the decoder does not support inSampleSize
+        // or didn't support the specified inSampleSize (some decoders only do powers of 2)
+        float scale = (float) targetSize / (float) (Math.max(result.getWidth(), result.getHeight()));
+
+        if (scale <= 0.5) {
+            result = BitmapUtils.resizeBitmapByScale(result, scale, true);
+        }
+        return ensureGLCompatibleBitmap(result);
+    }
+
+    private static Bitmap ensureGLCompatibleBitmap(Bitmap bitmap) {
+        if (bitmap == null || bitmap.getConfig() != null) {
+            return bitmap;
+        }
+        Bitmap newBitmap = bitmap.copy(Config.ARGB_8888, false);
+        bitmap.recycle();
+        return newBitmap;
+    }
+}
diff --git a/src/com/android/photos/views/BlockingGLTextureView.java b/WallpaperPicker/src/com/android/photos/views/BlockingGLTextureView.java
similarity index 100%
rename from src/com/android/photos/views/BlockingGLTextureView.java
rename to WallpaperPicker/src/com/android/photos/views/BlockingGLTextureView.java
diff --git a/src/com/android/photos/views/TiledImageRenderer.java b/WallpaperPicker/src/com/android/photos/views/TiledImageRenderer.java
similarity index 100%
rename from src/com/android/photos/views/TiledImageRenderer.java
rename to WallpaperPicker/src/com/android/photos/views/TiledImageRenderer.java
diff --git a/src/com/android/photos/views/TiledImageView.java b/WallpaperPicker/src/com/android/photos/views/TiledImageView.java
similarity index 100%
rename from src/com/android/photos/views/TiledImageView.java
rename to WallpaperPicker/src/com/android/photos/views/TiledImageView.java
diff --git a/proguard.flags b/proguard.flags
index 9b59b21..a922e91 100644
--- a/proguard.flags
+++ b/proguard.flags
@@ -8,6 +8,9 @@
   public void onClickAllAppsButton(android.view.View);
   public void onClickAppMarketButton(android.view.View);
   public void dismissFirstRunCling(android.view.View);
+  public void dismissMigrationClingCopyApps(android.view.View);
+  public void dismissMigrationClingUseDefault(android.view.View);
+  public void dismissMigrationWorkspaceCling(android.view.View);
   public void dismissWorkspaceCling(android.view.View);
   public void dismissAllAppsCling(android.view.View);
 }
diff --git a/res/drawable-hdpi/ic_setting.png b/res/drawable-hdpi/ic_setting.png
index c617154..3f5bc43 100644
--- a/res/drawable-hdpi/ic_setting.png
+++ b/res/drawable-hdpi/ic_setting.png
Binary files differ
diff --git a/res/drawable-hdpi/ic_setting_pressed.png b/res/drawable-hdpi/ic_setting_pressed.png
index fb58a4b..9201064 100644
--- a/res/drawable-hdpi/ic_setting_pressed.png
+++ b/res/drawable-hdpi/ic_setting_pressed.png
Binary files differ
diff --git a/res/drawable-hdpi/on_boarding_welcome.png b/res/drawable-hdpi/on_boarding_welcome.png
new file mode 100644
index 0000000..852a0cb
--- /dev/null
+++ b/res/drawable-hdpi/on_boarding_welcome.png
Binary files differ
diff --git a/res/drawable-hdpi/screenpanel_hover.9.png b/res/drawable-hdpi/screenpanel_hover.9.png
index 3321fc9..0fed7c9 100644
--- a/res/drawable-hdpi/screenpanel_hover.9.png
+++ b/res/drawable-hdpi/screenpanel_hover.9.png
Binary files differ
diff --git a/res/drawable-mdpi/ic_setting.png b/res/drawable-mdpi/ic_setting.png
index 0c8ae9d..1e76459 100644
--- a/res/drawable-mdpi/ic_setting.png
+++ b/res/drawable-mdpi/ic_setting.png
Binary files differ
diff --git a/res/drawable-mdpi/ic_setting_pressed.png b/res/drawable-mdpi/ic_setting_pressed.png
index 846091f..d7aca18 100644
--- a/res/drawable-mdpi/ic_setting_pressed.png
+++ b/res/drawable-mdpi/ic_setting_pressed.png
Binary files differ
diff --git a/res/drawable-mdpi/on_boarding_welcome.png b/res/drawable-mdpi/on_boarding_welcome.png
new file mode 100644
index 0000000..1d12e83
--- /dev/null
+++ b/res/drawable-mdpi/on_boarding_welcome.png
Binary files differ
diff --git a/res/drawable-mdpi/screenpanel_hover.9.png b/res/drawable-mdpi/screenpanel_hover.9.png
index dd77406..7dd8858 100644
--- a/res/drawable-mdpi/screenpanel_hover.9.png
+++ b/res/drawable-mdpi/screenpanel_hover.9.png
Binary files differ
diff --git a/res/drawable-sw600dp-hdpi/homescreen_blue_normal_holo.9.png b/res/drawable-sw600dp-hdpi/homescreen_blue_normal_holo.9.png
deleted file mode 100644
index 98f7ac8..0000000
--- a/res/drawable-sw600dp-hdpi/homescreen_blue_normal_holo.9.png
+++ /dev/null
Binary files differ
diff --git a/res/drawable-sw600dp-hdpi/homescreen_blue_strong_holo.9.png b/res/drawable-sw600dp-hdpi/homescreen_blue_strong_holo.9.png
deleted file mode 100644
index 0a511f9..0000000
--- a/res/drawable-sw600dp-hdpi/homescreen_blue_strong_holo.9.png
+++ /dev/null
Binary files differ
diff --git a/res/drawable-sw600dp-hdpi/ic_allapps.png b/res/drawable-sw600dp-hdpi/ic_allapps.png
deleted file mode 100644
index 8bda435..0000000
--- a/res/drawable-sw600dp-hdpi/ic_allapps.png
+++ /dev/null
Binary files differ
diff --git a/res/drawable-sw600dp-hdpi/ic_allapps_pressed.png b/res/drawable-sw600dp-hdpi/ic_allapps_pressed.png
deleted file mode 100644
index 07ff331..0000000
--- a/res/drawable-sw600dp-hdpi/ic_allapps_pressed.png
+++ /dev/null
Binary files differ
diff --git a/res/drawable-sw600dp-hdpi/overscroll_glow_left.9.png b/res/drawable-sw600dp-hdpi/overscroll_glow_left.9.png
deleted file mode 100644
index 3928e2c..0000000
--- a/res/drawable-sw600dp-hdpi/overscroll_glow_left.9.png
+++ /dev/null
Binary files differ
diff --git a/res/drawable-sw600dp-hdpi/overscroll_glow_right.9.png b/res/drawable-sw600dp-hdpi/overscroll_glow_right.9.png
deleted file mode 100644
index e34de34..0000000
--- a/res/drawable-sw600dp-hdpi/overscroll_glow_right.9.png
+++ /dev/null
Binary files differ
diff --git a/res/drawable-sw600dp-hdpi/portal_ring_inner_holo.png b/res/drawable-sw600dp-hdpi/portal_ring_inner_holo.png
deleted file mode 100644
index b3be472..0000000
--- a/res/drawable-sw600dp-hdpi/portal_ring_inner_holo.png
+++ /dev/null
Binary files differ
diff --git a/res/drawable-sw600dp-hdpi/portal_ring_inner_nolip_holo.png b/res/drawable-sw600dp-hdpi/portal_ring_inner_nolip_holo.png
deleted file mode 100644
index 96b981c..0000000
--- a/res/drawable-sw600dp-hdpi/portal_ring_inner_nolip_holo.png
+++ /dev/null
Binary files differ
diff --git a/res/drawable-sw600dp-hdpi/portal_ring_outer_holo.png b/res/drawable-sw600dp-hdpi/portal_ring_outer_holo.png
deleted file mode 100644
index bc13a26..0000000
--- a/res/drawable-sw600dp-hdpi/portal_ring_outer_holo.png
+++ /dev/null
Binary files differ
diff --git a/res/drawable-sw600dp-mdpi/homescreen_blue_normal_holo.9.png b/res/drawable-sw600dp-mdpi/homescreen_blue_normal_holo.9.png
deleted file mode 100644
index 3ae4aff..0000000
--- a/res/drawable-sw600dp-mdpi/homescreen_blue_normal_holo.9.png
+++ /dev/null
Binary files differ
diff --git a/res/drawable-sw600dp-mdpi/homescreen_blue_strong_holo.9.png b/res/drawable-sw600dp-mdpi/homescreen_blue_strong_holo.9.png
deleted file mode 100644
index 31148dd..0000000
--- a/res/drawable-sw600dp-mdpi/homescreen_blue_strong_holo.9.png
+++ /dev/null
Binary files differ
diff --git a/res/drawable-sw600dp-mdpi/ic_allapps.png b/res/drawable-sw600dp-mdpi/ic_allapps.png
deleted file mode 100644
index e2afea5..0000000
--- a/res/drawable-sw600dp-mdpi/ic_allapps.png
+++ /dev/null
Binary files differ
diff --git a/res/drawable-sw600dp-mdpi/ic_allapps_pressed.png b/res/drawable-sw600dp-mdpi/ic_allapps_pressed.png
deleted file mode 100644
index d409c7e..0000000
--- a/res/drawable-sw600dp-mdpi/ic_allapps_pressed.png
+++ /dev/null
Binary files differ
diff --git a/res/drawable-sw600dp-mdpi/overscroll_glow_left.9.png b/res/drawable-sw600dp-mdpi/overscroll_glow_left.9.png
deleted file mode 100644
index 58ec10c..0000000
--- a/res/drawable-sw600dp-mdpi/overscroll_glow_left.9.png
+++ /dev/null
Binary files differ
diff --git a/res/drawable-sw600dp-mdpi/overscroll_glow_right.9.png b/res/drawable-sw600dp-mdpi/overscroll_glow_right.9.png
deleted file mode 100644
index a986fd3..0000000
--- a/res/drawable-sw600dp-mdpi/overscroll_glow_right.9.png
+++ /dev/null
Binary files differ
diff --git a/res/drawable-sw600dp-mdpi/portal_ring_inner_holo.png b/res/drawable-sw600dp-mdpi/portal_ring_inner_holo.png
deleted file mode 100644
index 319c074..0000000
--- a/res/drawable-sw600dp-mdpi/portal_ring_inner_holo.png
+++ /dev/null
Binary files differ
diff --git a/res/drawable-sw600dp-mdpi/portal_ring_inner_nolip_holo.png b/res/drawable-sw600dp-mdpi/portal_ring_inner_nolip_holo.png
deleted file mode 100644
index 8537714..0000000
--- a/res/drawable-sw600dp-mdpi/portal_ring_inner_nolip_holo.png
+++ /dev/null
Binary files differ
diff --git a/res/drawable-sw600dp-mdpi/portal_ring_outer_holo.png b/res/drawable-sw600dp-mdpi/portal_ring_outer_holo.png
deleted file mode 100644
index 365dcfc..0000000
--- a/res/drawable-sw600dp-mdpi/portal_ring_outer_holo.png
+++ /dev/null
Binary files differ
diff --git a/res/drawable-sw600dp-xhdpi/homescreen_blue_normal_holo.9.png b/res/drawable-sw600dp-xhdpi/homescreen_blue_normal_holo.9.png
deleted file mode 100644
index c25b590..0000000
--- a/res/drawable-sw600dp-xhdpi/homescreen_blue_normal_holo.9.png
+++ /dev/null
Binary files differ
diff --git a/res/drawable-sw600dp-xhdpi/homescreen_blue_strong_holo.9.png b/res/drawable-sw600dp-xhdpi/homescreen_blue_strong_holo.9.png
deleted file mode 100644
index 24ac880..0000000
--- a/res/drawable-sw600dp-xhdpi/homescreen_blue_strong_holo.9.png
+++ /dev/null
Binary files differ
diff --git a/res/drawable-sw600dp-xhdpi/ic_allapps.png b/res/drawable-sw600dp-xhdpi/ic_allapps.png
deleted file mode 100644
index 8fed290..0000000
--- a/res/drawable-sw600dp-xhdpi/ic_allapps.png
+++ /dev/null
Binary files differ
diff --git a/res/drawable-sw600dp-xhdpi/ic_allapps_pressed.png b/res/drawable-sw600dp-xhdpi/ic_allapps_pressed.png
deleted file mode 100644
index 786b676..0000000
--- a/res/drawable-sw600dp-xhdpi/ic_allapps_pressed.png
+++ /dev/null
Binary files differ
diff --git a/res/drawable-sw600dp-xhdpi/overscroll_glow_left.9.png b/res/drawable-sw600dp-xhdpi/overscroll_glow_left.9.png
deleted file mode 100644
index b66dd2f..0000000
--- a/res/drawable-sw600dp-xhdpi/overscroll_glow_left.9.png
+++ /dev/null
Binary files differ
diff --git a/res/drawable-sw600dp-xhdpi/overscroll_glow_right.9.png b/res/drawable-sw600dp-xhdpi/overscroll_glow_right.9.png
deleted file mode 100644
index 3ccce33..0000000
--- a/res/drawable-sw600dp-xhdpi/overscroll_glow_right.9.png
+++ /dev/null
Binary files differ
diff --git a/res/drawable-sw600dp-xhdpi/portal_ring_inner_holo.png b/res/drawable-sw600dp-xhdpi/portal_ring_inner_holo.png
deleted file mode 100644
index d4ce45f..0000000
--- a/res/drawable-sw600dp-xhdpi/portal_ring_inner_holo.png
+++ /dev/null
Binary files differ
diff --git a/res/drawable-sw600dp-xhdpi/portal_ring_inner_nolip_holo.png b/res/drawable-sw600dp-xhdpi/portal_ring_inner_nolip_holo.png
deleted file mode 100644
index 9aa13c9..0000000
--- a/res/drawable-sw600dp-xhdpi/portal_ring_inner_nolip_holo.png
+++ /dev/null
Binary files differ
diff --git a/res/drawable-sw600dp-xhdpi/portal_ring_outer_holo.png b/res/drawable-sw600dp-xhdpi/portal_ring_outer_holo.png
deleted file mode 100644
index 0106cd6..0000000
--- a/res/drawable-sw600dp-xhdpi/portal_ring_outer_holo.png
+++ /dev/null
Binary files differ
diff --git a/res/drawable-sw600dp-xxhdpi/homescreen_blue_normal_holo.9.png b/res/drawable-sw600dp-xxhdpi/homescreen_blue_normal_holo.9.png
deleted file mode 100644
index c661f68..0000000
--- a/res/drawable-sw600dp-xxhdpi/homescreen_blue_normal_holo.9.png
+++ /dev/null
Binary files differ
diff --git a/res/drawable-sw600dp-xxhdpi/homescreen_blue_strong_holo.9.png b/res/drawable-sw600dp-xxhdpi/homescreen_blue_strong_holo.9.png
deleted file mode 100644
index bf6ab97..0000000
--- a/res/drawable-sw600dp-xxhdpi/homescreen_blue_strong_holo.9.png
+++ /dev/null
Binary files differ
diff --git a/res/drawable-sw600dp-xxhdpi/ic_allapps.png b/res/drawable-sw600dp-xxhdpi/ic_allapps.png
deleted file mode 100644
index 2429656..0000000
--- a/res/drawable-sw600dp-xxhdpi/ic_allapps.png
+++ /dev/null
Binary files differ
diff --git a/res/drawable-sw600dp-xxhdpi/ic_allapps_pressed.png b/res/drawable-sw600dp-xxhdpi/ic_allapps_pressed.png
deleted file mode 100644
index b93a51b..0000000
--- a/res/drawable-sw600dp-xxhdpi/ic_allapps_pressed.png
+++ /dev/null
Binary files differ
diff --git a/res/drawable-sw600dp-xxhdpi/overscroll_glow_left.9.png b/res/drawable-sw600dp-xxhdpi/overscroll_glow_left.9.png
deleted file mode 100644
index 472c3f9..0000000
--- a/res/drawable-sw600dp-xxhdpi/overscroll_glow_left.9.png
+++ /dev/null
Binary files differ
diff --git a/res/drawable-sw600dp-xxhdpi/overscroll_glow_right.9.png b/res/drawable-sw600dp-xxhdpi/overscroll_glow_right.9.png
deleted file mode 100644
index e30cc97..0000000
--- a/res/drawable-sw600dp-xxhdpi/overscroll_glow_right.9.png
+++ /dev/null
Binary files differ
diff --git a/res/drawable-sw600dp-xxhdpi/portal_ring_inner_holo.png b/res/drawable-sw600dp-xxhdpi/portal_ring_inner_holo.png
deleted file mode 100644
index 65b2541..0000000
--- a/res/drawable-sw600dp-xxhdpi/portal_ring_inner_holo.png
+++ /dev/null
Binary files differ
diff --git a/res/drawable-sw600dp-xxhdpi/portal_ring_inner_nolip_holo.png b/res/drawable-sw600dp-xxhdpi/portal_ring_inner_nolip_holo.png
deleted file mode 100644
index 5068646..0000000
--- a/res/drawable-sw600dp-xxhdpi/portal_ring_inner_nolip_holo.png
+++ /dev/null
Binary files differ
diff --git a/res/drawable-sw600dp-xxhdpi/portal_ring_outer_holo.png b/res/drawable-sw600dp-xxhdpi/portal_ring_outer_holo.png
deleted file mode 100644
index 6628425..0000000
--- a/res/drawable-sw600dp-xxhdpi/portal_ring_outer_holo.png
+++ /dev/null
Binary files differ
diff --git a/res/drawable-sw720dp-xxhdpi/workspace_bg.9.png b/res/drawable-sw720dp-xxhdpi/workspace_bg.9.png
new file mode 100644
index 0000000..efc9b04
--- /dev/null
+++ b/res/drawable-sw720dp-xxhdpi/workspace_bg.9.png
Binary files differ
diff --git a/res/drawable-xhdpi/ic_setting.png b/res/drawable-xhdpi/ic_setting.png
index 91ba98c..6f06bcf 100644
--- a/res/drawable-xhdpi/ic_setting.png
+++ b/res/drawable-xhdpi/ic_setting.png
Binary files differ
diff --git a/res/drawable-xhdpi/ic_setting_pressed.png b/res/drawable-xhdpi/ic_setting_pressed.png
index 08aafc4..bca8ccd 100644
--- a/res/drawable-xhdpi/ic_setting_pressed.png
+++ b/res/drawable-xhdpi/ic_setting_pressed.png
Binary files differ
diff --git a/res/drawable-xhdpi/on_boarding_welcome.png b/res/drawable-xhdpi/on_boarding_welcome.png
new file mode 100644
index 0000000..8c101e0
--- /dev/null
+++ b/res/drawable-xhdpi/on_boarding_welcome.png
Binary files differ
diff --git a/res/drawable-xhdpi/screenpanel_hover.9.png b/res/drawable-xhdpi/screenpanel_hover.9.png
index a44dc11..251bf20 100644
--- a/res/drawable-xhdpi/screenpanel_hover.9.png
+++ b/res/drawable-xhdpi/screenpanel_hover.9.png
Binary files differ
diff --git a/res/drawable-xxhdpi/ic_setting.png b/res/drawable-xxhdpi/ic_setting.png
index 6e1e662..b3729d3 100644
--- a/res/drawable-xxhdpi/ic_setting.png
+++ b/res/drawable-xxhdpi/ic_setting.png
Binary files differ
diff --git a/res/drawable-xxhdpi/ic_setting_pressed.png b/res/drawable-xxhdpi/ic_setting_pressed.png
index a202a40..5c9c1be 100644
--- a/res/drawable-xxhdpi/ic_setting_pressed.png
+++ b/res/drawable-xxhdpi/ic_setting_pressed.png
Binary files differ
diff --git a/res/drawable-xxhdpi/screenpanel_hover.9.png b/res/drawable-xxhdpi/screenpanel_hover.9.png
index 1ab18da..e8b36d8 100644
--- a/res/drawable-xxhdpi/screenpanel_hover.9.png
+++ b/res/drawable-xxhdpi/screenpanel_hover.9.png
Binary files differ
diff --git a/res/layout-land/all_apps_cling.xml b/res/layout-land/all_apps_cling.xml
deleted file mode 100644
index 820f00a..0000000
--- a/res/layout-land/all_apps_cling.xml
+++ /dev/null
@@ -1,48 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!-- Copyright (C) 2011 The Android Open Source Project
-
-     Licensed under the Apache License, Version 2.0 (the "License");
-     you may not use this file except in compliance with the License.
-     You may obtain a copy of the License at
-
-          http://www.apache.org/licenses/LICENSE-2.0
-
-     Unless required by applicable law or agreed to in writing, software
-     distributed under the License is distributed on an "AS IS" BASIS,
-     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-     See the License for the specific language governing permissions and
-     limitations under the License.
--->
-<com.android.launcher3.Cling
-    xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:launcher="http://schemas.android.com/apk/res-auto/com.android.launcher3"
-    launcher:drawIdentifier="all_apps_landscape">
-    <FrameLayout
-        android:layout_width="match_parent"
-        android:layout_height="match_parent"
-        android:layout_marginStart="40dp"
-        android:layout_marginTop="40dp">
-        <LinearLayout
-            android:layout_width="match_parent"
-            android:layout_height="wrap_content"
-            android:orientation="vertical">
-            <TextView
-                style="@style/ClingTitleText"
-                android:id="@+id/all_apps_cling_title"
-                android:text="@string/all_apps_cling_title" />
-            <TextView
-                style="@style/ClingText"
-                android:id="@+id/all_apps_cling_add_item"
-                android:layout_width="match_parent"
-                android:layout_height="wrap_content"
-                android:text="@string/all_apps_cling_add_item" />
-        </LinearLayout>
-    </FrameLayout>
-    <Button
-        style="@style/ClingButton"
-        android:id="@+id/cling_dismiss"
-        android:layout_marginBottom="15dp"
-        android:layout_marginEnd="10dp"
-        android:layout_gravity="bottom|end"
-        android:onClick="dismissAllAppsCling" />
-</com.android.launcher3.Cling>
diff --git a/res/layout-land/folder_cling.xml b/res/layout-land/folder_cling.xml
index 86286d7..5dd3729 100644
--- a/res/layout-land/folder_cling.xml
+++ b/res/layout-land/folder_cling.xml
@@ -16,7 +16,7 @@
 <com.android.launcher3.Cling
     xmlns:android="http://schemas.android.com/apk/res/android"
     xmlns:launcher="http://schemas.android.com/apk/res-auto/com.android.launcher3"
-    launcher:drawIdentifier="folder_portrait">
+    launcher:drawIdentifier="folder_landscape">
     <FrameLayout
         android:layout_width="match_parent"
         android:layout_height="match_parent"
@@ -25,6 +25,7 @@
         android:layout_marginTop="10dp"
         android:layout_marginBottom="10dp">
         <LinearLayout
+            android:id="@+id/folder_bubble"
             android:layout_width="match_parent"
             android:layout_height="wrap_content"
             android:orientation="vertical">
@@ -59,6 +60,6 @@
         android:id="@+id/cling_dismiss"
         android:layout_marginBottom="15dp"
         android:layout_marginEnd="20dp"
-        android:layout_gravity="bottom|end"
+        android:layout_gravity="bottom|right"
         android:onClick="dismissFolderCling" />
 </com.android.launcher3.Cling>
diff --git a/res/layout-land/launcher.xml b/res/layout-land/launcher.xml
index 77ea2e9..7791609 100644
--- a/res/layout-land/launcher.xml
+++ b/res/layout-land/launcher.xml
@@ -36,9 +36,7 @@
             android:layout_width="match_parent"
             android:layout_height="match_parent"
             android:layout_gravity="center"
-            launcher:defaultScreen="@integer/config_workspaceDefaultScreen"
-            launcher:pageSpacing="@dimen/workspace_page_spacing"
-            launcher:pageIndicator="@id/page_indicator" />
+            launcher:defaultScreen="@integer/config_workspaceDefaultScreen" />
 
         <include layout="@layout/hotseat"
             android:id="@+id/hotseat"
@@ -47,8 +45,8 @@
             android:layout_gravity="end" />
 
         <include
-            android:id="@+id/qsb_bar"
-            layout="@layout/qsb_bar" />
+            android:id="@+id/search_drop_target_bar"
+            layout="@layout/search_drop_target_bar" />
 
         <include layout="@layout/overview_panel"
             android:id="@+id/overview_panel"
@@ -67,31 +65,27 @@
             android:layout_width="match_parent"
             android:layout_height="match_parent"
             android:visibility="gone" />
+        <include layout="@layout/migration_cling"
+            android:id="@+id/migration_cling"
+            android:layout_width="match_parent"
+            android:layout_height="match_parent"
+            android:visibility="gone" />
+        <include layout="@layout/migration_workspace_cling"
+            android:id="@+id/migration_workspace_cling"
+            android:layout_width="match_parent"
+            android:layout_height="match_parent"
+            android:visibility="gone" />
         <include layout="@layout/workspace_cling"
             android:id="@+id/workspace_cling"
             android:layout_width="match_parent"
             android:layout_height="match_parent"
             android:visibility="gone" />
-
         <include layout="@layout/folder_cling"
             android:id="@+id/folder_cling"
             android:layout_width="match_parent"
             android:layout_height="match_parent"
             android:visibility="gone" />
 
-        <!-- TODO: Fix
-        <com.android.launcher3.DrawableStateProxyView
-            android:id="@+id/voice_button_proxy"
-            android:layout_width="0dp"
-            android:layout_height="0dp"
-            android:layout_gravity="top|start"
-            android:layout_marginTop="64dp"
-            android:clickable="true"
-            android:onClick="onClickVoiceButton"
-            android:importantForAccessibility="no"
-            launcher:sourceViewId="@+id/voice_button" />
-            -->
-
         <include layout="@layout/apps_customize_pane"
             android:id="@+id/apps_customize_pane"
             android:layout_width="match_parent"
diff --git a/res/layout-land/migration_cling.xml b/res/layout-land/migration_cling.xml
new file mode 100644
index 0000000..343f43f
--- /dev/null
+++ b/res/layout-land/migration_cling.xml
@@ -0,0 +1,100 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2011 The Android Open Source Project
+
+     Licensed under the Apache License, Version 2.0 (the "License");
+     you may not use this file except in compliance with the License.
+     You may obtain a copy of the License at
+
+          http://www.apache.org/licenses/LICENSE-2.0
+
+     Unless required by applicable law or agreed to in writing, software
+     distributed under the License is distributed on an "AS IS" BASIS,
+     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+     See the License for the specific language governing permissions and
+     limitations under the License.
+-->
+<com.android.launcher3.Cling
+    xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:launcher="http://schemas.android.com/apk/res-auto/com.android.launcher3"
+    android:layout_width="match_parent"
+    android:layout_height="match_parent"
+    launcher:drawIdentifier="migration_landscape">
+    <FrameLayout
+        android:id="@+id/content"
+        android:layout_width="match_parent"
+        android:layout_height="match_parent"
+        android:orientation="vertical">
+
+        <LinearLayout
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content"
+            android:layout_gravity="top"
+            android:orientation="vertical">
+            <TextView
+                android:layout_width="match_parent"
+                android:layout_height="wrap_content"
+                android:layout_gravity="top"
+                android:gravity="center"
+                android:text="@string/first_run_cling_title"
+                android:textSize="42dp"
+                android:textColor="#FFffffff" />
+            <ImageView
+                android:layout_width="wrap_content"
+                android:layout_height="wrap_content"
+                android:layout_marginTop="10dp"
+                android:layout_marginBottom="0dp"
+                android:layout_gravity="center_horizontal"
+                android:src="@drawable/on_boarding_welcome" />
+
+            <ImageView
+                android:layout_width="wrap_content"
+                android:layout_height="wrap_content"
+                android:layout_gravity="center_horizontal"
+                android:src="@drawable/cling_arrow_up" />
+            <LinearLayout
+                android:layout_width="match_parent"
+                android:layout_height="wrap_content"
+                android:layout_marginLeft="25dp"
+                android:layout_marginRight="25dp"
+                android:paddingLeft="25dp"
+                android:paddingRight="25dp"
+                android:paddingTop="20dp"
+                android:paddingBottom="20dp"
+                android:orientation="vertical"
+                android:background="@drawable/cling">
+                <TextView
+                    style="@style/ClingTitleText"
+                    android:layout_width="wrap_content"
+                    android:layout_height="wrap_content"
+                    android:text="@string/migration_cling_title" />
+                <TextView
+                    style="@style/ClingText"
+                    android:layout_width="match_parent"
+                    android:layout_height="wrap_content"
+                    android:text="@string/migration_cling_description" />
+            </LinearLayout>
+        </LinearLayout>
+
+        <LinearLayout
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content"
+            android:layout_gravity="bottom"
+            android:layout_marginLeft="25dp"
+            android:layout_marginRight="25dp"
+            android:layout_marginBottom="25dp"
+            android:orientation="vertical">
+            <Button
+                style="@style/ClingButton"
+                android:layout_width="match_parent"
+                android:layout_height="wrap_content"
+                android:text="@string/migration_cling_copy_apps"
+                android:onClick="dismissMigrationClingCopyApps" />
+            <Button
+                style="@style/ClingButton"
+                android:layout_width="match_parent"
+                android:layout_height="wrap_content"
+                android:text="@string/migration_cling_use_default"
+                android:onClick="dismissMigrationClingUseDefault" />
+        </LinearLayout>
+    </FrameLayout>
+</com.android.launcher3.Cling>
diff --git a/res/layout-land/migration_workspace_cling.xml b/res/layout-land/migration_workspace_cling.xml
new file mode 100644
index 0000000..2d71940
--- /dev/null
+++ b/res/layout-land/migration_workspace_cling.xml
@@ -0,0 +1,69 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2011 The Android Open Source Project
+
+     Licensed under the Apache License, Version 2.0 (the "License");
+     you may not use this file except in compliance with the License.
+     You may obtain a copy of the License at
+
+          http://www.apache.org/licenses/LICENSE-2.0
+
+     Unless required by applicable law or agreed to in writing, software
+     distributed under the License is distributed on an "AS IS" BASIS,
+     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+     See the License for the specific language governing permissions and
+     limitations under the License.
+-->
+<com.android.launcher3.Cling
+    xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:launcher="http://schemas.android.com/apk/res-auto/com.android.launcher3"
+    android:layout_width="match_parent"
+    android:layout_height="match_parent"
+    launcher:drawIdentifier="migration_workspace_landscape">
+    <LinearLayout
+        android:id="@+id/content"
+        android:layout_width="400dp"
+        android:layout_height="wrap_content"
+        android:layout_gravity="end|center_vertical"
+        android:paddingEnd="60dp"
+        android:orientation="vertical">
+        <LinearLayout
+            android:id="@+id/migration_workspace_cling_bubble"
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content"
+            android:orientation="horizontal">
+            <LinearLayout
+                android:layout_width="match_parent"
+                android:layout_height="wrap_content"
+                android:layout_marginRight="4dp"
+                android:paddingLeft="20dp"
+                android:paddingRight="20dp"
+                android:paddingTop="20dp"
+                android:paddingBottom="20dp"
+                android:orientation="vertical"
+                android:background="@drawable/cling">
+                <TextView
+                    style="@style/ClingTitleText"
+                    android:layout_width="wrap_content"
+                    android:layout_height="wrap_content"
+                    android:text="@string/workspace_cling_title" />
+                <TextView
+                    style="@style/ClingText"
+                    android:layout_width="match_parent"
+                    android:layout_height="wrap_content"
+                    android:text="@string/workspace_cling_move_item" />
+            </LinearLayout>
+            <ImageView
+                android:layout_width="wrap_content"
+                android:layout_height="wrap_content"
+                android:layout_gravity="center_vertical"
+                android:src="@drawable/cling_arrow_end" />
+        </LinearLayout>
+        <Button
+            style="@style/ClingButton"
+            android:layout_width="wrap_content"
+            android:layout_height="wrap_content"
+            android:layout_marginTop="5dp"
+            android:layout_gravity="right"
+            android:onClick="dismissMigrationWorkspaceCling" />
+    </LinearLayout>
+</com.android.launcher3.Cling>
diff --git a/res/layout-land/search_bar.xml b/res/layout-land/qsb.xml
similarity index 100%
rename from res/layout-land/search_bar.xml
rename to res/layout-land/qsb.xml
diff --git a/res/layout-land/workspace_cling.xml b/res/layout-land/workspace_cling.xml
index db33db0..d3b07d7 100644
--- a/res/layout-land/workspace_cling.xml
+++ b/res/layout-land/workspace_cling.xml
@@ -18,24 +18,20 @@
     xmlns:launcher="http://schemas.android.com/apk/res-auto/com.android.launcher3"
     android:layout_width="match_parent"
     android:layout_height="match_parent"
-    launcher:drawIdentifier="workspace_portrait">
+    launcher:drawIdentifier="workspace_landscape">
     <FrameLayout
         android:id="@+id/content"
         android:layout_width="match_parent"
-        android:layout_height="match_parent"
-        android:layout_marginStart="25dp"
-        android:layout_marginEnd="25dp"
-        android:layout_marginTop="310dp">
+        android:layout_height="match_parent">
         <LinearLayout
+            android:id="@+id/workspace_cling_bubble"
             android:layout_width="match_parent"
             android:layout_height="wrap_content"
             android:layout_gravity="top"
+            android:layout_marginStart="25dp"
+            android:layout_marginEnd="25dp"
+            android:layout_marginTop="30dp"
             android:orientation="vertical">
-            <ImageView
-                android:layout_width="wrap_content"
-                android:layout_height="wrap_content"
-                android:layout_gravity="center_horizontal"
-                android:src="@drawable/cling_arrow_up" />
             <LinearLayout
                 android:paddingLeft="20dp"
                 android:paddingRight="20dp"
@@ -56,14 +52,57 @@
                     android:layout_height="wrap_content"
                     android:text="@string/workspace_cling_move_item" />
             </LinearLayout>
+            <ImageView
+                android:layout_width="wrap_content"
+                android:layout_height="wrap_content"
+                android:layout_gravity="center_horizontal"
+                android:src="@drawable/cling_arrow_down" />
+        </LinearLayout>
+
+        <LinearLayout
+            android:id="@+id/focused_hotseat_app_bubble"
+            android:layout_width="wrap_content"
+            android:layout_height="wrap_content"
+            android:layout_gravity="bottom|left"
+            android:layout_marginLeft="25dp"
+            android:layout_marginBottom="90dp"
+            android:orientation="vertical"
+            android:visibility="gone">
+            <LinearLayout
+                android:paddingLeft="20dp"
+                android:paddingRight="20dp"
+                android:paddingTop="20dp"
+                android:paddingBottom="20dp"
+                android:layout_width="240dp"
+                android:layout_height="wrap_content"
+                android:orientation="vertical"
+                android:background="@drawable/cling">
+                <TextView
+                    android:id="@+id/focused_hotseat_app_title"
+                    style="@style/ClingTitleText"
+                    android:layout_width="wrap_content"
+                    android:layout_height="wrap_content" />
+                <TextView
+                    android:id="@+id/focused_hotseat_app_description"
+                    style="@style/ClingText"
+                    android:layout_width="match_parent"
+                    android:layout_height="wrap_content" />
+            </LinearLayout>
+            <ImageView
+                android:layout_width="wrap_content"
+                android:layout_height="wrap_content"
+                android:layout_gravity="left"
+                android:layout_marginLeft="78dp"
+                android:src="@drawable/cling_arrow_down" />
         </LinearLayout>
     </FrameLayout>
+
     <Button
         style="@style/ClingButton"
         android:layout_width="wrap_content"
         android:layout_height="wrap_content"
         android:layout_marginBottom="15dp"
-        android:layout_marginEnd="20dp"
-        android:layout_gravity="bottom|end"
+        android:layout_marginRight="20dp"
+        android:layout_gravity="bottom|right"
         android:onClick="dismissWorkspaceCling" />
 </com.android.launcher3.Cling>
diff --git a/res/layout-port/all_apps_cling.xml b/res/layout-port/all_apps_cling.xml
deleted file mode 100644
index 62284ec..0000000
--- a/res/layout-port/all_apps_cling.xml
+++ /dev/null
@@ -1,48 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!-- Copyright (C) 2011 The Android Open Source Project
-
-     Licensed under the Apache License, Version 2.0 (the "License");
-     you may not use this file except in compliance with the License.
-     You may obtain a copy of the License at
-
-          http://www.apache.org/licenses/LICENSE-2.0
-
-     Unless required by applicable law or agreed to in writing, software
-     distributed under the License is distributed on an "AS IS" BASIS,
-     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-     See the License for the specific language governing permissions and
-     limitations under the License.
--->
-<com.android.launcher3.Cling
-    xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:launcher="http://schemas.android.com/apk/res-auto/com.android.launcher3"
-    launcher:drawIdentifier="all_apps_portrait">
-    <FrameLayout
-        android:layout_width="match_parent"
-        android:layout_height="match_parent"
-        android:layout_marginStart="20dp"
-        android:layout_marginTop="20dp">
-        <LinearLayout
-            android:layout_width="match_parent"
-            android:layout_height="wrap_content"
-            android:orientation="vertical">
-            <TextView
-                style="@style/ClingTitleText"
-                android:id="@+id/all_apps_cling_title"
-                android:text="@string/all_apps_cling_title" />
-            <TextView
-                style="@style/ClingText"
-                android:id="@+id/all_apps_cling_add_item"
-                android:layout_width="285dp"
-                android:layout_height="wrap_content"
-                android:text="@string/all_apps_cling_add_item" />
-        </LinearLayout>
-    </FrameLayout>
-    <Button
-        style="@style/ClingButton"
-        android:id="@+id/cling_dismiss"
-        android:layout_marginBottom="15dp"
-        android:layout_marginEnd="10dp"
-        android:layout_gravity="bottom|end"
-        android:onClick="dismissAllAppsCling" />
-</com.android.launcher3.Cling>
diff --git a/res/layout-port/first_run_cling.xml b/res/layout-port/first_run_cling.xml
index 4830e5d..ac3939c 100644
--- a/res/layout-port/first_run_cling.xml
+++ b/res/layout-port/first_run_cling.xml
@@ -39,16 +39,14 @@
                 android:layout_marginBottom="10dp"
                 android:text="@string/first_run_cling_title"
                 android:textColor="#FFFFFFFF"
-                android:textSize="30sp"
                 android:gravity="center" />
             <TextView
-                style="@style/ClingAltTitleText"
+                style="@style/ClingAltText"
                 android:layout_width="match_parent"
                 android:layout_height="wrap_content"
                 android:layout_gravity="center_horizontal"
                 android:text="@string/first_run_cling_description"
                 android:textColor="#80000000"
-                android:textSize="16sp"
                 android:gravity="center" />
         </LinearLayout>
         <TextView
diff --git a/res/layout-port/folder_cling.xml b/res/layout-port/folder_cling.xml
index 86286d7..1a1b11f 100644
--- a/res/layout-port/folder_cling.xml
+++ b/res/layout-port/folder_cling.xml
@@ -25,6 +25,7 @@
         android:layout_marginTop="10dp"
         android:layout_marginBottom="10dp">
         <LinearLayout
+            android:id="@+id/folder_bubble"
             android:layout_width="match_parent"
             android:layout_height="wrap_content"
             android:orientation="vertical">
@@ -59,6 +60,6 @@
         android:id="@+id/cling_dismiss"
         android:layout_marginBottom="15dp"
         android:layout_marginEnd="20dp"
-        android:layout_gravity="bottom|end"
+        android:layout_gravity="bottom|right"
         android:onClick="dismissFolderCling" />
 </com.android.launcher3.Cling>
diff --git a/res/layout-port/launcher.xml b/res/layout-port/launcher.xml
index 6fbf7c7..574b73e 100644
--- a/res/layout-port/launcher.xml
+++ b/res/layout-port/launcher.xml
@@ -35,8 +35,7 @@
             android:layout_width="match_parent"
             android:layout_height="match_parent"
             launcher:defaultScreen="@integer/config_workspaceDefaultScreen"
-            launcher:pageSpacing="@dimen/workspace_page_spacing"
-            launcher:pageIndicator="@id/page_indicator">
+            launcher:pageIndicator="@+id/page_indicator">
         </com.android.launcher3.Workspace>
 
         <include layout="@layout/hotseat"
@@ -58,8 +57,8 @@
             android:layout_gravity="center_horizontal" />
 
         <include
-            android:id="@+id/qsb_bar"
-            layout="@layout/qsb_bar" />
+            android:id="@+id/search_drop_target_bar"
+            layout="@layout/search_drop_target_bar" />
 
         <!-- The Workspace cling must appear under the AppsCustomizePagedView below to ensure
              that it is still visible during the transition to AllApps and doesn't overlay on
@@ -74,6 +73,16 @@
             android:layout_width="match_parent"
             android:layout_height="match_parent"
             android:visibility="gone" />
+        <include layout="@layout/migration_cling"
+            android:id="@+id/migration_cling"
+            android:layout_width="match_parent"
+            android:layout_height="match_parent"
+            android:visibility="gone" />
+        <include layout="@layout/migration_workspace_cling"
+            android:id="@+id/migration_workspace_cling"
+            android:layout_width="match_parent"
+            android:layout_height="match_parent"
+            android:visibility="gone" />
         <include layout="@layout/workspace_cling"
             android:id="@+id/workspace_cling"
             android:layout_width="match_parent"
diff --git a/res/layout-port/migration_cling.xml b/res/layout-port/migration_cling.xml
new file mode 100644
index 0000000..1bffe6c
--- /dev/null
+++ b/res/layout-port/migration_cling.xml
@@ -0,0 +1,100 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2011 The Android Open Source Project
+
+     Licensed under the Apache License, Version 2.0 (the "License");
+     you may not use this file except in compliance with the License.
+     You may obtain a copy of the License at
+
+          http://www.apache.org/licenses/LICENSE-2.0
+
+     Unless required by applicable law or agreed to in writing, software
+     distributed under the License is distributed on an "AS IS" BASIS,
+     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+     See the License for the specific language governing permissions and
+     limitations under the License.
+-->
+<com.android.launcher3.Cling
+    xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:launcher="http://schemas.android.com/apk/res-auto/com.android.launcher3"
+    android:layout_width="match_parent"
+    android:layout_height="match_parent"
+    launcher:drawIdentifier="migration_portrait">
+    <FrameLayout
+        android:id="@+id/content"
+        android:layout_width="match_parent"
+        android:layout_height="match_parent"
+        android:orientation="vertical">
+
+        <LinearLayout
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content"
+            android:layout_gravity="top"
+            android:orientation="vertical">
+            <TextView
+                android:layout_width="match_parent"
+                android:layout_height="wrap_content"
+                android:layout_gravity="top"
+                android:gravity="center"
+                android:text="@string/first_run_cling_title"
+                android:textSize="42dp"
+                android:textColor="#FFffffff" />
+            <ImageView
+                android:layout_width="wrap_content"
+                android:layout_height="wrap_content"
+                android:layout_marginTop="10dp"
+                android:layout_marginBottom="0dp"
+                android:layout_gravity="center_horizontal"
+                android:src="@drawable/on_boarding_welcome" />
+
+            <ImageView
+                android:layout_width="wrap_content"
+                android:layout_height="wrap_content"
+                android:layout_gravity="center_horizontal"
+                android:src="@drawable/cling_arrow_up" />
+            <LinearLayout
+                android:layout_width="match_parent"
+                android:layout_height="wrap_content"
+                android:layout_marginLeft="25dp"
+                android:layout_marginRight="25dp"
+                android:paddingLeft="25dp"
+                android:paddingRight="25dp"
+                android:paddingTop="20dp"
+                android:paddingBottom="20dp"
+                android:orientation="vertical"
+                android:background="@drawable/cling">
+                <TextView
+                    style="@style/ClingTitleText"
+                    android:layout_width="wrap_content"
+                    android:layout_height="wrap_content"
+                    android:text="@string/migration_cling_title" />
+                <TextView
+                    style="@style/ClingText"
+                    android:layout_width="match_parent"
+                    android:layout_height="wrap_content"
+                    android:text="@string/migration_cling_description" />
+            </LinearLayout>
+        </LinearLayout>
+
+        <LinearLayout
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content"
+            android:layout_gravity="bottom"
+            android:layout_marginLeft="25dp"
+            android:layout_marginRight="25dp"
+            android:layout_marginBottom="25dp"
+            android:orientation="vertical">
+            <Button
+                style="@style/ClingButton"
+                android:layout_width="match_parent"
+                android:layout_height="wrap_content"
+                android:text="@string/migration_cling_copy_apps"
+                android:onClick="dismissMigrationClingCopyApps" />
+            <Button
+                style="@style/ClingButton"
+                android:layout_width="match_parent"
+                android:layout_height="wrap_content"
+                android:text="@string/migration_cling_use_default"
+                android:onClick="dismissMigrationClingUseDefault" />
+        </LinearLayout>
+    </FrameLayout>
+</com.android.launcher3.Cling>
diff --git a/res/layout-port/migration_workspace_cling.xml b/res/layout-port/migration_workspace_cling.xml
new file mode 100644
index 0000000..576bb41
--- /dev/null
+++ b/res/layout-port/migration_workspace_cling.xml
@@ -0,0 +1,70 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2011 The Android Open Source Project
+
+     Licensed under the Apache License, Version 2.0 (the "License");
+     you may not use this file except in compliance with the License.
+     You may obtain a copy of the License at
+
+          http://www.apache.org/licenses/LICENSE-2.0
+
+     Unless required by applicable law or agreed to in writing, software
+     distributed under the License is distributed on an "AS IS" BASIS,
+     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+     See the License for the specific language governing permissions and
+     limitations under the License.
+-->
+<com.android.launcher3.Cling
+    xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:launcher="http://schemas.android.com/apk/res-auto/com.android.launcher3"
+    android:layout_width="match_parent"
+    android:layout_height="match_parent"
+    launcher:drawIdentifier="migration_workspace_portrait">
+    <FrameLayout
+        android:id="@+id/content"
+        android:layout_width="match_parent"
+        android:layout_height="match_parent">
+        <LinearLayout
+            android:id="@+id/migration_workspace_cling_bubble"
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content"
+            android:layout_gravity="bottom"
+            android:layout_marginStart="25dp"
+            android:layout_marginEnd="25dp"
+            android:orientation="vertical">
+            <LinearLayout
+                android:paddingLeft="20dp"
+                android:paddingRight="20dp"
+                android:paddingTop="20dp"
+                android:paddingBottom="20dp"
+                android:layout_width="match_parent"
+                android:layout_height="wrap_content"
+                android:orientation="vertical"
+                android:background="@drawable/cling">
+                <TextView
+                    style="@style/ClingTitleText"
+                    android:layout_width="wrap_content"
+                    android:layout_height="wrap_content"
+                    android:text="@string/workspace_cling_title" />
+                <TextView
+                    style="@style/ClingText"
+                    android:layout_width="match_parent"
+                    android:layout_height="wrap_content"
+                    android:text="@string/workspace_cling_move_item" />
+            </LinearLayout>
+            <ImageView
+                android:layout_width="wrap_content"
+                android:layout_height="wrap_content"
+                android:layout_gravity="center_horizontal"
+                android:src="@drawable/cling_arrow_down" />
+        </LinearLayout>
+
+        <Button
+            style="@style/ClingButton"
+            android:layout_width="wrap_content"
+            android:layout_height="wrap_content"
+            android:layout_marginBottom="15dp"
+            android:layout_marginEnd="20dp"
+            android:layout_gravity="bottom|right"
+            android:onClick="dismissMigrationWorkspaceCling" />
+    </FrameLayout>
+</com.android.launcher3.Cling>
diff --git a/res/layout-port/search_bar.xml b/res/layout-port/qsb.xml
similarity index 96%
rename from res/layout-port/search_bar.xml
rename to res/layout-port/qsb.xml
index 1c96ca3..4c9963d 100644
--- a/res/layout-port/search_bar.xml
+++ b/res/layout-port/qsb.xml
@@ -16,13 +16,12 @@
 <RelativeLayout
     xmlns:android="http://schemas.android.com/apk/res/android"
     xmlns:launcher="http://schemas.android.com/apk/res-auto/com.android.launcher3"
-    style="@style/SearchDropTargetBar"
     android:layout_width="match_parent"
     android:layout_height="match_parent"
     android:background="@drawable/search_frame">
    <!-- Global search icon -->
    <com.android.launcher3.HolographicLinearLayout
-        style="@style/SearchButton"
+        style="@style/SearchButton.WithPaddingStart"
         launcher:sourceImageViewId="@+id/search_button"
         android:id="@+id/search_button_container"
         android:layout_width="match_parent"
@@ -31,7 +30,6 @@
         android:layout_centerVertical="true"
         android:layout_alignParentStart="true"
         android:layout_toStartOf="@+id/voice_button_container"
-        android:paddingStart="8dp"
         android:onClick="onClickSearchButton"
         android:focusable="true"
         android:clickable="true"
@@ -57,6 +55,7 @@
         android:layout_centerVertical="true"
         android:layout_alignParentEnd="true"
         android:paddingEnd="8dp"
+        android:paddingRight="8dp"
         android:onClick="onClickVoiceButton"
         android:focusable="true"
         android:clickable="true"
diff --git a/res/layout-port/workspace_cling.xml b/res/layout-port/workspace_cling.xml
index b926ca9..6245686 100644
--- a/res/layout-port/workspace_cling.xml
+++ b/res/layout-port/workspace_cling.xml
@@ -24,6 +24,7 @@
         android:layout_width="match_parent"
         android:layout_height="match_parent">
         <LinearLayout
+            android:id="@+id/workspace_cling_bubble"
             android:layout_width="match_parent"
             android:layout_height="wrap_content"
             android:layout_gravity="top"
diff --git a/res/layout-sw600dp-port/all_apps_cling.xml b/res/layout-sw600dp-port/all_apps_cling.xml
deleted file mode 100644
index cf65e41..0000000
--- a/res/layout-sw600dp-port/all_apps_cling.xml
+++ /dev/null
@@ -1,50 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!-- Copyright (C) 2011 The Android Open Source Project
-
-     Licensed under the Apache License, Version 2.0 (the "License");
-     you may not use this file except in compliance with the License.
-     You may obtain a copy of the License at
-
-          http://www.apache.org/licenses/LICENSE-2.0
-
-     Unless required by applicable law or agreed to in writing, software
-     distributed under the License is distributed on an "AS IS" BASIS,
-     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-     See the License for the specific language governing permissions and
-     limitations under the License.
--->
-<com.android.launcher3.Cling
-    xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:launcher="http://schemas.android.com/apk/res-auto/com.android.launcher3"
-    launcher:drawIdentifier="all_apps_portrait">
-    <FrameLayout
-        android:layout_width="match_parent"
-        android:layout_height="match_parent"
-        android:layout_marginStart="20dp"
-        android:layout_marginTop="20dp">
-        <LinearLayout
-            android:layout_width="match_parent"
-            android:layout_height="wrap_content"
-            android:orientation="vertical">
-            <TextView
-                style="@style/ClingTitleText"
-                android:id="@+id/all_apps_cling_title"
-                android:text="@string/all_apps_cling_title" />
-            <TextView
-                style="@style/ClingText"
-                android:id="@+id/all_apps_cling_add_item"
-                android:layout_width="match_parent"
-                android:layout_height="wrap_content"
-                android:text="@string/all_apps_cling_add_item" />
-        </LinearLayout>
-    </FrameLayout>
-    <Button
-        style="@style/ClingButton"
-        android:id="@+id/cling_dismiss"
-        android:minWidth="168dp"
-        android:textSize="24sp"
-        android:layout_marginTop="235dp"
-        android:layout_marginEnd="36dp"
-        android:layout_gravity="top|end"
-        android:onClick="dismissAllAppsCling" />
-</com.android.launcher3.Cling>
diff --git a/res/layout-sw600dp-port/first_run_cling.xml b/res/layout-sw600dp-port/first_run_cling.xml
new file mode 100644
index 0000000..d80c084
--- /dev/null
+++ b/res/layout-sw600dp-port/first_run_cling.xml
@@ -0,0 +1,100 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2011 The Android Open Source Project
+
+     Licensed under the Apache License, Version 2.0 (the "License");
+     you may not use this file except in compliance with the License.
+     You may obtain a copy of the License at
+
+          http://www.apache.org/licenses/LICENSE-2.0
+
+     Unless required by applicable law or agreed to in writing, software
+     distributed under the License is distributed on an "AS IS" BASIS,
+     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+     See the License for the specific language governing permissions and
+     limitations under the License.
+-->
+<com.android.launcher3.Cling
+    xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:launcher="http://schemas.android.com/apk/res-auto/com.android.launcher3"
+    android:layout_width="match_parent"
+    android:layout_height="match_parent"
+    launcher:drawIdentifier="first_run_portrait">
+    <FrameLayout 
+        android:id="@+id/content"
+        android:layout_width="match_parent"
+        android:layout_height="match_parent">
+        <LinearLayout
+            android:id="@+id/bubble_content"
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content"
+            android:layout_gravity="center"
+            android:layout_marginLeft="100dp"
+            android:layout_marginRight="100dp"
+            android:orientation="vertical">
+            <TextView
+                style="@style/ClingAltTitleText"
+                android:layout_width="match_parent"
+                android:layout_height="wrap_content"
+                android:layout_gravity="center_horizontal"
+                android:layout_marginBottom="10dp"
+                android:text="@string/first_run_cling_title"
+                android:textColor="#FFFFFFFF"
+                android:gravity="center" />
+            <TextView
+                style="@style/ClingAltText"
+                android:layout_width="match_parent"
+                android:layout_height="wrap_content"
+                android:layout_gravity="center_horizontal"
+                android:text="@string/first_run_cling_description"
+                android:textColor="#80000000"
+                android:gravity="center" />
+        </LinearLayout>
+        <TextView
+            style="@style/ClingHintText"
+            android:id="@+id/search_bar_hint"
+            android:layout_width="wrap_content"
+            android:layout_height="wrap_content"
+            android:layout_gravity="top|end"
+            android:layout_marginEnd="30dp"
+            android:layout_marginTop="80dp"
+            android:gravity="center_horizontal"
+            android:maxWidth="160dp"
+            android:visibility="gone"
+            android:drawableTop="@drawable/cling_arrow_up"
+            android:drawablePadding="10dp"
+            android:text="@string/first_run_cling_search_bar_hint" />
+        <TextView
+            style="@style/ClingHintText"
+            android:id="@+id/custom_content_hint"
+            android:layout_width="wrap_content"
+            android:layout_height="wrap_content"
+            android:layout_gravity="top|start"
+            android:layout_marginStart="30dp"
+            android:layout_marginTop="120dp"
+            android:gravity="start"
+            android:maxWidth="160dp"
+            android:visibility="gone"
+            android:drawableStart="@drawable/cling_arrow_start"
+            android:drawablePadding="10dp"
+            android:text="@string/first_run_cling_custom_content_hint" />
+        <TextView
+            style="@style/ClingHintText"
+            android:layout_width="wrap_content"
+            android:layout_height="wrap_content"
+            android:layout_gravity="bottom|end"
+            android:layout_marginEnd="30dp"
+            android:layout_marginBottom="120dp"
+            android:maxWidth="180dp"
+            android:drawableEnd="@drawable/cling_arrow_end"
+            android:drawablePadding="10dp"
+            android:text="@string/first_run_cling_create_screens_hint" />
+    </FrameLayout>
+    <Button
+        style="@style/ClingButton"
+        android:layout_width="wrap_content"
+        android:layout_height="wrap_content"
+        android:layout_marginBottom="30dp"
+        android:layout_marginEnd="30dp"
+        android:layout_gravity="bottom|end"
+        android:onClick="dismissFirstRunCling" />
+</com.android.launcher3.Cling>
diff --git a/res/layout-sw600dp-port/folder_cling.xml b/res/layout-sw600dp-port/folder_cling.xml
deleted file mode 100644
index 87086cb..0000000
--- a/res/layout-sw600dp-port/folder_cling.xml
+++ /dev/null
@@ -1,51 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!-- Copyright (C) 2011 The Android Open Source Project
-
-     Licensed under the Apache License, Version 2.0 (the "License");
-     you may not use this file except in compliance with the License.
-     You may obtain a copy of the License at
-
-          http://www.apache.org/licenses/LICENSE-2.0
-
-     Unless required by applicable law or agreed to in writing, software
-     distributed under the License is distributed on an "AS IS" BASIS,
-     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-     See the License for the specific language governing permissions and
-     limitations under the License.
--->
-<com.android.launcher3.Cling
-    xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:launcher="http://schemas.android.com/apk/res-auto/com.android.launcher3"
-    launcher:drawIdentifier="folder_portrait">
-    <FrameLayout
-        android:layout_width="match_parent"
-        android:layout_height="match_parent"
-        android:layout_marginStart="20dp"
-        android:layout_marginEnd="10dp"
-        android:layout_marginTop="@dimen/folderClingMarginTop">
-        <LinearLayout
-            android:layout_width="match_parent"
-            android:layout_height="wrap_content"
-            android:orientation="vertical">
-            <TextView
-                style="@style/ClingTitleText"
-                android:id="@+id/folder_cling_title"
-                android:text="@string/folder_cling_title" />
-            <TextView
-                style="@style/ClingText"
-                android:id="@+id/folder_cling_create_folder"
-                android:layout_width="match_parent"
-                android:layout_height="wrap_content"
-                android:text="@string/folder_cling_create_folder" />
-        </LinearLayout>
-    </FrameLayout>
-    <Button
-        style="@style/ClingButton"
-        android:id="@+id/cling_dismiss"
-        android:minWidth="168dp"
-        android:textSize="24sp"
-        android:layout_marginBottom="27dp"
-        android:layout_marginEnd="36dp"
-        android:layout_gravity="bottom|end"
-        android:onClick="dismissFolderCling" />
-</com.android.launcher3.Cling>
diff --git a/res/layout-sw600dp-port/migration_workspace_cling.xml b/res/layout-sw600dp-port/migration_workspace_cling.xml
new file mode 100644
index 0000000..eb13137
--- /dev/null
+++ b/res/layout-sw600dp-port/migration_workspace_cling.xml
@@ -0,0 +1,70 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2011 The Android Open Source Project
+
+     Licensed under the Apache License, Version 2.0 (the "License");
+     you may not use this file except in compliance with the License.
+     You may obtain a copy of the License at
+
+          http://www.apache.org/licenses/LICENSE-2.0
+
+     Unless required by applicable law or agreed to in writing, software
+     distributed under the License is distributed on an "AS IS" BASIS,
+     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+     See the License for the specific language governing permissions and
+     limitations under the License.
+-->
+<com.android.launcher3.Cling
+    xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:launcher="http://schemas.android.com/apk/res-auto/com.android.launcher3"
+    android:layout_width="match_parent"
+    android:layout_height="match_parent"
+    launcher:drawIdentifier="migration_workspace_large_portrait">
+    <FrameLayout
+        android:id="@+id/content"
+        android:layout_width="480dp"
+        android:layout_height="match_parent"
+        android:layout_gravity="bottom|center_horizontal">
+        <LinearLayout
+            android:id="@+id/migration_workspace_cling_bubble"
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content"
+            android:layout_gravity="bottom"
+            android:layout_marginStart="25dp"
+            android:layout_marginEnd="25dp"
+            android:orientation="vertical">
+            <LinearLayout
+                android:layout_width="match_parent"
+                android:layout_height="wrap_content"
+                android:layout_marginRight="4dp"
+                android:paddingLeft="20dp"
+                android:paddingRight="20dp"
+                android:paddingTop="20dp"
+                android:paddingBottom="20dp"
+                android:orientation="vertical"
+                android:background="@drawable/cling">
+                <TextView
+                    style="@style/ClingTitleText"
+                    android:layout_width="wrap_content"
+                    android:layout_height="wrap_content"
+                    android:text="@string/workspace_cling_title" />
+                <TextView
+                    style="@style/ClingText"
+                    android:layout_width="match_parent"
+                    android:layout_height="wrap_content"
+                    android:text="@string/workspace_cling_move_item" />
+            </LinearLayout>
+            <ImageView
+                android:layout_width="wrap_content"
+                android:layout_height="wrap_content"
+                android:layout_gravity="center_horizontal"
+                android:src="@drawable/cling_arrow_down" />
+            <Button
+                style="@style/ClingButton"
+                android:id="@+id/dismiss_migration_workspace_cling_button"
+                android:layout_width="wrap_content"
+                android:layout_height="wrap_content"
+                android:layout_gravity="right"
+                android:onClick="dismissMigrationWorkspaceCling" />
+        </LinearLayout>
+    </FrameLayout>
+</com.android.launcher3.Cling>
diff --git a/res/layout-sw600dp/first_run_cling.xml b/res/layout-sw600dp/first_run_cling.xml
new file mode 100644
index 0000000..295765b
--- /dev/null
+++ b/res/layout-sw600dp/first_run_cling.xml
@@ -0,0 +1,100 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2011 The Android Open Source Project
+
+     Licensed under the Apache License, Version 2.0 (the "License");
+     you may not use this file except in compliance with the License.
+     You may obtain a copy of the License at
+
+          http://www.apache.org/licenses/LICENSE-2.0
+
+     Unless required by applicable law or agreed to in writing, software
+     distributed under the License is distributed on an "AS IS" BASIS,
+     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+     See the License for the specific language governing permissions and
+     limitations under the License.
+-->
+<com.android.launcher3.Cling
+    xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:launcher="http://schemas.android.com/apk/res-auto/com.android.launcher3"
+    android:layout_width="match_parent"
+    android:layout_height="match_parent"
+    launcher:drawIdentifier="first_run_landscape">
+    <FrameLayout 
+        android:id="@+id/content"
+        android:layout_width="match_parent"
+        android:layout_height="match_parent">
+        <LinearLayout
+            android:id="@+id/bubble_content"
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content"
+            android:layout_gravity="center"
+            android:layout_marginLeft="100dp"
+            android:layout_marginRight="100dp"
+            android:orientation="vertical">
+            <TextView
+                style="@style/ClingAltTitleText"
+                android:layout_width="match_parent"
+                android:layout_height="wrap_content"
+                android:layout_gravity="center_horizontal"
+                android:layout_marginBottom="10dp"
+                android:text="@string/first_run_cling_title"
+                android:textColor="#FFFFFFFF"
+                android:gravity="center" />
+            <TextView
+                style="@style/ClingAltText"
+                android:layout_width="match_parent"
+                android:layout_height="wrap_content"
+                android:layout_gravity="center_horizontal"
+                android:text="@string/first_run_cling_description"
+                android:textColor="#80000000"
+                android:gravity="center" />
+        </LinearLayout>
+        <TextView
+            style="@style/ClingHintText"
+            android:id="@+id/search_bar_hint"
+            android:layout_width="wrap_content"
+            android:layout_height="wrap_content"
+            android:layout_gravity="top|start"
+            android:layout_marginStart="60dp"
+            android:layout_marginTop="105dp"
+            android:gravity="start"
+            android:maxWidth="160dp"
+            android:visibility="gone"
+            android:drawableStart="@drawable/cling_arrow_start"
+            android:drawablePadding="10dp"
+            android:text="@string/first_run_cling_search_bar_hint" />
+        <TextView
+            style="@style/ClingHintText"
+            android:id="@+id/custom_content_hint"
+            android:layout_width="wrap_content"
+            android:layout_height="wrap_content"
+            android:layout_gravity="top|start"
+            android:layout_marginStart="60dp"
+            android:layout_marginTop="200dp"
+            android:gravity="start"
+            android:maxWidth="160dp"
+            android:visibility="gone"
+            android:drawableStart="@drawable/cling_arrow_start"
+            android:drawablePadding="10dp"
+            android:text="@string/first_run_cling_custom_content_hint" />
+        <TextView
+            style="@style/ClingHintText"
+            android:layout_width="wrap_content"
+            android:layout_height="wrap_content"
+            android:layout_gravity="bottom|end"
+            android:layout_marginEnd="30dp"
+            android:layout_marginBottom="120dp"
+            android:maxWidth="180dp"
+            android:drawableEnd="@drawable/cling_arrow_end"
+            android:drawablePadding="10dp"
+            android:text="@string/first_run_cling_create_screens_hint" />
+    </FrameLayout>
+    <Button
+        style="@style/ClingButton"
+        android:layout_width="wrap_content"
+        android:layout_height="wrap_content"
+        android:layout_marginBottom="30dp"
+        android:layout_marginEnd="30dp"
+        android:layout_gravity="bottom|end"
+        android:onClick="dismissFirstRunCling" />
+</com.android.launcher3.Cling>
diff --git a/res/layout-sw600dp/folder_cling.xml b/res/layout-sw600dp/folder_cling.xml
new file mode 100644
index 0000000..f21aef4
--- /dev/null
+++ b/res/layout-sw600dp/folder_cling.xml
@@ -0,0 +1,66 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2011 The Android Open Source Project
+
+     Licensed under the Apache License, Version 2.0 (the "License");
+     you may not use this file except in compliance with the License.
+     You may obtain a copy of the License at
+
+          http://www.apache.org/licenses/LICENSE-2.0
+
+     Unless required by applicable law or agreed to in writing, software
+     distributed under the License is distributed on an "AS IS" BASIS,
+     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+     See the License for the specific language governing permissions and
+     limitations under the License.
+-->
+<com.android.launcher3.Cling
+    xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:launcher="http://schemas.android.com/apk/res-auto/com.android.launcher3"
+    launcher:drawIdentifier="folder_large">
+    <LinearLayout
+        android:id="@+id/folder_bubble"
+        android:layout_width="300dp"
+        android:layout_height="match_parent"
+        android:layout_gravity="left|top"
+        android:paddingTop="28dp"
+        android:paddingRight="10dp"
+        android:orientation="vertical">
+        <LinearLayout
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content"
+            android:orientation="horizontal">
+            <ImageView
+                android:layout_width="wrap_content"
+                android:layout_height="wrap_content"
+                android:layout_gravity="center_vertical"
+                android:src="@drawable/cling_arrow_start" />
+            <LinearLayout
+                android:layout_width="match_parent"
+                android:layout_height="wrap_content"
+                android:layout_marginRight="4dp"
+                android:paddingLeft="20dp"
+                android:paddingRight="20dp"
+                android:paddingTop="20dp"
+                android:paddingBottom="20dp"
+                android:orientation="vertical"
+                android:background="@drawable/cling">
+                <TextView
+                    style="@style/ClingTitleText"
+                    android:id="@+id/folder_cling_title"
+                    android:text="@string/folder_cling_title" />
+                <TextView
+                    style="@style/ClingText"
+                    android:id="@+id/folder_cling_create_folder"
+                    android:layout_width="match_parent"
+                    android:layout_height="wrap_content"
+                    android:text="@string/folder_cling_create_folder" />
+            </LinearLayout>
+        </LinearLayout>
+        <Button
+            style="@style/ClingButton"
+            android:id="@+id/cling_dismiss"
+            android:layout_marginTop="5dp"
+            android:layout_gravity="right"
+            android:onClick="dismissFolderCling" />
+    </LinearLayout>
+</com.android.launcher3.Cling>
diff --git a/res/layout-sw600dp/migration_cling.xml b/res/layout-sw600dp/migration_cling.xml
new file mode 100644
index 0000000..19def6a
--- /dev/null
+++ b/res/layout-sw600dp/migration_cling.xml
@@ -0,0 +1,98 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2011 The Android Open Source Project
+
+     Licensed under the Apache License, Version 2.0 (the "License");
+     you may not use this file except in compliance with the License.
+     You may obtain a copy of the License at
+
+          http://www.apache.org/licenses/LICENSE-2.0
+
+     Unless required by applicable law or agreed to in writing, software
+     distributed under the License is distributed on an "AS IS" BASIS,
+     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+     See the License for the specific language governing permissions and
+     limitations under the License.
+-->
+<com.android.launcher3.Cling
+    xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:launcher="http://schemas.android.com/apk/res-auto/com.android.launcher3"
+    android:layout_width="match_parent"
+    android:layout_height="match_parent"
+    launcher:drawIdentifier="migration_portrait">
+    <LinearLayout
+        android:id="@+id/content"
+        android:layout_width="360dp"
+        android:layout_height="wrap_content"
+        android:layout_gravity="center"
+        android:orientation="vertical">
+
+        <LinearLayout
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content"
+            android:layout_gravity="top"
+            android:layout_marginBottom="15dp"
+            android:orientation="vertical">
+            <TextView
+                android:layout_width="match_parent"
+                android:layout_height="wrap_content"
+                android:gravity="center"
+                android:text="@string/first_run_cling_title"
+                android:textSize="42dp"
+                android:textColor="#FFffffff" />
+            <ImageView
+                android:layout_width="wrap_content"
+                android:layout_height="wrap_content"
+                android:layout_marginTop="10dp"
+                android:layout_marginBottom="0dp"
+                android:layout_gravity="center_horizontal"
+                android:src="@drawable/on_boarding_welcome" />
+
+            <ImageView
+                android:layout_width="wrap_content"
+                android:layout_height="wrap_content"
+                android:layout_gravity="center_horizontal"
+                android:src="@drawable/cling_arrow_up" />
+            <LinearLayout
+                android:layout_width="match_parent"
+                android:layout_height="wrap_content"
+                android:layout_marginLeft="4dp"
+                android:layout_marginRight="4dp"
+                android:paddingLeft="25dp"
+                android:paddingRight="25dp"
+                android:paddingTop="20dp"
+                android:paddingBottom="20dp"
+                android:orientation="vertical"
+                android:background="@drawable/cling">
+                <TextView
+                    style="@style/ClingTitleText"
+                    android:layout_width="wrap_content"
+                    android:layout_height="wrap_content"
+                    android:text="@string/migration_cling_title" />
+                <TextView
+                    style="@style/ClingText"
+                    android:layout_width="match_parent"
+                    android:layout_height="wrap_content"
+                    android:text="@string/migration_cling_description" />
+            </LinearLayout>
+        </LinearLayout>
+
+        <LinearLayout
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content"
+            android:layout_gravity="bottom"
+            android:orientation="vertical">
+            <Button
+                style="@style/ClingButton"
+                android:layout_width="match_parent"
+                android:layout_height="wrap_content"
+                android:text="@string/migration_cling_copy_apps"
+                android:onClick="dismissMigrationClingCopyApps" />
+            <Button
+                style="@style/ClingButton"
+                android:layout_width="match_parent"
+                android:layout_height="wrap_content"
+                android:text="@string/migration_cling_use_default"
+                android:onClick="dismissMigrationClingUseDefault" />
+        </LinearLayout>
+    </LinearLayout>
+</com.android.launcher3.Cling>
diff --git a/res/layout-sw600dp/workspace_cling.xml b/res/layout-sw600dp/workspace_cling.xml
new file mode 100644
index 0000000..63b5522
--- /dev/null
+++ b/res/layout-sw600dp/workspace_cling.xml
@@ -0,0 +1,65 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2011 The Android Open Source Project
+
+     Licensed under the Apache License, Version 2.0 (the "License");
+     you may not use this file except in compliance with the License.
+     You may obtain a copy of the License at
+
+          http://www.apache.org/licenses/LICENSE-2.0
+
+     Unless required by applicable law or agreed to in writing, software
+     distributed under the License is distributed on an "AS IS" BASIS,
+     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+     See the License for the specific language governing permissions and
+     limitations under the License.
+-->
+<com.android.launcher3.Cling
+    xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:launcher="http://schemas.android.com/apk/res-auto/com.android.launcher3"
+    android:layout_width="match_parent"
+    android:layout_height="match_parent"
+    launcher:drawIdentifier="workspace_large">
+    <FrameLayout
+        android:id="@+id/content"
+        android:layout_width="match_parent"
+        android:layout_height="match_parent">
+        <LinearLayout
+            android:id="@+id/workspace_cling_bubble"
+            android:layout_width="400dp"
+            android:layout_height="wrap_content"
+            android:layout_gravity="center_horizontal|bottom"
+            android:orientation="vertical">
+            <LinearLayout
+                android:layout_width="match_parent"
+                android:layout_height="wrap_content"
+                android:paddingLeft="20dp"
+                android:paddingRight="20dp"
+                android:paddingTop="20dp"
+                android:paddingBottom="20dp"
+                android:orientation="vertical"
+                android:background="@drawable/cling">
+                <TextView
+                    style="@style/ClingTitleText"
+                    android:layout_width="wrap_content"
+                    android:layout_height="wrap_content"
+                    android:text="@string/workspace_cling_title" />
+                <TextView
+                    style="@style/ClingText"
+                    android:layout_width="match_parent"
+                    android:layout_height="wrap_content"
+                    android:text="@string/workspace_cling_move_item" />
+            </LinearLayout>
+            <ImageView
+                android:layout_width="wrap_content"
+                android:layout_height="wrap_content"
+                android:layout_gravity="center_horizontal"
+                android:src="@drawable/cling_arrow_down" />
+            <Button
+                style="@style/ClingButton"
+                android:layout_width="wrap_content"
+                android:layout_height="wrap_content"
+                android:layout_gravity="right"
+                android:onClick="dismissWorkspaceCling" />
+        </LinearLayout>
+    </FrameLayout>
+</com.android.launcher3.Cling>
diff --git a/res/layout-sw720dp-port/folder_cling.xml b/res/layout-sw720dp-port/folder_cling.xml
deleted file mode 100644
index 40d4e20..0000000
--- a/res/layout-sw720dp-port/folder_cling.xml
+++ /dev/null
@@ -1,46 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!-- Copyright (C) 2011 The Android Open Source Project
-
-     Licensed under the Apache License, Version 2.0 (the "License");
-     you may not use this file except in compliance with the License.
-     You may obtain a copy of the License at
-
-          http://www.apache.org/licenses/LICENSE-2.0
-
-     Unless required by applicable law or agreed to in writing, software
-     distributed under the License is distributed on an "AS IS" BASIS,
-     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-     See the License for the specific language governing permissions and
-     limitations under the License.
--->
-<com.android.launcher3.Cling
-    xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:launcher="http://schemas.android.com/apk/res-auto/com.android.launcher3"
-    launcher:drawIdentifier="folder_large">
-    <FrameLayout
-        android:layout_width="match_parent"
-        android:layout_height="match_parent"
-        android:layout_marginStart="@dimen/cling_text_block_offset_x"
-        android:layout_marginTop="@dimen/cling_text_block_offset_y">
-        <LinearLayout
-            android:layout_width="match_parent"
-            android:layout_height="wrap_content"
-            android:orientation="vertical">
-            <TextView
-                style="@style/ClingTitleText"
-                android:id="@+id/folder_cling_title"
-                android:text="@string/folder_cling_title" />
-            <TextView
-                style="@style/ClingText"
-                android:id="@+id/folder_cling_create_folder"
-                android:layout_width="480dp"
-                android:layout_height="wrap_content"
-                android:text="@string/folder_cling_create_folder" />
-            <Button
-                style="@style/ClingButton"
-                android:id="@+id/cling_dismiss"
-                android:layout_marginTop="15dp"
-                android:onClick="dismissFolderCling" />
-        </LinearLayout>
-    </FrameLayout>
-</com.android.launcher3.Cling>
diff --git a/res/layout-sw720dp/all_apps_cling.xml b/res/layout-sw720dp/all_apps_cling.xml
deleted file mode 100644
index 824d84f..0000000
--- a/res/layout-sw720dp/all_apps_cling.xml
+++ /dev/null
@@ -1,46 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!-- Copyright (C) 2011 The Android Open Source Project
-
-     Licensed under the Apache License, Version 2.0 (the "License");
-     you may not use this file except in compliance with the License.
-     You may obtain a copy of the License at
-
-          http://www.apache.org/licenses/LICENSE-2.0
-
-     Unless required by applicable law or agreed to in writing, software
-     distributed under the License is distributed on an "AS IS" BASIS,
-     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-     See the License for the specific language governing permissions and
-     limitations under the License.
--->
-<com.android.launcher3.Cling
-    xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:launcher="http://schemas.android.com/apk/res-auto/com.android.launcher3"
-    launcher:drawIdentifier="all_apps_large">
-    <FrameLayout
-        android:layout_width="match_parent"
-        android:layout_height="match_parent"
-        android:layout_marginStart="@dimen/cling_text_block_offset_x"
-        android:layout_marginTop="@dimen/cling_text_block_offset_y">
-        <LinearLayout
-            android:layout_width="match_parent"
-            android:layout_height="wrap_content"
-            android:orientation="vertical">
-            <TextView
-                style="@style/ClingTitleText"
-                android:id="@+id/all_apps_cling_title"
-                android:text="@string/all_apps_cling_title" />
-            <TextView
-                style="@style/ClingText"
-                android:id="@+id/all_apps_cling_add_item"
-                android:layout_width="match_parent"
-                android:layout_height="wrap_content"
-                android:text="@string/all_apps_cling_add_item" />
-            <Button
-                style="@style/ClingButton"
-                android:id="@+id/cling_dismiss"
-                android:layout_marginTop="15dp"
-                android:onClick="dismissAllAppsCling" />
-        </LinearLayout>
-    </FrameLayout>
-</com.android.launcher3.Cling>
diff --git a/res/layout-sw720dp/first_run_cling.xml b/res/layout-sw720dp/first_run_cling.xml
new file mode 100644
index 0000000..c43d8d3
--- /dev/null
+++ b/res/layout-sw720dp/first_run_cling.xml
@@ -0,0 +1,98 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2011 The Android Open Source Project
+
+     Licensed under the Apache License, Version 2.0 (the "License");
+     you may not use this file except in compliance with the License.
+     You may obtain a copy of the License at
+
+          http://www.apache.org/licenses/LICENSE-2.0
+
+     Unless required by applicable law or agreed to in writing, software
+     distributed under the License is distributed on an "AS IS" BASIS,
+     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+     See the License for the specific language governing permissions and
+     limitations under the License.
+-->
+<com.android.launcher3.Cling
+    xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:launcher="http://schemas.android.com/apk/res-auto/com.android.launcher3"
+    android:layout_width="match_parent"
+    android:layout_height="match_parent"
+    launcher:drawIdentifier="first_run_portrait">
+    <FrameLayout 
+        android:id="@+id/content"
+        android:layout_width="match_parent"
+        android:layout_height="match_parent">
+        <LinearLayout
+            android:id="@+id/bubble_content"
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content"
+            android:layout_gravity="center"
+            android:layout_marginLeft="100dp"
+            android:layout_marginRight="100dp"
+            android:orientation="vertical">
+            <TextView
+                style="@style/ClingAltTitleText"
+                android:layout_width="match_parent"
+                android:layout_height="wrap_content"
+                android:layout_gravity="center_horizontal"
+                android:layout_marginBottom="10dp"
+                android:text="@string/first_run_cling_title"
+                android:textColor="#FFFFFFFF"
+                android:gravity="center" />
+            <TextView
+                style="@style/ClingAltText"
+                android:layout_width="match_parent"
+                android:layout_height="wrap_content"
+                android:layout_gravity="center_horizontal"
+                android:text="@string/first_run_cling_description"
+                android:textColor="#80000000"
+                android:gravity="center" />
+        </LinearLayout>
+        <TextView
+            style="@style/ClingHintText"
+            android:id="@+id/search_bar_hint"
+            android:layout_width="wrap_content"
+            android:layout_height="wrap_content"
+            android:layout_gravity="top|end"
+            android:layout_marginEnd="120dp"
+            android:layout_marginTop="80dp"
+            android:gravity="center_horizontal"
+            android:maxWidth="160dp"
+            android:visibility="gone"
+            android:drawableTop="@drawable/cling_arrow_up"
+            android:drawablePadding="10dp"
+            android:text="@string/first_run_cling_search_bar_hint" />
+        <TextView
+            style="@style/ClingHintText"
+            android:id="@+id/custom_content_hint"
+            android:layout_width="wrap_content"
+            android:layout_height="wrap_content"
+            android:layout_gravity="center_vertical|start"
+            android:layout_marginStart="30dp"
+            android:gravity="start"
+            android:maxWidth="160dp"
+            android:visibility="gone"
+            android:drawableStart="@drawable/cling_arrow_start"
+            android:drawablePadding="10dp"
+            android:text="@string/first_run_cling_custom_content_hint" />
+        <TextView
+            style="@style/ClingHintText"
+            android:layout_width="wrap_content"
+            android:layout_height="wrap_content"
+            android:layout_gravity="center_vertical|end"
+            android:layout_marginEnd="30dp"
+            android:maxWidth="180dp"
+            android:drawableEnd="@drawable/cling_arrow_end"
+            android:drawablePadding="10dp"
+            android:text="@string/first_run_cling_create_screens_hint" />
+    </FrameLayout>
+    <Button
+        style="@style/ClingButton"
+        android:layout_width="wrap_content"
+        android:layout_height="wrap_content"
+        android:layout_marginBottom="30dp"
+        android:layout_marginEnd="40dp"
+        android:layout_gravity="bottom|end"
+        android:onClick="dismissFirstRunCling" />
+</com.android.launcher3.Cling>
diff --git a/res/layout-sw720dp/launcher.xml b/res/layout-sw720dp/launcher.xml
index 951e63a..685d03c 100644
--- a/res/layout-sw720dp/launcher.xml
+++ b/res/layout-sw720dp/launcher.xml
@@ -36,7 +36,6 @@
             android:layout_width="match_parent"
             android:layout_height="match_parent"
             launcher:defaultScreen="@integer/config_workspaceDefaultScreen"
-            launcher:pageSpacing="@dimen/workspace_page_spacing"
             launcher:pageIndicator="@id/page_indicator">
         </com.android.launcher3.Workspace>
 
@@ -46,8 +45,8 @@
             android:layout_height="match_parent" />
 
         <include
-            android:id="@+id/qsb_bar"
-            layout="@layout/qsb_bar" />
+            android:id="@+id/search_drop_target_bar"
+            layout="@layout/search_drop_target_bar" />
 
         <include layout="@layout/overview_panel"
             android:id="@+id/overview_panel"
@@ -65,17 +64,31 @@
         <!-- The Workspace cling must appear under the AppsCustomizePagedView below to ensure
              that it is still visible during the transition to AllApps and doesn't overlay on
              top of that view. -->
+        <com.android.launcher3.ScrimView
+            android:id="@+id/cling_scrim"
+            android:layout_width="match_parent"
+            android:layout_height="match_parent"
+            android:visibility="gone" />
         <include layout="@layout/first_run_cling"
             android:id="@+id/first_run_cling"
             android:layout_width="match_parent"
             android:layout_height="match_parent"
             android:visibility="gone" />
+        <include layout="@layout/migration_cling"
+            android:id="@+id/migration_cling"
+            android:layout_width="match_parent"
+            android:layout_height="match_parent"
+            android:visibility="gone" />
+        <include layout="@layout/migration_workspace_cling"
+            android:id="@+id/migration_workspace_cling"
+            android:layout_width="match_parent"
+            android:layout_height="match_parent"
+            android:visibility="gone" />
         <include layout="@layout/workspace_cling"
             android:id="@+id/workspace_cling"
             android:layout_width="match_parent"
             android:layout_height="match_parent"
             android:visibility="gone" />
-
         <include layout="@layout/folder_cling"
             android:id="@+id/folder_cling"
             android:layout_width="match_parent"
diff --git a/res/layout-sw720dp/market_button.xml b/res/layout-sw720dp/market_button.xml
index f1e9959..7eaeafa 100644
--- a/res/layout-sw720dp/market_button.xml
+++ b/res/layout-sw720dp/market_button.xml
@@ -18,8 +18,8 @@
     style="@style/MarketButton"
     android:onClick="onClickAppMarketButton"
     android:gravity="center"
-    android:paddingStart="32dp"
-    android:paddingEnd="32dp"
+    android:paddingLeft="32dp"
+    android:paddingRight="32dp"
     android:drawablePadding="10dp"
     android:background="@drawable/tab_widget_indicator_selector"
     android:text="@string/market"
diff --git a/res/layout-sw720dp/migration_workspace_cling.xml b/res/layout-sw720dp/migration_workspace_cling.xml
new file mode 100644
index 0000000..eb13137
--- /dev/null
+++ b/res/layout-sw720dp/migration_workspace_cling.xml
@@ -0,0 +1,70 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2011 The Android Open Source Project
+
+     Licensed under the Apache License, Version 2.0 (the "License");
+     you may not use this file except in compliance with the License.
+     You may obtain a copy of the License at
+
+          http://www.apache.org/licenses/LICENSE-2.0
+
+     Unless required by applicable law or agreed to in writing, software
+     distributed under the License is distributed on an "AS IS" BASIS,
+     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+     See the License for the specific language governing permissions and
+     limitations under the License.
+-->
+<com.android.launcher3.Cling
+    xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:launcher="http://schemas.android.com/apk/res-auto/com.android.launcher3"
+    android:layout_width="match_parent"
+    android:layout_height="match_parent"
+    launcher:drawIdentifier="migration_workspace_large_portrait">
+    <FrameLayout
+        android:id="@+id/content"
+        android:layout_width="480dp"
+        android:layout_height="match_parent"
+        android:layout_gravity="bottom|center_horizontal">
+        <LinearLayout
+            android:id="@+id/migration_workspace_cling_bubble"
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content"
+            android:layout_gravity="bottom"
+            android:layout_marginStart="25dp"
+            android:layout_marginEnd="25dp"
+            android:orientation="vertical">
+            <LinearLayout
+                android:layout_width="match_parent"
+                android:layout_height="wrap_content"
+                android:layout_marginRight="4dp"
+                android:paddingLeft="20dp"
+                android:paddingRight="20dp"
+                android:paddingTop="20dp"
+                android:paddingBottom="20dp"
+                android:orientation="vertical"
+                android:background="@drawable/cling">
+                <TextView
+                    style="@style/ClingTitleText"
+                    android:layout_width="wrap_content"
+                    android:layout_height="wrap_content"
+                    android:text="@string/workspace_cling_title" />
+                <TextView
+                    style="@style/ClingText"
+                    android:layout_width="match_parent"
+                    android:layout_height="wrap_content"
+                    android:text="@string/workspace_cling_move_item" />
+            </LinearLayout>
+            <ImageView
+                android:layout_width="wrap_content"
+                android:layout_height="wrap_content"
+                android:layout_gravity="center_horizontal"
+                android:src="@drawable/cling_arrow_down" />
+            <Button
+                style="@style/ClingButton"
+                android:id="@+id/dismiss_migration_workspace_cling_button"
+                android:layout_width="wrap_content"
+                android:layout_height="wrap_content"
+                android:layout_gravity="right"
+                android:onClick="dismissMigrationWorkspaceCling" />
+        </LinearLayout>
+    </FrameLayout>
+</com.android.launcher3.Cling>
diff --git a/res/layout-port/search_bar.xml b/res/layout-sw720dp/qsb.xml
similarity index 95%
copy from res/layout-port/search_bar.xml
copy to res/layout-sw720dp/qsb.xml
index 1c96ca3..4c9963d 100644
--- a/res/layout-port/search_bar.xml
+++ b/res/layout-sw720dp/qsb.xml
@@ -16,13 +16,12 @@
 <RelativeLayout
     xmlns:android="http://schemas.android.com/apk/res/android"
     xmlns:launcher="http://schemas.android.com/apk/res-auto/com.android.launcher3"
-    style="@style/SearchDropTargetBar"
     android:layout_width="match_parent"
     android:layout_height="match_parent"
     android:background="@drawable/search_frame">
    <!-- Global search icon -->
    <com.android.launcher3.HolographicLinearLayout
-        style="@style/SearchButton"
+        style="@style/SearchButton.WithPaddingStart"
         launcher:sourceImageViewId="@+id/search_button"
         android:id="@+id/search_button_container"
         android:layout_width="match_parent"
@@ -31,7 +30,6 @@
         android:layout_centerVertical="true"
         android:layout_alignParentStart="true"
         android:layout_toStartOf="@+id/voice_button_container"
-        android:paddingStart="8dp"
         android:onClick="onClickSearchButton"
         android:focusable="true"
         android:clickable="true"
@@ -57,6 +55,7 @@
         android:layout_centerVertical="true"
         android:layout_alignParentEnd="true"
         android:paddingEnd="8dp"
+        android:paddingRight="8dp"
         android:onClick="onClickVoiceButton"
         android:focusable="true"
         android:clickable="true"
diff --git a/res/layout-sw720dp/search_bar.xml b/res/layout-sw720dp/search_bar.xml
deleted file mode 100644
index 69dd61a..0000000
--- a/res/layout-sw720dp/search_bar.xml
+++ /dev/null
@@ -1,71 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!-- Copyright (C) 2011 The Android Open Source Project
-
-     Licensed under the Apache License, Version 2.0 (the "License");
-     you may not use this file except in compliance with the License.
-     You may obtain a copy of the License at
-
-          http://www.apache.org/licenses/LICENSE-2.0
-
-     Unless required by applicable law or agreed to in writing, software
-     distributed under the License is distributed on an "AS IS" BASIS,
-     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-     See the License for the specific language governing permissions and
-     limitations under the License.
--->
-<RelativeLayout
-    xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:launcher="http://schemas.android.com/apk/res-auto/com.android.launcher3"
-    style="@style/SearchDropTargetBar"
-    android:background="@drawable/search_frame">
-   <!-- Global search icon -->
-   <com.android.launcher3.HolographicLinearLayout
-        style="@style/SearchButton"
-        launcher:sourceImageViewId="@+id/search_button"
-        android:id="@+id/search_button_container"
-        android:layout_width="match_parent"
-        android:layout_height="match_parent"
-        android:layout_gravity="center_vertical"
-        android:layout_centerVertical="true"
-        android:layout_alignParentStart="true"
-        android:layout_toStartOf="@+id/voice_button_container"
-        android:paddingStart="8dp"
-        android:onClick="onClickSearchButton"
-        android:focusable="true"
-        android:clickable="true"
-        android:contentDescription="@string/accessibility_search_button">
-       <ImageView
-            android:id="@+id/search_button"
-            android:layout_width="wrap_content"
-            android:layout_height="match_parent"
-            android:layout_gravity="start"
-            android:scaleType="fitCenter"
-            android:src="@drawable/ic_home_search_normal_holo"
-            android:adjustViewBounds="true" />
-    </com.android.launcher3.HolographicLinearLayout>
-
-    <!-- Voice search icon -->
-    <com.android.launcher3.HolographicLinearLayout
-        style="@style/SearchButton"
-        launcher:sourceImageViewId="@+id/voice_button"
-        android:id="@+id/voice_button_container"
-        android:layout_width="@dimen/app_icon_size"
-        android:layout_height="match_parent"
-        android:layout_gravity="center_vertical"
-        android:layout_centerVertical="true"
-        android:layout_alignParentEnd="true"
-        android:paddingEnd="8dp"
-        android:onClick="onClickVoiceButton"
-        android:focusable="true"
-        android:clickable="true"
-        android:contentDescription="@string/accessibility_voice_search_button">
-        <ImageView
-            android:id="@+id/voice_button"
-            android:layout_width="match_parent"
-            android:layout_height="match_parent"
-            android:layout_gravity="end"
-            android:scaleType="fitCenter"
-            android:src="@drawable/ic_home_voice_search_holo"
-            android:adjustViewBounds="true" />
-    </com.android.launcher3.HolographicLinearLayout>
-</RelativeLayout>
diff --git a/res/layout/add_list_item.xml b/res/layout/add_list_item.xml
index 0ae0113..e937d7b 100644
--- a/res/layout/add_list_item.xml
+++ b/res/layout/add_list_item.xml
@@ -21,5 +21,5 @@
     android:textAppearance="?android:attr/textAppearanceLarge"
     android:gravity="center_vertical"
     android:drawablePadding="14dip"
-    android:paddingStart="15dip"
-    android:paddingEnd="15dip" />
+    android:paddingLeft="15dip"
+    android:paddingRight="15dip" />
diff --git a/res/layout/apps_customize_pane.xml b/res/layout/apps_customize_pane.xml
index 11a938f..eae216e 100644
--- a/res/layout/apps_customize_pane.xml
+++ b/res/layout/apps_customize_pane.xml
@@ -56,13 +56,12 @@
                 android:id="@+id/apps_customize_pane_content"
                 android:layout_width="match_parent"
                 android:layout_height="match_parent"
-                android:layout_marginBottom="@dimen/apps_customize_page_indicator_offset"
                 launcher:widgetCountX="@integer/apps_customize_widget_cell_count_x"
                 launcher:widgetCountY="@integer/apps_customize_widget_cell_count_y"
                 launcher:clingFocusedX="@integer/apps_customize_cling_focused_x"
                 launcher:clingFocusedY="@integer/apps_customize_cling_focused_y"
                 launcher:maxGap="@dimen/workspace_max_gap"
-                launcher:pageIndicator="@+id/page_indicator" />
+                launcher:pageIndicator="@+id/apps_customize_page_indicator" />
             <FrameLayout
                 android:id="@+id/animation_buffer"
                 android:layout_width="match_parent"
@@ -70,12 +69,11 @@
                 android:background="#FF000000"
                 android:visibility="gone" />
             <include
-                android:id="@+id/page_indicator"
+                android:id="@+id/apps_customize_page_indicator"
                 layout="@layout/page_indicator"
                 android:layout_width="wrap_content"
                 android:layout_height="wrap_content"
-                android:layout_gravity="bottom|center_horizontal"
-                android:layout_marginBottom="@dimen/apps_customize_page_indicator_margin" />
+                android:layout_gravity="center_horizontal|bottom" />
         </FrameLayout>
     </LinearLayout>
 </com.android.launcher3.AppsCustomizeTabHost>
diff --git a/res/layout/apps_customize_widget.xml b/res/layout/apps_customize_widget.xml
index f2d2342..7c98b4a 100644
--- a/res/layout/apps_customize_widget.xml
+++ b/res/layout/apps_customize_widget.xml
@@ -28,12 +28,13 @@
     <!-- The preview of the widget or shortcut. -->
     <com.android.launcher3.PagedViewWidgetImageView
         android:id="@+id/widget_preview"
+        style="@style/PagedViewWidgetImageView"
         android:layout_width="match_parent"
         android:layout_height="wrap_content"
         android:layout_weight="1"
         android:paddingTop="@dimen/app_widget_preview_padding_top"
-        android:paddingStart="@dimen/app_widget_preview_padding_left"
         android:paddingEnd="@dimen/app_widget_preview_padding_right"
+        android:paddingRight="@dimen/app_widget_preview_padding_right"
         android:scaleType="matrix"
         android:background="@drawable/screenpanel" />
     <LinearLayout
diff --git a/res/layout/appwidget_error.xml b/res/layout/appwidget_error.xml
index f5a9148..03d4ae4 100644
--- a/res/layout/appwidget_error.xml
+++ b/res/layout/appwidget_error.xml
@@ -19,8 +19,8 @@
     android:layout_height="wrap_content"
     android:paddingTop="10dip"
     android:paddingBottom="10dip"
-    android:paddingStart="20dip"
-    android:paddingEnd="20dip"
+    android:paddingLeft="20dip"
+    android:paddingRight="20dip"
     android:gravity="center"
     android:background="@drawable/bg_appwidget_error"
     android:textAppearance="?android:attr/textAppearanceMediumInverse"
diff --git a/res/layout/folder_icon.xml b/res/layout/folder_icon.xml
index 4405682..5147f99 100644
--- a/res/layout/folder_icon.xml
+++ b/res/layout/folder_icon.xml
@@ -30,5 +30,8 @@
         android:src="@drawable/portal_ring_inner_holo"/>
     <com.android.launcher3.BubbleTextView
         style="@style/WorkspaceIcon"
-        android:id="@+id/folder_icon_name" />
+        android:id="@+id/folder_icon_name"
+        android:layout_gravity="top"
+        android:layout_width="match_parent"
+        android:layout_height="match_parent" />
 </com.android.launcher3.FolderIcon>
diff --git a/res/layout/market_button.xml b/res/layout/market_button.xml
index 4a718c3..41e6ec7 100644
--- a/res/layout/market_button.xml
+++ b/res/layout/market_button.xml
@@ -18,8 +18,8 @@
     style="@style/MarketButton"
     android:onClick="onClickAppMarketButton"
     android:gravity="center"
-    android:paddingStart="16dp"
-    android:paddingEnd="16dp"
+    android:paddingLeft="16dp"
+    android:paddingRight="16dp"
     android:background="@drawable/tab_widget_indicator_selector"
     android:contentDescription="@string/market"
     android:shadowColor="@color/workspace_all_apps_and_delete_zone_text_shadow_color"
diff --git a/res/layout/overview_panel.xml b/res/layout/overview_panel.xml
index e36004c..558900c 100644
--- a/res/layout/overview_panel.xml
+++ b/res/layout/overview_panel.xml
@@ -13,18 +13,18 @@
      See the License for the specific language governing permissions and
      limitations under the License.
 -->
-<LinearLayout
+<FrameLayout
     xmlns:android="http://schemas.android.com/apk/res/android"
     android:layout_width="wrap_content"
     android:layout_height="wrap_content"
-    android:orientation="horizontal"
     android:layout_gravity="center_horizontal|bottom"
-    android:paddingBottom="@dimen/overview_panel_bottom_padding">
+    android:orientation="horizontal">
 
     <TextView
         android:id="@+id/wallpaper_button"
         android:layout_width="wrap_content"
         android:layout_height="wrap_content"
+        android:layout_gravity="start|top"
         android:text="@string/wallpaper_button_text"
         android:drawablePadding="4dp"
         android:drawableTop="@drawable/wallpaper_button"
@@ -32,13 +32,11 @@
         android:fontFamily="sans-serif-condensed"
         android:textAllCaps="true"
         android:textSize="12sp" />
-    <Space
-        android:layout_width="@dimen/overview_panel_buttonSpacing"
-        android:layout_height="wrap_content"/>
     <TextView
         android:id="@+id/widget_button"
         android:layout_width="wrap_content"
         android:layout_height="wrap_content"
+        android:layout_gravity="center_horizontal|top"
         android:text="@string/widget_button_text"
         android:drawablePadding="4dp"
         android:gravity="center_horizontal"
@@ -46,13 +44,11 @@
         android:fontFamily="sans-serif-condensed"
         android:textAllCaps="true"
         android:textSize="12sp"/>
-    <Space
-        android:layout_width="@dimen/overview_panel_buttonSpacing"
-        android:layout_height="wrap_content"/>
     <TextView
         android:id="@+id/settings_button"
         android:layout_width="wrap_content"
         android:layout_height="wrap_content"
+        android:layout_gravity="end|top"
         android:text="@string/settings_button_text"
         android:drawablePadding="4dp"
         android:gravity="center_horizontal"
@@ -60,4 +56,4 @@
         android:fontFamily="sans-serif-condensed"
         android:textAllCaps="true"
         android:textSize="12sp" />
-</LinearLayout>
+</FrameLayout>
diff --git a/res/layout/qsb_bar.xml b/res/layout/search_drop_target_bar.xml
similarity index 94%
rename from res/layout/qsb_bar.xml
rename to res/layout/search_drop_target_bar.xml
index 030acf6..2d51b93 100644
--- a/res/layout/qsb_bar.xml
+++ b/res/layout/search_drop_target_bar.xml
@@ -15,14 +15,13 @@
 -->
 <com.android.launcher3.SearchDropTargetBar
     xmlns:android="http://schemas.android.com/apk/res/android"
-    style="@style/QSBBar"
+    android:orientation="horizontal"
     android:focusable="false"
     android:layout_width="match_parent"
     android:layout_height="match_parent">
 
     <!-- Drag specific targets container -->
     <LinearLayout
-        style="@style/SearchDropTargetBar"
         android:id="@+id/drag_target_bar"
         android:layout_width="match_parent"
         android:layout_height="match_parent"
diff --git a/res/mipmap-xxhdpi/on_boarding_welcome.png b/res/mipmap-xxhdpi/on_boarding_welcome.png
new file mode 100644
index 0000000..7b11dea
--- /dev/null
+++ b/res/mipmap-xxhdpi/on_boarding_welcome.png
Binary files differ
diff --git a/res/values-af/strings.xml b/res/values-af/strings.xml
index e167189..53b5b5a 100644
--- a/res/values-af/strings.xml
+++ b/res/values-af/strings.xml
@@ -23,18 +23,6 @@
     <string name="home" msgid="7658288663002113681">"Tuis"</string>
     <string name="uid_name" msgid="7820867637514617527">"Android-kernprogramme"</string>
     <string name="folder_name" msgid="7371454440695724752"></string>
-    <string name="wallpaper_instructions" msgid="563973358787555519">"Stel muurpapier"</string>
-  <plurals name="number_of_items_selected">
-    <item quantity="zero" msgid="7464587177007785408">"%1$d gekies"</item>
-    <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>
-    <string name="crop_wallpaper" msgid="8334345984491368009">"Snoei muurpapier"</string>
     <string name="activity_not_found" msgid="8071924732094499514">"Program is nie geïnstalleer nie."</string>
     <string name="widgets_tab_label" msgid="2921133187116603919">"Legstukke"</string>
     <string name="widget_adder" msgid="3201040140710381657">"Legstukke"</string>
@@ -54,8 +42,8 @@
     <string name="group_widgets" msgid="1569030723286851002">"Legstukke"</string>
     <string name="completely_out_of_space" msgid="6106288382070760318">"Niks meer spasie op jou Tuisskerms nie."</string>
     <string name="out_of_space" msgid="4691004494942118364">"Niks meer spasie op die tuisskerm nie."</string>
-    <string name="hotseat_out_of_space" msgid="9139760413395605841">"Niks meer plek op die warmlaai nie."</string>
-    <string name="invalid_hotseat_item" msgid="1211534262129849507">"Hierdie legstuk is te groot vir die warmlaai."</string>
+    <string name="hotseat_out_of_space" msgid="7448809638125333693">"Geen plek meer in die Gunstelinge-laai nie"</string>
+    <string name="invalid_hotseat_item" msgid="5779907847267573691">"Hierdie legstuk is te groot vir die Gunstelinge-laai"</string>
     <string name="shortcut_installed" msgid="1701742129426969556">"Kortpad \"<xliff:g id="NAME">%s</xliff:g>\" is geskep."</string>
     <string name="shortcut_uninstalled" msgid="8176767991305701821">"Kortpad \"<xliff:g id="NAME">%s</xliff:g>\" is verwyder."</string>
     <string name="shortcut_duplicate" msgid="9167217446062498127">"Kortpad \"<xliff:g id="NAME">%s</xliff:g>\" bestaan reeds."</string>
@@ -96,15 +84,17 @@
     <string name="workspace_scroll_format" msgid="8458889198184077399">"Tuisskerm %1$d van %2$d"</string>
     <string name="apps_customize_apps_scroll_format" msgid="370005296147130238">"Programme-bladsy %1$d van %2$d"</string>
     <string name="apps_customize_widgets_scroll_format" msgid="3106209519974971521">"Legstukke-bladsy %1$d van %2$d"</string>
-    <string name="first_run_cling_title" msgid="7257389003637362144">"Welkom!"</string>
+    <string name="first_run_cling_title" msgid="2459738000155917941">"Welkom"</string>
     <string name="first_run_cling_description" msgid="6447072552696253358">"Maak jouself tuis."</string>
     <string name="first_run_cling_custom_content_hint" msgid="6090628589029352439"></string>
     <string name="first_run_cling_search_bar_hint" msgid="5909062802402452582"></string>
     <string name="first_run_cling_create_screens_hint" msgid="6950729526680114157">"Skep meer skerms vir programme en vouers"</string>
+    <string name="migration_cling_title" msgid="9181776667882933767">"Kopieer jou program-ikone"</string>
+    <string name="migration_cling_description" msgid="2752413805582227644">"Voer ikone en vouers vanaf jou ou tuisskerms in?"</string>
+    <string name="migration_cling_copy_apps" msgid="946331230090919440">"KOPIEER IKONE"</string>
+    <string name="migration_cling_use_default" msgid="2626475813981258626">"BEGIN VAN NUUTS AF"</string>
     <string name="workspace_cling_title" msgid="5626202359865825661">"Organiseer jou spasie"</string>
     <string name="workspace_cling_move_item" msgid="528201129978005352">"Raak en hou agtergrond om muurpapier, legstukke en instellings te bestuur."</string>
-    <string name="all_apps_cling_title" msgid="34929250753095858">"Kies \'n paar programme"</string>
-    <string name="all_apps_cling_add_item" msgid="400866858451850784">"Om \'n program by jou Tuisskerm te voeg, raak en hou dit."</string>
     <string name="folder_cling_title" msgid="3894908818693254164">"Hier\'s \'n vouer"</string>
     <string name="folder_cling_create_folder" msgid="6158215559475836131">"Om een soos dié te skep, raak en hou \'n program en skuif dit dan oor \'n ander een."</string>
     <string name="cling_dismiss" msgid="8962359497601507581">"OK"</string>
diff --git a/res/values-am/strings.xml b/res/values-am/strings.xml
index 6e8aaa4..b0c862d 100644
--- a/res/values-am/strings.xml
+++ b/res/values-am/strings.xml
@@ -23,18 +23,6 @@
     <string name="home" msgid="7658288663002113681">"መነሻ"</string>
     <string name="uid_name" msgid="7820867637514617527">"Android ዋና መተግበሪያዎች"</string>
     <string name="folder_name" msgid="7371454440695724752"></string>
-    <string name="wallpaper_instructions" msgid="563973358787555519">"የግድግዳ ወረቀት አዘጋጅ"</string>
-  <plurals name="number_of_items_selected">
-    <item quantity="zero" msgid="7464587177007785408">"%1$d ተመርጧል"</item>
-    <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>
-    <string name="crop_wallpaper" msgid="8334345984491368009">"የግድግዳ ወረቀት ከርክም"</string>
     <string name="activity_not_found" msgid="8071924732094499514">"መተግበሪያ አልተጫነም።"</string>
     <string name="widgets_tab_label" msgid="2921133187116603919">"ፍርግሞች"</string>
     <string name="widget_adder" msgid="3201040140710381657">"ፍርግሞች"</string>
@@ -54,8 +42,8 @@
     <string name="group_widgets" msgid="1569030723286851002">"ፍርግሞች"</string>
     <string name="completely_out_of_space" msgid="6106288382070760318">"የመነሻ ማያ ገጾችዎ ላይ ተጨማሪ ቦታ የለም።"</string>
     <string name="out_of_space" msgid="4691004494942118364">"በዚህ መነሻ ማያ ገጽ ላይ ምንም ቦታ የለም።"</string>
-    <string name="hotseat_out_of_space" msgid="9139760413395605841">"በመትከያ ቦታው ላይ ተጨማሪ ቦታ የለም።"</string>
-    <string name="invalid_hotseat_item" msgid="1211534262129849507">"ይህ ፍርግም ለመትከያ ቦታው በጣም ትልቅ ነው።"</string>
+    <string name="hotseat_out_of_space" msgid="7448809638125333693">"በተወዳጆች መሣቢያ ውስጥ ተጨማሪ ቦታ የለም"</string>
+    <string name="invalid_hotseat_item" msgid="5779907847267573691">"ይህ መግብር ወደ የተወዳጆች መሣቢያ ላይ እንዳይገባ በጣም ትልቅ ነው"</string>
     <string name="shortcut_installed" msgid="1701742129426969556">"አቋራጭ «<xliff:g id="NAME">%s</xliff:g>» ተፈጥሯል።"</string>
     <string name="shortcut_uninstalled" msgid="8176767991305701821">"አቋራጭ «<xliff:g id="NAME">%s</xliff:g>» ተወግዶ ነበር።"</string>
     <string name="shortcut_duplicate" msgid="9167217446062498127">"አቋራጭ «<xliff:g id="NAME">%s</xliff:g>» አስቀድሞ አለ።"</string>
@@ -96,15 +84,17 @@
     <string name="workspace_scroll_format" msgid="8458889198184077399">"መነሻ ማያ ገጽ %1$d ከ%2$d"</string>
     <string name="apps_customize_apps_scroll_format" msgid="370005296147130238">"የመተግበሪያዎች ገጽ %1$d ከ%2$d"</string>
     <string name="apps_customize_widgets_scroll_format" msgid="3106209519974971521">"የመግብሮች ገጽ %1$d ከ%2$d"</string>
-    <string name="first_run_cling_title" msgid="7257389003637362144">"እንኳን ደህና መጡ!"</string>
+    <string name="first_run_cling_title" msgid="2459738000155917941">"እንኳን በደህና መጡ"</string>
     <string name="first_run_cling_description" msgid="6447072552696253358">"ልክ እቤትዎ እንዳሉ ሆነው ዘና ይበሉ።"</string>
     <string name="first_run_cling_custom_content_hint" msgid="6090628589029352439"></string>
     <string name="first_run_cling_search_bar_hint" msgid="5909062802402452582"></string>
     <string name="first_run_cling_create_screens_hint" msgid="6950729526680114157">"ለመተግበሪያዎች እና አቃፊዎች ተጨማሪ ማያ ገጾችን ይፍጠሩ"</string>
+    <string name="migration_cling_title" msgid="9181776667882933767">"የመተግበሪያ አዶዎችዎን ይቅዱ"</string>
+    <string name="migration_cling_description" msgid="2752413805582227644">"አዶዎች እና አቃፊዎች ከድሮው የመነሻ ማያ ገጾችዎ ይምጡ?"</string>
+    <string name="migration_cling_copy_apps" msgid="946331230090919440">"አዶዎችን ይቅዱ"</string>
+    <string name="migration_cling_use_default" msgid="2626475813981258626">"እንደ አዲስ ይጀምሩ"</string>
     <string name="workspace_cling_title" msgid="5626202359865825661">"ቦታዎን ያደራጁ"</string>
     <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_create_folder" msgid="6158215559475836131">"አንድ እንደዚህ አይነት ለመፍጠር መተግበሪያውን ነክተው ይያዙት እና ወደ ሌላ ያንቀሳቅሱት።"</string>
     <string name="cling_dismiss" msgid="8962359497601507581">"እሺ"</string>
diff --git a/res/values-ar/strings.xml b/res/values-ar/strings.xml
index 4794772..98dce5f 100644
--- a/res/values-ar/strings.xml
+++ b/res/values-ar/strings.xml
@@ -23,18 +23,6 @@
     <string name="home" msgid="7658288663002113681">"الرئيسية"</string>
     <string name="uid_name" msgid="7820867637514617527">"‏تطبيقات Android الأساسية"</string>
     <string name="folder_name" msgid="7371454440695724752"></string>
-    <string name="wallpaper_instructions" msgid="563973358787555519">"تعيين خلفية"</string>
-  <plurals name="number_of_items_selected">
-    <item quantity="zero" msgid="7464587177007785408">"‏تم تحديد %1$d"</item>
-    <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>
-    <string name="crop_wallpaper" msgid="8334345984491368009">"اقتصاص الخلفية"</string>
     <string name="activity_not_found" msgid="8071924732094499514">"لم يتم تثبيت التطبيق."</string>
     <string name="widgets_tab_label" msgid="2921133187116603919">"الأدوات"</string>
     <string name="widget_adder" msgid="3201040140710381657">"الأدوات"</string>
@@ -54,8 +42,8 @@
     <string name="group_widgets" msgid="1569030723286851002">"الأدوات"</string>
     <string name="completely_out_of_space" msgid="6106288382070760318">"ليس هناك مساحة أخرى في الشاشات الرئيسية."</string>
     <string name="out_of_space" msgid="4691004494942118364">"ليس هناك مساحة أخرى في هذه الشاشة الرئيسية."</string>
-    <string name="hotseat_out_of_space" msgid="9139760413395605841">"ليست هناك مساحة أخرى في منطقة الإرساء القابلة للتخصيص."</string>
-    <string name="invalid_hotseat_item" msgid="1211534262129849507">"حجم هذه الأداة كبير للغاية بحيث لا تتسع له منطقة الإرساء القابلة للتخصيص."</string>
+    <string name="hotseat_out_of_space" msgid="7448809638125333693">"لا يوجد المزيد من الحقول في علبة المفضلة"</string>
+    <string name="invalid_hotseat_item" msgid="5779907847267573691">"هذه الأداة كبيرة جدًا مما يحول دون قبولها في علبة المفضّلة"</string>
     <string name="shortcut_installed" msgid="1701742129426969556">"تم إنشاء الاختصار \"<xliff:g id="NAME">%s</xliff:g>\"."</string>
     <string name="shortcut_uninstalled" msgid="8176767991305701821">"تمت إزالة الاختصار \"<xliff:g id="NAME">%s</xliff:g>\"."</string>
     <string name="shortcut_duplicate" msgid="9167217446062498127">"الاختصار \"<xliff:g id="NAME">%s</xliff:g>\" موجود من قبل."</string>
@@ -96,15 +84,17 @@
     <string name="workspace_scroll_format" msgid="8458889198184077399">"‏الشاشة الرئيسية %1$d من %2$d"</string>
     <string name="apps_customize_apps_scroll_format" msgid="370005296147130238">"‏صفحة التطبيقات %1$d من %2$d"</string>
     <string name="apps_customize_widgets_scroll_format" msgid="3106209519974971521">"‏صفحة الأدوات %1$d من %2$d"</string>
-    <string name="first_run_cling_title" msgid="7257389003637362144">"مرحبًا!"</string>
+    <string name="first_run_cling_title" msgid="2459738000155917941">"مرحبًا"</string>
     <string name="first_run_cling_description" msgid="6447072552696253358">"تصرف على راحتك."</string>
     <string name="first_run_cling_custom_content_hint" msgid="6090628589029352439"></string>
     <string name="first_run_cling_search_bar_hint" msgid="5909062802402452582"></string>
     <string name="first_run_cling_create_screens_hint" msgid="6950729526680114157">"إنشاء المزيد من الشاشات للتطبيقات والمجلدات"</string>
+    <string name="migration_cling_title" msgid="9181776667882933767">"نسخ رموز التطبيقات"</string>
+    <string name="migration_cling_description" msgid="2752413805582227644">"هل تريد استيراد رموز ومجلدات من الشاشات الرئيسية القديمة؟"</string>
+    <string name="migration_cling_copy_apps" msgid="946331230090919440">"نسخ الرموز"</string>
+    <string name="migration_cling_use_default" msgid="2626475813981258626">"بداية جديدة"</string>
     <string name="workspace_cling_title" msgid="5626202359865825661">"تنظيم مساحتك"</string>
     <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_create_folder" msgid="6158215559475836131">"لإنشاء مجلد مثل هذا، المس أحد التطبيقات مع استمرار اللمس، ثم حركه فوق آخر."</string>
     <string name="cling_dismiss" msgid="8962359497601507581">"موافق"</string>
diff --git a/res/values-be/strings.xml b/res/values-be/strings.xml
index ddcf404..2465534 100644
--- a/res/values-be/strings.xml
+++ b/res/values-be/strings.xml
@@ -26,23 +26,6 @@
     <!-- no translation found for uid_name (7820867637514617527) -->
     <skip />
     <string name="folder_name" msgid="7371454440695724752"></string>
-    <!-- no translation found for wallpaper_instructions (563973358787555519) -->
-    <skip />
-    <!-- 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) -->
-    <skip />
-    <!-- no translation found for pick_wallpaper (8179698221502010609) -->
-    <skip />
-    <!-- no translation found for crop_wallpaper (8334345984491368009) -->
-    <skip />
     <!-- no translation found for activity_not_found (8071924732094499514) -->
     <skip />
     <!-- no translation found for widgets_tab_label (2921133187116603919) -->
@@ -177,10 +160,6 @@
     <skip />
     <!-- no translation found for workspace_cling_move_item (528201129978005352) -->
     <skip />
-    <!-- no translation found for all_apps_cling_title (34929250753095858) -->
-    <skip />
-    <!-- no translation found for all_apps_cling_add_item (400866858451850784) -->
-    <skip />
     <!-- no translation found for folder_cling_title (3894908818693254164) -->
     <skip />
     <!-- no translation found for folder_cling_create_folder (6158215559475836131) -->
diff --git a/res/values-bg/strings.xml b/res/values-bg/strings.xml
index 2f53fa3..9082929 100644
--- a/res/values-bg/strings.xml
+++ b/res/values-bg/strings.xml
@@ -23,18 +23,6 @@
     <string name="home" msgid="7658288663002113681">"Начало"</string>
     <string name="uid_name" msgid="7820867637514617527">"Основни приложения на Android"</string>
     <string name="folder_name" msgid="7371454440695724752"></string>
-    <string name="wallpaper_instructions" msgid="563973358787555519">"Задаване на тапета"</string>
-  <plurals name="number_of_items_selected">
-    <item quantity="zero" msgid="7464587177007785408">"Избрахте %1$d"</item>
-    <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>
-    <string name="crop_wallpaper" msgid="8334345984491368009">"Подрязване на тапета"</string>
     <string name="activity_not_found" msgid="8071924732094499514">"Приложението не е инсталирано."</string>
     <string name="widgets_tab_label" msgid="2921133187116603919">"Приспособления"</string>
     <string name="widget_adder" msgid="3201040140710381657">"Приспособления"</string>
@@ -54,8 +42,8 @@
     <string name="group_widgets" msgid="1569030723286851002">"Приспособления"</string>
     <string name="completely_out_of_space" msgid="6106288382070760318">"На началните ви екрани няма повече място."</string>
     <string name="out_of_space" msgid="4691004494942118364">"На този начален екран няма повече място."</string>
-    <string name="hotseat_out_of_space" msgid="9139760413395605841">"В трамплина няма повече място."</string>
-    <string name="invalid_hotseat_item" msgid="1211534262129849507">"Това приспособление е твърде голямо за трамплина."</string>
+    <string name="hotseat_out_of_space" msgid="7448809638125333693">"Няма повече място в областта с любимите"</string>
+    <string name="invalid_hotseat_item" msgid="5779907847267573691">"Това приспособление е твърде голямо за областта с любимите"</string>
     <string name="shortcut_installed" msgid="1701742129426969556">"Прекият път към <xliff:g id="NAME">%s</xliff:g> е създаден."</string>
     <string name="shortcut_uninstalled" msgid="8176767991305701821">"Прекият път към <xliff:g id="NAME">%s</xliff:g> бе премахнат."</string>
     <string name="shortcut_duplicate" msgid="9167217446062498127">"Прекият път към <xliff:g id="NAME">%s</xliff:g> вече съществува."</string>
@@ -96,15 +84,17 @@
     <string name="workspace_scroll_format" msgid="8458889198184077399">"Начален екран %1$d от %2$d"</string>
     <string name="apps_customize_apps_scroll_format" msgid="370005296147130238">"Страница с приложения %1$d от %2$d"</string>
     <string name="apps_customize_widgets_scroll_format" msgid="3106209519974971521">"Страница с приспособления %1$d от %2$d"</string>
-    <string name="first_run_cling_title" msgid="7257389003637362144">"Добре дошли!"</string>
+    <string name="first_run_cling_title" msgid="2459738000155917941">"Добре дошли"</string>
     <string name="first_run_cling_description" msgid="6447072552696253358">"Персонализиране и приспособяване."</string>
     <string name="first_run_cling_custom_content_hint" msgid="6090628589029352439"></string>
     <string name="first_run_cling_search_bar_hint" msgid="5909062802402452582"></string>
     <string name="first_run_cling_create_screens_hint" msgid="6950729526680114157">"Създаване на още екрани за приложения и папки"</string>
+    <string name="migration_cling_title" msgid="9181776667882933767">"Икони на прилож. ви: Копиране"</string>
+    <string name="migration_cling_description" msgid="2752413805582227644">"Да се импортират ли иконите и папките от старите ви начални екрани?"</string>
+    <string name="migration_cling_copy_apps" msgid="946331230090919440">"КОПИРАНЕ НА ИКОНИТЕ"</string>
+    <string name="migration_cling_use_default" msgid="2626475813981258626">"СТАРТИРАНЕ ОТНАЧАЛО"</string>
     <string name="workspace_cling_title" msgid="5626202359865825661">"Организиране на мястото ви"</string>
     <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_create_folder" msgid="6158215559475836131">"За да създадете подобна, докоснете и задръжте приложение, след което го преместете върху друго."</string>
     <string name="cling_dismiss" msgid="8962359497601507581">"ОK"</string>
diff --git a/res/values-ca/strings.xml b/res/values-ca/strings.xml
index 3400482..865d0e0 100644
--- a/res/values-ca/strings.xml
+++ b/res/values-ca/strings.xml
@@ -23,18 +23,6 @@
     <string name="home" msgid="7658288663002113681">"Inici"</string>
     <string name="uid_name" msgid="7820867637514617527">"Aplicacions principals d\'Android"</string>
     <string name="folder_name" msgid="7371454440695724752"></string>
-    <string name="wallpaper_instructions" msgid="563973358787555519">"Estableix el fons de pantalla"</string>
-  <plurals name="number_of_items_selected">
-    <item quantity="zero" msgid="7464587177007785408">"Seleccionats: %1$d"</item>
-    <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>
-    <string name="crop_wallpaper" msgid="8334345984491368009">"Retalla el fons de pantalla"</string>
     <string name="activity_not_found" msgid="8071924732094499514">"L\'aplicació no s\'ha instal·lat."</string>
     <string name="widgets_tab_label" msgid="2921133187116603919">"Widgets"</string>
     <string name="widget_adder" msgid="3201040140710381657">"Widgets"</string>
@@ -54,8 +42,8 @@
     <string name="group_widgets" msgid="1569030723286851002">"Widgets"</string>
     <string name="completely_out_of_space" msgid="6106288382070760318">"No queda espai a les pantalles d\'inici."</string>
     <string name="out_of_space" msgid="4691004494942118364">"Ja no queda espai en aquesta pantalla d\'inici."</string>
-    <string name="hotseat_out_of_space" msgid="9139760413395605841">"No queda espai al hotseat."</string>
-    <string name="invalid_hotseat_item" msgid="1211534262129849507">"Aquest widget és massa gran per al hotseat."</string>
+    <string name="hotseat_out_of_space" msgid="7448809638125333693">"No hi ha més espai a la safata Preferits."</string>
+    <string name="invalid_hotseat_item" msgid="5779907847267573691">"Aquest widget és massa gran per a la safata Preferits."</string>
     <string name="shortcut_installed" msgid="1701742129426969556">"S\'ha creat la drecera \"<xliff:g id="NAME">%s</xliff:g>\"."</string>
     <string name="shortcut_uninstalled" msgid="8176767991305701821">"S\'ha suprimit la drecera \"<xliff:g id="NAME">%s</xliff:g>\"."</string>
     <string name="shortcut_duplicate" msgid="9167217446062498127">"La drecera \"<xliff:g id="NAME">%s</xliff:g>\" ja existeix."</string>
@@ -96,15 +84,17 @@
     <string name="workspace_scroll_format" msgid="8458889198184077399">"Pantalla d\'inici %1$d de %2$d"</string>
     <string name="apps_customize_apps_scroll_format" msgid="370005296147130238">"Pàgina d\'aplicacions %1$d de %2$d"</string>
     <string name="apps_customize_widgets_scroll_format" msgid="3106209519974971521">"Pàgina de widgets %1$d de %2$d"</string>
-    <string name="first_run_cling_title" msgid="7257389003637362144">"Hola!"</string>
+    <string name="first_run_cling_title" msgid="2459738000155917941">"Us donem la benvinguda"</string>
     <string name="first_run_cling_description" msgid="6447072552696253358">"Personalitza la pantalla d\'inici"</string>
     <string name="first_run_cling_custom_content_hint" msgid="6090628589029352439"></string>
     <string name="first_run_cling_search_bar_hint" msgid="5909062802402452582"></string>
     <string name="first_run_cling_create_screens_hint" msgid="6950729526680114157">"Crea més pantalles per a aplicacions i carpetes"</string>
+    <string name="migration_cling_title" msgid="9181776667882933767">"Copiar les icones d\'aplicació"</string>
+    <string name="migration_cling_description" msgid="2752413805582227644">"Importar icones i carpetes de pantalles d\'inici anteriors?"</string>
+    <string name="migration_cling_copy_apps" msgid="946331230090919440">"COPIA LES ICONES."</string>
+    <string name="migration_cling_use_default" msgid="2626475813981258626">"NOU COMENÇAMENT"</string>
     <string name="workspace_cling_title" msgid="5626202359865825661">"Organitza el teu espai"</string>
     <string name="workspace_cling_move_item" msgid="528201129978005352">"Toca i mantén premut el fons per gestionar el fons de pantalla, els widgets i la configuració."</string>
-    <string name="all_apps_cling_title" msgid="34929250753095858">"Tria unes quantes aplicacions"</string>
-    <string name="all_apps_cling_add_item" msgid="400866858451850784">"Per afegir una aplicació a la pantalla d\'inici, mantén-la premuda."</string>
     <string name="folder_cling_title" msgid="3894908818693254164">"Aquí hi ha una carpeta"</string>
     <string name="folder_cling_create_folder" msgid="6158215559475836131">"Per crear-ne una com aquesta, mantén premuda una aplicació i, a continuació, mou-la sobre una altra."</string>
     <string name="cling_dismiss" msgid="8962359497601507581">"D\'acord"</string>
diff --git a/res/values-cs/strings.xml b/res/values-cs/strings.xml
index 1061e79..0255709 100644
--- a/res/values-cs/strings.xml
+++ b/res/values-cs/strings.xml
@@ -23,18 +23,6 @@
     <string name="home" msgid="7658288663002113681">"Plocha"</string>
     <string name="uid_name" msgid="7820867637514617527">"Android Core Apps"</string>
     <string name="folder_name" msgid="7371454440695724752"></string>
-    <string name="wallpaper_instructions" msgid="563973358787555519">"Nastavit jako tapetu"</string>
-  <plurals name="number_of_items_selected">
-    <item quantity="zero" msgid="7464587177007785408">"Vybráno: %1$d"</item>
-    <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>
-    <string name="crop_wallpaper" msgid="8334345984491368009">"Oříznutí tapety"</string>
     <string name="activity_not_found" msgid="8071924732094499514">"Aplikace není nainstalována."</string>
     <string name="widgets_tab_label" msgid="2921133187116603919">"Widgety"</string>
     <string name="widget_adder" msgid="3201040140710381657">"Widgety"</string>
@@ -54,8 +42,8 @@
     <string name="group_widgets" msgid="1569030723286851002">"Widgety"</string>
     <string name="completely_out_of_space" msgid="6106288382070760318">"Na plochách již není místo."</string>
     <string name="out_of_space" msgid="4691004494942118364">"Na této ploše již není místo."</string>
-    <string name="hotseat_out_of_space" msgid="9139760413395605841">"V sekci hotseat již není místo."</string>
-    <string name="invalid_hotseat_item" msgid="1211534262129849507">"Widget je pro hotseat příliš velký."</string>
+    <string name="hotseat_out_of_space" msgid="7448809638125333693">"Na panelu Oblíbené položky již není místo."</string>
+    <string name="invalid_hotseat_item" msgid="5779907847267573691">"Tento widget je pro panel Oblíbené položky příliš velký."</string>
     <string name="shortcut_installed" msgid="1701742129426969556">"Zástupce aplikace <xliff:g id="NAME">%s</xliff:g> byl vytvořen."</string>
     <string name="shortcut_uninstalled" msgid="8176767991305701821">"Zástupce aplikace <xliff:g id="NAME">%s</xliff:g> byl odebrán."</string>
     <string name="shortcut_duplicate" msgid="9167217446062498127">"Zástupce aplikace <xliff:g id="NAME">%s</xliff:g> již existuje."</string>
@@ -96,15 +84,17 @@
     <string name="workspace_scroll_format" msgid="8458889198184077399">"Plocha %1$d z %2$d"</string>
     <string name="apps_customize_apps_scroll_format" msgid="370005296147130238">"Stránka aplikací %1$d z %2$d"</string>
     <string name="apps_customize_widgets_scroll_format" msgid="3106209519974971521">"Stránka widgetů %1$d z %2$d"</string>
-    <string name="first_run_cling_title" msgid="7257389003637362144">"Vítejte!"</string>
+    <string name="first_run_cling_title" msgid="2459738000155917941">"Vítejte"</string>
     <string name="first_run_cling_description" msgid="6447072552696253358">"Udělejte si pohodlí."</string>
     <string name="first_run_cling_custom_content_hint" msgid="6090628589029352439"></string>
     <string name="first_run_cling_search_bar_hint" msgid="5909062802402452582"></string>
     <string name="first_run_cling_create_screens_hint" msgid="6950729526680114157">"Vytvořte několik obrazovek pro aplikace a složky"</string>
+    <string name="migration_cling_title" msgid="9181776667882933767">"Zkopírování ikon aplikací"</string>
+    <string name="migration_cling_description" msgid="2752413805582227644">"Chcete importovat ikony a složky ze svých starých ploch?"</string>
+    <string name="migration_cling_copy_apps" msgid="946331230090919440">"ZKOPÍROVAT IKONY"</string>
+    <string name="migration_cling_use_default" msgid="2626475813981258626">"ZAČÍT S VÝCHOZÍM ROZVRŽENÍM"</string>
     <string name="workspace_cling_title" msgid="5626202359865825661">"Organizace prostoru"</string>
     <string name="workspace_cling_move_item" msgid="528201129978005352">"Chcete-li spravovat tapetu, widgety a nastavení, dotkněte se pozadí a přidržte je."</string>
-    <string name="all_apps_cling_title" msgid="34929250753095858">"Vyberte nějaké aplikace"</string>
-    <string name="all_apps_cling_add_item" msgid="400866858451850784">"Chcete-li na plochu přidat aplikaci, dotkněte se jí a přidržte ji."</string>
     <string name="folder_cling_title" msgid="3894908818693254164">"Toto je složka"</string>
     <string name="folder_cling_create_folder" msgid="6158215559475836131">"Chcete-li vytvořit složku, přetáhněte aplikaci na jinou aplikaci."</string>
     <string name="cling_dismiss" msgid="8962359497601507581">"OK"</string>
diff --git a/res/values-da/strings.xml b/res/values-da/strings.xml
index 5db246e..68ceb5b 100644
--- a/res/values-da/strings.xml
+++ b/res/values-da/strings.xml
@@ -23,18 +23,6 @@
     <string name="home" msgid="7658288663002113681">"Startskærm"</string>
     <string name="uid_name" msgid="7820867637514617527">"Kerneapps i Android"</string>
     <string name="folder_name" msgid="7371454440695724752"></string>
-    <string name="wallpaper_instructions" msgid="563973358787555519">"Angiv baggrund"</string>
-  <plurals name="number_of_items_selected">
-    <item quantity="zero" msgid="7464587177007785408">"%1$d er valgt"</item>
-    <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>
-    <string name="crop_wallpaper" msgid="8334345984491368009">"Beskær baggrund"</string>
     <string name="activity_not_found" msgid="8071924732094499514">"Appen er ikke installeret."</string>
     <string name="widgets_tab_label" msgid="2921133187116603919">"Widgets"</string>
     <string name="widget_adder" msgid="3201040140710381657">"Widgets"</string>
@@ -54,8 +42,8 @@
     <string name="group_widgets" msgid="1569030723286851002">"Widgets"</string>
     <string name="completely_out_of_space" msgid="6106288382070760318">"Der er ikke mere plads på dine startskærme."</string>
     <string name="out_of_space" msgid="4691004494942118364">"Der er ikke mere plads på denne startskærm."</string>
-    <string name="hotseat_out_of_space" msgid="9139760413395605841">"Der er ikke mere plads i hotseat."</string>
-    <string name="invalid_hotseat_item" msgid="1211534262129849507">"Denne widget er for stor til hotseat."</string>
+    <string name="hotseat_out_of_space" msgid="7448809638125333693">"Der er ikke mere plads i bakken Foretrukne"</string>
+    <string name="invalid_hotseat_item" msgid="5779907847267573691">"Denne widget er for stor til bakken Foretrukne"</string>
     <string name="shortcut_installed" msgid="1701742129426969556">"Genvejen \"<xliff:g id="NAME">%s</xliff:g>\" blev oprettet."</string>
     <string name="shortcut_uninstalled" msgid="8176767991305701821">"Genvejen \"<xliff:g id="NAME">%s</xliff:g>\" blev fjernet."</string>
     <string name="shortcut_duplicate" msgid="9167217446062498127">"Genvejen \"<xliff:g id="NAME">%s</xliff:g>\" findes allerede."</string>
@@ -96,15 +84,17 @@
     <string name="workspace_scroll_format" msgid="8458889198184077399">"Startskærm %1$d ud af %2$d"</string>
     <string name="apps_customize_apps_scroll_format" msgid="370005296147130238">"Apps-side %1$d ud af %2$d"</string>
     <string name="apps_customize_widgets_scroll_format" msgid="3106209519974971521">"Widgets-side %1$d ud af %2$d"</string>
-    <string name="first_run_cling_title" msgid="7257389003637362144">"Velkommen"</string>
+    <string name="first_run_cling_title" msgid="2459738000155917941">"Velkommen"</string>
     <string name="first_run_cling_description" msgid="6447072552696253358">"Føl dig hjemme."</string>
     <string name="first_run_cling_custom_content_hint" msgid="6090628589029352439"></string>
     <string name="first_run_cling_search_bar_hint" msgid="5909062802402452582"></string>
     <string name="first_run_cling_create_screens_hint" msgid="6950729526680114157">"Opret flere skærme til apps og mapper"</string>
+    <string name="migration_cling_title" msgid="9181776667882933767">"Kopiér dine appikoner"</string>
+    <string name="migration_cling_description" msgid="2752413805582227644">"Vil du importere ikoner og mapper fra gamle startskærme?"</string>
+    <string name="migration_cling_copy_apps" msgid="946331230090919440">"KOPIÉR IKONER"</string>
+    <string name="migration_cling_use_default" msgid="2626475813981258626">"START PÅ EN FRISK"</string>
     <string name="workspace_cling_title" msgid="5626202359865825661">"Organiser din arbejdsplads"</string>
     <string name="workspace_cling_move_item" msgid="528201129978005352">"Tryk på en baggrund, og hold fingeren nede for at administrere baggrunde, widgets og indstillinger."</string>
-    <string name="all_apps_cling_title" msgid="34929250753095858">"Vælge nogle apps"</string>
-    <string name="all_apps_cling_add_item" msgid="400866858451850784">"Tryk på en app, og hold fingeren nede for at føje appen til startskærmen."</string>
     <string name="folder_cling_title" msgid="3894908818693254164">"Her kan du se en mappe"</string>
     <string name="folder_cling_create_folder" msgid="6158215559475836131">"Du kan oprette en mappe magen til denne ved at trykke på en app og holde fingeren nede, mens du flytter appen til en anden mappe."</string>
     <string name="cling_dismiss" msgid="8962359497601507581">"OK"</string>
diff --git a/res/values-de/strings.xml b/res/values-de/strings.xml
index ee732aa..4bd04b2 100644
--- a/res/values-de/strings.xml
+++ b/res/values-de/strings.xml
@@ -23,18 +23,6 @@
     <string name="home" msgid="7658288663002113681">"Startseite"</string>
     <string name="uid_name" msgid="7820867637514617527">"Android Core Apps"</string>
     <string name="folder_name" msgid="7371454440695724752"></string>
-    <string name="wallpaper_instructions" msgid="563973358787555519">"Hintergrund auswählen"</string>
-  <plurals name="number_of_items_selected">
-    <item quantity="zero" msgid="7464587177007785408">"%1$d ausgewählt"</item>
-    <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>
-    <string name="crop_wallpaper" msgid="8334345984491368009">"Hintergrund zuschneiden"</string>
     <string name="activity_not_found" msgid="8071924732094499514">"App ist nicht installiert."</string>
     <string name="widgets_tab_label" msgid="2921133187116603919">"Widgets"</string>
     <string name="widget_adder" msgid="3201040140710381657">"Widgets"</string>
@@ -54,8 +42,8 @@
     <string name="group_widgets" msgid="1569030723286851002">"Widgets"</string>
     <string name="completely_out_of_space" msgid="6106288382070760318">"Auf Ihren Startbildschirmen ist kein Platz mehr vorhanden."</string>
     <string name="out_of_space" msgid="4691004494942118364">"Auf diesem Startbildschirm ist kein Platz mehr vorhanden."</string>
-    <string name="hotseat_out_of_space" msgid="9139760413395605841">"Kein Platz mehr auf der App-Leiste"</string>
-    <string name="invalid_hotseat_item" msgid="1211534262129849507">"Dieses Widget ist zu groß für die App-Leiste."</string>
+    <string name="hotseat_out_of_space" msgid="7448809638125333693">"Ablage \"Favoriten\" ist voll."</string>
+    <string name="invalid_hotseat_item" msgid="5779907847267573691">"Dieses Widget ist zu groß für die Ablage \"Favoriten\"."</string>
     <string name="shortcut_installed" msgid="1701742129426969556">"Verknüpfung \"<xliff:g id="NAME">%s</xliff:g>\" wurde erstellt."</string>
     <string name="shortcut_uninstalled" msgid="8176767991305701821">"Verknüpfung \"<xliff:g id="NAME">%s</xliff:g>\" wurde entfernt."</string>
     <string name="shortcut_duplicate" msgid="9167217446062498127">"Verknüpfung \"<xliff:g id="NAME">%s</xliff:g>\" ist bereits vorhanden."</string>
@@ -96,15 +84,17 @@
     <string name="workspace_scroll_format" msgid="8458889198184077399">"Startbildschirm %1$d von %2$d"</string>
     <string name="apps_customize_apps_scroll_format" msgid="370005296147130238">"Apps-Seite %1$d von %2$d"</string>
     <string name="apps_customize_widgets_scroll_format" msgid="3106209519974971521">"Widgets-Seite %1$d von %2$d"</string>
-    <string name="first_run_cling_title" msgid="7257389003637362144">"Hallo!"</string>
+    <string name="first_run_cling_title" msgid="2459738000155917941">"Willkommen"</string>
     <string name="first_run_cling_description" msgid="6447072552696253358">"Gerät personalisieren"</string>
     <string name="first_run_cling_custom_content_hint" msgid="6090628589029352439"></string>
     <string name="first_run_cling_search_bar_hint" msgid="5909062802402452582"></string>
     <string name="first_run_cling_create_screens_hint" msgid="6950729526680114157">"Mehr Bildschirme für Apps und Ordner erstellen"</string>
+    <string name="migration_cling_title" msgid="9181776667882933767">"App-Symbole kopieren"</string>
+    <string name="migration_cling_description" msgid="2752413805582227644">"Symbole und Ordner alter Startbildschirme importieren?"</string>
+    <string name="migration_cling_copy_apps" msgid="946331230090919440">"Symbole kopieren"</string>
+    <string name="migration_cling_use_default" msgid="2626475813981258626">"Standardübersicht verwenden"</string>
     <string name="workspace_cling_title" msgid="5626202359865825661">"Arbeitsbereich organisieren"</string>
     <string name="workspace_cling_move_item" msgid="528201129978005352">"Hintergrund berühren und halten, um Hintergrund, Widgets und Einstellungen zu verwalten"</string>
-    <string name="all_apps_cling_title" msgid="34929250753095858">"Apps auswählen"</string>
-    <string name="all_apps_cling_add_item" msgid="400866858451850784">"Berühren und halten Sie eine App, um sie zum Startbildschirm hinzuzufügen."</string>
     <string name="folder_cling_title" msgid="3894908818693254164">"Hier ist ein Ordner"</string>
     <string name="folder_cling_create_folder" msgid="6158215559475836131">"Um einen Ordner zu erstellen, berühren und halten Sie eine App und verschieben Sie sie auf eine andere."</string>
     <string name="cling_dismiss" msgid="8962359497601507581">"OK"</string>
diff --git a/res/values-el/strings.xml b/res/values-el/strings.xml
index 74322e0..b6a9855 100644
--- a/res/values-el/strings.xml
+++ b/res/values-el/strings.xml
@@ -23,18 +23,6 @@
     <string name="home" msgid="7658288663002113681">"Αρχική σελίδα"</string>
     <string name="uid_name" msgid="7820867637514617527">"Βασικές εφαρμογές Android"</string>
     <string name="folder_name" msgid="7371454440695724752"></string>
-    <string name="wallpaper_instructions" msgid="563973358787555519">"Ορισμός ταπετσαρίας"</string>
-  <plurals name="number_of_items_selected">
-    <item quantity="zero" msgid="7464587177007785408">"%1$d επιλεγμένα"</item>
-    <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>
-    <string name="crop_wallpaper" msgid="8334345984491368009">"Περικοπή ταπετσαρίας"</string>
     <string name="activity_not_found" msgid="8071924732094499514">"Η εφαρμογή δεν έχει εγκατασταθεί."</string>
     <string name="widgets_tab_label" msgid="2921133187116603919">"Γραφικά στοιχεία"</string>
     <string name="widget_adder" msgid="3201040140710381657">"Γραφικά στοιχεία"</string>
@@ -54,8 +42,8 @@
     <string name="group_widgets" msgid="1569030723286851002">"Γραφικά στοιχεία"</string>
     <string name="completely_out_of_space" msgid="6106288382070760318">"Δεν υπάρχει άλλος χώρος στις Αρχικές οθόνες σας."</string>
     <string name="out_of_space" msgid="4691004494942118364">"Δεν υπάρχει χώρος σε αυτήν την αρχική οθόνη."</string>
-    <string name="hotseat_out_of_space" msgid="9139760413395605841">"Δεν υπάρχει άλλος χώρος στη γραμμή γρήγορης πρόσβασης."</string>
-    <string name="invalid_hotseat_item" msgid="1211534262129849507">"Αυτό το γραφικό στοιχείο είναι πολύ μεγάλο για τη γραμμή γρήγορης πρόσβασης."</string>
+    <string name="hotseat_out_of_space" msgid="7448809638125333693">"Δεν υπάρχει επιπλέον χώρος στην περιοχή Αγαπημένα"</string>
+    <string name="invalid_hotseat_item" msgid="5779907847267573691">"Αυτό το γραφικό στοιχείο είναι πολύ μεγάλο για την περιοχή Αγαπημένα."</string>
     <string name="shortcut_installed" msgid="1701742129426969556">"Δημιουργήθηκε η συντόμευση \"<xliff:g id="NAME">%s</xliff:g>\"."</string>
     <string name="shortcut_uninstalled" msgid="8176767991305701821">"Η συντόμευση \"<xliff:g id="NAME">%s</xliff:g>\" καταργήθηκε."</string>
     <string name="shortcut_duplicate" msgid="9167217446062498127">"Η συντόμευση \"<xliff:g id="NAME">%s</xliff:g>\" υπάρχει ήδη."</string>
@@ -96,15 +84,17 @@
     <string name="workspace_scroll_format" msgid="8458889198184077399">"Αρχική οθόνη %1$d από %2$d"</string>
     <string name="apps_customize_apps_scroll_format" msgid="370005296147130238">"Σελίδα εφαρμογών %1$d από %2$d"</string>
     <string name="apps_customize_widgets_scroll_format" msgid="3106209519974971521">"Σελίδα γραφικών στοιχείων %1$d από %2$d"</string>
-    <string name="first_run_cling_title" msgid="7257389003637362144">"Καλώς ορίσατε!"</string>
+    <string name="first_run_cling_title" msgid="2459738000155917941">"Καλώς ορίσατε"</string>
     <string name="first_run_cling_description" msgid="6447072552696253358">"Νιώστε σαν στο σπίτι σας."</string>
     <string name="first_run_cling_custom_content_hint" msgid="6090628589029352439"></string>
     <string name="first_run_cling_search_bar_hint" msgid="5909062802402452582"></string>
     <string name="first_run_cling_create_screens_hint" msgid="6950729526680114157">"Δημιουργία περισσότερων οθονών για εφαρμογές και φακέλους"</string>
+    <string name="migration_cling_title" msgid="9181776667882933767">"Αντιγραφή εικονιδίων εφαρμογών"</string>
+    <string name="migration_cling_description" msgid="2752413805582227644">"Εισαγωγή εικονιδίων και φακέλων από παλιές αρχικές οθόνες;"</string>
+    <string name="migration_cling_copy_apps" msgid="946331230090919440">"ΑΝΤΙΓΡΑΦΗ ΕΙΚΟΝΙΔΙΩΝ"</string>
+    <string name="migration_cling_use_default" msgid="2626475813981258626">"ΝΕΑ ΕΝΑΡΞΗ"</string>
     <string name="workspace_cling_title" msgid="5626202359865825661">"Οργανώστε το χώρο σας"</string>
     <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_create_folder" msgid="6158215559475836131">"Για να δημιουργήσετε έναν φάκελο σαν κι αυτόν, πατήστε παρατεταμένα μια εφαρμογή και στη συνέχεια, μετακινήστε τη πάνω σε μια άλλη."</string>
     <string name="cling_dismiss" msgid="8962359497601507581">"OK"</string>
diff --git a/res/values-en-rGB/strings.xml b/res/values-en-rGB/strings.xml
index 316585e..9f732e0 100644
--- a/res/values-en-rGB/strings.xml
+++ b/res/values-en-rGB/strings.xml
@@ -23,18 +23,6 @@
     <string name="home" msgid="7658288663002113681">"Home"</string>
     <string name="uid_name" msgid="7820867637514617527">"Android Core Apps"</string>
     <string name="folder_name" msgid="7371454440695724752"></string>
-    <string name="wallpaper_instructions" msgid="563973358787555519">"Set wallpaper"</string>
-  <plurals name="number_of_items_selected">
-    <item quantity="zero" msgid="7464587177007785408">"%1$d selected"</item>
-    <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>
-    <string name="crop_wallpaper" msgid="8334345984491368009">"Crop wallpaper"</string>
     <string name="activity_not_found" msgid="8071924732094499514">"App isn\'t installed."</string>
     <string name="widgets_tab_label" msgid="2921133187116603919">"Widgets"</string>
     <string name="widget_adder" msgid="3201040140710381657">"Widgets"</string>
@@ -54,8 +42,8 @@
     <string name="group_widgets" msgid="1569030723286851002">"Widgets"</string>
     <string name="completely_out_of_space" msgid="6106288382070760318">"No more room on your Home screens."</string>
     <string name="out_of_space" msgid="4691004494942118364">"No more room on this Home screen."</string>
-    <string name="hotseat_out_of_space" msgid="9139760413395605841">"No more room on the hot seat."</string>
-    <string name="invalid_hotseat_item" msgid="1211534262129849507">"This widget is too large for the hot seat."</string>
+    <string name="hotseat_out_of_space" msgid="7448809638125333693">"No more room in the Favourites tray"</string>
+    <string name="invalid_hotseat_item" msgid="5779907847267573691">"This widget is too large for the Favourites tray"</string>
     <string name="shortcut_installed" msgid="1701742129426969556">"Shortcut \"<xliff:g id="NAME">%s</xliff:g>\" created."</string>
     <string name="shortcut_uninstalled" msgid="8176767991305701821">"Shortcut \"<xliff:g id="NAME">%s</xliff:g>\" was removed."</string>
     <string name="shortcut_duplicate" msgid="9167217446062498127">"Shortcut \"<xliff:g id="NAME">%s</xliff:g>\" already exists."</string>
@@ -96,15 +84,17 @@
     <string name="workspace_scroll_format" msgid="8458889198184077399">"Home screen %1$d of %2$d"</string>
     <string name="apps_customize_apps_scroll_format" msgid="370005296147130238">"Apps page %1$d of %2$d"</string>
     <string name="apps_customize_widgets_scroll_format" msgid="3106209519974971521">"Widgets page %1$d of %2$d"</string>
-    <string name="first_run_cling_title" msgid="7257389003637362144">"Welcome!"</string>
+    <string name="first_run_cling_title" msgid="2459738000155917941">"Welcome"</string>
     <string name="first_run_cling_description" msgid="6447072552696253358">"Make yourself at home."</string>
     <string name="first_run_cling_custom_content_hint" msgid="6090628589029352439"></string>
     <string name="first_run_cling_search_bar_hint" msgid="5909062802402452582"></string>
     <string name="first_run_cling_create_screens_hint" msgid="6950729526680114157">"Create more screens for apps and folders"</string>
+    <string name="migration_cling_title" msgid="9181776667882933767">"Copy your app icons"</string>
+    <string name="migration_cling_description" msgid="2752413805582227644">"Import icons and folders from your old Home screens?"</string>
+    <string name="migration_cling_copy_apps" msgid="946331230090919440">"COPY ICONS"</string>
+    <string name="migration_cling_use_default" msgid="2626475813981258626">"START AFRESH"</string>
     <string name="workspace_cling_title" msgid="5626202359865825661">"Organise your space"</string>
     <string name="workspace_cling_move_item" msgid="528201129978005352">"Touch &amp; hold background to manage wallpaper, widgets and settings."</string>
-    <string name="all_apps_cling_title" msgid="34929250753095858">"Choose some apps"</string>
-    <string name="all_apps_cling_add_item" msgid="400866858451850784">"To add an app to your Home screen, touch &amp; hold it."</string>
     <string name="folder_cling_title" msgid="3894908818693254164">"Here\'s a folder"</string>
     <string name="folder_cling_create_folder" msgid="6158215559475836131">"To create one like this, touch &amp; hold an app, then move it over another."</string>
     <string name="cling_dismiss" msgid="8962359497601507581">"OK"</string>
diff --git a/res/values-en-rIN/strings.xml b/res/values-en-rIN/strings.xml
index 316585e..9f732e0 100644
--- a/res/values-en-rIN/strings.xml
+++ b/res/values-en-rIN/strings.xml
@@ -23,18 +23,6 @@
     <string name="home" msgid="7658288663002113681">"Home"</string>
     <string name="uid_name" msgid="7820867637514617527">"Android Core Apps"</string>
     <string name="folder_name" msgid="7371454440695724752"></string>
-    <string name="wallpaper_instructions" msgid="563973358787555519">"Set wallpaper"</string>
-  <plurals name="number_of_items_selected">
-    <item quantity="zero" msgid="7464587177007785408">"%1$d selected"</item>
-    <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>
-    <string name="crop_wallpaper" msgid="8334345984491368009">"Crop wallpaper"</string>
     <string name="activity_not_found" msgid="8071924732094499514">"App isn\'t installed."</string>
     <string name="widgets_tab_label" msgid="2921133187116603919">"Widgets"</string>
     <string name="widget_adder" msgid="3201040140710381657">"Widgets"</string>
@@ -54,8 +42,8 @@
     <string name="group_widgets" msgid="1569030723286851002">"Widgets"</string>
     <string name="completely_out_of_space" msgid="6106288382070760318">"No more room on your Home screens."</string>
     <string name="out_of_space" msgid="4691004494942118364">"No more room on this Home screen."</string>
-    <string name="hotseat_out_of_space" msgid="9139760413395605841">"No more room on the hot seat."</string>
-    <string name="invalid_hotseat_item" msgid="1211534262129849507">"This widget is too large for the hot seat."</string>
+    <string name="hotseat_out_of_space" msgid="7448809638125333693">"No more room in the Favourites tray"</string>
+    <string name="invalid_hotseat_item" msgid="5779907847267573691">"This widget is too large for the Favourites tray"</string>
     <string name="shortcut_installed" msgid="1701742129426969556">"Shortcut \"<xliff:g id="NAME">%s</xliff:g>\" created."</string>
     <string name="shortcut_uninstalled" msgid="8176767991305701821">"Shortcut \"<xliff:g id="NAME">%s</xliff:g>\" was removed."</string>
     <string name="shortcut_duplicate" msgid="9167217446062498127">"Shortcut \"<xliff:g id="NAME">%s</xliff:g>\" already exists."</string>
@@ -96,15 +84,17 @@
     <string name="workspace_scroll_format" msgid="8458889198184077399">"Home screen %1$d of %2$d"</string>
     <string name="apps_customize_apps_scroll_format" msgid="370005296147130238">"Apps page %1$d of %2$d"</string>
     <string name="apps_customize_widgets_scroll_format" msgid="3106209519974971521">"Widgets page %1$d of %2$d"</string>
-    <string name="first_run_cling_title" msgid="7257389003637362144">"Welcome!"</string>
+    <string name="first_run_cling_title" msgid="2459738000155917941">"Welcome"</string>
     <string name="first_run_cling_description" msgid="6447072552696253358">"Make yourself at home."</string>
     <string name="first_run_cling_custom_content_hint" msgid="6090628589029352439"></string>
     <string name="first_run_cling_search_bar_hint" msgid="5909062802402452582"></string>
     <string name="first_run_cling_create_screens_hint" msgid="6950729526680114157">"Create more screens for apps and folders"</string>
+    <string name="migration_cling_title" msgid="9181776667882933767">"Copy your app icons"</string>
+    <string name="migration_cling_description" msgid="2752413805582227644">"Import icons and folders from your old Home screens?"</string>
+    <string name="migration_cling_copy_apps" msgid="946331230090919440">"COPY ICONS"</string>
+    <string name="migration_cling_use_default" msgid="2626475813981258626">"START AFRESH"</string>
     <string name="workspace_cling_title" msgid="5626202359865825661">"Organise your space"</string>
     <string name="workspace_cling_move_item" msgid="528201129978005352">"Touch &amp; hold background to manage wallpaper, widgets and settings."</string>
-    <string name="all_apps_cling_title" msgid="34929250753095858">"Choose some apps"</string>
-    <string name="all_apps_cling_add_item" msgid="400866858451850784">"To add an app to your Home screen, touch &amp; hold it."</string>
     <string name="folder_cling_title" msgid="3894908818693254164">"Here\'s a folder"</string>
     <string name="folder_cling_create_folder" msgid="6158215559475836131">"To create one like this, touch &amp; hold an app, then move it over another."</string>
     <string name="cling_dismiss" msgid="8962359497601507581">"OK"</string>
diff --git a/res/values-en/dimens.xml b/res/values-en/dimens.xml
new file mode 100644
index 0000000..01d4693
--- /dev/null
+++ b/res/values-en/dimens.xml
@@ -0,0 +1,24 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2009 The Android Open Source Project
+
+     Licensed under the Apache License, Version 2.0 (the "License");
+     you may not use this file except in compliance with the License.
+     You may obtain a copy of the License at
+  
+          http://www.apache.org/licenses/LICENSE-2.0
+  
+     Unless required by applicable law or agreed to in writing, software
+     distributed under the License is distributed on an "AS IS" BASIS,
+     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+     See the License for the specific language governing permissions and
+     limitations under the License.
+-->
+
+<resources>
+<!-- Cling -->
+    <dimen name="cling_title_text_size">22sp</dimen>
+    <dimen name="cling_text_size">16sp</dimen>
+    <dimen name="cling_alt_title_text_size">30sp</dimen>
+    <dimen name="cling_alt_text_size">16sp</dimen>
+    <dimen name="cling_hint_text_size">18sp</dimen>
+</resources>
diff --git a/res/values-es-rUS/strings.xml b/res/values-es-rUS/strings.xml
index c9a44a9..95e4a99 100644
--- a/res/values-es-rUS/strings.xml
+++ b/res/values-es-rUS/strings.xml
@@ -23,18 +23,6 @@
     <string name="home" msgid="7658288663002113681">"Pantalla principal"</string>
     <string name="uid_name" msgid="7820867637514617527">"Aplicaciones básicas de Android"</string>
     <string name="folder_name" msgid="7371454440695724752"></string>
-    <string name="wallpaper_instructions" msgid="563973358787555519">"Establecer como fondo de pantalla"</string>
-  <plurals name="number_of_items_selected">
-    <item quantity="zero" msgid="7464587177007785408">"%1$d seleccionados"</item>
-    <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>
-    <string name="crop_wallpaper" msgid="8334345984491368009">"Recortar fondo de pantalla"</string>
     <string name="activity_not_found" msgid="8071924732094499514">"No se instaló la aplicación."</string>
     <string name="widgets_tab_label" msgid="2921133187116603919">"Widgets"</string>
     <string name="widget_adder" msgid="3201040140710381657">"Widgets"</string>
@@ -54,8 +42,8 @@
     <string name="group_widgets" msgid="1569030723286851002">"Widgets"</string>
     <string name="completely_out_of_space" msgid="6106288382070760318">"No hay más espacio en tus pantallas principales."</string>
     <string name="out_of_space" msgid="4691004494942118364">"No hay más espacio en esta pantalla principal."</string>
-    <string name="hotseat_out_of_space" msgid="9139760413395605841">"No hay más espacio en la barra de accesos directos."</string>
-    <string name="invalid_hotseat_item" msgid="1211534262129849507">"Este widget es demasiado grande para la barra de accesos directos."</string>
+    <string name="hotseat_out_of_space" msgid="7448809638125333693">"La bandeja de favoritos está llena."</string>
+    <string name="invalid_hotseat_item" msgid="5779907847267573691">"Este widget es demasiado grande para la bandeja de favoritos."</string>
     <string name="shortcut_installed" msgid="1701742129426969556">"Se creó el acceso directo \"<xliff:g id="NAME">%s</xliff:g>\"."</string>
     <string name="shortcut_uninstalled" msgid="8176767991305701821">"Se eliminó el acceso directo \"<xliff:g id="NAME">%s</xliff:g>\"."</string>
     <string name="shortcut_duplicate" msgid="9167217446062498127">"El acceso directo \"<xliff:g id="NAME">%s</xliff:g>\" ya existe."</string>
@@ -96,15 +84,17 @@
     <string name="workspace_scroll_format" msgid="8458889198184077399">"Pantalla principal %1$d de %2$d"</string>
     <string name="apps_customize_apps_scroll_format" msgid="370005296147130238">"Página de aplicaciones %1$d de %2$d"</string>
     <string name="apps_customize_widgets_scroll_format" msgid="3106209519974971521">"Página de widgets %1$d de %2$d"</string>
-    <string name="first_run_cling_title" msgid="7257389003637362144">"¡Bienvenido/a!"</string>
+    <string name="first_run_cling_title" msgid="2459738000155917941">"Bienvenido"</string>
     <string name="first_run_cling_description" msgid="6447072552696253358">"Siéntete como en casa."</string>
     <string name="first_run_cling_custom_content_hint" msgid="6090628589029352439"></string>
     <string name="first_run_cling_search_bar_hint" msgid="5909062802402452582"></string>
     <string name="first_run_cling_create_screens_hint" msgid="6950729526680114157">"Crea más pantallas para aplicaciones y carpetas."</string>
+    <string name="migration_cling_title" msgid="9181776667882933767">"Copiar íconos de aplicaciones"</string>
+    <string name="migration_cling_description" msgid="2752413805582227644">"¿Importar íconos y carpetas de pant. principales antiguas?"</string>
+    <string name="migration_cling_copy_apps" msgid="946331230090919440">"COPIAR ÍCONOS"</string>
+    <string name="migration_cling_use_default" msgid="2626475813981258626">"EMPEZAR DE CERO"</string>
     <string name="workspace_cling_title" msgid="5626202359865825661">"Organiza tu espacio"</string>
     <string name="workspace_cling_move_item" msgid="528201129978005352">"Mantén presionado el fondo para administrar el fondo de pantalla, los widgets y la configuración."</string>
-    <string name="all_apps_cling_title" msgid="34929250753095858">"Elige algunas aplicaciones"</string>
-    <string name="all_apps_cling_add_item" msgid="400866858451850784">"Para agregar una aplicación a tu pantalla principal, mantenla presionada."</string>
     <string name="folder_cling_title" msgid="3894908818693254164">"Aquí tienes una carpeta"</string>
     <string name="folder_cling_create_folder" msgid="6158215559475836131">"Para crear una carpeta como esta, mantén presionada una aplicación y luego muévela sobre otra."</string>
     <string name="cling_dismiss" msgid="8962359497601507581">"Aceptar"</string>
diff --git a/res/values-es/strings.xml b/res/values-es/strings.xml
index 193e096..e5beb90 100644
--- a/res/values-es/strings.xml
+++ b/res/values-es/strings.xml
@@ -23,18 +23,6 @@
     <string name="home" msgid="7658288663002113681">"Home"</string>
     <string name="uid_name" msgid="7820867637514617527">"Aplicaciones básicas de Android"</string>
     <string name="folder_name" msgid="7371454440695724752"></string>
-    <string name="wallpaper_instructions" msgid="563973358787555519">"Establecer fondo"</string>
-  <plurals name="number_of_items_selected">
-    <item quantity="zero" msgid="7464587177007785408">"Seleccionados: %1$d"</item>
-    <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>
-    <string name="crop_wallpaper" msgid="8334345984491368009">"Recortar fondo de pantalla"</string>
     <string name="activity_not_found" msgid="8071924732094499514">"La aplicación no está instalada."</string>
     <string name="widgets_tab_label" msgid="2921133187116603919">"Widgets"</string>
     <string name="widget_adder" msgid="3201040140710381657">"Widgets"</string>
@@ -54,8 +42,8 @@
     <string name="group_widgets" msgid="1569030723286851002">"Widgets"</string>
     <string name="completely_out_of_space" msgid="6106288382070760318">"No queda espacio en las pantallas de inicio."</string>
     <string name="out_of_space" msgid="4691004494942118364">"No queda espacio en la pantalla de inicio."</string>
-    <string name="hotseat_out_of_space" msgid="9139760413395605841">"No queda espacio en la barra de accesos directos."</string>
-    <string name="invalid_hotseat_item" msgid="1211534262129849507">"Este widget es demasiado grande para la barra de accesos directos."</string>
+    <string name="hotseat_out_of_space" msgid="7448809638125333693">"La bandeja de favoritos está completa"</string>
+    <string name="invalid_hotseat_item" msgid="5779907847267573691">"Este widget es demasiado grande para la bandeja de favoritos"</string>
     <string name="shortcut_installed" msgid="1701742129426969556">"Se ha creado el acceso directo \"<xliff:g id="NAME">%s</xliff:g>\"."</string>
     <string name="shortcut_uninstalled" msgid="8176767991305701821">"Se ha eliminado el acceso directo \"<xliff:g id="NAME">%s</xliff:g>\"."</string>
     <string name="shortcut_duplicate" msgid="9167217446062498127">"El acceso directo \"<xliff:g id="NAME">%s</xliff:g>\" ya existe."</string>
@@ -96,15 +84,17 @@
     <string name="workspace_scroll_format" msgid="8458889198184077399">"Pantalla de inicio %1$d de %2$d"</string>
     <string name="apps_customize_apps_scroll_format" msgid="370005296147130238">"Página de aplicaciones %1$d de %2$d"</string>
     <string name="apps_customize_widgets_scroll_format" msgid="3106209519974971521">"Página de widgets %1$d de %2$d"</string>
-    <string name="first_run_cling_title" msgid="7257389003637362144">"Te damos la bienvenida"</string>
+    <string name="first_run_cling_title" msgid="2459738000155917941">"Te damos la bienvenida"</string>
     <string name="first_run_cling_description" msgid="6447072552696253358">"Personaliza tu pantalla de inicio."</string>
     <string name="first_run_cling_custom_content_hint" msgid="6090628589029352439"></string>
     <string name="first_run_cling_search_bar_hint" msgid="5909062802402452582"></string>
     <string name="first_run_cling_create_screens_hint" msgid="6950729526680114157">"Crea más pantallas para aplicaciones y carpetas"</string>
+    <string name="migration_cling_title" msgid="9181776667882933767">"Copiar iconos de aplicaciones"</string>
+    <string name="migration_cling_description" msgid="2752413805582227644">"¿Importar iconos y carpetas de pantallas de inicio antiguas?"</string>
+    <string name="migration_cling_copy_apps" msgid="946331230090919440">"COPIAR ICONOS"</string>
+    <string name="migration_cling_use_default" msgid="2626475813981258626">"AJUSTES PREDETERMINADOS"</string>
     <string name="workspace_cling_title" msgid="5626202359865825661">"Organiza tu espacio"</string>
     <string name="workspace_cling_move_item" msgid="528201129978005352">"Mantén pulsado el fondo para gestionar el fondo de pantalla, los widgets y los ajustes."</string>
-    <string name="all_apps_cling_title" msgid="34929250753095858">"Selecciona algunas aplicaciones"</string>
-    <string name="all_apps_cling_add_item" msgid="400866858451850784">"Para añadir una aplicación a tu pantalla de inicio, solo tienes que mantenerla pulsada."</string>
     <string name="folder_cling_title" msgid="3894908818693254164">"Esto es una carpeta"</string>
     <string name="folder_cling_create_folder" msgid="6158215559475836131">"Para crear una carpeta como esta, mantén pulsada una aplicación y muévela sobre otra."</string>
     <string name="cling_dismiss" msgid="8962359497601507581">"Aceptar"</string>
diff --git a/res/values-et-rEE/strings.xml b/res/values-et-rEE/strings.xml
index f026b08..a2f3125 100644
--- a/res/values-et-rEE/strings.xml
+++ b/res/values-et-rEE/strings.xml
@@ -23,18 +23,6 @@
     <string name="home" msgid="7658288663002113681">"Avaekraan"</string>
     <string name="uid_name" msgid="7820867637514617527">"Androidi tuumrakendused"</string>
     <string name="folder_name" msgid="7371454440695724752"></string>
-    <string name="wallpaper_instructions" msgid="563973358787555519">"Määra taustapilt"</string>
-  <plurals name="number_of_items_selected">
-    <item quantity="zero" msgid="7464587177007785408">"Valitud on %1$d"</item>
-    <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>
-    <string name="crop_wallpaper" msgid="8334345984491368009">"Taustapildi kärpimine"</string>
     <string name="activity_not_found" msgid="8071924732094499514">"Rakendus pole installitud."</string>
     <string name="widgets_tab_label" msgid="2921133187116603919">"Vidinad"</string>
     <string name="widget_adder" msgid="3201040140710381657">"Vidinad"</string>
@@ -54,8 +42,8 @@
     <string name="group_widgets" msgid="1569030723286851002">"Vidinad"</string>
     <string name="completely_out_of_space" msgid="6106288382070760318">"Teie avaekraanidel ei ole enam ruumi."</string>
     <string name="out_of_space" msgid="4691004494942118364">"Sellel avaekraanil pole enam ruumi."</string>
-    <string name="hotseat_out_of_space" msgid="9139760413395605841">"Kohandataval dokialal pole rohkem ruumi."</string>
-    <string name="invalid_hotseat_item" msgid="1211534262129849507">"See vidin on kohandatava dokiala jaoks liiga suur."</string>
+    <string name="hotseat_out_of_space" msgid="7448809638125333693">"Salves Lemmikud pole rohkem ruumi"</string>
+    <string name="invalid_hotseat_item" msgid="5779907847267573691">"See vidin on salve Lemmikud jaoks liiga suur"</string>
     <string name="shortcut_installed" msgid="1701742129426969556">"Otsetee „<xliff:g id="NAME">%s</xliff:g>” on loodud."</string>
     <string name="shortcut_uninstalled" msgid="8176767991305701821">"Otsetee „<xliff:g id="NAME">%s</xliff:g>” on eemaldatud."</string>
     <string name="shortcut_duplicate" msgid="9167217446062498127">"Otsetee „<xliff:g id="NAME">%s</xliff:g>” on juba olemas."</string>
@@ -96,15 +84,17 @@
     <string name="workspace_scroll_format" msgid="8458889198184077399">"Avaekraan %1$d/%2$d"</string>
     <string name="apps_customize_apps_scroll_format" msgid="370005296147130238">"Rakenduste leht %1$d/%2$d"</string>
     <string name="apps_customize_widgets_scroll_format" msgid="3106209519974971521">"Vidinate leht %1$d/%2$d"</string>
-    <string name="first_run_cling_title" msgid="7257389003637362144">"Tere tulemast!"</string>
+    <string name="first_run_cling_title" msgid="2459738000155917941">"Tere tulemast"</string>
     <string name="first_run_cling_description" msgid="6447072552696253358">"Tundke end nagu kodus."</string>
     <string name="first_run_cling_custom_content_hint" msgid="6090628589029352439"></string>
     <string name="first_run_cling_search_bar_hint" msgid="5909062802402452582"></string>
     <string name="first_run_cling_create_screens_hint" msgid="6950729526680114157">"Looge rakenduste ja kaustade jaoks rohkem ekraanikuvasid"</string>
+    <string name="migration_cling_title" msgid="9181776667882933767">"Kopeerige rakenduste ikoonid"</string>
+    <string name="migration_cling_description" msgid="2752413805582227644">"Kas importida vanade avaekraanide ikoonid ja kaustad?"</string>
+    <string name="migration_cling_copy_apps" msgid="946331230090919440">"KOPEERI IKOONID"</string>
+    <string name="migration_cling_use_default" msgid="2626475813981258626">"ALUSTA ALGUSEST"</string>
     <string name="workspace_cling_title" msgid="5626202359865825661">"Korraldage oma ruumi"</string>
     <string name="workspace_cling_move_item" msgid="528201129978005352">"Taustapildi, vidinate ja seadete haldamiseks puudutage tausta ning hoidke seda all."</string>
-    <string name="all_apps_cling_title" msgid="34929250753095858">"Valige mõned rakendused"</string>
-    <string name="all_apps_cling_add_item" msgid="400866858451850784">"Rakenduse lisamiseks avaekraanile vajutage ja hoidke seda all."</string>
     <string name="folder_cling_title" msgid="3894908818693254164">"Siin on kaust"</string>
     <string name="folder_cling_create_folder" msgid="6158215559475836131">"Sarnase loomiseks vajutage ja hoidke rakendust all, seejärel viige see teise peale."</string>
     <string name="cling_dismiss" msgid="8962359497601507581">"OK"</string>
diff --git a/res/values-fa/strings.xml b/res/values-fa/strings.xml
index 657b5db..9f22f93 100644
--- a/res/values-fa/strings.xml
+++ b/res/values-fa/strings.xml
@@ -23,18 +23,6 @@
     <string name="home" msgid="7658288663002113681">"صفحه اصلی"</string>
     <string name="uid_name" msgid="7820867637514617527">"‏برنامه‌های Android Core"</string>
     <string name="folder_name" msgid="7371454440695724752"></string>
-    <string name="wallpaper_instructions" msgid="563973358787555519">"تنظیم کاغذدیواری"</string>
-  <plurals name="number_of_items_selected">
-    <item quantity="zero" msgid="7464587177007785408">"‏%1$d انتخاب شد"</item>
-    <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>
-    <string name="crop_wallpaper" msgid="8334345984491368009">"برش کاغذ دیواری"</string>
     <string name="activity_not_found" msgid="8071924732094499514">"برنامه نصب نشده است."</string>
     <string name="widgets_tab_label" msgid="2921133187116603919">"ابزارک‌ها"</string>
     <string name="widget_adder" msgid="3201040140710381657">"ابزارک‌ها"</string>
@@ -54,8 +42,8 @@
     <string name="group_widgets" msgid="1569030723286851002">"ابزارک‌ها"</string>
     <string name="completely_out_of_space" msgid="6106288382070760318">"فضای بیشتری در صفحات نمایش اصلی شما موجود نیست."</string>
     <string name="out_of_space" msgid="4691004494942118364">"فضای بیشتری در این صفحه اصلی موجود نیست."</string>
-    <string name="hotseat_out_of_space" msgid="9139760413395605841">"فضای بیشتری در جایگاه اتصال نیست."</string>
-    <string name="invalid_hotseat_item" msgid="1211534262129849507">"این ابزارک بیش از حد برای جایگاه اتصال بزرگ است."</string>
+    <string name="hotseat_out_of_space" msgid="7448809638125333693">"فضای بیشتری در سینی موارد دلخواه وجود ندارد"</string>
+    <string name="invalid_hotseat_item" msgid="5779907847267573691">"این ابزارک برای سینی موارد دلخواه بسیار بزرگ است"</string>
     <string name="shortcut_installed" msgid="1701742129426969556">"میان‌بر «<xliff:g id="NAME">%s</xliff:g>» ایجاد شد."</string>
     <string name="shortcut_uninstalled" msgid="8176767991305701821">"میان‌بر «<xliff:g id="NAME">%s</xliff:g>» حذف شد."</string>
     <string name="shortcut_duplicate" msgid="9167217446062498127">"میان‌بر «<xliff:g id="NAME">%s</xliff:g>» در حال حاضر وجود دارد."</string>
@@ -96,15 +84,17 @@
     <string name="workspace_scroll_format" msgid="8458889198184077399">"‏صفحه اصلی %1$d از %2$d"</string>
     <string name="apps_customize_apps_scroll_format" msgid="370005296147130238">"‏صفحه برنامه‌ها %1$d از %2$d"</string>
     <string name="apps_customize_widgets_scroll_format" msgid="3106209519974971521">"‏صفحه ابزارک‌ها %1$d از %2$d"</string>
-    <string name="first_run_cling_title" msgid="7257389003637362144">"خوش آمدید!"</string>
+    <string name="first_run_cling_title" msgid="2459738000155917941">"خوش آمدید"</string>
     <string name="first_run_cling_description" msgid="6447072552696253358">"راحت باشید."</string>
     <string name="first_run_cling_custom_content_hint" msgid="6090628589029352439"></string>
     <string name="first_run_cling_search_bar_hint" msgid="5909062802402452582"></string>
     <string name="first_run_cling_create_screens_hint" msgid="6950729526680114157">"صفحات بیشتری را برای برنامه‌ها و پوشه‌ها ایجاد کنید"</string>
+    <string name="migration_cling_title" msgid="9181776667882933767">"کپی کردن نمادهای برنامه شما"</string>
+    <string name="migration_cling_description" msgid="2752413805582227644">"نمادها و پوشه‌ها از صفحه‌های اصلی قدیمی شما وارد شوند؟"</string>
+    <string name="migration_cling_copy_apps" msgid="946331230090919440">"کپی نمادها"</string>
+    <string name="migration_cling_use_default" msgid="2626475813981258626">"شروع تازه"</string>
     <string name="workspace_cling_title" msgid="5626202359865825661">"فضای خود را سازماندهی کنید"</string>
     <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_create_folder" msgid="6158215559475836131">"برای ایجاد پوشه‌ای مثل این، یک برنامه را لمس کرده و نگه‌دارید، سپس آن را روی برنامه دیگر بیاندازید."</string>
     <string name="cling_dismiss" msgid="8962359497601507581">"تأیید"</string>
diff --git a/res/values-fi/strings.xml b/res/values-fi/strings.xml
index d327250..af461a5 100644
--- a/res/values-fi/strings.xml
+++ b/res/values-fi/strings.xml
@@ -23,18 +23,6 @@
     <string name="home" msgid="7658288663002113681">"Aloitusruutu"</string>
     <string name="uid_name" msgid="7820867637514617527">"Androidin ydinsovellukset"</string>
     <string name="folder_name" msgid="7371454440695724752"></string>
-    <string name="wallpaper_instructions" msgid="563973358787555519">"Aseta taustakuva"</string>
-  <plurals name="number_of_items_selected">
-    <item quantity="zero" msgid="7464587177007785408">"%1$d valittu"</item>
-    <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>
-    <string name="crop_wallpaper" msgid="8334345984491368009">"Rajaa taustakuva"</string>
     <string name="activity_not_found" msgid="8071924732094499514">"Sovellusta ei ole asennettu."</string>
     <string name="widgets_tab_label" msgid="2921133187116603919">"Widgetit"</string>
     <string name="widget_adder" msgid="3201040140710381657">"Widgetit"</string>
@@ -54,8 +42,8 @@
     <string name="group_widgets" msgid="1569030723286851002">"Widgetit"</string>
     <string name="completely_out_of_space" msgid="6106288382070760318">"Aloitusruuduilla ei ole enää tilaa."</string>
     <string name="out_of_space" msgid="4691004494942118364">"Tässä aloitusruudussa ei ole enää tilaa."</string>
-    <string name="hotseat_out_of_space" msgid="9139760413395605841">"Hotseatissa ei ole enää tilaa."</string>
-    <string name="invalid_hotseat_item" msgid="1211534262129849507">"Tämä widget on liian suuri tähän hotseat-paikkaan."</string>
+    <string name="hotseat_out_of_space" msgid="7448809638125333693">"Suosikit-valikossa ei ole enää tilaa"</string>
+    <string name="invalid_hotseat_item" msgid="5779907847267573691">"Tämä widget on liian suuri Suosikit-valikkoon lisättäväksi"</string>
     <string name="shortcut_installed" msgid="1701742129426969556">"Pikakuvake <xliff:g id="NAME">%s</xliff:g> luotiin."</string>
     <string name="shortcut_uninstalled" msgid="8176767991305701821">"Pikakuvake <xliff:g id="NAME">%s</xliff:g> poistettiin."</string>
     <string name="shortcut_duplicate" msgid="9167217446062498127">"Pikakuvake <xliff:g id="NAME">%s</xliff:g> on jo olemassa."</string>
@@ -96,15 +84,17 @@
     <string name="workspace_scroll_format" msgid="8458889198184077399">"Aloitusruutu %1$d/%2$d"</string>
     <string name="apps_customize_apps_scroll_format" msgid="370005296147130238">"Apps-sivu %1$d / %2$d"</string>
     <string name="apps_customize_widgets_scroll_format" msgid="3106209519974971521">"Widgetit-sivu %1$d / %2$d"</string>
-    <string name="first_run_cling_title" msgid="7257389003637362144">"Tervetuloa!"</string>
+    <string name="first_run_cling_title" msgid="2459738000155917941">"Tervetuloa"</string>
     <string name="first_run_cling_description" msgid="6447072552696253358">"Ole kuin kotonasi."</string>
     <string name="first_run_cling_custom_content_hint" msgid="6090628589029352439"></string>
     <string name="first_run_cling_search_bar_hint" msgid="5909062802402452582"></string>
     <string name="first_run_cling_create_screens_hint" msgid="6950729526680114157">"Luo lisää ruutuja sovelluksille ja kansioille"</string>
+    <string name="migration_cling_title" msgid="9181776667882933767">"Kopioi sovelluskuvakkeet"</string>
+    <string name="migration_cling_description" msgid="2752413805582227644">"Tuodaanko kuvakkeet ja kansiot vanhoista aloitusruuduista?"</string>
+    <string name="migration_cling_copy_apps" msgid="946331230090919440">"KOPIOI KUVAKKEET"</string>
+    <string name="migration_cling_use_default" msgid="2626475813981258626">"ALOITA ALUSTA"</string>
     <string name="workspace_cling_title" msgid="5626202359865825661">"Järjestä tilasi"</string>
     <string name="workspace_cling_move_item" msgid="528201129978005352">"Hallitse taustakuvaa, widgetejä ja asetuksia koskettamalla taustaa pitkään."</string>
-    <string name="all_apps_cling_title" msgid="34929250753095858">"Valitse joitakin sovelluksia"</string>
-    <string name="all_apps_cling_add_item" msgid="400866858451850784">"Voit lisätä sovelluksen aloitusruutuun koskettamalla sitä pitkään."</string>
     <string name="folder_cling_title" msgid="3894908818693254164">"Tässä on kansio"</string>
     <string name="folder_cling_create_folder" msgid="6158215559475836131">"Luo se seuraavasti: kosketa sovellusta pitkään ja siirrä se sitten toisen päälle."</string>
     <string name="cling_dismiss" msgid="8962359497601507581">"OK"</string>
diff --git a/res/values-fr-rCA/strings.xml b/res/values-fr-rCA/strings.xml
index 9d8dbeb..0334351 100644
--- a/res/values-fr-rCA/strings.xml
+++ b/res/values-fr-rCA/strings.xml
@@ -23,18 +23,6 @@
     <string name="home" msgid="7658288663002113681">"Accueil"</string>
     <string name="uid_name" msgid="7820867637514617527">"Applications de base Android"</string>
     <string name="folder_name" msgid="7371454440695724752"></string>
-    <string name="wallpaper_instructions" msgid="563973358787555519">"Définir le fond d\'écran"</string>
-  <plurals name="number_of_items_selected">
-    <item quantity="zero" msgid="7464587177007785408">"%1$d sélectionné"</item>
-    <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>
-    <string name="crop_wallpaper" msgid="8334345984491368009">"Rogner le fond d\'écran"</string>
     <string name="activity_not_found" msgid="8071924732094499514">"L\'application n\'est pas installée."</string>
     <string name="widgets_tab_label" msgid="2921133187116603919">"Widgets"</string>
     <string name="widget_adder" msgid="3201040140710381657">"Widgets"</string>
@@ -54,8 +42,8 @@
     <string name="group_widgets" msgid="1569030723286851002">"Widgets"</string>
     <string name="completely_out_of_space" msgid="6106288382070760318">"Vous n\'avez plus d\'espace libre sur vos écrans d\'accueil."</string>
     <string name="out_of_space" msgid="4691004494942118364">"Pas d\'espace libre sur l\'écran d\'accueil."</string>
-    <string name="hotseat_out_of_space" msgid="9139760413395605841">"Vous n\'avez plus de place sur la barre d\'accès rapide."</string>
-    <string name="invalid_hotseat_item" msgid="1211534262129849507">"Ce widget est trop volumineux pour la barre d\'accès rapide."</string>
+    <string name="hotseat_out_of_space" msgid="7448809638125333693">"Il n\'y a plus d\'espace dans la zone des favoris"</string>
+    <string name="invalid_hotseat_item" msgid="5779907847267573691">"Ce widget est trop volumineux pour la zone des favoris"</string>
     <string name="shortcut_installed" msgid="1701742129426969556">"Le raccourci « <xliff:g id="NAME">%s</xliff:g> » a été créé."</string>
     <string name="shortcut_uninstalled" msgid="8176767991305701821">"Le raccourci « <xliff:g id="NAME">%s</xliff:g> » a été supprimé."</string>
     <string name="shortcut_duplicate" msgid="9167217446062498127">"Le raccourci « <xliff:g id="NAME">%s</xliff:g> » existe déjà."</string>
@@ -96,15 +84,17 @@
     <string name="workspace_scroll_format" msgid="8458889198184077399">"Écran d\'accueil %1$d sur %2$d"</string>
     <string name="apps_customize_apps_scroll_format" msgid="370005296147130238">"Page des applications : %1$d sur %2$d"</string>
     <string name="apps_customize_widgets_scroll_format" msgid="3106209519974971521">"Page des widgets : %1$d sur %2$d"</string>
-    <string name="first_run_cling_title" msgid="7257389003637362144">"Bienvenue!"</string>
+    <string name="first_run_cling_title" msgid="2459738000155917941">"Bienvenue"</string>
     <string name="first_run_cling_description" msgid="6447072552696253358">"Faites comme chez vous."</string>
     <string name="first_run_cling_custom_content_hint" msgid="6090628589029352439"></string>
     <string name="first_run_cling_search_bar_hint" msgid="5909062802402452582"></string>
     <string name="first_run_cling_create_screens_hint" msgid="6950729526680114157">"Créer plus d\'écrans pour les applications et les dossiers"</string>
+    <string name="migration_cling_title" msgid="9181776667882933767">"Copier les icônes de vos applis"</string>
+    <string name="migration_cling_description" msgid="2752413805582227644">"Importer les icônes et dossiers des anciens écrans d\'accueil?"</string>
+    <string name="migration_cling_copy_apps" msgid="946331230090919440">"COPIER LES ICÔNES"</string>
+    <string name="migration_cling_use_default" msgid="2626475813981258626">"DISPOSITION PAR DÉFAUT"</string>
     <string name="workspace_cling_title" msgid="5626202359865825661">"Organiser son espace personnel"</string>
     <string name="workspace_cling_move_item" msgid="528201129978005352">"Maintenez votre doigt sur l\'arrière-plan pour gérer les fonds d\'écran, les widgets et les paramètres."</string>
-    <string name="all_apps_cling_title" msgid="34929250753095858">"Sélectionner des applications"</string>
-    <string name="all_apps_cling_add_item" msgid="400866858451850784">"Pour ajouter une application à votre écran d\'accueil, maintenez votre doigt dessus."</string>
     <string name="folder_cling_title" msgid="3894908818693254164">"Voici un dossier"</string>
     <string name="folder_cling_create_folder" msgid="6158215559475836131">"Pour créer un dossier comme ça, maintenez votre doigt sur une application, puis déplacez-la sur une autre."</string>
     <string name="cling_dismiss" msgid="8962359497601507581">"OK"</string>
diff --git a/res/values-fr/strings.xml b/res/values-fr/strings.xml
index b1b0a79..5f0607e 100644
--- a/res/values-fr/strings.xml
+++ b/res/values-fr/strings.xml
@@ -23,18 +23,6 @@
     <string name="home" msgid="7658288663002113681">"Accueil"</string>
     <string name="uid_name" msgid="7820867637514617527">"Applications de base Android"</string>
     <string name="folder_name" msgid="7371454440695724752"></string>
-    <string name="wallpaper_instructions" msgid="563973358787555519">"Définir comme fond d\'écran"</string>
-  <plurals name="number_of_items_selected">
-    <item quantity="zero" msgid="7464587177007785408">"%1$d fond d\'écran sélectionné"</item>
-    <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>
-    <string name="crop_wallpaper" msgid="8334345984491368009">"Rogner le fond d\'écran"</string>
     <string name="activity_not_found" msgid="8071924732094499514">"L\'application n\'est pas installée."</string>
     <string name="widgets_tab_label" msgid="2921133187116603919">"Widgets"</string>
     <string name="widget_adder" msgid="3201040140710381657">"Widgets"</string>
@@ -54,8 +42,8 @@
     <string name="group_widgets" msgid="1569030723286851002">"Widgets"</string>
     <string name="completely_out_of_space" msgid="6106288382070760318">"Vous n\'avez plus d\'espace libre sur vos écrans d\'accueil."</string>
     <string name="out_of_space" msgid="4691004494942118364">"Pas d\'espace libre sur cet écran d\'accueil."</string>
-    <string name="hotseat_out_of_space" msgid="9139760413395605841">"Vous n\'avez plus de place sur la barre d\'accès rapide."</string>
-    <string name="invalid_hotseat_item" msgid="1211534262129849507">"Ce widget est trop volumineux pour la barre d\'accès rapide."</string>
+    <string name="hotseat_out_of_space" msgid="7448809638125333693">"Plus d\'espace disponible dans la zone de favoris."</string>
+    <string name="invalid_hotseat_item" msgid="5779907847267573691">"Ce widget est trop volumineux pour la zone de favoris."</string>
     <string name="shortcut_installed" msgid="1701742129426969556">"Le raccourci \"<xliff:g id="NAME">%s</xliff:g>\" a été créé."</string>
     <string name="shortcut_uninstalled" msgid="8176767991305701821">"Le raccourci \"<xliff:g id="NAME">%s</xliff:g>\" a été supprimé."</string>
     <string name="shortcut_duplicate" msgid="9167217446062498127">"Le raccourci \"<xliff:g id="NAME">%s</xliff:g>\" existe déjà."</string>
@@ -96,15 +84,17 @@
     <string name="workspace_scroll_format" msgid="8458889198184077399">"Écran d\'accueil %1$d sur %2$d"</string>
     <string name="apps_customize_apps_scroll_format" msgid="370005296147130238">"Page des applications %1$d sur %2$d"</string>
     <string name="apps_customize_widgets_scroll_format" msgid="3106209519974971521">"Page des widgets %1$d sur %2$d"</string>
-    <string name="first_run_cling_title" msgid="7257389003637362144">"Bienvenue !"</string>
+    <string name="first_run_cling_title" msgid="2459738000155917941">"Bienvenue"</string>
     <string name="first_run_cling_description" msgid="6447072552696253358">"Familiarisez-vous avec l\'écran d\'accueil."</string>
     <string name="first_run_cling_custom_content_hint" msgid="6090628589029352439"></string>
     <string name="first_run_cling_search_bar_hint" msgid="5909062802402452582"></string>
     <string name="first_run_cling_create_screens_hint" msgid="6950729526680114157">"Créez des écrans personnalisés pour vos applis et dossiers"</string>
+    <string name="migration_cling_title" msgid="9181776667882933767">"Copier les icônes de vos applis"</string>
+    <string name="migration_cling_description" msgid="2752413805582227644">"Importer les icônes et dossiers des anciens écrans d\'accueil ?"</string>
+    <string name="migration_cling_copy_apps" msgid="946331230090919440">"COPIER LES ICÔNES"</string>
+    <string name="migration_cling_use_default" msgid="2626475813981258626">"DISPOSITION PAR DÉFAUT"</string>
     <string name="workspace_cling_title" msgid="5626202359865825661">"Organisez votre espace"</string>
     <string name="workspace_cling_move_item" msgid="528201129978005352">"Appuyez de manière prolongée sur l\'arrière-plan pour gérer les fonds d\'écran, les widgets et les paramètres."</string>
-    <string name="all_apps_cling_title" msgid="34929250753095858">"Sélectionner des applications"</string>
-    <string name="all_apps_cling_add_item" msgid="400866858451850784">"Pour ajouter une application à votre écran d\'accueil, appuyez dessus de manière prolongée."</string>
     <string name="folder_cling_title" msgid="3894908818693254164">"Voici un dossier"</string>
     <string name="folder_cling_create_folder" msgid="6158215559475836131">"Pour en créer un, appuyez de manière prolongée sur une application, puis déplacez-la vers une autre."</string>
     <string name="cling_dismiss" msgid="8962359497601507581">"OK"</string>
diff --git a/res/values-hi/strings.xml b/res/values-hi/strings.xml
index eddd75c..058f534 100644
--- a/res/values-hi/strings.xml
+++ b/res/values-hi/strings.xml
@@ -23,18 +23,6 @@
     <string name="home" msgid="7658288663002113681">"होम"</string>
     <string name="uid_name" msgid="7820867637514617527">"Android के मुख्य एप्लिकेशन"</string>
     <string name="folder_name" msgid="7371454440695724752"></string>
-    <string name="wallpaper_instructions" msgid="563973358787555519">"वॉलपेपर सेट करें"</string>
-  <plurals name="number_of_items_selected">
-    <item quantity="zero" msgid="7464587177007785408">"%1$d चयनित"</item>
-    <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>
-    <string name="crop_wallpaper" msgid="8334345984491368009">"वॉलपेपर काटें"</string>
     <string name="activity_not_found" msgid="8071924732094499514">"एप्‍लिकेशन इंस्‍टॉल नहीं है."</string>
     <string name="widgets_tab_label" msgid="2921133187116603919">"विजेट"</string>
     <string name="widget_adder" msgid="3201040140710381657">"विजेट"</string>
@@ -54,8 +42,8 @@
     <string name="group_widgets" msgid="1569030723286851002">"विजेट"</string>
     <string name="completely_out_of_space" msgid="6106288382070760318">"आपकी होम स्‍क्रीन पर स्थान शेष नहीं है."</string>
     <string name="out_of_space" msgid="4691004494942118364">"इस होम स्‍क्रीन पर स्थान शेष नहीं है."</string>
-    <string name="hotseat_out_of_space" msgid="9139760413395605841">"हॉटसीट पर स्थान शेष नहीं है."</string>
-    <string name="invalid_hotseat_item" msgid="1211534262129849507">"हॉटसीट के लि‍ए यह वि‍जेट बहुत बड़ा है."</string>
+    <string name="hotseat_out_of_space" msgid="7448809638125333693">"पसंदीदा ट्रे में और स्थान नहीं है"</string>
+    <string name="invalid_hotseat_item" msgid="5779907847267573691">"पसंदीदा ट्रे के लिए यह विजेट बहुत ही बड़ा है"</string>
     <string name="shortcut_installed" msgid="1701742129426969556">"शॉर्टकट \"<xliff:g id="NAME">%s</xliff:g>\" बनाया गया."</string>
     <string name="shortcut_uninstalled" msgid="8176767991305701821">"शॉर्टकट \"<xliff:g id="NAME">%s</xliff:g>\" निकाल दिया गया था."</string>
     <string name="shortcut_duplicate" msgid="9167217446062498127">"शॉर्टकट \"<xliff:g id="NAME">%s</xliff:g>\" पहले से मौजूद है."</string>
@@ -96,15 +84,17 @@
     <string name="workspace_scroll_format" msgid="8458889198184077399">"होम स्क्रीन %2$d में से %1$d"</string>
     <string name="apps_customize_apps_scroll_format" msgid="370005296147130238">"एप्लिकेशन पृष्ठ %2$d में से %1$d"</string>
     <string name="apps_customize_widgets_scroll_format" msgid="3106209519974971521">"विजेट पृष्ठ %2$d में से %1$d"</string>
-    <string name="first_run_cling_title" msgid="7257389003637362144">"स्वागत है!"</string>
+    <string name="first_run_cling_title" msgid="2459738000155917941">"स्वागत है"</string>
     <string name="first_run_cling_description" msgid="6447072552696253358">"जैसा चाहें वैसा उपयोग करें."</string>
     <string name="first_run_cling_custom_content_hint" msgid="6090628589029352439"></string>
     <string name="first_run_cling_search_bar_hint" msgid="5909062802402452582"></string>
     <string name="first_run_cling_create_screens_hint" msgid="6950729526680114157">"एप्लिकेशन और फ़ोल्डर के लिए और अधिक स्क्रीन बनाएं"</string>
+    <string name="migration_cling_title" msgid="9181776667882933767">"ऐप्स आइकन की प्रतिलिपि बनाएं"</string>
+    <string name="migration_cling_description" msgid="2752413805582227644">"अपनी पुरानी होम स्क्रीन से आइकन और फ़ोल्डर आयात करें?"</string>
+    <string name="migration_cling_copy_apps" msgid="946331230090919440">"आइकन की प्रतिलिपि बनाएं"</string>
+    <string name="migration_cling_use_default" msgid="2626475813981258626">"फिर से शुरू करें"</string>
     <string name="workspace_cling_title" msgid="5626202359865825661">"अपने स्थान को व्यवस्थित करें"</string>
     <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_create_folder" msgid="6158215559475836131">"इसके जैसा कोई एक बनाने के लिए, किसी एप्लिकेशन को स्पर्श करके रखें, फिर इसे किसी दूसरे पर ले जाएं."</string>
     <string name="cling_dismiss" msgid="8962359497601507581">"ठीक"</string>
diff --git a/res/values-hr/strings.xml b/res/values-hr/strings.xml
index 783946d..52a91a3 100644
--- a/res/values-hr/strings.xml
+++ b/res/values-hr/strings.xml
@@ -23,18 +23,6 @@
     <string name="home" msgid="7658288663002113681">"Početna"</string>
     <string name="uid_name" msgid="7820867637514617527">"Matične aplikacije za Android"</string>
     <string name="folder_name" msgid="7371454440695724752"></string>
-    <string name="wallpaper_instructions" msgid="563973358787555519">"Postavi pozadinsku sliku"</string>
-  <plurals name="number_of_items_selected">
-    <item quantity="zero" msgid="7464587177007785408">"Odabrano: %1$d"</item>
-    <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>
-    <string name="crop_wallpaper" msgid="8334345984491368009">"Obreži pozadinsku sliku"</string>
     <string name="activity_not_found" msgid="8071924732094499514">"Aplikacija nije instalirana."</string>
     <string name="widgets_tab_label" msgid="2921133187116603919">"Widgeti"</string>
     <string name="widget_adder" msgid="3201040140710381657">"Widgeti"</string>
@@ -54,8 +42,8 @@
     <string name="group_widgets" msgid="1569030723286851002">"Widgeti"</string>
     <string name="completely_out_of_space" msgid="6106288382070760318">"Na vašim početnim zaslonima više nema mjesta."</string>
     <string name="out_of_space" msgid="4691004494942118364">"Na ovom početnom zaslonu više nema mjesta."</string>
-    <string name="hotseat_out_of_space" msgid="9139760413395605841">"Na hotseatu više nema mjesta."</string>
-    <string name="invalid_hotseat_item" msgid="1211534262129849507">"Ovaj je widget prevelik za hotseat."</string>
+    <string name="hotseat_out_of_space" msgid="7448809638125333693">"Nema više prostora na traci Favoriti"</string>
+    <string name="invalid_hotseat_item" msgid="5779907847267573691">"Widget je prevelik za traku Favoriti"</string>
     <string name="shortcut_installed" msgid="1701742129426969556">"Izrađen je prečac za \"<xliff:g id="NAME">%s</xliff:g>\"."</string>
     <string name="shortcut_uninstalled" msgid="8176767991305701821">"Uklonjen je prečac za \"<xliff:g id="NAME">%s</xliff:g>\"."</string>
     <string name="shortcut_duplicate" msgid="9167217446062498127">"Prečac za \"<xliff:g id="NAME">%s</xliff:g>\" već postoji."</string>
@@ -96,15 +84,17 @@
     <string name="workspace_scroll_format" msgid="8458889198184077399">"Početni zaslon %1$d od %2$d"</string>
     <string name="apps_customize_apps_scroll_format" msgid="370005296147130238">"Stranica aplikacija %1$d od %2$d"</string>
     <string name="apps_customize_widgets_scroll_format" msgid="3106209519974971521">"Stranica widgeta %1$d od %2$d"</string>
-    <string name="first_run_cling_title" msgid="7257389003637362144">"Dobro došli!"</string>
+    <string name="first_run_cling_title" msgid="2459738000155917941">"Dobro došli"</string>
     <string name="first_run_cling_description" msgid="6447072552696253358">"Osjećajte se kao kod kuće."</string>
     <string name="first_run_cling_custom_content_hint" msgid="6090628589029352439"></string>
     <string name="first_run_cling_search_bar_hint" msgid="5909062802402452582"></string>
     <string name="first_run_cling_create_screens_hint" msgid="6950729526680114157">"Izradite više zaslona za aplikacije i mape"</string>
+    <string name="migration_cling_title" msgid="9181776667882933767">"Kopiranje ikona aplikacija"</string>
+    <string name="migration_cling_description" msgid="2752413805582227644">"Želite li uvesti ikone i mape sa starih početnih zaslona?"</string>
+    <string name="migration_cling_copy_apps" msgid="946331230090919440">"KOPIRAJ IKONE"</string>
+    <string name="migration_cling_use_default" msgid="2626475813981258626">"POKRENI NOVO"</string>
     <string name="workspace_cling_title" msgid="5626202359865825661">"Organizirajte svoj prostor"</string>
     <string name="workspace_cling_move_item" msgid="528201129978005352">"Dodirnite i držite pozadinu da biste upravljali pozadinskom slikom, widgetima i postavkama."</string>
-    <string name="all_apps_cling_title" msgid="34929250753095858">"Odaberite neke aplikacije"</string>
-    <string name="all_apps_cling_add_item" msgid="400866858451850784">"Da biste dodali aplikaciju na početni zaslon, dodirnite je i zadržite."</string>
     <string name="folder_cling_title" msgid="3894908818693254164">"Evo mape"</string>
     <string name="folder_cling_create_folder" msgid="6158215559475836131">"Da biste izradili ovakvu mapu, dodirnite i držite aplikaciju pa je pomaknite preko druge aplikacije."</string>
     <string name="cling_dismiss" msgid="8962359497601507581">"U redu"</string>
diff --git a/res/values-hu/strings.xml b/res/values-hu/strings.xml
index 8876652..38b6b5c 100644
--- a/res/values-hu/strings.xml
+++ b/res/values-hu/strings.xml
@@ -23,18 +23,6 @@
     <string name="home" msgid="7658288663002113681">"Főoldal"</string>
     <string name="uid_name" msgid="7820867637514617527">"Alap Android-alkalmazások"</string>
     <string name="folder_name" msgid="7371454440695724752"></string>
-    <string name="wallpaper_instructions" msgid="563973358787555519">"Háttérkép beállítása"</string>
-  <plurals name="number_of_items_selected">
-    <item quantity="zero" msgid="7464587177007785408">"%1$d kiválasztva"</item>
-    <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>
-    <string name="crop_wallpaper" msgid="8334345984491368009">"Háttérkép körbevágása"</string>
     <string name="activity_not_found" msgid="8071924732094499514">"Az alkalmazás nincs telepítve."</string>
     <string name="widgets_tab_label" msgid="2921133187116603919">"Modulok"</string>
     <string name="widget_adder" msgid="3201040140710381657">"Modulok"</string>
@@ -54,8 +42,8 @@
     <string name="group_widgets" msgid="1569030723286851002">"Modulok"</string>
     <string name="completely_out_of_space" msgid="6106288382070760318">"Nincs több hely a kezdőképernyőkön."</string>
     <string name="out_of_space" msgid="4691004494942118364">"Nincs több hely ezen a kezdőképernyőn."</string>
-    <string name="hotseat_out_of_space" msgid="9139760413395605841">"Nincs több hely az egyéni mezőben."</string>
-    <string name="invalid_hotseat_item" msgid="1211534262129849507">"Ez a modul túl nagy az egyéni mező számára."</string>
+    <string name="hotseat_out_of_space" msgid="7448809638125333693">"Nincs több hely a Kedvencek tálcán"</string>
+    <string name="invalid_hotseat_item" msgid="5779907847267573691">"Ez a modul túl nagy a Kedvencek tálcán való elhelyezéshez"</string>
     <string name="shortcut_installed" msgid="1701742129426969556">"A(z) „<xliff:g id="NAME">%s</xliff:g>” parancsikon létrehozva."</string>
     <string name="shortcut_uninstalled" msgid="8176767991305701821">"A(z) „<xliff:g id="NAME">%s</xliff:g>” parancsikon eltávolítva."</string>
     <string name="shortcut_duplicate" msgid="9167217446062498127">"A(z) „<xliff:g id="NAME">%s</xliff:g>” parancsikon már létezik."</string>
@@ -96,15 +84,17 @@
     <string name="workspace_scroll_format" msgid="8458889198184077399">"%2$d/%1$d. kezdőképernyő"</string>
     <string name="apps_customize_apps_scroll_format" msgid="370005296147130238">"%2$d/%1$d. alkalmazásoldal"</string>
     <string name="apps_customize_widgets_scroll_format" msgid="3106209519974971521">"%2$d/%1$d. moduloldal"</string>
-    <string name="first_run_cling_title" msgid="7257389003637362144">"Üdvözöljük!"</string>
+    <string name="first_run_cling_title" msgid="2459738000155917941">"Üdvözöljük!"</string>
     <string name="first_run_cling_description" msgid="6447072552696253358">"Varázsolja egyedivé készülékét."</string>
     <string name="first_run_cling_custom_content_hint" msgid="6090628589029352439"></string>
     <string name="first_run_cling_search_bar_hint" msgid="5909062802402452582"></string>
     <string name="first_run_cling_create_screens_hint" msgid="6950729526680114157">"Hozzon létre további képernyőket az alkalmazásoknak és mappáknak"</string>
+    <string name="migration_cling_title" msgid="9181776667882933767">"Alkalmazásikonok másolása"</string>
+    <string name="migration_cling_description" msgid="2752413805582227644">"Importálja ikonjait és mappáit régi kezdőképernyőiről?"</string>
+    <string name="migration_cling_copy_apps" msgid="946331230090919440">"IKONOK MÁSOLÁSA"</string>
+    <string name="migration_cling_use_default" msgid="2626475813981258626">"TELJESEN ÚJ"</string>
     <string name="workspace_cling_title" msgid="5626202359865825661">"Munkaterület rendezése"</string>
     <string name="workspace_cling_move_item" msgid="528201129978005352">"Érintse meg és tartsa lenyomva a hátteret a háttérkép, modulok és beállítások kezeléséhez."</string>
-    <string name="all_apps_cling_title" msgid="34929250753095858">"Válasszon ki néhány alkalmazást"</string>
-    <string name="all_apps_cling_add_item" msgid="400866858451850784">"Ha egy alkalmazást szeretne elhelyezni a kezdőképernyőn, érintse meg, és tartsa lenyomva."</string>
     <string name="folder_cling_title" msgid="3894908818693254164">"Itt egy mappa"</string>
     <string name="folder_cling_create_folder" msgid="6158215559475836131">"Mappa létrehozásához érintse meg és tartsa lenyomva az alkalmazást, majd húzza egy másik fölé."</string>
     <string name="cling_dismiss" msgid="8962359497601507581">"OK"</string>
diff --git a/res/values-hy-rAM/strings.xml b/res/values-hy-rAM/strings.xml
index ab7388a..1faae76 100644
--- a/res/values-hy-rAM/strings.xml
+++ b/res/values-hy-rAM/strings.xml
@@ -23,18 +23,6 @@
     <string name="home" msgid="7658288663002113681">"Հիմնական"</string>
     <string name="uid_name" msgid="7820867637514617527">"Android Core Apps"</string>
     <string name="folder_name" msgid="7371454440695724752"></string>
-    <string name="wallpaper_instructions" msgid="563973358787555519">"Սահմանել պաստառը"</string>
-  <plurals name="number_of_items_selected">
-    <item quantity="zero" msgid="7464587177007785408">"%1$d ընտրված"</item>
-    <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>
-    <string name="crop_wallpaper" msgid="8334345984491368009">"Եզրատել պաստառը"</string>
     <string name="activity_not_found" msgid="8071924732094499514">"Ծրագիրը տեղադրված չէ:"</string>
     <string name="widgets_tab_label" msgid="2921133187116603919">"Վիջեթներ"</string>
     <string name="widget_adder" msgid="3201040140710381657">"Վիջեթներ"</string>
@@ -54,8 +42,8 @@
     <string name="group_widgets" msgid="1569030723286851002">"Վիջեթներ"</string>
     <string name="completely_out_of_space" msgid="6106288382070760318">"Այլևս տեղ չկա ձեր հիմնական էկրաններին:"</string>
     <string name="out_of_space" msgid="4691004494942118364">"Այլևս տեղ չկա այս հիմնական էկրանին:"</string>
-    <string name="hotseat_out_of_space" msgid="9139760413395605841">"Թեժ նստատեղերում այլևս տեղ չկա:"</string>
-    <string name="invalid_hotseat_item" msgid="1211534262129849507">"Այս վիջեթը չափազանց մեծ է թեժ նստատեղերի համար:"</string>
+    <string name="hotseat_out_of_space" msgid="7448809638125333693">"Ընտրյալների ցուցակում այլևս ազատ տեղ չկա"</string>
+    <string name="invalid_hotseat_item" msgid="5779907847267573691">"Այս վիջեթը շատ մեծ է Ընտրյալների ցուցակի համար"</string>
     <string name="shortcut_installed" msgid="1701742129426969556">"«<xliff:g id="NAME">%s</xliff:g>» դյուրանցումը ստեղծված է:"</string>
     <string name="shortcut_uninstalled" msgid="8176767991305701821">"«<xliff:g id="NAME">%s</xliff:g>» դյուրանցումը հեռացվեց:"</string>
     <string name="shortcut_duplicate" msgid="9167217446062498127">"«<xliff:g id="NAME">%s</xliff:g>» դյուրանցումն արդեն գոյություն ունի:"</string>
@@ -96,15 +84,17 @@
     <string name="workspace_scroll_format" msgid="8458889198184077399">"Հիմնական էկրան %1$d` %2$d-ից"</string>
     <string name="apps_customize_apps_scroll_format" msgid="370005296147130238">"Ծրագրերի էջերը՝ %1$d %2$d-ից"</string>
     <string name="apps_customize_widgets_scroll_format" msgid="3106209519974971521">"Վիջեթների էջերը՝ %1$d %2$d-ից"</string>
-    <string name="first_run_cling_title" msgid="7257389003637362144">"Բարի գալուստ:"</string>
+    <string name="first_run_cling_title" msgid="2459738000155917941">"Բարի գալուստ"</string>
     <string name="first_run_cling_description" msgid="6447072552696253358">"Զգացեք ձեզ ինչպես տանը:"</string>
     <string name="first_run_cling_custom_content_hint" msgid="6090628589029352439"></string>
     <string name="first_run_cling_search_bar_hint" msgid="5909062802402452582"></string>
     <string name="first_run_cling_create_screens_hint" msgid="6950729526680114157">"Ստեղծեք նոր էկրաններ ծրագրերի և թղթապանակների համար"</string>
+    <string name="migration_cling_title" msgid="9181776667882933767">"Պատճենել ձեր ծրագրի պատկերակները"</string>
+    <string name="migration_cling_description" msgid="2752413805582227644">"Ներմուծե՞լ պատկերակները և թղթապանակները ձեր նախկին Հիմնական էկրանից"</string>
+    <string name="migration_cling_copy_apps" msgid="946331230090919440">"ՊԱՏՃԵՆԵԼ ՊԱՏԿԵՐԱԿՆԵՐԸ"</string>
+    <string name="migration_cling_use_default" msgid="2626475813981258626">"ՄԵԿՆԱՐԿԵԼ ԸՍՏ ԿԱՆԽԱԴՐՎԱԾԻ"</string>
     <string name="workspace_cling_title" msgid="5626202359865825661">"Կառավարեք ձեր տարածությունը"</string>
     <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_create_folder" msgid="6158215559475836131">"Նման թղթապանակ ստեղծելու համար հպեք և պահեք որևէ ծրագրի վրա, ապա տեղաշարժեք այն մեկ ուրիշ ծրագրի վրա:"</string>
     <string name="cling_dismiss" msgid="8962359497601507581">"Լավ"</string>
diff --git a/res/values-in/strings.xml b/res/values-in/strings.xml
index e1e93f7..732dd45 100644
--- a/res/values-in/strings.xml
+++ b/res/values-in/strings.xml
@@ -23,18 +23,6 @@
     <string name="home" msgid="7658288663002113681">"Layar Utama"</string>
     <string name="uid_name" msgid="7820867637514617527">"Aplikasi Inti Android"</string>
     <string name="folder_name" msgid="7371454440695724752"></string>
-    <string name="wallpaper_instructions" msgid="563973358787555519">"Setel wallpaper"</string>
-  <plurals name="number_of_items_selected">
-    <item quantity="zero" msgid="7464587177007785408">"%1$d dipilih"</item>
-    <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>
-    <string name="crop_wallpaper" msgid="8334345984491368009">"Pangkas wallpaper"</string>
     <string name="activity_not_found" msgid="8071924732094499514">"Aplikasi tidak dipasang."</string>
     <string name="widgets_tab_label" msgid="2921133187116603919">"Widget"</string>
     <string name="widget_adder" msgid="3201040140710381657">"Widget"</string>
@@ -54,8 +42,8 @@
     <string name="group_widgets" msgid="1569030723286851002">"Widget"</string>
     <string name="completely_out_of_space" msgid="6106288382070760318">"Tidak ada ruang lagi di layar Utama Anda."</string>
     <string name="out_of_space" msgid="4691004494942118364">"Tidak ada ruang lagi pada layar Utama ini."</string>
-    <string name="hotseat_out_of_space" msgid="9139760413395605841">"Tidak ada ruang lagi di hotseat."</string>
-    <string name="invalid_hotseat_item" msgid="1211534262129849507">"Widget ini terlalu besar untuk hotseat tersebut."</string>
+    <string name="hotseat_out_of_space" msgid="7448809638125333693">"Tidak ada ruang tersisa di baki Favorit"</string>
+    <string name="invalid_hotseat_item" msgid="5779907847267573691">"Widget ini terlalu besar untuk baki Favorit"</string>
     <string name="shortcut_installed" msgid="1701742129426969556">"Pintasan \"<xliff:g id="NAME">%s</xliff:g>\" sudah dibuat."</string>
     <string name="shortcut_uninstalled" msgid="8176767991305701821">"Pintasan \"<xliff:g id="NAME">%s</xliff:g>\" telah dihapus."</string>
     <string name="shortcut_duplicate" msgid="9167217446062498127">"Pintasan \"<xliff:g id="NAME">%s</xliff:g>\" sudah ada."</string>
@@ -96,15 +84,17 @@
     <string name="workspace_scroll_format" msgid="8458889198184077399">"Layar utama %1$d dari %2$d"</string>
     <string name="apps_customize_apps_scroll_format" msgid="370005296147130238">"Laman aplikasi %1$d dari %2$d"</string>
     <string name="apps_customize_widgets_scroll_format" msgid="3106209519974971521">"Laman widget %1$d dari %2$d"</string>
-    <string name="first_run_cling_title" msgid="7257389003637362144">"Selamat datang!"</string>
+    <string name="first_run_cling_title" msgid="2459738000155917941">"Selamat Datang"</string>
     <string name="first_run_cling_description" msgid="6447072552696253358">"Serasa di rumah sendiri."</string>
     <string name="first_run_cling_custom_content_hint" msgid="6090628589029352439"></string>
     <string name="first_run_cling_search_bar_hint" msgid="5909062802402452582"></string>
     <string name="first_run_cling_create_screens_hint" msgid="6950729526680114157">"Buat lebih banyak layar untuk aplikasi dan folder"</string>
+    <string name="migration_cling_title" msgid="9181776667882933767">"Salin ikon aplikasi Anda"</string>
+    <string name="migration_cling_description" msgid="2752413805582227644">"Impor ikon dan folder dari layar Utama lama Anda?"</string>
+    <string name="migration_cling_copy_apps" msgid="946331230090919440">"IKON SALIN"</string>
+    <string name="migration_cling_use_default" msgid="2626475813981258626">"MULAI DARI AWAL"</string>
     <string name="workspace_cling_title" msgid="5626202359865825661">"Kelola ruang Anda"</string>
     <string name="workspace_cling_move_item" msgid="528201129978005352">"Sentuh lama latar belakang untuk mengelola wallpaper, widget, dan setelan."</string>
-    <string name="all_apps_cling_title" msgid="34929250753095858">"Pilih beberapa aplikasi"</string>
-    <string name="all_apps_cling_add_item" msgid="400866858451850784">"Untuk menambah aplikasi ke layar Utama Anda, sentuh lama aplikasi tersebut."</string>
     <string name="folder_cling_title" msgid="3894908818693254164">"Ini adalah folder"</string>
     <string name="folder_cling_create_folder" msgid="6158215559475836131">"Untuk membuat seperti yang ini, sentuh lama aplikasi, lalu pindahkan ke atas aplikasi lain."</string>
     <string name="cling_dismiss" msgid="8962359497601507581">"Oke"</string>
diff --git a/res/values-it/strings.xml b/res/values-it/strings.xml
index d5ada8f..f379ae7 100644
--- a/res/values-it/strings.xml
+++ b/res/values-it/strings.xml
@@ -23,18 +23,6 @@
     <string name="home" msgid="7658288663002113681">"Home page"</string>
     <string name="uid_name" msgid="7820867637514617527">"Applicazioni di base Android"</string>
     <string name="folder_name" msgid="7371454440695724752"></string>
-    <string name="wallpaper_instructions" msgid="563973358787555519">"Imposta sfondo"</string>
-  <plurals name="number_of_items_selected">
-    <item quantity="zero" msgid="7464587177007785408">"%1$d selezionati"</item>
-    <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>
-    <string name="crop_wallpaper" msgid="8334345984491368009">"Ritaglia sfondo"</string>
     <string name="activity_not_found" msgid="8071924732094499514">"App non installata."</string>
     <string name="widgets_tab_label" msgid="2921133187116603919">"Widget"</string>
     <string name="widget_adder" msgid="3201040140710381657">"Widget"</string>
@@ -54,8 +42,8 @@
     <string name="group_widgets" msgid="1569030723286851002">"Widget"</string>
     <string name="completely_out_of_space" msgid="6106288382070760318">"Spazio nelle schermate Home esaurito."</string>
     <string name="out_of_space" msgid="4691004494942118364">"Spazio nella schermata Home esaurito."</string>
-    <string name="hotseat_out_of_space" msgid="9139760413395605841">"Spazio nell\'area hotseat esaurito."</string>
-    <string name="invalid_hotseat_item" msgid="1211534262129849507">"Questo widget è troppo grande per l\'area hotseat."</string>
+    <string name="hotseat_out_of_space" msgid="7448809638125333693">"Spazio esaurito nella barra dei Preferiti"</string>
+    <string name="invalid_hotseat_item" msgid="5779907847267573691">"Questo widget è troppo grande per la barra dei Preferiti"</string>
     <string name="shortcut_installed" msgid="1701742129426969556">"Scorciatoia \"<xliff:g id="NAME">%s</xliff:g>\" creata."</string>
     <string name="shortcut_uninstalled" msgid="8176767991305701821">"La scorciatoia \"<xliff:g id="NAME">%s</xliff:g>\" è stata rimossa."</string>
     <string name="shortcut_duplicate" msgid="9167217446062498127">"Scorciatoia \"<xliff:g id="NAME">%s</xliff:g>\" già presente."</string>
@@ -96,15 +84,17 @@
     <string name="workspace_scroll_format" msgid="8458889198184077399">"Schermata Home %1$d di %2$d"</string>
     <string name="apps_customize_apps_scroll_format" msgid="370005296147130238">"Pagina di applicazioni %1$d di %2$d"</string>
     <string name="apps_customize_widgets_scroll_format" msgid="3106209519974971521">"Pagina di widget %1$d di %2$d"</string>
-    <string name="first_run_cling_title" msgid="7257389003637362144">"Benvenuto!"</string>
+    <string name="first_run_cling_title" msgid="2459738000155917941">"Benvenuto"</string>
     <string name="first_run_cling_description" msgid="6447072552696253358">"Personalizza la schermata Home."</string>
     <string name="first_run_cling_custom_content_hint" msgid="6090628589029352439"></string>
     <string name="first_run_cling_search_bar_hint" msgid="5909062802402452582"></string>
     <string name="first_run_cling_create_screens_hint" msgid="6950729526680114157">"Creare più schermate per app e cartelle"</string>
+    <string name="migration_cling_title" msgid="9181776667882933767">"Copia le icone delle tue app"</string>
+    <string name="migration_cling_description" msgid="2752413805582227644">"Importare icone e cartelle dalle schermate Home precedenti?"</string>
+    <string name="migration_cling_copy_apps" msgid="946331230090919440">"COPIA ICONE"</string>
+    <string name="migration_cling_use_default" msgid="2626475813981258626">"RICOMINCIA"</string>
     <string name="workspace_cling_title" msgid="5626202359865825661">"Organizza il tuo spazio"</string>
     <string name="workspace_cling_move_item" msgid="528201129978005352">"Tocca e tieni premuto lo sfondo per gestire sfondi, widget e impostazioni."</string>
-    <string name="all_apps_cling_title" msgid="34929250753095858">"Scegli alcune applicazioni"</string>
-    <string name="all_apps_cling_add_item" msgid="400866858451850784">"Per aggiungere un\'app alla schermata Home, tocca e tieni premuto."</string>
     <string name="folder_cling_title" msgid="3894908818693254164">"Ecco una cartella"</string>
     <string name="folder_cling_create_folder" msgid="6158215559475836131">"Per crearne una simile, tocca un\'app e tieni premuto, dopodiché spostala sopra un\'altra."</string>
     <string name="cling_dismiss" msgid="8962359497601507581">"OK"</string>
diff --git a/res/values-iw/strings.xml b/res/values-iw/strings.xml
index 562ce4f..af853a8 100644
--- a/res/values-iw/strings.xml
+++ b/res/values-iw/strings.xml
@@ -23,18 +23,6 @@
     <string name="home" msgid="7658288663002113681">"דף הבית"</string>
     <string name="uid_name" msgid="7820867637514617527">"‏אפליקציות הליבה של Android"</string>
     <string name="folder_name" msgid="7371454440695724752"></string>
-    <string name="wallpaper_instructions" msgid="563973358787555519">"בחר טפט"</string>
-  <plurals name="number_of_items_selected">
-    <item quantity="zero" msgid="7464587177007785408">"‏%1$d נבחרו"</item>
-    <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>
-    <string name="crop_wallpaper" msgid="8334345984491368009">"חתוך את הטפט"</string>
     <string name="activity_not_found" msgid="8071924732094499514">"האפליקציה לא מותקנת."</string>
     <string name="widgets_tab_label" msgid="2921133187116603919">"רכיבי ווידג\'ט"</string>
     <string name="widget_adder" msgid="3201040140710381657">"רכיבי ווידג\'ט"</string>
@@ -54,8 +42,8 @@
     <string name="group_widgets" msgid="1569030723286851002">"רכיבי ווידג\'ט"</string>
     <string name="completely_out_of_space" msgid="6106288382070760318">"אין יותר מקום במסכי דף הבית."</string>
     <string name="out_of_space" msgid="4691004494942118364">"אין עוד מקום במסך דף הבית הזה."</string>
-    <string name="hotseat_out_of_space" msgid="9139760413395605841">"אין יותר מקום בפס האפליקציות."</string>
-    <string name="invalid_hotseat_item" msgid="1211534262129849507">"הווידג\'ט הזה גדול מדי עבור פס האפליקציות."</string>
+    <string name="hotseat_out_of_space" msgid="7448809638125333693">"אין עוד מקום במגש המועדפים"</string>
+    <string name="invalid_hotseat_item" msgid="5779907847267573691">"הווידג\'ט הזה גדול מדי עבור מגש המועדפים."</string>
     <string name="shortcut_installed" msgid="1701742129426969556">"קיצור הדרך \'<xliff:g id="NAME">%s</xliff:g>\' נוצר."</string>
     <string name="shortcut_uninstalled" msgid="8176767991305701821">"קיצור הדרך \'<xliff:g id="NAME">%s</xliff:g>\' הוסר."</string>
     <string name="shortcut_duplicate" msgid="9167217446062498127">"קיצור הדרך \'<xliff:g id="NAME">%s</xliff:g>\' כבר קיים."</string>
@@ -96,15 +84,17 @@
     <string name="workspace_scroll_format" msgid="8458889198184077399">"‏מסך דף הבית %1$d מתוך %2$d"</string>
     <string name="apps_customize_apps_scroll_format" msgid="370005296147130238">"‏דף אפליקציות %1$d מתוך %2$d"</string>
     <string name="apps_customize_widgets_scroll_format" msgid="3106209519974971521">"‏דף רכיבי ווידג\'ט ‏%1$d מתוך %2$d"</string>
-    <string name="first_run_cling_title" msgid="7257389003637362144">"ברוך הבא!"</string>
+    <string name="first_run_cling_title" msgid="2459738000155917941">"ברוכים הבאים"</string>
     <string name="first_run_cling_description" msgid="6447072552696253358">"להרגיש בבית."</string>
     <string name="first_run_cling_custom_content_hint" msgid="6090628589029352439"></string>
     <string name="first_run_cling_search_bar_hint" msgid="5909062802402452582"></string>
     <string name="first_run_cling_create_screens_hint" msgid="6950729526680114157">"צור מסכים נוספים עבור אפליקציות ותיקיות"</string>
+    <string name="migration_cling_title" msgid="9181776667882933767">"העתקת סמלי האפליקציות שלך"</string>
+    <string name="migration_cling_description" msgid="2752413805582227644">"האם לייבא סמלים ותיקיות ממסכי דף הבית הישנים שלך?"</string>
+    <string name="migration_cling_copy_apps" msgid="946331230090919440">"העתק סמלים"</string>
+    <string name="migration_cling_use_default" msgid="2626475813981258626">"התחל דף חדש"</string>
     <string name="workspace_cling_title" msgid="5626202359865825661">"ארגן את אזור העבודה שלך"</string>
     <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_create_folder" msgid="6158215559475836131">"כדי ליצור תיקייה כזו, גע נגיעה רציפה באפליקציה, ולאחר מכן גרור ושחרר אותו על-גבי אפליקציה אחרת."</string>
     <string name="cling_dismiss" msgid="8962359497601507581">"אישור"</string>
diff --git a/res/values-ja/strings.xml b/res/values-ja/strings.xml
index 6e39c54..b396893 100644
--- a/res/values-ja/strings.xml
+++ b/res/values-ja/strings.xml
@@ -23,18 +23,6 @@
     <string name="home" msgid="7658288663002113681">"ホーム"</string>
     <string name="uid_name" msgid="7820867637514617527">"Android Core Apps"</string>
     <string name="folder_name" msgid="7371454440695724752"></string>
-    <string name="wallpaper_instructions" msgid="563973358787555519">"壁紙を設定"</string>
-  <plurals name="number_of_items_selected">
-    <item quantity="zero" msgid="7464587177007785408">"%1$d件選択済み"</item>
-    <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>
-    <string name="crop_wallpaper" msgid="8334345984491368009">"壁紙をトリミング"</string>
     <string name="activity_not_found" msgid="8071924732094499514">"このアプリはインストールされていません。"</string>
     <string name="widgets_tab_label" msgid="2921133187116603919">"ウィジェット"</string>
     <string name="widget_adder" msgid="3201040140710381657">"ウィジェット"</string>
@@ -54,8 +42,8 @@
     <string name="group_widgets" msgid="1569030723286851002">"ウィジェット"</string>
     <string name="completely_out_of_space" msgid="6106288382070760318">"ホーム画面に空きスペースがありません。"</string>
     <string name="out_of_space" msgid="4691004494942118364">"このホーム画面に空きスペースがありません。"</string>
-    <string name="hotseat_out_of_space" msgid="9139760413395605841">"ホットシートに空きスペースがありません。"</string>
-    <string name="invalid_hotseat_item" msgid="1211534262129849507">"このウィジェットはホットシートには大きすぎます。"</string>
+    <string name="hotseat_out_of_space" msgid="7448809638125333693">"お気に入りトレイに空きスペースがありません"</string>
+    <string name="invalid_hotseat_item" msgid="5779907847267573691">"このウィジェットはお気に入りトレイには大きすぎます"</string>
     <string name="shortcut_installed" msgid="1701742129426969556">"ショートカット「<xliff:g id="NAME">%s</xliff:g>」を作成しました。"</string>
     <string name="shortcut_uninstalled" msgid="8176767991305701821">"ショートカット「<xliff:g id="NAME">%s</xliff:g>」を削除しました。"</string>
     <string name="shortcut_duplicate" msgid="9167217446062498127">"ショートカット「<xliff:g id="NAME">%s</xliff:g>」は既に存在します。"</string>
@@ -96,15 +84,17 @@
     <string name="workspace_scroll_format" msgid="8458889198184077399">"ホーム画面: %1$d/%2$d"</string>
     <string name="apps_customize_apps_scroll_format" msgid="370005296147130238">"アプリの%1$d/%2$dページ"</string>
     <string name="apps_customize_widgets_scroll_format" msgid="3106209519974971521">"ウィジェットの%1$d/%2$dページ"</string>
-    <string name="first_run_cling_title" msgid="7257389003637362144">"ようこそ!"</string>
+    <string name="first_run_cling_title" msgid="2459738000155917941">"ようこそ"</string>
     <string name="first_run_cling_description" msgid="6447072552696253358">"ホームをカスタマイズします。"</string>
     <string name="first_run_cling_custom_content_hint" msgid="6090628589029352439"></string>
     <string name="first_run_cling_search_bar_hint" msgid="5909062802402452582"></string>
     <string name="first_run_cling_create_screens_hint" msgid="6950729526680114157">"アプリとフォルダの画面をもっと作成します"</string>
+    <string name="migration_cling_title" msgid="9181776667882933767">"アプリのアイコンをコピー"</string>
+    <string name="migration_cling_description" msgid="2752413805582227644">"古いホーム画面からアイコンとフォルダをインポートしますか?"</string>
+    <string name="migration_cling_copy_apps" msgid="946331230090919440">"アイコンをコピー"</string>
+    <string name="migration_cling_use_default" msgid="2626475813981258626">"初期状態にリセットする"</string>
     <string name="workspace_cling_title" msgid="5626202359865825661">"スペースを整理"</string>
     <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_create_folder" msgid="6158215559475836131">"これと同じフォルダを作成するには、アプリを押し続けてから別のアプリの上に移動します。"</string>
     <string name="cling_dismiss" msgid="8962359497601507581">"OK"</string>
diff --git a/res/values-ka-rGE/strings.xml b/res/values-ka-rGE/strings.xml
index a2e3374..4c53cc8 100644
--- a/res/values-ka-rGE/strings.xml
+++ b/res/values-ka-rGE/strings.xml
@@ -23,18 +23,6 @@
     <string name="home" msgid="7658288663002113681">"მთავარი"</string>
     <string name="uid_name" msgid="7820867637514617527">"Android-ის ბირთვის აპები"</string>
     <string name="folder_name" msgid="7371454440695724752"></string>
-    <string name="wallpaper_instructions" msgid="563973358787555519">"ფონის დაყენება"</string>
-  <plurals name="number_of_items_selected">
-    <item quantity="zero" msgid="7464587177007785408">"არჩეულია %1$d"</item>
-    <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>
-    <string name="crop_wallpaper" msgid="8334345984491368009">"ფონის ჩამოჭრა"</string>
     <string name="activity_not_found" msgid="8071924732094499514">"აპი არ არის დაყენებული."</string>
     <string name="widgets_tab_label" msgid="2921133187116603919">"ვიჯეტები"</string>
     <string name="widget_adder" msgid="3201040140710381657">"ვიჯეტები"</string>
@@ -54,8 +42,8 @@
     <string name="group_widgets" msgid="1569030723286851002">"ვიჯეტები"</string>
     <string name="completely_out_of_space" msgid="6106288382070760318">"მთავარ ეკრანებზე ადგილი აღარ არის."</string>
     <string name="out_of_space" msgid="4691004494942118364">"ამ მთავარ ეკრანზე ადგილი აღარ არის."</string>
-    <string name="hotseat_out_of_space" msgid="9139760413395605841">"hotseat-ში მეტი ადგილი არ არის."</string>
-    <string name="invalid_hotseat_item" msgid="1211534262129849507">"ეს ვიჯეტი ძალიან დიდია hotseat-ისთვის."</string>
+    <string name="hotseat_out_of_space" msgid="7448809638125333693">"რჩეულების თაროზე ადგილი არ არის"</string>
+    <string name="invalid_hotseat_item" msgid="5779907847267573691">"ეს ვიჯეტი ძალიან დიდია რჩეულების თაროსთვის"</string>
     <string name="shortcut_installed" msgid="1701742129426969556">"შეიქმნა მალსახმობი „<xliff:g id="NAME">%s</xliff:g>“."</string>
     <string name="shortcut_uninstalled" msgid="8176767991305701821">"მასლახმობი „<xliff:g id="NAME">%s</xliff:g>“ წაშლილია."</string>
     <string name="shortcut_duplicate" msgid="9167217446062498127">"მალსახმობი „<xliff:g id="NAME">%s</xliff:g>“ უკვე არსებობს."</string>
@@ -96,15 +84,17 @@
     <string name="workspace_scroll_format" msgid="8458889198184077399">"მთავარი ეკრანი %1$d, %2$d-დან"</string>
     <string name="apps_customize_apps_scroll_format" msgid="370005296147130238">"აპების გვერდი %1$d, %2$d-დან"</string>
     <string name="apps_customize_widgets_scroll_format" msgid="3106209519974971521">"ვიჯეტების გვერდი %1$d, %2$d-დან"</string>
-    <string name="first_run_cling_title" msgid="7257389003637362144">"კეთილი იყოს თქვენი მობრძანება!"</string>
+    <string name="first_run_cling_title" msgid="2459738000155917941">"მოგესალმებით"</string>
     <string name="first_run_cling_description" msgid="6447072552696253358">"იგრძენით თავი საკუთარ სახლში"</string>
     <string name="first_run_cling_custom_content_hint" msgid="6090628589029352439"></string>
     <string name="first_run_cling_search_bar_hint" msgid="5909062802402452582"></string>
     <string name="first_run_cling_create_screens_hint" msgid="6950729526680114157">"აპებისა და საქაღალდეებისთვის კიდევ ერთი ეკრანის შექმნა"</string>
+    <string name="migration_cling_title" msgid="9181776667882933767">"თქვენი აპის ხატულების კოპირება"</string>
+    <string name="migration_cling_description" msgid="2752413805582227644">"გსურთ, ძველი მთავარი ეკრანიდან ხატულების და საქაღ. იმპორტი?"</string>
+    <string name="migration_cling_copy_apps" msgid="946331230090919440">"ხატულების კოპირება"</string>
+    <string name="migration_cling_use_default" msgid="2626475813981258626">"სტანდარტული განლაგება"</string>
     <string name="workspace_cling_title" msgid="5626202359865825661">"თქვენი სივრცის ორგანიზება"</string>
     <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_create_folder" msgid="6158215559475836131">"ასეთის შესაქმნელად, შეეხეთ და დააყოვნეთ აპზე, ხოლო შემდეგ გადააჩოჩეთ შემდეგზე."</string>
     <string name="cling_dismiss" msgid="8962359497601507581">"კარგი"</string>
diff --git a/res/values-km-rKH/strings.xml b/res/values-km-rKH/strings.xml
index 977b2dd..eb30a16 100644
--- a/res/values-km-rKH/strings.xml
+++ b/res/values-km-rKH/strings.xml
@@ -23,18 +23,6 @@
     <string name="home" msgid="7658288663002113681">"ដើម"</string>
     <string name="uid_name" msgid="7820867637514617527">"កម្មវិធី​​សំខាន់​ៗ​របស់ Android"</string>
     <string name="folder_name" msgid="7371454440695724752"></string>
-    <string name="wallpaper_instructions" msgid="563973358787555519">"កំណត់​ផ្ទាំង​រូបភាព"</string>
-  <plurals name="number_of_items_selected">
-    <item quantity="zero" msgid="7464587177007785408">"បាន​ជ្រើស %1$d"</item>
-    <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>
-    <string name="crop_wallpaper" msgid="8334345984491368009">"ច្រឹប​ផ្ទាំង​រូបភាព"</string>
     <string name="activity_not_found" msgid="8071924732094499514">"មិន​បាន​ដំឡើង​កម្មវិធី។"</string>
     <string name="widgets_tab_label" msgid="2921133187116603919">"ធាតុ​ក្រាហ្វិក"</string>
     <string name="widget_adder" msgid="3201040140710381657">"ធាតុ​ក្រាហ្វិក"</string>
@@ -54,8 +42,8 @@
     <string name="group_widgets" msgid="1569030723286851002">"ធាតុ​ក្រាហ្វិក"</string>
     <string name="completely_out_of_space" msgid="6106288382070760318">"គ្មាន​បន្ទប់​នៅ​លើ​អេក្រង់​ដើម​រស់​អ្នក​ទៀត​ទេ។"</string>
     <string name="out_of_space" msgid="4691004494942118364">"គ្មាន​បន្ទប់​នៅ​លើ​អេក្រង់​ដើម​នេះ​ទៀត​ទេ។"</string>
-    <string name="hotseat_out_of_space" msgid="9139760413395605841">"គ្មាន​បន្ទប់​នៅ​ក្នុង​មជ្ឈមណ្ឌល​ទៀត​ទេ។"</string>
-    <string name="invalid_hotseat_item" msgid="1211534262129849507">"ធាតុ​ក្រាហ្វិក​នេះ​ធំ​ពេក​សម្រាប់​មជ្ឈមណ្ឌល។"</string>
+    <string name="hotseat_out_of_space" msgid="7448809638125333693">"គ្មាន​បន្ទប់​​ក្នុង​ថាស​និយម​ប្រើ"</string>
+    <string name="invalid_hotseat_item" msgid="5779907847267573691">"ធាតុ​ក្រាហ្វិក​នេះ​ធំ​ពេក​សម្រាប់​ថាស​និយម​ប្រើ"</string>
     <string name="shortcut_installed" msgid="1701742129426969556">"បាន​បង្កើត​ផ្លូវកាត់ \"<xliff:g id="NAME">%s</xliff:g>\" ។"</string>
     <string name="shortcut_uninstalled" msgid="8176767991305701821">"បាន​លុប​ផ្លូវកាត់ \"<xliff:g id="NAME">%s</xliff:g>\" ។"</string>
     <string name="shortcut_duplicate" msgid="9167217446062498127">"មាន​ផ្លូវកាត់ \"<xliff:g id="NAME">%s</xliff:g>\" រួច​ហើយ។"</string>
@@ -96,15 +84,17 @@
     <string name="workspace_scroll_format" msgid="8458889198184077399">"អេក្រង់​ដើម %1$d នៃ %2$d"</string>
     <string name="apps_customize_apps_scroll_format" msgid="370005296147130238">"ទំព័រ​កម្មវិធី %1$d នៃ %2$d"</string>
     <string name="apps_customize_widgets_scroll_format" msgid="3106209519974971521">"ទំព័រ​ធាតុ​ក្រាហ្វិក ​%1$d នៃ %2$d"</string>
-    <string name="first_run_cling_title" msgid="7257389003637362144">"សូម​ស្វាគមន៍​!"</string>
+    <string name="first_run_cling_title" msgid="2459738000155917941">"សូម​ស្វាគមន៍"</string>
     <string name="first_run_cling_description" msgid="6447072552696253358">"ធ្វើ​ដោយ​ខ្លួន​ឯង​នៅ​លើ​អេក្រង់​ដើម។"</string>
     <string name="first_run_cling_custom_content_hint" msgid="6090628589029352439"></string>
     <string name="first_run_cling_search_bar_hint" msgid="5909062802402452582"></string>
     <string name="first_run_cling_create_screens_hint" msgid="6950729526680114157">"បង្កើត​អេក្រង់​ច្រើន​សម្រាប់​កម្មវិធី​ ​និង​ថតឯកសារ"</string>
+    <string name="migration_cling_title" msgid="9181776667882933767">"ចម្លង​រូបតំណាង​កម្មវិធី​របស់​អ្នក"</string>
+    <string name="migration_cling_description" msgid="2752413805582227644">"នាំចូល​រូបតំណាង និង​ថត​ពី​អេក្រង់​ដើម​ចាស់​របស់​អ្នក?"</string>
+    <string name="migration_cling_copy_apps" msgid="946331230090919440">"រូប​តំណាង​ច្បាប់​ចម្លង"</string>
+    <string name="migration_cling_use_default" msgid="2626475813981258626">"ចាប់ផ្ដើម​ធ្វើ​ឲ្យ​ស្រស់"</string>
     <string name="workspace_cling_title" msgid="5626202359865825661">"រៀបចំ​ចន្លោះ​របស់​អ្នក"</string>
     <string name="workspace_cling_move_item" msgid="528201129978005352">"ប៉ះ &amp; សង្កត់​លើ​ផ្ទៃ​ខាង​ក្រោម ដើម្បី​គ្រប់គ្រង​ផ្ទាំង​រូបភាព, ធាតុ​ក្រាហ្វិក និង​ការ​កំណត់។"</string>
-    <string name="all_apps_cling_title" msgid="34929250753095858">"ជ្រើស​កម្មវិធី​មួយ​ចំនួន"</string>
-    <string name="all_apps_cling_add_item" msgid="400866858451850784">"ប៉ះ​ &amp; សង្កត់​វា ដើម្បី​បន្ថែម​កម្មវិធី​ទៅ​​​អេក្រង់​ដើម​របស់​អ្នក"</string>
     <string name="folder_cling_title" msgid="3894908818693254164">"នេះ​ជា​ថត"</string>
     <string name="folder_cling_create_folder" msgid="6158215559475836131">"ដើម្បី​បង្កើត​មួយ​ដូច​នេះ ប៉ះ &amp; សង្កត់​​លើ​កម្មវិធី បន្ទាប់​មក​ផ្លាស់ទី​វា​ទៅ​លើ​ធាតុ​មួយ​ផ្សេង​ទៀត។"</string>
     <string name="cling_dismiss" msgid="8962359497601507581">"យល់ព្រម"</string>
diff --git a/res/values-ko/strings.xml b/res/values-ko/strings.xml
index 31c2d69..656c972 100644
--- a/res/values-ko/strings.xml
+++ b/res/values-ko/strings.xml
@@ -23,18 +23,6 @@
     <string name="home" msgid="7658288663002113681">"홈"</string>
     <string name="uid_name" msgid="7820867637514617527">"Android 핵심 앱"</string>
     <string name="folder_name" msgid="7371454440695724752"></string>
-    <string name="wallpaper_instructions" msgid="563973358787555519">"배경화면 설정"</string>
-  <plurals name="number_of_items_selected">
-    <item quantity="zero" msgid="7464587177007785408">"%1$d개 선택됨"</item>
-    <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>
-    <string name="crop_wallpaper" msgid="8334345984491368009">"배경화면 잘라내기"</string>
     <string name="activity_not_found" msgid="8071924732094499514">"앱이 설치되지 않았습니다."</string>
     <string name="widgets_tab_label" msgid="2921133187116603919">"위젯"</string>
     <string name="widget_adder" msgid="3201040140710381657">"위젯"</string>
@@ -54,8 +42,8 @@
     <string name="group_widgets" msgid="1569030723286851002">"위젯"</string>
     <string name="completely_out_of_space" msgid="6106288382070760318">"홈 화면에 더 이상 공간이 없습니다."</string>
     <string name="out_of_space" msgid="4691004494942118364">"홈 화면에 더 이상 공간이 없습니다."</string>
-    <string name="hotseat_out_of_space" msgid="9139760413395605841">"즐겨찾는 앱 모음에 더 이상 빈 공간이 없습니다."</string>
-    <string name="invalid_hotseat_item" msgid="1211534262129849507">"이 위젯은 너무 커서 즐겨찾는 앱 모음에 들어갈 수 없습니다."</string>
+    <string name="hotseat_out_of_space" msgid="7448809638125333693">"즐겨찾기 트레이에 더 이상 공간이 없습니다."</string>
+    <string name="invalid_hotseat_item" msgid="5779907847267573691">"위젯이 너무 커서 즐겨찾기 트레이에 들어갈 수 없습니다."</string>
     <string name="shortcut_installed" msgid="1701742129426969556">"바로가기(\'<xliff:g id="NAME">%s</xliff:g>\')가 생성되었습니다."</string>
     <string name="shortcut_uninstalled" msgid="8176767991305701821">"바로가기(\'<xliff:g id="NAME">%s</xliff:g>\')가 삭제되었습니다."</string>
     <string name="shortcut_duplicate" msgid="9167217446062498127">"바로가기(\'<xliff:g id="NAME">%s</xliff:g>\')가 이미 있습니다."</string>
@@ -96,15 +84,17 @@
     <string name="workspace_scroll_format" msgid="8458889198184077399">"홈 화면 %1$d/%2$d"</string>
     <string name="apps_customize_apps_scroll_format" msgid="370005296147130238">"앱 페이지 %1$d/%2$d"</string>
     <string name="apps_customize_widgets_scroll_format" msgid="3106209519974971521">"위젯 페이지 %1$d/%2$d"</string>
-    <string name="first_run_cling_title" msgid="7257389003637362144">"환영합니다!"</string>
+    <string name="first_run_cling_title" msgid="2459738000155917941">"환영합니다."</string>
     <string name="first_run_cling_description" msgid="6447072552696253358">"편리한 사용 환경을 만드세요."</string>
     <string name="first_run_cling_custom_content_hint" msgid="6090628589029352439"></string>
     <string name="first_run_cling_search_bar_hint" msgid="5909062802402452582"></string>
     <string name="first_run_cling_create_screens_hint" msgid="6950729526680114157">"앱 및 폴더를 표시할 화면 더 만들기"</string>
+    <string name="migration_cling_title" msgid="9181776667882933767">"앱 아이콘 복사"</string>
+    <string name="migration_cling_description" msgid="2752413805582227644">"이전 메인 스크린에서 아이콘과 폴더를 가져오시겠습니까?"</string>
+    <string name="migration_cling_copy_apps" msgid="946331230090919440">"아이콘 복사"</string>
+    <string name="migration_cling_use_default" msgid="2626475813981258626">"새로 시작"</string>
     <string name="workspace_cling_title" msgid="5626202359865825661">"공간 관리하기"</string>
     <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_create_folder" msgid="6158215559475836131">"폴더를 만들려면 앱을 길게 터치한 다음 다른 앱 위에 올려 놓으세요."</string>
     <string name="cling_dismiss" msgid="8962359497601507581">"확인"</string>
diff --git a/res/values-land/config.xml b/res/values-land/config.xml
index 121bb0c..31115c9 100644
--- a/res/values-land/config.xml
+++ b/res/values-land/config.xml
@@ -18,6 +18,4 @@
 <!-- Workspace -->
     <!-- Whether or not the drop targets drop down as opposed to fade in -->
     <bool name="config_useDropTargetDownTransition">false</bool>
-    <!-- Whether or not to fade the side pages -->
-    <bool name="config_workspaceFadeAdjacentScreens">false</bool>
 </resources>
diff --git a/res/values-land/dimens.xml b/res/values-land/dimens.xml
index 5961b19..07d9279 100644
--- a/res/values-land/dimens.xml
+++ b/res/values-land/dimens.xml
@@ -19,11 +19,6 @@
     <dimen name="toolbar_button_vertical_padding">8dip</dimen>
     <dimen name="toolbar_button_horizontal_padding">0dip</dimen>
 
-<!-- Workspace -->
-    <!-- We really want the page spacing to be the max of either the button bar
-     height or the qsb bar height -->
-    <dimen name="workspace_page_spacing">-1dp</dimen>
-
 <!-- AppsCustomize -->
     <dimen name="apps_customize_tab_bar_height">42dp</dimen>
     <integer name="apps_customize_widget_cell_count_x">3</integer>
diff --git a/res/values-land/styles.xml b/res/values-land/styles.xml
index ccb5fcb..87a7444 100644
--- a/res/values-land/styles.xml
+++ b/res/values-land/styles.xml
@@ -19,15 +19,11 @@
 
 <resources>
 <!-- Search Bar -->
-    <style name="QSBBar">
-    </style>
-    <style name="SearchDropTargetBar">
-    </style>
     <style name="SearchButton">
     </style>
     <style name="DropTargetButtonContainer">
         <item name="android:layout_width">match_parent</item>
-        <item name="android:layout_height">0dp</item>
+        <item name="android:layout_height">wrap_content</item>
     </style>
     <style name="DropTargetButton">
         <item name="android:layout_width">wrap_content</item>
@@ -36,8 +32,8 @@
         <item name="android:gravity">center</item>
         <item name="android:paddingTop">@dimen/toolbar_button_vertical_padding</item>
         <item name="android:paddingBottom">@dimen/toolbar_button_vertical_padding</item>
-        <item name="android:paddingStart">@dimen/toolbar_button_horizontal_padding</item>
-        <item name="android:paddingEnd">@dimen/toolbar_button_horizontal_padding</item>
+        <item name="android:paddingLeft">@dimen/toolbar_button_horizontal_padding</item>
+        <item name="android:paddingRight">@dimen/toolbar_button_horizontal_padding</item>
         <item name="android:shadowColor">#DD000000</item>
         <item name="android:shadowDx">0.0</item>
         <item name="android:shadowDy">1.0</item>
diff --git a/res/values-lo-rLA/strings.xml b/res/values-lo-rLA/strings.xml
index e3a95dd..79a0a4a 100644
--- a/res/values-lo-rLA/strings.xml
+++ b/res/values-lo-rLA/strings.xml
@@ -23,18 +23,6 @@
     <string name="home" msgid="7658288663002113681">"ໜ້າຫຼັກ"</string>
     <string name="uid_name" msgid="7820867637514617527">"ແອັບພລິເຄຊັນຫຼັກຂອງ Android"</string>
     <string name="folder_name" msgid="7371454440695724752"></string>
-    <string name="wallpaper_instructions" msgid="563973358787555519">"ຕັ້ງເປັນພາບພື້ນຫຼັງ"</string>
-  <plurals name="number_of_items_selected">
-    <item quantity="zero" msgid="7464587177007785408">"ເລືອກ %1$d ລາຍການແລ້ວ"</item>
-    <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>
-    <string name="crop_wallpaper" msgid="8334345984491368009">"ຕັດຮູບພື້ນຫຼັງ"</string>
     <string name="activity_not_found" msgid="8071924732094499514">"ແອັບຯບໍ່ໄດ້ຖືກຕິດຕັ້ງ."</string>
     <string name="widgets_tab_label" msgid="2921133187116603919">"ວິດເຈັດ"</string>
     <string name="widget_adder" msgid="3201040140710381657">"ວິດເຈັດ"</string>
@@ -54,8 +42,8 @@
     <string name="group_widgets" msgid="1569030723286851002">"ວິດເຈັດ"</string>
     <string name="completely_out_of_space" msgid="6106288382070760318">"ບໍ່ມີຫ້ອງເຫຼືອໃນໜ້າຈໍຫຼັກຂອງທ່ານ."</string>
     <string name="out_of_space" msgid="4691004494942118364">"ບໍ່ມີຫ້ອງເຫຼືອໃນໜ້າຈໍຫຼັກນີ້."</string>
-    <string name="hotseat_out_of_space" msgid="9139760413395605841">"ບໍ່ມີຫ້ອງຫວ່າງໃນ hotseat ແລ້ວ."</string>
-    <string name="invalid_hotseat_item" msgid="1211534262129849507">"ວິດເຈັດ ມີຂະໜາດໃຫຍ່ເກີນໄປສຳລັບ hotseat."</string>
+    <string name="hotseat_out_of_space" msgid="7448809638125333693">"ບໍ່ມີບ່ອນຫວ່າງໃນຖາດສຳລັບເກັບສິ່ງທີ່ໃຊ້ເປັນປະຈຳ"</string>
+    <string name="invalid_hotseat_item" msgid="5779907847267573691">"ວິດເຈັດນີ້ໃຫຍ່ເກີນໄປທີ່ຈະເກັບໄວ້ໃນຖາດເກັບສິ່ງທີ່ໃຊ້ເປັນປະຈຳ"</string>
     <string name="shortcut_installed" msgid="1701742129426969556">"ທາງລັດ \"<xliff:g id="NAME">%s</xliff:g>\" ຖືກສ້າງແລ້ວ."</string>
     <string name="shortcut_uninstalled" msgid="8176767991305701821">"ທາງລັດ \"<xliff:g id="NAME">%s</xliff:g>\" ຖືກລຶບແລ້ວ."</string>
     <string name="shortcut_duplicate" msgid="9167217446062498127">"ທາງລັດ \"<xliff:g id="NAME">%s</xliff:g>\" ມີຢູ່ແລ້ວ."</string>
@@ -96,17 +84,19 @@
     <string name="workspace_scroll_format" msgid="8458889198184077399">"ໜ້າຈໍຫຼັກ %1$d ໃນ %2$d"</string>
     <string name="apps_customize_apps_scroll_format" msgid="370005296147130238">"ແອັບຯໜ້າ %1$d ໃນ %2$d"</string>
     <string name="apps_customize_widgets_scroll_format" msgid="3106209519974971521">"ວິດເຈັດໜ້າ %1$d ໃນ %2$d"</string>
-    <string name="first_run_cling_title" msgid="7257389003637362144">"ຍິນດີຕ້ອນຮັບ!"</string>
+    <string name="first_run_cling_title" msgid="2459738000155917941">"ຍິນດີຕ້ອນຮັບ"</string>
     <string name="first_run_cling_description" msgid="6447072552696253358">"ເຮັດໂຕໃຫ້ຄືຢູ່ໃນບ້ານ"</string>
     <string name="first_run_cling_custom_content_hint" msgid="6090628589029352439"></string>
     <string name="first_run_cling_search_bar_hint" msgid="5909062802402452582"></string>
     <string name="first_run_cling_create_screens_hint" msgid="6950729526680114157">"ສ້າງຈໍເພີ່ມເຕີມສຳລັບແອັບຯ ແລະໂຟນເດີ"</string>
+    <string name="migration_cling_title" msgid="9181776667882933767">"ສຳເນົາໄອຄອນແອັບຯຂອງທ່ານ"</string>
+    <string name="migration_cling_description" msgid="2752413805582227644">"ນຳເຂົ້າໄອຄອນ ແລະ ໂຟນເດີຈາກໂຮມສະກຣີນອັນເກົ່າຂອງທ່ານບໍ່?"</string>
+    <string name="migration_cling_copy_apps" msgid="946331230090919440">"ສຳເນົາໄອຄອນ"</string>
+    <string name="migration_cling_use_default" msgid="2626475813981258626">"ເລີ່ມຕົ້ນໃໝ່"</string>
     <string name="workspace_cling_title" msgid="5626202359865825661">"ຈັດການພື້ນທີ່ຂອງທ່ານ"</string>
     <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_create_folder" msgid="6158215559475836131">"ເພື່ອສ້າງອັນໃໝ່ແບບນີ້, ແຕະຄ້າງໄວ້ທີ່ແອັບຯ ແລ້ວຍ້າຍມັນໄປຫາໂຕອື່ນ."</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>
     <string name="folder_tap_to_close" msgid="1884479294466410023">"ສຳພັດເພື່ອປິດໂຟນເດີ"</string>
diff --git a/res/values-lt/strings.xml b/res/values-lt/strings.xml
index 80d4412..aed0e84 100644
--- a/res/values-lt/strings.xml
+++ b/res/values-lt/strings.xml
@@ -23,18 +23,6 @@
     <string name="home" msgid="7658288663002113681">"Pagrindinis"</string>
     <string name="uid_name" msgid="7820867637514617527">"Pagrindinės „Android“ programos"</string>
     <string name="folder_name" msgid="7371454440695724752"></string>
-    <string name="wallpaper_instructions" msgid="563973358787555519">"Nustatyti ekrano foną"</string>
-  <plurals name="number_of_items_selected">
-    <item quantity="zero" msgid="7464587177007785408">"Pasirinkta: %1$d"</item>
-    <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>
-    <string name="crop_wallpaper" msgid="8334345984491368009">"Ekrano fono apkirpimas"</string>
     <string name="activity_not_found" msgid="8071924732094499514">"Programa neįdiegta."</string>
     <string name="widgets_tab_label" msgid="2921133187116603919">"Valdikliai"</string>
     <string name="widget_adder" msgid="3201040140710381657">"Valdikliai"</string>
@@ -54,8 +42,8 @@
     <string name="group_widgets" msgid="1569030723286851002">"Valdikliai"</string>
     <string name="completely_out_of_space" msgid="6106288382070760318">"Pagrindiniuose ekranuose vietos nebėra."</string>
     <string name="out_of_space" msgid="4691004494942118364">"Šiame pagrindiniame ekrane vietos nebėra."</string>
-    <string name="hotseat_out_of_space" msgid="9139760413395605841">"Įtvirtintojoje srityje nebėra vietos."</string>
-    <string name="invalid_hotseat_item" msgid="1211534262129849507">"Šis valdiklis įtvirtintajai sričiai per didelis."</string>
+    <string name="hotseat_out_of_space" msgid="7448809638125333693">"Mėgstamiausių dėkle nebėra vietos"</string>
+    <string name="invalid_hotseat_item" msgid="5779907847267573691">"Mėgstamiausių dėklui šis valdiklis per didelis."</string>
     <string name="shortcut_installed" msgid="1701742129426969556">"Spartusis klavišas „<xliff:g id="NAME">%s</xliff:g>“ sukurtas."</string>
     <string name="shortcut_uninstalled" msgid="8176767991305701821">"Spartusis klavišas „<xliff:g id="NAME">%s</xliff:g>“ pašalintas."</string>
     <string name="shortcut_duplicate" msgid="9167217446062498127">"Spartusis klavišas „<xliff:g id="NAME">%s</xliff:g>“ jau yra."</string>
@@ -96,15 +84,17 @@
     <string name="workspace_scroll_format" msgid="8458889198184077399">"%1$d pagrindinis ekranas iš %2$d"</string>
     <string name="apps_customize_apps_scroll_format" msgid="370005296147130238">"%1$d programų psl. iš %2$d"</string>
     <string name="apps_customize_widgets_scroll_format" msgid="3106209519974971521">"%1$d valdiklių psl. iš %2$d"</string>
-    <string name="first_run_cling_title" msgid="7257389003637362144">"Sveiki!"</string>
+    <string name="first_run_cling_title" msgid="2459738000155917941">"Sveiki"</string>
     <string name="first_run_cling_description" msgid="6447072552696253358">"Jauskitės kaip namie."</string>
     <string name="first_run_cling_custom_content_hint" msgid="6090628589029352439"></string>
     <string name="first_run_cling_search_bar_hint" msgid="5909062802402452582"></string>
     <string name="first_run_cling_create_screens_hint" msgid="6950729526680114157">"Sukurkite daugiau programų ir aplankų ekrano kopijų"</string>
+    <string name="migration_cling_title" msgid="9181776667882933767">"Programų piktogramų kopij."</string>
+    <string name="migration_cling_description" msgid="2752413805582227644">"Importuoti piktogramas ir aplankus iš senų pagr. ekranų?"</string>
+    <string name="migration_cling_copy_apps" msgid="946331230090919440">"KOPIJUOTI PIKTOGRAMAS"</string>
+    <string name="migration_cling_use_default" msgid="2626475813981258626">"PRADĖTI IŠ NAUJO"</string>
     <string name="workspace_cling_title" msgid="5626202359865825661">"Tvarkykite savo vietą"</string>
     <string name="workspace_cling_move_item" msgid="528201129978005352">"Palieskite ir laikykite foną, jei norite tvarkyti ekrano foną, valdiklius ir nustatymus."</string>
-    <string name="all_apps_cling_title" msgid="34929250753095858">"Pasirinkite kelias programas"</string>
-    <string name="all_apps_cling_add_item" msgid="400866858451850784">"Jei norite prie pagrindinio ekrano pridėti programą, palieskite ją ir laikykite."</string>
     <string name="folder_cling_title" msgid="3894908818693254164">"Štai aplankas"</string>
     <string name="folder_cling_create_folder" msgid="6158215559475836131">"Kad sukurtumėte tokį patį, palieskite ir laikykite programą, tada perkelkite ją virš kitos programos."</string>
     <string name="cling_dismiss" msgid="8962359497601507581">"Gerai"</string>
diff --git a/res/values-lv/strings.xml b/res/values-lv/strings.xml
index b70f5dc..74ae7a4 100644
--- a/res/values-lv/strings.xml
+++ b/res/values-lv/strings.xml
@@ -23,18 +23,6 @@
     <string name="home" msgid="7658288663002113681">"Sākums"</string>
     <string name="uid_name" msgid="7820867637514617527">"Android pamatlietotnes"</string>
     <string name="folder_name" msgid="7371454440695724752"></string>
-    <string name="wallpaper_instructions" msgid="563973358787555519">"Iestatīt fona tapeti"</string>
-  <plurals name="number_of_items_selected">
-    <item quantity="zero" msgid="7464587177007785408">"Atlasīti: %1$d"</item>
-    <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>
-    <string name="crop_wallpaper" msgid="8334345984491368009">"Apgriezt fona tapeti"</string>
     <string name="activity_not_found" msgid="8071924732094499514">"Lietotne nav instalēta."</string>
     <string name="widgets_tab_label" msgid="2921133187116603919">"Logrīki"</string>
     <string name="widget_adder" msgid="3201040140710381657">"Logrīki"</string>
@@ -54,8 +42,8 @@
     <string name="group_widgets" msgid="1569030723286851002">"Logrīki"</string>
     <string name="completely_out_of_space" msgid="6106288382070760318">"Sākuma ekrānos vairs nav vietas."</string>
     <string name="out_of_space" msgid="4691004494942118364">"Šajā sākuma ekrānā vairs nav vietas."</string>
-    <string name="hotseat_out_of_space" msgid="9139760413395605841">"Režīmā “hotseat” vairs nav vietas."</string>
-    <string name="invalid_hotseat_item" msgid="1211534262129849507">"Šis logrīks ir pārāk liels režīmam “hotseat”."</string>
+    <string name="hotseat_out_of_space" msgid="7448809638125333693">"Izlases joslā vairs nav vietas."</string>
+    <string name="invalid_hotseat_item" msgid="5779907847267573691">"Šis logrīks ir pārāk liels izlases joslai."</string>
     <string name="shortcut_installed" msgid="1701742129426969556">"Tika izveidota saīsne “<xliff:g id="NAME">%s</xliff:g>”."</string>
     <string name="shortcut_uninstalled" msgid="8176767991305701821">"Tika noņemta saīsne “<xliff:g id="NAME">%s</xliff:g>”."</string>
     <string name="shortcut_duplicate" msgid="9167217446062498127">"Saīsne “<xliff:g id="NAME">%s</xliff:g>” jau pastāv."</string>
@@ -96,15 +84,17 @@
     <string name="workspace_scroll_format" msgid="8458889198184077399">"Sākuma ekrāns: %1$d no %2$d"</string>
     <string name="apps_customize_apps_scroll_format" msgid="370005296147130238">"%1$d. lietotņu lapa no %2$d"</string>
     <string name="apps_customize_widgets_scroll_format" msgid="3106209519974971521">"%1$d. logrīku lapa no %2$d"</string>
-    <string name="first_run_cling_title" msgid="7257389003637362144">"Laipni lūdzam!"</string>
+    <string name="first_run_cling_title" msgid="2459738000155917941">"Laipni lūdzam!"</string>
     <string name="first_run_cling_description" msgid="6447072552696253358">"Informācija par pamatfunkcijām"</string>
     <string name="first_run_cling_custom_content_hint" msgid="6090628589029352439"></string>
     <string name="first_run_cling_search_bar_hint" msgid="5909062802402452582"></string>
     <string name="first_run_cling_create_screens_hint" msgid="6950729526680114157">"Izveidojiet vairāk ekrānu lietotnēm un mapēm."</string>
+    <string name="migration_cling_title" msgid="9181776667882933767">"Lietotņu ikonu kopēšana"</string>
+    <string name="migration_cling_description" msgid="2752413805582227644">"Vai importēt ikonas, mapes no iepriekšējiem sākuma ekrāniem?"</string>
+    <string name="migration_cling_copy_apps" msgid="946331230090919440">"KOPĒT IKONAS"</string>
+    <string name="migration_cling_use_default" msgid="2626475813981258626">"SĀKT NO SĀKUMA"</string>
     <string name="workspace_cling_title" msgid="5626202359865825661">"Kārtojiet savu darbvietu"</string>
     <string name="workspace_cling_move_item" msgid="528201129978005352">"Pieskarieties fonam un turiet to, lai pārvaldītu fona tapeti, logrīkus un iestatījumus."</string>
-    <string name="all_apps_cling_title" msgid="34929250753095858">"Izvēlieties dažas lietotnes"</string>
-    <string name="all_apps_cling_add_item" msgid="400866858451850784">"Lai sākuma ekrānam pievienotu lietotni, pieskarieties tai un turiet to."</string>
     <string name="folder_cling_title" msgid="3894908818693254164">"Lūk, mape!"</string>
     <string name="folder_cling_create_folder" msgid="6158215559475836131">"Lai izveidotu tādu pašu, pieskarieties lietotnei un turiet to, pēc tam pārvietojiet to virs citas lietotnes."</string>
     <string name="cling_dismiss" msgid="8962359497601507581">"Labi"</string>
diff --git a/res/values-mn-rMN/strings.xml b/res/values-mn-rMN/strings.xml
index 7cf7a9c..0430ac5 100644
--- a/res/values-mn-rMN/strings.xml
+++ b/res/values-mn-rMN/strings.xml
@@ -23,18 +23,6 @@
     <string name="home" msgid="7658288663002113681">"Нүүр"</string>
     <string name="uid_name" msgid="7820867637514617527">"Андройд үндсэн апп"</string>
     <string name="folder_name" msgid="7371454440695724752"></string>
-    <string name="wallpaper_instructions" msgid="563973358787555519">"Ханын зургийг тохируулах"</string>
-  <plurals name="number_of_items_selected">
-    <item quantity="zero" msgid="7464587177007785408">"%1$d сонгогдсон"</item>
-    <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>
-    <string name="crop_wallpaper" msgid="8334345984491368009">"Ханын зургийг тайрах"</string>
     <string name="activity_not_found" msgid="8071924732094499514">"Апп суугаагүй байна."</string>
     <string name="widgets_tab_label" msgid="2921133187116603919">"Виджет"</string>
     <string name="widget_adder" msgid="3201040140710381657">"Виджет"</string>
@@ -54,8 +42,8 @@
     <string name="group_widgets" msgid="1569030723286851002">"Виджет"</string>
     <string name="completely_out_of_space" msgid="6106288382070760318">"Таны Нүүр дэлгэц зайгүй."</string>
     <string name="out_of_space" msgid="4691004494942118364">"Энэ Нүүр дэлгэц зайгүй."</string>
-    <string name="hotseat_out_of_space" msgid="9139760413395605841">"Суурь зайгүй."</string>
-    <string name="invalid_hotseat_item" msgid="1211534262129849507">"Энэ виджет сууринд хэт томдож байна."</string>
+    <string name="hotseat_out_of_space" msgid="7448809638125333693">"\"Дуртай\" трей дээр өөр зай байхгүй байна"</string>
+    <string name="invalid_hotseat_item" msgid="5779907847267573691">"Энэ виджет трей дээр хэт томдож байна"</string>
     <string name="shortcut_installed" msgid="1701742129426969556">"\"<xliff:g id="NAME">%s</xliff:g>\" товчлол үүсэв."</string>
     <string name="shortcut_uninstalled" msgid="8176767991305701821">"\"<xliff:g id="NAME">%s</xliff:g>\" товчлол устгагдав."</string>
     <string name="shortcut_duplicate" msgid="9167217446062498127">"\"<xliff:g id="NAME">%s</xliff:g>\" товчлол өмнө үүссэн байна."</string>
@@ -96,15 +84,17 @@
     <string name="workspace_scroll_format" msgid="8458889198184077399">"%2$d-н Нүүр дэлгэц %1$d"</string>
     <string name="apps_customize_apps_scroll_format" msgid="370005296147130238">"%2$d-н %1$d апп хуудас"</string>
     <string name="apps_customize_widgets_scroll_format" msgid="3106209519974971521">"%2$d-н %1$d виджет хуудас"</string>
-    <string name="first_run_cling_title" msgid="7257389003637362144">"Тавтай морилно уу!"</string>
+    <string name="first_run_cling_title" msgid="2459738000155917941">"Тавтай морилно уу"</string>
     <string name="first_run_cling_description" msgid="6447072552696253358">"Гэртээ байгаа мэт тухлаарай."</string>
     <string name="first_run_cling_custom_content_hint" msgid="6090628589029352439"></string>
     <string name="first_run_cling_search_bar_hint" msgid="5909062802402452582"></string>
     <string name="first_run_cling_create_screens_hint" msgid="6950729526680114157">"Апп болон фолдеруудад зориулан өөр дэлгэцүүд үүсгээрэй"</string>
+    <string name="migration_cling_title" msgid="9181776667882933767">"Таны апп дүрсүүдийг хуулах"</string>
+    <string name="migration_cling_description" msgid="2752413805582227644">"Таны хуучин Үндсэн дэлгэц дээрх дүрсүүдийг импорт хийх үү?"</string>
+    <string name="migration_cling_copy_apps" msgid="946331230090919440">"ДҮРСҮҮДИЙГ ХУУЛАХ"</string>
+    <string name="migration_cling_use_default" msgid="2626475813981258626">"ШИНЭЭР ЭХЛЭХ"</string>
     <string name="workspace_cling_title" msgid="5626202359865825661">"Өөрийнхөө зайг тохируулаарай"</string>
     <string name="workspace_cling_move_item" msgid="528201129978005352">"Арын дэвсгэр дээр хүрээд &amp; дарснаар ханын зураг, виджет болон тохиргоог өөрчилж болно."</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_create_folder" msgid="6158215559475836131">"Үүнтэй адилханыг үүсгэхийн тулд апп дээр хүрч &amp; бариад нөгөөхийн дээр зөөнө үү."</string>
     <string name="cling_dismiss" msgid="8962359497601507581">"Тийм"</string>
diff --git a/res/values-ms-rMY/strings.xml b/res/values-ms-rMY/strings.xml
index 4ee3545..802aa95 100644
--- a/res/values-ms-rMY/strings.xml
+++ b/res/values-ms-rMY/strings.xml
@@ -23,18 +23,6 @@
     <string name="home" msgid="7658288663002113681">"Laman Utama"</string>
     <string name="uid_name" msgid="7820867637514617527">"Apl Teras Android"</string>
     <string name="folder_name" msgid="7371454440695724752"></string>
-    <string name="wallpaper_instructions" msgid="563973358787555519">"Tetapkan kertas dinding"</string>
-  <plurals name="number_of_items_selected">
-    <item quantity="zero" msgid="7464587177007785408">"%1$d dipilih"</item>
-    <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>
-    <string name="crop_wallpaper" msgid="8334345984491368009">"Pangkas kertas dinding"</string>
     <string name="activity_not_found" msgid="8071924732094499514">"Apl tidak dipasang."</string>
     <string name="widgets_tab_label" msgid="2921133187116603919">"Widget"</string>
     <string name="widget_adder" msgid="3201040140710381657">"Widget"</string>
@@ -54,8 +42,8 @@
     <string name="group_widgets" msgid="1569030723286851002">"Widget"</string>
     <string name="completely_out_of_space" msgid="6106288382070760318">"Tiada lagi ruang pada skrin Laman Utama anda."</string>
     <string name="out_of_space" msgid="4691004494942118364">"Tiada lagi ruang pada skrin Laman Utama ini."</string>
-    <string name="hotseat_out_of_space" msgid="9139760413395605841">"Tiada lagi ruang pada kerusi panas."</string>
-    <string name="invalid_hotseat_item" msgid="1211534262129849507">"Widget ini terlalu besar untuk kerusi panas."</string>
+    <string name="hotseat_out_of_space" msgid="7448809638125333693">"Tiada ruang dalam dulang Kegemaran lagi"</string>
+    <string name="invalid_hotseat_item" msgid="5779907847267573691">"Widget ini terlalu besar untuk dulang Kegemaran"</string>
     <string name="shortcut_installed" msgid="1701742129426969556">"Pintasan \"<xliff:g id="NAME">%s</xliff:g>\" telah dibuat."</string>
     <string name="shortcut_uninstalled" msgid="8176767991305701821">"Pintasan \"<xliff:g id="NAME">%s</xliff:g>\" telah dialih keluar."</string>
     <string name="shortcut_duplicate" msgid="9167217446062498127">"Pintasan \"<xliff:g id="NAME">%s</xliff:g>\" sudah wujud."</string>
@@ -96,15 +84,17 @@
     <string name="workspace_scroll_format" msgid="8458889198184077399">"Skrin Laman Utama %1$d daripada %2$d"</string>
     <string name="apps_customize_apps_scroll_format" msgid="370005296147130238">"Halaman apl %1$d daripada %2$d"</string>
     <string name="apps_customize_widgets_scroll_format" msgid="3106209519974971521">"Halaman widget %1$d daripada %2$d"</string>
-    <string name="first_run_cling_title" msgid="7257389003637362144">"Selamat datang!"</string>
+    <string name="first_run_cling_title" msgid="2459738000155917941">"Selamat datang"</string>
     <string name="first_run_cling_description" msgid="6447072552696253358">"Buat seperti berada di rumah sendiri."</string>
     <string name="first_run_cling_custom_content_hint" msgid="6090628589029352439"></string>
     <string name="first_run_cling_search_bar_hint" msgid="5909062802402452582"></string>
     <string name="first_run_cling_create_screens_hint" msgid="6950729526680114157">"Buat lebih banyak skrin untuk apl dan folder"</string>
+    <string name="migration_cling_title" msgid="9181776667882933767">"Salin ikon apl anda"</string>
+    <string name="migration_cling_description" msgid="2752413805582227644">"Import ikon dan folder dari skrin Laman Utama lama anda?"</string>
+    <string name="migration_cling_copy_apps" msgid="946331230090919440">"SALIN IKON"</string>
+    <string name="migration_cling_use_default" msgid="2626475813981258626">"MULAKAN YANG BAHARU"</string>
     <string name="workspace_cling_title" msgid="5626202359865825661">"Susun ruang anda"</string>
     <string name="workspace_cling_move_item" msgid="528201129978005352">"Sentuh &amp; tahan latar belakang untuk mengurus kertas dinding, widget dan tetapan."</string>
-    <string name="all_apps_cling_title" msgid="34929250753095858">"Pilih beberapa apl"</string>
-    <string name="all_apps_cling_add_item" msgid="400866858451850784">"Untuk menambahkan apl pada skrin Laman Utama anda, sentuh &amp; tahan apl."</string>
     <string name="folder_cling_title" msgid="3894908818693254164">"Ini ada folder"</string>
     <string name="folder_cling_create_folder" msgid="6158215559475836131">"Untuk membuat satu folder seperti ini, sentuh &amp; tahan apl, kemudian alihkan ke atas folder lain."</string>
     <string name="cling_dismiss" msgid="8962359497601507581">"OK"</string>
diff --git a/res/values-nb/strings.xml b/res/values-nb/strings.xml
index ce50754..0e16375 100644
--- a/res/values-nb/strings.xml
+++ b/res/values-nb/strings.xml
@@ -23,18 +23,6 @@
     <string name="home" msgid="7658288663002113681">"Startside"</string>
     <string name="uid_name" msgid="7820867637514617527">"Kjerneapper for Android"</string>
     <string name="folder_name" msgid="7371454440695724752"></string>
-    <string name="wallpaper_instructions" msgid="563973358787555519">"Angi bakgrunn"</string>
-  <plurals name="number_of_items_selected">
-    <item quantity="zero" msgid="7464587177007785408">"%1$d valgt"</item>
-    <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>
-    <string name="crop_wallpaper" msgid="8334345984491368009">"Beskjær bakgrunnen"</string>
     <string name="activity_not_found" msgid="8071924732094499514">"Appen er ikke installert."</string>
     <string name="widgets_tab_label" msgid="2921133187116603919">"Moduler"</string>
     <string name="widget_adder" msgid="3201040140710381657">"Moduler"</string>
@@ -54,8 +42,8 @@
     <string name="group_widgets" msgid="1569030723286851002">"Moduler"</string>
     <string name="completely_out_of_space" msgid="6106288382070760318">"Ikke mer plass på startsidene dine."</string>
     <string name="out_of_space" msgid="4691004494942118364">"Denne startsiden er full."</string>
-    <string name="hotseat_out_of_space" msgid="9139760413395605841">"Dokksonen er full."</string>
-    <string name="invalid_hotseat_item" msgid="1211534262129849507">"Denne modulen er for stor for dokksonen."</string>
+    <string name="hotseat_out_of_space" msgid="7448809638125333693">"Favoritter-skuffen er full"</string>
+    <string name="invalid_hotseat_item" msgid="5779907847267573691">"Denne modulen er for stor for Favoritter-skuffen."</string>
     <string name="shortcut_installed" msgid="1701742129426969556">"Snarveien «<xliff:g id="NAME">%s</xliff:g>» er opprettet."</string>
     <string name="shortcut_uninstalled" msgid="8176767991305701821">"Snarveien «<xliff:g id="NAME">%s</xliff:g>» er fjernet."</string>
     <string name="shortcut_duplicate" msgid="9167217446062498127">"Snarveien «<xliff:g id="NAME">%s</xliff:g>» fins allerede."</string>
@@ -96,15 +84,17 @@
     <string name="workspace_scroll_format" msgid="8458889198184077399">"Startside %1$d av %2$d"</string>
     <string name="apps_customize_apps_scroll_format" msgid="370005296147130238">"Appside %1$d av %2$d"</string>
     <string name="apps_customize_widgets_scroll_format" msgid="3106209519974971521">"Modulside %1$d av %2$d"</string>
-    <string name="first_run_cling_title" msgid="7257389003637362144">"Velkommen!"</string>
+    <string name="first_run_cling_title" msgid="2459738000155917941">"Velkommen"</string>
     <string name="first_run_cling_description" msgid="6447072552696253358">"Føl deg som hjemme."</string>
     <string name="first_run_cling_custom_content_hint" msgid="6090628589029352439"></string>
     <string name="first_run_cling_search_bar_hint" msgid="5909062802402452582"></string>
     <string name="first_run_cling_create_screens_hint" msgid="6950729526680114157">"Opprett flere sider for apper og mapper"</string>
+    <string name="migration_cling_title" msgid="9181776667882933767">"Kopiér appikonene dine"</string>
+    <string name="migration_cling_description" msgid="2752413805582227644">"Vil du importere ikoner og mapper fra dine gamle startsider?"</string>
+    <string name="migration_cling_copy_apps" msgid="946331230090919440">"KOPIÉR IKONENE"</string>
+    <string name="migration_cling_use_default" msgid="2626475813981258626">"START PÅ NYTT"</string>
     <string name="workspace_cling_title" msgid="5626202359865825661">"Organiser plassen din"</string>
     <string name="workspace_cling_move_item" msgid="528201129978005352">"Trykk og hold på bakgrunnen for å administrere bakgrunnen, moduler og innstillinger."</string>
-    <string name="all_apps_cling_title" msgid="34929250753095858">"Velg noen apper"</string>
-    <string name="all_apps_cling_add_item" msgid="400866858451850784">"Trykk og hold på en app for å legge den til på startsiden."</string>
     <string name="folder_cling_title" msgid="3894908818693254164">"Dette er en mappe"</string>
     <string name="folder_cling_create_folder" msgid="6158215559475836131">"For å opprette en som denne, trykker og holder du på en app og flytter den over en annen."</string>
     <string name="cling_dismiss" msgid="8962359497601507581">"OK"</string>
diff --git a/res/values-nl/strings.xml b/res/values-nl/strings.xml
index e2a2a07..f6c1b09 100644
--- a/res/values-nl/strings.xml
+++ b/res/values-nl/strings.xml
@@ -23,18 +23,6 @@
     <string name="home" msgid="7658288663002113681">"Startpagina"</string>
     <string name="uid_name" msgid="7820867637514617527">"Android-kernapps"</string>
     <string name="folder_name" msgid="7371454440695724752"></string>
-    <string name="wallpaper_instructions" msgid="563973358787555519">"Achtergrond instellen"</string>
-  <plurals name="number_of_items_selected">
-    <item quantity="zero" msgid="7464587177007785408">"%1$d geselecteerd"</item>
-    <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>
-    <string name="crop_wallpaper" msgid="8334345984491368009">"Achtergrond bijsnijden"</string>
     <string name="activity_not_found" msgid="8071924732094499514">"App is niet geïnstalleerd."</string>
     <string name="widgets_tab_label" msgid="2921133187116603919">"Widgets"</string>
     <string name="widget_adder" msgid="3201040140710381657">"Widgets"</string>
@@ -54,8 +42,8 @@
     <string name="group_widgets" msgid="1569030723286851002">"Widgets"</string>
     <string name="completely_out_of_space" msgid="6106288382070760318">"Er is geen ruimte meer op uw startschermen."</string>
     <string name="out_of_space" msgid="4691004494942118364">"Er is geen ruimte meer op dit startscherm."</string>
-    <string name="hotseat_out_of_space" msgid="9139760413395605841">"Er is geen ruimte meer op de hotseat."</string>
-    <string name="invalid_hotseat_item" msgid="1211534262129849507">"Deze widget is te groot voor de hotseat."</string>
+    <string name="hotseat_out_of_space" msgid="7448809638125333693">"Geen ruimte meer in het vak \'Favorieten\'"</string>
+    <string name="invalid_hotseat_item" msgid="5779907847267573691">"Deze widget is te groot voor het vak \'Favorieten\'"</string>
     <string name="shortcut_installed" msgid="1701742129426969556">"Snelkoppeling \'<xliff:g id="NAME">%s</xliff:g>\' is gemaakt."</string>
     <string name="shortcut_uninstalled" msgid="8176767991305701821">"Snelkoppeling \'<xliff:g id="NAME">%s</xliff:g>\' is verwijderd."</string>
     <string name="shortcut_duplicate" msgid="9167217446062498127">"Snelkoppeling \'<xliff:g id="NAME">%s</xliff:g>\' bestaat al."</string>
@@ -96,15 +84,17 @@
     <string name="workspace_scroll_format" msgid="8458889198184077399">"Startscherm %1$d van %2$d"</string>
     <string name="apps_customize_apps_scroll_format" msgid="370005296147130238">"App-pagina %1$d van %2$d"</string>
     <string name="apps_customize_widgets_scroll_format" msgid="3106209519974971521">"Widgetpagina %1$d van %2$d"</string>
-    <string name="first_run_cling_title" msgid="7257389003637362144">"Welkom!"</string>
+    <string name="first_run_cling_title" msgid="2459738000155917941">"Welkom"</string>
     <string name="first_run_cling_description" msgid="6447072552696253358">"Personaliseer uw startscherm."</string>
     <string name="first_run_cling_custom_content_hint" msgid="6090628589029352439"></string>
     <string name="first_run_cling_search_bar_hint" msgid="5909062802402452582"></string>
     <string name="first_run_cling_create_screens_hint" msgid="6950729526680114157">"Meer schermen maken voor apps en mappen"</string>
+    <string name="migration_cling_title" msgid="9181776667882933767">"Uw app-pictogrammen kopiëren"</string>
+    <string name="migration_cling_description" msgid="2752413805582227644">"Pictogrammen en mappen importeren uit uw oude startschermen?"</string>
+    <string name="migration_cling_copy_apps" msgid="946331230090919440">"PICTOGRAMMEN KOPIËREN"</string>
+    <string name="migration_cling_use_default" msgid="2626475813981258626">"OPNIEUW BEGINNEN"</string>
     <string name="workspace_cling_title" msgid="5626202359865825661">"Uw ruimte indelen"</string>
     <string name="workspace_cling_move_item" msgid="528201129978005352">"Blijf de achtergrond aanraken om de achtergrond, widgets en instellingen te beheren."</string>
-    <string name="all_apps_cling_title" msgid="34929250753095858">"Selecteer een aantal apps"</string>
-    <string name="all_apps_cling_add_item" msgid="400866858451850784">"Als u een app wilt toevoegen aan het startscherm, blijft u de app aanraken."</string>
     <string name="folder_cling_title" msgid="3894908818693254164">"Dit is een map"</string>
     <string name="folder_cling_create_folder" msgid="6158215559475836131">"Als u een map zoals deze wilt maken, blijft u een app aanraken en schuift u deze boven op een andere app."</string>
     <string name="cling_dismiss" msgid="8962359497601507581">"OK"</string>
diff --git a/res/values-pl/strings.xml b/res/values-pl/strings.xml
index b629f3d..5a2efbf 100644
--- a/res/values-pl/strings.xml
+++ b/res/values-pl/strings.xml
@@ -23,18 +23,6 @@
     <string name="home" msgid="7658288663002113681">"Ekran główny"</string>
     <string name="uid_name" msgid="7820867637514617527">"Główne aplikacje Androida"</string>
     <string name="folder_name" msgid="7371454440695724752"></string>
-    <string name="wallpaper_instructions" msgid="563973358787555519">"Ustaw tapetę"</string>
-  <plurals name="number_of_items_selected">
-    <item quantity="zero" msgid="7464587177007785408">"Wybrane: %1$d"</item>
-    <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>
-    <string name="crop_wallpaper" msgid="8334345984491368009">"Przytnij tapetę"</string>
     <string name="activity_not_found" msgid="8071924732094499514">"Aplikacja nie jest zainstalowana."</string>
     <string name="widgets_tab_label" msgid="2921133187116603919">"Widżety"</string>
     <string name="widget_adder" msgid="3201040140710381657">"Widżety"</string>
@@ -54,8 +42,8 @@
     <string name="group_widgets" msgid="1569030723286851002">"Widżety"</string>
     <string name="completely_out_of_space" msgid="6106288382070760318">"Brak miejsca na ekranach głównych."</string>
     <string name="out_of_space" msgid="4691004494942118364">"Brak miejsca na tym ekranie głównym."</string>
-    <string name="hotseat_out_of_space" msgid="9139760413395605841">"Brak miejsca w kieszonce."</string>
-    <string name="invalid_hotseat_item" msgid="1211534262129849507">"Ten widżet jest za duży, by umieścić go w kieszonce."</string>
+    <string name="hotseat_out_of_space" msgid="7448809638125333693">"Brak miejsca w Ulubionych"</string>
+    <string name="invalid_hotseat_item" msgid="5779907847267573691">"Ten widżet jest za duży, by zmieścił się w Ulubionych"</string>
     <string name="shortcut_installed" msgid="1701742129426969556">"Skrót „<xliff:g id="NAME">%s</xliff:g>” został utworzony."</string>
     <string name="shortcut_uninstalled" msgid="8176767991305701821">"Skrót „<xliff:g id="NAME">%s</xliff:g>” został usunięty."</string>
     <string name="shortcut_duplicate" msgid="9167217446062498127">"Skrót „<xliff:g id="NAME">%s</xliff:g>” już istnieje."</string>
@@ -96,15 +84,17 @@
     <string name="workspace_scroll_format" msgid="8458889198184077399">"Ekran główny %1$d z %2$d"</string>
     <string name="apps_customize_apps_scroll_format" msgid="370005296147130238">"Strona aplikacji: %1$d z %2$d"</string>
     <string name="apps_customize_widgets_scroll_format" msgid="3106209519974971521">"Strona widżetów: %1$d z %2$d"</string>
-    <string name="first_run_cling_title" msgid="7257389003637362144">"Witamy"</string>
+    <string name="first_run_cling_title" msgid="2459738000155917941">"Witamy"</string>
     <string name="first_run_cling_description" msgid="6447072552696253358">"Poczuj się jak u siebie."</string>
     <string name="first_run_cling_custom_content_hint" msgid="6090628589029352439"></string>
     <string name="first_run_cling_search_bar_hint" msgid="5909062802402452582"></string>
     <string name="first_run_cling_create_screens_hint" msgid="6950729526680114157">"Dodaj więcej ekranów na aplikacje i foldery"</string>
+    <string name="migration_cling_title" msgid="9181776667882933767">"Kopiuj ikony aplikacji"</string>
+    <string name="migration_cling_description" msgid="2752413805582227644">"Zaimportować ikony i foldery ze starych ekranów głównych?"</string>
+    <string name="migration_cling_copy_apps" msgid="946331230090919440">"KOPIUJ IKONY"</string>
+    <string name="migration_cling_use_default" msgid="2626475813981258626">"ZACZNIJ OD NOWA"</string>
     <string name="workspace_cling_title" msgid="5626202359865825661">"Uporządkuj obszar roboczy"</string>
     <string name="workspace_cling_move_item" msgid="528201129978005352">"Kliknij i przytrzymaj tło, by zmienić tapetę, widżety lub ustawienia."</string>
-    <string name="all_apps_cling_title" msgid="34929250753095858">"Wybierz kilka aplikacji"</string>
-    <string name="all_apps_cling_add_item" msgid="400866858451850784">"Aby dodać aplikację na ekran główny, dotknij i przytrzymaj jej ikonę."</string>
     <string name="folder_cling_title" msgid="3894908818693254164">"Tu jest folder"</string>
     <string name="folder_cling_create_folder" msgid="6158215559475836131">"Aby utworzyć taki sam, kliknij i przytrzymaj aplikację, a następnie przenieś ją na następną."</string>
     <string name="cling_dismiss" msgid="8962359497601507581">"OK"</string>
diff --git a/res/values-port/dimens.xml b/res/values-port/dimens.xml
index 7194a2a..7753ab3 100644
--- a/res/values-port/dimens.xml
+++ b/res/values-port/dimens.xml
@@ -15,9 +15,6 @@
 -->
 
 <resources>
-<!-- Workspace -->
-    <dimen name="workspace_page_spacing">-1dp</dimen>
-
 <!-- AppsCustomize -->
     <integer name="apps_customize_cling_focused_x">1</integer>
     <integer name="apps_customize_cling_focused_y">1</integer>
diff --git a/res/values-pt-rPT/strings.xml b/res/values-pt-rPT/strings.xml
index 1ef3982..c6f5710 100644
--- a/res/values-pt-rPT/strings.xml
+++ b/res/values-pt-rPT/strings.xml
@@ -23,18 +23,6 @@
     <string name="home" msgid="7658288663002113681">"Ecrã principal"</string>
     <string name="uid_name" msgid="7820867637514617527">"Aplicações principais do Android"</string>
     <string name="folder_name" msgid="7371454440695724752"></string>
-    <string name="wallpaper_instructions" msgid="563973358787555519">"Definir imagem fundo"</string>
-  <plurals name="number_of_items_selected">
-    <item quantity="zero" msgid="7464587177007785408">"%1$d selecionado(s)"</item>
-    <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>
-    <string name="crop_wallpaper" msgid="8334345984491368009">"Recortar imagem de fundo"</string>
     <string name="activity_not_found" msgid="8071924732094499514">"A aplicação não está instalada."</string>
     <string name="widgets_tab_label" msgid="2921133187116603919">"Widgets"</string>
     <string name="widget_adder" msgid="3201040140710381657">"Widgets"</string>
@@ -54,8 +42,8 @@
     <string name="group_widgets" msgid="1569030723286851002">"Widgets"</string>
     <string name="completely_out_of_space" msgid="6106288382070760318">"Sem espaço suficiente nos Ecrãs principais."</string>
     <string name="out_of_space" msgid="4691004494942118364">"Sem espaço suficiente neste Ecrã principal."</string>
-    <string name="hotseat_out_of_space" msgid="9139760413395605841">"Sem espaço suficiente na barra personalizável."</string>
-    <string name="invalid_hotseat_item" msgid="1211534262129849507">"Este widget é demasiado grande para a barra personalizável."</string>
+    <string name="hotseat_out_of_space" msgid="7448809638125333693">"Não existe mais espaço no tabuleiro de Favoritos"</string>
+    <string name="invalid_hotseat_item" msgid="5779907847267573691">"Este widget é demasiado grande para o tabuleiro de Favoritos"</string>
     <string name="shortcut_installed" msgid="1701742129426969556">"Atalho “<xliff:g id="NAME">%s</xliff:g>” criado."</string>
     <string name="shortcut_uninstalled" msgid="8176767991305701821">"O atalho “<xliff:g id="NAME">%s</xliff:g>” foi removido."</string>
     <string name="shortcut_duplicate" msgid="9167217446062498127">"O atalho “<xliff:g id="NAME">%s</xliff:g>” já existe."</string>
@@ -96,15 +84,17 @@
     <string name="workspace_scroll_format" msgid="8458889198184077399">"Ecrã principal %1$d de %2$d"</string>
     <string name="apps_customize_apps_scroll_format" msgid="370005296147130238">"Página de aplicações %1$d de %2$d"</string>
     <string name="apps_customize_widgets_scroll_format" msgid="3106209519974971521">"Página de widgets %1$d de %2$d"</string>
-    <string name="first_run_cling_title" msgid="7257389003637362144">"Bem-vindo(a)!"</string>
+    <string name="first_run_cling_title" msgid="2459738000155917941">"Bem-vindo(a)"</string>
     <string name="first_run_cling_description" msgid="6447072552696253358">"Sinta-se em casa."</string>
     <string name="first_run_cling_custom_content_hint" msgid="6090628589029352439"></string>
     <string name="first_run_cling_search_bar_hint" msgid="5909062802402452582"></string>
     <string name="first_run_cling_create_screens_hint" msgid="6950729526680114157">"Crie mais ecrãs para aplicações e pastas"</string>
+    <string name="migration_cling_title" msgid="9181776667882933767">"Copiar ícones das aplicações"</string>
+    <string name="migration_cling_description" msgid="2752413805582227644">"Importar ícones e pastas dos ecrãs principais antigos?"</string>
+    <string name="migration_cling_copy_apps" msgid="946331230090919440">"COPIAR ÍCONES"</string>
+    <string name="migration_cling_use_default" msgid="2626475813981258626">"COMEÇAR DO INÍCIO"</string>
     <string name="workspace_cling_title" msgid="5626202359865825661">"Organizar o seu espaço"</string>
     <string name="workspace_cling_move_item" msgid="528201129978005352">"Toque sem soltar no fundo para gerir a imagem de fundo, os widgets e as definições."</string>
-    <string name="all_apps_cling_title" msgid="34929250753095858">"Escolher algumas aplicações"</string>
-    <string name="all_apps_cling_add_item" msgid="400866858451850784">"Para adicionar uma aplicação ao Ecrã principal, toque na mesma sem soltar."</string>
     <string name="folder_cling_title" msgid="3894908818693254164">"Eis uma pasta"</string>
     <string name="folder_cling_create_folder" msgid="6158215559475836131">"Para criar uma pasta, toque sem soltar numa aplicação e arraste-a para cima de outra aplicação."</string>
     <string name="cling_dismiss" msgid="8962359497601507581">"OK"</string>
diff --git a/res/values-pt/strings.xml b/res/values-pt/strings.xml
index 4d40388..0252d61 100644
--- a/res/values-pt/strings.xml
+++ b/res/values-pt/strings.xml
@@ -23,18 +23,6 @@
     <string name="home" msgid="7658288663002113681">"Início"</string>
     <string name="uid_name" msgid="7820867637514617527">"Principais aplicativos do Android"</string>
     <string name="folder_name" msgid="7371454440695724752"></string>
-    <string name="wallpaper_instructions" msgid="563973358787555519">"Definir plano de fundo"</string>
-  <plurals name="number_of_items_selected">
-    <item quantity="zero" msgid="7464587177007785408">"%1$d selecionados"</item>
-    <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>
-    <string name="crop_wallpaper" msgid="8334345984491368009">"Cortar plano de fundo"</string>
     <string name="activity_not_found" msgid="8071924732094499514">"O aplicativo não está instalado."</string>
     <string name="widgets_tab_label" msgid="2921133187116603919">"Widgets"</string>
     <string name="widget_adder" msgid="3201040140710381657">"Widgets"</string>
@@ -54,8 +42,8 @@
     <string name="group_widgets" msgid="1569030723286851002">"Widgets"</string>
     <string name="completely_out_of_space" msgid="6106288382070760318">"Não há mais espaço nas telas iniciais."</string>
     <string name="out_of_space" msgid="4691004494942118364">"Não há mais espaço na tela inicial."</string>
-    <string name="hotseat_out_of_space" msgid="9139760413395605841">"Não há mais espaço no hotseat."</string>
-    <string name="invalid_hotseat_item" msgid="1211534262129849507">"Este widget é muito grande para o hotseat."</string>
+    <string name="hotseat_out_of_space" msgid="7448809638125333693">"Sem espaço na bandeja de favoritos"</string>
+    <string name="invalid_hotseat_item" msgid="5779907847267573691">"O widget é muito grande para a bandeja de favoritos"</string>
     <string name="shortcut_installed" msgid="1701742129426969556">"Atalho \"<xliff:g id="NAME">%s</xliff:g>\" criado."</string>
     <string name="shortcut_uninstalled" msgid="8176767991305701821">"O atalho \"<xliff:g id="NAME">%s</xliff:g>\" foi removido."</string>
     <string name="shortcut_duplicate" msgid="9167217446062498127">"O atalho \"<xliff:g id="NAME">%s</xliff:g>\" já existe."</string>
@@ -96,15 +84,17 @@
     <string name="workspace_scroll_format" msgid="8458889198184077399">"Tela inicial %1$d de %2$d"</string>
     <string name="apps_customize_apps_scroll_format" msgid="370005296147130238">"Página de aplicativos, %1$d de %2$d"</string>
     <string name="apps_customize_widgets_scroll_format" msgid="3106209519974971521">"Página de widgets, %1$d de %2$d"</string>
-    <string name="first_run_cling_title" msgid="7257389003637362144">"Bem-vindo!"</string>
+    <string name="first_run_cling_title" msgid="2459738000155917941">"Bem-vindo"</string>
     <string name="first_run_cling_description" msgid="6447072552696253358">"Fique à vontade."</string>
     <string name="first_run_cling_custom_content_hint" msgid="6090628589029352439"></string>
     <string name="first_run_cling_search_bar_hint" msgid="5909062802402452582"></string>
     <string name="first_run_cling_create_screens_hint" msgid="6950729526680114157">"Crie mais telas para aplicativos e pastas"</string>
+    <string name="migration_cling_title" msgid="9181776667882933767">"Copiar ícones de aplicativos"</string>
+    <string name="migration_cling_description" msgid="2752413805582227644">"Importar ícones e pastas de suas telas iniciais antigas?"</string>
+    <string name="migration_cling_copy_apps" msgid="946331230090919440">"COPIAR ÍCONES"</string>
+    <string name="migration_cling_use_default" msgid="2626475813981258626">"COMEÇAR DO ZERO"</string>
     <string name="workspace_cling_title" msgid="5626202359865825661">"Organize seu espaço"</string>
     <string name="workspace_cling_move_item" msgid="528201129978005352">"Toque e mantenha pressionada a tela de fundo para gerenciar o plano de fundo, os widgets e as configurações."</string>
-    <string name="all_apps_cling_title" msgid="34929250753095858">"Escolha alguns aplicativos"</string>
-    <string name="all_apps_cling_add_item" msgid="400866858451850784">"Para adicionar um aplicativo a sua tela inicial, toque e mantenha-o pressionado."</string>
     <string name="folder_cling_title" msgid="3894908818693254164">"Aqui está uma pasta"</string>
     <string name="folder_cling_create_folder" msgid="6158215559475836131">"Para criar uma pasta como esta, mantenha pressionado um aplicativo e mova-o para cima de outro."</string>
     <string name="cling_dismiss" msgid="8962359497601507581">"Ok"</string>
diff --git a/res/values-rm/strings.xml b/res/values-rm/strings.xml
index ddcf404..8563d7d 100644
--- a/res/values-rm/strings.xml
+++ b/res/values-rm/strings.xml
@@ -26,23 +26,6 @@
     <!-- no translation found for uid_name (7820867637514617527) -->
     <skip />
     <string name="folder_name" msgid="7371454440695724752"></string>
-    <!-- no translation found for wallpaper_instructions (563973358787555519) -->
-    <skip />
-    <!-- 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) -->
-    <skip />
-    <!-- no translation found for pick_wallpaper (8179698221502010609) -->
-    <skip />
-    <!-- no translation found for crop_wallpaper (8334345984491368009) -->
-    <skip />
     <!-- no translation found for activity_not_found (8071924732094499514) -->
     <skip />
     <!-- no translation found for widgets_tab_label (2921133187116603919) -->
@@ -81,9 +64,9 @@
     <skip />
     <!-- no translation found for out_of_space (4691004494942118364) -->
     <skip />
-    <!-- no translation found for hotseat_out_of_space (9139760413395605841) -->
+    <!-- no translation found for hotseat_out_of_space (7448809638125333693) -->
     <skip />
-    <!-- no translation found for invalid_hotseat_item (1211534262129849507) -->
+    <!-- no translation found for invalid_hotseat_item (5779907847267573691) -->
     <skip />
     <!-- no translation found for shortcut_installed (1701742129426969556) -->
     <skip />
@@ -165,7 +148,7 @@
     <skip />
     <!-- no translation found for apps_customize_widgets_scroll_format (3106209519974971521) -->
     <skip />
-    <!-- no translation found for first_run_cling_title (7257389003637362144) -->
+    <!-- no translation found for first_run_cling_title (2459738000155917941) -->
     <skip />
     <!-- no translation found for first_run_cling_description (6447072552696253358) -->
     <skip />
@@ -173,14 +156,18 @@
     <string name="first_run_cling_search_bar_hint" msgid="5909062802402452582"></string>
     <!-- no translation found for first_run_cling_create_screens_hint (6950729526680114157) -->
     <skip />
+    <!-- no translation found for migration_cling_title (9181776667882933767) -->
+    <skip />
+    <!-- no translation found for migration_cling_description (2752413805582227644) -->
+    <skip />
+    <!-- no translation found for migration_cling_copy_apps (946331230090919440) -->
+    <skip />
+    <!-- no translation found for migration_cling_use_default (2626475813981258626) -->
+    <skip />
     <!-- no translation found for workspace_cling_title (5626202359865825661) -->
     <skip />
     <!-- no translation found for workspace_cling_move_item (528201129978005352) -->
     <skip />
-    <!-- no translation found for all_apps_cling_title (34929250753095858) -->
-    <skip />
-    <!-- no translation found for all_apps_cling_add_item (400866858451850784) -->
-    <skip />
     <!-- no translation found for folder_cling_title (3894908818693254164) -->
     <skip />
     <!-- no translation found for folder_cling_create_folder (6158215559475836131) -->
diff --git a/res/values-ro/strings.xml b/res/values-ro/strings.xml
index 78d9da4..75479ed 100644
--- a/res/values-ro/strings.xml
+++ b/res/values-ro/strings.xml
@@ -23,18 +23,6 @@
     <string name="home" msgid="7658288663002113681">"Ecran de pornire"</string>
     <string name="uid_name" msgid="7820867637514617527">"Android Core Apps"</string>
     <string name="folder_name" msgid="7371454440695724752"></string>
-    <string name="wallpaper_instructions" msgid="563973358787555519">"Setați imaginea de fundal"</string>
-  <plurals name="number_of_items_selected">
-    <item quantity="zero" msgid="7464587177007785408">"%1$d selectate"</item>
-    <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>
-    <string name="crop_wallpaper" msgid="8334345984491368009">"Decupați imaginea de fundal"</string>
     <string name="activity_not_found" msgid="8071924732094499514">"Aplicația nu este instalată."</string>
     <string name="widgets_tab_label" msgid="2921133187116603919">"Widgeturi"</string>
     <string name="widget_adder" msgid="3201040140710381657">"Widgeturi"</string>
@@ -54,8 +42,8 @@
     <string name="group_widgets" msgid="1569030723286851002">"Widgeturi"</string>
     <string name="completely_out_of_space" msgid="6106288382070760318">"Nu mai este loc pe ecranele de pornire."</string>
     <string name="out_of_space" msgid="4691004494942118364">"Nu mai este loc pe acest Ecran de pornire."</string>
-    <string name="hotseat_out_of_space" msgid="9139760413395605841">"Nu mai este loc în bara de lansare rapidă."</string>
-    <string name="invalid_hotseat_item" msgid="1211534262129849507">"Acest widget este prea mare pentru bara de lansare rapidă."</string>
+    <string name="hotseat_out_of_space" msgid="7448809638125333693">"Spațiu epuizat în bara Preferate"</string>
+    <string name="invalid_hotseat_item" msgid="5779907847267573691">"Acest widget este prea mare pentru bara Preferate"</string>
     <string name="shortcut_installed" msgid="1701742129426969556">"Comanda rapidă „<xliff:g id="NAME">%s</xliff:g>\" a fost creată."</string>
     <string name="shortcut_uninstalled" msgid="8176767991305701821">"Comanda rapidă „<xliff:g id="NAME">%s</xliff:g>” a fost eliminată."</string>
     <string name="shortcut_duplicate" msgid="9167217446062498127">"Comanda rapidă „<xliff:g id="NAME">%s</xliff:g>” există deja."</string>
@@ -96,15 +84,17 @@
     <string name="workspace_scroll_format" msgid="8458889198184077399">"Ecranul de pornire %1$d din %2$d"</string>
     <string name="apps_customize_apps_scroll_format" msgid="370005296147130238">"Pagina de aplicații %1$d din %2$d"</string>
     <string name="apps_customize_widgets_scroll_format" msgid="3106209519974971521">"Pagina de widgeturi %1$d din %2$d"</string>
-    <string name="first_run_cling_title" msgid="7257389003637362144">"Bun venit!"</string>
+    <string name="first_run_cling_title" msgid="2459738000155917941">"Bun venit"</string>
     <string name="first_run_cling_description" msgid="6447072552696253358">"Simțiți-vă ca acasă."</string>
     <string name="first_run_cling_custom_content_hint" msgid="6090628589029352439"></string>
     <string name="first_run_cling_search_bar_hint" msgid="5909062802402452582"></string>
     <string name="first_run_cling_create_screens_hint" msgid="6950729526680114157">"Creați mai multe ecrane pentru aplicații și dosare"</string>
+    <string name="migration_cling_title" msgid="9181776667882933767">"Copiați pictogr. aplicațiilor"</string>
+    <string name="migration_cling_description" msgid="2752413805582227644">"Import. pictogr. și dosare de pe ecranele de pornire anter.?"</string>
+    <string name="migration_cling_copy_apps" msgid="946331230090919440">"COPIAȚI PICTOGRAMELE"</string>
+    <string name="migration_cling_use_default" msgid="2626475813981258626">"REÎNCEPEȚI"</string>
     <string name="workspace_cling_title" msgid="5626202359865825661">"Organizați-vă spațiul"</string>
     <string name="workspace_cling_move_item" msgid="528201129978005352">"Atingeți lung fundalul pentru a gestiona imaginea de fundal, widgeturile și setările."</string>
-    <string name="all_apps_cling_title" msgid="34929250753095858">"Alegeți unele aplicații"</string>
-    <string name="all_apps_cling_add_item" msgid="400866858451850784">"Atingeți lung o aplicație pentru a o adăuga pe ecranul de pornire."</string>
     <string name="folder_cling_title" msgid="3894908818693254164">"Iată un dosar"</string>
     <string name="folder_cling_create_folder" msgid="6158215559475836131">"Pentru a crea un dosar similar, atingeți și țineți degetul pe o aplicație, apoi mutați-o deasupra alteia."</string>
     <string name="cling_dismiss" msgid="8962359497601507581">"OK"</string>
diff --git a/res/values-ru/strings.xml b/res/values-ru/strings.xml
index 06fbd26..a93583d 100644
--- a/res/values-ru/strings.xml
+++ b/res/values-ru/strings.xml
@@ -23,18 +23,6 @@
     <string name="home" msgid="7658288663002113681">"Главный экран"</string>
     <string name="uid_name" msgid="7820867637514617527">"Основные приложения Android"</string>
     <string name="folder_name" msgid="7371454440695724752"></string>
-    <string name="wallpaper_instructions" msgid="563973358787555519">"Установить как обои"</string>
-  <plurals name="number_of_items_selected">
-    <item quantity="zero" msgid="7464587177007785408">"Выбрано: %1$d"</item>
-    <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>
-    <string name="crop_wallpaper" msgid="8334345984491368009">"Обрезать обои"</string>
     <string name="activity_not_found" msgid="8071924732094499514">"Приложение удалено"</string>
     <string name="widgets_tab_label" msgid="2921133187116603919">"Виджеты"</string>
     <string name="widget_adder" msgid="3201040140710381657">"Виджеты"</string>
@@ -54,8 +42,8 @@
     <string name="group_widgets" msgid="1569030723286851002">"Виджеты"</string>
     <string name="completely_out_of_space" msgid="6106288382070760318">"На главных экранах все занято"</string>
     <string name="out_of_space" msgid="4691004494942118364">"На этом экране все занято"</string>
-    <string name="hotseat_out_of_space" msgid="9139760413395605841">"Нет свободного места в слоте"</string>
-    <string name="invalid_hotseat_item" msgid="1211534262129849507">"Виджет слишком велик для слота"</string>
+    <string name="hotseat_out_of_space" msgid="7448809638125333693">"В разделе \"Избранное\" больше нет места"</string>
+    <string name="invalid_hotseat_item" msgid="5779907847267573691">"Виджет слишком велик для раздела \"Избранное\""</string>
     <string name="shortcut_installed" msgid="1701742129426969556">"Ярлык \"<xliff:g id="NAME">%s</xliff:g>\" создан"</string>
     <string name="shortcut_uninstalled" msgid="8176767991305701821">"Ярлык \"<xliff:g id="NAME">%s</xliff:g>\" удален"</string>
     <string name="shortcut_duplicate" msgid="9167217446062498127">"Ярлык \"<xliff:g id="NAME">%s</xliff:g>\" уже существует"</string>
@@ -96,15 +84,17 @@
     <string name="workspace_scroll_format" msgid="8458889198184077399">"Главные экран %1$d из %2$d"</string>
     <string name="apps_customize_apps_scroll_format" msgid="370005296147130238">"Приложения: стр. %1$d из %2$d"</string>
     <string name="apps_customize_widgets_scroll_format" msgid="3106209519974971521">"Виджеты: стр. %1$d из %2$d"</string>
-    <string name="first_run_cling_title" msgid="7257389003637362144">"Добро пожаловать!"</string>
+    <string name="first_run_cling_title" msgid="2459738000155917941">"Добро пожаловать!"</string>
     <string name="first_run_cling_description" msgid="6447072552696253358">"Будьте как дома"</string>
     <string name="first_run_cling_custom_content_hint" msgid="6090628589029352439"></string>
     <string name="first_run_cling_search_bar_hint" msgid="5909062802402452582"></string>
     <string name="first_run_cling_create_screens_hint" msgid="6950729526680114157">"Создание дополнительных экранов для приложений и папок"</string>
+    <string name="migration_cling_title" msgid="9181776667882933767">"Копировать значки приложений"</string>
+    <string name="migration_cling_description" msgid="2752413805582227644">"Импортировать значки и папки со старого главного экрана?"</string>
+    <string name="migration_cling_copy_apps" msgid="946331230090919440">"КОПИРОВАТЬ ЗНАЧКИ"</string>
+    <string name="migration_cling_use_default" msgid="2626475813981258626">"ИСПОЛЬЗОВАТЬ СТАНДАРТНЫЙ МАКЕТ"</string>
     <string name="workspace_cling_title" msgid="5626202359865825661">"Организация рабочего пространства"</string>
     <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_create_folder" msgid="6158215559475836131">"Чтобы создать папку, нажмите и удерживайте значок приложения, а затем перетащите его на другой значок."</string>
     <string name="cling_dismiss" msgid="8962359497601507581">"ОК"</string>
diff --git a/res/values-sk/strings.xml b/res/values-sk/strings.xml
index 29de526..485a2ec 100644
--- a/res/values-sk/strings.xml
+++ b/res/values-sk/strings.xml
@@ -23,18 +23,6 @@
     <string name="home" msgid="7658288663002113681">"Plocha"</string>
     <string name="uid_name" msgid="7820867637514617527">"Android Core Apps"</string>
     <string name="folder_name" msgid="7371454440695724752"></string>
-    <string name="wallpaper_instructions" msgid="563973358787555519">"Nastaviť tapetu"</string>
-  <plurals name="number_of_items_selected">
-    <item quantity="zero" msgid="7464587177007785408">"Počet vybratých položiek: %1$d"</item>
-    <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>
-    <string name="crop_wallpaper" msgid="8334345984491368009">"Orezanie tapety"</string>
     <string name="activity_not_found" msgid="8071924732094499514">"Aplikácia nie je nainštalovaná."</string>
     <string name="widgets_tab_label" msgid="2921133187116603919">"Miniaplikácie"</string>
     <string name="widget_adder" msgid="3201040140710381657">"Miniaplikácie"</string>
@@ -54,8 +42,8 @@
     <string name="group_widgets" msgid="1569030723286851002">"Miniaplikácie"</string>
     <string name="completely_out_of_space" msgid="6106288382070760318">"Na plochách už nie je miesto."</string>
     <string name="out_of_space" msgid="4691004494942118364">"Na tejto ploche už nie je miesto"</string>
-    <string name="hotseat_out_of_space" msgid="9139760413395605841">"V časti hotseat už nie je miesto."</string>
-    <string name="invalid_hotseat_item" msgid="1211534262129849507">"Táto miniaplikácia je pre hotseat príliš veľká."</string>
+    <string name="hotseat_out_of_space" msgid="7448809638125333693">"Na paneli Obľúbené položky už nie je miesto"</string>
+    <string name="invalid_hotseat_item" msgid="5779907847267573691">"Táto miniaplikácia je príliš veľká pre panel Obľúbené položky"</string>
     <string name="shortcut_installed" msgid="1701742129426969556">"Odkaz <xliff:g id="NAME">%s</xliff:g> bol vytvorený."</string>
     <string name="shortcut_uninstalled" msgid="8176767991305701821">"Odkaz <xliff:g id="NAME">%s</xliff:g> bol odstránený."</string>
     <string name="shortcut_duplicate" msgid="9167217446062498127">"Odkaz <xliff:g id="NAME">%s</xliff:g> už existuje."</string>
@@ -96,15 +84,17 @@
     <string name="workspace_scroll_format" msgid="8458889198184077399">"Plocha %1$d z %2$d"</string>
     <string name="apps_customize_apps_scroll_format" msgid="370005296147130238">"Stránka aplikácií %1$d z %2$d"</string>
     <string name="apps_customize_widgets_scroll_format" msgid="3106209519974971521">"Stránka miniaplikácií %1$d z %2$d"</string>
-    <string name="first_run_cling_title" msgid="7257389003637362144">"Vitajte!"</string>
+    <string name="first_run_cling_title" msgid="2459738000155917941">"Vitajte"</string>
     <string name="first_run_cling_description" msgid="6447072552696253358">"Cíťte sa tu ako doma."</string>
     <string name="first_run_cling_custom_content_hint" msgid="6090628589029352439"></string>
     <string name="first_run_cling_search_bar_hint" msgid="5909062802402452582"></string>
     <string name="first_run_cling_create_screens_hint" msgid="6950729526680114157">"Vytvorte viac obrazoviek pre aplikácie a priečinky"</string>
+    <string name="migration_cling_title" msgid="9181776667882933767">"Kopírovanie ikon aplikácií"</string>
+    <string name="migration_cling_description" msgid="2752413805582227644">"Chcete importovať ikony a priečinky zo starých plôch?"</string>
+    <string name="migration_cling_copy_apps" msgid="946331230090919440">"SKOPÍROVAŤ IKONY"</string>
+    <string name="migration_cling_use_default" msgid="2626475813981258626">"ZAČAŤ S PREDVOLENÝM ROZLOŽENÍM"</string>
     <string name="workspace_cling_title" msgid="5626202359865825661">"Usporiadajte svoj priestor"</string>
     <string name="workspace_cling_move_item" msgid="528201129978005352">"Ak chcete spravovať tapetu, miniaplikácie a nastavenia, dotknite sa pozadia a podržte."</string>
-    <string name="all_apps_cling_title" msgid="34929250753095858">"Vyberte niektoré aplikácie"</string>
-    <string name="all_apps_cling_add_item" msgid="400866858451850784">"Ak chcete pridať aplikáciu na plochu, dotknite sa jej a podržte."</string>
     <string name="folder_cling_title" msgid="3894908818693254164">"Tu je priečinok"</string>
     <string name="folder_cling_create_folder" msgid="6158215559475836131">"Ak chcete vytvoriť takýto priečinok, dotknite sa príslušnej aplikácie a podržte ju. Potom ju presuňte na druhú aplikáciu."</string>
     <string name="cling_dismiss" msgid="8962359497601507581">"OK"</string>
diff --git a/res/values-sl/strings.xml b/res/values-sl/strings.xml
index 021eca8..dfd63e2 100644
--- a/res/values-sl/strings.xml
+++ b/res/values-sl/strings.xml
@@ -23,18 +23,6 @@
     <string name="home" msgid="7658288663002113681">"Začetni zaslon"</string>
     <string name="uid_name" msgid="7820867637514617527">"Osnovne aplikacije sistema Android"</string>
     <string name="folder_name" msgid="7371454440695724752"></string>
-    <string name="wallpaper_instructions" msgid="563973358787555519">"Nastavi ozadje"</string>
-  <plurals name="number_of_items_selected">
-    <item quantity="zero" msgid="7464587177007785408">"Št. izbranih: %1$d"</item>
-    <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>
-    <string name="crop_wallpaper" msgid="8334345984491368009">"Obrezovanje ozadja"</string>
     <string name="activity_not_found" msgid="8071924732094499514">"Aplikacija ni nameščena."</string>
     <string name="widgets_tab_label" msgid="2921133187116603919">"Pripomočki"</string>
     <string name="widget_adder" msgid="3201040140710381657">"Pripomočki"</string>
@@ -54,8 +42,8 @@
     <string name="group_widgets" msgid="1569030723286851002">"Pripomočki"</string>
     <string name="completely_out_of_space" msgid="6106288382070760318">"Na začetnih zaslonih ni več prostora."</string>
     <string name="out_of_space" msgid="4691004494942118364">"Na tem začetnem zaslonu ni več prostora."</string>
-    <string name="hotseat_out_of_space" msgid="9139760413395605841">"V vrstici z ikonami ni več prostora."</string>
-    <string name="invalid_hotseat_item" msgid="1211534262129849507">"Ta pripomoček je prevelik za vrstico z ikonami."</string>
+    <string name="hotseat_out_of_space" msgid="7448809638125333693">"V vrstici za priljubljene ni več prostora"</string>
+    <string name="invalid_hotseat_item" msgid="5779907847267573691">"Ta pripomoček je prevelik za vrstico s priljubljenimi"</string>
     <string name="shortcut_installed" msgid="1701742129426969556">"Bližnjica »<xliff:g id="NAME">%s</xliff:g>« je ustvarjena."</string>
     <string name="shortcut_uninstalled" msgid="8176767991305701821">"Bližnjica »<xliff:g id="NAME">%s</xliff:g>« je bila odstranjena."</string>
     <string name="shortcut_duplicate" msgid="9167217446062498127">"Bližnjica »<xliff:g id="NAME">%s</xliff:g>« že obstaja."</string>
@@ -96,15 +84,17 @@
     <string name="workspace_scroll_format" msgid="8458889198184077399">"Začetni zaslon %1$d od %2$d"</string>
     <string name="apps_customize_apps_scroll_format" msgid="370005296147130238">"Stran aplikacij %1$d od %2$d"</string>
     <string name="apps_customize_widgets_scroll_format" msgid="3106209519974971521">"Stran pripomočkov %1$d od %2$d"</string>
-    <string name="first_run_cling_title" msgid="7257389003637362144">"Pozdravljeni!"</string>
+    <string name="first_run_cling_title" msgid="2459738000155917941">"Pozdravljeni"</string>
     <string name="first_run_cling_description" msgid="6447072552696253358">"Počutite se kot doma."</string>
     <string name="first_run_cling_custom_content_hint" msgid="6090628589029352439"></string>
     <string name="first_run_cling_search_bar_hint" msgid="5909062802402452582"></string>
     <string name="first_run_cling_create_screens_hint" msgid="6950729526680114157">"Ustvarite več zaslonov za aplikacije in mape"</string>
+    <string name="migration_cling_title" msgid="9181776667882933767">"Kopiranje ikon aplikacij"</string>
+    <string name="migration_cling_description" msgid="2752413805582227644">"Želite uvoziti ikone in mape iz starih začetnih zaslonov?"</string>
+    <string name="migration_cling_copy_apps" msgid="946331230090919440">"KOPIRAJ IKONE"</string>
+    <string name="migration_cling_use_default" msgid="2626475813981258626">"SVEŽ ZAČETEK"</string>
     <string name="workspace_cling_title" msgid="5626202359865825661">"Organizirajte svoj prostor"</string>
     <string name="workspace_cling_move_item" msgid="528201129978005352">"Če želite upravljati ozadje, pripomočke in nastavitve, se dotaknite ozadja in ga pridržite."</string>
-    <string name="all_apps_cling_title" msgid="34929250753095858">"Izberite nekaj aplikacij"</string>
-    <string name="all_apps_cling_add_item" msgid="400866858451850784">"Če želite dodati aplikacijo na začetni zaslon, se je dotaknite in jo pridržite."</string>
     <string name="folder_cling_title" msgid="3894908818693254164">"To je mapa"</string>
     <string name="folder_cling_create_folder" msgid="6158215559475836131">"Če želite ustvariti mapo, podobno tej, se dotaknite aplikacije in jo pridržite, nato pa jo premaknite nad drugo."</string>
     <string name="cling_dismiss" msgid="8962359497601507581">"V redu"</string>
diff --git a/res/values-sr/strings.xml b/res/values-sr/strings.xml
index 06d80ef..dd28fa3 100644
--- a/res/values-sr/strings.xml
+++ b/res/values-sr/strings.xml
@@ -23,18 +23,6 @@
     <string name="home" msgid="7658288663002113681">"Почетна"</string>
     <string name="uid_name" msgid="7820867637514617527">"Основне Android апликације"</string>
     <string name="folder_name" msgid="7371454440695724752"></string>
-    <string name="wallpaper_instructions" msgid="563973358787555519">"Подеси позадину"</string>
-  <plurals name="number_of_items_selected">
-    <item quantity="zero" msgid="7464587177007785408">"Изабранo je %1$d"</item>
-    <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>
-    <string name="crop_wallpaper" msgid="8334345984491368009">"Опсецање позадине"</string>
     <string name="activity_not_found" msgid="8071924732094499514">"Апликација није инсталирана."</string>
     <string name="widgets_tab_label" msgid="2921133187116603919">"Виџети"</string>
     <string name="widget_adder" msgid="3201040140710381657">"Виџети"</string>
@@ -54,8 +42,8 @@
     <string name="group_widgets" msgid="1569030723286851002">"Виџети"</string>
     <string name="completely_out_of_space" msgid="6106288382070760318">"Нема више простора на почетним екранима."</string>
     <string name="out_of_space" msgid="4691004494942118364">"Нема више простора на овом почетном екрану."</string>
-    <string name="hotseat_out_of_space" msgid="9139760413395605841">"Нема више простора на траци актуелности."</string>
-    <string name="invalid_hotseat_item" msgid="1211534262129849507">"Овај виџет је превелики за траку актуелности."</string>
+    <string name="hotseat_out_of_space" msgid="7448809638125333693">"Нема више простора на траци Омиљено"</string>
+    <string name="invalid_hotseat_item" msgid="5779907847267573691">"Виџет је превелик за траку Омиљено"</string>
     <string name="shortcut_installed" msgid="1701742129426969556">"Пречица „<xliff:g id="NAME">%s</xliff:g>“ је направљена."</string>
     <string name="shortcut_uninstalled" msgid="8176767991305701821">"Пречица „<xliff:g id="NAME">%s</xliff:g>“ је уклоњена."</string>
     <string name="shortcut_duplicate" msgid="9167217446062498127">"Пречица „<xliff:g id="NAME">%s</xliff:g>“ већ постоји."</string>
@@ -96,15 +84,17 @@
     <string name="workspace_scroll_format" msgid="8458889198184077399">"%1$d. почетни екран од %2$d"</string>
     <string name="apps_customize_apps_scroll_format" msgid="370005296147130238">"%1$d. страница апликација од %2$d"</string>
     <string name="apps_customize_widgets_scroll_format" msgid="3106209519974971521">"%1$d. страница виџета од %2$d"</string>
-    <string name="first_run_cling_title" msgid="7257389003637362144">"Добро дошли!"</string>
+    <string name="first_run_cling_title" msgid="2459738000155917941">"Добро дошли"</string>
     <string name="first_run_cling_description" msgid="6447072552696253358">"Осећајте се као код куће."</string>
     <string name="first_run_cling_custom_content_hint" msgid="6090628589029352439"></string>
     <string name="first_run_cling_search_bar_hint" msgid="5909062802402452582"></string>
     <string name="first_run_cling_create_screens_hint" msgid="6950729526680114157">"Направите још екрана за апликације и директоријуме"</string>
+    <string name="migration_cling_title" msgid="9181776667882933767">"Копирајте иконе апликација"</string>
+    <string name="migration_cling_description" msgid="2752413805582227644">"Увести иконе и директоријуме са старих почетних екрана?"</string>
+    <string name="migration_cling_copy_apps" msgid="946331230090919440">"КОПИРАЈТЕ ИКОНЕ"</string>
+    <string name="migration_cling_use_default" msgid="2626475813981258626">"ПОЧНИТЕ ИСПОЧЕТКА"</string>
     <string name="workspace_cling_title" msgid="5626202359865825661">"Организујте простор"</string>
     <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_create_folder" msgid="6158215559475836131">"Да бисте направили директоријум попут овога, додирните и задржите апликацију, па је превуците преко друге."</string>
     <string name="cling_dismiss" msgid="8962359497601507581">"Потврди"</string>
diff --git a/res/values-sv/strings.xml b/res/values-sv/strings.xml
index bf75200..4005b7e 100644
--- a/res/values-sv/strings.xml
+++ b/res/values-sv/strings.xml
@@ -23,18 +23,6 @@
     <string name="home" msgid="7658288663002113681">"Startskärm"</string>
     <string name="uid_name" msgid="7820867637514617527">"Android Core Apps"</string>
     <string name="folder_name" msgid="7371454440695724752"></string>
-    <string name="wallpaper_instructions" msgid="563973358787555519">"Ange bakgrund"</string>
-  <plurals name="number_of_items_selected">
-    <item quantity="zero" msgid="7464587177007785408">"%1$d har valts"</item>
-    <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>
-    <string name="crop_wallpaper" msgid="8334345984491368009">"Beskär bakgrund"</string>
     <string name="activity_not_found" msgid="8071924732094499514">"Appen är inte installerad."</string>
     <string name="widgets_tab_label" msgid="2921133187116603919">"Widgetar"</string>
     <string name="widget_adder" msgid="3201040140710381657">"Widgetar"</string>
@@ -54,8 +42,8 @@
     <string name="group_widgets" msgid="1569030723286851002">"Widgetar"</string>
     <string name="completely_out_of_space" msgid="6106288382070760318">"Det finns inte plats för mer på dina startsidor."</string>
     <string name="out_of_space" msgid="4691004494942118364">"Det finns inte plats för mer på den här startskärmen."</string>
-    <string name="hotseat_out_of_space" msgid="9139760413395605841">"Utrymmet på Hotseat är fullt."</string>
-    <string name="invalid_hotseat_item" msgid="1211534262129849507">"Denna widget är för stor för Hotseat."</string>
+    <string name="hotseat_out_of_space" msgid="7448809638125333693">"Favoritfältet är fullt"</string>
+    <string name="invalid_hotseat_item" msgid="5779907847267573691">"Denna widget är för stor för favoritfältet"</string>
     <string name="shortcut_installed" msgid="1701742129426969556">"Genvägen <xliff:g id="NAME">%s</xliff:g> har skapats."</string>
     <string name="shortcut_uninstalled" msgid="8176767991305701821">"Genvägen <xliff:g id="NAME">%s</xliff:g> har tagits bort."</string>
     <string name="shortcut_duplicate" msgid="9167217446062498127">"Genvägen <xliff:g id="NAME">%s</xliff:g> finns redan."</string>
@@ -96,17 +84,19 @@
     <string name="workspace_scroll_format" msgid="8458889198184077399">"Startskärmen %1$d av %2$d"</string>
     <string name="apps_customize_apps_scroll_format" msgid="370005296147130238">"Appsida %1$d av %2$d"</string>
     <string name="apps_customize_widgets_scroll_format" msgid="3106209519974971521">"Widget-sida %1$d av %2$d"</string>
-    <string name="first_run_cling_title" msgid="7257389003637362144">"Välkommen!"</string>
+    <string name="first_run_cling_title" msgid="2459738000155917941">"Välkommen"</string>
     <string name="first_run_cling_description" msgid="6447072552696253358">"Känn dig som hemma."</string>
     <string name="first_run_cling_custom_content_hint" msgid="6090628589029352439"></string>
     <string name="first_run_cling_search_bar_hint" msgid="5909062802402452582"></string>
     <string name="first_run_cling_create_screens_hint" msgid="6950729526680114157">"Skapa fler skärmar för appar och mappar"</string>
+    <string name="migration_cling_title" msgid="9181776667882933767">"Kopiera appikoner"</string>
+    <string name="migration_cling_description" msgid="2752413805582227644">"Vill du importera ikoner och mappar från gamla startskärmar?"</string>
+    <string name="migration_cling_copy_apps" msgid="946331230090919440">"KOPIERA IKONER"</string>
+    <string name="migration_cling_use_default" msgid="2626475813981258626">"BÖRJA OM"</string>
     <string name="workspace_cling_title" msgid="5626202359865825661">"Organisera ditt utrymme"</string>
     <string name="workspace_cling_move_item" msgid="528201129978005352">"Tryck länge på bakgrunden om du vill hantera bakgrundsbilder, widgetar och inställningar."</string>
-    <string name="all_apps_cling_title" msgid="34929250753095858">"Välj några appar"</string>
-    <string name="all_apps_cling_add_item" msgid="400866858451850784">"Om du vill lägga till en app på startskärmen trycker du länge på den."</string>
     <string name="folder_cling_title" msgid="3894908818693254164">"Det här är en mapp"</string>
-    <string name="folder_cling_create_folder" msgid="6158215559475836131">"Om du vill skapa en till mapp av det här slaget trycker du länge på en app och drar den sedan ovanpå en annan."</string>
+    <string name="folder_cling_create_folder" msgid="6158215559475836131">"Skapa en till mapp av det här slaget genom att trycka och hålla ned en app och sedan dra den ovanpå en annan."</string>
     <string name="cling_dismiss" msgid="8962359497601507581">"OK"</string>
     <string name="folder_opened" msgid="94695026776264709">"Mappen är öppen, <xliff:g id="WIDTH">%1$d</xliff:g> gånger <xliff:g id="HEIGHT">%2$d</xliff:g>"</string>
     <string name="folder_tap_to_close" msgid="1884479294466410023">"Tryck om du vill stänga mappen"</string>
diff --git a/res/values-sw/strings.xml b/res/values-sw/strings.xml
index c610f34..4397d3b 100644
--- a/res/values-sw/strings.xml
+++ b/res/values-sw/strings.xml
@@ -23,18 +23,6 @@
     <string name="home" msgid="7658288663002113681">"Mwanzo"</string>
     <string name="uid_name" msgid="7820867637514617527">"Programu Msingi za Android"</string>
     <string name="folder_name" msgid="7371454440695724752"></string>
-    <string name="wallpaper_instructions" msgid="563973358787555519">"Weka mandhari"</string>
-  <plurals name="number_of_items_selected">
-    <item quantity="zero" msgid="7464587177007785408">"%1$d zimechaguliwa"</item>
-    <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>
-    <string name="crop_wallpaper" msgid="8334345984491368009">"Punguza mandhari"</string>
     <string name="activity_not_found" msgid="8071924732094499514">"Programu haijasakinishwa."</string>
     <string name="widgets_tab_label" msgid="2921133187116603919">"Wijeti"</string>
     <string name="widget_adder" msgid="3201040140710381657">"Wijeti"</string>
@@ -54,8 +42,8 @@
     <string name="group_widgets" msgid="1569030723286851002">"Wijeti"</string>
     <string name="completely_out_of_space" msgid="6106288382070760318">"Hakuna nafasi zaidi kwenye skrini zako za Nyumbani."</string>
     <string name="out_of_space" msgid="4691004494942118364">"Hakuna nafasi katika skrini hii ya Mwanzo."</string>
-    <string name="hotseat_out_of_space" msgid="9139760413395605841">"Hakuna nafasi zaidi kwenye eneo kali."</string>
-    <string name="invalid_hotseat_item" msgid="1211534262129849507">"Wijeti hii ni kubwa zaidi kwa eneo kali."</string>
+    <string name="hotseat_out_of_space" msgid="7448809638125333693">"Hakuna nafasi zaidi katika treya ya Vipendeleo"</string>
+    <string name="invalid_hotseat_item" msgid="5779907847267573691">"Wijeti hii ni kubwa mno kwa treya ya Vipendeleo"</string>
     <string name="shortcut_installed" msgid="1701742129426969556">"Njia ya mkato ya \"<xliff:g id="NAME">%s</xliff:g>\" imeundwa."</string>
     <string name="shortcut_uninstalled" msgid="8176767991305701821">"Njia ya mkato ya \"<xliff:g id="NAME">%s</xliff:g>\" iliondolewa."</string>
     <string name="shortcut_duplicate" msgid="9167217446062498127">"\"<xliff:g id="NAME">%s</xliff:g>\" la njia ya mkato tayari lipo."</string>
@@ -98,15 +86,17 @@
     <skip />
     <string name="apps_customize_apps_scroll_format" msgid="370005296147130238">"Ukurasa wa programu %1$d ya %2$d"</string>
     <string name="apps_customize_widgets_scroll_format" msgid="3106209519974971521">"Ukurasa wa wijeti %1$d ya %2$d"</string>
-    <string name="first_run_cling_title" msgid="7257389003637362144">"Karibu!"</string>
+    <string name="first_run_cling_title" msgid="2459738000155917941">"Karibu"</string>
     <string name="first_run_cling_description" msgid="6447072552696253358">"Jisikie huru."</string>
     <string name="first_run_cling_custom_content_hint" msgid="6090628589029352439"></string>
     <string name="first_run_cling_search_bar_hint" msgid="5909062802402452582"></string>
     <string name="first_run_cling_create_screens_hint" msgid="6950729526680114157">"Unda skrini zaidi za programu na folda"</string>
+    <string name="migration_cling_title" msgid="9181776667882933767">"Nakili ikoni za programu yako"</string>
+    <string name="migration_cling_description" msgid="2752413805582227644">"Je, ungependa kuingiza ikoni na folda kutoka kwenye skrini zako za Mwanzo za zamani?"</string>
+    <string name="migration_cling_copy_apps" msgid="946331230090919440">"NAKILI IKONI"</string>
+    <string name="migration_cling_use_default" msgid="2626475813981258626">"ANZA UPYA"</string>
     <string name="workspace_cling_title" msgid="5626202359865825661">"Panga nafasi yako"</string>
     <string name="workspace_cling_move_item" msgid="528201129978005352">"Gusa na ushikilie mandharinyuma ili udhibiti mandhari, wijeti, na mipangilio."</string>
-    <string name="all_apps_cling_title" msgid="34929250753095858">"Chagua programu kadhaa"</string>
-    <string name="all_apps_cling_add_item" msgid="400866858451850784">"Ili kuongeza programu kwenye Skrini yako Kuu, iguse na uishikilie."</string>
     <string name="folder_cling_title" msgid="3894908818693254164">"Hii ni folda"</string>
     <string name="folder_cling_create_folder" msgid="6158215559475836131">"Ili kuunda kama hii, gusa na ushikilie programu, kisha ipitishe juu ya nyingine."</string>
     <string name="cling_dismiss" msgid="8962359497601507581">"SAWA"</string>
diff --git a/res/values-sw340dp-port/config.xml b/res/values-sw340dp-port/config.xml
index d31ee59..5f71077 100644
--- a/res/values-sw340dp-port/config.xml
+++ b/res/values-sw340dp-port/config.xml
@@ -15,7 +15,4 @@
 -->
 
 <resources>
-<!-- Workspace -->
-    <!-- Whether or not to fade the side pages -->
-    <bool name="config_workspaceFadeAdjacentScreens">false</bool>
 </resources>
diff --git a/res/values-sw600dp-land/dimens.xml b/res/values-sw600dp-land/dimens.xml
index 7f5594d..f9ca01b 100644
--- a/res/values-sw600dp-land/dimens.xml
+++ b/res/values-sw600dp-land/dimens.xml
@@ -15,12 +15,6 @@
 -->
 
 <resources>
-<!-- AppsCustomize -->
-    <dimen name="apps_customize_pageLayoutWidthGap">36dp</dimen>
-    <dimen name="apps_customize_pageLayoutHeightGap">8dp</dimen>
-    <dimen name="apps_customize_pageLayoutPaddingTop">20dp</dimen>
-    <dimen name="apps_customize_pageLayoutPaddingBottom">14dp</dimen>
-
 <!-- QSB -->
     <dimen name="toolbar_button_vertical_padding">12dip</dimen>
     <dimen name="toolbar_button_horizontal_padding">20dip</dimen>
diff --git a/res/values-sw600dp/styles.xml b/res/values-sw600dp/styles.xml
index 3754304..bcbbafd 100644
--- a/res/values-sw600dp/styles.xml
+++ b/res/values-sw600dp/styles.xml
@@ -18,33 +18,4 @@
 -->
 
 <resources>
-    <style name="ClingButton">
-        <item name="android:layout_width">wrap_content</item>
-        <item name="android:layout_height">wrap_content</item>
-        <item name="android:paddingTop">10dp</item>
-        <item name="android:paddingBottom">15dp</item>
-        <item name="android:paddingStart">35dp</item>
-        <item name="android:paddingEnd">35dp</item>
-        <item name="android:text">@string/cling_dismiss</item>
-        <item name="android:textStyle">bold</item>
-        <item name="android:background">@drawable/cling_button_bg</item>
-    </style>
-    <style name="ClingTitleText">
-        <item name="android:layout_width">wrap_content</item>
-        <item name="android:layout_height">wrap_content</item>
-        <item name="android:layout_marginBottom">5dp</item>
-        <item name="android:textSize">30sp</item>
-        <item name="android:textColor">#33B5E5</item>
-        <item name="android:shadowColor">#000000</item>
-        <item name="android:shadowDy">2</item>
-        <item name="android:shadowRadius">2.0</item>
-    </style>
-    <style name="ClingText">
-        <item name="android:textSize">22sp</item>
-        <item name="android:textColor">#FFFFFF</item>
-        <item name="android:shadowColor">#000000</item>
-        <item name="android:shadowDy">2</item>
-        <item name="android:shadowRadius">2.0</item>
-        <item name="android:lineSpacingMultiplier">1.1</item>
-    </style>
 </resources>
diff --git a/res/values-sw720dp-land/dimens.xml b/res/values-sw720dp-land/dimens.xml
index eb8f83c..433a5d4 100644
--- a/res/values-sw720dp-land/dimens.xml
+++ b/res/values-sw720dp-land/dimens.xml
@@ -21,9 +21,6 @@
     <integer name="apps_customize_cling_focused_x">4</integer>
     <integer name="apps_customize_cling_focused_y">2</integer>
 
-<!-- Workspace -->
-    <dimen name="workspace_page_spacing">50dp</dimen>
-
     <!-- the area at the edge of the screen that makes the workspace go left
          or right while you're dragging. -->
     <dimen name="scroll_zone">100dip</dimen>
diff --git a/res/values-sw720dp-port/dimens.xml b/res/values-sw720dp-port/dimens.xml
index 62bdaaa..9fe312b 100644
--- a/res/values-sw720dp-port/dimens.xml
+++ b/res/values-sw720dp-port/dimens.xml
@@ -19,7 +19,6 @@
     <!-- the area at the edge of the screen that makes the workspace go left
          or right while you're dragging. -->
     <dimen name="scroll_zone">40dp</dimen>
-    <dimen name="workspace_page_spacing">24dp</dimen>
 
     <integer name="apps_customize_cling_focused_x">2</integer>
     <integer name="apps_customize_cling_focused_y">2</integer>
diff --git a/res/values-sw720dp/config.xml b/res/values-sw720dp/config.xml
index 4f537a9..c00b594 100644
--- a/res/values-sw720dp/config.xml
+++ b/res/values-sw720dp/config.xml
@@ -9,8 +9,6 @@
 <!-- Workspace -->
     <!-- Whether or not the drop targets drop down as opposed to fade in -->
     <bool name="config_useDropTargetDownTransition">false</bool>
-    <!-- Whether or not to fade the side pages -->
-    <bool name="config_workspaceFadeAdjacentScreens">true</bool>
 
     <!-- Camera distance for the overscroll effect -->
     <integer name="config_cameraDistance">18000</integer>
diff --git a/res/values-sw720dp/dimens.xml b/res/values-sw720dp/dimens.xml
index 01227e1..9ae155b 100644
--- a/res/values-sw720dp/dimens.xml
+++ b/res/values-sw720dp/dimens.xml
@@ -21,10 +21,6 @@
     <dimen name="toolbar_button_vertical_padding">8dip</dimen>
     <dimen name="toolbar_button_horizontal_padding">8dip</dimen>
 
-    <!-- dimensions for the wallpaper picker wallpaper thumbnail width -->
-    <dimen name="wallpaper_chooser_grid_width">196dp</dimen>
-    <dimen name="wallpaper_chooser_grid_height">140dp</dimen>
-
     <!-- When dragging items on the workspace, the number of dps by which the position of
      the drag view should be offset from the position of the original view. -->
     <dimen name="dragViewOffsetX">0dp</dimen>
diff --git a/res/values-sw720dp/styles.xml b/res/values-sw720dp/styles.xml
index 9738a12..71f0304 100644
--- a/res/values-sw720dp/styles.xml
+++ b/res/values-sw720dp/styles.xml
@@ -18,57 +18,14 @@
 -->
 
 <resources>
-<!-- Clings -->
-    <style name="ClingButton">
-        <item name="android:layout_width">wrap_content</item>
-        <item name="android:layout_height">wrap_content</item>
-        <item name="android:paddingTop">10dp</item>
-        <item name="android:paddingBottom">15dp</item>
-        <item name="android:paddingStart">35dp</item>
-        <item name="android:paddingEnd">35dp</item>
-        <item name="android:text">@string/cling_dismiss</item>
-        <item name="android:textSize">20sp</item>
-        <item name="android:textStyle">bold</item>
-        <item name="android:background">@drawable/cling_button_bg</item>
-    </style>
-    <style name="ClingTitleText">
-        <item name="android:layout_width">wrap_content</item>
-        <item name="android:layout_height">wrap_content</item>
-        <item name="android:layout_marginBottom">5dp</item>
-        <item name="android:textSize">32sp</item>
-        <item name="android:textColor">#49C0EC</item>
-        <item name="android:shadowColor">#000000</item>
-        <item name="android:shadowDy">2</item>
-        <item name="android:shadowRadius">2.0</item>
-    </style>
-    <style name="ClingText">
-        <item name="android:textSize">22sp</item>
-        <item name="android:textColor">#FFFFFF</item>
-        <item name="android:shadowColor">#000000</item>
-        <item name="android:shadowDy">2</item>
-        <item name="android:shadowRadius">2.0</item>
-        <item name="android:lineSpacingMultiplier">1.1</item>
-    </style>
-
 <!-- 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">
-        <item name="android:paddingStart">32dp</item>
-        <item name="android:paddingEnd">32dp</item>
+        <item name="android:paddingLeft">32dp</item>
+        <item name="android:paddingRight">32dp</item>
         <item name="android:textSize">14sp</item>
         <item name="android:maxWidth">240dp</item>
     </style>
 
-    <!-- QSB Search / Drop Target bar -->
-    <style name="QSBBar">
-    </style>
-    <style name="SearchDropTargetBar">
-    </style>
     <style name="SearchButton">
     </style>
     <style name="DropTargetButtonContainer">
@@ -81,8 +38,8 @@
         <item name="android:layout_gravity">center</item>
         <item name="android:gravity">center_vertical</item>
         <item name="android:drawablePadding">7.5dp</item>
-        <item name="android:paddingStart">60dp</item>
-        <item name="android:paddingEnd">60dp</item>
+        <item name="android:paddingLeft">60dp</item>
+        <item name="android:paddingRight">60dp</item>
         <item name="android:textColor">#FFFFFFFF</item>
         <item name="android:textSize">16sp</item>
         <item name="android:shadowColor">#393939</item>
diff --git a/res/values-th/strings.xml b/res/values-th/strings.xml
index 68118a7..413c78a 100644
--- a/res/values-th/strings.xml
+++ b/res/values-th/strings.xml
@@ -23,18 +23,6 @@
     <string name="home" msgid="7658288663002113681">"หน้าแรก"</string>
     <string name="uid_name" msgid="7820867637514617527">"แอปหลักของแอนดรอยด์"</string>
     <string name="folder_name" msgid="7371454440695724752"></string>
-    <string name="wallpaper_instructions" msgid="563973358787555519">"ตั้งค่าวอลเปเปอร์"</string>
-  <plurals name="number_of_items_selected">
-    <item quantity="zero" msgid="7464587177007785408">"เลือกไว้ %1$d"</item>
-    <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>
-    <string name="crop_wallpaper" msgid="8334345984491368009">"ครอบตัดวอลล์เปเปอร์"</string>
     <string name="activity_not_found" msgid="8071924732094499514">"ไม่ได้ติดตั้งแอป"</string>
     <string name="widgets_tab_label" msgid="2921133187116603919">"วิดเจ็ต"</string>
     <string name="widget_adder" msgid="3201040140710381657">"วิดเจ็ต"</string>
@@ -54,8 +42,8 @@
     <string name="group_widgets" msgid="1569030723286851002">"วิดเจ็ต"</string>
     <string name="completely_out_of_space" msgid="6106288382070760318">"ไม่มีที่ว่างในหน้าจอหลักของคุณ"</string>
     <string name="out_of_space" msgid="4691004494942118364">"ไม่มีที่ว่างในหน้าจอหลักนี้"</string>
-    <string name="hotseat_out_of_space" msgid="9139760413395605841">"ไม่มีที่ว่างใน hotseat"</string>
-    <string name="invalid_hotseat_item" msgid="1211534262129849507">"วิดเจ็ตนี้มีขนาดใหญ่เกินไปสำหรับ hotseat"</string>
+    <string name="hotseat_out_of_space" msgid="7448809638125333693">"ไม่มีพื้นที่เหลือในถาดรายการโปรด"</string>
+    <string name="invalid_hotseat_item" msgid="5779907847267573691">"วิดเจ็ตนี้มีขนาดใหญ่เกินไปสำหรับถาดรายการโปรด"</string>
     <string name="shortcut_installed" msgid="1701742129426969556">"สร้างทางลัด \"<xliff:g id="NAME">%s</xliff:g>\" แล้ว"</string>
     <string name="shortcut_uninstalled" msgid="8176767991305701821">"นำทางลัด \"<xliff:g id="NAME">%s</xliff:g>\" ออกแล้ว"</string>
     <string name="shortcut_duplicate" msgid="9167217446062498127">"มีทางลัด \"<xliff:g id="NAME">%s</xliff:g>\" อยู่แล้ว"</string>
@@ -96,15 +84,17 @@
     <string name="workspace_scroll_format" msgid="8458889198184077399">"หน้าจอหลัก %1$d จาก %2$d"</string>
     <string name="apps_customize_apps_scroll_format" msgid="370005296147130238">"แอปหน้า %1$d จาก %2$d"</string>
     <string name="apps_customize_widgets_scroll_format" msgid="3106209519974971521">"วิดเจ็ตหน้า %1$d จาก %2$d"</string>
-    <string name="first_run_cling_title" msgid="7257389003637362144">"ยินดีต้อนรับ!"</string>
+    <string name="first_run_cling_title" msgid="2459738000155917941">"ยินดีต้อนรับ"</string>
     <string name="first_run_cling_description" msgid="6447072552696253358">"ทำตัวตามสบาย"</string>
     <string name="first_run_cling_custom_content_hint" msgid="6090628589029352439"></string>
     <string name="first_run_cling_search_bar_hint" msgid="5909062802402452582"></string>
     <string name="first_run_cling_create_screens_hint" msgid="6950729526680114157">"สร้างหน้าจอเพิ่มสำหรับแอปและโฟลเดอร์"</string>
+    <string name="migration_cling_title" msgid="9181776667882933767">"คัดลอกไอคอนแอปของคุณ"</string>
+    <string name="migration_cling_description" msgid="2752413805582227644">"นำเข้าไอคอนและโฟลเดอร์จากหน้าจอหลักเก่าของคุณ"</string>
+    <string name="migration_cling_copy_apps" msgid="946331230090919440">"คัดลอกไอคอน"</string>
+    <string name="migration_cling_use_default" msgid="2626475813981258626">"เริ่มต้นใหม่"</string>
     <string name="workspace_cling_title" msgid="5626202359865825661">"จัดระเบียบพื้นที่ของคุณ"</string>
     <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_create_folder" msgid="6158215559475836131">"หากต้องการสร้างโฟลเดอร์ลักษณะนี้ แตะแอปค้างไว้ แล้วย้ายไปทับอีกแอปหนึ่ง"</string>
     <string name="cling_dismiss" msgid="8962359497601507581">"ตกลง"</string>
diff --git a/res/values-tl/strings.xml b/res/values-tl/strings.xml
index 56801b4..897631a 100644
--- a/res/values-tl/strings.xml
+++ b/res/values-tl/strings.xml
@@ -23,18 +23,6 @@
     <string name="home" msgid="7658288663002113681">"Home"</string>
     <string name="uid_name" msgid="7820867637514617527">"Android Core Apps"</string>
     <string name="folder_name" msgid="7371454440695724752"></string>
-    <string name="wallpaper_instructions" msgid="563973358787555519">"Itakda ang wallpaper"</string>
-  <plurals name="number_of_items_selected">
-    <item quantity="zero" msgid="7464587177007785408">"%1$d ang napili"</item>
-    <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>
-    <string name="crop_wallpaper" msgid="8334345984491368009">"I-crop ang wallpaper"</string>
     <string name="activity_not_found" msgid="8071924732094499514">"Hindi naka-install ang app."</string>
     <string name="widgets_tab_label" msgid="2921133187116603919">"Mga Widget"</string>
     <string name="widget_adder" msgid="3201040140710381657">"Mga Widget"</string>
@@ -54,8 +42,8 @@
     <string name="group_widgets" msgid="1569030723286851002">"Mga Widget"</string>
     <string name="completely_out_of_space" msgid="6106288382070760318">"Wala nang lugar sa iyong mga Home screen."</string>
     <string name="out_of_space" msgid="4691004494942118364">"Wala nang lugar sa Home screen na ito."</string>
-    <string name="hotseat_out_of_space" msgid="9139760413395605841">"Wala nang lugar sa hotseat."</string>
-    <string name="invalid_hotseat_item" msgid="1211534262129849507">"Masyadong malaki ang widget na ito para sa hotseat."</string>
+    <string name="hotseat_out_of_space" msgid="7448809638125333693">"Wala nang lugar sa tray ng Mga Paborito"</string>
+    <string name="invalid_hotseat_item" msgid="5779907847267573691">"Masyadong malaki ang widget na ito para sa tray ng Mga Paborito"</string>
     <string name="shortcut_installed" msgid="1701742129426969556">"Nagawa ang shortcut na \"<xliff:g id="NAME">%s</xliff:g>.\""</string>
     <string name="shortcut_uninstalled" msgid="8176767991305701821">"Inalis ang shortcut na \"<xliff:g id="NAME">%s</xliff:g>.\""</string>
     <string name="shortcut_duplicate" msgid="9167217446062498127">"Umiiral na ang shortcut na \"<xliff:g id="NAME">%s</xliff:g>.\""</string>
@@ -96,15 +84,17 @@
     <string name="workspace_scroll_format" msgid="8458889198184077399">"Home screen %1$d ng %2$d"</string>
     <string name="apps_customize_apps_scroll_format" msgid="370005296147130238">"Pahina ng apps %1$d ng %2$d"</string>
     <string name="apps_customize_widgets_scroll_format" msgid="3106209519974971521">"Pahina ng widget %1$d ng %2$d"</string>
-    <string name="first_run_cling_title" msgid="7257389003637362144">"Maligayang pagdating!"</string>
+    <string name="first_run_cling_title" msgid="2459738000155917941">"Maligayang Pagdating"</string>
     <string name="first_run_cling_description" msgid="6447072552696253358">"Gawing kumportable ang iyong sarili."</string>
     <string name="first_run_cling_custom_content_hint" msgid="6090628589029352439"></string>
     <string name="first_run_cling_search_bar_hint" msgid="5909062802402452582"></string>
     <string name="first_run_cling_create_screens_hint" msgid="6950729526680114157">"Gumawa ng higit pang mga screen para sa apps at mga folder"</string>
+    <string name="migration_cling_title" msgid="9181776667882933767">"Kopyahin ang mga icon ng app"</string>
+    <string name="migration_cling_description" msgid="2752413805582227644">"I-import ang icon at folder mula sa luma mong Home screen?"</string>
+    <string name="migration_cling_copy_apps" msgid="946331230090919440">"KOPYAHIN ANG MGA ICON"</string>
+    <string name="migration_cling_use_default" msgid="2626475813981258626">"MAGSIMULA NANG BAGO"</string>
     <string name="workspace_cling_title" msgid="5626202359865825661">"Ayusin ang iyong espasyo"</string>
     <string name="workspace_cling_move_item" msgid="528201129978005352">"Pindutin nang matagal ang background upang pamahalaan ang wallpaper, mga widget at setting"</string>
-    <string name="all_apps_cling_title" msgid="34929250753095858">"Pumili ng ilang apps"</string>
-    <string name="all_apps_cling_add_item" msgid="400866858451850784">"Upang magdagdag ng app sa iyong Home screen, pindutin ito nang matagal."</string>
     <string name="folder_cling_title" msgid="3894908818693254164">"Narito ang isang folder"</string>
     <string name="folder_cling_create_folder" msgid="6158215559475836131">"Upang gumawa ng katulad nito, pindutin nang matagal ang isang app, pagkatapos ay ilipat ito sa isa pang folder."</string>
     <string name="cling_dismiss" msgid="8962359497601507581">"OK"</string>
diff --git a/res/values-tr/strings.xml b/res/values-tr/strings.xml
index dbbdee2..42fa172 100644
--- a/res/values-tr/strings.xml
+++ b/res/values-tr/strings.xml
@@ -23,18 +23,6 @@
     <string name="home" msgid="7658288663002113681">"Ana ekran"</string>
     <string name="uid_name" msgid="7820867637514617527">"Android Çekirdek Uygulamaları"</string>
     <string name="folder_name" msgid="7371454440695724752"></string>
-    <string name="wallpaper_instructions" msgid="563973358787555519">"Duvar kağıdını ayarla"</string>
-  <plurals name="number_of_items_selected">
-    <item quantity="zero" msgid="7464587177007785408">"%1$d tane seçildi"</item>
-    <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>
-    <string name="crop_wallpaper" msgid="8334345984491368009">"Duvar kağıdını kırp"</string>
     <string name="activity_not_found" msgid="8071924732094499514">"Uygulama yüklü değil."</string>
     <string name="widgets_tab_label" msgid="2921133187116603919">"Widget\'lar"</string>
     <string name="widget_adder" msgid="3201040140710381657">"Widget\'lar"</string>
@@ -54,8 +42,8 @@
     <string name="group_widgets" msgid="1569030723286851002">"Widget\'lar"</string>
     <string name="completely_out_of_space" msgid="6106288382070760318">"Ana ekranlarınızda yer kalmadı."</string>
     <string name="out_of_space" msgid="4691004494942118364">"Bu Ana ekranda yer kalmadı."</string>
-    <string name="hotseat_out_of_space" msgid="9139760413395605841">"Favori kısa yollarda yer yok"</string>
-    <string name="invalid_hotseat_item" msgid="1211534262129849507">"Bu widget, favori kısa yollar için çok büyük."</string>
+    <string name="hotseat_out_of_space" msgid="7448809638125333693">"Favoriler tepsisinde başka yer kalmadı"</string>
+    <string name="invalid_hotseat_item" msgid="5779907847267573691">"Bu widget, Favoriler tepsisi için çok geniş"</string>
     <string name="shortcut_installed" msgid="1701742129426969556">"\"<xliff:g id="NAME">%s</xliff:g>\" kısayolu oluşturuldu."</string>
     <string name="shortcut_uninstalled" msgid="8176767991305701821">"\"<xliff:g id="NAME">%s</xliff:g>\" kısayolu kaldırıldı."</string>
     <string name="shortcut_duplicate" msgid="9167217446062498127">"\"<xliff:g id="NAME">%s</xliff:g>\" kısayolu zaten var."</string>
@@ -96,15 +84,17 @@
     <string name="workspace_scroll_format" msgid="8458889198184077399">"Ana ekran %1$d / %2$d"</string>
     <string name="apps_customize_apps_scroll_format" msgid="370005296147130238">"Uygulama sayfası %1$d / %2$d"</string>
     <string name="apps_customize_widgets_scroll_format" msgid="3106209519974971521">"Widget sayfası %1$d / %2$d"</string>
-    <string name="first_run_cling_title" msgid="7257389003637362144">"Hoş geldiniz!"</string>
+    <string name="first_run_cling_title" msgid="2459738000155917941">"Hoş geldiniz"</string>
     <string name="first_run_cling_description" msgid="6447072552696253358">"Rahatınıza bakın."</string>
     <string name="first_run_cling_custom_content_hint" msgid="6090628589029352439"></string>
     <string name="first_run_cling_search_bar_hint" msgid="5909062802402452582"></string>
     <string name="first_run_cling_create_screens_hint" msgid="6950729526680114157">"Uygulamalar ve klasörler için daha fazla ekran oluşturun"</string>
+    <string name="migration_cling_title" msgid="9181776667882933767">"Uygulama simgelerini kopyala"</string>
+    <string name="migration_cling_description" msgid="2752413805582227644">"Eski Ana ekranlarınızdaki simgeler ve klasörler içe aktarılsın mı?"</string>
+    <string name="migration_cling_copy_apps" msgid="946331230090919440">"SİMGELERİ KOPYALA"</string>
+    <string name="migration_cling_use_default" msgid="2626475813981258626">"VARSAYILANI KULLAN"</string>
     <string name="workspace_cling_title" msgid="5626202359865825661">"Alanınızı düzenleyin"</string>
     <string name="workspace_cling_move_item" msgid="528201129978005352">"Duvar kağıdını, widget\'ları ve ayarları yönetmek için arka plana uzun basın."</string>
-    <string name="all_apps_cling_title" msgid="34929250753095858">"İstediğiniz uygulamaları seçin"</string>
-    <string name="all_apps_cling_add_item" msgid="400866858451850784">"Bir uygulamayı Ana ekranınıza eklemek için, ilgili uygulamayı basılı tutun."</string>
     <string name="folder_cling_title" msgid="3894908818693254164">"İşte bir klasör"</string>
     <string name="folder_cling_create_folder" msgid="6158215559475836131">"Buna benzer bir klasör oluşturmak için uygulamaya uzun basın ve sonra uygulamayı başka bir uygulamanın üzerine taşıyın."</string>
     <string name="cling_dismiss" msgid="8962359497601507581">"Tamam"</string>
diff --git a/res/values-uk/strings.xml b/res/values-uk/strings.xml
index e0f3211..7cef321 100644
--- a/res/values-uk/strings.xml
+++ b/res/values-uk/strings.xml
@@ -23,18 +23,6 @@
     <string name="home" msgid="7658288663002113681">"Головний екран"</string>
     <string name="uid_name" msgid="7820867637514617527">"Базові програми Android"</string>
     <string name="folder_name" msgid="7371454440695724752"></string>
-    <string name="wallpaper_instructions" msgid="563973358787555519">"Установити фон"</string>
-  <plurals name="number_of_items_selected">
-    <item quantity="zero" msgid="7464587177007785408">"Вибрано %1$d"</item>
-    <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>
-    <string name="crop_wallpaper" msgid="8334345984491368009">"Обрізати фоновий малюнок"</string>
     <string name="activity_not_found" msgid="8071924732094499514">"Програму не встановлено."</string>
     <string name="widgets_tab_label" msgid="2921133187116603919">"Віджети"</string>
     <string name="widget_adder" msgid="3201040140710381657">"Віджети"</string>
@@ -54,8 +42,8 @@
     <string name="group_widgets" msgid="1569030723286851002">"Віджети"</string>
     <string name="completely_out_of_space" msgid="6106288382070760318">"На головних екранах більше немає місця."</string>
     <string name="out_of_space" msgid="4691004494942118364">"На цьому головному екрані більше немає місця."</string>
-    <string name="hotseat_out_of_space" msgid="9139760413395605841">"Немає вільного місця."</string>
-    <string name="invalid_hotseat_item" msgid="1211534262129849507">"Цей віджет завеликий."</string>
+    <string name="hotseat_out_of_space" msgid="7448809638125333693">"В області \"Вибране\" немає місця"</string>
+    <string name="invalid_hotseat_item" msgid="5779907847267573691">"Цей віджет завеликий для області \"Вибране\""</string>
     <string name="shortcut_installed" msgid="1701742129426969556">"Ярлик \"<xliff:g id="NAME">%s</xliff:g>\" створено."</string>
     <string name="shortcut_uninstalled" msgid="8176767991305701821">"Ярлик \"<xliff:g id="NAME">%s</xliff:g>\" вилучено."</string>
     <string name="shortcut_duplicate" msgid="9167217446062498127">"Ярлик \"<xliff:g id="NAME">%s</xliff:g>\" уже існує."</string>
@@ -96,15 +84,17 @@
     <string name="workspace_scroll_format" msgid="8458889198184077399">"Головний екран %1$d з %2$d"</string>
     <string name="apps_customize_apps_scroll_format" msgid="370005296147130238">"Сторінка програм %1$d з %2$d"</string>
     <string name="apps_customize_widgets_scroll_format" msgid="3106209519974971521">"Сторінка віджетів %1$d з %2$d"</string>
-    <string name="first_run_cling_title" msgid="7257389003637362144">"Вітаємо!"</string>
+    <string name="first_run_cling_title" msgid="2459738000155917941">"Вітаємо"</string>
     <string name="first_run_cling_description" msgid="6447072552696253358">"Будьте як удома."</string>
     <string name="first_run_cling_custom_content_hint" msgid="6090628589029352439"></string>
     <string name="first_run_cling_search_bar_hint" msgid="5909062802402452582"></string>
     <string name="first_run_cling_create_screens_hint" msgid="6950729526680114157">"Створюйте нові екрани для програм і папок"</string>
+    <string name="migration_cling_title" msgid="9181776667882933767">"Копіювати значки програм"</string>
+    <string name="migration_cling_description" msgid="2752413805582227644">"Імпортувати значки та папки зі старих головних екранів?"</string>
+    <string name="migration_cling_copy_apps" msgid="946331230090919440">"КОПІЮВАТИ ЗНАЧКИ"</string>
+    <string name="migration_cling_use_default" msgid="2626475813981258626">"ПАНЕЛЬ ЗАПУСКУ ЗА УМОВЧАННЯМ"</string>
     <string name="workspace_cling_title" msgid="5626202359865825661">"Організуйте робочий простір"</string>
     <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_create_folder" msgid="6158215559475836131">"Щоб створити папку, натисніть і утримуйте програму, а потім перетягніть її на іншу."</string>
     <string name="cling_dismiss" msgid="8962359497601507581">"OК"</string>
diff --git a/res/values-v17/styles.xml b/res/values-v17/styles.xml
new file mode 100644
index 0000000..71c4bfa
--- /dev/null
+++ b/res/values-v17/styles.xml
@@ -0,0 +1,9 @@
+<?xml version="1.0" encoding="utf-8"?>
+<resources>
+    <style name="PagedViewWidgetImageView">
+        <item name="android:paddingStart">@dimen/app_widget_preview_padding_left</item>
+    </style>
+    <style name="SearchButton.WithPaddingStart">
+        <item name="android:paddingStart">8dp</item>
+    </style>
+</resources>
diff --git a/res/values-vi/strings.xml b/res/values-vi/strings.xml
index 3b081d0..20a9b3a 100644
--- a/res/values-vi/strings.xml
+++ b/res/values-vi/strings.xml
@@ -23,18 +23,6 @@
     <string name="home" msgid="7658288663002113681">"Màn hình chính"</string>
     <string name="uid_name" msgid="7820867637514617527">"Ứng dụng lõi Android"</string>
     <string name="folder_name" msgid="7371454440695724752"></string>
-    <string name="wallpaper_instructions" msgid="563973358787555519">"Đặt hình nền"</string>
-  <plurals name="number_of_items_selected">
-    <item quantity="zero" msgid="7464587177007785408">"Đã chọn %1$d"</item>
-    <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>
-    <string name="crop_wallpaper" msgid="8334345984491368009">"Cắt hình nền"</string>
     <string name="activity_not_found" msgid="8071924732094499514">"Ứng dụng chưa được cài đặt."</string>
     <string name="widgets_tab_label" msgid="2921133187116603919">"Tiện ích con"</string>
     <string name="widget_adder" msgid="3201040140710381657">"Tiện ích con"</string>
@@ -54,8 +42,8 @@
     <string name="group_widgets" msgid="1569030723286851002">"Tiện ích con"</string>
     <string name="completely_out_of_space" msgid="6106288382070760318">"Không còn chỗ trên Màn hình chính của bạn."</string>
     <string name="out_of_space" msgid="4691004494942118364">"Không còn chỗ trên Màn hình chính này."</string>
-    <string name="hotseat_out_of_space" msgid="9139760413395605841">"Không còn chỗ trên vùng gắn."</string>
-    <string name="invalid_hotseat_item" msgid="1211534262129849507">"Tiện ích con này quá lớn cho vùng gắn."</string>
+    <string name="hotseat_out_of_space" msgid="7448809638125333693">"Không còn chỗ trong khay Mục yêu thích"</string>
+    <string name="invalid_hotseat_item" msgid="5779907847267573691">"Tiện ích con này có kích thước quá lớn để đặt vào khay Mục yêu thích"</string>
     <string name="shortcut_installed" msgid="1701742129426969556">"Lối tắt \"<xliff:g id="NAME">%s</xliff:g>\" đã được tạo."</string>
     <string name="shortcut_uninstalled" msgid="8176767991305701821">"Lối tắt \"<xliff:g id="NAME">%s</xliff:g>\" đã bị xóa."</string>
     <string name="shortcut_duplicate" msgid="9167217446062498127">"Lối tắt \"<xliff:g id="NAME">%s</xliff:g>\" đã tồn tại."</string>
@@ -96,15 +84,17 @@
     <string name="workspace_scroll_format" msgid="8458889198184077399">"Màn hình chính %1$d / %2$d"</string>
     <string name="apps_customize_apps_scroll_format" msgid="370005296147130238">"Trang ứng dụng %1$d / %2$d"</string>
     <string name="apps_customize_widgets_scroll_format" msgid="3106209519974971521">"Trang tiện ích con %1$d / %2$d"</string>
-    <string name="first_run_cling_title" msgid="7257389003637362144">"Xin chào!"</string>
+    <string name="first_run_cling_title" msgid="2459738000155917941">"Chào mừng"</string>
     <string name="first_run_cling_description" msgid="6447072552696253358">"Tự nhiên như ở nhà."</string>
     <string name="first_run_cling_custom_content_hint" msgid="6090628589029352439"></string>
     <string name="first_run_cling_search_bar_hint" msgid="5909062802402452582"></string>
     <string name="first_run_cling_create_screens_hint" msgid="6950729526680114157">"Tạo thêm màn hình cho ứng dụng và thư mục"</string>
+    <string name="migration_cling_title" msgid="9181776667882933767">"Sao chép biểu tượng ứng dụng của bạn"</string>
+    <string name="migration_cling_description" msgid="2752413805582227644">"Nhập biểu tượng và thư mục từ Màn hình chính cũ của bạn?"</string>
+    <string name="migration_cling_copy_apps" msgid="946331230090919440">"BIỂU TƯỢNG SAO CHÉP"</string>
+    <string name="migration_cling_use_default" msgid="2626475813981258626">"BẮT ĐẦU LÀM MỚI"</string>
     <string name="workspace_cling_title" msgid="5626202359865825661">"Sắp xếp không gian của bạn"</string>
     <string name="workspace_cling_move_item" msgid="528201129978005352">"Chạm và giữ nền để quản lý hình nền, tiện ích con và cài đặt."</string>
-    <string name="all_apps_cling_title" msgid="34929250753095858">"Chọn một số ứng dụng"</string>
-    <string name="all_apps_cling_add_item" msgid="400866858451850784">"Để thêm ứng dụng vào Màn hình chính của bạn, chạm và giữ ứng dụng đó."</string>
     <string name="folder_cling_title" msgid="3894908818693254164">"Đây là một thư mục"</string>
     <string name="folder_cling_create_folder" msgid="6158215559475836131">"Để tạo thư mục như thế này, hãy chạm và giữ một ứng dụng, sau đó di chuyển ứng dụng đó lên trên một ứng dụng khác."</string>
     <string name="cling_dismiss" msgid="8962359497601507581">"OK"</string>
diff --git a/res/values-zh-rCN/strings.xml b/res/values-zh-rCN/strings.xml
index 43a57c4..540291e 100644
--- a/res/values-zh-rCN/strings.xml
+++ b/res/values-zh-rCN/strings.xml
@@ -23,18 +23,6 @@
     <string name="home" msgid="7658288663002113681">"主屏"</string>
     <string name="uid_name" msgid="7820867637514617527">"Android 核心应用"</string>
     <string name="folder_name" msgid="7371454440695724752"></string>
-    <string name="wallpaper_instructions" msgid="563973358787555519">"设置壁纸"</string>
-  <plurals name="number_of_items_selected">
-    <item quantity="zero" msgid="7464587177007785408">"已选择%1$d项"</item>
-    <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>
-    <string name="crop_wallpaper" msgid="8334345984491368009">"剪裁壁纸"</string>
     <string name="activity_not_found" msgid="8071924732094499514">"未安装该应用。"</string>
     <string name="widgets_tab_label" msgid="2921133187116603919">"小部件"</string>
     <string name="widget_adder" msgid="3201040140710381657">"小部件"</string>
@@ -54,8 +42,8 @@
     <string name="group_widgets" msgid="1569030723286851002">"小部件"</string>
     <string name="completely_out_of_space" msgid="6106288382070760318">"您的主屏幕上没有空间了。"</string>
     <string name="out_of_space" msgid="4691004494942118364">"此主屏幕上已没有空间。"</string>
-    <string name="hotseat_out_of_space" msgid="9139760413395605841">"底部区域已无空间。"</string>
-    <string name="invalid_hotseat_item" msgid="1211534262129849507">"该小部件太大,底部区域容纳不下。"</string>
+    <string name="hotseat_out_of_space" msgid="7448809638125333693">"收藏栏已满"</string>
+    <string name="invalid_hotseat_item" msgid="5779907847267573691">"该小部件太大,收藏栏中放不下"</string>
     <string name="shortcut_installed" msgid="1701742129426969556">"已创建“<xliff:g id="NAME">%s</xliff:g>”快捷方式。"</string>
     <string name="shortcut_uninstalled" msgid="8176767991305701821">"已删除“<xliff:g id="NAME">%s</xliff:g>”快捷方式。"</string>
     <string name="shortcut_duplicate" msgid="9167217446062498127">"“<xliff:g id="NAME">%s</xliff:g>”快捷方式已存在。"</string>
@@ -96,15 +84,17 @@
     <string name="workspace_scroll_format" msgid="8458889198184077399">"主屏幕:第%1$d屏,共%2$d屏"</string>
     <string name="apps_customize_apps_scroll_format" msgid="370005296147130238">"应用:第%1$d页,共%2$d页"</string>
     <string name="apps_customize_widgets_scroll_format" msgid="3106209519974971521">"小部件:第%1$d页,共%2$d页"</string>
-    <string name="first_run_cling_title" msgid="7257389003637362144">"欢迎!"</string>
+    <string name="first_run_cling_title" msgid="2459738000155917941">"欢迎使用"</string>
     <string name="first_run_cling_description" msgid="6447072552696253358">"您的主屏幕您做主。"</string>
     <string name="first_run_cling_custom_content_hint" msgid="6090628589029352439"></string>
     <string name="first_run_cling_search_bar_hint" msgid="5909062802402452582"></string>
     <string name="first_run_cling_create_screens_hint" msgid="6950729526680114157">"添加更多屏幕来容纳应用和文件夹"</string>
+    <string name="migration_cling_title" msgid="9181776667882933767">"复制应用图标"</string>
+    <string name="migration_cling_description" msgid="2752413805582227644">"要导入旧的主屏幕中的图标和文件夹吗?"</string>
+    <string name="migration_cling_copy_apps" msgid="946331230090919440">"复制图标"</string>
+    <string name="migration_cling_use_default" msgid="2626475813981258626">"使用全新配置"</string>
     <string name="workspace_cling_title" msgid="5626202359865825661">"整理您的空间"</string>
     <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_create_folder" msgid="6158215559475836131">"要创建一个类似的文件夹,请触摸并按住某个应用,然后将其移至另一个应用上。"</string>
     <string name="cling_dismiss" msgid="8962359497601507581">"确定"</string>
diff --git a/res/values-zh-rHK/strings.xml b/res/values-zh-rHK/strings.xml
index eb3def4..c1486ef 100644
--- a/res/values-zh-rHK/strings.xml
+++ b/res/values-zh-rHK/strings.xml
@@ -23,18 +23,6 @@
     <string name="home" msgid="7658288663002113681">"主畫面"</string>
     <string name="uid_name" msgid="7820867637514617527">"Android 核心應用程式"</string>
     <string name="folder_name" msgid="7371454440695724752"></string>
-    <string name="wallpaper_instructions" msgid="563973358787555519">"設定桌布"</string>
-  <plurals name="number_of_items_selected">
-    <item quantity="zero" msgid="7464587177007785408">"已選取 %1$d 個"</item>
-    <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>
-    <string name="crop_wallpaper" msgid="8334345984491368009">"裁剪桌布"</string>
     <string name="activity_not_found" msgid="8071924732094499514">"尚未安裝應用程式。"</string>
     <string name="widgets_tab_label" msgid="2921133187116603919">"小工具"</string>
     <string name="widget_adder" msgid="3201040140710381657">"小工具"</string>
@@ -54,8 +42,8 @@
     <string name="group_widgets" msgid="1569030723286851002">"小工具"</string>
     <string name="completely_out_of_space" msgid="6106288382070760318">"主畫面已無空間。"</string>
     <string name="out_of_space" msgid="4691004494942118364">"主畫面已無空間。"</string>
-    <string name="hotseat_out_of_space" msgid="9139760413395605841">"停駐區已無可用空間。"</string>
-    <string name="invalid_hotseat_item" msgid="1211534262129849507">"這個小工具過大,停駐區沒有足夠空間。"</string>
+    <string name="hotseat_out_of_space" msgid="7448809638125333693">"我的收藏寄存區沒有足夠空間"</string>
+    <string name="invalid_hotseat_item" msgid="5779907847267573691">"這個小工具過大,我的收藏寄存區沒有足夠空間"</string>
     <string name="shortcut_installed" msgid="1701742129426969556">"已建立「<xliff:g id="NAME">%s</xliff:g>」捷徑。"</string>
     <string name="shortcut_uninstalled" msgid="8176767991305701821">"已移除「<xliff:g id="NAME">%s</xliff:g>」捷徑。"</string>
     <string name="shortcut_duplicate" msgid="9167217446062498127">"「<xliff:g id="NAME">%s</xliff:g>」捷徑已存在。"</string>
@@ -96,15 +84,17 @@
     <string name="workspace_scroll_format" msgid="8458889198184077399">"主畫面 %1$d,共 %2$d 個"</string>
     <string name="apps_customize_apps_scroll_format" msgid="370005296147130238">"第 %1$d 個應用程式頁面,共 %2$d 頁"</string>
     <string name="apps_customize_widgets_scroll_format" msgid="3106209519974971521">"第 %1$d 個小工具頁面,共 %2$d 頁"</string>
-    <string name="first_run_cling_title" msgid="7257389003637362144">"歡迎!"</string>
+    <string name="first_run_cling_title" msgid="2459738000155917941">"歡迎"</string>
     <string name="first_run_cling_description" msgid="6447072552696253358">"自訂主畫面。"</string>
     <string name="first_run_cling_custom_content_hint" msgid="6090628589029352439"></string>
     <string name="first_run_cling_search_bar_hint" msgid="5909062802402452582"></string>
     <string name="first_run_cling_create_screens_hint" msgid="6950729526680114157">"建立更多應用程式和資料夾的畫面"</string>
+    <string name="migration_cling_title" msgid="9181776667882933767">"複製您的應用程式圖示"</string>
+    <string name="migration_cling_description" msgid="2752413805582227644">"要從舊主畫面匯入圖示和資料夾嗎?"</string>
+    <string name="migration_cling_copy_apps" msgid="946331230090919440">"複製圖示"</string>
+    <string name="migration_cling_use_default" msgid="2626475813981258626">"重新開始"</string>
     <string name="workspace_cling_title" msgid="5626202359865825661">"管理您的空間"</string>
     <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_create_folder" msgid="6158215559475836131">"如要建立類似的資料夾,請輕觸並按住某個應用程式,然後疊到另一個應用程式之上。"</string>
     <string name="cling_dismiss" msgid="8962359497601507581">"確定"</string>
diff --git a/res/values-zh-rTW/strings.xml b/res/values-zh-rTW/strings.xml
index a68f163..d4acb20 100644
--- a/res/values-zh-rTW/strings.xml
+++ b/res/values-zh-rTW/strings.xml
@@ -23,18 +23,6 @@
     <string name="home" msgid="7658288663002113681">"主螢幕"</string>
     <string name="uid_name" msgid="7820867637514617527">"Android 核心應用程式"</string>
     <string name="folder_name" msgid="7371454440695724752"></string>
-    <string name="wallpaper_instructions" msgid="563973358787555519">"設定桌布"</string>
-  <plurals name="number_of_items_selected">
-    <item quantity="zero" msgid="7464587177007785408">"已選取 %1$d 個項目"</item>
-    <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>
-    <string name="crop_wallpaper" msgid="8334345984491368009">"裁剪桌布"</string>
     <string name="activity_not_found" msgid="8071924732094499514">"應用程式未安裝。"</string>
     <string name="widgets_tab_label" msgid="2921133187116603919">"小工具"</string>
     <string name="widget_adder" msgid="3201040140710381657">"小工具"</string>
@@ -54,8 +42,8 @@
     <string name="group_widgets" msgid="1569030723286851002">"小工具"</string>
     <string name="completely_out_of_space" msgid="6106288382070760318">"主螢幕已無空間。"</string>
     <string name="out_of_space" msgid="4691004494942118364">"這個主螢幕已無空間。"</string>
-    <string name="hotseat_out_of_space" msgid="9139760413395605841">"停駐區已無空間。"</string>
-    <string name="invalid_hotseat_item" msgid="1211534262129849507">"這個小工具過大,停駐區無法容納。"</string>
+    <string name="hotseat_out_of_space" msgid="7448809638125333693">"「我的最愛」匣已無可用空間"</string>
+    <string name="invalid_hotseat_item" msgid="5779907847267573691">"這個小工具過大,「我的最愛」匣無法容納"</string>
     <string name="shortcut_installed" msgid="1701742129426969556">"已建立「<xliff:g id="NAME">%s</xliff:g>」捷徑。"</string>
     <string name="shortcut_uninstalled" msgid="8176767991305701821">"已移除「<xliff:g id="NAME">%s</xliff:g>」捷徑。"</string>
     <string name="shortcut_duplicate" msgid="9167217446062498127">"「<xliff:g id="NAME">%s</xliff:g>」捷徑已存在。"</string>
@@ -96,15 +84,17 @@
     <string name="workspace_scroll_format" msgid="8458889198184077399">"主螢幕:第 %1$d 頁,共 %2$d 頁"</string>
     <string name="apps_customize_apps_scroll_format" msgid="370005296147130238">"應用程式:第 %1$d 頁,共 %2$d 頁"</string>
     <string name="apps_customize_widgets_scroll_format" msgid="3106209519974971521">"小工具:第 %1$d 頁,共 %2$d 頁"</string>
-    <string name="first_run_cling_title" msgid="7257389003637362144">"歡迎使用!"</string>
+    <string name="first_run_cling_title" msgid="2459738000155917941">"歡迎使用"</string>
     <string name="first_run_cling_description" msgid="6447072552696253358">"主螢幕由您作主。"</string>
     <string name="first_run_cling_custom_content_hint" msgid="6090628589029352439"></string>
     <string name="first_run_cling_search_bar_hint" msgid="5909062802402452582"></string>
     <string name="first_run_cling_create_screens_hint" msgid="6950729526680114157">"建立更多畫面容納應用程式和資料夾"</string>
+    <string name="migration_cling_title" msgid="9181776667882933767">"複製您的應用程式圖示"</string>
+    <string name="migration_cling_description" msgid="2752413805582227644">"要從舊的主螢幕匯入圖示和資料夾嗎?"</string>
+    <string name="migration_cling_copy_apps" msgid="946331230090919440">"複製圖示"</string>
+    <string name="migration_cling_use_default" msgid="2626475813981258626">"重新開始"</string>
     <string name="workspace_cling_title" msgid="5626202359865825661">"管理您的空間"</string>
     <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_create_folder" msgid="6158215559475836131">"如要建立類似的資料夾,請輕觸並按住應用程式,然後將應用程式疊放在另一個應用程式上。"</string>
     <string name="cling_dismiss" msgid="8962359497601507581">"確定"</string>
diff --git a/res/values-zu/strings.xml b/res/values-zu/strings.xml
index da790e6..c07f6a9 100644
--- a/res/values-zu/strings.xml
+++ b/res/values-zu/strings.xml
@@ -23,18 +23,6 @@
     <string name="home" msgid="7658288663002113681">"Ikhaya"</string>
     <string name="uid_name" msgid="7820867637514617527">"Izinhlelo zokusebenza ze-Android Core"</string>
     <string name="folder_name" msgid="7371454440695724752"></string>
-    <string name="wallpaper_instructions" msgid="563973358787555519">"Setha isithombe sangemuva"</string>
-  <plurals name="number_of_items_selected">
-    <item quantity="zero" msgid="7464587177007785408">"%1$d khethiwe"</item>
-    <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>
-    <string name="crop_wallpaper" msgid="8334345984491368009">"Nqampuna isithombe sangemuva"</string>
     <string name="activity_not_found" msgid="8071924732094499514">"Uhlelo lokusebenza alufakiwe."</string>
     <string name="widgets_tab_label" msgid="2921133187116603919">"Amawijethi"</string>
     <string name="widget_adder" msgid="3201040140710381657">"Amawijethi"</string>
@@ -54,8 +42,8 @@
     <string name="group_widgets" msgid="1569030723286851002">"Amawijethi"</string>
     <string name="completely_out_of_space" msgid="6106288382070760318">"Akusenagumbi ezikrinini zakho Zekhaya."</string>
     <string name="out_of_space" msgid="4691004494942118364">"Asisekho isikhala kulesi sikrini Sasekhaya."</string>
-    <string name="hotseat_out_of_space" msgid="9139760413395605841">"Akusenagumbi ku-hotseat."</string>
-    <string name="invalid_hotseat_item" msgid="1211534262129849507">"Le wijethi inkulu kakhulu ukuba ku-hotseat."</string>
+    <string name="hotseat_out_of_space" msgid="7448809638125333693">"Asisekho isikhala kwitreyi lezintandokazi"</string>
+    <string name="invalid_hotseat_item" msgid="5779907847267573691">"Le wijethi inkulu kakhulu ukuba kwitreyi lezintandokazi."</string>
     <string name="shortcut_installed" msgid="1701742129426969556">"Isinqamuleli esithi \"<xliff:g id="NAME">%s</xliff:g>\" sidaliwe."</string>
     <string name="shortcut_uninstalled" msgid="8176767991305701821">"Isinqamuleli esithi \"<xliff:g id="NAME">%s</xliff:g>\" sisusiwe."</string>
     <string name="shortcut_duplicate" msgid="9167217446062498127">"Isinqamuleli esithi \"<xliff:g id="NAME">%s</xliff:g>\" sesivele sikhona."</string>
@@ -96,15 +84,17 @@
     <string name="workspace_scroll_format" msgid="8458889198184077399">"Isikrini sasekhaya esingu-%1$d se-%2$d"</string>
     <string name="apps_customize_apps_scroll_format" msgid="370005296147130238">"Ikhasi lezinhlelo zokusebenza elingu-%1$d le-%2$d"</string>
     <string name="apps_customize_widgets_scroll_format" msgid="3106209519974971521">"Ikhasi lamawijethi elingu-%1$d le-%2$d"</string>
-    <string name="first_run_cling_title" msgid="7257389003637362144">"Siyakwamukela!"</string>
+    <string name="first_run_cling_title" msgid="2459738000155917941">"Siyakwamukela"</string>
     <string name="first_run_cling_description" msgid="6447072552696253358">"Zizwe usekhaya."</string>
     <string name="first_run_cling_custom_content_hint" msgid="6090628589029352439"></string>
     <string name="first_run_cling_search_bar_hint" msgid="5909062802402452582"></string>
     <string name="first_run_cling_create_screens_hint" msgid="6950729526680114157">"Dala izikrini eziningi zezinhlelo zokusebenza namafolda"</string>
+    <string name="migration_cling_title" msgid="9181776667882933767">"Kopisha izithonjana zakho zohlelo lokusebenza"</string>
+    <string name="migration_cling_description" msgid="2752413805582227644">"Ngenisa izithonjana namafolda kusukela kuzikrini zakho ezindala zasekhaya?"</string>
+    <string name="migration_cling_copy_apps" msgid="946331230090919440">"KOPISHA IZITHONJANA"</string>
+    <string name="migration_cling_use_default" msgid="2626475813981258626">"QALISA KABUSHA"</string>
     <string name="workspace_cling_title" msgid="5626202359865825661">"Hlela isikhala sakho"</string>
     <string name="workspace_cling_move_item" msgid="528201129978005352">"Thinta uphinde ubambe okungemuva ukuze uphathe isithombe sangemuva, amawijethi nezilungiselelo."</string>
-    <string name="all_apps_cling_title" msgid="34929250753095858">"Khetha izinhlelo zokusebenza ezithile"</string>
-    <string name="all_apps_cling_add_item" msgid="400866858451850784">"Ukuze ungeze uhlelo lokusebenza kusikrini sakho se-Ikhaya, thinta futhi uyibambe."</string>
     <string name="folder_cling_title" msgid="3894908818693254164">"Nayi ifolda"</string>
     <string name="folder_cling_create_folder" msgid="6158215559475836131">"Ukuze udale eyodwa efana nale, thinta uphinde ubambe uhlelo lokusebenza, bese ulidlulisa ngaphezulu kwelinye."</string>
     <string name="cling_dismiss" msgid="8962359497601507581">"KULUNGILE"</string>
diff --git a/res/values/attrs.xml b/res/values/attrs.xml
index a2d3a83..0006a74 100644
--- a/res/values/attrs.xml
+++ b/res/values/attrs.xml
@@ -103,8 +103,7 @@
         <attr name="pageLayoutPaddingBottom" format="dimension" />
         <attr name="pageLayoutPaddingLeft" format="dimension" />
         <attr name="pageLayoutPaddingRight" format="dimension" />
-        <!-- The space between adjacent pages of the PagedView. -->
-        <attr name="pageSpacing" format="dimension" />
+
         <!-- The page indicator for this workspace -->
         <attr name="pageIndicator" format="reference" />
     </declare-styleable>
diff --git a/res/values/colors.xml b/res/values/colors.xml
index dc35a3f..ffee05f 100644
--- a/res/values/colors.xml
+++ b/res/values/colors.xml
@@ -32,8 +32,8 @@
     <color name="workspace_icon_text_color">#FFF</color>
 
     <color name="apps_customize_icon_text_color">#FFF</color>
-    <color name="wallpaper_picker_translucent_gray">#66000000</color>
     <color name="folder_items_text_color">#FF333333</color>
+    <color name="folder_items_glow_color">#FFCCCCCC</color>
     <color name="outline_color">#FFFFFFFF</color>
     
     <color name="first_run_cling_circle_background_color">#64b1ea</color>
diff --git a/res/values/config.xml b/res/values/config.xml
index 4978281..b512ffe 100644
--- a/res/values/config.xml
+++ b/res/values/config.xml
@@ -1,4 +1,14 @@
 <resources>
+<!-- Dynamic Grid -->
+    <integer name="config_dynamic_grid_max_long_edge_cell_count">6</integer>
+    <integer name="config_dynamic_grid_max_short_edge_cell_count">5</integer>
+    <integer name="config_dynamic_grid_min_edge_cell_count">3</integer>
+    <!-- Out of 100, the percent of space the overview bar should try and take vertically. -->
+    <integer name="config_dynamic_grid_overview_icon_zone_percentage">20</integer>
+    <!-- Out of 100, the percent to shrink the workspace during overview mode. -->
+    <integer name="config_dynamic_grid_overview_scale_percentage">80</integer>
+
+<!-- Miscellaneous -->
     <bool name="config_largeHeap">false</bool>
     <bool name="is_tablet">false</bool>
     <bool name="is_large_tablet">false</bool>
@@ -18,8 +28,6 @@
 
     <!-- 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. -->
-    <integer name="config_workspaceOverviewShrinkPercentage">58</integer>
 
     <!-- Fade/zoom in/out duration & scale in the AllApps transition.
          Note: This should be less than the workspaceShrinkTime as they happen together. -->
@@ -44,8 +52,6 @@
 <!-- Workspace -->
     <!-- Whether or not the drop targets drop down as opposed to fade in -->
     <bool name="config_useDropTargetDownTransition">false</bool>
-    <!-- Whether or not to fade the side pages -->
-    <bool name="config_workspaceFadeAdjacentScreens">false</bool>
 
     <!-- The transition duration for the background of the drop targets -->
     <integer name="config_dropTargetBgTransitionDuration">0</integer>
@@ -88,4 +94,7 @@
          filter the activities shown in the launcher. Can be empty. -->
     <string name="app_filter_class" translatable="false"></string>
 
+    <!-- Name of a subclass of com.android.launcher3.BuildInfo used to
+         get build information. Can be empty. -->
+    <string name="build_info_class" translatable="false"></string>
 </resources>
diff --git a/res/values/dimens.xml b/res/values/dimens.xml
index b4b2367..1eca5b3 100644
--- a/res/values/dimens.xml
+++ b/res/values/dimens.xml
@@ -20,11 +20,13 @@
     <dimen name="dynamic_grid_search_bar_max_width">500dp</dimen>
     <dimen name="dynamic_grid_search_bar_height">48dp</dimen>
     <dimen name="dynamic_grid_page_indicator_height">24dp</dimen>
-
-<!-- Wallpaper picker -->
-    <dimen name="wallpaperThumbnailWidth">106.5dp</dimen>
-    <dimen name="wallpaperThumbnailHeight">94.5dp</dimen>
-    <dimen name="wallpaperItemIconSize">32dp</dimen>
+    <dimen name="dynamic_grid_icon_drawable_padding">4dp</dimen>
+    <dimen name="dynamic_grid_all_apps_cell_padding">18dp</dimen>
+    <dimen name="dynamic_grid_workspace_page_spacing">8dp</dimen>
+    <dimen name="dynamic_grid_overview_min_icon_zone_height">80dp</dimen>
+    <dimen name="dynamic_grid_overview_max_icon_zone_height">120dp</dimen>
+    <dimen name="dynamic_grid_overview_bar_item_width">48dp</dimen>
+    <dimen name="dynamic_grid_overview_bar_spacer_width">68dp</dimen>
 
 <!-- Cling -->
     <dimen name="clingPunchThroughGraphicCenterRadius">94dp</dimen>
@@ -36,14 +38,16 @@
     <add-resource type="dimen" name="custom_cling_margin_top" />
     <add-resource type="dimen" name="custom_cling_margin_right" />
     <add-resource type="dimen" name="custom_cling_margin_left" />
+    
+    <dimen name="cling_title_text_size">20sp</dimen>
+    <dimen name="cling_text_size">14sp</dimen>
+    <dimen name="cling_alt_title_text_size">24sp</dimen>
+    <dimen name="cling_alt_text_size">16sp</dimen>
+    <dimen name="cling_hint_text_size">14sp</dimen>
 
 <!-- Workspace -->
     <dimen name="workspace_max_gap">16dp</dimen>
     <dimen name="workspace_overscroll_drawable_padding">0dp</dimen>
-    <dimen name="workspace_spring_loaded_page_spacing">15dp</dimen>
-    <dimen name="overview_panel_bottom_padding">50dp</dimen>
-    <dimen name="overview_panel_buttonSpacing">60dp</dimen>
-    <dimen name="overview_mode_page_offset">130dp</dimen>
 
 <!-- QSB -->
     <dimen name="toolbar_button_vertical_padding">4dip</dimen>
diff --git a/res/values/strings.xml b/res/values/strings.xml
index cafa424..2c6306a 100644
--- a/res/values/strings.xml
+++ b/res/values/strings.xml
@@ -28,30 +28,6 @@
     <string name="uid_name">Android Core Apps</string>
     <!-- Default folder name -->
     <string name="folder_name"></string>
-    <!-- Button label on Wallpaper picker screen; user selects this button to set a specific wallpaper -->
-    <string name="wallpaper_instructions">Set wallpaper</string>
-    <!-- Shown when wallpapers are selected in Wallpaper picker -->
-    <!-- String indicating how many media item(s) is(are) selected
-            eg. 1 selected [CHAR LIMIT=30] -->
-    <plurals name="number_of_items_selected">
-        <item quantity="zero">%1$d selected</item>
-        <item quantity="one">%1$d selected</item>
-        <item quantity="other">%1$d selected</item>
-    </plurals>
-    <!-- Accessibility string used as a label for a particular wallpaper in the Wallpaper Picker list.
-         e.g. "Wallpaper 3 of 10" -->
-    <string name="wallpaper_accessibility_name">Wallpaper %1$d of %2$d</string>
-    <!-- Accessibility string used to announce that a wallpaper has been selected. -->
-    <string name="announce_selection">Selected <xliff:g id="label" example="Wallpaper 3 of 10">%1$s</xliff:g></string>
-
-    <!-- Label on button to delete wallpaper(s) -->
-    <string name="wallpaper_delete">Delete</string>
-    <!-- Label on button in Wallpaper Picker to pick an image -->
-    <string name="pick_image">Pick image</string>
-    <!-- Option in "Select wallpaper from" dialog box -->
-    <string name="pick_wallpaper">Wallpapers</string>
-    <!-- Title of activity for cropping wallpapers -->
-    <string name="crop_wallpaper">Crop wallpaper</string>
     <!-- Displayed when user selects a shortcut for an app that was uninstalled [CHAR_LIMIT=none]-->
     <string name="activity_not_found">App isn\'t installed.</string>
     <!--  Labels for the tabs in the customize drawer -->
@@ -109,9 +85,9 @@
     <!-- Error message when user has filled a home screen -->
     <string name="out_of_space">No more room on this Home screen.</string>
     <!-- Error message when user has filled the hotseat -->
-    <string name="hotseat_out_of_space">No more room on the hotseat.</string>
+    <string name="hotseat_out_of_space">No more room in the Favorites tray</string>
     <!-- Error message when user tries to drop an invalid item on the hotseat -->
-    <string name="invalid_hotseat_item">This widget is too large for the hotseat.</string>
+    <string name="invalid_hotseat_item">This widget is too large for the Favorites tray</string>
     <!-- Message displayed when a shortcut is created by an external application -->
     <string name="shortcut_installed">Shortcut \"<xliff:g id="name" example="Browser">%s</xliff:g>\" created.</string>
     <!-- Message displayed when a shortcut is uninstalled by an external application -->
@@ -230,8 +206,8 @@
     <string name="apps_customize_widgets_scroll_format">Widgets page %1$d of %2$d</string>
 
     <!-- Clings -->
-    <!-- The title text for the workspace cling [CHAR_LIMIT=60] -->
-    <string name="first_run_cling_title">Welcome!</string>
+    <!-- The title text for the workspace cling [CHAR_LIMIT=30] -->
+    <string name="first_run_cling_title">Welcome</string>
     <!-- The description of how to use the workspace [CHAR_LIMIT=60] -->
     <string name="first_run_cling_description">Make yourself at home.</string>
     <!-- The description of how to use the workspace [CHAR_LIMIT=60] -->
@@ -240,17 +216,21 @@
     <string name="first_run_cling_search_bar_hint"></string>
     <!-- The description of how to use the workspace [CHAR_LIMIT=60] -->
     <string name="first_run_cling_create_screens_hint">Create more screens for apps and folders</string>
-    <!-- The title text for the workspace cling [CHAR_LIMIT=60] -->
+    <!-- The title text for the migration cling [CHAR_LIMIT=30] -->
+    <string name="migration_cling_title">Copy your app icons</string>
+    <!-- The description of what migration does [CHAR_LIMIT=70] -->
+    <string name="migration_cling_description">Import icons and folders from your old Home screens?</string>
+    <!-- The description of the button to migrate apps from another launcher [CHAR_LIMIT=30] -->
+    <string name="migration_cling_copy_apps">COPY ICONS</string>
+    <!-- The description of the button to use the default launcher layout [CHAR_LIMIT=30] -->
+    <string name="migration_cling_use_default">START FRESH</string>
+    <!-- The title text for the workspace cling [CHAR_LIMIT=30] -->
     <string name="workspace_cling_title">Organize your space</string>
-    <!-- The description of how to use the workspace [CHAR_LIMIT=160] -->
+    <!-- The description of how to use the workspace [CHAR_LIMIT=70] -->
     <string name="workspace_cling_move_item">Touch &amp; hold background to manage wallpaper, widgets and settings.</string>
-    <!-- The title text for the All Apps cling [CHAR_LIMIT=60] -->
-    <string name="all_apps_cling_title">Choose some apps</string>
-    <!-- The description of how to pick up and add an item to the workspace [CHAR_LIMIT=160] -->
-    <string name="all_apps_cling_add_item">To add an app to your Home screen, touch &amp; hold it.</string>
-    <!-- The title text for the Folder cling [CHAR_LIMIT=60] -->
+    <!-- The title text for the Folder cling [CHAR_LIMIT=30] -->
     <string name="folder_cling_title">Here\'s a folder</string>
-    <!-- The description of how to create a folder [CHAR_LIMIT=160] -->
+    <!-- The description of how to create a folder [CHAR_LIMIT=70] -->
     <string name="folder_cling_create_folder">To create one like this, touch &amp; hold an app, then move it over another.</string>
     <!-- The text on the button to dismiss a cling [CHAR_LIMIT=30] -->
     <string name="cling_dismiss">OK</string>
diff --git a/res/values/styles.xml b/res/values/styles.xml
index a1d2c5c..c18dccb 100644
--- a/res/values/styles.xml
+++ b/res/values/styles.xml
@@ -18,30 +18,13 @@
 -->
 
 <resources>
-    <style name="Theme.WallpaperCropper" parent="@android:style/Theme.Holo">
-        <item name="android:actionBarStyle">@style/WallpaperCropperActionBar</item>
-        <item name="android:windowFullscreen">true</item>
-        <item name="android:windowActionBarOverlay">true</item>
-        <item name="android:windowTranslucentNavigation">true</item>
-    </style>
-
-    <style name="WallpaperCropperActionBar" parent="android:style/Widget.Holo.ActionBar">
-        <item name="android:displayOptions">showCustom</item>
-        <item name="android:background">#88000000</item>
-    </style>
-
-    <style name="Theme" parent="@android:style/Theme.Holo.Wallpaper.NoTitleBar">
-        <item name="android:windowTranslucentStatus">true</item>
-        <item name="android:windowTranslucentNavigation">true</item>
-    </style>
-
     <style name="ClingButton">
         <item name="android:layout_width">wrap_content</item>
         <item name="android:layout_height">wrap_content</item>
         <item name="android:paddingTop">15dp</item>
         <item name="android:paddingBottom">15dp</item>
-        <item name="android:paddingStart">50dp</item>
-        <item name="android:paddingEnd">50dp</item>
+        <item name="android:paddingLeft">50dp</item>
+        <item name="android:paddingRight">50dp</item>
         <item name="android:text">@string/cling_dismiss</item>
         <item name="android:textColor">#ffffff</item>
         <item name="android:textStyle">bold</item>
@@ -52,27 +35,33 @@
         <item name="android:layout_width">wrap_content</item>
         <item name="android:layout_height">wrap_content</item>
         <item name="android:layout_marginBottom">5dp</item>
-        <item name="android:textSize">22sp</item>
+        <item name="android:textSize">@dimen/cling_title_text_size</item>
         <item name="android:textColor">#ffffff</item>
         <item name="android:fontFamily">sans-serif-condensed</item>
     </style>
-    <style name="ClingAltTitleText">
-        <item name="android:layout_width">wrap_content</item>
-        <item name="android:layout_height">wrap_content</item>
-        <item name="android:textSize">24sp</item>
-        <item name="android:textColor">#49C0EC</item>
-    </style>
     <style name="ClingText">
         <item name="android:layout_width">wrap_content</item>
         <item name="android:layout_height">wrap_content</item>
-        <item name="android:textSize">16sp</item>
+        <item name="android:textSize">@dimen/cling_text_size</item>
         <item name="android:textColor">#80000000</item>
         <item name="android:lineSpacingMultiplier">1.1</item>
     </style>
+    <style name="ClingAltTitleText">
+        <item name="android:layout_width">wrap_content</item>
+        <item name="android:layout_height">wrap_content</item>
+        <item name="android:textSize">@dimen/cling_alt_title_text_size</item>
+        <item name="android:textColor">#49C0EC</item>
+    </style>
+    <style name="ClingAltText">
+        <item name="android:layout_width">wrap_content</item>
+        <item name="android:layout_height">wrap_content</item>
+        <item name="android:textSize">@dimen/cling_alt_text_size</item>
+        <item name="android:textColor">#49C0EC</item>
+    </style>
     <style name="ClingHintText">
         <item name="android:layout_width">wrap_content</item>
         <item name="android:layout_height">wrap_content</item>
-        <item name="android:textSize">18sp</item>
+        <item name="android:textSize">@dimen/cling_hint_text_size</item>
         <item name="android:textColor">#80ffffff</item>
         <item name="android:fontFamily">sans-serif-condensed</item>
     </style>
@@ -98,14 +87,10 @@
     <style name="WorkspaceIcon.AppsCustomize">
         <item name="android:background">@null</item>
         <item name="android:textColor">@color/apps_customize_icon_text_color</item>
-        <item name="android:drawablePadding">4dp</item>
+        <item name="android:drawablePadding">@dimen/dynamic_grid_icon_drawable_padding</item>
         <item name="android:shadowRadius">4.0</item>
         <item name="android:shadowColor">#FF000000</item>
     </style>
-
-    <style name="QSBBar">
-        <item name="android:orientation">horizontal</item>
-    </style>
     <style name="SearchDropTargetBar">
     </style>
     <style name="SearchButton">
@@ -120,8 +105,8 @@
         <item name="android:layout_gravity">center</item>
         <item name="android:gravity">center_vertical</item>
         <item name="android:drawablePadding">7.5dp</item>
-        <item name="android:paddingStart">25dp</item>
-        <item name="android:paddingEnd">25dp</item>
+        <item name="android:paddingLeft">25dp</item>
+        <item name="android:paddingRight">25dp</item>
         <item name="android:textColor">#FFFFFFFF</item>
         <item name="android:textSize">16sp</item>
         <item name="android:singleLine">true</item>
@@ -136,8 +121,8 @@
         <item name="android:layout_width">wrap_content</item>
         <item name="android:layout_height">match_parent</item>
         <item name="android:gravity">center</item>
-        <item name="android:paddingStart">20dp</item>
-        <item name="android:paddingEnd">20dp</item>
+        <item name="android:paddingLeft">20dp</item>
+        <item name="android:paddingRight">20dp</item>
         <item name="android:background">@drawable/tab_widget_indicator_selector</item>
         <item name="android:textColor">?android:attr/textColorPrimary</item>
         <item name="android:textSize">12sp</item>
@@ -151,8 +136,8 @@
     </style>
 
     <style name="MarketButton">
-        <item name="android:paddingStart">5dp</item>
-        <item name="android:paddingEnd">5dp</item>
+        <item name="android:paddingLeft">5dp</item>
+        <item name="android:paddingRight">5dp</item>
         <item name="android:textColor">@color/workspace_all_apps_and_delete_zone_text_color</item>
         <item name="android:textSize">18sp</item>
         <item name="android:shadowColor">@color/workspace_all_apps_and_delete_zone_text_shadow_color</item>
@@ -166,4 +151,10 @@
     </style>
     <style name="CustomClingText">
     </style>
+    <style name="PagedViewWidgetImageView">
+        <item name="android:paddingLeft">@dimen/app_widget_preview_padding_left</item>
+    </style>
+    <style name="SearchButton.WithPaddingStart">
+        <item name="android:paddingLeft">8dp</item>
+    </style>
 </resources>
diff --git a/res/xml/default_workspace_no_all_apps.xml b/res/xml/default_workspace_no_all_apps.xml
new file mode 100644
index 0000000..7e1301c
--- /dev/null
+++ b/res/xml/default_workspace_no_all_apps.xml
@@ -0,0 +1,56 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2013 The Android Open Source Project
+
+     Licensed under the Apache License, Version 2.0 (the "License");
+     you may not use this file except in compliance with the License.
+     You may obtain a copy of the License at
+
+          http://www.apache.org/licenses/LICENSE-2.0
+
+     Unless required by applicable law or agreed to in writing, software
+     distributed under the License is distributed on an "AS IS" BASIS,
+     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+     See the License for the specific language governing permissions and
+     limitations under the License.
+-->
+
+<favorites xmlns:launcher="http://schemas.android.com/apk/res-auto/com.android.launcher3">
+    <!-- Hotseat (We use the screen as the position of the item in the hotseat) -->
+    <!-- Dialer Hangouts Maps Chrome Camera -->
+    <favorite
+        launcher:packageName="com.google.android.dialer"
+        launcher:className="com.google.android.dialer.extensions.GoogleDialtactsActivity"
+        launcher:container="-101"
+        launcher:screen="0"
+        launcher:x="0"
+        launcher:y="0" />
+    <favorite
+        launcher:packageName="com.google.android.talk"
+        launcher:className="com.google.android.talk.SigningInActivity"
+        launcher:container="-101"
+        launcher:screen="1"
+        launcher:x="1"
+        launcher:y="0" />
+    <favorite
+        launcher:packageName="com.google.android.apps.maps"
+        launcher:className="com.google.android.maps.MapsActivity"
+        launcher:container="-101"
+        launcher:screen="2"
+        launcher:x="2"
+        launcher:y="0"/>
+    <favorite
+        launcher:packageName="com.android.chrome"
+        launcher:className="com.google.android.apps.chrome.Main"
+        launcher:container="-101"
+        launcher:screen="3"
+        launcher:x="3"
+        launcher:y="0" />
+    <favorite
+        launcher:packageName="com.google.android.GoogleCamera"
+        launcher:className="com.android.camera.CameraLauncher"
+        launcher:container="-101"
+        launcher:screen="4"
+        launcher:x="4"
+        launcher:y="0" />
+</favorites>
+
diff --git a/src/com/android/launcher3/AddAdapter.java b/src/com/android/launcher3/AddAdapter.java
index ad15e75..5308a3d 100644
--- a/src/com/android/launcher3/AddAdapter.java
+++ b/src/com/android/launcher3/AddAdapter.java
@@ -27,8 +27,6 @@
 
 import java.util.ArrayList;
 
-import com.android.launcher3.R;
-
 /**
  * Adapter showing the types of items that can be added to a {@link Workspace}.
  */
diff --git a/src/com/android/launcher3/Alarm.java b/src/com/android/launcher3/Alarm.java
index 91f9bd0..e9f1fd9 100644
--- a/src/com/android/launcher3/Alarm.java
+++ b/src/com/android/launcher3/Alarm.java
@@ -78,7 +78,3 @@
         return mAlarmPending;
     }
 }
-
-interface OnAlarmListener {
-    public void onAlarm(Alarm alarm);
-}
diff --git a/src/com/android/launcher3/AllAppsList.java b/src/com/android/launcher3/AllAppsList.java
index d955e4e..b641eb5 100644
--- a/src/com/android/launcher3/AllAppsList.java
+++ b/src/com/android/launcher3/AllAppsList.java
@@ -16,9 +16,6 @@
 
 package com.android.launcher3;
 
-import java.util.ArrayList;
-import java.util.List;
-
 import android.content.ComponentName;
 import android.content.Context;
 import android.content.Intent;
@@ -26,6 +23,9 @@
 import android.content.pm.PackageManager;
 import android.content.pm.ResolveInfo;
 
+import java.util.ArrayList;
+import java.util.List;
+
 
 /**
  * Stores the list of all applications for the all apps view.
diff --git a/src/com/android/launcher3/AppInfo.java b/src/com/android/launcher3/AppInfo.java
index 53f81bb..d5a7769 100644
--- a/src/com/android/launcher3/AppInfo.java
+++ b/src/com/android/launcher3/AppInfo.java
@@ -18,9 +18,9 @@
 
 import android.content.ComponentName;
 import android.content.Intent;
+import android.content.pm.PackageInfo;
 import android.content.pm.PackageManager;
 import android.content.pm.PackageManager.NameNotFoundException;
-import android.content.pm.PackageInfo;
 import android.content.pm.ResolveInfo;
 import android.graphics.Bitmap;
 import android.util.Log;
diff --git a/src/com/android/launcher3/AppWidgetResizeFrame.java b/src/com/android/launcher3/AppWidgetResizeFrame.java
index fcb04ea..f57f4d0 100644
--- a/src/com/android/launcher3/AppWidgetResizeFrame.java
+++ b/src/com/android/launcher3/AppWidgetResizeFrame.java
@@ -13,8 +13,6 @@
 import android.widget.FrameLayout;
 import android.widget.ImageView;
 
-import com.android.launcher3.R;
-
 public class AppWidgetResizeFrame extends FrameLayout {
     private LauncherAppWidgetHostView mWidgetView;
     private CellLayout mCellLayout;
diff --git a/src/com/android/launcher3/AppsCustomizePagedView.java b/src/com/android/launcher3/AppsCustomizePagedView.java
index 9b35bb5..49b12b1 100644
--- a/src/com/android/launcher3/AppsCustomizePagedView.java
+++ b/src/com/android/launcher3/AppsCustomizePagedView.java
@@ -187,6 +187,7 @@
     private PagedViewCellLayout mWidgetSpacingLayout;
     private int mNumAppsPages;
     private int mNumWidgetPages;
+    private Rect mAllAppsPadding = new Rect();
 
     // Relating to the scroll and overscroll effects
     Workspace.ZInterpolator mZInterpolator = new Workspace.ZInterpolator(0.5f);
@@ -198,8 +199,6 @@
     private AccelerateInterpolator mAlphaInterpolator = new AccelerateInterpolator(0.9f);
     private DecelerateInterpolator mLeftScreenAlphaInterpolator = new DecelerateInterpolator(4);
 
-    public static boolean DISABLE_ALL_APPS = false;
-
     // Previews & outlines
     ArrayList<AppsCustomizeAsyncTask> mRunningTasks;
     private static final int sPageSleepDelay = 200;
@@ -293,6 +292,20 @@
                 grid.edgeMarginPx, 2 * grid.edgeMarginPx);
     }
 
+    void setAllAppsPadding(Rect r) {
+        mAllAppsPadding.set(r);
+    }
+    void setWidgetsPageIndicatorPadding(int pageIndicatorHeight) {
+        mPageLayoutPaddingBottom = pageIndicatorHeight;
+    }
+
+    WidgetPreviewLoader getWidgetPreviewLoader() {
+        if (mWidgetPreviewLoader == null) {
+            mWidgetPreviewLoader = new WidgetPreviewLoader(mLauncher);
+        }
+        return mWidgetPreviewLoader;
+    }
+
     /** Returns the item index of the center item on this page so that we can restore to this
      *  item index when we rotate. */
     private int getMiddleComponentIndexOnCurrentPage() {
@@ -358,10 +371,6 @@
     }
 
     protected void onDataReady(int width, int height) {
-        if (mWidgetPreviewLoader == null) {
-            mWidgetPreviewLoader = new WidgetPreviewLoader(mLauncher);
-        }
-
         // Now that the data is ready, we can calculate the content width, the number of cells to
         // use for each page
         LauncherAppState app = LauncherAppState.getInstance();
@@ -419,7 +428,7 @@
         int width = MeasureSpec.getSize(widthMeasureSpec);
         int height = MeasureSpec.getSize(heightMeasureSpec);
         if (!isDataReady()) {
-            if ((DISABLE_ALL_APPS || !mApps.isEmpty()) && !mWidgets.isEmpty()) {
+            if ((LauncherAppState.isDisableAllApps() || !mApps.isEmpty()) && !mWidgets.isEmpty()) {
                 setDataIsReady();
                 setMeasuredDimension(width, height);
                 onDataReady(width, height);
@@ -721,13 +730,13 @@
 
             int[] previewSizeBeforeScale = new int[1];
 
-            preview = mWidgetPreviewLoader.generateWidgetPreview(createWidgetInfo.componentName,
+            preview = getWidgetPreviewLoader().generateWidgetPreview(createWidgetInfo.componentName,
                     createWidgetInfo.previewImage, createWidgetInfo.icon, spanX, spanY,
                     maxWidth, maxHeight, null, previewSizeBeforeScale);
 
             // Compare the size of the drag preview to the preview in the AppsCustomize tray
             int previewWidthInAppsCustomize = Math.min(previewSizeBeforeScale[0],
-                    mWidgetPreviewLoader.maxWidthForWidgetPreview(spanX));
+                    getWidgetPreviewLoader().maxWidthForWidgetPreview(spanX));
             scale = previewWidthInAppsCustomize / (float) preview.getWidth();
 
             // The bitmap in the AppsCustomize tray is always the the same size, so there
@@ -811,13 +820,23 @@
                 !(target instanceof DeleteDropTarget))) {
             // Exit spring loaded mode if we have not successfully dropped or have not handled the
             // drop in Workspace
-            mLauncher.exitSpringLoadedDragMode();
+            mLauncher.getWorkspace().removeExtraEmptyScreen(true, new Runnable() {
+                @Override
+                public void run() {
+                    mLauncher.exitSpringLoadedDragMode();
+                    mLauncher.unlockScreenOrientation(false);
+                }
+            });
+        } else {
+            mLauncher.unlockScreenOrientation(false);
         }
-        mLauncher.unlockScreenOrientation(false);
     }
 
     @Override
     public View getContent() {
+        if (getChildCount() > 0) {
+            return getChildAt(0);
+        }
         return null;
     }
 
@@ -841,7 +860,7 @@
     public void onLauncherTransitionEnd(Launcher l, boolean animated, boolean toWorkspace) {
         mInTransition = false;
         for (AsyncTaskPageData d : mDeferredSyncWidgetPageItems) {
-            onSyncWidgetPageItems(d);
+            onSyncWidgetPageItems(d, false);
         }
         mDeferredSyncWidgetPageItems.clear();
         for (Runnable r : mDeferredPrepareLoadWidgetPreviewsTasks) {
@@ -898,6 +917,23 @@
     }
 
     @Override
+    public boolean supportsAppInfoDropTarget() {
+        return true;
+    }
+
+    @Override
+    public boolean supportsDeleteDropTarget() {
+        return false;
+    }
+
+    @Override
+    public float getIntrinsicIconScaleFactor() {
+        LauncherAppState app = LauncherAppState.getInstance();
+        DeviceProfile grid = app.getDynamicGrid().getDeviceProfile();
+        return (float) grid.allAppsIconSizePx / grid.iconSizePx;
+    }
+
+    @Override
     protected void onDetachedFromWindow() {
         super.onDetachedFromWindow();
         cancelAllTasks();
@@ -935,12 +971,12 @@
     }
 
     public void setContentType(ContentType type) {
-        int page = getCurrentPage();
-        if (mContentType != type) {
-            page = 0;
+        // Widgets appear to be cleared every time you leave, always force invalidate for them
+        if (mContentType != type || type == ContentType.Widgets) {
+            int page = (mContentType != type) ? 0 : getCurrentPage();
+            mContentType = type;
+            invalidatePageData(page, true);
         }
-        mContentType = type;
-        invalidatePageData(page, true);
     }
 
     public ContentType getContentType() {
@@ -985,6 +1021,8 @@
         int heightSpec = MeasureSpec.makeMeasureSpec(mContentHeight, MeasureSpec.AT_MOST);
         layout.setMinimumWidth(getPageContentWidth());
         layout.measure(widthSpec, heightSpec);
+        layout.setPadding(mAllAppsPadding.left, mAllAppsPadding.top, mAllAppsPadding.right,
+                mAllAppsPadding.bottom);
         setVisibilityOnChildren(layout, View.VISIBLE);
     }
 
@@ -1110,9 +1148,9 @@
                     mRunningTasks.remove(task);
                     if (task.isCancelled()) return;
                     // do cleanup inside onSyncWidgetPageItems
-                    onSyncWidgetPageItems(data);
+                    onSyncWidgetPageItems(data, false);
                 }
-            }, mWidgetPreviewLoader);
+            }, getWidgetPreviewLoader());
 
         // Ensure that the task is appropriately prioritized and runs in parallel
         AppsCustomizeAsyncTask t = new AppsCustomizeAsyncTask(page,
@@ -1173,7 +1211,7 @@
                 createItemInfo.minSpanX = minSpanXY[0];
                 createItemInfo.minSpanY = minSpanXY[1];
 
-                widget.applyFromAppWidgetProviderInfo(info, -1, spanXY, mWidgetPreviewLoader);
+                widget.applyFromAppWidgetProviderInfo(info, -1, spanXY, getWidgetPreviewLoader());
                 widget.setTag(createItemInfo);
                 widget.setShortPressListener(this);
             } else if (rawInfo instanceof ResolveInfo) {
@@ -1183,7 +1221,7 @@
                 createItemInfo.itemType = LauncherSettings.Favorites.ITEM_TYPE_SHORTCUT;
                 createItemInfo.componentName = new ComponentName(info.activityInfo.packageName,
                         info.activityInfo.name);
-                widget.applyFromResolveInfo(mPackageManager, info, mWidgetPreviewLoader);
+                widget.applyFromResolveInfo(mPackageManager, info, getWidgetPreviewLoader());
                 widget.setTag(createItemInfo);
             }
             widget.setOnClickListener(this);
@@ -1220,13 +1258,13 @@
                     maxPreviewHeight = maxSize[1];
                 }
 
-                mWidgetPreviewLoader.setPreviewSize(
+                getWidgetPreviewLoader().setPreviewSize(
                         maxPreviewWidth, maxPreviewHeight, mWidgetSpacingLayout);
                 if (immediate) {
                     AsyncTaskPageData data = new AsyncTaskPageData(page, items,
-                            maxPreviewWidth, maxPreviewHeight, null, null, mWidgetPreviewLoader);
+                            maxPreviewWidth, maxPreviewHeight, null, null, getWidgetPreviewLoader());
                     loadWidgetPreviewsInBackground(null, data);
-                    onSyncWidgetPageItems(data);
+                    onSyncWidgetPageItems(data, immediate);
                 } else {
                     if (mInTransition) {
                         mDeferredPrepareLoadWidgetPreviewsTasks.add(this);
@@ -1261,12 +1299,12 @@
                 task.syncThreadPriority();
             }
 
-            images.add(mWidgetPreviewLoader.getPreview(items.get(i)));
+            images.add(getWidgetPreviewLoader().getPreview(items.get(i)));
         }
     }
 
-    private void onSyncWidgetPageItems(AsyncTaskPageData data) {
-        if (mInTransition) {
+    private void onSyncWidgetPageItems(AsyncTaskPageData data, boolean immediatelySyncItems) {
+        if (!immediatelySyncItems && mInTransition) {
             mDeferredSyncWidgetPageItems.add(data);
             return;
         }
@@ -1521,7 +1559,7 @@
     }
 
     public void setApps(ArrayList<AppInfo> list) {
-        if (!DISABLE_ALL_APPS) {
+        if (!LauncherAppState.isDisableAllApps()) {
             mApps = list;
             Collections.sort(mApps, LauncherModel.getAppNameComparator());
             updatePageCountsAndInvalidateData();
@@ -1539,7 +1577,7 @@
         }
     }
     public void addApps(ArrayList<AppInfo> list) {
-        if (!DISABLE_ALL_APPS) {
+        if (!LauncherAppState.isDisableAllApps()) {
             addAppsWithoutInvalidate(list);
             updatePageCountsAndInvalidateData();
         }
@@ -1567,7 +1605,7 @@
         }
     }
     public void removeApps(ArrayList<AppInfo> appInfos) {
-        if (!DISABLE_ALL_APPS) {
+        if (!LauncherAppState.isDisableAllApps()) {
             removeAppsWithoutInvalidate(appInfos);
             updatePageCountsAndInvalidateData();
         }
@@ -1576,7 +1614,7 @@
         // We remove and re-add the updated applications list because it's properties may have
         // changed (ie. the title), and this will ensure that the items will be in their proper
         // place in the list.
-        if (!DISABLE_ALL_APPS) {
+        if (!LauncherAppState.isDisableAllApps()) {
             removeAppsWithoutInvalidate(list);
             addAppsWithoutInvalidate(list);
             updatePageCountsAndInvalidateData();
diff --git a/src/com/android/launcher3/AppsCustomizeTabHost.java b/src/com/android/launcher3/AppsCustomizeTabHost.java
index bfcf92a..bb7f045 100644
--- a/src/com/android/launcher3/AppsCustomizeTabHost.java
+++ b/src/com/android/launcher3/AppsCustomizeTabHost.java
@@ -367,6 +367,10 @@
 
     @Override
     public View getContent() {
+        View appsCustomizeContent = mAppsCustomizePane.getContent();
+        if (appsCustomizeContent != null) {
+            return appsCustomizeContent;
+        }
         return mContent;
     }
 
@@ -397,17 +401,18 @@
 
     @Override
     public void onLauncherTransitionStart(Launcher l, boolean animated, boolean toWorkspace) {
+        mAppsCustomizePane.onLauncherTransitionStart(l, animated, toWorkspace);
         if (animated) {
             enableAndBuildHardwareLayer();
         }
 
         // Dismiss the workspace cling
-        l.dismissWorkspaceCling(null);
+        l.getLauncherClings().dismissWorkspaceCling(null);
     }
 
     @Override
     public void onLauncherTransitionStep(Launcher l, float t) {
-        // Do nothing
+        mAppsCustomizePane.onLauncherTransitionStep(l, t);
     }
 
     @Override
diff --git a/src/com/android/launcher3/BubbleTextView.java b/src/com/android/launcher3/BubbleTextView.java
index 8dab943..ee42904 100644
--- a/src/com/android/launcher3/BubbleTextView.java
+++ b/src/com/android/launcher3/BubbleTextView.java
@@ -20,7 +20,6 @@
 import android.content.res.Resources;
 import android.graphics.Bitmap;
 import android.graphics.Canvas;
-import android.graphics.Color;
 import android.graphics.Rect;
 import android.graphics.Region;
 import android.graphics.Region.Op;
@@ -87,7 +86,7 @@
         // Ensure we are using the right text size
         LauncherAppState app = LauncherAppState.getInstance();
         DeviceProfile grid = app.getDynamicGrid().getDeviceProfile();
-        setTextSize(TypedValue.COMPLEX_UNIT_SP, grid.iconTextSize);
+        setTextSize(TypedValue.COMPLEX_UNIT_PX, grid.iconTextSizePx);
         setTextColor(getResources().getColor(R.color.workspace_icon_text_color));
     }
 
@@ -111,7 +110,7 @@
 
         setCompoundDrawables(null,
                 Utilities.createIconDrawable(b), null, null);
-        setCompoundDrawablePadding((int) ((grid.folderIconSizePx - grid.iconSizePx) / 2f));
+        setCompoundDrawablePadding(grid.iconDrawablePaddingPx);
         setText(info.title);
         setTag(info);
     }
@@ -203,6 +202,10 @@
         destCanvas.restore();
     }
 
+    public void setGlowColor(int color) {
+        mFocusedOutlineColor = mFocusedGlowColor = mPressedOutlineColor = mPressedGlowColor = color;
+    }
+
     /**
      * Returns a new bitmap to be used as the object outline, e.g. to visualize the drop location.
      * Responsibility for the bitmap is transferred to the caller.
diff --git a/src/com/android/launcher3/BuildInfo.java b/src/com/android/launcher3/BuildInfo.java
new file mode 100644
index 0000000..b49ee0d
--- /dev/null
+++ b/src/com/android/launcher3/BuildInfo.java
@@ -0,0 +1,32 @@
+package com.android.launcher3;
+
+import android.text.TextUtils;
+import android.util.Log;
+
+public class BuildInfo {
+    private static final boolean DBG = false;
+    private static final String TAG = "BuildInfo";
+
+    public boolean isDogfoodBuild() {
+        return false;
+    }
+
+    public static BuildInfo loadByName(String className) {
+        if (TextUtils.isEmpty(className)) return new BuildInfo();
+
+        if (DBG) Log.d(TAG, "Loading BuildInfo: " + className);
+        try {
+            Class<?> cls = Class.forName(className);
+            return (BuildInfo) cls.newInstance();
+        } catch (ClassNotFoundException e) {
+            Log.e(TAG, "Bad BuildInfo class", e);
+        } catch (InstantiationException e) {
+            Log.e(TAG, "Bad BuildInfo class", e);
+        } catch (IllegalAccessException e) {
+            Log.e(TAG, "Bad BuildInfo class", e);
+        } catch (ClassCastException e) {
+            Log.e(TAG, "Bad BuildInfo class", e);
+        }
+        return new BuildInfo();
+    }
+}
diff --git a/src/com/android/launcher3/ButtonDropTarget.java b/src/com/android/launcher3/ButtonDropTarget.java
index d51ae46..019f86c 100644
--- a/src/com/android/launcher3/ButtonDropTarget.java
+++ b/src/com/android/launcher3/ButtonDropTarget.java
@@ -25,8 +25,6 @@
 import android.view.View;
 import android.widget.TextView;
 
-import com.android.launcher3.R;
-
 
 /**
  * Implements a DropTarget.
diff --git a/src/com/android/launcher3/CellLayout.java b/src/com/android/launcher3/CellLayout.java
index dafb79f..2436a51 100644
--- a/src/com/android/launcher3/CellLayout.java
+++ b/src/com/android/launcher3/CellLayout.java
@@ -35,7 +35,6 @@
 import android.graphics.Rect;
 import android.graphics.drawable.ColorDrawable;
 import android.graphics.drawable.Drawable;
-import android.graphics.drawable.NinePatchDrawable;
 import android.os.Parcelable;
 import android.util.AttributeSet;
 import android.util.Log;
@@ -48,7 +47,6 @@
 import android.view.animation.DecelerateInterpolator;
 import android.view.animation.LayoutAnimationController;
 
-import com.android.launcher3.R;
 import com.android.launcher3.FolderIcon.FolderRingAnimator;
 
 import java.util.ArrayList;
@@ -76,6 +74,7 @@
     private int mHeightGap;
     private int mMaxGap;
     private boolean mScrollingTransformsDirty = false;
+    private boolean mDropPending = false;
 
     private final Rect mRect = new Rect();
     private final CellInfo mCellInfo = new CellInfo();
@@ -99,6 +98,7 @@
     private int mForegroundAlpha = 0;
     private float mBackgroundAlpha;
     private float mBackgroundAlphaMultiplier = 1.0f;
+    private boolean mDrawBackground = true;
 
     private Drawable mNormalBackground;
     private Drawable mActiveGlowBackground;
@@ -132,8 +132,8 @@
 
     private HashMap<CellLayout.LayoutParams, Animator> mReorderAnimators = new
             HashMap<CellLayout.LayoutParams, Animator>();
-    private HashMap<View, ReorderHintAnimation>
-            mShakeAnimators = new HashMap<View, ReorderHintAnimation>();
+    private HashMap<View, ReorderPreviewAnimation>
+            mShakeAnimators = new HashMap<View, ReorderPreviewAnimation>();
 
     private boolean mItemPlacementDirty = false;
 
@@ -148,19 +148,20 @@
     private boolean mIsHotseat = false;
     private float mHotseatScale = 1f;
 
-    public static final int MODE_DRAG_OVER = 0;
-    public static final int MODE_ON_DROP = 1;
-    public static final int MODE_ON_DROP_EXTERNAL = 2;
-    public static final int MODE_ACCEPT_DROP = 3;
+    public static final int MODE_SHOW_REORDER_HINT = 0;
+    public static final int MODE_DRAG_OVER = 1;
+    public static final int MODE_ON_DROP = 2;
+    public static final int MODE_ON_DROP_EXTERNAL = 3;
+    public static final int MODE_ACCEPT_DROP = 4;
     private static final boolean DESTRUCTIVE_REORDER = false;
     private static final boolean DEBUG_VISUALIZE_OCCUPIED = false;
 
     static final int LANDSCAPE = 0;
     static final int PORTRAIT = 1;
 
-    private static final float REORDER_HINT_MAGNITUDE = 0.12f;
+    private static final float REORDER_PREVIEW_MAGNITUDE = 0.12f;
     private static final int REORDER_ANIMATION_DURATION = 150;
-    private float mReorderHintAnimationMagnitude;
+    private float mReorderPreviewAnimationMagnitude;
 
     private ArrayList<View> mIntersectingViews = new ArrayList<View>();
     private Rect mOccupiedRect = new Rect();
@@ -198,7 +199,7 @@
         TypedArray a = context.obtainStyledAttributes(attrs, R.styleable.CellLayout, defStyle, 0);
 
         mCellWidth = mCellHeight = -1;
-        mFixedCellHeight = mFixedCellHeight = -1;
+        mFixedCellWidth = mFixedCellHeight = -1;
         mWidthGap = mOriginalWidthGap = 0;
         mHeightGap = mOriginalHeightGap = 0;
         mMaxGap = Integer.MAX_VALUE;
@@ -214,7 +215,7 @@
         setAlwaysDrawnWithCacheEnabled(false);
 
         final Resources res = getResources();
-        mHotseatScale = (float) grid.hotseatIconSize / grid.iconSize;
+        mHotseatScale = (float) grid.hotseatIconSizePx / grid.iconSizePx;
 
         mNormalBackground = res.getDrawable(R.drawable.screenpanel);
         mActiveGlowBackground = res.getDrawable(R.drawable.screenpanel_hover);
@@ -224,7 +225,7 @@
         mForegroundPadding =
                 res.getDimensionPixelSize(R.dimen.workspace_overscroll_drawable_padding);
 
-        mReorderHintAnimationMagnitude = (REORDER_HINT_MAGNITUDE *
+        mReorderPreviewAnimationMagnitude = (REORDER_PREVIEW_MAGNITUDE *
                 grid.iconSizePx);
 
         mNormalBackground.setFilterBitmap(true);
@@ -332,6 +333,14 @@
         mShortcutsAndWidgets.setInvertIfRtl(invert);
     }
 
+    public void setDropPending(boolean pending) {
+        mDropPending = pending;
+    }
+
+    public boolean isDropPending() {
+        return mDropPending;
+    }
+
     private void invalidateBubbleTextView(BubbleTextView icon) {
         final int padding = icon.getPressedOrFocusedBackgroundPadding();
         invalidate(icon.getLeft() + getPaddingLeft() - padding,
@@ -378,6 +387,10 @@
         mUseActiveGlowBackground = use;
     }
 
+    void disableBackground() {
+        mDrawBackground = false;
+    }
+
     boolean getIsDragOverlapping() {
         return mIsDragOverlapping;
     }
@@ -406,7 +419,7 @@
         // When we're small, we are either drawn normally or in the "accepts drops" state (during
         // a drag). However, we also drag the mini hover background *over* one of those two
         // backgrounds
-        if (mBackgroundAlpha > 0.0f) {
+        if (mDrawBackground && mBackgroundAlpha > 0.0f) {
             Drawable bg;
 
             if (mUseActiveGlowBackground) {
@@ -2079,6 +2092,8 @@
             }
         }
 
+        solution.intersectingViews = new ArrayList<View>(mIntersectingViews);
+
         // First we try to find a solution which respects the push mechanic. That is,
         // we try to find a solution such that no displaced item travels through another item
         // without also displacing that item.
@@ -2127,8 +2142,9 @@
         }
     }
 
-    ItemConfiguration simpleSwap(int pixelX, int pixelY, int minSpanX, int minSpanY, int spanX,
-            int spanY, int[] direction, View dragView, boolean decX, ItemConfiguration solution) {
+    ItemConfiguration findReorderSolution(int pixelX, int pixelY, int minSpanX, int minSpanY,
+            int spanX, int spanY, int[] direction, View dragView, boolean decX,
+            ItemConfiguration solution) {
         // Copy the current state into the solution. This solution will be manipulated as necessary.
         copyCurrentStateToSolution(solution, false);
         // Copy the current occupied array into the temporary occupied array. This array will be
@@ -2150,11 +2166,11 @@
             // We try shrinking the widget down to size in an alternating pattern, shrink 1 in
             // x, then 1 in y etc.
             if (spanX > minSpanX && (minSpanY == spanY || decX)) {
-                return simpleSwap(pixelX, pixelY, minSpanX, minSpanY, spanX - 1, spanY, direction,
-                        dragView, false, solution);
+                return findReorderSolution(pixelX, pixelY, minSpanX, minSpanY, spanX - 1, spanY,
+                        direction, dragView, false, solution);
             } else if (spanY > minSpanY) {
-                return simpleSwap(pixelX, pixelY, minSpanX, minSpanY, spanX, spanY - 1, direction,
-                        dragView, true, solution);
+                return findReorderSolution(pixelX, pixelY, minSpanX, minSpanY, spanX, spanY - 1,
+                        direction, dragView, true, solution);
             }
             solution.isSolution = false;
         } else {
@@ -2234,25 +2250,30 @@
         }
     }
 
-    // This method starts or changes the reorder hint animations
-    private void beginOrAdjustHintAnimations(ItemConfiguration solution, View dragView, int delay) {
+
+    // This method starts or changes the reorder preview animations
+    private void beginOrAdjustReorderPreviewAnimations(ItemConfiguration solution,
+            View dragView, int delay, int mode) {
         int childCount = mShortcutsAndWidgets.getChildCount();
         for (int i = 0; i < childCount; i++) {
             View child = mShortcutsAndWidgets.getChildAt(i);
             if (child == dragView) continue;
             CellAndSpan c = solution.map.get(child);
+            boolean skip = mode == ReorderPreviewAnimation.MODE_HINT && solution.intersectingViews
+                    != null && !solution.intersectingViews.contains(child);
+
             LayoutParams lp = (LayoutParams) child.getLayoutParams();
-            if (c != null) {
-                ReorderHintAnimation rha = new ReorderHintAnimation(child, lp.cellX, lp.cellY,
-                        c.x, c.y, c.spanX, c.spanY);
+            if (c != null && !skip) {
+                ReorderPreviewAnimation rha = new ReorderPreviewAnimation(child, mode, lp.cellX,
+                        lp.cellY, c.x, c.y, c.spanX, c.spanY);
                 rha.animate();
             }
         }
     }
 
-    // Class which represents the reorder hint animations. These animations show that an item is
+    // Class which represents the reorder preview animations. These animations show that an item is
     // in a temporary state, and hint at where the item will return to.
-    class ReorderHintAnimation {
+    class ReorderPreviewAnimation {
         View child;
         float finalDeltaX;
         float finalDeltaY;
@@ -2260,11 +2281,18 @@
         float initDeltaY;
         float finalScale;
         float initScale;
-        private static final int DURATION = 300;
+        int mode;
+        boolean repeating = false;
+        private static final int PREVIEW_DURATION = 300;
+        private static final int HINT_DURATION = Workspace.REORDER_TIMEOUT;
+
+        public static final int MODE_HINT = 0;
+        public static final int MODE_PREVIEW = 1;
+
         Animator a;
 
-        public ReorderHintAnimation(View child, int cellX0, int cellY0, int cellX1, int cellY1,
-                int spanX, int spanY) {
+        public ReorderPreviewAnimation(View child, int mode, int cellX0, int cellY0, int cellX1,
+                int cellY1, int spanX, int spanY) {
             regionToCenterPoint(cellX0, cellY0, spanX, spanY, mTmpPoint);
             final int x0 = mTmpPoint[0];
             final int y0 = mTmpPoint[1];
@@ -2275,20 +2303,22 @@
             final int dY = y1 - y0;
             finalDeltaX = 0;
             finalDeltaY = 0;
+            int dir = mode == MODE_HINT ? -1 : 1;
             if (dX == dY && dX == 0) {
             } else {
                 if (dY == 0) {
-                    finalDeltaX = - Math.signum(dX) * mReorderHintAnimationMagnitude;
+                    finalDeltaX = - dir * Math.signum(dX) * mReorderPreviewAnimationMagnitude;
                 } else if (dX == 0) {
-                    finalDeltaY = - Math.signum(dY) * mReorderHintAnimationMagnitude;
+                    finalDeltaY = - dir * Math.signum(dY) * mReorderPreviewAnimationMagnitude;
                 } else {
                     double angle = Math.atan( (float) (dY) / dX);
-                    finalDeltaX = (int) (- Math.signum(dX) *
-                            Math.abs(Math.cos(angle) * mReorderHintAnimationMagnitude));
-                    finalDeltaY = (int) (- Math.signum(dY) *
-                            Math.abs(Math.sin(angle) * mReorderHintAnimationMagnitude));
+                    finalDeltaX = (int) (- dir * Math.signum(dX) *
+                            Math.abs(Math.cos(angle) * mReorderPreviewAnimationMagnitude));
+                    finalDeltaY = (int) (- dir * Math.signum(dY) *
+                            Math.abs(Math.sin(angle) * mReorderPreviewAnimationMagnitude));
                 }
             }
+            this.mode = mode;
             initDeltaX = child.getTranslationX();
             initDeltaY = child.getTranslationY();
             finalScale = getChildrenScale() - 4.0f / child.getWidth();
@@ -2298,7 +2328,7 @@
 
         void animate() {
             if (mShakeAnimators.containsKey(child)) {
-                ReorderHintAnimation oldAnimation = mShakeAnimators.get(child);
+                ReorderPreviewAnimation oldAnimation = mShakeAnimators.get(child);
                 oldAnimation.cancel();
                 mShakeAnimators.remove(child);
                 if (finalDeltaX == 0 && finalDeltaY == 0) {
@@ -2313,14 +2343,15 @@
             a = va;
             va.setRepeatMode(ValueAnimator.REVERSE);
             va.setRepeatCount(ValueAnimator.INFINITE);
-            va.setDuration(DURATION);
+            va.setDuration(mode == MODE_HINT ? HINT_DURATION : PREVIEW_DURATION);
             va.setStartDelay((int) (Math.random() * 60));
             va.addUpdateListener(new AnimatorUpdateListener() {
                 @Override
                 public void onAnimationUpdate(ValueAnimator animation) {
                     float r = ((Float) animation.getAnimatedValue()).floatValue();
-                    float x = r * finalDeltaX + (1 - r) * initDeltaX;
-                    float y = r * finalDeltaY + (1 - r) * initDeltaY;
+                    float r1 = (mode == MODE_HINT && repeating) ? 1.0f : r;
+                    float x = r1 * finalDeltaX + (1 - r1) * initDeltaX;
+                    float y = r1 * finalDeltaY + (1 - r1) * initDeltaY;
                     child.setTranslationX(x);
                     child.setTranslationY(y);
                     float s = r * finalScale + (1 - r) * initScale;
@@ -2334,6 +2365,7 @@
                     initDeltaX = 0;
                     initDeltaY = 0;
                     initScale = getChildrenScale();
+                    repeating = true;
                 }
             });
             mShakeAnimators.put(child, this);
@@ -2365,8 +2397,8 @@
         }
     }
 
-    private void completeAndClearReorderHintAnimations() {
-        for (ReorderHintAnimation a: mShakeAnimators.values()) {
+    private void completeAndClearReorderPreviewAnimations() {
+        for (ReorderPreviewAnimation a: mShakeAnimators.values()) {
             a.completeAnimationImmediately();
         }
         mShakeAnimators.clear();
@@ -2509,20 +2541,21 @@
     }
 
     void revertTempState() {
-        if (!isItemPlacementDirty() || DESTRUCTIVE_REORDER) return;
-        final int count = mShortcutsAndWidgets.getChildCount();
-        for (int i = 0; i < count; i++) {
-            View child = mShortcutsAndWidgets.getChildAt(i);
-            LayoutParams lp = (LayoutParams) child.getLayoutParams();
-            if (lp.tmpCellX != lp.cellX || lp.tmpCellY != lp.cellY) {
-                lp.tmpCellX = lp.cellX;
-                lp.tmpCellY = lp.cellY;
-                animateChildToPosition(child, lp.cellX, lp.cellY, REORDER_ANIMATION_DURATION,
-                        0, false, false);
+        completeAndClearReorderPreviewAnimations();
+        if (isItemPlacementDirty() && !DESTRUCTIVE_REORDER) {
+            final int count = mShortcutsAndWidgets.getChildCount();
+            for (int i = 0; i < count; i++) {
+                View child = mShortcutsAndWidgets.getChildAt(i);
+                LayoutParams lp = (LayoutParams) child.getLayoutParams();
+                if (lp.tmpCellX != lp.cellX || lp.tmpCellY != lp.cellY) {
+                    lp.tmpCellX = lp.cellX;
+                    lp.tmpCellY = lp.cellY;
+                    animateChildToPosition(child, lp.cellX, lp.cellY, REORDER_ANIMATION_DURATION,
+                            0, false, false);
+                }
             }
+            setItemPlacementDirty(false);
         }
-        completeAndClearReorderHintAnimations();
-        setItemPlacementDirty(false);
     }
 
     boolean createAreaForResize(int cellX, int cellY, int spanX, int spanY,
@@ -2531,7 +2564,7 @@
         regionToCenterPoint(cellX, cellY, spanX, spanY, pixelXY);
 
         // First we determine if things have moved enough to cause a different layout
-        ItemConfiguration swapSolution = simpleSwap(pixelXY[0], pixelXY[1], spanX, spanY,
+        ItemConfiguration swapSolution = findReorderSolution(pixelXY[0], pixelXY[1], spanX, spanY,
                  spanX,  spanY, direction, dragView,  true,  new ItemConfiguration());
 
         setUseTempCoords(true);
@@ -2545,18 +2578,18 @@
 
             if (commit) {
                 commitTempPlacement();
-                completeAndClearReorderHintAnimations();
+                completeAndClearReorderPreviewAnimations();
                 setItemPlacementDirty(false);
             } else {
-                beginOrAdjustHintAnimations(swapSolution, dragView,
-                        REORDER_ANIMATION_DURATION);
+                beginOrAdjustReorderPreviewAnimations(swapSolution, dragView,
+                        REORDER_ANIMATION_DURATION, ReorderPreviewAnimation.MODE_PREVIEW);
             }
             mShortcutsAndWidgets.requestLayout();
         }
         return swapSolution.isSolution;
     }
 
-    int[] createArea(int pixelX, int pixelY, int minSpanX, int minSpanY, int spanX, int spanY,
+    int[] performReorder(int pixelX, int pixelY, int minSpanX, int minSpanY, int spanX, int spanY,
             View dragView, int[] result, int resultSpan[], int mode) {
         // First we determine if things have moved enough to cause a different layout
         result = findNearestArea(pixelX, pixelY, spanX, spanY, result);
@@ -2583,7 +2616,8 @@
             mPreviousReorderDirection[1] = mDirectionVector[1];
         }
 
-        ItemConfiguration swapSolution = simpleSwap(pixelX, pixelY, minSpanX, minSpanY,
+        // Find a solution involving pushing / displacing any items in the way
+        ItemConfiguration swapSolution = findReorderSolution(pixelX, pixelY, minSpanX, minSpanY,
                  spanX,  spanY, mDirectionVector, dragView,  true,  new ItemConfiguration());
 
         // We attempt the approach which doesn't shuffle views at all
@@ -2591,12 +2625,29 @@
                 minSpanY, spanX, spanY, dragView, new ItemConfiguration());
 
         ItemConfiguration finalSolution = null;
+
+        // If the reorder solution requires resizing (shrinking) the item being dropped, we instead
+        // favor a solution in which the item is not resized, but
         if (swapSolution.isSolution && swapSolution.area() >= noShuffleSolution.area()) {
             finalSolution = swapSolution;
         } else if (noShuffleSolution.isSolution) {
             finalSolution = noShuffleSolution;
         }
 
+        if (mode == MODE_SHOW_REORDER_HINT) {
+            if (finalSolution != null) {
+                beginOrAdjustReorderPreviewAnimations(finalSolution, dragView, 0,
+                        ReorderPreviewAnimation.MODE_HINT);
+                result[0] = finalSolution.dragViewX;
+                result[1] = finalSolution.dragViewY;
+                resultSpan[0] = finalSolution.dragViewSpanX;
+                resultSpan[1] = finalSolution.dragViewSpanY;
+            } else {
+                result[0] = result[1] = resultSpan[0] = resultSpan[1] = -1;
+            }
+            return result;
+        }
+
         boolean foundSolution = true;
         if (!DESTRUCTIVE_REORDER) {
             setUseTempCoords(true);
@@ -2621,11 +2672,11 @@
                 if (!DESTRUCTIVE_REORDER &&
                         (mode == MODE_ON_DROP || mode == MODE_ON_DROP_EXTERNAL)) {
                     commitTempPlacement();
-                    completeAndClearReorderHintAnimations();
+                    completeAndClearReorderPreviewAnimations();
                     setItemPlacementDirty(false);
                 } else {
-                    beginOrAdjustHintAnimations(finalSolution, dragView,
-                            REORDER_ANIMATION_DURATION);
+                    beginOrAdjustReorderPreviewAnimations(finalSolution, dragView,
+                            REORDER_ANIMATION_DURATION,  ReorderPreviewAnimation.MODE_PREVIEW);
                 }
             }
         } else {
@@ -2652,6 +2703,7 @@
         HashMap<View, CellAndSpan> map = new HashMap<View, CellAndSpan>();
         private HashMap<View, CellAndSpan> savedMap = new HashMap<View, CellAndSpan>();
         ArrayList<View> sortedViews = new ArrayList<View>();
+        ArrayList<View> intersectingViews;
         boolean isSolution = false;
         int dragViewX, dragViewY, dragViewSpanX, dragViewSpanY;
 
diff --git a/src/com/android/launcher3/Cling.java b/src/com/android/launcher3/Cling.java
index 338b722..a6139cc 100644
--- a/src/com/android/launcher3/Cling.java
+++ b/src/com/android/launcher3/Cling.java
@@ -18,9 +18,8 @@
 
 import android.animation.Animator;
 import android.animation.AnimatorListenerAdapter;
-import android.app.ActivityOptions;
-import android.content.Context;
 import android.content.ComponentName;
+import android.content.Context;
 import android.content.Intent;
 import android.content.res.Resources;
 import android.content.res.TypedArray;
@@ -31,6 +30,7 @@
 import android.view.FocusFinder;
 import android.view.MotionEvent;
 import android.view.View;
+import android.view.ViewGroup;
 import android.view.animation.AccelerateInterpolator;
 import android.widget.FrameLayout;
 import android.widget.TextView;
@@ -38,10 +38,6 @@
 public class Cling extends FrameLayout implements Insettable, View.OnClickListener,
         View.OnLongClickListener, View.OnTouchListener {
 
-    static final String FIRST_RUN_CLING_DISMISSED_KEY = "cling_gel.first_run.dismissed";
-    static final String WORKSPACE_CLING_DISMISSED_KEY = "cling_gel.workspace.dismissed";
-    static final String FOLDER_CLING_DISMISSED_KEY = "cling_gel.folder.dismissed";
-
     private static String FIRST_RUN_PORTRAIT = "first_run_portrait";
     private static String FIRST_RUN_LANDSCAPE = "first_run_landscape";
 
@@ -50,14 +46,24 @@
     private static String WORKSPACE_LARGE = "workspace_large";
     private static String WORKSPACE_CUSTOM = "workspace_custom";
 
+    private static String MIGRATION_PORTRAIT = "migration_portrait";
+    private static String MIGRATION_LANDSCAPE = "migration_landscape";
+
+    private static String MIGRATION_WORKSPACE_PORTRAIT = "migration_workspace_portrait";
+    private static String MIGRATION_WORKSPACE_LARGE_PORTRAIT = "migration_workspace_large_portrait";
+    private static String MIGRATION_WORKSPACE_LANDSCAPE = "migration_workspace_landscape";
+
     private static String FOLDER_PORTRAIT = "folder_portrait";
     private static String FOLDER_LANDSCAPE = "folder_landscape";
     private static String FOLDER_LARGE = "folder_large";
 
     private static float FIRST_RUN_CIRCLE_BUFFER_DPS = 60;
+    private static float FIRST_RUN_MAX_CIRCLE_RADIUS_DPS = 180;
     private static float WORKSPACE_INNER_CIRCLE_RADIUS_DPS = 50;
     private static float WORKSPACE_OUTER_CIRCLE_RADIUS_DPS = 60;
     private static float WORKSPACE_CIRCLE_Y_OFFSET_DPS = 30;
+    private static float MIGRATION_WORKSPACE_INNER_CIRCLE_RADIUS_DPS = 42;
+    private static float MIGRATION_WORKSPACE_OUTER_CIRCLE_RADIUS_DPS = 46;
 
     private Launcher mLauncher;
     private boolean mIsInitialized;
@@ -71,6 +77,7 @@
     private Rect mFocusedHotseatAppBounds;
 
     private Paint mErasePaint;
+    private Paint mBorderPaint;
     private Paint mBubblePaint;
     private Paint mDotPaint;
 
@@ -102,7 +109,7 @@
         if (!mIsInitialized) {
             mLauncher = l;
             mScrimView = scrim;
-            mBackgroundColor = 0xdd000000;
+            mBackgroundColor = 0xcc000000;
             setOnLongClickListener(this);
             setOnClickListener(this);
             setOnTouchListener(this);
@@ -113,6 +120,10 @@
             mErasePaint.setAlpha(0);
             mErasePaint.setAntiAlias(true);
 
+            mBorderPaint = new Paint();
+            mBorderPaint.setColor(0xFFFFFFFF);
+            mBorderPaint.setAntiAlias(true);
+
             int circleColor = getResources().getColor(
                     R.color.first_run_cling_circle_background_color);
             mBubblePaint = new Paint();
@@ -133,7 +144,9 @@
         Resources r = getResources();
         int appIconId = drawableId;
         Hotseat hotseat = mLauncher.getHotseat();
-        if (hotseat != null && appIconId > -1 && appRank > -1 && !title.isEmpty() &&
+        // Skip the focused app in the large layouts
+        if (!mDrawIdentifier.equals(WORKSPACE_LARGE) &&
+                hotseat != null && appIconId > -1 && appRank > -1 && !title.isEmpty() &&
                 !description.isEmpty()) {
             // Set the app bounds
             int x = hotseat.getCellXFromOrder(appRank);
@@ -147,7 +160,7 @@
                     pos.left + Utilities.sIconTextureWidth,
                     pos.top + Utilities.sIconTextureHeight);
             Utilities.scaleRectAboutCenter(mFocusedHotseatAppBounds,
-                    (grid.hotseatIconSize / grid.iconSize));
+                    ((float) grid.hotseatIconSizePx / grid.iconSizePx));
 
             // Set the title
             TextView v = (TextView) findViewById(R.id.focused_hotseat_app_title);
@@ -167,13 +180,92 @@
         }
     }
 
+    void setOpenFolderRect(Rect r) {
+        if (mDrawIdentifier.equals(FOLDER_LANDSCAPE) ||
+            mDrawIdentifier.equals(FOLDER_LARGE)) {
+            ViewGroup vg = (ViewGroup) findViewById(R.id.folder_bubble);
+            ViewGroup.MarginLayoutParams lp = (ViewGroup.MarginLayoutParams) vg.getLayoutParams();
+            lp.topMargin = r.top - mInsets.bottom;
+            lp.leftMargin = r.right;
+            vg.setLayoutDirection(View.LAYOUT_DIRECTION_LTR);
+            vg.requestLayout();
+        }
+    }
+
+    void updateMigrationWorkspaceBubblePosition() {
+        DisplayMetrics metrics = new DisplayMetrics();
+        mLauncher.getWindowManager().getDefaultDisplay().getMetrics(metrics);
+
+        // Get the page indicator bounds
+        LauncherAppState app = LauncherAppState.getInstance();
+        DeviceProfile grid = app.getDynamicGrid().getDeviceProfile();
+        Rect pageIndicatorBounds = grid.getWorkspacePageIndicatorBounds(mInsets);
+
+        if (mDrawIdentifier.equals(MIGRATION_WORKSPACE_PORTRAIT)) {
+            View bubble = findViewById(R.id.migration_workspace_cling_bubble);
+            ViewGroup.MarginLayoutParams lp =
+                    (ViewGroup.MarginLayoutParams) bubble.getLayoutParams();
+            lp.bottomMargin = grid.heightPx - pageIndicatorBounds.top;
+            bubble.requestLayout();
+        } else if (mDrawIdentifier.equals(MIGRATION_WORKSPACE_LARGE_PORTRAIT)) {
+            View bubble = findViewById(R.id.content);
+            ViewGroup.MarginLayoutParams lp =
+                    (ViewGroup.MarginLayoutParams) bubble.getLayoutParams();
+            lp.bottomMargin = grid.heightPx - pageIndicatorBounds.top;
+            bubble.requestLayout();
+        } else if (mDrawIdentifier.equals(MIGRATION_WORKSPACE_LANDSCAPE)) {
+            View bubble = findViewById(R.id.content);
+            ViewGroup.MarginLayoutParams lp =
+                    (ViewGroup.MarginLayoutParams) bubble.getLayoutParams();
+            if (grid.isLayoutRtl) {
+                lp.leftMargin = pageIndicatorBounds.right;
+            } else {
+                lp.rightMargin = (grid.widthPx - pageIndicatorBounds.left);
+            }
+            bubble.requestLayout();
+        }
+    }
+
+    void updateWorkspaceBubblePosition() {
+        DisplayMetrics metrics = new DisplayMetrics();
+        mLauncher.getWindowManager().getDefaultDisplay().getMetrics(metrics);
+
+        // Get the cut-out bounds
+        LauncherAppState app = LauncherAppState.getInstance();
+        DeviceProfile grid = app.getDynamicGrid().getDeviceProfile();
+        Rect cutOutBounds = getWorkspaceCutOutBounds(metrics);
+
+        if (mDrawIdentifier.equals(WORKSPACE_LARGE)) {
+            View bubble = findViewById(R.id.workspace_cling_bubble);
+            ViewGroup.MarginLayoutParams lp =
+                    (ViewGroup.MarginLayoutParams) bubble.getLayoutParams();
+            lp.bottomMargin = grid.heightPx - cutOutBounds.top - mInsets.bottom;
+            bubble.requestLayout();
+        }
+    }
+
+    private Rect getWorkspaceCutOutBounds(DisplayMetrics metrics) {
+        int halfWidth = metrics.widthPixels / 2;
+        int halfHeight = metrics.heightPixels / 2;
+        int yOffset = DynamicGrid.pxFromDp(WORKSPACE_CIRCLE_Y_OFFSET_DPS, metrics);
+        if (mDrawIdentifier.equals(WORKSPACE_LARGE)) {
+            yOffset = 0;
+        }
+        int radius = DynamicGrid.pxFromDp(WORKSPACE_OUTER_CIRCLE_RADIUS_DPS, metrics);
+        return new Rect(halfWidth - radius, halfHeight - yOffset - radius, halfWidth + radius,
+                halfHeight - yOffset + radius);
+    }
+
     void show(boolean animate, int duration) {
         setVisibility(View.VISIBLE);
         setLayerType(View.LAYER_TYPE_HARDWARE, null);
         if (mDrawIdentifier.equals(WORKSPACE_PORTRAIT) ||
                 mDrawIdentifier.equals(WORKSPACE_LANDSCAPE) ||
                 mDrawIdentifier.equals(WORKSPACE_LARGE) ||
-                mDrawIdentifier.equals(WORKSPACE_CUSTOM)) {
+                mDrawIdentifier.equals(WORKSPACE_CUSTOM) ||
+                mDrawIdentifier.equals(MIGRATION_WORKSPACE_PORTRAIT) ||
+                mDrawIdentifier.equals(MIGRATION_WORKSPACE_LARGE_PORTRAIT) ||
+                mDrawIdentifier.equals(MIGRATION_WORKSPACE_LANDSCAPE)) {
             View content = getContent();
             content.setAlpha(0f);
             content.animate()
@@ -219,7 +311,9 @@
 
     void hide(final int duration, final Runnable postCb) {
         if (mDrawIdentifier.equals(FIRST_RUN_PORTRAIT) ||
-                mDrawIdentifier.equals(FIRST_RUN_LANDSCAPE)) {
+                mDrawIdentifier.equals(FIRST_RUN_LANDSCAPE) ||
+                mDrawIdentifier.equals(MIGRATION_PORTRAIT) ||
+                mDrawIdentifier.equals(MIGRATION_LANDSCAPE)) {
             View content = getContent();
             content.animate()
                 .alpha(0f)
@@ -341,7 +435,7 @@
                 intent.setComponent(mFocusedHotseatAppComponent);
                 intent.addCategory(Intent.CATEGORY_LAUNCHER);
                 mLauncher.startActivity(intent, null);
-                mLauncher.dismissWorkspaceCling(this);
+                mLauncher.getLauncherClings().dismissWorkspaceCling(this);
             }
         }
     }
@@ -351,7 +445,12 @@
         if (mDrawIdentifier.equals(WORKSPACE_PORTRAIT) ||
                 mDrawIdentifier.equals(WORKSPACE_LANDSCAPE) ||
                 mDrawIdentifier.equals(WORKSPACE_LARGE)) {
-            mLauncher.dismissWorkspaceCling(null);
+            mLauncher.getLauncherClings().dismissWorkspaceCling(null);
+            return true;
+        } else if (mDrawIdentifier.equals(MIGRATION_WORKSPACE_PORTRAIT) ||
+                mDrawIdentifier.equals(MIGRATION_WORKSPACE_LARGE_PORTRAIT) ||
+                mDrawIdentifier.equals(MIGRATION_WORKSPACE_LANDSCAPE)) {
+            mLauncher.getLauncherClings().dismissMigrationWorkspaceCling(null);
             return true;
         }
         return false;
@@ -362,6 +461,11 @@
         if (mIsInitialized) {
             canvas.save();
 
+            // Get the page indicator bounds
+            LauncherAppState app = LauncherAppState.getInstance();
+            DeviceProfile grid = app.getDynamicGrid().getDeviceProfile();
+            Rect pageIndicatorBounds = grid.getWorkspacePageIndicatorBounds(mInsets);
+
             // Get the background override if there is one
             if (mBackground == null) {
                 if (mDrawIdentifier.equals(WORKSPACE_CUSTOM)) {
@@ -379,7 +483,10 @@
                 mBackground.draw(canvas);
             } else if (mDrawIdentifier.equals(WORKSPACE_PORTRAIT) ||
                     mDrawIdentifier.equals(WORKSPACE_LANDSCAPE) ||
-                    mDrawIdentifier.equals(WORKSPACE_LARGE)) {
+                    mDrawIdentifier.equals(WORKSPACE_LARGE) ||
+                    mDrawIdentifier.equals(MIGRATION_WORKSPACE_PORTRAIT) ||
+                    mDrawIdentifier.equals(MIGRATION_WORKSPACE_LARGE_PORTRAIT) ||
+                    mDrawIdentifier.equals(MIGRATION_WORKSPACE_LANDSCAPE)) {
                 // Initialize the draw buffer (to allow punching through)
                 eraseBg = Bitmap.createBitmap(getMeasuredWidth(), getMeasuredHeight(),
                         Bitmap.Config.ARGB_8888);
@@ -405,22 +512,23 @@
                 bubbleContent.getGlobalVisibleRect(bubbleRect);
                 mBubblePaint.setAlpha((int) (255 * alpha));
                 float buffer = DynamicGrid.pxFromDp(FIRST_RUN_CIRCLE_BUFFER_DPS, metrics);
+                float maxRadius = DynamicGrid.pxFromDp(FIRST_RUN_MAX_CIRCLE_RADIUS_DPS, metrics);
+                float radius = Math.min(maxRadius, (bubbleContent.getMeasuredWidth() + buffer) / 2);
                 canvas.drawCircle(metrics.widthPixels / 2,
-                        bubbleRect.centerY(),
-                        (bubbleContent.getMeasuredWidth() + buffer) / 2,
+                        bubbleRect.centerY(), radius,
                         mBubblePaint);
             } else if (mDrawIdentifier.equals(WORKSPACE_PORTRAIT) ||
                     mDrawIdentifier.equals(WORKSPACE_LANDSCAPE) ||
                     mDrawIdentifier.equals(WORKSPACE_LARGE)) {
-                int offset = DynamicGrid.pxFromDp(WORKSPACE_CIRCLE_Y_OFFSET_DPS, metrics);
-                mErasePaint.setAlpha((int) (128));
-                eraseCanvas.drawCircle(metrics.widthPixels / 2,
-                        metrics.heightPixels / 2 - offset,
+                Rect cutOutBounds = getWorkspaceCutOutBounds(metrics);
+                // Draw the outer circle
+                mErasePaint.setAlpha(128);
+                eraseCanvas.drawCircle(cutOutBounds.centerX(), cutOutBounds.centerY(),
                         DynamicGrid.pxFromDp(WORKSPACE_OUTER_CIRCLE_RADIUS_DPS, metrics),
                         mErasePaint);
+                // Draw the inner circle
                 mErasePaint.setAlpha(0);
-                eraseCanvas.drawCircle(metrics.widthPixels / 2,
-                        metrics.heightPixels / 2 - offset,
+                eraseCanvas.drawCircle(cutOutBounds.centerX(), cutOutBounds.centerY(),
                         DynamicGrid.pxFromDp(WORKSPACE_INNER_CIRCLE_RADIUS_DPS, metrics),
                         mErasePaint);
                 canvas.drawBitmap(eraseBg, 0, 0, null);
@@ -435,8 +543,25 @@
                     mFocusedHotseatApp.setAlpha((int) (255 * alpha));
                     mFocusedHotseatApp.draw(canvas);
                 }
+            } else if (mDrawIdentifier.equals(MIGRATION_WORKSPACE_PORTRAIT) ||
+                    mDrawIdentifier.equals(MIGRATION_WORKSPACE_LARGE_PORTRAIT) ||
+                    mDrawIdentifier.equals(MIGRATION_WORKSPACE_LANDSCAPE)) {
+                int offset = DynamicGrid.pxFromDp(WORKSPACE_CIRCLE_Y_OFFSET_DPS, metrics);
+                // Draw the outer circle
+                eraseCanvas.drawCircle(pageIndicatorBounds.centerX(),
+                        pageIndicatorBounds.centerY(),
+                        DynamicGrid.pxFromDp(MIGRATION_WORKSPACE_OUTER_CIRCLE_RADIUS_DPS, metrics),
+                        mBorderPaint);
+                // Draw the inner circle
+                mErasePaint.setAlpha(0);
+                eraseCanvas.drawCircle(pageIndicatorBounds.centerX(),
+                        pageIndicatorBounds.centerY(),
+                        DynamicGrid.pxFromDp(MIGRATION_WORKSPACE_INNER_CIRCLE_RADIUS_DPS, metrics),
+                        mErasePaint);
+                canvas.drawBitmap(eraseBg, 0, 0, null);
+                eraseCanvas.setBitmap(null);
+                eraseBg = null;
             }
-
             canvas.restore();
         }
 
diff --git a/src/com/android/launcher3/DeferredHandler.java b/src/com/android/launcher3/DeferredHandler.java
index 92ecf96..a2d121d 100644
--- a/src/com/android/launcher3/DeferredHandler.java
+++ b/src/com/android/launcher3/DeferredHandler.java
@@ -21,6 +21,7 @@
 import android.os.Message;
 import android.os.MessageQueue;
 import android.util.Pair;
+
 import java.util.LinkedList;
 import java.util.ListIterator;
 
diff --git a/src/com/android/launcher3/DeleteDropTarget.java b/src/com/android/launcher3/DeleteDropTarget.java
index 4023daf..75d906b 100644
--- a/src/com/android/launcher3/DeleteDropTarget.java
+++ b/src/com/android/launcher3/DeleteDropTarget.java
@@ -29,6 +29,7 @@
 import android.graphics.PointF;
 import android.graphics.Rect;
 import android.graphics.drawable.TransitionDrawable;
+import android.os.AsyncTask;
 import android.util.AttributeSet;
 import android.view.View;
 import android.view.ViewConfiguration;
@@ -95,7 +96,7 @@
     }
 
     private boolean isAllAppsApplication(DragSource source, Object info) {
-        return (source instanceof AppsCustomizePagedView) && (info instanceof AppInfo);
+        return source.supportsAppInfoDropTarget() && (info instanceof AppInfo);
     }
     private boolean isAllAppsWidget(DragSource source, Object info) {
         if (source instanceof AppsCustomizePagedView) {
@@ -145,12 +146,12 @@
                 return true;
             }
 
-            if (!AppsCustomizePagedView.DISABLE_ALL_APPS &&
+            if (!LauncherAppState.isDisableAllApps() &&
                     item.itemType == LauncherSettings.Favorites.ITEM_TYPE_FOLDER) {
                 return true;
             }
 
-            if (!AppsCustomizePagedView.DISABLE_ALL_APPS &&
+            if (!LauncherAppState.isDisableAllApps() &&
                     item.itemType == LauncherSettings.Favorites.ITEM_TYPE_APPLICATION &&
                     item instanceof AppInfo) {
                 AppInfo appInfo = (AppInfo) info;
@@ -159,7 +160,7 @@
 
             if (item.itemType == LauncherSettings.Favorites.ITEM_TYPE_APPLICATION &&
                 item instanceof ShortcutInfo) {
-                if (AppsCustomizePagedView.DISABLE_ALL_APPS) {
+                if (LauncherAppState.isDisableAllApps()) {
                     ShortcutInfo shortcutInfo = (ShortcutInfo) info;
                     return (shortcutInfo.flags & AppInfo.DOWNLOADED_FLAG) != 0;
                 } else {
@@ -173,8 +174,9 @@
     @Override
     public void onDragStart(DragSource source, Object info, int dragAction) {
         boolean isVisible = true;
-        boolean useUninstallLabel = !AppsCustomizePagedView.DISABLE_ALL_APPS &&
+        boolean useUninstallLabel = !LauncherAppState.isDisableAllApps() &&
                 isAllAppsApplication(source, info);
+        boolean useDeleteLabel = !useUninstallLabel && source.supportsDeleteDropTarget();
 
         // If we are dragging an application from AppsCustomize, only show the control if we can
         // delete the app (it was downloaded), and rename the string to "uninstall" in such a case.
@@ -185,15 +187,17 @@
 
         if (useUninstallLabel) {
             setCompoundDrawablesRelativeWithIntrinsicBounds(mUninstallDrawable, null, null, null);
-        } else {
+        } else if (useDeleteLabel) {
             setCompoundDrawablesRelativeWithIntrinsicBounds(mRemoveDrawable, null, null, null);
+        } else {
+            isVisible = false;
         }
         mCurrentDrawable = (TransitionDrawable) getCurrentDrawable();
 
         mActive = isVisible;
         resetHoverColor();
         ((ViewGroup) getParent()).setVisibility(isVisible ? View.VISIBLE : View.GONE);
-        if (getText().length() > 0) {
+        if (isVisible && getText().length() > 0) {
             setText(useUninstallLabel ? R.string.delete_target_uninstall_label
                 : R.string.delete_target_label);
         }
@@ -260,21 +264,10 @@
     }
 
     private boolean isUninstallFromWorkspace(DragObject d) {
-        if (AppsCustomizePagedView.DISABLE_ALL_APPS && isWorkspaceOrFolderApplication(d)) {
+        if (LauncherAppState.isDisableAllApps() && isWorkspaceOrFolderApplication(d)) {
             ShortcutInfo shortcut = (ShortcutInfo) d.dragInfo;
-            if (shortcut.intent != null && shortcut.intent.getComponent() != null) {
-                Set<String> categories = shortcut.intent.getCategories();
-                boolean includesLauncherCategory = false;
-                if (categories != null) {
-                    for (String category : categories) {
-                        if (category.equals(Intent.CATEGORY_LAUNCHER)) {
-                            includesLauncherCategory = true;
-                            break;
-                        }
-                    }
-                }
-                return includesLauncherCategory;
-            }
+            // Only allow manifest shortcuts to initiate an un-install.
+            return !InstallShortcutReceiver.isValidShortcutLaunchIntent(shortcut.intent);
         }
         return false;
     }
@@ -334,11 +327,12 @@
             if (appWidgetHost != null) {
                 // Deleting an app widget ID is a void call but writes to disk before returning
                 // to the caller...
-                new Thread("deleteAppWidgetId") {
-                    public void run() {
+                new AsyncTask<Void, Void, Void>() {
+                    public Void doInBackground(Void ... args) {
                         appWidgetHost.deleteAppWidgetId(launcherAppWidgetInfo.appWidgetId);
+                        return null;
                     }
-                }.start();
+                }.executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR, (Void) null);
             }
         }
         if (wasWaitingForUninstall && !mWaitingForUninstall) {
diff --git a/src/com/android/launcher3/DeviceProfile.java b/src/com/android/launcher3/DeviceProfile.java
new file mode 100644
index 0000000..e67ec19
--- /dev/null
+++ b/src/com/android/launcher3/DeviceProfile.java
@@ -0,0 +1,786 @@
+/*
+ * Copyright (C) 2008 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.launcher3;
+
+import android.appwidget.AppWidgetHostView;
+import android.content.ComponentName;
+import android.content.Context;
+import android.content.res.Configuration;
+import android.content.res.Resources;
+import android.graphics.Paint;
+import android.graphics.Paint.FontMetrics;
+import android.graphics.Point;
+import android.graphics.PointF;
+import android.graphics.Rect;
+import android.util.DisplayMetrics;
+import android.view.Display;
+import android.view.Gravity;
+import android.view.Surface;
+import android.view.View;
+import android.view.ViewGroup;
+import android.view.ViewGroup.LayoutParams;
+import android.view.WindowManager;
+import android.widget.FrameLayout;
+import android.widget.LinearLayout;
+
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.Comparator;
+
+
+class DeviceProfileQuery {
+    float widthDps;
+    float heightDps;
+    float value;
+    PointF dimens;
+
+    DeviceProfileQuery(float w, float h, float v) {
+        widthDps = w;
+        heightDps = h;
+        value = v;
+        dimens = new PointF(w, h);
+    }
+}
+
+public class DeviceProfile {
+    public static interface DeviceProfileCallbacks {
+        public void onAvailableSizeChanged(DeviceProfile grid);
+    }
+
+    String name;
+    float minWidthDps;
+    float minHeightDps;
+    float numRows;
+    float numColumns;
+    float numHotseatIcons;
+    private float iconSize;
+    private float iconTextSize;
+    private int iconDrawablePaddingOriginalPx;
+    private float hotseatIconSize;
+
+    boolean isLandscape;
+    boolean isTablet;
+    boolean isLargeTablet;
+    boolean isLayoutRtl;
+    boolean transposeLayoutWithOrientation;
+
+    int desiredWorkspaceLeftRightMarginPx;
+    int edgeMarginPx;
+    Rect defaultWidgetPadding;
+
+    int widthPx;
+    int heightPx;
+    int availableWidthPx;
+    int availableHeightPx;
+    int defaultPageSpacingPx;
+
+    int overviewModeMinIconZoneHeightPx;
+    int overviewModeMaxIconZoneHeightPx;
+    int overviewModeBarItemWidthPx;
+    int overviewModeBarSpacerWidthPx;
+    float overviewModeIconZoneRatio;
+    float overviewModeScaleFactor;
+
+    int iconSizePx;
+    int iconTextSizePx;
+    int iconDrawablePaddingPx;
+    int cellWidthPx;
+    int cellHeightPx;
+    int allAppsIconSizePx;
+    int allAppsIconTextSizePx;
+    int allAppsCellWidthPx;
+    int allAppsCellHeightPx;
+    int allAppsCellPaddingPx;
+    int folderBackgroundOffset;
+    int folderIconSizePx;
+    int folderCellWidthPx;
+    int folderCellHeightPx;
+    int hotseatCellWidthPx;
+    int hotseatCellHeightPx;
+    int hotseatIconSizePx;
+    int hotseatBarHeightPx;
+    int hotseatAllAppsRank;
+    int allAppsNumRows;
+    int allAppsNumCols;
+    int searchBarSpaceWidthPx;
+    int searchBarSpaceMaxWidthPx;
+    int searchBarSpaceHeightPx;
+    int searchBarHeightPx;
+    int pageIndicatorHeightPx;
+
+    float dragViewScale;
+
+    private ArrayList<DeviceProfileCallbacks> mCallbacks = new ArrayList<DeviceProfileCallbacks>();
+
+    DeviceProfile(String n, float w, float h, float r, float c,
+                  float is, float its, float hs, float his) {
+        // Ensure that we have an odd number of hotseat items (since we need to place all apps)
+        if (!LauncherAppState.isDisableAllApps() && hs % 2 == 0) {
+            throw new RuntimeException("All Device Profiles must have an odd number of hotseat spaces");
+        }
+
+        name = n;
+        minWidthDps = w;
+        minHeightDps = h;
+        numRows = r;
+        numColumns = c;
+        iconSize = is;
+        iconTextSize = its;
+        numHotseatIcons = hs;
+        hotseatIconSize = his;
+    }
+
+    DeviceProfile(Context context,
+                  ArrayList<DeviceProfile> profiles,
+                  float minWidth, float minHeight,
+                  int wPx, int hPx,
+                  int awPx, int ahPx,
+                  Resources res) {
+        DisplayMetrics dm = res.getDisplayMetrics();
+        ArrayList<DeviceProfileQuery> points =
+                new ArrayList<DeviceProfileQuery>();
+        transposeLayoutWithOrientation =
+                res.getBoolean(R.bool.hotseat_transpose_layout_with_orientation);
+        minWidthDps = minWidth;
+        minHeightDps = minHeight;
+
+        ComponentName cn = new ComponentName(context.getPackageName(),
+                this.getClass().getName());
+        defaultWidgetPadding = AppWidgetHostView.getDefaultPaddingForWidget(context, cn, null);
+        edgeMarginPx = res.getDimensionPixelSize(R.dimen.dynamic_grid_edge_margin);
+        desiredWorkspaceLeftRightMarginPx = 2 * edgeMarginPx;
+        pageIndicatorHeightPx =
+                res.getDimensionPixelSize(R.dimen.dynamic_grid_page_indicator_height);
+        defaultPageSpacingPx =
+                res.getDimensionPixelSize(R.dimen.dynamic_grid_workspace_page_spacing);
+        allAppsCellPaddingPx =
+                res.getDimensionPixelSize(R.dimen.dynamic_grid_all_apps_cell_padding);
+        overviewModeMinIconZoneHeightPx =
+                res.getDimensionPixelSize(R.dimen.dynamic_grid_overview_min_icon_zone_height);
+        overviewModeMaxIconZoneHeightPx =
+                res.getDimensionPixelSize(R.dimen.dynamic_grid_overview_max_icon_zone_height);
+        overviewModeBarItemWidthPx =
+                res.getDimensionPixelSize(R.dimen.dynamic_grid_overview_bar_item_width);
+        overviewModeBarSpacerWidthPx =
+                res.getDimensionPixelSize(R.dimen.dynamic_grid_overview_bar_spacer_width);
+        overviewModeIconZoneRatio =
+                res.getInteger(R.integer.config_dynamic_grid_overview_icon_zone_percentage) / 100f;
+        overviewModeScaleFactor =
+                res.getInteger(R.integer.config_dynamic_grid_overview_scale_percentage) / 100f;
+
+        // Interpolate the rows
+        for (DeviceProfile p : profiles) {
+            points.add(new DeviceProfileQuery(p.minWidthDps, p.minHeightDps, p.numRows));
+        }
+        numRows = Math.round(invDistWeightedInterpolate(minWidth, minHeight, points));
+        // Interpolate the columns
+        points.clear();
+        for (DeviceProfile p : profiles) {
+            points.add(new DeviceProfileQuery(p.minWidthDps, p.minHeightDps, p.numColumns));
+        }
+        numColumns = Math.round(invDistWeightedInterpolate(minWidth, minHeight, points));
+        // Interpolate the hotseat length
+        points.clear();
+        for (DeviceProfile p : profiles) {
+            points.add(new DeviceProfileQuery(p.minWidthDps, p.minHeightDps, p.numHotseatIcons));
+        }
+        numHotseatIcons = Math.round(invDistWeightedInterpolate(minWidth, minHeight, points));
+        hotseatAllAppsRank = (int) (numHotseatIcons / 2);
+
+        // Interpolate the icon size
+        points.clear();
+        for (DeviceProfile p : profiles) {
+            points.add(new DeviceProfileQuery(p.minWidthDps, p.minHeightDps, p.iconSize));
+        }
+        iconSize = invDistWeightedInterpolate(minWidth, minHeight, points);
+        // AllApps uses the original non-scaled icon size
+        allAppsIconSizePx = DynamicGrid.pxFromDp(iconSize, dm);
+
+        // Interpolate the icon text size
+        points.clear();
+        for (DeviceProfile p : profiles) {
+            points.add(new DeviceProfileQuery(p.minWidthDps, p.minHeightDps, p.iconTextSize));
+        }
+        iconTextSize = invDistWeightedInterpolate(minWidth, minHeight, points);
+        iconDrawablePaddingOriginalPx =
+                res.getDimensionPixelSize(R.dimen.dynamic_grid_icon_drawable_padding);
+        // AllApps uses the original non-scaled icon text size
+        allAppsIconTextSizePx = DynamicGrid.pxFromDp(iconTextSize, dm);
+
+        // Interpolate the hotseat icon size
+        points.clear();
+        for (DeviceProfile p : profiles) {
+            points.add(new DeviceProfileQuery(p.minWidthDps, p.minHeightDps, p.hotseatIconSize));
+        }
+        // Hotseat
+        hotseatIconSize = invDistWeightedInterpolate(minWidth, minHeight, points);
+
+        // Calculate the remaining vars
+        updateFromConfiguration(context, res, wPx, hPx, awPx, ahPx);
+        updateAvailableDimensions(context);
+    }
+
+    void addCallback(DeviceProfileCallbacks cb) {
+        mCallbacks.add(cb);
+        cb.onAvailableSizeChanged(this);
+    }
+    void removeCallback(DeviceProfileCallbacks cb) {
+        mCallbacks.remove(cb);
+    }
+
+    private int getDeviceOrientation(Context context) {
+        WindowManager windowManager =  (WindowManager)
+                context.getSystemService(Context.WINDOW_SERVICE);
+        Resources resources = context.getResources();
+        DisplayMetrics dm = resources.getDisplayMetrics();
+        Configuration config = resources.getConfiguration();
+        int rotation = windowManager.getDefaultDisplay().getRotation();
+
+        boolean isLandscape = (config.orientation == Configuration.ORIENTATION_LANDSCAPE) &&
+                (rotation == Surface.ROTATION_0 || rotation == Surface.ROTATION_180);
+        boolean isRotatedPortrait = (config.orientation == Configuration.ORIENTATION_PORTRAIT) &&
+                (rotation == Surface.ROTATION_90 || rotation == Surface.ROTATION_270);
+        if (isLandscape || isRotatedPortrait) {
+            return CellLayout.LANDSCAPE;
+        } else {
+            return CellLayout.PORTRAIT;
+        }
+    }
+
+    private void updateAvailableDimensions(Context context) {
+        WindowManager windowManager =  (WindowManager)
+                context.getSystemService(Context.WINDOW_SERVICE);
+        Display display = windowManager.getDefaultDisplay();
+        Resources resources = context.getResources();
+        DisplayMetrics dm = resources.getDisplayMetrics();
+        Configuration config = resources.getConfiguration();
+
+        // There are three possible configurations that the dynamic grid accounts for, portrait,
+        // landscape with the nav bar at the bottom, and landscape with the nav bar at the side.
+        // To prevent waiting for fitSystemWindows(), we make the observation that in landscape,
+        // the height is the smallest height (either with the nav bar at the bottom or to the
+        // side) and otherwise, the height is simply the largest possible height for a portrait
+        // device.
+        Point size = new Point();
+        Point smallestSize = new Point();
+        Point largestSize = new Point();
+        display.getSize(size);
+        display.getCurrentSizeRange(smallestSize, largestSize);
+        availableWidthPx = size.x;
+        if (config.orientation == Configuration.ORIENTATION_LANDSCAPE) {
+            availableHeightPx = smallestSize.y;
+        } else {
+            availableHeightPx = largestSize.y;
+        }
+
+        // Check to see if the icons fit in the new available height.  If not, then we need to
+        // shrink the icon size.
+        float scale = 1f;
+        int drawablePadding = iconDrawablePaddingOriginalPx;
+        updateIconSize(1f, drawablePadding, resources, dm);
+        float usedHeight = (cellHeightPx * numRows);
+
+        Rect workspacePadding = getWorkspacePadding();
+        int maxHeight = (availableHeightPx - workspacePadding.top - workspacePadding.bottom);
+        if (usedHeight > maxHeight) {
+            scale = maxHeight / usedHeight;
+            drawablePadding = 0;
+        }
+        updateIconSize(scale, drawablePadding, resources, dm);
+
+        // Make the callbacks
+        for (DeviceProfileCallbacks cb : mCallbacks) {
+            cb.onAvailableSizeChanged(this);
+        }
+    }
+
+    private void updateIconSize(float scale, int drawablePadding, Resources resources,
+                                DisplayMetrics dm) {
+        iconSizePx = (int) (DynamicGrid.pxFromDp(iconSize, dm) * scale);
+        iconTextSizePx = (int) (DynamicGrid.pxFromSp(iconTextSize, dm) * scale);
+        iconDrawablePaddingPx = drawablePadding;
+        hotseatIconSizePx = (int) (DynamicGrid.pxFromDp(hotseatIconSize, dm) * scale);
+
+        // Search Bar
+        searchBarSpaceMaxWidthPx = resources.getDimensionPixelSize(R.dimen.dynamic_grid_search_bar_max_width);
+        searchBarHeightPx = resources.getDimensionPixelSize(R.dimen.dynamic_grid_search_bar_height);
+        searchBarSpaceWidthPx = Math.min(searchBarSpaceMaxWidthPx, widthPx);
+        searchBarSpaceHeightPx = searchBarHeightPx + getSearchBarTopOffset();
+
+        // Calculate the actual text height
+        Paint textPaint = new Paint();
+        textPaint.setTextSize(iconTextSizePx);
+        FontMetrics fm = textPaint.getFontMetrics();
+        cellWidthPx = iconSizePx;
+        cellHeightPx = iconSizePx + iconDrawablePaddingPx + (int) Math.ceil(fm.bottom - fm.top);
+        final float scaleDps = resources.getDimensionPixelSize(R.dimen.dragViewScale);
+        dragViewScale = (iconSizePx + scaleDps) / iconSizePx;
+
+        // Hotseat
+        hotseatBarHeightPx = iconSizePx + 4 * edgeMarginPx;
+        hotseatCellWidthPx = iconSizePx;
+        hotseatCellHeightPx = iconSizePx;
+
+        // Folder
+        folderCellWidthPx = cellWidthPx + 3 * edgeMarginPx;
+        folderCellHeightPx = cellHeightPx + edgeMarginPx;
+        folderBackgroundOffset = -edgeMarginPx;
+        folderIconSizePx = iconSizePx + 2 * -folderBackgroundOffset;
+
+        // All Apps
+        Rect padding = getWorkspacePadding(isLandscape ?
+                CellLayout.LANDSCAPE : CellLayout.PORTRAIT);
+        int pageIndicatorOffset =
+                resources.getDimensionPixelSize(R.dimen.apps_customize_page_indicator_offset);
+        allAppsCellWidthPx = allAppsIconSizePx;
+        allAppsCellHeightPx = allAppsIconSizePx + drawablePadding + iconTextSizePx;
+        int maxLongEdgeCellCount =
+                resources.getInteger(R.integer.config_dynamic_grid_max_long_edge_cell_count);
+        int maxShortEdgeCellCount =
+                resources.getInteger(R.integer.config_dynamic_grid_max_short_edge_cell_count);
+        int minEdgeCellCount =
+                resources.getInteger(R.integer.config_dynamic_grid_min_edge_cell_count);
+        int maxRows = (isLandscape ? maxShortEdgeCellCount : maxLongEdgeCellCount);
+        int maxCols = (isLandscape ? maxLongEdgeCellCount : maxShortEdgeCellCount);
+
+        allAppsNumRows = (availableHeightPx - pageIndicatorHeightPx) /
+                (allAppsCellHeightPx + allAppsCellPaddingPx);
+        allAppsNumRows = Math.max(minEdgeCellCount, Math.min(maxRows, allAppsNumRows));
+        allAppsNumCols = (availableWidthPx) /
+                (allAppsCellWidthPx + allAppsCellPaddingPx);
+        allAppsNumCols = Math.max(minEdgeCellCount, Math.min(maxCols, allAppsNumCols));
+    }
+
+    void updateFromConfiguration(Context context, Resources resources, int wPx, int hPx,
+                                 int awPx, int ahPx) {
+        Configuration configuration = resources.getConfiguration();
+        isLandscape = (configuration.orientation == Configuration.ORIENTATION_LANDSCAPE);
+        isTablet = resources.getBoolean(R.bool.is_tablet);
+        isLargeTablet = resources.getBoolean(R.bool.is_large_tablet);
+        if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.JELLY_BEAN_MR1) {
+            isLayoutRtl = (configuration.getLayoutDirection() == View.LAYOUT_DIRECTION_RTL);
+        } else {
+            isLayoutRtl = false;
+        }
+        widthPx = wPx;
+        heightPx = hPx;
+        availableWidthPx = awPx;
+        availableHeightPx = ahPx;
+
+        updateAvailableDimensions(context);
+    }
+
+    private float dist(PointF p0, PointF p1) {
+        return (float) Math.sqrt((p1.x - p0.x)*(p1.x-p0.x) +
+                (p1.y-p0.y)*(p1.y-p0.y));
+    }
+
+    private float weight(PointF a, PointF b,
+                        float pow) {
+        float d = dist(a, b);
+        if (d == 0f) {
+            return Float.POSITIVE_INFINITY;
+        }
+        return (float) (1f / Math.pow(d, pow));
+    }
+
+    private float invDistWeightedInterpolate(float width, float height,
+                ArrayList<DeviceProfileQuery> points) {
+        float sum = 0;
+        float weights = 0;
+        float pow = 5;
+        float kNearestNeighbors = 3;
+        final PointF xy = new PointF(width, height);
+
+        ArrayList<DeviceProfileQuery> pointsByNearness = points;
+        Collections.sort(pointsByNearness, new Comparator<DeviceProfileQuery>() {
+            public int compare(DeviceProfileQuery a, DeviceProfileQuery b) {
+                return (int) (dist(xy, a.dimens) - dist(xy, b.dimens));
+            }
+        });
+
+        for (int i = 0; i < pointsByNearness.size(); ++i) {
+            DeviceProfileQuery p = pointsByNearness.get(i);
+            if (i < kNearestNeighbors) {
+                float w = weight(xy, p.dimens, pow);
+                if (w == Float.POSITIVE_INFINITY) {
+                    return p.value;
+                }
+                weights += w;
+            }
+        }
+
+        for (int i = 0; i < pointsByNearness.size(); ++i) {
+            DeviceProfileQuery p = pointsByNearness.get(i);
+            if (i < kNearestNeighbors) {
+                float w = weight(xy, p.dimens, pow);
+                sum += w * p.value / weights;
+            }
+        }
+
+        return sum;
+    }
+
+    /** Returns the search bar top offset */
+    int getSearchBarTopOffset() {
+        if (isTablet() && !isVerticalBarLayout()) {
+            return 4 * edgeMarginPx;
+        } else {
+            return 2 * edgeMarginPx;
+        }
+    }
+
+    /** Returns the search bar bounds in the current orientation */
+    Rect getSearchBarBounds() {
+        return getSearchBarBounds(isLandscape ? CellLayout.LANDSCAPE : CellLayout.PORTRAIT);
+    }
+    /** Returns the search bar bounds in the specified orientation */
+    Rect getSearchBarBounds(int orientation) {
+        Rect bounds = new Rect();
+        if (orientation == CellLayout.LANDSCAPE &&
+                transposeLayoutWithOrientation) {
+            if (isLayoutRtl) {
+                bounds.set(availableWidthPx - searchBarSpaceHeightPx, edgeMarginPx,
+                        availableWidthPx, availableHeightPx - edgeMarginPx);
+            } else {
+                bounds.set(0, edgeMarginPx, searchBarSpaceHeightPx,
+                        availableHeightPx - edgeMarginPx);
+            }
+        } else {
+            if (isTablet()) {
+                // Pad the left and right of the workspace to ensure consistent spacing
+                // between all icons
+                int width = (orientation == CellLayout.LANDSCAPE)
+                        ? Math.max(widthPx, heightPx)
+                        : Math.min(widthPx, heightPx);
+                // XXX: If the icon size changes across orientations, we will have to take
+                //      that into account here too.
+                int gap = (int) ((width - 2 * edgeMarginPx -
+                        (numColumns * cellWidthPx)) / (2 * (numColumns + 1)));
+                bounds.set(edgeMarginPx + gap, getSearchBarTopOffset(),
+                        availableWidthPx - (edgeMarginPx + gap),
+                        searchBarSpaceHeightPx);
+            } else {
+                bounds.set(desiredWorkspaceLeftRightMarginPx - defaultWidgetPadding.left,
+                        getSearchBarTopOffset(),
+                        availableWidthPx - (desiredWorkspaceLeftRightMarginPx -
+                        defaultWidgetPadding.right), searchBarSpaceHeightPx);
+            }
+        }
+        return bounds;
+    }
+
+    /** Returns the bounds of the workspace page indicators. */
+    Rect getWorkspacePageIndicatorBounds(Rect insets) {
+        Rect workspacePadding = getWorkspacePadding();
+        if (isLandscape && transposeLayoutWithOrientation) {
+            if (isLayoutRtl) {
+                return new Rect(workspacePadding.left, workspacePadding.top,
+                        workspacePadding.left + pageIndicatorHeightPx,
+                        heightPx - workspacePadding.bottom - insets.bottom);
+            } else {
+                int pageIndicatorLeft = widthPx - workspacePadding.right;
+                return new Rect(pageIndicatorLeft, workspacePadding.top,
+                        pageIndicatorLeft + pageIndicatorHeightPx,
+                        heightPx - workspacePadding.bottom - insets.bottom);
+            }
+        } else {
+            int pageIndicatorTop = heightPx - insets.bottom - workspacePadding.bottom;
+            return new Rect(workspacePadding.left, pageIndicatorTop,
+                    widthPx - workspacePadding.right, pageIndicatorTop + pageIndicatorHeightPx);
+        }
+    }
+
+    /** Returns the workspace padding in the specified orientation */
+    Rect getWorkspacePadding() {
+        return getWorkspacePadding(isLandscape ? CellLayout.LANDSCAPE : CellLayout.PORTRAIT);
+    }
+    Rect getWorkspacePadding(int orientation) {
+        Rect searchBarBounds = getSearchBarBounds(orientation);
+        Rect padding = new Rect();
+        if (orientation == CellLayout.LANDSCAPE &&
+                transposeLayoutWithOrientation) {
+            // Pad the left and right of the workspace with search/hotseat bar sizes
+            if (isLayoutRtl) {
+                padding.set(hotseatBarHeightPx, edgeMarginPx,
+                        searchBarBounds.width(), edgeMarginPx);
+            } else {
+                padding.set(searchBarBounds.width(), edgeMarginPx,
+                        hotseatBarHeightPx, edgeMarginPx);
+            }
+        } else {
+            if (isTablet()) {
+                // Pad the left and right of the workspace to ensure consistent spacing
+                // between all icons
+                float gapScale = 1f + (dragViewScale - 1f) / 2f;
+                int width = (orientation == CellLayout.LANDSCAPE)
+                        ? Math.max(widthPx, heightPx)
+                        : Math.min(widthPx, heightPx);
+                int height = (orientation != CellLayout.LANDSCAPE)
+                        ? Math.max(widthPx, heightPx)
+                        : Math.min(widthPx, heightPx);
+                int paddingTop = searchBarBounds.bottom;
+                int paddingBottom = hotseatBarHeightPx + pageIndicatorHeightPx;
+                int availableWidth = Math.max(0, width - (int) ((numColumns * cellWidthPx) +
+                        (numColumns * gapScale * cellWidthPx)));
+                int availableHeight = Math.max(0, height - paddingTop - paddingBottom
+                        - (int) (2 * numRows * cellHeightPx));
+                padding.set(availableWidth / 2, paddingTop + availableHeight / 2,
+                        availableWidth / 2, paddingBottom + availableHeight / 2);
+            } else {
+                // Pad the top and bottom of the workspace with search/hotseat bar sizes
+                padding.set(desiredWorkspaceLeftRightMarginPx - defaultWidgetPadding.left,
+                        searchBarBounds.bottom,
+                        desiredWorkspaceLeftRightMarginPx - defaultWidgetPadding.right,
+                        hotseatBarHeightPx + pageIndicatorHeightPx);
+            }
+        }
+        return padding;
+    }
+
+    int getWorkspacePageSpacing(int orientation) {
+        if ((orientation == CellLayout.LANDSCAPE &&
+                transposeLayoutWithOrientation) || isLargeTablet()) {
+            // In landscape mode the page spacing is set to the default.
+            return defaultPageSpacingPx;
+        } else {
+            // In portrait, we want the pages spaced such that there is no
+            // overhang of the previous / next page into the current page viewport.
+            // We assume symmetrical padding in portrait mode.
+            return Math.max(defaultPageSpacingPx, 2 * getWorkspacePadding().left);
+        }
+    }
+
+    Rect getOverviewModeButtonBarRect() {
+        int zoneHeight = (int) (overviewModeIconZoneRatio * availableHeightPx);
+        zoneHeight = Math.min(overviewModeMaxIconZoneHeightPx,
+                Math.max(overviewModeMinIconZoneHeightPx, zoneHeight));
+        return new Rect(0, availableHeightPx - zoneHeight, 0, availableHeightPx);
+    }
+
+    float getOverviewModeScale() {
+        Rect workspacePadding = getWorkspacePadding();
+        Rect overviewBar = getOverviewModeButtonBarRect();
+        int pageSpace = availableHeightPx - workspacePadding.top - workspacePadding.bottom;
+        return (overviewModeScaleFactor * (pageSpace - overviewBar.height())) / pageSpace;
+    }
+
+    // The rect returned will be extended to below the system ui that covers the workspace
+    Rect getHotseatRect() {
+        if (isVerticalBarLayout()) {
+            return new Rect(availableWidthPx - hotseatBarHeightPx, 0,
+                    Integer.MAX_VALUE, availableHeightPx);
+        } else {
+            return new Rect(0, availableHeightPx - hotseatBarHeightPx,
+                    availableWidthPx, Integer.MAX_VALUE);
+        }
+    }
+
+    int calculateCellWidth(int width, int countX) {
+        return width / countX;
+    }
+    int calculateCellHeight(int height, int countY) {
+        return height / countY;
+    }
+
+    boolean isPhone() {
+        return !isTablet && !isLargeTablet;
+    }
+    boolean isTablet() {
+        return isTablet;
+    }
+    boolean isLargeTablet() {
+        return isLargeTablet;
+    }
+
+    boolean isVerticalBarLayout() {
+        return isLandscape && transposeLayoutWithOrientation;
+    }
+
+    boolean shouldFadeAdjacentWorkspaceScreens() {
+        return isVerticalBarLayout() || isLargeTablet();
+    }
+
+    int getVisibleChildCount(ViewGroup parent) {
+        int visibleChildren = 0;
+        for (int i = 0; i < parent.getChildCount(); i++) {
+            if (parent.getChildAt(i).getVisibility() != View.GONE) {
+                visibleChildren++;
+            }
+        }
+        return visibleChildren;
+    }
+
+    int calculateOverviewModeWidth(int visibleChildCount) {
+        return visibleChildCount * overviewModeBarItemWidthPx +
+                (visibleChildCount-1) * overviewModeBarSpacerWidthPx;
+    }
+
+    public void layout(Launcher launcher) {
+        FrameLayout.LayoutParams lp;
+        Resources res = launcher.getResources();
+        boolean hasVerticalBarLayout = isVerticalBarLayout();
+
+        // Layout the search bar space
+        View searchBar = launcher.getSearchBar();
+        lp = (FrameLayout.LayoutParams) searchBar.getLayoutParams();
+        if (hasVerticalBarLayout) {
+            // Vertical search bar space
+            lp.gravity = Gravity.TOP | Gravity.LEFT;
+            lp.width = searchBarSpaceHeightPx;
+            lp.height = LayoutParams.WRAP_CONTENT;
+            searchBar.setPadding(
+                    0, 2 * edgeMarginPx, 0,
+                    2 * edgeMarginPx);
+
+            LinearLayout targets = (LinearLayout) searchBar.findViewById(R.id.drag_target_bar);
+            targets.setOrientation(LinearLayout.VERTICAL);
+        } else {
+            // Horizontal search bar space
+            lp.gravity = Gravity.TOP | Gravity.CENTER_HORIZONTAL;
+            lp.width = searchBarSpaceWidthPx;
+            lp.height = searchBarSpaceHeightPx;
+            searchBar.setPadding(
+                    2 * edgeMarginPx,
+                    getSearchBarTopOffset(),
+                    2 * edgeMarginPx, 0);
+        }
+        searchBar.setLayoutParams(lp);
+
+        // Layout the voice proxy
+        View voiceButtonProxy = launcher.findViewById(R.id.voice_button_proxy);
+        if (voiceButtonProxy != null) {
+            if (hasVerticalBarLayout) {
+                // TODO: MOVE THIS INTO SEARCH BAR MEASURE
+            } else {
+                lp = (FrameLayout.LayoutParams) voiceButtonProxy.getLayoutParams();
+                lp.gravity = Gravity.TOP | Gravity.END;
+                lp.width = (widthPx - searchBarSpaceWidthPx) / 2 +
+                        2 * iconSizePx;
+                lp.height = searchBarSpaceHeightPx;
+            }
+        }
+
+        // Layout the workspace
+        PagedView workspace = (PagedView) launcher.findViewById(R.id.workspace);
+        lp = (FrameLayout.LayoutParams) workspace.getLayoutParams();
+        lp.gravity = Gravity.CENTER;
+        int orientation = isLandscape ? CellLayout.LANDSCAPE : CellLayout.PORTRAIT;
+        Rect padding = getWorkspacePadding(orientation);
+        workspace.setLayoutParams(lp);
+        workspace.setPadding(padding.left, padding.top, padding.right, padding.bottom);
+        workspace.setPageSpacing(getWorkspacePageSpacing(orientation));
+
+        // Layout the hotseat
+        View hotseat = launcher.findViewById(R.id.hotseat);
+        lp = (FrameLayout.LayoutParams) hotseat.getLayoutParams();
+        if (hasVerticalBarLayout) {
+            // Vertical hotseat
+            lp.gravity = Gravity.END;
+            lp.width = hotseatBarHeightPx;
+            lp.height = LayoutParams.MATCH_PARENT;
+            hotseat.findViewById(R.id.layout).setPadding(0, 2 * edgeMarginPx, 0, 2 * edgeMarginPx);
+        } else if (isTablet()) {
+            // Pad the hotseat with the workspace padding calculated above
+            lp.gravity = Gravity.BOTTOM;
+            lp.width = LayoutParams.MATCH_PARENT;
+            lp.height = hotseatBarHeightPx;
+            hotseat.setPadding(edgeMarginPx + padding.left, 0,
+                    edgeMarginPx + padding.right,
+                    2 * edgeMarginPx);
+        } else {
+            // For phones, layout the hotseat without any bottom margin
+            // to ensure that we have space for the folders
+            lp.gravity = Gravity.BOTTOM;
+            lp.width = LayoutParams.MATCH_PARENT;
+            lp.height = hotseatBarHeightPx;
+            hotseat.findViewById(R.id.layout).setPadding(2 * edgeMarginPx, 0,
+                    2 * edgeMarginPx, 0);
+        }
+        hotseat.setLayoutParams(lp);
+
+        // Layout the page indicators
+        View pageIndicator = launcher.findViewById(R.id.page_indicator);
+        if (pageIndicator != null) {
+            if (hasVerticalBarLayout) {
+                // Hide the page indicators when we have vertical search/hotseat
+                pageIndicator.setVisibility(View.GONE);
+            } else {
+                // Put the page indicators above the hotseat
+                lp = (FrameLayout.LayoutParams) pageIndicator.getLayoutParams();
+                lp.gravity = Gravity.CENTER_HORIZONTAL | Gravity.BOTTOM;
+                lp.width = LayoutParams.WRAP_CONTENT;
+                lp.height = LayoutParams.WRAP_CONTENT;
+                lp.bottomMargin = hotseatBarHeightPx;
+                pageIndicator.setLayoutParams(lp);
+            }
+        }
+
+        // Layout AllApps
+        AppsCustomizeTabHost host = (AppsCustomizeTabHost)
+                launcher.findViewById(R.id.apps_customize_pane);
+        if (host != null) {
+            // Center the all apps page indicator
+            int pageIndicatorHeight = (int) (pageIndicatorHeightPx * Math.min(1f,
+                    (allAppsIconSizePx / DynamicGrid.DEFAULT_ICON_SIZE_PX)));
+            pageIndicator = host.findViewById(R.id.apps_customize_page_indicator);
+            if (pageIndicator != null) {
+                lp = (FrameLayout.LayoutParams) pageIndicator.getLayoutParams();
+                lp.gravity = Gravity.CENTER_HORIZONTAL | Gravity.BOTTOM;
+                lp.width = LayoutParams.WRAP_CONTENT;
+                lp.height = pageIndicatorHeight;
+                pageIndicator.setLayoutParams(lp);
+            }
+
+            AppsCustomizePagedView pagedView = (AppsCustomizePagedView)
+                    host.findViewById(R.id.apps_customize_pane_content);
+            padding = new Rect();
+            if (pagedView != null) {
+                // Constrain the dimensions of all apps so that it does not span the full width
+                int paddingLR = (availableWidthPx - (allAppsCellWidthPx * allAppsNumCols)) /
+                        (2 * (allAppsNumCols + 1));
+                int paddingTB = (availableHeightPx - (allAppsCellHeightPx * allAppsNumRows)) /
+                        (2 * (allAppsNumRows + 1));
+                paddingLR = Math.min(paddingLR, (int)((paddingLR + paddingTB) * 0.75f));
+                paddingTB = Math.min(paddingTB, (int)((paddingLR + paddingTB) * 0.75f));
+                int maxAllAppsWidth = (allAppsNumCols * (allAppsCellWidthPx + 2 * paddingLR));
+                int gridPaddingLR = (availableWidthPx - maxAllAppsWidth) / 2;
+                // Only adjust the side paddings on landscape phones, or tablets
+                if ((isTablet() || isLandscape) && gridPaddingLR > (allAppsCellWidthPx / 4)) {
+                    padding.left = padding.right = gridPaddingLR;
+                }
+                // The icons are centered, so we can't just offset by the page indicator height
+                // because the empty space will actually be pageIndicatorHeight + paddingTB
+                padding.bottom = Math.max(0, pageIndicatorHeight - paddingTB);
+                pagedView.setAllAppsPadding(padding);
+                pagedView.setWidgetsPageIndicatorPadding(pageIndicatorHeight);
+            }
+        }
+
+        // Layout the Overview Mode
+        ViewGroup overviewMode = launcher.getOverviewPanel();
+        if (overviewMode != null) {
+            Rect r = getOverviewModeButtonBarRect();
+            lp = (FrameLayout.LayoutParams) overviewMode.getLayoutParams();
+            lp.gravity = Gravity.CENTER_HORIZONTAL | Gravity.BOTTOM;
+            lp.width = Math.min(availableWidthPx,
+                    calculateOverviewModeWidth(getVisibleChildCount(overviewMode)));
+            lp.height = r.height();
+            overviewMode.setLayoutParams(lp);
+        }
+    }
+}
diff --git a/src/com/android/launcher3/DragController.java b/src/com/android/launcher3/DragController.java
index 5b5c35c..4c3ea2a 100644
--- a/src/com/android/launcher3/DragController.java
+++ b/src/com/android/launcher3/DragController.java
@@ -16,6 +16,7 @@
 
 package com.android.launcher3;
 
+import android.content.ComponentName;
 import android.content.Context;
 import android.content.res.Resources;
 import android.graphics.Bitmap;
@@ -25,16 +26,9 @@
 import android.os.Handler;
 import android.os.IBinder;
 import android.util.Log;
-import android.view.HapticFeedbackConstants;
-import android.view.KeyEvent;
-import android.view.MotionEvent;
-import android.view.VelocityTracker;
-import android.view.View;
-import android.view.ViewConfiguration;
+import android.view.*;
 import android.view.inputmethod.InputMethodManager;
 
-import com.android.launcher3.R;
-
 import java.util.ArrayList;
 
 /**
@@ -203,7 +197,7 @@
      * @param dragRegion Coordinates within the bitmap b for the position of item being dragged.
      *          Makes dragging feel more precise, e.g. you can clip out a transparent border
      */
-    public void startDrag(Bitmap b, int dragLayerX, int dragLayerY,
+    public DragView startDrag(Bitmap b, int dragLayerX, int dragLayerY,
             DragSource source, Object dragInfo, int dragAction, Point dragOffset, Rect dragRegion,
             float initialDragViewScale) {
         if (PROFILE_DRAWING_DURING_DRAG) {
@@ -250,6 +244,7 @@
         mLauncher.getDragLayer().performHapticFeedback(HapticFeedbackConstants.LONG_PRESS);
         dragView.show(mMotionDownX, mMotionDownY);
         handleMoveEvent(mMotionDownX, mMotionDownY);
+        return dragView;
     }
 
     /**
@@ -323,7 +318,7 @@
         }
         endDrag();
     }
-    public void onAppsRemoved(ArrayList<AppInfo> appInfos, Context context) {
+    public void onAppsRemoved(final ArrayList<String> packageNames, ArrayList<AppInfo> appInfos) {
         // Cancel the current drag if we are removing an app that we are dragging
         if (mDragObject != null) {
             Object rawDragInfo = mDragObject.dragInfo;
@@ -332,9 +327,10 @@
                 for (AppInfo info : appInfos) {
                     // Added null checks to prevent NPE we've seen in the wild
                     if (dragInfo != null &&
-                        dragInfo.intent != null) {
-                        boolean isSameComponent =
-                                dragInfo.intent.getComponent().equals(info.componentName);
+                            dragInfo.intent != null && info != null) {
+                        ComponentName cn = dragInfo.intent.getComponent();
+                        boolean isSameComponent = cn.equals(info.componentName) ||
+                                packageNames.contains(cn.getPackageName());
                         if (isSameComponent) {
                             cancelDrag();
                             return;
diff --git a/src/com/android/launcher3/DragLayer.java b/src/com/android/launcher3/DragLayer.java
index 89f8275..ab0469d 100644
--- a/src/com/android/launcher3/DragLayer.java
+++ b/src/com/android/launcher3/DragLayer.java
@@ -24,11 +24,13 @@
 import android.content.Context;
 import android.content.res.Resources;
 import android.graphics.Canvas;
-import android.graphics.Matrix;
 import android.graphics.Rect;
 import android.graphics.drawable.Drawable;
 import android.util.AttributeSet;
-import android.view.*;
+import android.view.KeyEvent;
+import android.view.MotionEvent;
+import android.view.View;
+import android.view.ViewGroup;
 import android.view.accessibility.AccessibilityEvent;
 import android.view.accessibility.AccessibilityManager;
 import android.view.animation.DecelerateInterpolator;
@@ -106,21 +108,31 @@
         final int n = getChildCount();
         for (int i = 0; i < n; i++) {
             final View child = getChildAt(i);
-            final FrameLayout.LayoutParams flp = (FrameLayout.LayoutParams) child.getLayoutParams();
-            if (child instanceof Insettable) {
-                ((Insettable)child).setInsets(insets);
-            } else {
-                flp.topMargin += (insets.top - mInsets.top);
-                flp.leftMargin += (insets.left - mInsets.left);
-                flp.rightMargin += (insets.right - mInsets.right);
-                flp.bottomMargin += (insets.bottom - mInsets.bottom);
-            }
-            child.setLayoutParams(flp);
+            setInsets(child, insets, mInsets);
         }
         mInsets.set(insets);
         return true; // I'll take it from here
     }
 
+    @Override
+    public void addView(View child, int index, android.view.ViewGroup.LayoutParams params) {
+        super.addView(child, index, params);
+        setInsets(child, mInsets, new Rect());
+    }
+
+    private void setInsets(View child, Rect newInsets, Rect oldInsets) {
+        final FrameLayout.LayoutParams flp = (FrameLayout.LayoutParams) child.getLayoutParams();
+        if (child instanceof Insettable) {
+            ((Insettable) child).setInsets(newInsets);
+        } else {
+            flp.topMargin += (newInsets.top - oldInsets.top);
+            flp.leftMargin += (newInsets.left - oldInsets.left);
+            flp.rightMargin += (newInsets.right - oldInsets.right);
+            flp.bottomMargin += (newInsets.bottom - oldInsets.bottom);
+        }
+        child.setLayoutParams(flp);
+    }
+
     private boolean isEventOverFolderTextRegion(Folder folder, MotionEvent ev) {
         getDescendantRectRelativeToSelf(folder.getEditTextRegion(), mHitRect);
         if (mHitRect.contains((int) ev.getX(), (int) ev.getY())) {
@@ -156,7 +168,8 @@
         }
 
         Folder currentFolder = mLauncher.getWorkspace().getOpenFolder();
-        if (currentFolder != null && !mLauncher.isFolderClingVisible() && intercept) {
+        if (currentFolder != null && !mLauncher.getLauncherClings().isFolderClingVisible() &&
+                intercept) {
             if (currentFolder.isEditingName()) {
                 if (!isEventOverFolderTextRegion(currentFolder, ev)) {
                     currentFolder.dismissEditingName();
@@ -212,22 +225,19 @@
                             sendTapOutsideFolderAccessibilityEvent(currentFolder.isEditingName());
                             mHoverPointClosesFolder = true;
                             return true;
-                        } else if (isOverFolder) {
-                            mHoverPointClosesFolder = false;
-                        } else {
-                            return true;
                         }
+                        mHoverPointClosesFolder = false;
+                        break;
                     case MotionEvent.ACTION_HOVER_MOVE:
                         isOverFolder = isEventOverFolder(currentFolder, ev);
                         if (!isOverFolder && !mHoverPointClosesFolder) {
                             sendTapOutsideFolderAccessibilityEvent(currentFolder.isEditingName());
                             mHoverPointClosesFolder = true;
                             return true;
-                        } else if (isOverFolder) {
-                            mHoverPointClosesFolder = false;
-                        } else {
+                        } else if (!isOverFolder) {
                             return true;
                         }
+                        mHoverPointClosesFolder = false;
                 }
             }
         }
@@ -480,7 +490,7 @@
     }
 
     public void animateViewIntoPosition(DragView dragView, final View child) {
-        animateViewIntoPosition(dragView, child, null);
+        animateViewIntoPosition(dragView, child, null, null);
     }
 
     public void animateViewIntoPosition(DragView dragView, final int[] pos, float alpha,
@@ -496,8 +506,8 @@
     }
 
     public void animateViewIntoPosition(DragView dragView, final View child,
-            final Runnable onFinishAnimationRunnable) {
-        animateViewIntoPosition(dragView, child, -1, onFinishAnimationRunnable, null);
+            final Runnable onFinishAnimationRunnable, View anchorView) {
+        animateViewIntoPosition(dragView, child, -1, onFinishAnimationRunnable, anchorView);
     }
 
     public void animateViewIntoPosition(DragView dragView, final View child, int duration,
@@ -522,14 +532,18 @@
         scale *= childScale;
         int toX = coord[0];
         int toY = coord[1];
+        float toScale = scale;
         if (child instanceof TextView) {
             TextView tv = (TextView) child;
+            // Account for the source scale of the icon (ie. from AllApps to Workspace, in which
+            // the workspace may have smaller icon bounds).
+            toScale = scale / dragView.getIntrinsicIconScaleFactor();
 
             // The child may be scaled (always about the center of the view) so to account for it,
             // we have to offset the position by the scaled size.  Once we do that, we can center
             // the drag view about the scaled child view.
-            toY += Math.round(scale * tv.getPaddingTop());
-            toY -= dragView.getMeasuredHeight() * (1 - scale) / 2;
+            toY += Math.round(toScale * tv.getPaddingTop());
+            toY -= dragView.getMeasuredHeight() * (1 - toScale) / 2;
             toX -= (dragView.getMeasuredWidth() - Math.round(scale * child.getMeasuredWidth())) / 2;
         } else if (child instanceof FolderIcon) {
             // Account for holographic blur padding on the drag view
@@ -555,7 +569,7 @@
                 }
             }
         };
-        animateViewIntoPosition(dragView, fromX, fromY, toX, toY, 1, 1, 1, scale, scale,
+        animateViewIntoPosition(dragView, fromX, fromY, toX, toY, 1, 1, 1, toScale, toScale,
                 onCompleteRunnable, ANIMATION_END_DISAPPEAR, duration, anchorView);
     }
 
@@ -645,8 +659,10 @@
                 int x = (int) (fromLeft + Math.round(((to.left - fromLeft) * motionPercent)));
                 int y = (int) (fromTop + Math.round(((to.top - fromTop) * motionPercent)));
 
-                int xPos = x - mDropView.getScrollX() + (mAnchorView != null
-                        ? (mAnchorViewInitialScrollX - mAnchorView.getScrollX()) : 0);
+                int anchorAdjust = mAnchorView == null ? 0 : (int) (mAnchorView.getScaleX() *
+                    (mAnchorViewInitialScrollX - mAnchorView.getScrollX()));
+
+                int xPos = x - mDropView.getScrollX() + anchorAdjust;
                 int yPos = y - mDropView.getScrollY();
 
                 mDropView.setTranslationX(xPos);
diff --git a/src/com/android/launcher3/DragSource.java b/src/com/android/launcher3/DragSource.java
index 2ef99ae..7369eea 100644
--- a/src/com/android/launcher3/DragSource.java
+++ b/src/com/android/launcher3/DragSource.java
@@ -31,6 +31,22 @@
     boolean supportsFlingToDelete();
 
     /**
+     * @return whether items dragged from this source supports 'App Info'
+     */
+    boolean supportsAppInfoDropTarget();
+
+    /**
+     * @return whether items dragged from this source supports 'Delete' drop target (e.g. to remove
+     * a shortcut.
+     */
+    boolean supportsDeleteDropTarget();
+
+    /*
+     * @return the scale of the icons over the workspace icon size
+     */
+    float getIntrinsicIconScaleFactor();
+
+    /**
      * A callback specifically made back to the source after an item from this source has been flung
      * to be deleted on a DropTarget.  In such a situation, this method will be called after
      * onDropCompleted, and more importantly, after the fling animation has completed.
diff --git a/src/com/android/launcher3/DragView.java b/src/com/android/launcher3/DragView.java
index 686cf62..ea34e46 100644
--- a/src/com/android/launcher3/DragView.java
+++ b/src/com/android/launcher3/DragView.java
@@ -14,7 +14,6 @@
  * limitations under the License.
  */
 
-
 package com.android.launcher3;
 
 import android.animation.ValueAnimator;
@@ -30,8 +29,6 @@
 import android.view.View;
 import android.view.animation.DecelerateInterpolator;
 
-import com.android.launcher3.R;
-
 public class DragView extends View {
     private static float sDragAlpha = 1f;
 
@@ -51,6 +48,9 @@
     private float mOffsetX = 0.0f;
     private float mOffsetY = 0.0f;
     private float mInitialScale = 1f;
+    // The intrinsic icon scale factor is the scale factor for a drag icon over the workspace
+    // size.  This is ignored for non-icons.
+    private float mIntrinsicIconScale = 1f;
 
     /**
      * Construct the drag view.
@@ -120,6 +120,15 @@
         mPaint = new Paint(Paint.FILTER_BITMAP_FLAG);
     }
 
+    /** Sets the scale of the view over the normal workspace icon size. */
+    public void setIntrinsicIconScaleFactor(float scale) {
+        mIntrinsicIconScale = scale;
+    }
+
+    public float getIntrinsicIconScaleFactor() {
+        return mIntrinsicIconScale;
+    }
+
     public float getOffsetY() {
         return mOffsetY;
     }
diff --git a/src/com/android/launcher3/DrawableStateProxyView.java b/src/com/android/launcher3/DrawableStateProxyView.java
index 0758de1..c83659a 100644
--- a/src/com/android/launcher3/DrawableStateProxyView.java
+++ b/src/com/android/launcher3/DrawableStateProxyView.java
@@ -23,8 +23,6 @@
 import android.view.View;
 import android.widget.LinearLayout;
 
-import com.android.launcher3.R;
-
 public class DrawableStateProxyView extends LinearLayout {
 
     private View mView;
diff --git a/src/com/android/launcher3/DynamicGrid.java b/src/com/android/launcher3/DynamicGrid.java
index 4776c86..447bb1c 100644
--- a/src/com/android/launcher3/DynamicGrid.java
+++ b/src/com/android/launcher3/DynamicGrid.java
@@ -16,468 +16,14 @@
 
 package com.android.launcher3;
 
-import android.appwidget.AppWidgetHostView;
-import android.content.ComponentName;
 import android.content.Context;
-import android.content.res.Configuration;
 import android.content.res.Resources;
-import android.graphics.Paint;
-import android.graphics.Paint.FontMetrics;
-import android.graphics.PointF;
-import android.graphics.Rect;
 import android.util.DisplayMetrics;
 import android.util.TypedValue;
-import android.view.Gravity;
-import android.view.View;
-import android.view.ViewGroup.LayoutParams;
-import android.widget.FrameLayout;
 
 import java.util.ArrayList;
-import java.util.Collections;
-import java.util.Comparator;
 
 
-class DeviceProfileQuery {
-    float widthDps;
-    float heightDps;
-    float value;
-    PointF dimens;
-
-    DeviceProfileQuery(float w, float h, float v) {
-        widthDps = w;
-        heightDps = h;
-        value = v;
-        dimens = new PointF(w, h);
-    }
-}
-
-class DeviceProfile {
-    String name;
-    float minWidthDps;
-    float minHeightDps;
-    float numRows;
-    float numColumns;
-    float iconSize;
-    float iconTextSize;
-    float numHotseatIcons;
-    float hotseatIconSize;
-
-    boolean isLandscape;
-    boolean isTablet;
-    boolean isLargeTablet;
-    boolean transposeLayoutWithOrientation;
-
-    int desiredWorkspaceLeftRightMarginPx;
-    int edgeMarginPx;
-    Rect defaultWidgetPadding;
-
-    int widthPx;
-    int heightPx;
-    int availableWidthPx;
-    int availableHeightPx;
-    int iconSizePx;
-    int iconTextSizePx;
-    int cellWidthPx;
-    int cellHeightPx;
-    int folderBackgroundOffset;
-    int folderIconSizePx;
-    int folderCellWidthPx;
-    int folderCellHeightPx;
-    int hotseatCellWidthPx;
-    int hotseatCellHeightPx;
-    int hotseatIconSizePx;
-    int hotseatBarHeightPx;
-    int hotseatAllAppsRank;
-    int allAppsNumRows;
-    int allAppsNumCols;
-    int searchBarSpaceWidthPx;
-    int searchBarSpaceMaxWidthPx;
-    int searchBarSpaceHeightPx;
-    int searchBarHeightPx;
-    int pageIndicatorHeightPx;
-
-    DeviceProfile(String n, float w, float h, float r, float c,
-                  float is, float its, float hs, float his) {
-        // Ensure that we have an odd number of hotseat items (since we need to place all apps)
-        if (!AppsCustomizePagedView.DISABLE_ALL_APPS && hs % 2 == 0) {
-            throw new RuntimeException("All Device Profiles must have an odd number of hotseat spaces");
-        }
-
-        name = n;
-        minWidthDps = w;
-        minHeightDps = h;
-        numRows = r;
-        numColumns = c;
-        iconSize = is;
-        iconTextSize = its;
-        numHotseatIcons = hs;
-        hotseatIconSize = his;
-    }
-
-    DeviceProfile(Context context,
-                  ArrayList<DeviceProfile> profiles,
-                  float minWidth, float minHeight,
-                  int wPx, int hPx,
-                  int awPx, int ahPx,
-                  Resources resources) {
-        DisplayMetrics dm = resources.getDisplayMetrics();
-        ArrayList<DeviceProfileQuery> points =
-                new ArrayList<DeviceProfileQuery>();
-        transposeLayoutWithOrientation =
-                resources.getBoolean(R.bool.hotseat_transpose_layout_with_orientation);
-        minWidthDps = minWidth;
-        minHeightDps = minHeight;
-
-        ComponentName cn = new ComponentName(context.getPackageName(),
-                this.getClass().getName());
-        defaultWidgetPadding = AppWidgetHostView.getDefaultPaddingForWidget(context, cn, null);
-        edgeMarginPx = resources.getDimensionPixelSize(R.dimen.dynamic_grid_edge_margin);
-        desiredWorkspaceLeftRightMarginPx = 2 * edgeMarginPx;
-        pageIndicatorHeightPx = resources.getDimensionPixelSize(R.dimen.dynamic_grid_page_indicator_height);
-
-        // Interpolate the rows
-        for (DeviceProfile p : profiles) {
-            points.add(new DeviceProfileQuery(p.minWidthDps, p.minHeightDps, p.numRows));
-        }
-        numRows = Math.round(invDistWeightedInterpolate(minWidth, minHeight, points));
-        // Interpolate the columns
-        points.clear();
-        for (DeviceProfile p : profiles) {
-            points.add(new DeviceProfileQuery(p.minWidthDps, p.minHeightDps, p.numColumns));
-        }
-        numColumns = Math.round(invDistWeightedInterpolate(minWidth, minHeight, points));
-        // Interpolate the icon size
-        points.clear();
-        for (DeviceProfile p : profiles) {
-            points.add(new DeviceProfileQuery(p.minWidthDps, p.minHeightDps, p.iconSize));
-        }
-        iconSize = invDistWeightedInterpolate(minWidth, minHeight, points);
-        iconSizePx = DynamicGrid.pxFromDp(iconSize, dm);
-
-        // Interpolate the icon text size
-        points.clear();
-        for (DeviceProfile p : profiles) {
-            points.add(new DeviceProfileQuery(p.minWidthDps, p.minHeightDps, p.iconTextSize));
-        }
-        iconTextSize = invDistWeightedInterpolate(minWidth, minHeight, points);
-        iconTextSizePx = DynamicGrid.pxFromSp(iconTextSize, dm);
-
-        // Interpolate the hotseat size
-        points.clear();
-        for (DeviceProfile p : profiles) {
-            points.add(new DeviceProfileQuery(p.minWidthDps, p.minHeightDps, p.numHotseatIcons));
-        }
-        numHotseatIcons = Math.round(invDistWeightedInterpolate(minWidth, minHeight, points));
-        // Interpolate the hotseat icon size
-        points.clear();
-        for (DeviceProfile p : profiles) {
-            points.add(new DeviceProfileQuery(p.minWidthDps, p.minHeightDps, p.hotseatIconSize));
-        }
-        // Hotseat
-        hotseatIconSize = invDistWeightedInterpolate(minWidth, minHeight, points);
-        hotseatIconSizePx = DynamicGrid.pxFromDp(hotseatIconSize, dm);
-        hotseatAllAppsRank = (int) (numColumns / 2);
-
-        // Calculate other vars based on Configuration
-        updateFromConfiguration(resources, wPx, hPx, awPx, ahPx);
-
-        // Search Bar
-        searchBarSpaceMaxWidthPx = resources.getDimensionPixelSize(R.dimen.dynamic_grid_search_bar_max_width);
-        searchBarHeightPx = resources.getDimensionPixelSize(R.dimen.dynamic_grid_search_bar_height);
-        searchBarSpaceWidthPx = Math.min(searchBarSpaceMaxWidthPx, widthPx);
-        searchBarSpaceHeightPx = searchBarHeightPx + 2 * edgeMarginPx;
-
-        // Calculate the actual text height
-        Paint textPaint = new Paint();
-        textPaint.setTextSize(iconTextSizePx);
-        FontMetrics fm = textPaint.getFontMetrics();
-        cellWidthPx = iconSizePx;
-        cellHeightPx = iconSizePx + (int) Math.ceil(fm.bottom - fm.top);
-
-        // At this point, if the cells do not fit into the available height, then we need
-        // to shrink the icon size
-        /*
-        Rect padding = getWorkspacePadding(isLandscape ?
-                CellLayout.LANDSCAPE : CellLayout.PORTRAIT);
-        int h = (int) (numRows * cellHeightPx) + padding.top + padding.bottom;
-        if (h > availableHeightPx) {
-            float delta = h - availableHeightPx;
-            int deltaPx = (int) Math.ceil(delta / numRows);
-            iconSizePx -= deltaPx;
-            iconSize = DynamicGrid.dpiFromPx(iconSizePx, dm);
-            cellWidthPx = iconSizePx;
-            cellHeightPx = iconSizePx + (int) Math.ceil(fm.bottom - fm.top);
-        }
-        */
-
-        // Hotseat
-        hotseatBarHeightPx = iconSizePx + 4 * edgeMarginPx;
-        hotseatCellWidthPx = iconSizePx;
-        hotseatCellHeightPx = iconSizePx;
-
-        // Folder
-        folderCellWidthPx = cellWidthPx + 3 * edgeMarginPx;
-        folderCellHeightPx = cellHeightPx + (int) ((3f/2f) * edgeMarginPx);
-        folderBackgroundOffset = -edgeMarginPx;
-        folderIconSizePx = iconSizePx + 2 * -folderBackgroundOffset;
-    }
-
-    void updateFromConfiguration(Resources resources, int wPx, int hPx,
-                                 int awPx, int ahPx) {
-        isLandscape = (resources.getConfiguration().orientation ==
-                Configuration.ORIENTATION_LANDSCAPE);
-        isTablet = resources.getBoolean(R.bool.is_tablet);
-        isLargeTablet = resources.getBoolean(R.bool.is_large_tablet);
-        widthPx = wPx;
-        heightPx = hPx;
-        availableWidthPx = awPx;
-        availableHeightPx = ahPx;
-
-        Rect padding = getWorkspacePadding(isLandscape ?
-                CellLayout.LANDSCAPE : CellLayout.PORTRAIT);
-        int pageIndicatorOffset =
-            resources.getDimensionPixelSize(R.dimen.apps_customize_page_indicator_offset);
-        if (isLandscape) {
-            allAppsNumRows = (availableHeightPx - pageIndicatorOffset - 4 * edgeMarginPx) /
-                    (iconSizePx + iconTextSizePx + 2 * edgeMarginPx);
-        } else {
-            allAppsNumRows = (int) numRows + 1;
-        }
-        allAppsNumCols = (availableWidthPx - padding.left - padding.right - 2 * edgeMarginPx) /
-                (iconSizePx + 2 * edgeMarginPx);
-    }
-
-    private float dist(PointF p0, PointF p1) {
-        return (float) Math.sqrt((p1.x - p0.x)*(p1.x-p0.x) +
-                (p1.y-p0.y)*(p1.y-p0.y));
-    }
-
-    private float weight(PointF a, PointF b,
-                        float pow) {
-        float d = dist(a, b);
-        if (d == 0f) {
-            return Float.POSITIVE_INFINITY;
-        }
-        return (float) (1f / Math.pow(d, pow));
-    }
-
-    private float invDistWeightedInterpolate(float width, float height,
-                ArrayList<DeviceProfileQuery> points) {
-        float sum = 0;
-        float weights = 0;
-        float pow = 5;
-        float kNearestNeighbors = 3;
-        final PointF xy = new PointF(width, height);
-
-        ArrayList<DeviceProfileQuery> pointsByNearness = points;
-        Collections.sort(pointsByNearness, new Comparator<DeviceProfileQuery>() {
-            public int compare(DeviceProfileQuery a, DeviceProfileQuery b) {
-                return (int) (dist(xy, a.dimens) - dist(xy, b.dimens));
-            }
-        });
-
-        for (int i = 0; i < pointsByNearness.size(); ++i) {
-            DeviceProfileQuery p = pointsByNearness.get(i);
-            if (i < kNearestNeighbors) {
-                float w = weight(xy, p.dimens, pow);
-                if (w == Float.POSITIVE_INFINITY) {
-                    return p.value;
-                }
-                weights += w;
-            }
-        }
-
-        for (int i = 0; i < pointsByNearness.size(); ++i) {
-            DeviceProfileQuery p = pointsByNearness.get(i);
-            if (i < kNearestNeighbors) {
-                float w = weight(xy, p.dimens, pow);
-                sum += w * p.value / weights;
-            }
-        }
-
-        return sum;
-    }
-
-    Rect getWorkspacePadding(int orientation) {
-        Rect padding = new Rect();
-        if (orientation == CellLayout.LANDSCAPE &&
-                transposeLayoutWithOrientation) {
-            // Pad the left and right of the workspace with search/hotseat bar sizes
-            padding.set(searchBarSpaceHeightPx, edgeMarginPx,
-                    hotseatBarHeightPx, edgeMarginPx);
-        } else {
-            if (isTablet()) {
-                // Pad the left and right of the workspace to ensure consistent spacing
-                // between all icons
-                int width = (orientation == CellLayout.LANDSCAPE)
-                        ? Math.max(widthPx, heightPx)
-                        : Math.min(widthPx, heightPx);
-                // XXX: If the icon size changes across orientations, we will have to take
-                //      that into account here too.
-                int gap = (int) ((width - 2 * edgeMarginPx -
-                        (numColumns * cellWidthPx)) / (2 * (numColumns + 1)));
-                padding.set(edgeMarginPx + gap,
-                        searchBarSpaceHeightPx,
-                        edgeMarginPx + gap,
-                        hotseatBarHeightPx + pageIndicatorHeightPx);
-            } else {
-                // Pad the top and bottom of the workspace with search/hotseat bar sizes
-                padding.set(desiredWorkspaceLeftRightMarginPx - defaultWidgetPadding.left,
-                        searchBarSpaceHeightPx,
-                        desiredWorkspaceLeftRightMarginPx - defaultWidgetPadding.right,
-                        hotseatBarHeightPx + pageIndicatorHeightPx);
-            }
-        }
-        return padding;
-    }
-
-    // The rect returned will be extended to below the system ui that covers the workspace
-    Rect getHotseatRect() {
-        if (isVerticalBarLayout()) {
-            return new Rect(availableWidthPx - hotseatBarHeightPx, 0,
-                    Integer.MAX_VALUE, availableHeightPx);
-        } else {
-            return new Rect(0, availableHeightPx - hotseatBarHeightPx,
-                    availableWidthPx, Integer.MAX_VALUE);
-        }
-    }
-
-    int calculateCellWidth(int width, int countX) {
-        return width / countX;
-    }
-    int calculateCellHeight(int height, int countY) {
-        return height / countY;
-    }
-
-    boolean isPhone() {
-        return !isTablet && !isLargeTablet;
-    }
-    boolean isTablet() {
-        return isTablet;
-    }
-    boolean isLargeTablet() {
-        return isLargeTablet;
-    }
-
-    boolean isVerticalBarLayout() {
-        return isLandscape && transposeLayoutWithOrientation;
-    }
-
-    public void layout(Launcher launcher) {
-        FrameLayout.LayoutParams lp;
-        Resources res = launcher.getResources();
-        boolean hasVerticalBarLayout = isVerticalBarLayout();
-
-        // Layout the search bar space
-        View searchBar = launcher.getSearchBar();
-        lp = (FrameLayout.LayoutParams) searchBar.getLayoutParams();
-        if (hasVerticalBarLayout) {
-            // Vertical search bar
-            lp.gravity = Gravity.TOP | Gravity.LEFT;
-            lp.width = searchBarSpaceHeightPx;
-            lp.height = LayoutParams.MATCH_PARENT;
-            searchBar.setPadding(
-                    0, 2 * edgeMarginPx, 0,
-                    2 * edgeMarginPx);
-        } else {
-            // Horizontal search bar
-            lp.gravity = Gravity.TOP | Gravity.CENTER_HORIZONTAL;
-            lp.width = searchBarSpaceWidthPx;
-            lp.height = searchBarSpaceHeightPx;
-            searchBar.setPadding(
-                    2 * edgeMarginPx,
-                    2 * edgeMarginPx,
-                    2 * edgeMarginPx, 0);
-        }
-        searchBar.setLayoutParams(lp);
-
-        // Layout the search bar
-        View qsbBar = launcher.getQsbBar();
-        LayoutParams vglp = qsbBar.getLayoutParams();
-        vglp.width = LayoutParams.MATCH_PARENT;
-        vglp.height = LayoutParams.MATCH_PARENT;
-        qsbBar.setLayoutParams(vglp);
-
-        // Layout the voice proxy
-        View voiceButtonProxy = launcher.findViewById(R.id.voice_button_proxy);
-        if (voiceButtonProxy != null) {
-            if (hasVerticalBarLayout) {
-                // TODO: MOVE THIS INTO SEARCH BAR MEASURE
-            } else {
-                lp = (FrameLayout.LayoutParams) voiceButtonProxy.getLayoutParams();
-                lp.gravity = Gravity.TOP | Gravity.END;
-                lp.width = (widthPx - searchBarSpaceWidthPx) / 2 +
-                        2 * iconSizePx;
-                lp.height = searchBarSpaceHeightPx;
-            }
-        }
-
-        // Layout the workspace
-        View workspace = launcher.findViewById(R.id.workspace);
-        lp = (FrameLayout.LayoutParams) workspace.getLayoutParams();
-        lp.gravity = Gravity.CENTER;
-        Rect padding = getWorkspacePadding(isLandscape
-                ? CellLayout.LANDSCAPE
-                : CellLayout.PORTRAIT);
-        workspace.setPadding(padding.left, padding.top,
-                padding.right, padding.bottom);
-        workspace.setLayoutParams(lp);
-
-        // Layout the hotseat
-        View hotseat = launcher.findViewById(R.id.hotseat);
-        lp = (FrameLayout.LayoutParams) hotseat.getLayoutParams();
-        if (hasVerticalBarLayout) {
-            // Vertical hotseat
-            lp.gravity = Gravity.RIGHT;
-            lp.width = hotseatBarHeightPx;
-            lp.height = LayoutParams.MATCH_PARENT;
-            hotseat.setPadding(0, 2 * edgeMarginPx,
-                    2 * edgeMarginPx, 2 * edgeMarginPx);
-        } else if (isTablet()) {
-            // Pad the hotseat with the grid gap calculated above
-            int gridGap = (int) ((widthPx - 2 * edgeMarginPx -
-                    (numColumns * cellWidthPx)) / (2 * (numColumns + 1)));
-            int gridWidth = (int) ((numColumns * cellWidthPx) +
-                    ((numColumns - 1) * gridGap));
-            int hotseatGap = (int) Math.max(0,
-                    (gridWidth - (numHotseatIcons * hotseatCellWidthPx))
-                            / (numHotseatIcons - 1));
-            lp.gravity = Gravity.BOTTOM;
-            lp.width = LayoutParams.MATCH_PARENT;
-            lp.height = hotseatBarHeightPx;
-            hotseat.setPadding(2 * edgeMarginPx + gridGap + hotseatGap, 0,
-                    2 * edgeMarginPx + gridGap + hotseatGap,
-                    2 * edgeMarginPx);
-        } else {
-            // For phones, layout the hotseat without any bottom margin
-            // to ensure that we have space for the folders
-            lp.gravity = Gravity.BOTTOM;
-            lp.width = LayoutParams.MATCH_PARENT;
-            lp.height = hotseatBarHeightPx;
-            hotseat.findViewById(R.id.layout).setPadding(2 * edgeMarginPx, 0,
-                    2 * edgeMarginPx, 0);
-        }
-        hotseat.setLayoutParams(lp);
-
-        // Layout the page indicators
-        View pageIndicator = launcher.findViewById(R.id.page_indicator);
-        if (pageIndicator != null) {
-            if (hasVerticalBarLayout) {
-                // Hide the page indicators when we have vertical search/hotseat
-                pageIndicator.setVisibility(View.GONE);
-            } else {
-                // Put the page indicators above the hotseat
-                lp = (FrameLayout.LayoutParams) pageIndicator.getLayoutParams();
-                lp.gravity = Gravity.CENTER_HORIZONTAL | Gravity.BOTTOM;
-                lp.width = LayoutParams.WRAP_CONTENT;
-                lp.height = LayoutParams.WRAP_CONTENT;
-                lp.bottomMargin = hotseatBarHeightPx;
-                pageIndicator.setLayoutParams(lp);
-            }
-        }
-    }
-}
-
 public class DynamicGrid {
     @SuppressWarnings("unused")
     private static final String TAG = "DynamicGrid";
@@ -486,6 +32,10 @@
     private float mMinWidth;
     private float mMinHeight;
 
+    // This is a static that we use for the default icon size on a 4/5-inch phone
+    static float DEFAULT_ICON_SIZE_DP = 60;
+    static float DEFAULT_ICON_SIZE_PX = 0;
+
     public static float dpiFromPx(int size, DisplayMetrics metrics){
         float densityRatio = (float) metrics.densityDpi / DisplayMetrics.DENSITY_DEFAULT;
         return (size / densityRatio);
@@ -506,27 +56,32 @@
         DisplayMetrics dm = resources.getDisplayMetrics();
         ArrayList<DeviceProfile> deviceProfiles =
                 new ArrayList<DeviceProfile>();
-        boolean hasAA = !AppsCustomizePagedView.DISABLE_ALL_APPS;
+        boolean hasAA = !LauncherAppState.isDisableAllApps();
+        DEFAULT_ICON_SIZE_PX = pxFromDp(DEFAULT_ICON_SIZE_DP, dm);
         // Our phone profiles include the bar sizes in each orientation
         deviceProfiles.add(new DeviceProfile("Super Short Stubby",
-                255, 300,  2, 3,  48, 13, (hasAA ? 5 : 4), 48));
+                255, 300,  2, 3,  48, 13, (hasAA ? 5 : 5), 48));
         deviceProfiles.add(new DeviceProfile("Shorter Stubby",
-                255, 400,  3, 3,  48, 13, (hasAA ? 5 : 4), 48));
+                255, 400,  3, 3,  48, 13, (hasAA ? 5 : 5), 48));
         deviceProfiles.add(new DeviceProfile("Short Stubby",
-                275, 420,  3, 4,  48, 13, (hasAA ? 5 : 4), 48));
+                275, 420,  3, 4,  48, 13, (hasAA ? 5 : 5), 48));
         deviceProfiles.add(new DeviceProfile("Stubby",
-                255, 450,  3, 4,  48, 13, (hasAA ? 5 : 4), 48));
+                255, 450,  3, 4,  48, 13, (hasAA ? 5 : 5), 48));
         deviceProfiles.add(new DeviceProfile("Nexus S",
-                296, 491.33f,  4, 4,  48, 13, (hasAA ? 5 : 4), 48));
+                296, 491.33f,  4, 4,  48, 13, (hasAA ? 5 : 5), 48));
         deviceProfiles.add(new DeviceProfile("Nexus 4",
-                359, 518,  4, 4,  60, 13, (hasAA ? 5 : 4), 56));
+                335, 567,  4, 4,  DEFAULT_ICON_SIZE_DP, 13, (hasAA ? 5 : 5), 56));
+        deviceProfiles.add(new DeviceProfile("Nexus 5",
+                359, 567,  4, 4,  DEFAULT_ICON_SIZE_DP, 13, (hasAA ? 5 : 5), 56));
+        deviceProfiles.add(new DeviceProfile("Large Phone",
+                406, 694,  5, 5,  64, 14.4f,  5, 56));
         // The tablet profile is odd in that the landscape orientation
         // also includes the nav bar on the side
         deviceProfiles.add(new DeviceProfile("Nexus 7",
-                575, 904,  6, 6,  72, 14.4f,  7, 60));
+                575, 904,  5, 6,  72, 14.4f,  7, 60));
         // Larger tablet profiles always have system bars on the top & bottom
         deviceProfiles.add(new DeviceProfile("Nexus 10",
-                727, 1207,  5, 8,  80, 14.4f,  9, 64));
+                727, 1207,  5, 6,  76, 14.4f,  7, 64));
         /*
         deviceProfiles.add(new DeviceProfile("Nexus 7",
                 600, 960,  5, 5,  72, 14.4f,  5, 60));
@@ -544,7 +99,7 @@
                 resources);
     }
 
-    DeviceProfile getDeviceProfile() {
+    public DeviceProfile getDeviceProfile() {
         return mProfile;
     }
 
@@ -553,7 +108,7 @@
                 "Wd: " + mProfile.minWidthDps + ", Hd: " + mProfile.minHeightDps +
                 ", W: " + mProfile.widthPx + ", H: " + mProfile.heightPx +
                 " [r: " + mProfile.numRows + ", c: " + mProfile.numColumns +
-                ", is: " + mProfile.iconSizePx + ", its: " + mProfile.iconTextSize +
+                ", is: " + mProfile.iconSizePx + ", its: " + mProfile.iconTextSizePx +
                 ", cw: " + mProfile.cellWidthPx + ", ch: " + mProfile.cellHeightPx +
                 ", hc: " + mProfile.numHotseatIcons + ", his: " + mProfile.hotseatIconSizePx + "]";
     }
diff --git a/src/com/android/launcher3/FastBitmapDrawable.java b/src/com/android/launcher3/FastBitmapDrawable.java
index 14760c7..85e9020 100644
--- a/src/com/android/launcher3/FastBitmapDrawable.java
+++ b/src/com/android/launcher3/FastBitmapDrawable.java
@@ -27,19 +27,12 @@
 class FastBitmapDrawable extends Drawable {
     private Bitmap mBitmap;
     private int mAlpha;
-    private int mWidth;
-    private int mHeight;
     private final Paint mPaint = new Paint(Paint.FILTER_BITMAP_FLAG);
 
     FastBitmapDrawable(Bitmap b) {
-	mAlpha = 255;
+        mAlpha = 255;
         mBitmap = b;
-        if (b != null) {
-            mWidth = mBitmap.getWidth();
-            mHeight = mBitmap.getHeight();
-        } else {
-            mWidth = mHeight = 0;
-        }
+        setBounds(0, 0, b.getWidth(), b.getHeight());
     }
 
     @Override
@@ -67,6 +60,7 @@
 
     public void setFilterBitmap(boolean filterBitmap) {
         mPaint.setFilterBitmap(filterBitmap);
+        mPaint.setAntiAlias(filterBitmap);
     }
 
     public int getAlpha() {
@@ -75,32 +69,22 @@
 
     @Override
     public int getIntrinsicWidth() {
-        return mWidth;
+        return getBounds().width();
     }
 
     @Override
     public int getIntrinsicHeight() {
-        return mHeight;
+        return getBounds().height();
     }
 
     @Override
     public int getMinimumWidth() {
-        return mWidth;
+        return getBounds().width();
     }
 
     @Override
     public int getMinimumHeight() {
-        return mHeight;
-    }
-
-    public void setBitmap(Bitmap b) {
-        mBitmap = b;
-        if (b != null) {
-            mWidth = mBitmap.getWidth();
-            mHeight = mBitmap.getHeight();
-        } else {
-            mWidth = mHeight = 0;
-        }
+        return getBounds().height();
     }
 
     public Bitmap getBitmap() {
diff --git a/src/com/android/launcher3/FirstFrameAnimatorHelper.java b/src/com/android/launcher3/FirstFrameAnimatorHelper.java
index 78fdadd..f4c49d7 100644
--- a/src/com/android/launcher3/FirstFrameAnimatorHelper.java
+++ b/src/com/android/launcher3/FirstFrameAnimatorHelper.java
@@ -91,29 +91,30 @@
             mStartTime = currentTime;
         }
 
+        final long currentPlayTime = animation.getCurrentPlayTime();
         if (!mHandlingOnAnimationUpdate &&
             sVisible &&
             // If the current play time exceeds the duration, the animation
             // will get finished, even if we call setCurrentPlayTime -- therefore
             // don't adjust the animation in that case
-            animation.getCurrentPlayTime() < animation.getDuration()) {
+            currentPlayTime < animation.getDuration()) {
             mHandlingOnAnimationUpdate = true;
             long frameNum = sGlobalFrameCounter - mStartFrame;
             // If we haven't drawn our first frame, reset the time to t = 0
             // (give up after MAX_DELAY ms of waiting though - might happen, for example, if we
             // are no longer in the foreground and no frames are being rendered ever)
-            if (frameNum == 0 && currentTime < mStartTime + MAX_DELAY) {
+            if (frameNum == 0 && currentTime < mStartTime + MAX_DELAY && currentPlayTime > 0) {
                 // The first frame on animations doesn't always trigger an invalidate...
                 // force an invalidate here to make sure the animation continues to advance
                 mTarget.getRootView().invalidate();
                 animation.setCurrentPlayTime(0);
-
             // For the second frame, if the first frame took more than 16ms,
             // adjust the start time and pretend it took only 16ms anyway. This
             // prevents a large jump in the animation due to an expensive first frame
             } else if (frameNum == 1 && currentTime < mStartTime + MAX_DELAY &&
                        !mAdjustedSecondFrameTime &&
-                       currentTime > mStartTime + IDEAL_FRAME_DURATION) {
+                       currentTime > mStartTime + IDEAL_FRAME_DURATION &&
+                       currentPlayTime > IDEAL_FRAME_DURATION) {
                 animation.setCurrentPlayTime(IDEAL_FRAME_DURATION);
                 mAdjustedSecondFrameTime = true;
             } else {
diff --git a/src/com/android/launcher3/FocusHelper.java b/src/com/android/launcher3/FocusHelper.java
index 4600985..bb62bac 100644
--- a/src/com/android/launcher3/FocusHelper.java
+++ b/src/com/android/launcher3/FocusHelper.java
@@ -665,7 +665,7 @@
         final CellLayout layout = (CellLayout) parent.getParent();
         final Workspace workspace = (Workspace) layout.getParent();
         final ViewGroup launcher = (ViewGroup) workspace.getParent();
-        final ViewGroup tabs = (ViewGroup) launcher.findViewById(R.id.qsb_bar);
+        final ViewGroup tabs = (ViewGroup) launcher.findViewById(R.id.search_drop_target_bar);
         final ViewGroup hotseat = (ViewGroup) launcher.findViewById(R.id.hotseat);
         int pageIndex = workspace.indexOfChild(layout);
         int pageCount = workspace.getChildCount();
diff --git a/src/com/android/launcher3/Folder.java b/src/com/android/launcher3/Folder.java
index 69d9a3d..a9134e1 100644
--- a/src/com/android/launcher3/Folder.java
+++ b/src/com/android/launcher3/Folder.java
@@ -31,9 +31,7 @@
 import android.text.Selection;
 import android.text.Spannable;
 import android.util.AttributeSet;
-import android.util.DisplayMetrics;
 import android.util.Log;
-import android.util.TypedValue;
 import android.view.ActionMode;
 import android.view.KeyEvent;
 import android.view.LayoutInflater;
@@ -43,8 +41,6 @@
 import android.view.View;
 import android.view.accessibility.AccessibilityEvent;
 import android.view.accessibility.AccessibilityManager;
-import android.view.animation.AccelerateInterpolator;
-import android.view.animation.Interpolator;
 import android.view.inputmethod.EditorInfo;
 import android.view.inputmethod.InputMethodManager;
 import android.widget.LinearLayout;
@@ -82,7 +78,7 @@
     private int mState = STATE_NONE;
     private static final int REORDER_ANIMATION_DURATION = 230;
     private static final int REORDER_DELAY = 250;
-    private static final int ON_EXIT_CLOSE_DELAY = 800;
+    private static final int ON_EXIT_CLOSE_DELAY = 400;
     private boolean mRearrangeOnClose = false;
     private FolderIcon mFolderIcon;
     private int mMaxCountX;
@@ -119,6 +115,11 @@
     private int DRAG_MODE_REORDER = 1;
     private int mDragMode = DRAG_MODE_NONE;
 
+    // We avoid measuring the scroll view with a 0 width or height, as this
+    // results in CellLayout being measured as UNSPECIFIED, which it does
+    // not support.
+    private static final int MIN_CONTENT_DIMEN = 5;
+
     private boolean mDestroyed;
 
     private AutoScrollHelper mAutoScrollHelper;
@@ -144,8 +145,13 @@
 
         Resources res = getResources();
         mMaxCountX = (int) grid.numColumns;
-        mMaxCountY = (int) grid.numRows;
-        mMaxNumItems = mMaxCountX * mMaxCountY;
+        // Allow scrolling folders when DISABLE_ALL_APPS is true.
+        if (LauncherAppState.isDisableAllApps()) {
+            mMaxCountY = mMaxNumItems = Integer.MAX_VALUE;
+        } else {
+            mMaxCountY = (int) grid.numRows;
+            mMaxNumItems = mMaxCountX * mMaxCountY;
+        }
 
         mInputMethodManager = (InputMethodManager)
                 getContext().getSystemService(Context.INPUT_METHOD_SERVICE);
@@ -232,7 +238,7 @@
                 return false;
             }
 
-            mLauncher.dismissFolderCling(null);
+            mLauncher.getLauncherClings().dismissFolderCling(null);
 
             mLauncher.getWorkspace().onDragStartedWithItem(v);
             mLauncher.getWorkspace().beginDragShared(v, this);
@@ -403,6 +409,15 @@
             mFolderName.setText("");
         }
         updateItemLocationsInDatabase();
+
+        // In case any children didn't come across during loading, clean up the folder accordingly
+        mFolderIcon.post(new Runnable() {
+            public void run() {
+                if (getItemCount() <= 1) {
+                    replaceFolderWithFinalItem();
+                }
+            }
+        });
     }
 
     /**
@@ -451,7 +466,7 @@
             public void onAnimationEnd(Animator animation) {
                 mState = STATE_OPEN;
                 setLayerType(LAYER_TYPE_NONE, null);
-                Cling cling = mLauncher.showFirstRunFoldersCling();
+                Cling cling = mLauncher.getLauncherClings().showFoldersCling();
                 if (cling != null) {
                     cling.bringScrimToFront();
                     bringToFront();
@@ -538,6 +553,7 @@
         textView.setTag(item);
         textView.setTextColor(getResources().getColor(R.color.folder_items_text_color));
         textView.setShadowsEnabled(false);
+        textView.setGlowColor(getResources().getColor(R.color.folder_items_glow_color));
 
         textView.setOnClickListener(this);
         textView.setOnLongClickListener(this);
@@ -759,6 +775,12 @@
             }
         }
 
+        // This is kind of hacky, but in general, dropping on the workspace handles removing
+        // the extra screen, but dropping elsewhere (back to self, or onto delete) doesn't.
+        if (target != mLauncher.getWorkspace()) {
+            mLauncher.getWorkspace().removeExtraEmptyScreen(true, null);
+        }
+
         mDeleteFolderOnDropCompleted = false;
         mDragInProgress = false;
         mItemAddedBackToSelfViaIcon = false;
@@ -784,10 +806,25 @@
     }
 
     @Override
+    public float getIntrinsicIconScaleFactor() {
+        return 1f;
+    }
+
+    @Override
     public boolean supportsFlingToDelete() {
         return true;
     }
 
+    @Override
+    public boolean supportsAppInfoDropTarget() {
+        return false;
+    }
+
+    @Override
+    public boolean supportsDeleteDropTarget() {
+        return true;
+    }
+
     public void onFlingToDelete(DragObject d, int x, int y, PointF vec) {
         // Do nothing
     }
@@ -803,7 +840,7 @@
             View v = list.get(i);
             ItemInfo info = (ItemInfo) v.getTag();
             LauncherModel.moveItemInDatabase(mLauncher, info, mInfo.id, 0,
-                        info.cellX, info.cellY);
+                    info.cellX, info.cellY);
         }
     }
 
@@ -956,12 +993,15 @@
         Rect workspacePadding = grid.getWorkspacePadding(grid.isLandscape ?
                 CellLayout.LANDSCAPE : CellLayout.PORTRAIT);
         int maxContentAreaHeight = grid.availableHeightPx -
-                4 * grid.edgeMarginPx -
                 workspacePadding.top - workspacePadding.bottom -
-                getPaddingTop() - getPaddingBottom() -
                 mFolderNameHeight;
-        return Math.min(maxContentAreaHeight,
+        int height = Math.min(maxContentAreaHeight,
                 mContent.getDesiredHeight());
+        return Math.max(height, MIN_CONTENT_DIMEN);
+    }
+
+    private int getContentAreaWidth() {
+        return Math.max(mContent.getDesiredWidth(), MIN_CONTENT_DIMEN);
     }
 
     private int getFolderHeight() {
@@ -973,11 +1013,18 @@
     protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
         int width = getPaddingLeft() + getPaddingRight() + mContent.getDesiredWidth();
         int height = getFolderHeight();
-        int contentAreaWidthSpec = MeasureSpec.makeMeasureSpec(mContent.getDesiredWidth(),
+        int contentAreaWidthSpec = MeasureSpec.makeMeasureSpec(getContentAreaWidth(),
                 MeasureSpec.EXACTLY);
         int contentAreaHeightSpec = MeasureSpec.makeMeasureSpec(getContentAreaHeight(),
                 MeasureSpec.EXACTLY);
-        mContent.setFixedSize(mContent.getDesiredWidth(), mContent.getDesiredHeight());
+
+        if (LauncherAppState.isDisableAllApps()) {
+            // Don't cap the height of the content to allow scrolling.
+            mContent.setFixedSize(getContentAreaWidth(), mContent.getDesiredHeight());
+        } else {
+            mContent.setFixedSize(getContentAreaWidth(), getContentAreaHeight());
+        }
+
         mScrollView.measure(contentAreaWidthSpec, contentAreaHeightSpec);
         mFolderName.measure(contentAreaWidthSpec,
                 MeasureSpec.makeMeasureSpec(mFolderNameHeight, MeasureSpec.EXACTLY));
@@ -1048,7 +1095,7 @@
             public void run() {
                 CellLayout cellLayout = mLauncher.getCellLayout(mInfo.container, mInfo.screenId);
 
-               View child = null;
+                View child = null;
                 // Move the item from the folder to the workspace, in the position of the folder
                 if (getItemCount() == 1) {
                     ShortcutInfo finalItem = mInfo.contents.get(0);
@@ -1060,7 +1107,10 @@
                 if (getItemCount() <= 1) {
                     // Remove the folder
                     LauncherModel.deleteItemFromDatabase(mLauncher, mInfo);
-                    cellLayout.removeView(mFolderIcon);
+                    if (cellLayout != null) {
+                        // b/12446428 -- sometimes the cell layout has already gone away?
+                        cellLayout.removeView(mFolderIcon);
+                    }
                     if (mFolderIcon instanceof DropTarget) {
                         mDragController.removeDropTarget((DropTarget) mFolderIcon);
                     }
@@ -1078,6 +1128,8 @@
         View finalChild = getItemAt(0);
         if (finalChild != null) {
             mFolderIcon.performDestroyAnimation(finalChild, onCompleteRunnable);
+        } else {
+            onCompleteRunnable.run();
         }
         mDestroyed = true;
     }
diff --git a/src/com/android/launcher3/FolderIcon.java b/src/com/android/launcher3/FolderIcon.java
index cd1ff2c..644db47 100644
--- a/src/com/android/launcher3/FolderIcon.java
+++ b/src/com/android/launcher3/FolderIcon.java
@@ -36,11 +36,10 @@
 import android.view.ViewGroup;
 import android.view.animation.AccelerateInterpolator;
 import android.view.animation.DecelerateInterpolator;
+import android.widget.FrameLayout;
 import android.widget.ImageView;
-import android.widget.LinearLayout;
 import android.widget.TextView;
 
-import com.android.launcher3.R;
 import com.android.launcher3.DropTarget.DragObject;
 import com.android.launcher3.FolderInfo.FolderListener;
 
@@ -49,7 +48,7 @@
 /**
  * An icon that can appear on in the workspace representing an {@link UserFolder}.
  */
-public class FolderIcon extends LinearLayout implements FolderListener {
+public class FolderIcon extends FrameLayout implements FolderListener {
     private Launcher mLauncher;
     private Folder mFolder;
     private FolderInfo mInfo;
@@ -134,17 +133,20 @@
                     "INITIAL_ITEM_ANIMATION_DURATION, as sequencing of adding first two items " +
                     "is dependent on this");
         }
+        LauncherAppState app = LauncherAppState.getInstance();
+        DeviceProfile grid = app.getDynamicGrid().getDeviceProfile();
 
         FolderIcon icon = (FolderIcon) LayoutInflater.from(launcher).inflate(resId, group, false);
         icon.setClipToPadding(false);
         icon.mFolderName = (BubbleTextView) icon.findViewById(R.id.folder_icon_name);
         icon.mFolderName.setText(folderInfo.title);
-        icon.mPreviewBackground = (ImageView) icon.findViewById(R.id.preview_background);
-        LauncherAppState app = LauncherAppState.getInstance();
-        DeviceProfile grid = app.getDynamicGrid().getDeviceProfile();
+        icon.mFolderName.setCompoundDrawablePadding(0);
+        FrameLayout.LayoutParams lp = (FrameLayout.LayoutParams) icon.mFolderName.getLayoutParams();
+        lp.topMargin = grid.iconSizePx + grid.iconDrawablePaddingPx;
+
         // Offset the preview background to center this view accordingly
-        LinearLayout.LayoutParams lp =
-                (LinearLayout.LayoutParams) icon.mPreviewBackground.getLayoutParams();
+        icon.mPreviewBackground = (ImageView) icon.findViewById(R.id.preview_background);
+        lp = (FrameLayout.LayoutParams) icon.mPreviewBackground.getLayoutParams();
         lp.topMargin = grid.folderBackgroundOffset;
         lp.width = grid.folderIconSizePx;
         lp.height = grid.folderIconSizePx;
@@ -537,12 +539,10 @@
         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),
                     PorterDuff.Mode.SRC_ATOP);
             d.draw(canvas);
             d.clearColorFilter();
-            d.setFilterBitmap(false);
             d.setBounds(mOldBounds);
         }
         canvas.restore();
diff --git a/src/com/android/launcher3/FolderInfo.java b/src/com/android/launcher3/FolderInfo.java
index bb5ae82..d45e4e4 100644
--- a/src/com/android/launcher3/FolderInfo.java
+++ b/src/com/android/launcher3/FolderInfo.java
@@ -16,10 +16,10 @@
 
 package com.android.launcher3;
 
-import java.util.ArrayList;
-
 import android.content.ContentValues;
 
+import java.util.ArrayList;
+
 /**
  * Represents a folder containing shortcuts or apps.
  */
diff --git a/src/com/android/launcher3/Hotseat.java b/src/com/android/launcher3/Hotseat.java
index 094e188..59d60e3 100644
--- a/src/com/android/launcher3/Hotseat.java
+++ b/src/com/android/launcher3/Hotseat.java
@@ -95,7 +95,7 @@
         return hasVerticalHotseat() ? (mContent.getCountY() - (rank + 1)) : 0;
     }
     public boolean isAllAppsButtonRank(int rank) {
-        if (AppsCustomizePagedView.DISABLE_ALL_APPS) {
+        if (LauncherAppState.isDisableAllApps()) {
             return false;
         } else {
             return rank == mAllAppsButtonRank;
@@ -142,7 +142,7 @@
     void resetLayout() {
         mContent.removeAllViewsInLayout();
 
-        if (!AppsCustomizePagedView.DISABLE_ALL_APPS) {
+        if (!LauncherAppState.isDisableAllApps()) {
             // Add the Apps button
             Context context = getContext();
 
@@ -189,7 +189,7 @@
     void addAllAppsFolder(IconCache iconCache,
             ArrayList<AppInfo> allApps, ArrayList<ComponentName> onWorkspace,
             Launcher launcher, Workspace workspace) {
-        if (AppsCustomizePagedView.DISABLE_ALL_APPS) {
+        if (LauncherAppState.isDisableAllApps()) {
             FolderInfo fi = new FolderInfo();
 
             fi.cellX = getCellXFromOrder(mAllAppsButtonRank);
@@ -219,7 +219,7 @@
     }
 
     void addAppsToAllAppsFolder(ArrayList<AppInfo> apps) {
-        if (AppsCustomizePagedView.DISABLE_ALL_APPS) {
+        if (LauncherAppState.isDisableAllApps()) {
             View v = mContent.getChildAt(getCellXFromOrder(mAllAppsButtonRank), getCellYFromOrder(mAllAppsButtonRank));
             FolderIcon fi = null;
 
diff --git a/src/com/android/launcher3/IconCache.java b/src/com/android/launcher3/IconCache.java
index 543b8ee..a55fce0 100644
--- a/src/com/android/launcher3/IconCache.java
+++ b/src/com/android/launcher3/IconCache.java
@@ -156,7 +156,7 @@
             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) {
+                if (e.icon.getWidth() < grid.iconSizePx || e.icon.getHeight() < grid.iconSizePx) {
                     it.remove();
                 }
             }
diff --git a/src/com/android/launcher3/InfoDropTarget.java b/src/com/android/launcher3/InfoDropTarget.java
index 2ad43b6..374238c 100644
--- a/src/com/android/launcher3/InfoDropTarget.java
+++ b/src/com/android/launcher3/InfoDropTarget.java
@@ -62,10 +62,6 @@
         }
     }
 
-    private boolean isFromAllApps(DragSource source) {
-        return (source instanceof AppsCustomizePagedView);
-    }
-
     @Override
     public boolean acceptDrop(DragObject d) {
         // acceptDrop is called just before onDrop. We do the work here, rather than
@@ -93,7 +89,7 @@
         boolean isVisible = true;
 
         // Hide this button unless we are dragging something from AllApps
-        if (!isFromAllApps(source)) {
+        if (!source.supportsAppInfoDropTarget()) {
             isVisible = false;
         }
 
diff --git a/src/com/android/launcher3/InstallShortcutReceiver.java b/src/com/android/launcher3/InstallShortcutReceiver.java
index 7df73b1..7ab4e04 100644
--- a/src/com/android/launcher3/InstallShortcutReceiver.java
+++ b/src/com/android/launcher3/InstallShortcutReceiver.java
@@ -24,17 +24,20 @@
 import android.content.pm.PackageManager;
 import android.graphics.Bitmap;
 import android.graphics.BitmapFactory;
+import android.text.TextUtils;
 import android.util.Base64;
 import android.util.Log;
 import android.widget.Toast;
 
+import org.json.JSONObject;
+import org.json.JSONStringer;
+import org.json.JSONTokener;
+
 import java.util.ArrayList;
 import java.util.HashSet;
 import java.util.Iterator;
 import java.util.Set;
 
-import org.json.*;
-
 public class InstallShortcutReceiver extends BroadcastReceiver {
     private static final String TAG = "InstallShortcutReceiver";
     private static final boolean DBG = false;
@@ -108,6 +111,9 @@
 
     public static void removeFromInstallQueue(SharedPreferences sharedPrefs,
                                               ArrayList<String> packageNames) {
+        if (packageNames.isEmpty()) {
+            return;
+        }
         synchronized(sLock) {
             Set<String> strings = sharedPrefs.getStringSet(APPS_PENDING_INSTALL, null);
             if (DBG) {
@@ -218,18 +224,11 @@
         if (intent == null) {
             return;
         }
+
         // This name is only used for comparisons and notifications, so fall back to activity name
         // if not supplied
-        String name = data.getStringExtra(Intent.EXTRA_SHORTCUT_NAME);
-        if (name == null) {
-            try {
-                PackageManager pm = context.getPackageManager();
-                ActivityInfo info = pm.getActivityInfo(intent.getComponent(), 0);
-                name = info.loadLabel(pm).toString();
-            } catch (PackageManager.NameNotFoundException nnfe) {
-                return;
-            }
-        }
+        String name = ensureValidName(context, intent,
+                data.getStringExtra(Intent.EXTRA_SHORTCUT_NAME)).toString();
         Bitmap icon = data.getParcelableExtra(Intent.EXTRA_SHORTCUT_ICON);
         Intent.ShortcutIconResource iconResource =
             data.getParcelableExtra(Intent.EXTRA_SHORTCUT_ICON_RESOURCE);
@@ -272,6 +271,12 @@
                 //final Intent data = pendingInfo.data;
                 final Intent intent = pendingInfo.launchIntent;
                 final String name = pendingInfo.name;
+
+                if (LauncherAppState.isDisableAllApps() && !isValidShortcutLaunchIntent(intent)) {
+                    if (DBG) Log.d(TAG, "Ignoring shortcut with launchIntent:" + intent);
+                    continue;
+                }
+
                 final boolean exists = LauncherModel.shortcutExists(context, name, intent);
                 //final boolean allowDuplicate = data.getBooleanExtra(Launcher.EXTRA_SHORTCUT_DUPLICATE, true);
 
@@ -299,11 +304,35 @@
             // Add the new apps to the model and bind them
             if (!addShortcuts.isEmpty()) {
                 LauncherAppState app = LauncherAppState.getInstance();
-                app.getModel().addAndBindAddedApps(context, addShortcuts, null);
+                app.getModel().addAndBindAddedApps(context, addShortcuts, new ArrayList<AppInfo>());
             }
         }
     }
 
+    /**
+     * Returns true if the intent is a valid launch intent for a shortcut.
+     * This is used to identify shortcuts which are different from the ones exposed by the
+     * applications' manifest file.
+     *
+     * When DISABLE_ALL_APPS is true, shortcuts exposed via the app's manifest should never be
+     * duplicated or removed(unless the app is un-installed).
+     *
+     * @param launchIntent The intent that will be launched when the shortcut is clicked.
+     */
+    static boolean isValidShortcutLaunchIntent(Intent launchIntent) {
+        if (launchIntent != null
+                && Intent.ACTION_MAIN.equals(launchIntent.getAction())
+                && launchIntent.getComponent() != null
+                && launchIntent.getCategories() != null
+                && launchIntent.getCategories().size() == 1
+                && launchIntent.hasCategory(Intent.CATEGORY_LAUNCHER)
+                && launchIntent.getExtras() == null
+                && TextUtils.isEmpty(launchIntent.getDataString())) {
+            return false;
+        }
+        return true;
+    }
+
     private static ShortcutInfo getShortcutInfo(Context context, Intent data,
                                                 Intent launchIntent) {
         if (launchIntent.getAction() == null) {
@@ -315,6 +344,25 @@
                     Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_RESET_TASK_IF_NEEDED);
         }
         LauncherAppState app = LauncherAppState.getInstance();
-        return app.getModel().infoFromShortcutIntent(context, data, null);
+        ShortcutInfo info = app.getModel().infoFromShortcutIntent(context, data, null);
+        info.title = ensureValidName(context, launchIntent, info.title);
+        return info;
+    }
+
+    /**
+     * Ensures that we have a valid, non-null name.  If the provided name is null, we will return
+     * the application name instead.
+     */
+    private static CharSequence ensureValidName(Context context, Intent intent, CharSequence name) {
+        if (name == null) {
+            try {
+                PackageManager pm = context.getPackageManager();
+                ActivityInfo info = pm.getActivityInfo(intent.getComponent(), 0);
+                name = info.loadLabel(pm).toString();
+            } catch (PackageManager.NameNotFoundException nnfe) {
+                return "";
+            }
+        }
+        return name;
     }
 }
diff --git a/src/com/android/launcher3/InstallWidgetReceiver.java b/src/com/android/launcher3/InstallWidgetReceiver.java
index 0ef4780..74b9e3d 100644
--- a/src/com/android/launcher3/InstallWidgetReceiver.java
+++ b/src/com/android/launcher3/InstallWidgetReceiver.java
@@ -16,8 +16,6 @@
 
 package com.android.launcher3;
 
-import java.util.List;
-
 import android.appwidget.AppWidgetProviderInfo;
 import android.content.ClipData;
 import android.content.Context;
@@ -33,7 +31,7 @@
 import android.widget.ListAdapter;
 import android.widget.TextView;
 
-import com.android.launcher3.R;
+import java.util.List;
 
 
 /**
diff --git a/src/com/android/launcher3/ItemInfo.java b/src/com/android/launcher3/ItemInfo.java
index 8c4cefd..36ba6c1 100644
--- a/src/com/android/launcher3/ItemInfo.java
+++ b/src/com/android/launcher3/ItemInfo.java
@@ -27,7 +27,7 @@
 /**
  * Represents an item in the launcher.
  */
-class ItemInfo {
+public class ItemInfo {
     
     static final int NO_ID = -1;
     
diff --git a/src/com/android/launcher3/Launcher.java b/src/com/android/launcher3/Launcher.java
index b0e4968..50bbe51 100644
--- a/src/com/android/launcher3/Launcher.java
+++ b/src/com/android/launcher3/Launcher.java
@@ -17,8 +17,6 @@
 
 package com.android.launcher3;
 
-import android.accounts.Account;
-import android.accounts.AccountManager;
 import android.animation.Animator;
 import android.animation.AnimatorListenerAdapter;
 import android.animation.AnimatorSet;
@@ -43,6 +41,7 @@
 import android.content.IntentFilter;
 import android.content.SharedPreferences;
 import android.content.pm.ActivityInfo;
+import android.content.pm.ApplicationInfo;
 import android.content.pm.PackageManager;
 import android.content.pm.PackageManager.NameNotFoundException;
 import android.content.pm.ResolveInfo;
@@ -87,7 +86,6 @@
 import android.view.ViewTreeObserver.OnGlobalLayoutListener;
 import android.view.WindowManager;
 import android.view.accessibility.AccessibilityEvent;
-import android.view.accessibility.AccessibilityManager;
 import android.view.animation.AccelerateDecelerateInterpolator;
 import android.view.animation.DecelerateInterpolator;
 import android.view.inputmethod.InputMethodManager;
@@ -113,6 +111,8 @@
 import java.util.Date;
 import java.util.HashMap;
 import java.util.List;
+import java.util.concurrent.atomic.AtomicInteger;
+
 
 /**
  * Default launcher application.
@@ -129,6 +129,8 @@
     static final boolean DEBUG_RESUME_TIME = false;
     static final boolean DEBUG_DUMP_LOG = false;
 
+    static final boolean ENABLE_DEBUG_INTENTS = false; // allow DebugIntents to run
+
     private static final int REQUEST_CREATE_SHORTCUT = 1;
     private static final int REQUEST_CREATE_APPWIDGET = 5;
     private static final int REQUEST_PICK_APPLICATION = 6;
@@ -154,6 +156,7 @@
     // adb shell setprop log.tag.PROPERTY_NAME [VERBOSE | SUPPRESS]
     static final String FORCE_ENABLE_ROTATION_PROPERTY = "launcher_force_rotate";
     static final String DUMP_STATE_PROPERTY = "launcher_dump_state";
+    static final String DISABLE_ALL_APPS_PROPERTY = "launcher_noallapps";
 
     // The Intent extra that defines whether to ignore the launch animation
     static final String INTENT_EXTRA_IGNORE_LAUNCH_ANIMATION =
@@ -181,6 +184,13 @@
     private static final String RUNTIME_STATE_PENDING_ADD_SPAN_Y = "launcher.add_span_y";
     // Type: parcelable
     private static final String RUNTIME_STATE_PENDING_ADD_WIDGET_INFO = "launcher.add_widget_info";
+    // Type: parcelable
+    private static final String RUNTIME_STATE_PENDING_ADD_WIDGET_ID = "launcher.add_widget_id";
+    // Type: int[]
+    private static final String RUNTIME_STATE_VIEW_IDS = "launcher.view_ids";
+
+
+    static final String FIRST_RUN_ACTIVITY_DISPLAYED = "launcher.first_run_activity_displayed";
 
     private static final String TOOLBAR_ICON_METADATA_NAME = "com.android.launcher.toolbar_icon";
     private static final String TOOLBAR_SEARCH_ICON_METADATA_NAME =
@@ -191,20 +201,23 @@
     public static final String SHOW_WEIGHT_WATCHER = "debug.show_mem";
     public static final boolean SHOW_WEIGHT_WATCHER_DEFAULT = false;
 
+    public static final String USER_HAS_MIGRATED = "launcher.user_migrated_from_old_data";
+
     /** The different states that Launcher can be in. */
     private enum State { NONE, WORKSPACE, APPS_CUSTOMIZE, APPS_CUSTOMIZE_SPRING_LOADED };
     private State mState = State.WORKSPACE;
     private AnimatorSet mStateAnimation;
 
     static final int APPWIDGET_HOST_ID = 1024;
-    private static final int EXIT_SPRINGLOADED_MODE_SHORT_TIMEOUT = 300;
-    private static final int EXIT_SPRINGLOADED_MODE_LONG_TIMEOUT = 600;
-    private static final int SHOW_CLING_DURATION = 250;
-    private static final int DISMISS_CLING_DURATION = 200;
+    public static final int EXIT_SPRINGLOADED_MODE_SHORT_TIMEOUT = 300;
+    private static final int ON_ACTIVITY_RESULT_ANIMATION_DELAY = 500;
 
     private static final Object sLock = new Object();
     private static int sScreen = DEFAULT_SCREEN;
 
+    private HashMap<Integer, Integer> mItemIdToViewId = new HashMap<Integer, Integer>();
+    private static final AtomicInteger sNextGeneratedId = new AtomicInteger(1);
+
     // How long to wait before the new-shortcut animation automatically pans the workspace
     private static int NEW_APPS_PAGE_MOVE_DELAY = 500;
     private static int NEW_APPS_ANIMATION_INACTIVE_TIMEOUT_SECONDS = 5;
@@ -218,22 +231,25 @@
 
     private Workspace mWorkspace;
     private View mLauncherView;
+    private View mPageIndicators;
     private DragLayer mDragLayer;
     private DragController mDragController;
     private View mWeightWatcher;
+    private LauncherClings mLauncherClings;
 
     private AppWidgetManager mAppWidgetManager;
     private LauncherAppWidgetHost mAppWidgetHost;
 
     private ItemInfo mPendingAddInfo = new ItemInfo();
     private AppWidgetProviderInfo mPendingAddWidgetInfo;
+    private int mPendingAddWidgetId = -1;
 
     private int[] mTmpAddItemCellCoordinates = new int[2];
 
     private FolderInfo mFolderInfo;
 
     private Hotseat mHotseat;
-    private View mOverviewPanel;
+    private ViewGroup mOverviewPanel;
 
     private View mAllAppsButton;
 
@@ -241,7 +257,7 @@
     private AppsCustomizeTabHost mAppsCustomizeTabHost;
     private AppsCustomizePagedView mAppsCustomizeContent;
     private boolean mAutoAdvanceRunning = false;
-    private View mQsbBar;
+    private View mQsb;
 
     private Bundle mSavedState;
     // We set the state in both onCreate and then onNewIntent in some cases, which causes both
@@ -272,8 +288,6 @@
     private boolean mVisible = false;
     private boolean mHasFocus = false;
     private boolean mAttached = false;
-    private static final boolean DISABLE_CLINGS = false;
-    private static final boolean DISABLE_CUSTOM_CLINGS = true;
 
     private static LocaleConfiguration sLocaleConfiguration = null;
 
@@ -305,6 +319,7 @@
     private Drawable mWorkspaceBackgroundDrawable;
 
     private final ArrayList<Integer> mSynchronouslyBoundPages = new ArrayList<Integer>();
+    private static final boolean DISABLE_SYNCHRONOUS_BINDING_CURRENT_PAGE = false;
 
     static final ArrayList<String> sDumpLogs = new ArrayList<String>();
     static Date sDateStamp = new Date();
@@ -328,9 +343,6 @@
 
     private BubbleTextView mWaitingForResume;
 
-    private HideFromAccessibilityHelper mHideFromAccessibilityHelper
-        = new HideFromAccessibilityHelper();
-
     private Runnable mBuildLayersRunnable = new Runnable() {
         public void run() {
             if (mWorkspace != null) {
@@ -355,7 +367,7 @@
 
     private Stats mStats;
 
-    private static boolean isPropertyEnabled(String propertyName) {
+    static boolean isPropertyEnabled(String propertyName) {
         return Log.isLoggable(propertyName, Log.VERBOSE);
     }
 
@@ -390,6 +402,7 @@
         display.getRealSize(realSize);
         DisplayMetrics dm = new DisplayMetrics();
         display.getMetrics(dm);
+
         // Lazy-initialize the dynamic grid
         DeviceProfile grid = app.initDynamicGrid(this,
                 Math.min(smallestSize.x, smallestSize.y),
@@ -404,6 +417,7 @@
         mIconCache = app.getIconCache();
         mIconCache.flushInvalidIcons(grid);
         mDragController = new DragController(this);
+        mLauncherClings = new LauncherClings(this);
         mInflater = getLayoutInflater();
 
         mStats = new Stats(this);
@@ -437,25 +451,19 @@
         mSavedState = savedInstanceState;
         restoreState(mSavedState);
 
-        // Update customization drawer _after_ restoring the states
-        if (mAppsCustomizeContent != null) {
-            mAppsCustomizeContent.onPackagesUpdated(
-                LauncherModel.getSortedWidgetsAndShortcuts(this));
-        }
-
         if (PROFILE_STARTUP) {
             android.os.Debug.stopMethodTracing();
         }
 
         if (!mRestoring) {
-            if (sPausedFromUserAction) {
+            if (DISABLE_SYNCHRONOUS_BINDING_CURRENT_PAGE || sPausedFromUserAction) {
                 // If the user leaves launcher, then we should just load items asynchronously when
                 // they return.
-                mModel.startLoader(true, -1);
+                mModel.startLoader(true, PagedView.INVALID_RESTORE_PAGE);
             } else {
                 // We only load the page synchronously if the user rotates (or triggers a
                 // configuration change) while launcher is in the foreground
-                mModel.startLoader(true, mWorkspace.getCurrentPage());
+                mModel.startLoader(true, mWorkspace.getRestorePage());
             }
         }
 
@@ -471,7 +479,19 @@
         // On large interfaces, we want the screen to auto-rotate based on the current orientation
         unlockScreenOrientation(true);
 
-        showFirstRunCling();
+        // The two first run cling paths are mutually exclusive, if the launcher is preinstalled
+        // on the device, then we always show the first run cling experience (or if there is no
+        // launcher2). Otherwise, we prompt the user upon started for migration
+        showFirstRunActivity();
+        if (mLauncherClings.shouldShowFirstRunOrMigrationClings()) {
+            if (mModel.canMigrateFromOldLauncherDb(this)) {
+                mLauncherClings.showMigrationCling();
+            } else {
+                mLauncherClings.showFirstRunCling();
+            }
+        } else {
+            mLauncherClings.removeFirstRunAndMigrationClings();
+        }
     }
 
     protected void onUserLeaveHint() {
@@ -493,6 +513,21 @@
     }
 
     /**
+     * To be overridden by subclasses to indicate that there is an activity to launch
+     * before showing the standard launcher experience.
+     */
+    protected boolean hasFirstRunActivity() {
+        return false;
+    }
+
+    /**
+     * To be overridden by subclasses to launch any first run activity
+     */
+    protected Intent getFirstRunActivity() {
+        return null;
+    }
+
+    /**
      * Invoked by subclasses to signal a change to the {@link #addCustomContentToLeft} value to
      * ensure the custom content page is added or removed if necessary.
      */
@@ -580,12 +615,12 @@
             mIconCache.flush();
 
             final LocaleConfiguration localeConfiguration = sLocaleConfiguration;
-            new Thread("WriteLocaleConfiguration") {
-                @Override
-                public void run() {
+            new AsyncTask<Void, Void, Void>() {
+                public Void doInBackground(Void ... args) {
                     writeConfiguration(Launcher.this, localeConfiguration);
+                    return null;
                 }
-            }.start();
+            }.executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR, (Void) null);
         }
     }
 
@@ -649,10 +684,6 @@
         return mInflater;
     }
 
-    public DragLayer getDragLayer() {
-        return mDragLayer;
-    }
-
     boolean isDraggingEnabled() {
         // We prevent dragging when we are loading the workspace as it is possible to pick up a view
         // that is subsequently removed from the workspace in startBinding().
@@ -672,6 +703,34 @@
     }
 
     /**
+     * Copied from View -- the View version of the method isn't called
+     * anywhere else in our process and only exists for API level 17+,
+     * so it's ok to keep our own version with no API requirement.
+     */
+    public static int generateViewId() {
+        for (;;) {
+            final int result = sNextGeneratedId.get();
+            // aapt-generated IDs have the high byte nonzero; clamp to the range under that.
+            int newValue = result + 1;
+            if (newValue > 0x00FFFFFF) newValue = 1; // Roll over to 1, not 0.
+            if (sNextGeneratedId.compareAndSet(result, newValue)) {
+                return result;
+            }
+        }
+    }
+
+    public int getViewIdForItem(ItemInfo info) {
+        // This cast is safe given the > 2B range for int.
+        int itemId = (int) info.id;
+        if (mItemIdToViewId.containsKey(itemId)) {
+            return mItemIdToViewId.get(itemId);
+        }
+        int viewId = generateViewId();
+        mItemIdToViewId.put(itemId, viewId);
+        return viewId;
+    }
+
+    /**
      * Returns whether we should delay spring loaded mode -- for shortcuts and widgets that have
      * a configuration step, this allows the proper animations to run after other transitions.
      */
@@ -708,14 +767,27 @@
             final int requestCode, final int resultCode, final Intent data) {
         // Reset the startActivity waiting flag
         mWaitingForResult = false;
+        int pendingAddWidgetId = mPendingAddWidgetId;
+        mPendingAddWidgetId = -1;
+
+        Runnable exitSpringLoaded = new Runnable() {
+            @Override
+            public void run() {
+                exitSpringLoadedDragModeDelayed((resultCode != RESULT_CANCELED),
+                        EXIT_SPRINGLOADED_MODE_SHORT_TIMEOUT, null);
+            }
+        };
 
         if (requestCode == REQUEST_BIND_APPWIDGET) {
-            int appWidgetId = data != null ?
+            final int appWidgetId = data != null ?
                     data.getIntExtra(AppWidgetManager.EXTRA_APPWIDGET_ID, -1) : -1;
             if (resultCode == RESULT_CANCELED) {
                 completeTwoStageWidgetDrop(RESULT_CANCELED, appWidgetId);
+                mWorkspace.removeExtraEmptyScreen(true, exitSpringLoaded,
+                        ON_ACTIVITY_RESULT_ANIMATION_DELAY, false);
             } else if (resultCode == RESULT_OK) {
-                addAppWidgetImpl(appWidgetId, mPendingAddInfo, null, mPendingAddWidgetInfo);
+                addAppWidgetImpl(appWidgetId, mPendingAddInfo, null,
+                        mPendingAddWidgetInfo, ON_ACTIVITY_RESULT_ANIMATION_DELAY);
             }
             return;
         } else if (requestCode == REQUEST_PICK_WALLPAPER) {
@@ -725,22 +797,48 @@
             return;
         }
 
-        boolean delayExitSpringLoadedMode = false;
         boolean isWidgetDrop = (requestCode == REQUEST_PICK_APPWIDGET ||
                 requestCode == REQUEST_CREATE_APPWIDGET);
 
         // We have special handling for widgets
         if (isWidgetDrop) {
-            int appWidgetId = data != null ?
-                    data.getIntExtra(AppWidgetManager.EXTRA_APPWIDGET_ID, -1) : -1;
-            if (appWidgetId < 0) {
+            final int appWidgetId;
+            int widgetId = data != null ? data.getIntExtra(AppWidgetManager.EXTRA_APPWIDGET_ID, -1)
+                    : -1;
+            if (widgetId < 0) {
+                appWidgetId = pendingAddWidgetId;
+            } else {
+                appWidgetId = widgetId;
+            }
+
+            final int result;
+            final Runnable onComplete;
+            if (appWidgetId < 0 || resultCode == RESULT_CANCELED) {
                 Log.e(TAG, "Error: appWidgetId (EXTRA_APPWIDGET_ID) was not returned from the \\" +
                         "widget configuration activity.");
-                completeTwoStageWidgetDrop(RESULT_CANCELED, appWidgetId);
-                mWorkspace.stripEmptyScreens();
+                result = RESULT_CANCELED;
+                completeTwoStageWidgetDrop(result, appWidgetId);
+                onComplete = new Runnable() {
+                    @Override
+                    public void run() {
+                        exitSpringLoadedDragModeDelayed(false, 0, null);
+                    }
+                };
             } else {
-                completeTwoStageWidgetDrop(resultCode, appWidgetId);
+                result = resultCode;
+                final CellLayout dropLayout =
+                        (CellLayout) mWorkspace.getScreenWithId(mPendingAddInfo.screenId);
+                dropLayout.setDropPending(true);
+                onComplete = new Runnable() {
+                    @Override
+                    public void run() {
+                        completeTwoStageWidgetDrop(result, appWidgetId);
+                        dropLayout.setDropPending(false);
+                    }
+                };
             }
+            mWorkspace.removeExtraEmptyScreen(true, onComplete, ON_ACTIVITY_RESULT_ANIMATION_DELAY,
+                    false);
             return;
         }
 
@@ -760,15 +858,15 @@
             if (isWorkspaceLocked()) {
                 sPendingAddList.add(args);
             } else {
-                delayExitSpringLoadedMode = completeAdd(args);
+                completeAdd(args);
             }
+            mWorkspace.removeExtraEmptyScreen(true, exitSpringLoaded,
+                    ON_ACTIVITY_RESULT_ANIMATION_DELAY, false);
         } else if (resultCode == RESULT_CANCELED) {
-            mWorkspace.stripEmptyScreens();
+            mWorkspace.removeExtraEmptyScreen(true, exitSpringLoaded,
+                    ON_ACTIVITY_RESULT_ANIMATION_DELAY, false);
         }
         mDragLayer.clearAnimatedView();
-        // Exit spring loaded mode if necessary after cancelling the configuration of a widget
-        exitSpringLoadedDragModeDelayed((resultCode != RESULT_CANCELED), delayExitSpringLoadedMode,
-                null);
     }
 
     private void completeTwoStageWidgetDrop(final int resultCode, final int appWidgetId) {
@@ -788,25 +886,19 @@
                 public void run() {
                     completeAddAppWidget(appWidgetId, mPendingAddInfo.container,
                             mPendingAddInfo.screenId, layout, null);
-                    exitSpringLoadedDragModeDelayed((resultCode != RESULT_CANCELED), false,
-                            null);
+                    exitSpringLoadedDragModeDelayed((resultCode != RESULT_CANCELED),
+                            EXIT_SPRINGLOADED_MODE_SHORT_TIMEOUT, null);
                 }
             };
         } else if (resultCode == RESULT_CANCELED) {
+            mAppWidgetHost.deleteAppWidgetId(appWidgetId);
             animationType = Workspace.CANCEL_TWO_STAGE_WIDGET_DROP_ANIMATION;
-            onCompleteRunnable = new Runnable() {
-                @Override
-                public void run() {
-                    exitSpringLoadedDragModeDelayed((resultCode != RESULT_CANCELED), false,
-                            null);
-                }
-            };
         }
         if (mDragLayer.getAnimatedView() != null) {
             mWorkspace.animateWidgetDrop(mPendingAddInfo, cellLayout,
                     (DragView) mDragLayer.getAnimatedView(), onCompleteRunnable,
                     animationType, boundWidget, true);
-        } else {
+        } else if (onCompleteRunnable != null) {
             // The animated view may be null in the case of a rotation during widget configuration
             onCompleteRunnable.run();
         }
@@ -837,7 +929,7 @@
         if (mOnResumeState == State.WORKSPACE) {
             showWorkspace(false);
         } else if (mOnResumeState == State.APPS_CUSTOMIZE) {
-            showAllApps(false, AppsCustomizePagedView.ContentType.Applications, false);
+            showAllApps(false, mAppsCustomizeContent.getContentType(), false);
         }
         mOnResumeState = State.NONE;
 
@@ -848,7 +940,7 @@
         sPausedFromUserAction = false;
         if (mRestoring || mOnResumeNeedsLoad) {
             mWorkspaceLoading = true;
-            mModel.startLoader(true, -1);
+            mModel.startLoader(true, PagedView.INVALID_RESTORE_PAGE);
             mRestoring = false;
             mOnResumeNeedsLoad = false;
         }
@@ -977,6 +1069,10 @@
         public void onScrollProgressChanged(float progress);
     }
 
+    protected boolean hasSettings() {
+        return false;
+    }
+
     protected void startSettings() {
     }
 
@@ -1076,6 +1172,7 @@
      *
      * @param savedState The previous state.
      */
+    @SuppressWarnings("unchecked")
     private void restoreState(Bundle savedState) {
         if (savedState == null) {
             return;
@@ -1103,6 +1200,7 @@
             mPendingAddInfo.spanX = savedState.getInt(RUNTIME_STATE_PENDING_ADD_SPAN_X);
             mPendingAddInfo.spanY = savedState.getInt(RUNTIME_STATE_PENDING_ADD_SPAN_Y);
             mPendingAddWidgetInfo = savedState.getParcelable(RUNTIME_STATE_PENDING_ADD_WIDGET_INFO);
+            mPendingAddWidgetId = savedState.getInt(RUNTIME_STATE_PENDING_ADD_WIDGET_ID);
             mWaitingForResult = true;
             mRestoring = true;
         }
@@ -1127,6 +1225,8 @@
             int currentIndex = savedState.getInt("apps_customize_currentIndex");
             mAppsCustomizeContent.restorePageForIndex(currentIndex);
         }
+        mItemIdToViewId = (HashMap<Integer, Integer>)
+                savedState.getSerializable(RUNTIME_STATE_VIEW_IDS);
     }
 
     /**
@@ -1138,6 +1238,7 @@
         mLauncherView = findViewById(R.id.launcher);
         mDragLayer = (DragLayer) findViewById(R.id.drag_layer);
         mWorkspace = (Workspace) mDragLayer.findViewById(R.id.workspace);
+        mPageIndicators = mDragLayer.findViewById(R.id.page_indicator);
 
         mLauncherView.setSystemUiVisibility(
                 View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN | View.SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION);
@@ -1153,12 +1254,14 @@
             mHotseat.setOnLongClickListener(this);
         }
 
-        mOverviewPanel = findViewById(R.id.overview_panel);
+        mOverviewPanel = (ViewGroup) findViewById(R.id.overview_panel);
         View widgetButton = findViewById(R.id.widget_button);
         widgetButton.setOnClickListener(new OnClickListener() {
             @Override
             public void onClick(View arg0) {
-                showAllApps(true, AppsCustomizePagedView.ContentType.Widgets, true);
+                if (!mWorkspace.isSwitchingState()) {
+                    showAllApps(true, AppsCustomizePagedView.ContentType.Widgets, true);
+                }
             }
         });
         widgetButton.setOnTouchListener(getHapticFeedbackTouchListener());
@@ -1167,19 +1270,31 @@
         wallpaperButton.setOnClickListener(new OnClickListener() {
             @Override
             public void onClick(View arg0) {
-                startWallpaper();
+                if (!mWorkspace.isSwitchingState()) {
+                    startWallpaper();
+                }
             }
         });
         wallpaperButton.setOnTouchListener(getHapticFeedbackTouchListener());
 
         View settingsButton = findViewById(R.id.settings_button);
-        settingsButton.setOnClickListener(new OnClickListener() {
-            @Override
-            public void onClick(View arg0) {
-                startSettings();
-            }
-        });
-        settingsButton.setOnTouchListener(getHapticFeedbackTouchListener());
+        if (hasSettings()) {
+            settingsButton.setOnClickListener(new OnClickListener() {
+                @Override
+                public void onClick(View arg0) {
+                    if (!mWorkspace.isSwitchingState()) {
+                        startSettings();
+                    }
+                    }
+            });
+            settingsButton.setOnTouchListener(getHapticFeedbackTouchListener());
+        } else {
+            settingsButton.setVisibility(View.GONE);
+            FrameLayout.LayoutParams lp = (FrameLayout.LayoutParams) widgetButton.getLayoutParams();
+            lp.gravity = Gravity.END | Gravity.TOP;
+            widgetButton.requestLayout();
+        }
+
         mOverviewPanel.setAlpha(0f);
 
         // Setup the workspace
@@ -1189,7 +1304,8 @@
         dragController.addDragListener(mWorkspace);
 
         // Get the search/delete bar
-        mSearchDropTargetBar = (SearchDropTargetBar) mDragLayer.findViewById(R.id.qsb_bar);
+        mSearchDropTargetBar = (SearchDropTargetBar)
+                mDragLayer.findViewById(R.id.search_drop_target_bar);
 
         // Setup AppsCustomize
         mAppsCustomizeTabHost = (AppsCustomizeTabHost) findViewById(R.id.apps_customize_pane);
@@ -1414,11 +1530,12 @@
             if (appWidgetId != -1) {
                 // Deleting an app widget ID is a void call but writes to disk before returning
                 // to the caller...
-                new Thread("deleteAppWidgetId") {
-                    public void run() {
+                new AsyncTask<Void, Void, Void>() {
+                    public Void doInBackground(Void ... args) {
                         mAppWidgetHost.deleteAppWidgetId(appWidgetId);
+                        return null;
                     }
-                }.start();
+                }.executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR, (Void) null);
             }
             showOutOfSpaceMessage(isHotseatLayout(layout));
             return;
@@ -1474,6 +1591,15 @@
             } else if (Intent.ACTION_USER_PRESENT.equals(action)) {
                 mUserPresent = true;
                 updateRunning();
+            } else if (ENABLE_DEBUG_INTENTS && DebugIntents.DELETE_DATABASE.equals(action)) {
+                mModel.resetLoadedState(false, true);
+                mModel.startLoader(false, PagedView.INVALID_RESTORE_PAGE,
+                        LauncherModel.LOADER_FLAG_CLEAR_WORKSPACE);
+            } else if (ENABLE_DEBUG_INTENTS && DebugIntents.MIGRATE_DATABASE.equals(action)) {
+                mModel.resetLoadedState(false, true);
+                mModel.startLoader(false, PagedView.INVALID_RESTORE_PAGE,
+                        LauncherModel.LOADER_FLAG_CLEAR_WORKSPACE
+                                | LauncherModel.LOADER_FLAG_MIGRATE_SHORTCUTS);
             }
         }
     };
@@ -1486,6 +1612,10 @@
         final IntentFilter filter = new IntentFilter();
         filter.addAction(Intent.ACTION_SCREEN_OFF);
         filter.addAction(Intent.ACTION_USER_PRESENT);
+        if (ENABLE_DEBUG_INTENTS) {
+            filter.addAction(DebugIntents.DELETE_DATABASE);
+            filter.addAction(DebugIntents.MIGRATE_DATABASE);
+        }
         registerReceiver(mReceiver, filter);
         FirstFrameAnimatorHelper.initializeDrawListener(getWindow().getDecorView());
         mAttached = true;
@@ -1625,6 +1755,26 @@
         Toast.makeText(this, getString(strId), Toast.LENGTH_SHORT).show();
     }
 
+    public DragLayer getDragLayer() {
+        return mDragLayer;
+    }
+
+    public Workspace getWorkspace() {
+        return mWorkspace;
+    }
+
+    public Hotseat getHotseat() {
+        return mHotseat;
+    }
+
+    public ViewGroup getOverviewPanel() {
+        return mOverviewPanel;
+    }
+
+    public SearchDropTargetBar getSearchBar() {
+        return mSearchDropTargetBar;
+    }
+
     public LauncherAppWidgetHost getAppWidgetHost() {
         return mAppWidgetHost;
     }
@@ -1633,6 +1783,14 @@
         return mModel;
     }
 
+    public LauncherClings getLauncherClings() {
+        return mLauncherClings;
+    }
+
+    protected SharedPreferences getSharedPrefs() {
+        return mSharedPrefs;
+    }
+
     public void closeSystemDialogs() {
         getWindow().closeAllPanels();
 
@@ -1665,7 +1823,7 @@
             // In all these cases, only animate if we're already on home
             mWorkspace.exitWidgetResizeMode();
             if (alreadyOnHome && mState == State.WORKSPACE && !mWorkspace.isTouchActive() &&
-                    openFolder == null) {
+                    openFolder == null && shouldMoveToDefaultScreenOnHomeIntent()) {
                 mWorkspace.moveToDefaultScreen(true);
             }
 
@@ -1688,9 +1846,11 @@
             }
 
             // Reset the apps customize page
-            if (mAppsCustomizeTabHost != null) {
+            if (!alreadyOnHome && mAppsCustomizeTabHost != null) {
                 mAppsCustomizeTabHost.reset();
             }
+
+            onHomeIntent();
         }
 
         if (DEBUG_RESUME_TIME) {
@@ -1698,6 +1858,21 @@
         }
     }
 
+    /**
+     * Override point for subclasses to prevent movement to the default screen when the home
+     * button is pressed. Used (for example) in GEL, to prevent movement during a search.
+     */
+    protected boolean shouldMoveToDefaultScreenOnHomeIntent() {
+        return true;
+    }
+
+    /**
+     * Override point for subclasses to provide custom behaviour for when a home intent is fired.
+     */
+    protected void onHomeIntent() {
+        // Do nothing
+    }
+
     @Override
     public void onRestoreInstanceState(Bundle state) {
         super.onRestoreInstanceState(state);
@@ -1709,7 +1884,8 @@
     @Override
     protected void onSaveInstanceState(Bundle outState) {
         if (mWorkspace.getChildCount() > 0) {
-            outState.putInt(RUNTIME_STATE_CURRENT_SCREEN, mWorkspace.getRestorePage());
+            outState.putInt(RUNTIME_STATE_CURRENT_SCREEN,
+                    mWorkspace.getCurrentPageOffsetFromCustomContent());
         }
         super.onSaveInstanceState(outState);
 
@@ -1727,6 +1903,7 @@
             outState.putInt(RUNTIME_STATE_PENDING_ADD_SPAN_X, mPendingAddInfo.spanX);
             outState.putInt(RUNTIME_STATE_PENDING_ADD_SPAN_Y, mPendingAddInfo.spanY);
             outState.putParcelable(RUNTIME_STATE_PENDING_ADD_WIDGET_INFO, mPendingAddWidgetInfo);
+            outState.putInt(RUNTIME_STATE_PENDING_ADD_WIDGET_ID, mPendingAddWidgetId);
         }
 
         if (mFolderInfo != null && mWaitingForResult) {
@@ -1736,13 +1913,15 @@
 
         // Save the current AppsCustomize tab
         if (mAppsCustomizeTabHost != null) {
-            String currentTabTag = mAppsCustomizeTabHost.getCurrentTabTag();
+            AppsCustomizePagedView.ContentType type = mAppsCustomizeContent.getContentType();
+            String currentTabTag = mAppsCustomizeTabHost.getTabTagForContentType(type);
             if (currentTabTag != null) {
                 outState.putString("apps_customize_currentTab", currentTabTag);
             }
             int currentIndex = mAppsCustomizeContent.getSaveInstanceStateIndex();
             outState.putInt("apps_customize_currentIndex", currentIndex);
         }
+        outState.putSerializable(RUNTIME_STATE_VIEW_IDS, mItemIdToViewId);
     }
 
     @Override
@@ -1781,7 +1960,7 @@
 
         mDragLayer.clearAllResizeFrames();
         ((ViewGroup) mWorkspace.getParent()).removeAllViews();
-        mWorkspace.removeAllViews();
+        mWorkspace.removeAllWorkspaceScreens();
         mWorkspace = null;
         mDragController = null;
 
@@ -1874,8 +2053,15 @@
     @Override
     public boolean onPrepareOptionsMenu(Menu menu) {
         super.onPrepareOptionsMenu(menu);
+        // Close any open folders
+        closeFolder();
+        // Stop resizing any widgets
+        mWorkspace.exitWidgetResizeMode();
         if (!mWorkspace.isInOverviewMode()) {
-            mWorkspace.enterOverviewMode();
+            // Show the overview mode
+            showOverviewMode(true);
+        } else {
+            showWorkspace(true);
         }
         return false;
     }
@@ -1900,10 +2086,17 @@
         mPendingAddInfo.dropPos = null;
     }
 
-    void addAppWidgetImpl(final int appWidgetId, ItemInfo info, AppWidgetHostView boundWidget,
-            AppWidgetProviderInfo appWidgetInfo) {
+    void addAppWidgetImpl(final int appWidgetId, final ItemInfo info,
+            final AppWidgetHostView boundWidget, final AppWidgetProviderInfo appWidgetInfo) {
+        addAppWidgetImpl(appWidgetId, info, boundWidget, appWidgetInfo, 0);
+    }
+
+    void addAppWidgetImpl(final int appWidgetId, final ItemInfo info,
+            final AppWidgetHostView boundWidget, final AppWidgetProviderInfo appWidgetInfo, int
+            delay) {
         if (appWidgetInfo.configure != null) {
             mPendingAddWidgetInfo = appWidgetInfo;
+            mPendingAddWidgetId = appWidgetId;
 
             // Launch over to configure widget, if needed
             Intent intent = new Intent(AppWidgetManager.ACTION_APPWIDGET_CONFIGURE);
@@ -1912,10 +2105,17 @@
             Utilities.startActivityForResultSafely(this, intent, REQUEST_CREATE_APPWIDGET);
         } else {
             // Otherwise just add it
+            Runnable onComplete = new Runnable() {
+                @Override
+                public void run() {
+                    // Exit spring loaded mode if necessary after adding the widget
+                    exitSpringLoadedDragModeDelayed(true, EXIT_SPRINGLOADED_MODE_SHORT_TIMEOUT,
+                            null);
+                }
+            };
             completeAddAppWidget(appWidgetId, info.container, info.screenId, boundWidget,
                     appWidgetInfo);
-            // Exit spring loaded mode if necessary after adding the widget
-            exitSpringLoadedDragModeDelayed(true, false, null);
+            mWorkspace.removeExtraEmptyScreen(true, onComplete, delay, false);
         }
     }
 
@@ -2062,7 +2262,7 @@
     }
 
     protected ComponentName getWallpaperPickerComponent() {
-        return new ComponentName(getPackageName(), WallpaperPickerActivity.class.getName());
+        return new ComponentName(getPackageName(), LauncherWallpaperPickerActivity.class.getName());
     }
 
     /**
@@ -2263,7 +2463,7 @@
      * @param v The view that was clicked.
      */
     public void onClickAllAppsButton(View v) {
-        showAllApps(true, AppsCustomizePagedView.ContentType.Applications, true);
+        showAllApps(true, AppsCustomizePagedView.ContentType.Applications, false);
     }
 
     public void onTouchDownAllAppsButton(View v) {
@@ -2553,7 +2753,7 @@
     }
 
     public void closeFolder() {
-        Folder folder = mWorkspace.getOpenFolder();
+        Folder folder = mWorkspace != null ? mWorkspace.getOpenFolder() : null;
         if (folder != null) {
             if (folder.isEditingName()) {
                 folder.dismissEditingName();
@@ -2561,7 +2761,7 @@
             closeFolder(folder);
 
             // Dismiss the folder cling
-            dismissFolderCling(null);
+            mLauncherClings.dismissFolderCling(null);
         }
     }
 
@@ -2611,7 +2811,8 @@
         // The hotseat touch handling does not go through Workspace, and we always allow long press
         // on hotseat items.
         final View itemUnderLongClick = longClickCellInfo.cell;
-        boolean allowLongPress = isHotseatLayout(v) || mWorkspace.allowLongPress();
+        final boolean inHotseat = isHotseatLayout(v);
+        boolean allowLongPress = inHotseat || mWorkspace.allowLongPress();
         if (allowLongPress && !mDragController.isDragging()) {
             if (itemUnderLongClick == null) {
                 // User long pressed on empty space
@@ -2624,7 +2825,11 @@
                     mWorkspace.enterOverviewMode();
                 }
             } else {
-                if (!(itemUnderLongClick instanceof Folder)) {
+                final boolean isAllAppsButton = inHotseat && isAllAppsButtonRank(
+                        mHotseat.getOrderInHotseat(
+                                longClickCellInfo.cellX,
+                                longClickCellInfo.cellY));
+                if (!(itemUnderLongClick instanceof Folder || isAllAppsButton)) {
                     // User long pressed on an item
                     mWorkspace.startDrag(longClickCellInfo);
                 }
@@ -2637,15 +2842,6 @@
         return mHotseat != null && layout != null &&
                 (layout instanceof CellLayout) && (layout == mHotseat.getLayout());
     }
-    Hotseat getHotseat() {
-        return mHotseat;
-    }
-    View getOverviewPanel() {
-        return mOverviewPanel;
-    }
-    SearchDropTargetBar getSearchBar() {
-        return mSearchDropTargetBar;
-    }
 
     /**
      * Returns the CellLayout of the specified container at the specified screen.
@@ -2662,10 +2858,6 @@
         }
     }
 
-    Workspace getWorkspace() {
-        return mWorkspace;
-    }
-
     public boolean isAllAppsVisible() {
         return (mState == State.APPS_CUSTOMIZE) || (mOnResumeState == State.APPS_CUSTOMIZE);
     }
@@ -2796,8 +2988,9 @@
         // Shrink workspaces away if going to AppsCustomize from workspace
         Animator workspaceAnim =
                 mWorkspace.getChangeStateAnimation(Workspace.State.SMALL, animated);
-        if (!AppsCustomizePagedView.DISABLE_ALL_APPS) {
-            // Set the content type for the all apps space
+        if (!LauncherAppState.isDisableAllApps()
+                || contentType == AppsCustomizePagedView.ContentType.Widgets) {
+            // Set the content type for the all apps/widgets space
             mAppsCustomizeTabHost.setContentTypeImmediate(contentType);
         }
 
@@ -2979,7 +3172,7 @@
 
             dispatchOnLauncherTransitionPrepare(fromView, animated, true);
             dispatchOnLauncherTransitionPrepare(toView, animated, true);
-            mAppsCustomizeContent.pauseScrolling();
+            mAppsCustomizeContent.stopScrolling();
 
             mStateAnimation.addListener(new AnimatorListenerAdapter() {
                 @Override
@@ -2991,7 +3184,6 @@
                         onCompleteRunnable.run();
                     }
                     mAppsCustomizeContent.updateCurrentPageScroll();
-                    mAppsCustomizeContent.resumeScrolling();
                 }
             });
 
@@ -3104,7 +3296,7 @@
         }
     }
 
-    void exitSpringLoadedDragModeDelayed(final boolean successfulDrop, boolean extendedDelay,
+    void exitSpringLoadedDragModeDelayed(final boolean successfulDrop, int delay,
             final Runnable onCompleteRunnable) {
         if (mState != State.APPS_CUSTOMIZE_SPRING_LOADED) return;
 
@@ -3121,9 +3313,8 @@
                     exitSpringLoadedDragMode();
                 }
             }
-        }, (extendedDelay ?
-                EXIT_SPRINGLOADED_MODE_LONG_TIMEOUT :
-                EXIT_SPRINGLOADED_MODE_SHORT_TIMEOUT));
+        }, delay);
+
     }
 
     void exitSpringLoadedDragMode() {
@@ -3297,11 +3488,11 @@
     }
 
     public View getQsbBar() {
-        if (mQsbBar == null) {
-            mQsbBar = mInflater.inflate(R.layout.search_bar, mSearchDropTargetBar, false);
-            mSearchDropTargetBar.addView(mQsbBar);
+        if (mQsb == null) {
+            mQsb = mInflater.inflate(R.layout.qsb, mSearchDropTargetBar, false);
+            mSearchDropTargetBar.addView(mQsb);
         }
-        return mQsbBar;
+        return mQsb;
     }
 
     protected boolean updateGlobalSearchIcon() {
@@ -3604,6 +3795,10 @@
 
     @Override
     public void bindAddScreens(ArrayList<Long> orderedScreenIds) {
+        // Log to disk
+        Launcher.addDumpLog(TAG, "11683562 - bindAddScreens()", true);
+        Launcher.addDumpLog(TAG, "11683562 -   orderedScreenIds: " +
+                TextUtils.join(", ", orderedScreenIds), true);
         int count = orderedScreenIds.size();
         for (int i = 0; i < count; i++) {
             mWorkspace.insertNewWorkspaceScreenBeforeEmptyScreen(orderedScreenIds.get(i));
@@ -3662,9 +3857,9 @@
         }
 
         // Remove the extra empty screen
-        mWorkspace.removeExtraEmptyScreen();
+        mWorkspace.removeExtraEmptyScreen(false, null);
 
-        if (!AppsCustomizePagedView.DISABLE_ALL_APPS &&
+        if (!LauncherAppState.isDisableAllApps() &&
                 addedApps != null && mAppsCustomizeContent != null) {
             mAppsCustomizeContent.addApps(addedApps);
         }
@@ -3756,9 +3951,11 @@
                     // when we are loading right after we return to launcher.
                     mWorkspace.postDelayed(new Runnable() {
                         public void run() {
-                            mWorkspace.snapToPage(newScreenIndex);
-                            mWorkspace.postDelayed(startBounceAnimRunnable,
-                                    NEW_APPS_ANIMATION_DELAY);
+                            if (mWorkspace != null) {
+                                mWorkspace.snapToPage(newScreenIndex);
+                                mWorkspace.postDelayed(startBounceAnimRunnable,
+                                        NEW_APPS_ANIMATION_DELAY);
+                            }
                         }
                     }, NEW_APPS_PAGE_MOVE_DELAY);
                 } else {
@@ -3906,6 +4103,16 @@
         return bounceAnim;
     }
 
+    public boolean useVerticalBarLayout() {
+        return LauncherAppState.getInstance().getDynamicGrid().
+                getDeviceProfile().isVerticalBarLayout();
+    }
+
+    protected Rect getSearchBarBounds() {
+        return LauncherAppState.getInstance().getDynamicGrid().
+                getDeviceProfile().getSearchBarBounds();
+    }
+
     @Override
     public void bindSearchablesChanged() {
         boolean searchVisible = updateGlobalSearchIcon();
@@ -3921,7 +4128,7 @@
      * Implementation of the method from LauncherModel.Callbacks.
      */
     public void bindAllApplications(final ArrayList<AppInfo> apps) {
-        if (AppsCustomizePagedView.DISABLE_ALL_APPS) {
+        if (LauncherAppState.isDisableAllApps()) {
             if (mIntentsOnWorkspaceFromUpgradePath != null) {
                 if (LauncherModel.UPGRADE_USE_MORE_APPS_FOLDER) {
                     getHotseat().addAllAppsFolder(mIconCache, apps,
@@ -3929,9 +4136,15 @@
                 }
                 mIntentsOnWorkspaceFromUpgradePath = null;
             }
+            if (mAppsCustomizeContent != null) {
+                mAppsCustomizeContent.onPackagesUpdated(
+                        LauncherModel.getSortedWidgetsAndShortcuts(this));
+            }
         } else {
             if (mAppsCustomizeContent != null) {
                 mAppsCustomizeContent.setApps(apps);
+                mAppsCustomizeContent.onPackagesUpdated(
+                        LauncherModel.getSortedWidgetsAndShortcuts(this));
             }
         }
     }
@@ -3955,7 +4168,7 @@
             mWorkspace.updateShortcuts(apps);
         }
 
-        if (!AppsCustomizePagedView.DISABLE_ALL_APPS &&
+        if (!LauncherAppState.isDisableAllApps() &&
                 mAppsCustomizeContent != null) {
             mAppsCustomizeContent.updateApps(apps);
         }
@@ -3971,27 +4184,28 @@
      * Implementation of the method from LauncherModel.Callbacks.
      */
     public void bindComponentsRemoved(final ArrayList<String> packageNames,
-                                      final ArrayList<AppInfo> appInfos,
-                                      final boolean packageRemoved) {
+                                      final ArrayList<AppInfo> appInfos) {
         Runnable r = new Runnable() {
             public void run() {
-                bindComponentsRemoved(packageNames, appInfos, packageRemoved);
+                bindComponentsRemoved(packageNames, appInfos);
             }
         };
         if (waitUntilResume(r)) {
             return;
         }
 
-        if (packageRemoved) {
+        if (!packageNames.isEmpty()) {
             mWorkspace.removeItemsByPackageName(packageNames);
-        } else {
+        }
+        if (!appInfos.isEmpty()) {
             mWorkspace.removeItemsByApplicationInfo(appInfos);
         }
 
         // Notify the drag controller
-        mDragController.onAppsRemoved(appInfos, this);
+        mDragController.onAppsRemoved(packageNames, appInfos);
 
-        if (!AppsCustomizePagedView.DISABLE_ALL_APPS &&
+        // Update AllApps
+        if (!LauncherAppState.isDisableAllApps() &&
                 mAppsCustomizeContent != null) {
             mAppsCustomizeContent.removeApps(appInfos);
         }
@@ -4007,7 +4221,6 @@
                 mWidgetsAndShortcuts = null;
             }
         };
-
     public void bindPackagesUpdated(final ArrayList<Object> widgetsAndShortcuts) {
         if (waitUntilResume(mBindPackagesUpdatedRunnable, true)) {
             mWidgetsAndShortcuts = widgetsAndShortcuts;
@@ -4015,8 +4228,7 @@
         }
 
         // Update the widgets pane
-        if (!AppsCustomizePagedView.DISABLE_ALL_APPS &&
-                mAppsCustomizeContent != null) {
+        if (mAppsCustomizeContent != null) {
             mAppsCustomizeContent.onPackagesUpdated(widgetsAndShortcuts);
         }
     }
@@ -4078,209 +4290,27 @@
         }
     }
 
-    /* Cling related */
-    private boolean isClingsEnabled() {
-        if (DISABLE_CLINGS) {
-            return false;
-        }
-
-        // For now, limit only to phones
-        LauncherAppState app = LauncherAppState.getInstance();
-        DeviceProfile grid = app.getDynamicGrid().getDeviceProfile();
-        if (grid.isTablet()) {
-            return false;
-        }
-
-        // disable clings when running in a test harness
-        if(ActivityManager.isRunningInTestHarness()) return false;
-
-        // Disable clings for accessibility when explore by touch is enabled
-        final AccessibilityManager a11yManager = (AccessibilityManager) getSystemService(
-                ACCESSIBILITY_SERVICE);
-        if (a11yManager.isTouchExplorationEnabled()) {
-            return false;
-        }
-
-        // Restricted secondary users (child mode) will potentially have very few apps
-        // seeded when they start up for the first time. Clings won't work well with that
-//        boolean supportsLimitedUsers =
-//                android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.JELLY_BEAN_MR2;
-//        Account[] accounts = AccountManager.get(this).getAccounts();
-//        if (supportsLimitedUsers && accounts.length == 0) {
-//            UserManager um = (UserManager) getSystemService(Context.USER_SERVICE);
-//            Bundle restrictions = um.getUserRestrictions();
-//            if (restrictions.getBoolean(UserManager.DISALLOW_MODIFY_ACCOUNTS, false)) {
-//               return false;
-//            }
-//        }
-        return true;
+    /**
+     * Called when the SearchBar hint should be changed.
+     *
+     * @param hint the hint to be displayed in the search bar.
+     */
+    protected void onSearchBarHintChanged(String hint) {
+        mLauncherClings.updateSearchBarHint(hint);
     }
 
-    private Cling initCling(int clingId, int scrimId, boolean animate,
-                            boolean dimNavBarVisibilty) {
-        Cling cling = (Cling) findViewById(clingId);
-        View scrim = null;
-        if (scrimId > 0) {
-            scrim = findViewById(R.id.cling_scrim);
-        }
-        if (cling != null) {
-            cling.init(this, scrim);
-            cling.show(animate, SHOW_CLING_DURATION);
-
-            if (dimNavBarVisibilty) {
-                cling.setSystemUiVisibility(cling.getSystemUiVisibility() |
-                        View.SYSTEM_UI_FLAG_LOW_PROFILE);
-            }
-        }
-        return cling;
-    }
-
-    private void dismissCling(final Cling cling, final Runnable postAnimationCb,
-                              final String flag, int duration, boolean restoreNavBarVisibilty) {
-        // To catch cases where siblings of top-level views are made invisible, just check whether
-        // the cling is directly set to GONE before dismissing it.
-        if (cling != null && cling.getVisibility() != View.GONE) {
-            final Runnable cleanUpClingCb = new Runnable() {
-                public void run() {
-                    cling.cleanup();
-                    // We should update the shared preferences on a background thread
-                    new Thread("dismissClingThread") {
-                        public void run() {
-                            SharedPreferences.Editor editor = mSharedPrefs.edit();
-                            editor.putBoolean(flag, true);
-                            editor.commit();
-                        }
-                    }.start();
-                    if (postAnimationCb != null) {
-                        postAnimationCb.run();
-                    }
-                }
-            };
-            if (duration <= 0) {
-                cleanUpClingCb.run();
+    protected boolean isLauncherPreinstalled() {
+        PackageManager pm = getPackageManager();
+        try {
+            ApplicationInfo ai = pm.getApplicationInfo(getComponentName().getPackageName(), 0);
+            if ((ai.flags & ApplicationInfo.FLAG_SYSTEM) != 0) {
+                return true;
             } else {
-                cling.hide(duration, cleanUpClingCb);
+                return false;
             }
-            mHideFromAccessibilityHelper.restoreImportantForAccessibility(mDragLayer);
-
-            if (restoreNavBarVisibilty) {
-                cling.setSystemUiVisibility(cling.getSystemUiVisibility() &
-                        ~View.SYSTEM_UI_FLAG_LOW_PROFILE);
-            }
-        }
-    }
-
-    private void removeCling(int id) {
-        final View cling = findViewById(id);
-        if (cling != null) {
-            final ViewGroup parent = (ViewGroup) cling.getParent();
-            parent.post(new Runnable() {
-                @Override
-                public void run() {
-                    parent.removeView(cling);
-                }
-            });
-            mHideFromAccessibilityHelper.restoreImportantForAccessibility(mDragLayer);
-        }
-    }
-
-    private boolean skipCustomClingIfNoAccounts() {
-        Cling cling = (Cling) findViewById(R.id.workspace_cling);
-        boolean customCling = cling.getDrawIdentifier().equals("workspace_custom");
-        if (customCling) {
-            AccountManager am = AccountManager.get(this);
-            if (am == null) return false;
-            Account[] accounts = am.getAccountsByType("com.google");
-            return accounts.length == 0;
-        }
-        return false;
-    }
-
-    public void updateCustomContentHintVisibility() {
-        Cling cling = (Cling) findViewById(R.id.first_run_cling);
-        String ccHintStr = getFirstRunCustomContentHint();
-
-        if (mWorkspace.hasCustomContent()) {
-            // Show the custom content hint if ccHintStr is not empty
-            if (cling != null) {
-                setCustomContentHintVisibility(cling, ccHintStr, true, true);
-            }
-        } else {
-            // Hide the custom content hint
-            if (cling != null) {
-                setCustomContentHintVisibility(cling, ccHintStr, false, true);
-            }
-        }
-    }
-
-    private void setCustomContentHintVisibility(Cling cling, String ccHintStr, boolean visible,
-                                                boolean animate) {
-        final TextView ccHint = (TextView) cling.findViewById(R.id.custom_content_hint);
-        if (ccHint != null) {
-            if (visible && !ccHintStr.isEmpty()) {
-                ccHint.setText(ccHintStr);
-                ccHint.setVisibility(View.VISIBLE);
-                if (animate) {
-                    ccHint.setAlpha(0f);
-                    ccHint.animate().alpha(1f)
-                                    .setDuration(SHOW_CLING_DURATION)
-                                    .start();
-                } else {
-                    ccHint.setAlpha(1f);
-                }
-            } else {
-                if (animate) {
-                    ccHint.animate().alpha(0f)
-                                    .setDuration(SHOW_CLING_DURATION)
-                                    .setListener(new AnimatorListenerAdapter() {
-                                        @Override
-                                        public void onAnimationEnd(Animator animation) {
-                                            ccHint.setVisibility(View.GONE);
-                                        }
-                                    })
-                                    .start();
-                } else {
-                    ccHint.setAlpha(0f);
-                    ccHint.setVisibility(View.GONE);
-                }
-            }
-        }
-    }
-
-    public void showFirstRunCling() {
-        if (isClingsEnabled() &&
-                !mSharedPrefs.getBoolean(Cling.FIRST_RUN_CLING_DISMISSED_KEY, false) &&
-                !skipCustomClingIfNoAccounts() ) {
-            // If we're not using the default workspace layout, replace workspace cling
-            // with a custom workspace cling (usually specified in an overlay)
-            // For now, only do this on tablets
-            if (!DISABLE_CUSTOM_CLINGS) {
-                if (mSharedPrefs.getInt(LauncherProvider.DEFAULT_WORKSPACE_RESOURCE_ID, 0) != 0 &&
-                        getResources().getBoolean(R.bool.config_useCustomClings)) {
-                    // Use a custom cling
-                    View cling = findViewById(R.id.workspace_cling);
-                    ViewGroup clingParent = (ViewGroup) cling.getParent();
-                    int clingIndex = clingParent.indexOfChild(cling);
-                    clingParent.removeViewAt(clingIndex);
-                    View customCling = mInflater.inflate(R.layout.custom_workspace_cling, clingParent, false);
-                    clingParent.addView(customCling, clingIndex);
-                    customCling.setId(R.id.workspace_cling);
-                }
-            }
-            Cling cling = (Cling) findViewById(R.id.first_run_cling);
-            if (cling != null) {
-                String sbHintStr = getFirstRunClingSearchBarHint();
-                String ccHintStr = getFirstRunCustomContentHint();
-                if (!sbHintStr.isEmpty()) {
-                    TextView sbHint = (TextView) cling.findViewById(R.id.search_bar_hint);
-                    sbHint.setText(sbHintStr);
-                    sbHint.setVisibility(View.VISIBLE);
-                }
-                setCustomContentHintVisibility(cling, ccHintStr, true, false);
-            }
-            initCling(R.id.first_run_cling, 0, false, true);
-        } else {
-            removeCling(R.id.first_run_cling);
+        } catch (NameNotFoundException e) {
+            e.printStackTrace();
+            return false;
         }
     }
 
@@ -4306,78 +4336,79 @@
         return "";
     }
 
-    public void showFirstRunWorkspaceCling() {
-        // Enable the clings only if they have not been dismissed before
-        if (isClingsEnabled() &&
-                !mSharedPrefs.getBoolean(Cling.WORKSPACE_CLING_DISMISSED_KEY, false)) {
-            Cling c = initCling(R.id.workspace_cling, 0, false, true);
-
-            // Set the focused hotseat app if there is one
-            c.setFocusedHotseatApp(getFirstRunFocusedHotseatAppDrawableId(),
-                    getFirstRunFocusedHotseatAppRank(),
-                    getFirstRunFocusedHotseatAppComponentName(),
-                    getFirstRunFocusedHotseatAppBubbleTitle(),
-                    getFirstRunFocusedHotseatAppBubbleDescription());
-        } else {
-            removeCling(R.id.workspace_cling);
-        }
-    }
-    public Cling showFirstRunFoldersCling() {
-        // Enable the clings only if they have not been dismissed before
-        if (isClingsEnabled() &&
-                !mSharedPrefs.getBoolean(Cling.FOLDER_CLING_DISMISSED_KEY, false)) {
-            Cling cling = initCling(R.id.folder_cling, R.id.cling_scrim,
-                    true, true);
-            return cling;
-        } else {
-            removeCling(R.id.folder_cling);
-            return null;
-        }
-    }
-    protected SharedPreferences getSharedPrefs() {
-        return mSharedPrefs;
-    }
-    public boolean isFolderClingVisible() {
-        Cling cling = (Cling) findViewById(R.id.folder_cling);
-        if (cling != null) {
-            return cling.getVisibility() == View.VISIBLE;
-        }
-        return false;
-    }
     public void dismissFirstRunCling(View v) {
-        Cling cling = (Cling) findViewById(R.id.first_run_cling);
-        Runnable cb = new Runnable() {
-            public void run() {
-                // Show the workspace cling next
-                showFirstRunWorkspaceCling();
-            }
-        };
-        dismissCling(cling, cb, Cling.FIRST_RUN_CLING_DISMISSED_KEY,
-                DISMISS_CLING_DURATION, false);
-
-        // Fade out the search bar for the workspace cling coming up
-        mSearchDropTargetBar.hideSearchBar(true);
+        mLauncherClings.dismissFirstRunCling(v);
+    }
+    public void dismissMigrationClingCopyApps(View v) {
+        mLauncherClings.dismissMigrationClingCopyApps(v);
+    }
+    public void dismissMigrationClingUseDefault(View v) {
+        mLauncherClings.dismissMigrationClingUseDefault(v);
+    }
+    public void dismissMigrationWorkspaceCling(View v) {
+        mLauncherClings.dismissMigrationWorkspaceCling(v);
     }
     public void dismissWorkspaceCling(View v) {
-        Cling cling = (Cling) findViewById(R.id.workspace_cling);
-        Runnable cb = null;
-        if (v == null) {
-            cb = new Runnable() {
-                public void run() {
-                    mWorkspace.enterOverviewMode();
-                }
-            };
-        }
-        dismissCling(cling, cb, Cling.WORKSPACE_CLING_DISMISSED_KEY,
-                DISMISS_CLING_DURATION, true);
-
-        // Fade in the search bar
-        mSearchDropTargetBar.showSearchBar(true);
+        mLauncherClings.dismissWorkspaceCling(v);
     }
     public void dismissFolderCling(View v) {
-        Cling cling = (Cling) findViewById(R.id.folder_cling);
-        dismissCling(cling, null, Cling.FOLDER_CLING_DISMISSED_KEY,
-                DISMISS_CLING_DURATION, true);
+        mLauncherClings.dismissFolderCling(v);
+    }
+
+    private boolean shouldRunFirstRunActivity() {
+        return !ActivityManager.isRunningInTestHarness() &&
+                !mSharedPrefs.getBoolean(FIRST_RUN_ACTIVITY_DISPLAYED, false);
+    }
+
+    public void showFirstRunActivity() {
+        if (shouldRunFirstRunActivity() &&
+                hasFirstRunActivity()) {
+            Intent firstRunIntent = getFirstRunActivity();
+            if (firstRunIntent != null) {
+                startActivity(firstRunIntent);
+                markFirstRunActivityShown();
+            }
+        }
+    }
+
+    private void markFirstRunActivityShown() {
+        SharedPreferences.Editor editor = mSharedPrefs.edit();
+        editor.putBoolean(FIRST_RUN_ACTIVITY_DISPLAYED, true);
+        editor.apply();
+    }
+
+    void showWorkspaceSearchAndHotseat() {
+        if (mWorkspace != null) mWorkspace.setAlpha(1f);
+        if (mHotseat != null) mHotseat.setAlpha(1f);
+        if (mPageIndicators != null) mPageIndicators.setAlpha(1f);
+        if (mSearchDropTargetBar != null) mSearchDropTargetBar.showSearchBar(false);
+    }
+
+    void hideWorkspaceSearchAndHotseat() {
+        if (mWorkspace != null) mWorkspace.setAlpha(0f);
+        if (mHotseat != null) mHotseat.setAlpha(0f);
+        if (mPageIndicators != null) mPageIndicators.setAlpha(0f);
+        if (mSearchDropTargetBar != null) mSearchDropTargetBar.hideSearchBar(false);
+    }
+
+
+    public ItemInfo createAppDragInfo(Intent appLaunchIntent) {
+        ResolveInfo ri = getPackageManager().resolveActivity(appLaunchIntent, 0);
+        if (ri == null) {
+            return null;
+        }
+        return new AppInfo(getPackageManager(), ri, mIconCache, null);
+    }
+
+    public ItemInfo createShortcutDragInfo(Intent shortcutIntent, CharSequence caption,
+            Bitmap icon) {
+        return new ShortcutInfo(shortcutIntent, caption, icon);
+    }
+
+    public void startDrag(View dragView, ItemInfo dragInfo, DragSource source) {
+        dragView.setTag(dragInfo);
+        mWorkspace.onDragStartedWithItem(dragView);
+        mWorkspace.beginDragShared(dragView, source);
     }
 
     /**
@@ -4427,22 +4458,30 @@
     }
 
     public static void addDumpLog(String tag, String log, boolean debugLog) {
+        addDumpLog(tag, log, null, debugLog);
+    }
+
+    public static void addDumpLog(String tag, String log, Exception e, boolean debugLog) {
         if (debugLog) {
-            Log.d(tag, log);
+            if (e != null) {
+                Log.d(tag, log, e);
+            } else {
+                Log.d(tag, log);
+            }
         }
         if (DEBUG_DUMP_LOG) {
             sDateStamp.setTime(System.currentTimeMillis());
             synchronized (sDumpLogs) {
-                sDumpLogs.add(sDateFormat.format(sDateStamp) + ": " + tag + ", " + log);
+                sDumpLogs.add(sDateFormat.format(sDateStamp) + ": " + tag + ", " + log
+                    + (e == null ? "" : (", Exception: " + e)));
             }
         }
     }
 
     public void dumpLogsToLocalData() {
         if (DEBUG_DUMP_LOG) {
-            new Thread("DumpLogsToLocalData") {
-                @Override
-                public void run() {
+            new AsyncTask<Void, Void, Void>() {
+                public Void doInBackground(Void ... args) {
                     boolean success = false;
                     sDateStamp.setTime(sRunStart);
                     String FILENAME = sDateStamp.getMonth() + "-"
@@ -4480,8 +4519,9 @@
                     } catch (IOException e) {
                         e.printStackTrace();
                     }
+                    return null;
                 }
-            }.start();
+            }.executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR, (Void) null);
         }
     }
 }
@@ -4493,3 +4533,8 @@
     void onLauncherTransitionStep(Launcher l, float t);
     void onLauncherTransitionEnd(Launcher l, boolean animated, boolean toWorkspace);
 }
+
+interface DebugIntents {
+    static final String DELETE_DATABASE = "com.android.launcher3.action.DELETE_DATABASE";
+    static final String MIGRATE_DATABASE = "com.android.launcher3.action.MIGRATE_DATABASE";
+}
diff --git a/src/com/android/launcher3/LauncherAnimUtils.java b/src/com/android/launcher3/LauncherAnimUtils.java
index 5d4f9c6..e6c220b 100644
--- a/src/com/android/launcher3/LauncherAnimUtils.java
+++ b/src/com/android/launcher3/LauncherAnimUtils.java
@@ -25,12 +25,13 @@
 import android.view.ViewTreeObserver;
 
 import java.util.HashSet;
+import java.util.WeakHashMap;
 
 public class LauncherAnimUtils {
-    static HashSet<Animator> sAnimators = new HashSet<Animator>();
+    static WeakHashMap<Animator, Object> sAnimators = new WeakHashMap<Animator, Object>();
     static Animator.AnimatorListener sEndAnimListener = new Animator.AnimatorListener() {
         public void onAnimationStart(Animator animation) {
-            sAnimators.add(animation);
+            sAnimators.put(animation, null);
         }
 
         public void onAnimationRepeat(Animator animation) {
@@ -74,13 +75,12 @@
     }
 
     public static void onDestroyActivity() {
-        HashSet<Animator> animators = new HashSet<Animator>(sAnimators);
+        HashSet<Animator> animators = new HashSet<Animator>(sAnimators.keySet());
         for (Animator a : animators) {
             if (a.isRunning()) {
                 a.cancel();
-            } else {
-                sAnimators.remove(a);
             }
+            sAnimators.remove(a);
         }
     }
 
diff --git a/src/com/android/launcher3/LauncherAppState.java b/src/com/android/launcher3/LauncherAppState.java
index a255b89..29e18f9 100644
--- a/src/com/android/launcher3/LauncherAppState.java
+++ b/src/com/android/launcher3/LauncherAppState.java
@@ -22,23 +22,23 @@
 import android.content.res.Resources;
 import android.database.ContentObserver;
 import android.os.Handler;
-import android.provider.Settings;
 import android.util.Log;
-import android.view.Display;
 
 import java.lang.ref.WeakReference;
 
-public class LauncherAppState {
+public class LauncherAppState implements DeviceProfile.DeviceProfileCallbacks {
     private static final String TAG = "LauncherAppState";
     private static final String SHARED_PREFERENCES_KEY = "com.android.launcher3.prefs";
 
+    private final AppFilter mAppFilter;
+    private final BuildInfo mBuildInfo;
     private LauncherModel mModel;
     private IconCache mIconCache;
-    private AppFilter mAppFilter;
     private WidgetPreviewLoader.CacheDb mWidgetPreviewCacheDb;
     private boolean mIsScreenLarge;
     private float mScreenDensity;
     private int mLongPressTimeout = 300;
+    private boolean mWallpaperChangedSinceLastCheck;
 
     private static WeakReference<LauncherProvider> sLauncherProvider;
     private static Context sContext;
@@ -84,10 +84,11 @@
         mIsScreenLarge = isScreenLarge(sContext.getResources());
         mScreenDensity = sContext.getResources().getDisplayMetrics().density;
 
-        mWidgetPreviewCacheDb = new WidgetPreviewLoader.CacheDb(sContext);
+        recreateWidgetPreviewDb();
         mIconCache = new IconCache(sContext);
 
         mAppFilter = AppFilter.loadByName(sContext.getString(R.string.app_filter_class));
+        mBuildInfo = BuildInfo.loadByName(sContext.getString(R.string.build_info_class));
         mModel = new LauncherModel(this, mIconCache, mAppFilter);
 
         // Register intent receivers
@@ -114,6 +115,13 @@
         resolver.registerContentObserver(LauncherSettings.Favorites.CONTENT_URI, true,
                 mFavoritesObserver);
     }
+    
+    public void recreateWidgetPreviewDb() {
+        if (mWidgetPreviewCacheDb != null) {
+            mWidgetPreviewCacheDb.close();
+        }
+        mWidgetPreviewCacheDb = new WidgetPreviewLoader.CacheDb(sContext);
+    }
 
     /**
      * Call from Application.onTerminate(), which is not guaranteed to ever be called.
@@ -182,16 +190,16 @@
                     context.getResources(),
                     minWidth, minHeight, width, height,
                     availableWidth, availableHeight);
+            mDynamicGrid.getDeviceProfile().addCallback(this);
         }
 
         // Update the icon size
         DeviceProfile grid = mDynamicGrid.getDeviceProfile();
-        Utilities.setIconSize(grid.iconSizePx);
-        grid.updateFromConfiguration(context.getResources(), width, height,
+        grid.updateFromConfiguration(context, context.getResources(), width, height,
                 availableWidth, availableHeight);
         return grid;
     }
-    DynamicGrid getDynamicGrid() {
+    public DynamicGrid getDynamicGrid() {
         return mDynamicGrid;
     }
 
@@ -216,4 +224,29 @@
     public int getLongPressTimeout() {
         return mLongPressTimeout;
     }
+
+    public void onWallpaperChanged() {
+        mWallpaperChangedSinceLastCheck = true;
+    }
+
+    public boolean hasWallpaperChangedSinceLastCheck() {
+        boolean result = mWallpaperChangedSinceLastCheck;
+        mWallpaperChangedSinceLastCheck = false;
+        return result;
+    }
+
+    @Override
+    public void onAvailableSizeChanged(DeviceProfile grid) {
+        Utilities.setIconSize(grid.iconSizePx);
+    }
+
+    public static boolean isDisableAllApps() {
+        // Returns false on non-dogfood builds.
+        return getInstance().mBuildInfo.isDogfoodBuild() &&
+                Launcher.isPropertyEnabled(Launcher.DISABLE_ALL_APPS_PROPERTY);
+    }
+
+    public static boolean isDogfoodBuild() {
+        return getInstance().mBuildInfo.isDogfoodBuild();
+    }
 }
diff --git a/src/com/android/launcher3/LauncherAppWidgetHostView.java b/src/com/android/launcher3/LauncherAppWidgetHostView.java
index 83aef1a..51a649a 100644
--- a/src/com/android/launcher3/LauncherAppWidgetHostView.java
+++ b/src/com/android/launcher3/LauncherAppWidgetHostView.java
@@ -65,6 +65,12 @@
     }
 
     public boolean onInterceptTouchEvent(MotionEvent ev) {
+        // Just in case the previous long press hasn't been cleared, we make sure to start fresh
+        // on touch down.
+        if (ev.getAction() == MotionEvent.ACTION_DOWN) {
+            mLongPressHelper.cancelLongPress();
+        }
+
         // Consume any touch events for ourselves after longpress is triggered
         if (mLongPressHelper.hasPerformedLongPress()) {
             mLongPressHelper.cancelLongPress();
@@ -110,13 +116,15 @@
 
     @Override
     public void onTouchComplete() {
-        mLongPressHelper.cancelLongPress();
+        if (!mLongPressHelper.hasPerformedLongPress()) {
+            // If a long press has been performed, we don't want to clear the record of that since
+            // we still may be receiving a touch up which we want to intercept
+            mLongPressHelper.cancelLongPress();
+        }
     }
 
     @Override
     public int getDescendantFocusability() {
         return ViewGroup.FOCUS_BLOCK_DESCENDANTS;
     }
-
-
 }
diff --git a/src/com/android/launcher3/LauncherBackupAgentHelper.java b/src/com/android/launcher3/LauncherBackupAgentHelper.java
index 2b5059b..de6aedd 100644
--- a/src/com/android/launcher3/LauncherBackupAgentHelper.java
+++ b/src/com/android/launcher3/LauncherBackupAgentHelper.java
@@ -18,12 +18,22 @@
 
 import android.app.backup.BackupAgentHelper;
 import android.app.backup.BackupManager;
+import android.app.backup.SharedPreferencesBackupHelper;
 import android.content.Context;
+import android.content.SharedPreferences;
+import android.provider.Settings;
+import android.util.Log;
 
 public class LauncherBackupAgentHelper extends BackupAgentHelper {
 
+    private static final String TAG = "LauncherBackupAgentHelper";
+    static final boolean VERBOSE = true;
+    static final boolean DEBUG = false;
+
     private static BackupManager sBackupManager;
 
+    protected static final String SETTING_RESTORE_ENABLED = "launcher_restore_enabled";
+
     /**
      * Notify the backup manager that out database is dirty.
      *
@@ -38,9 +48,27 @@
         sBackupManager.dataChanged();
     }
 
+    @Override
+    public void onDestroy() {
+        // There is only one process accessing this preference file, but the restore
+        // modifies the file outside the normal codepaths, so it looks like another
+        // process.  This forces a reload of the file, in case this process persists.
+        String spKey = LauncherAppState.getSharedPreferencesKey();
+        SharedPreferences sp = getSharedPreferences(spKey, Context.MODE_MULTI_PROCESS);
+        super.onDestroy();
+    }
 
     @Override
     public void onCreate() {
-        addHelper(LauncherBackupHelper.LAUNCHER_PREFIX, new LauncherBackupHelper(this));
+        boolean restoreEnabled = 0 != Settings.Secure.getInt(
+                getContentResolver(), SETTING_RESTORE_ENABLED, 0);
+        if (VERBOSE) Log.v(TAG, "restore is " + (restoreEnabled ? "enabled" : "disabled"));
+
+        addHelper(LauncherBackupHelper.LAUNCHER_PREFS_PREFIX,
+                new LauncherPreferencesBackupHelper(this,
+                        LauncherAppState.getSharedPreferencesKey(),
+                        restoreEnabled));
+        addHelper(LauncherBackupHelper.LAUNCHER_PREFIX,
+                new LauncherBackupHelper(this, restoreEnabled));
     }
 }
diff --git a/src/com/android/launcher3/LauncherBackupHelper.java b/src/com/android/launcher3/LauncherBackupHelper.java
index 9b901ee..57cdfb9 100644
--- a/src/com/android/launcher3/LauncherBackupHelper.java
+++ b/src/com/android/launcher3/LauncherBackupHelper.java
@@ -13,7 +13,6 @@
  * See the License for the specific language governing permissions and
  * limitations under the License.
  */
-
 package com.android.launcher3;
 
 import com.google.protobuf.nano.InvalidProtocolBufferNanoException;
@@ -31,14 +30,14 @@
 import com.android.launcher3.backup.BackupProtos.Widget;
 
 import android.app.backup.BackupDataInputStream;
-import android.app.backup.BackupHelper;
-import android.app.backup.BackupDataInput;
 import android.app.backup.BackupDataOutput;
+import android.app.backup.BackupHelper;
 import android.app.backup.BackupManager;
 import android.appwidget.AppWidgetManager;
 import android.appwidget.AppWidgetProviderInfo;
 import android.content.ComponentName;
 import android.content.ContentResolver;
+import android.content.ContentValues;
 import android.content.Context;
 import android.content.Intent;
 import android.database.Cursor;
@@ -68,7 +67,8 @@
 public class LauncherBackupHelper implements BackupHelper {
 
     private static final String TAG = "LauncherBackupHelper";
-    private static final boolean DEBUG = false;
+    private static final boolean VERBOSE = LauncherBackupAgentHelper.VERBOSE;
+    private static final boolean DEBUG = LauncherBackupAgentHelper.DEBUG;
     private static final boolean DEBUG_PAYLOAD = false;
 
     private static final int MAX_JOURNAL_SIZE = 1000000;
@@ -83,6 +83,8 @@
 
     public static final String LAUNCHER_PREFIX = "L";
 
+    public static final String LAUNCHER_PREFS_PREFIX = "LP";
+
     private static final Bitmap.CompressFormat IMAGE_FORMAT =
             android.graphics.Bitmap.CompressFormat.PNG;
 
@@ -136,12 +138,15 @@
 
     private final Context mContext;
 
+    private final boolean mRestoreEnabled;
+
     private HashMap<ComponentName, AppWidgetProviderInfo> mWidgetMap;
 
     private ArrayList<Key> mKeys;
 
-    public LauncherBackupHelper(Context context) {
+    public LauncherBackupHelper(Context context, boolean restoreEnabled) {
         mContext = context;
+        mRestoreEnabled = restoreEnabled;
     }
 
     private void dataChanged() {
@@ -166,7 +171,7 @@
     @Override
     public void performBackup(ParcelFileDescriptor oldState, BackupDataOutput data,
             ParcelFileDescriptor newState) {
-        Log.v(TAG, "onBackup");
+        if (VERBOSE) Log.v(TAG, "onBackup");
 
         Journal in = readJournal(oldState);
         Journal out = new Journal();
@@ -176,7 +181,7 @@
         out.rows = 0;
         out.bytes = 0;
 
-        Log.v(TAG, "lastBackupTime=" + lastBackupTime);
+        Log.v(TAG, "lastBackupTime = " + lastBackupTime);
 
         ArrayList<Key> keys = new ArrayList<Key>();
         try {
@@ -202,7 +207,7 @@
      */
     @Override
     public void restoreEntity(BackupDataInputStream data) {
-        Log.v(TAG, "restoreEntity");
+        if (VERBOSE) Log.v(TAG, "restoreEntity");
         if (mKeys == null) {
             mKeys = new ArrayList<Key>();
         }
@@ -218,10 +223,11 @@
             bytesRead = data.read(buffer, 0, dataSize);
             if (DEBUG) Log.d(TAG, "read " + bytesRead + " of " + dataSize + " available");
         } catch (IOException e) {
-            Log.d(TAG, "failed to read entity from restore data", e);
+            Log.e(TAG, "failed to read entity from restore data", e);
         }
         try {
             key = backupKeyToKey(backupKey);
+            mKeys.add(key);
             switch (key.type) {
                 case Key.FAVORITE:
                     restoreFavorite(key, buffer, dataSize, mKeys);
@@ -295,10 +301,13 @@
                 final long updateTime = cursor.getLong(ID_MODIFIED);
                 Key key = getKey(Key.FAVORITE, id);
                 keys.add(key);
-                currentIds.add(keyToBackupKey(key));
-                if (updateTime > in.t) {
+                final String backupKey = keyToBackupKey(key);
+                currentIds.add(backupKey);
+                if (!savedIds.contains(backupKey) || updateTime >= in.t) {
                     byte[] blob = packFavorite(cursor);
                     writeRowToBackup(key, blob, out, data);
+                } else {
+                    if (VERBOSE) Log.v(TAG, "favorite " + id + " was too old: " + updateTime);
                 }
             }
         } finally {
@@ -322,15 +331,21 @@
      * @param keys keys to mark as clean in the notes for next backup
      */
     private void restoreFavorite(Key key, byte[] buffer, int dataSize, ArrayList<Key> keys) {
-        Log.v(TAG, "unpacking favorite " + key.id + " (" + dataSize + " bytes)");
+        if (VERBOSE) Log.v(TAG, "unpacking favorite " + key.id);
         if (DEBUG) Log.d(TAG, "read (" + buffer.length + "): " +
                 Base64.encodeToString(buffer, 0, dataSize, Base64.NO_WRAP));
 
+        if (!mRestoreEnabled) {
+            if (VERBOSE) Log.v(TAG, "restore not enabled: skipping database mutation");
+            return;
+        }
+
         try {
-            Favorite favorite =  unpackFavorite(buffer, 0, dataSize);
-            if (DEBUG) Log.d(TAG, "unpacked " + favorite.itemType);
+            ContentResolver cr = mContext.getContentResolver();
+            ContentValues values = unpackFavorite(buffer, 0, dataSize);
+            cr.insert(Favorites.CONTENT_URI, values);
         } catch (InvalidProtocolBufferNanoException e) {
-            Log.w(TAG, "failed to decode proto", e);
+            Log.e(TAG, "failed to decode favorite", e);
         }
     }
 
@@ -358,15 +373,19 @@
         Set<String> currentIds = new HashSet<String>(cursor.getCount());
         try {
             cursor.moveToPosition(-1);
+            if (DEBUG) Log.d(TAG, "dumping screens after: " + in.t);
             while(cursor.moveToNext()) {
                 final long id = cursor.getLong(ID_INDEX);
                 final long updateTime = cursor.getLong(ID_MODIFIED);
                 Key key = getKey(Key.SCREEN, id);
                 keys.add(key);
-                currentIds.add(keyToBackupKey(key));
-                if (updateTime > in.t) {
+                final String backupKey = keyToBackupKey(key);
+                currentIds.add(backupKey);
+                if (!savedIds.contains(backupKey) || updateTime >= in.t) {
                     byte[] blob = packScreen(cursor);
                     writeRowToBackup(key, blob, out, data);
+                } else {
+                    if (VERBOSE) Log.v(TAG, "screen " + id + " was too old: " + updateTime);
                 }
             }
         } finally {
@@ -390,14 +409,22 @@
      * @param keys keys to mark as clean in the notes for next backup
      */
     private void restoreScreen(Key key, byte[] buffer, int dataSize, ArrayList<Key> keys) {
-        Log.v(TAG, "unpacking screen " + key.id);
+        if (VERBOSE) Log.v(TAG, "unpacking screen " + key.id);
         if (DEBUG) Log.d(TAG, "read (" + buffer.length + "): " +
                 Base64.encodeToString(buffer, 0, dataSize, Base64.NO_WRAP));
+
+        if (!mRestoreEnabled) {
+            if (VERBOSE) Log.v(TAG, "restore not enabled: skipping database mutation");
+            return;
+        }
+
         try {
-            Screen screen = unpackScreen(buffer, 0, dataSize);
-            if (DEBUG) Log.d(TAG, "unpacked " + screen.rank);
+            ContentResolver cr = mContext.getContentResolver();
+            ContentValues values = unpackScreen(buffer, 0, dataSize);
+            cr.insert(WorkspaceScreens.CONTENT_URI, values);
+
         } catch (InvalidProtocolBufferNanoException e) {
-            Log.w(TAG, "failed to decode proto", e);
+            Log.e(TAG, "failed to decode screen", e);
         }
     }
 
@@ -452,14 +479,14 @@
                         Log.w(TAG, "empty intent on application favorite: " + id);
                     }
                     if (savedIds.contains(backupKey)) {
-                        if (DEBUG) Log.d(TAG, "already saved icon " + backupKey);
+                        if (VERBOSE) Log.v(TAG, "already saved icon " + backupKey);
 
                         // remember that we already backed this up previously
                         keys.add(key);
                     } else if (backupKey != null) {
                         if (DEBUG) Log.d(TAG, "I can count this high: " + out.rows);
                         if ((out.rows - startRows) < MAX_ICONS_PER_PASS) {
-                            if (DEBUG) Log.d(TAG, "saving icon " + backupKey);
+                            if (VERBOSE) Log.v(TAG, "saving icon " + backupKey);
                             Bitmap icon = iconCache.getIcon(intent);
                             keys.add(key);
                             if (icon != null && !iconCache.isDefaultIcon(icon)) {
@@ -467,15 +494,15 @@
                                 writeRowToBackup(key, blob, out, data);
                             }
                         } else {
-                            if (DEBUG) Log.d(TAG, "scheduling another run for icon " + backupKey);
+                            if (VERBOSE) Log.d(TAG, "deferring icon backup " + backupKey);
                             // too many icons for this pass, request another.
                             dataChanged();
                         }
                     }
                 } catch (URISyntaxException e) {
-                    Log.w(TAG, "invalid URI on application favorite: " + id);
+                    Log.e(TAG, "invalid URI on application favorite: " + id);
                 } catch (IOException e) {
-                    Log.w(TAG, "unable to save application icon for favorite: " + id);
+                    Log.e(TAG, "unable to save application icon for favorite: " + id);
                 }
 
             }
@@ -500,21 +527,28 @@
      * @param keys keys to mark as clean in the notes for next backup
      */
     private void restoreIcon(Key key, byte[] buffer, int dataSize, ArrayList<Key> keys) {
-        Log.v(TAG, "unpacking icon " + key.id);
+        if (VERBOSE) Log.v(TAG, "unpacking icon " + key.id);
         if (DEBUG) Log.d(TAG, "read (" + buffer.length + "): " +
                 Base64.encodeToString(buffer, 0, dataSize, Base64.NO_WRAP));
         try {
             Resource res = unpackIcon(buffer, 0, dataSize);
-            if (DEBUG) Log.d(TAG, "unpacked " + res.dpi);
-            if (DEBUG) Log.d(TAG, "read " +
+            if (DEBUG) Log.d(TAG, "unpacked " + res.dpi + " dpi icon");
+            if (DEBUG_PAYLOAD) Log.d(TAG, "read " +
                     Base64.encodeToString(res.data, 0, res.data.length,
                             Base64.NO_WRAP));
             Bitmap icon = BitmapFactory.decodeByteArray(res.data, 0, res.data.length);
             if (icon == null) {
                 Log.w(TAG, "failed to unpack icon for " + key.name);
             }
+
+            if (!mRestoreEnabled) {
+                if (VERBOSE) Log.v(TAG, "restore not enabled: skipping database mutation");
+                return;
+            } else {
+                // future site of icon cache mutation
+            }
         } catch (InvalidProtocolBufferNanoException e) {
-            Log.w(TAG, "failed to decode proto", e);
+            Log.e(TAG, "failed to decode icon", e);
         }
     }
 
@@ -573,14 +607,14 @@
                     Log.w(TAG, "empty intent on appwidget: " + id);
                 }
                 if (savedIds.contains(backupKey)) {
-                    if (DEBUG) Log.d(TAG, "already saved widget " + backupKey);
+                    if (VERBOSE) Log.v(TAG, "already saved widget " + backupKey);
 
                     // remember that we already backed this up previously
                     keys.add(key);
                 } else if (backupKey != null) {
                     if (DEBUG) Log.d(TAG, "I can count this high: " + out.rows);
                     if ((out.rows - startRows) < MAX_WIDGETS_PER_PASS) {
-                        if (DEBUG) Log.d(TAG, "saving widget " + backupKey);
+                        if (VERBOSE) Log.v(TAG, "saving widget " + backupKey);
                         previewLoader.setPreviewSize(spanX * profile.cellWidthPx,
                                 spanY * profile.cellHeightPx, widgetSpacingLayout);
                         byte[] blob = packWidget(dpi, previewLoader, iconCache, provider);
@@ -588,7 +622,7 @@
                         writeRowToBackup(key, blob, out, data);
 
                     } else {
-                        if (DEBUG) Log.d(TAG, "scheduling another run for widget " + backupKey);
+                        if (VERBOSE) Log.d(TAG, "deferring widget backup " + backupKey);
                         // too many widgets for this pass, request another.
                         dataChanged();
                     }
@@ -615,7 +649,7 @@
      * @param keys keys to mark as clean in the notes for next backup
      */
     private void restoreWidget(Key key, byte[] buffer, int dataSize, ArrayList<Key> keys) {
-        Log.v(TAG, "unpacking widget " + key.id);
+        if (VERBOSE) Log.v(TAG, "unpacking widget " + key.id);
         if (DEBUG) Log.d(TAG, "read (" + buffer.length + "): " +
                 Base64.encodeToString(buffer, 0, dataSize, Base64.NO_WRAP));
         try {
@@ -628,8 +662,15 @@
                     Log.w(TAG, "failed to unpack widget icon for " + key.name);
                 }
             }
+
+            if (!mRestoreEnabled) {
+                if (VERBOSE) Log.v(TAG, "restore not enabled: skipping database mutation");
+                return;
+            } else {
+                // future site of widget table mutation
+            }
         } catch (InvalidProtocolBufferNanoException e) {
-            Log.w(TAG, "failed to decode proto", e);
+            Log.e(TAG, "failed to decode widget", e);
         }
     }
 
@@ -764,11 +805,44 @@
     }
 
     /** Deserialize a Favorite from persistence, after verifying checksum wrapper. */
-    private Favorite unpackFavorite(byte[] buffer, int offset, int dataSize)
+    private ContentValues unpackFavorite(byte[] buffer, int offset, int dataSize)
             throws InvalidProtocolBufferNanoException {
         Favorite favorite = new Favorite();
         MessageNano.mergeFrom(favorite, readCheckedBytes(buffer, offset, dataSize));
-        return favorite;
+        if (VERBOSE) Log.v(TAG, "unpacked favorite " + favorite.itemType + ", " +
+                (TextUtils.isEmpty(favorite.title) ? favorite.id : favorite.title));
+        ContentValues values = new ContentValues();
+        values.put(Favorites._ID, favorite.id);
+        values.put(Favorites.SCREEN, favorite.screen);
+        values.put(Favorites.CONTAINER, favorite.container);
+        values.put(Favorites.CELLX, favorite.cellX);
+        values.put(Favorites.CELLY, favorite.cellY);
+        values.put(Favorites.SPANX, favorite.spanX);
+        values.put(Favorites.SPANY, favorite.spanY);
+        values.put(Favorites.ICON_TYPE, favorite.iconType);
+        if (favorite.iconType == Favorites.ICON_TYPE_RESOURCE) {
+            values.put(Favorites.ICON_PACKAGE, favorite.iconPackage);
+            values.put(Favorites.ICON_RESOURCE, favorite.iconResource);
+        }
+        if (favorite.iconType == Favorites.ICON_TYPE_BITMAP) {
+            values.put(Favorites.ICON, favorite.icon);
+        }
+        if (!TextUtils.isEmpty(favorite.title)) {
+            values.put(Favorites.TITLE, favorite.title);
+        } else {
+            values.put(Favorites.TITLE, "");
+        }
+        if (!TextUtils.isEmpty(favorite.intent)) {
+            values.put(Favorites.INTENT, favorite.intent);
+        }
+        values.put(Favorites.ITEM_TYPE, favorite.itemType);
+        if (favorite.itemType == Favorites.ITEM_TYPE_APPWIDGET) {
+            if (!TextUtils.isEmpty(favorite.appWidgetProvider)) {
+                values.put(Favorites.APPWIDGET_PROVIDER, favorite.appWidgetProvider);
+            }
+            values.put(Favorites.APPWIDGET_ID, favorite.appWidgetId);
+        }
+        return values;
     }
 
     /** Serialize a Screen for persistence, including a checksum wrapper. */
@@ -781,11 +855,15 @@
     }
 
     /** Deserialize a Screen from persistence, after verifying checksum wrapper. */
-    private Screen unpackScreen(byte[] buffer, int offset, int dataSize)
+    private ContentValues unpackScreen(byte[] buffer, int offset, int dataSize)
             throws InvalidProtocolBufferNanoException {
         Screen screen = new Screen();
         MessageNano.mergeFrom(screen, readCheckedBytes(buffer, offset, dataSize));
-        return screen;
+        if (VERBOSE) Log.v(TAG, "unpacked screen " + screen.id + "/" + screen.rank);
+        ContentValues values = new ContentValues();
+        values.put(WorkspaceScreens._ID, screen.id);
+        values.put(WorkspaceScreens.SCREEN_RANK, screen.rank);
+        return values;
     }
 
     /** Serialize an icon Resource for persistence, including a checksum wrapper. */
@@ -804,6 +882,7 @@
             throws InvalidProtocolBufferNanoException {
         Resource res = new Resource();
         MessageNano.mergeFrom(res, readCheckedBytes(buffer, offset, dataSize));
+        if (VERBOSE) Log.v(TAG, "unpacked icon " + res.dpi + "/" + res.data.length);
         return res;
     }
 
@@ -842,6 +921,7 @@
             throws InvalidProtocolBufferNanoException {
         Widget widget = new Widget();
         MessageNano.mergeFrom(widget, readCheckedBytes(buffer, offset, dataSize));
+        if (VERBOSE) Log.v(TAG, "unpacked widget " + widget.provider);
         return widget;
     }
 
@@ -852,7 +932,7 @@
      * in that case, do a full backup.
      *
      * @param oldState the read-0only file descriptor pointing to the old journal
-     * @return a Journal protocol bugffer
+     * @return a Journal protocol buffer
      */
     private Journal readJournal(ParcelFileDescriptor oldState) {
         Journal journal = new Journal();
@@ -861,47 +941,61 @@
         }
         FileInputStream inStream = new FileInputStream(oldState.getFileDescriptor());
         try {
-            int remaining = inStream.available();
-            if (DEBUG) Log.d(TAG, "available " + remaining);
-            if (remaining < MAX_JOURNAL_SIZE) {
-                byte[] buffer = new byte[remaining];
+            int availableBytes = inStream.available();
+            if (DEBUG) Log.d(TAG, "available " + availableBytes);
+            if (availableBytes < MAX_JOURNAL_SIZE) {
+                byte[] buffer = new byte[availableBytes];
                 int bytesRead = 0;
-                while (remaining > 0) {
+                boolean valid = false;
+                InvalidProtocolBufferNanoException lastProtoException = null;
+                while (availableBytes > 0) {
                     try {
-                        int result = inStream.read(buffer, bytesRead, remaining);
+                        // OMG what are you doing? This is crazy inefficient!
+                        // If we read a byte that is not ours, we will cause trouble: b/12491813
+                        // However, we don't know how many bytes to expect (oops).
+                        // So we have to step through *slowly*, watching for the end.
+                        int result = inStream.read(buffer, bytesRead, 1);
                         if (result > 0) {
-                            if (DEBUG) Log.d(TAG, "read some bytes: " + result);
-                            remaining -= result;
+                            availableBytes -= result;
                             bytesRead += result;
+                            if (DEBUG && (bytesRead % 100 == 0)) {
+                                Log.d(TAG, "read some bytes: " + bytesRead);
+                            }
                         } else {
-                            // stop reading ands see what there is to parse
-                            Log.w(TAG, "read error: " + result);
-                            remaining = 0;
+                            Log.w(TAG, "unexpected end of file while reading journal.");
+                            // stop reading and see what there is to parse
+                            availableBytes = 0;
                         }
                     } catch (IOException e) {
-                        Log.w(TAG, "failed to read the journal", e);
                         buffer = null;
-                        remaining = 0;
+                        availableBytes = 0;
                     }
-                }
-                if (DEBUG) Log.d(TAG, "journal bytes read: " + bytesRead);
 
-                if (buffer != null) {
+                    // check the buffer to see if we have a valid journal
                     try {
                         MessageNano.mergeFrom(journal, readCheckedBytes(buffer, 0, bytesRead));
+                        // if we are here, then we have read a valid, checksum-verified journal
+                        valid = true;
+                        availableBytes = 0;
+                        if (VERBOSE) Log.v(TAG, "read " + bytesRead + " bytes of journal");
                     } catch (InvalidProtocolBufferNanoException e) {
-                        Log.d(TAG, "failed to read the journal", e);
+                        // if we don't have the whole journal yet, mergeFrom will throw. keep going.
+                        lastProtoException = e;
                         journal.clear();
                     }
                 }
+                if (DEBUG) Log.d(TAG, "journal bytes read: " + bytesRead);
+                if (!valid) {
+                    Log.w(TAG, "could not find a valid journal", lastProtoException);
+                }
             }
         } catch (IOException e) {
-            Log.d(TAG, "failed to close the journal", e);
+            Log.w(TAG, "failed to close the journal", e);
         } finally {
             try {
                 inStream.close();
             } catch (IOException e) {
-                Log.d(TAG, "failed to close the journal", e);
+                Log.w(TAG, "failed to close the journal", e);
             }
         }
         return journal;
@@ -914,7 +1008,7 @@
         data.writeEntityData(blob, blob.length);
         out.rows++;
         out.bytes += blob.length;
-        Log.v(TAG, "saving " + geKeyType(key) + " " + backupKey + ": " +
+        if (VERBOSE) Log.v(TAG, "saving " + geKeyType(key) + " " + backupKey + ": " +
                 getKeyName(key) + "/" + blob.length);
         if(DEBUG_PAYLOAD) {
             String encoded = Base64.encodeToString(blob, 0, blob.length, Base64.NO_WRAP);
@@ -922,7 +1016,7 @@
             for (int offset = 0; offset < encoded.length(); offset += chunkSize) {
                 int end = offset + chunkSize;
                 end = Math.min(end, encoded.length());
-                Log.d(TAG, "wrote " + encoded.substring(offset, end));
+                Log.w(TAG, "wrote " + encoded.substring(offset, end));
             }
         }
     }
@@ -942,7 +1036,7 @@
             throws IOException {
         int rows = 0;
         for(String deleted: deletedIds) {
-            Log.v(TAG, "dropping icon " + deleted);
+            if (VERBOSE) Log.v(TAG, "dropping deleted item " + deleted);
             data.writeEntityHeader(deleted, -1);
             rows++;
         }
@@ -962,10 +1056,12 @@
         FileOutputStream outStream = null;
         try {
             outStream = new FileOutputStream(newState.getFileDescriptor());
-            outStream.write(writeCheckedBytes(journal));
+            final byte[] journalBytes = writeCheckedBytes(journal);
+            outStream.write(journalBytes);
             outStream.close();
+            if (VERBOSE) Log.v(TAG, "wrote " + journalBytes.length + " bytes of journal");
         } catch (IOException e) {
-            Log.d(TAG, "failed to write backup journal", e);
+            Log.w(TAG, "failed to write backup journal", e);
         }
     }
 
diff --git a/src/com/android/launcher3/LauncherClings.java b/src/com/android/launcher3/LauncherClings.java
new file mode 100644
index 0000000..00711fe
--- /dev/null
+++ b/src/com/android/launcher3/LauncherClings.java
@@ -0,0 +1,456 @@
+/*
+ * Copyright (C) 2008 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.launcher3;
+
+import android.accounts.Account;
+import android.accounts.AccountManager;
+import android.animation.Animator;
+import android.animation.AnimatorListenerAdapter;
+import android.app.ActivityManager;
+import android.content.Context;
+import android.content.SharedPreferences;
+import android.graphics.Rect;
+import android.os.Bundle;
+import android.os.UserManager;
+import android.view.LayoutInflater;
+import android.view.View;
+import android.view.ViewGroup;
+import android.view.accessibility.AccessibilityManager;
+import android.widget.TextView;
+
+class LauncherClings {
+    private static final String FIRST_RUN_CLING_DISMISSED_KEY = "cling_gel.first_run.dismissed";
+    private static final String MIGRATION_CLING_DISMISSED_KEY = "cling_gel.migration.dismissed";
+    private static final String MIGRATION_WORKSPACE_CLING_DISMISSED_KEY =
+            "cling_gel.migration_workspace.dismissed";
+    private static final String WORKSPACE_CLING_DISMISSED_KEY = "cling_gel.workspace.dismissed";
+    private static final String FOLDER_CLING_DISMISSED_KEY = "cling_gel.folder.dismissed";
+
+    private static final boolean DISABLE_CLINGS = false;
+    private static final boolean DISABLE_CUSTOM_CLINGS = true;
+
+    private static final int SHOW_CLING_DURATION = 250;
+    private static final int DISMISS_CLING_DURATION = 200;
+
+    private Launcher mLauncher;
+    private LayoutInflater mInflater;
+    private HideFromAccessibilityHelper mHideFromAccessibilityHelper
+            = new HideFromAccessibilityHelper();
+
+    /** Ctor */
+    public LauncherClings(Launcher launcher) {
+        mLauncher = launcher;
+        mInflater = mLauncher.getLayoutInflater();
+    }
+
+    /** Initializes a cling */
+    private Cling initCling(int clingId, int scrimId, boolean animate,
+                            boolean dimNavBarVisibilty) {
+        Cling cling = (Cling) mLauncher.findViewById(clingId);
+        View scrim = null;
+        if (scrimId > 0) {
+            scrim = mLauncher.findViewById(scrimId);
+        }
+        if (cling != null) {
+            cling.init(mLauncher, scrim);
+            cling.show(animate, SHOW_CLING_DURATION);
+
+            if (dimNavBarVisibilty) {
+                cling.setSystemUiVisibility(cling.getSystemUiVisibility() |
+                        View.SYSTEM_UI_FLAG_LOW_PROFILE);
+            }
+        }
+        return cling;
+    }
+
+    /** Returns whether the clings are enabled or should be shown */
+    private boolean areClingsEnabled() {
+        if (DISABLE_CLINGS) {
+            return false;
+        }
+
+        // disable clings when running in a test harness
+        if(ActivityManager.isRunningInTestHarness()) return false;
+
+        // Disable clings for accessibility when explore by touch is enabled
+        final AccessibilityManager a11yManager = (AccessibilityManager) mLauncher.getSystemService(
+                Launcher.ACCESSIBILITY_SERVICE);
+        if (a11yManager.isTouchExplorationEnabled()) {
+            return false;
+        }
+
+        // Restricted secondary users (child mode) will potentially have very few apps
+        // seeded when they start up for the first time. Clings won't work well with that
+        boolean supportsLimitedUsers =
+                android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.JELLY_BEAN_MR2;
+        Account[] accounts = AccountManager.get(mLauncher).getAccounts();
+        if (supportsLimitedUsers && accounts.length == 0) {
+            UserManager um = (UserManager) mLauncher.getSystemService(Context.USER_SERVICE);
+            Bundle restrictions = um.getUserRestrictions();
+            if (restrictions.getBoolean(UserManager.DISALLOW_MODIFY_ACCOUNTS, false)) {
+                return false;
+            }
+        }
+        return true;
+    }
+
+    /** Returns whether the folder cling is visible. */
+    public boolean isFolderClingVisible() {
+        Cling cling = (Cling) mLauncher.findViewById(R.id.folder_cling);
+        if (cling != null) {
+            return cling.getVisibility() == View.VISIBLE;
+        }
+        return false;
+    }
+
+    private boolean skipCustomClingIfNoAccounts() {
+        Cling cling = (Cling) mLauncher.findViewById(R.id.workspace_cling);
+        boolean customCling = cling.getDrawIdentifier().equals("workspace_custom");
+        if (customCling) {
+            AccountManager am = AccountManager.get(mLauncher);
+            if (am == null) return false;
+            Account[] accounts = am.getAccountsByType("com.google");
+            return accounts.length == 0;
+        }
+        return false;
+    }
+
+    /** Updates the first run cling custom content hint */
+    private void setCustomContentHintVisibility(Cling cling, String ccHintStr, boolean visible,
+                                                boolean animate) {
+        final TextView ccHint = (TextView) cling.findViewById(R.id.custom_content_hint);
+        if (ccHint != null) {
+            if (visible && !ccHintStr.isEmpty()) {
+                ccHint.setText(ccHintStr);
+                ccHint.setVisibility(View.VISIBLE);
+                if (animate) {
+                    ccHint.setAlpha(0f);
+                    ccHint.animate().alpha(1f)
+                            .setDuration(SHOW_CLING_DURATION)
+                            .start();
+                } else {
+                    ccHint.setAlpha(1f);
+                }
+            } else {
+                if (animate) {
+                    ccHint.animate().alpha(0f)
+                            .setDuration(SHOW_CLING_DURATION)
+                            .setListener(new AnimatorListenerAdapter() {
+                                @Override
+                                public void onAnimationEnd(Animator animation) {
+                                    ccHint.setVisibility(View.GONE);
+                                }
+                            })
+                            .start();
+                } else {
+                    ccHint.setAlpha(0f);
+                    ccHint.setVisibility(View.GONE);
+                }
+            }
+        }
+    }
+
+    /** Updates the first run cling custom content hint */
+    public void updateCustomContentHintVisibility() {
+        Cling cling = (Cling) mLauncher.findViewById(R.id.first_run_cling);
+        String ccHintStr = mLauncher.getFirstRunCustomContentHint();
+
+        if (mLauncher.getWorkspace().hasCustomContent()) {
+            // Show the custom content hint if ccHintStr is not empty
+            if (cling != null) {
+                setCustomContentHintVisibility(cling, ccHintStr, true, true);
+            }
+        } else {
+            // Hide the custom content hint
+            if (cling != null) {
+                setCustomContentHintVisibility(cling, ccHintStr, false, true);
+            }
+        }
+    }
+
+    /** Updates the first run cling search bar hint. */
+    public void updateSearchBarHint(String hint) {
+        Cling cling = (Cling) mLauncher.findViewById(R.id.first_run_cling);
+        if (cling != null && cling.getVisibility() == View.VISIBLE && !hint.isEmpty()) {
+            TextView sbHint = (TextView) cling.findViewById(R.id.search_bar_hint);
+            sbHint.setText(hint);
+            sbHint.setVisibility(View.VISIBLE);
+        }
+    }
+
+    public boolean shouldShowFirstRunOrMigrationClings() {
+        SharedPreferences sharedPrefs = mLauncher.getSharedPrefs();
+        return areClingsEnabled() &&
+            !sharedPrefs.getBoolean(FIRST_RUN_CLING_DISMISSED_KEY, false) &&
+            !sharedPrefs.getBoolean(MIGRATION_CLING_DISMISSED_KEY, false) &&
+            LauncherAppState.getLauncherProvider().wasNewDbCreated();
+    }
+
+    public void removeFirstRunAndMigrationClings() {
+        removeCling(R.id.first_run_cling);
+        removeCling(R.id.migration_cling);
+    }
+
+    /**
+     * Shows the first run cling.
+     *
+     * This flow is mutually exclusive with showMigrationCling, and only runs if this Launcher
+     * package was preinstalled or there is no db to migrate from.
+     */
+    public void showFirstRunCling() {
+        if (!skipCustomClingIfNoAccounts()) {
+            SharedPreferences sharedPrefs = mLauncher.getSharedPrefs();
+            // If we're not using the default workspace layout, replace workspace cling
+            // with a custom workspace cling (usually specified in an overlay)
+            // For now, only do this on tablets
+            if (!DISABLE_CUSTOM_CLINGS) {
+                if (sharedPrefs.getInt(LauncherProvider.DEFAULT_WORKSPACE_RESOURCE_ID, 0) != 0 &&
+                        mLauncher.getResources().getBoolean(R.bool.config_useCustomClings)) {
+                    // Use a custom cling
+                    View cling = mLauncher.findViewById(R.id.workspace_cling);
+                    ViewGroup clingParent = (ViewGroup) cling.getParent();
+                    int clingIndex = clingParent.indexOfChild(cling);
+                    clingParent.removeViewAt(clingIndex);
+                    View customCling = mInflater.inflate(R.layout.custom_workspace_cling,
+                            clingParent, false);
+                    clingParent.addView(customCling, clingIndex);
+                    customCling.setId(R.id.workspace_cling);
+                }
+            }
+            Cling cling = (Cling) mLauncher.findViewById(R.id.first_run_cling);
+            if (cling != null) {
+                String sbHintStr = mLauncher.getFirstRunClingSearchBarHint();
+                String ccHintStr = mLauncher.getFirstRunCustomContentHint();
+                if (!sbHintStr.isEmpty()) {
+                    TextView sbHint = (TextView) cling.findViewById(R.id.search_bar_hint);
+                    sbHint.setText(sbHintStr);
+                    sbHint.setVisibility(View.VISIBLE);
+                }
+                setCustomContentHintVisibility(cling, ccHintStr, true, false);
+            }
+            initCling(R.id.first_run_cling, 0, false, true);
+        } else {
+            removeFirstRunAndMigrationClings();
+        }
+    }
+
+    /**
+     * Shows the migration cling.
+     *
+     * This flow is mutually exclusive with showFirstRunCling, and only runs if this Launcher
+     * package was not preinstalled and there exists a db to migrate from.
+     */
+    public void showMigrationCling() {
+        mLauncher.hideWorkspaceSearchAndHotseat();
+
+        Cling c = initCling(R.id.migration_cling, 0, false, true);
+        c.bringScrimToFront();
+        c.bringToFront();
+    }
+
+    public void showMigrationWorkspaceCling() {
+        // Enable the clings only if they have not been dismissed before
+        if (areClingsEnabled() && !mLauncher.getSharedPrefs().getBoolean(
+                MIGRATION_WORKSPACE_CLING_DISMISSED_KEY, false)) {
+            Cling c = initCling(R.id.migration_workspace_cling, 0, false, true);
+            c.updateMigrationWorkspaceBubblePosition();
+            c.bringScrimToFront();
+            c.bringToFront();
+        } else {
+            removeCling(R.id.migration_workspace_cling);
+        }
+    }
+
+    public void showWorkspaceCling() {
+        // Enable the clings only if they have not been dismissed before
+        if (areClingsEnabled() && !mLauncher.getSharedPrefs().getBoolean(
+                WORKSPACE_CLING_DISMISSED_KEY, false)) {
+            Cling c = initCling(R.id.workspace_cling, 0, false, true);
+            c.updateWorkspaceBubblePosition();
+
+            // Set the focused hotseat app if there is one
+            c.setFocusedHotseatApp(mLauncher.getFirstRunFocusedHotseatAppDrawableId(),
+                    mLauncher.getFirstRunFocusedHotseatAppRank(),
+                    mLauncher.getFirstRunFocusedHotseatAppComponentName(),
+                    mLauncher.getFirstRunFocusedHotseatAppBubbleTitle(),
+                    mLauncher.getFirstRunFocusedHotseatAppBubbleDescription());
+        } else {
+            removeCling(R.id.workspace_cling);
+        }
+    }
+    public Cling showFoldersCling() {
+        SharedPreferences sharedPrefs = mLauncher.getSharedPrefs();
+        // Enable the clings only if they have not been dismissed before
+        if (areClingsEnabled() &&
+                !sharedPrefs.getBoolean(FOLDER_CLING_DISMISSED_KEY, false) &&
+                !sharedPrefs.getBoolean(Launcher.USER_HAS_MIGRATED, false)) {
+            Cling cling = initCling(R.id.folder_cling, R.id.cling_scrim,
+                    true, true);
+            Folder openFolder = mLauncher.getWorkspace().getOpenFolder();
+            if (openFolder != null) {
+                Rect openFolderRect = new Rect();
+                openFolder.getHitRect(openFolderRect);
+                cling.setOpenFolderRect(openFolderRect);
+                openFolder.bringToFront();
+            }
+            return cling;
+        } else {
+            removeCling(R.id.folder_cling);
+            return null;
+        }
+    }
+
+    /** Removes the cling outright from the DragLayer */
+    private void removeCling(int id) {
+        final View cling = mLauncher.findViewById(id);
+        if (cling != null) {
+            final ViewGroup parent = (ViewGroup) cling.getParent();
+            parent.post(new Runnable() {
+                @Override
+                public void run() {
+                    parent.removeView(cling);
+                }
+            });
+            mHideFromAccessibilityHelper.restoreImportantForAccessibility(mLauncher.getDragLayer());
+        }
+    }
+
+    /** Hides the specified Cling */
+    private void dismissCling(final Cling cling, final Runnable postAnimationCb,
+                              final String flag, int duration, boolean restoreNavBarVisibilty) {
+        // To catch cases where siblings of top-level views are made invisible, just check whether
+        // the cling is directly set to GONE before dismissing it.
+        if (cling != null && cling.getVisibility() != View.GONE) {
+            final Runnable cleanUpClingCb = new Runnable() {
+                public void run() {
+                    cling.cleanup();
+                    SharedPreferences.Editor editor = mLauncher.getSharedPrefs().edit();
+                    editor.putBoolean(flag, true);
+                    editor.apply();
+                    if (postAnimationCb != null) {
+                        postAnimationCb.run();
+                    }
+                }
+            };
+            if (duration <= 0) {
+                cleanUpClingCb.run();
+            } else {
+                cling.hide(duration, cleanUpClingCb);
+            }
+            mHideFromAccessibilityHelper.restoreImportantForAccessibility(mLauncher.getDragLayer());
+
+            if (restoreNavBarVisibilty) {
+                cling.setSystemUiVisibility(cling.getSystemUiVisibility() &
+                        ~View.SYSTEM_UI_FLAG_LOW_PROFILE);
+            }
+        }
+    }
+
+    public void dismissFirstRunCling(View v) {
+        Cling cling = (Cling) mLauncher.findViewById(R.id.first_run_cling);
+        Runnable cb = new Runnable() {
+            public void run() {
+                // Show the workspace cling next
+                showWorkspaceCling();
+            }
+        };
+        dismissCling(cling, cb, FIRST_RUN_CLING_DISMISSED_KEY,
+                DISMISS_CLING_DURATION, false);
+
+        // Fade out the search bar for the workspace cling coming up
+        mLauncher.getSearchBar().hideSearchBar(true);
+    }
+
+    private void dismissMigrationCling() {
+        mLauncher.showWorkspaceSearchAndHotseat();
+        Runnable dismissCb = new Runnable() {
+            public void run() {
+                Cling cling = (Cling) mLauncher.findViewById(R.id.migration_cling);
+                Runnable cb = new Runnable() {
+                    public void run() {
+                        // Show the migration workspace cling next
+                        showMigrationWorkspaceCling();
+                    }
+                };
+                dismissCling(cling, cb, MIGRATION_CLING_DISMISSED_KEY,
+                        DISMISS_CLING_DURATION, true);
+            }
+        };
+        mLauncher.getWorkspace().post(dismissCb);
+    }
+
+    private void dismissAnyWorkspaceCling(Cling cling, String key, View v) {
+        Runnable cb = null;
+        if (v == null) {
+            cb = new Runnable() {
+                public void run() {
+                    mLauncher.getWorkspace().enterOverviewMode();
+                }
+            };
+        }
+        dismissCling(cling, cb, key, DISMISS_CLING_DURATION, true);
+
+        // Fade in the search bar
+        mLauncher.getSearchBar().showSearchBar(true);
+    }
+
+    public void dismissMigrationClingCopyApps(View v) {
+        // Copy the shortcuts from the old database
+        LauncherModel model = mLauncher.getModel();
+        model.resetLoadedState(false, true);
+        model.startLoader(false, PagedView.INVALID_RESTORE_PAGE,
+                LauncherModel.LOADER_FLAG_CLEAR_WORKSPACE
+                        | LauncherModel.LOADER_FLAG_MIGRATE_SHORTCUTS);
+
+        // Set the flag to skip the folder cling
+        String spKey = LauncherAppState.getSharedPreferencesKey();
+        SharedPreferences sp = mLauncher.getSharedPreferences(spKey, Context.MODE_PRIVATE);
+        SharedPreferences.Editor editor = sp.edit();
+        editor.putBoolean(Launcher.USER_HAS_MIGRATED, true);
+        editor.apply();
+
+        // Disable the migration cling
+        dismissMigrationCling();
+    }
+
+    public void dismissMigrationClingUseDefault(View v) {
+        // Clear the workspace
+        LauncherModel model = mLauncher.getModel();
+        model.resetLoadedState(false, true);
+        model.startLoader(false, PagedView.INVALID_RESTORE_PAGE,
+                LauncherModel.LOADER_FLAG_CLEAR_WORKSPACE);
+
+        // Disable the migration cling
+        dismissMigrationCling();
+    }
+
+    public void dismissMigrationWorkspaceCling(View v) {
+        Cling cling = (Cling) mLauncher.findViewById(R.id.migration_workspace_cling);
+        dismissAnyWorkspaceCling(cling, MIGRATION_WORKSPACE_CLING_DISMISSED_KEY, v);
+    }
+
+    public void dismissWorkspaceCling(View v) {
+        Cling cling = (Cling) mLauncher.findViewById(R.id.workspace_cling);
+        dismissAnyWorkspaceCling(cling, WORKSPACE_CLING_DISMISSED_KEY, v);
+    }
+
+    public void dismissFolderCling(View v) {
+        Cling cling = (Cling) mLauncher.findViewById(R.id.folder_cling);
+        dismissCling(cling, null, FOLDER_CLING_DISMISSED_KEY,
+                DISMISS_CLING_DURATION, true);
+    }
+}
diff --git a/src/com/android/launcher3/LauncherModel.java b/src/com/android/launcher3/LauncherModel.java
index 7e1442d..2102a1f 100644
--- a/src/com/android/launcher3/LauncherModel.java
+++ b/src/com/android/launcher3/LauncherModel.java
@@ -40,8 +40,10 @@
 import android.os.RemoteException;
 import android.os.SystemClock;
 import android.provider.BaseColumns;
+import android.text.TextUtils;
 import android.util.Log;
 import android.util.Pair;
+
 import com.android.launcher3.InstallWidgetReceiver.WidgetMimeTypeHandlerData;
 
 import java.lang.ref.WeakReference;
@@ -73,8 +75,15 @@
     // false = strew non-workspace apps across the workspace on upgrade
     public static final boolean UPGRADE_USE_MORE_APPS_FOLDER = false;
 
+    public static final int LOADER_FLAG_NONE = 0;
+    public static final int LOADER_FLAG_CLEAR_WORKSPACE = 1 << 0;
+    public static final int LOADER_FLAG_MIGRATE_SHORTCUTS = 1 << 1;
+
     private static final int ITEMS_CHUNK = 6; // batch size for the workspace icons
+    private static final long INVALID_SCREEN_ID = -1L;
+
     private final boolean mAppsCanBeOnRemoveableStorage;
+    private final boolean mOldContentProviderExists;
 
     private final LauncherAppState mApp;
     private final Object mLock = new Object();
@@ -165,8 +174,7 @@
                                   ArrayList<AppInfo> addedApps);
         public void bindAppsUpdated(ArrayList<AppInfo> apps);
         public void bindComponentsRemoved(ArrayList<String> packageNames,
-                        ArrayList<AppInfo> appInfos,
-                        boolean matchPackageNamesOnly);
+                        ArrayList<AppInfo> appInfos);
         public void bindPackagesUpdated(ArrayList<Object> widgetsAndShortcuts);
         public void bindSearchablesChanged();
         public boolean isAllAppsButtonRank(int rank);
@@ -179,16 +187,16 @@
     }
 
     LauncherModel(LauncherAppState app, IconCache iconCache, AppFilter appFilter) {
-        final Context context = app.getContext();
+        Context context = app.getContext();
+        ContentResolver contentResolver = context.getContentResolver();
 
         mAppsCanBeOnRemoveableStorage = Environment.isExternalStorageRemovable();
+        mOldContentProviderExists = (contentResolver.acquireContentProviderClient(
+                LauncherSettings.Favorites.OLD_CONTENT_URI) != null);
         mApp = app;
         mBgAllAppsList = new AllAppsList(iconCache, appFilter);
         mIconCache = iconCache;
 
-        mDefaultIcon = Utilities.createIconBitmap(
-                mIconCache.getFullResDefaultActivityIcon(), context);
-
         final Resources res = context.getResources();
         Configuration config = res.getConfiguration();
         mPreviousConfigMcc = config.mcc;
@@ -219,6 +227,10 @@
         }
     }
 
+    boolean canMigrateFromOldLauncherDb(Launcher launcher) {
+        return mOldContentProviderExists && !launcher.isLauncherPreinstalled() ;
+    }
+
     static boolean findNextAvailableIconSpaceInScreen(ArrayList<ItemInfo> items, int[] xy,
                                  long screen) {
         LauncherAppState app = LauncherAppState.getInstance();
@@ -286,7 +298,10 @@
         addAndBindAddedApps(context, workspaceApps, cb, allAppsApps);
     }
     public void addAndBindAddedApps(final Context context, final ArrayList<ItemInfo> workspaceApps,
-                                    final Callbacks callbacks, final ArrayList<AppInfo> allAppsApps) {
+                                final Callbacks callbacks, final ArrayList<AppInfo> allAppsApps) {
+        if (workspaceApps == null || allAppsApps == null) {
+            throw new RuntimeException("workspaceApps and allAppsApps must not be null");
+        }
         if (workspaceApps.isEmpty() && allAppsApps.isEmpty()) {
             return;
         }
@@ -400,6 +415,11 @@
     }
 
     public Bitmap getFallbackIcon() {
+        if (mDefaultIcon == null) {
+            final Context context = LauncherAppState.getInstance().getContext();
+            mDefaultIcon = Utilities.createIconBitmap(
+                    mIconCache.getFullResDefaultActivityIcon(), context);
+        }
         return Bitmap.createBitmap(mDefaultIcon);
     }
 
@@ -495,8 +515,7 @@
             if (stackTrace != null) {
                 e.setStackTrace(stackTrace);
             }
-            // TODO: something breaks this in the upgrade path
-            //throw e;
+            throw e;
         }
     }
 
@@ -580,8 +599,9 @@
             // as in Workspace.onDrop. Here, we just add/remove them from the list of items
             // that are on the desktop, as appropriate
             ItemInfo modelItem = sBgItemsIdMap.get(itemId);
-            if (modelItem.container == LauncherSettings.Favorites.CONTAINER_DESKTOP ||
-                    modelItem.container == LauncherSettings.Favorites.CONTAINER_HOTSEAT) {
+            if (modelItem != null &&
+                    (modelItem.container == LauncherSettings.Favorites.CONTAINER_DESKTOP ||
+                     modelItem.container == LauncherSettings.Favorites.CONTAINER_HOTSEAT)) {
                 switch (modelItem.itemType) {
                     case LauncherSettings.Favorites.ITEM_TYPE_APPLICATION:
                     case LauncherSettings.Favorites.ITEM_TYPE_SHORTCUT:
@@ -955,6 +975,10 @@
      * a list of screen ids in the order that they should appear.
      */
     void updateWorkspaceScreenOrder(Context context, final ArrayList<Long> screens) {
+        // Log to disk
+        Launcher.addDumpLog(TAG, "11683562 - updateWorkspaceScreenOrder()", true);
+        Launcher.addDumpLog(TAG, "11683562 -   screens: " + TextUtils.join(", ", screens), true);
+
         final ArrayList<Long> screensCopy = new ArrayList<Long>(screens);
         final ContentResolver cr = context.getContentResolver();
         final Uri uri = LauncherSettings.WorkspaceScreens.CONTENT_URI;
@@ -1077,15 +1101,29 @@
             }
 
         } else if (Intent.ACTION_EXTERNAL_APPLICATIONS_AVAILABLE.equals(action)) {
-            // First, schedule to add these apps back in.
+            final boolean replacing = intent.getBooleanExtra(Intent.EXTRA_REPLACING, false);
             String[] packages = intent.getStringArrayExtra(Intent.EXTRA_CHANGED_PACKAGE_LIST);
-            enqueuePackageUpdated(new PackageUpdatedTask(PackageUpdatedTask.OP_ADD, packages));
-            // Then, rebind everything.
-            startLoaderFromBackground();
+            if (!replacing) {
+                enqueuePackageUpdated(new PackageUpdatedTask(PackageUpdatedTask.OP_ADD, packages));
+                if (mAppsCanBeOnRemoveableStorage) {
+                    // Only rebind if we support removable storage.  It catches the case where
+                    // apps on the external sd card need to be reloaded
+                    startLoaderFromBackground();
+                }
+            } else {
+                // If we are replacing then just update the packages in the list
+                enqueuePackageUpdated(new PackageUpdatedTask(PackageUpdatedTask.OP_UPDATE,
+                        packages));
+            }
         } else if (Intent.ACTION_EXTERNAL_APPLICATIONS_UNAVAILABLE.equals(action)) {
-            String[] packages = intent.getStringArrayExtra(Intent.EXTRA_CHANGED_PACKAGE_LIST);
-            enqueuePackageUpdated(new PackageUpdatedTask(
-                        PackageUpdatedTask.OP_UNAVAILABLE, packages));
+            final boolean replacing = intent.getBooleanExtra(Intent.EXTRA_REPLACING, false);
+            if (!replacing) {
+                String[] packages = intent.getStringArrayExtra(Intent.EXTRA_CHANGED_PACKAGE_LIST);
+                enqueuePackageUpdated(new PackageUpdatedTask(
+                            PackageUpdatedTask.OP_UNAVAILABLE, packages));
+            }
+            // else, we are replacing the packages, so ignore this event and wait for
+            // EXTERNAL_APPLICATIONS_AVAILABLE to update the packages at that time
         } else if (Intent.ACTION_LOCALE_CHANGED.equals(action)) {
             // If we have changed locale we need to clear out the labels in all apps/workspace.
             forceReload();
@@ -1149,7 +1187,7 @@
             }
         }
         if (runLoader) {
-            startLoader(false, -1);
+            startLoader(false, PagedView.INVALID_RESTORE_PAGE);
         }
     }
 
@@ -1168,6 +1206,10 @@
     }
 
     public void startLoader(boolean isLaunching, int synchronousBindPage) {
+        startLoader(isLaunching, synchronousBindPage, LOADER_FLAG_NONE);
+    }
+
+    public void startLoader(boolean isLaunching, int synchronousBindPage, int loadFlags) {
         synchronized (mLock) {
             if (DEBUG_LOADERS) {
                 Log.d(TAG, "startLoader isLaunching=" + isLaunching);
@@ -1182,8 +1224,9 @@
                 // If there is already one running, tell it to stop.
                 // also, don't downgrade isLaunching if we're already running
                 isLaunching = isLaunching || stopLoaderLocked();
-                mLoaderTask = new LoaderTask(mApp.getContext(), isLaunching);
-                if (synchronousBindPage > -1 && mAllAppsLoaded && mWorkspaceLoaded) {
+                mLoaderTask = new LoaderTask(mApp.getContext(), isLaunching, loadFlags);
+                if (synchronousBindPage != PagedView.INVALID_RESTORE_PAGE
+                        && mAllAppsLoaded && mWorkspaceLoaded) {
                     mLoaderTask.runBindSynchronousPage(synchronousBindPage);
                 } else {
                     sWorkerThread.setPriority(Thread.NORM_PRIORITY);
@@ -1235,6 +1278,15 @@
         } finally {
             sc.close();
         }
+
+        // Log to disk
+        Launcher.addDumpLog(TAG, "11683562 - loadWorkspaceScreensDb()", true);
+        ArrayList<String> orderedScreensPairs= new ArrayList<String>();
+        for (Integer i : orderedScreens.keySet()) {
+            orderedScreensPairs.add("{ " + i + ": " + orderedScreens.get(i) + " }");
+        }
+        Launcher.addDumpLog(TAG, "11683562 -   screens: " +
+                TextUtils.join(", ", orderedScreensPairs), true);
         return orderedScreens;
     }
 
@@ -1263,13 +1315,15 @@
         private boolean mIsLoadingAndBindingWorkspace;
         private boolean mStopped;
         private boolean mLoadAndBindStepFinished;
+        private int mFlags;
 
         private HashMap<Object, CharSequence> mLabelCache;
 
-        LoaderTask(Context context, boolean isLaunching) {
+        LoaderTask(Context context, boolean isLaunching, int flags) {
             mContext = context;
             mIsLaunching = isLaunching;
             mLabelCache = new HashMap<Object, CharSequence>();
+            mFlags = flags;
         }
 
         boolean isLaunching() {
@@ -1342,7 +1396,7 @@
         }
 
         void runBindSynchronousPage(int synchronousBindPage) {
-            if (synchronousBindPage < 0) {
+            if (synchronousBindPage == PagedView.INVALID_RESTORE_PAGE) {
                 // Ensure that we have a valid page index to load synchronously
                 throw new RuntimeException("Should not call runBindSynchronousPage() without " +
                         "valid page index");
@@ -1431,7 +1485,7 @@
                 sBgDbIconCache.clear();
             }
 
-            if (AppsCustomizePagedView.DISABLE_ALL_APPS) {
+            if (LauncherAppState.isDisableAllApps()) {
                 // Ensure that all the applications that are in the system are
                 // represented on the home screen.
                 if (!UPGRADE_USE_MORE_APPS_FOLDER || !isUpgrade) {
@@ -1508,46 +1562,55 @@
             }
             if (!added.isEmpty()) {
                 Callbacks cb = mCallbacks != null ? mCallbacks.get() : null;
-                addAndBindAddedApps(context, added, cb, null);
+                addAndBindAddedApps(context, added, cb, new ArrayList<AppInfo>());
             }
         }
 
-        private boolean checkItemDimensions(ItemInfo info) {
-            LauncherAppState app = LauncherAppState.getInstance();
-            DeviceProfile grid = app.getDynamicGrid().getDeviceProfile();
-            return (info.cellX + info.spanX) > (int) grid.numColumns ||
-                    (info.cellY + info.spanY) > (int) grid.numRows;
-        }
-
         // check & update map of what's occupied; used to discard overlapping/invalid items
         private boolean checkItemPlacement(HashMap<Long, ItemInfo[][]> occupied, ItemInfo item,
-                                           AtomicBoolean deleteOnItemOverlap) {
+                                           AtomicBoolean deleteOnInvalidPlacement) {
             LauncherAppState app = LauncherAppState.getInstance();
             DeviceProfile grid = app.getDynamicGrid().getDeviceProfile();
-            int countX = (int) grid.numColumns;
-            int countY = (int) grid.numRows;
+            final int countX = (int) grid.numColumns;
+            final int countY = (int) grid.numRows;
 
             long containerIndex = item.screenId;
             if (item.container == LauncherSettings.Favorites.CONTAINER_HOTSEAT) {
                 // Return early if we detect that an item is under the hotseat button
                 if (mCallbacks == null ||
                         mCallbacks.get().isAllAppsButtonRank((int) item.screenId)) {
-                    deleteOnItemOverlap.set(true);
+                    deleteOnInvalidPlacement.set(true);
+                    Log.e(TAG, "Error loading shortcut into hotseat " + item
+                            + " into position (" + item.screenId + ":" + item.cellX + ","
+                            + item.cellY + ") occupied by all apps");
                     return false;
                 }
 
-                if (occupied.containsKey(LauncherSettings.Favorites.CONTAINER_HOTSEAT)) {
-                    if (occupied.get(LauncherSettings.Favorites.CONTAINER_HOTSEAT)
-                            [(int) item.screenId][0] != null) {
+                final ItemInfo[][] hotseatItems =
+                        occupied.get((long) LauncherSettings.Favorites.CONTAINER_HOTSEAT);
+
+                if (item.screenId >= grid.numHotseatIcons) {
+                    Log.e(TAG, "Error loading shortcut " + item
+                            + " into hotseat position " + item.screenId
+                            + ", position out of bounds: (0 to " + (grid.numHotseatIcons - 1)
+                            + ")");
+                    return false;
+                }
+
+                if (hotseatItems != null) {
+                    if (hotseatItems[(int) item.screenId][0] != null) {
                         Log.e(TAG, "Error loading shortcut into hotseat " + item
                                 + " into position (" + item.screenId + ":" + item.cellX + ","
                                 + item.cellY + ") occupied by "
                                 + occupied.get(LauncherSettings.Favorites.CONTAINER_HOTSEAT)
                                 [(int) item.screenId][0]);
                             return false;
+                    } else {
+                        hotseatItems[(int) item.screenId][0] = item;
+                        return true;
                     }
                 } else {
-                    ItemInfo[][] items = new ItemInfo[countX + 1][countY + 1];
+                    final ItemInfo[][] items = new ItemInfo[(int) grid.numHotseatIcons][1];
                     items[(int) item.screenId][0] = item;
                     occupied.put((long) LauncherSettings.Favorites.CONTAINER_HOTSEAT, items);
                     return true;
@@ -1562,7 +1625,17 @@
                 occupied.put(item.screenId, items);
             }
 
-            ItemInfo[][] screens = occupied.get(item.screenId);
+            final ItemInfo[][] screens = occupied.get(item.screenId);
+            if (item.container == LauncherSettings.Favorites.CONTAINER_DESKTOP &&
+                    item.cellX < 0 || item.cellY < 0 ||
+                    item.cellX + item.spanX > countX || item.cellY + item.spanY > countY) {
+                Log.e(TAG, "Error loading shortcut " + item
+                        + " into cell (" + containerIndex + "-" + item.screenId + ":"
+                        + item.cellX + "," + item.cellY
+                        + ") out of screen bounds ( " + countX + "x" + countY + ")");
+                return false;
+            }
+
             // Check if any workspace icons overlap with each other
             for (int x = item.cellX; x < (item.cellX+item.spanX); x++) {
                 for (int y = item.cellY; y < (item.cellY+item.spanY); y++) {
@@ -1597,8 +1670,11 @@
             }
         }
 
-        /** Returns whether this is an upgradge path */
+        /** Returns whether this is an upgrade path */
         private boolean loadWorkspace() {
+            // Log to disk
+            Launcher.addDumpLog(TAG, "11683562 - loadWorkspace()", true);
+
             final long t = DEBUG_LOADERS ? SystemClock.uptimeMillis() : 0;
 
             final Context context = mContext;
@@ -1612,12 +1688,28 @@
             int countX = (int) grid.numColumns;
             int countY = (int) grid.numRows;
 
-            // Make sure the default workspace is loaded, if needed
-            LauncherAppState.getLauncherProvider().loadDefaultFavoritesIfNecessary(0);
+            if ((mFlags & LOADER_FLAG_CLEAR_WORKSPACE) != 0) {
+                Launcher.addDumpLog(TAG, "loadWorkspace: resetting launcher database", true);
+                LauncherAppState.getLauncherProvider().deleteDatabase();
+            }
+
+            if ((mFlags & LOADER_FLAG_MIGRATE_SHORTCUTS) != 0) {
+                // append the user's Launcher2 shortcuts
+                Launcher.addDumpLog(TAG, "loadWorkspace: migrating from launcher2", true);
+                LauncherAppState.getLauncherProvider().migrateLauncher2Shortcuts();
+            } else {
+                // Make sure the default workspace is loaded
+                Launcher.addDumpLog(TAG, "loadWorkspace: loading default favorites", false);
+                LauncherAppState.getLauncherProvider().loadDefaultFavoritesIfNecessary(0);
+            }
 
             // Check if we need to do any upgrade-path logic
+            // (Includes having just imported default favorites)
             boolean loadedOldDb = LauncherAppState.getLauncherProvider().justLoadedOldDb();
 
+            // Log to disk
+            Launcher.addDumpLog(TAG, "11683562 -   loadedOldDb: " + loadedOldDb, true);
+
             synchronized (sBgLock) {
                 clearSBgDataStructures();
 
@@ -1674,7 +1766,7 @@
                     Intent intent;
 
                     while (!mStopped && c.moveToNext()) {
-                        AtomicBoolean deleteOnItemOverlap = new AtomicBoolean(false);
+                        AtomicBoolean deleteOnInvalidPlacement = new AtomicBoolean(false);
                         try {
                             int itemType = c.getInt(itemTypeIndex);
 
@@ -1735,18 +1827,11 @@
                                     info.cellY = c.getInt(cellYIndex);
                                     info.spanX = 1;
                                     info.spanY = 1;
-                                    // Skip loading items that are out of bounds
-                                    if (container == LauncherSettings.Favorites.CONTAINER_DESKTOP) {
-                                        if (checkItemDimensions(info)) {
-                                            Launcher.addDumpLog(TAG, "Skipped loading out of bounds shortcut: "
-                                                    + info + ", " + grid.numColumns + "x" + grid.numRows, true);
-                                            continue;
-                                        }
-                                    }
+
                                     // check & update map of what's occupied
-                                    deleteOnItemOverlap.set(false);
-                                    if (!checkItemPlacement(occupied, info, deleteOnItemOverlap)) {
-                                        if (deleteOnItemOverlap.get()) {
+                                    deleteOnInvalidPlacement.set(false);
+                                    if (!checkItemPlacement(occupied, info, deleteOnInvalidPlacement)) {
+                                        if (deleteOnInvalidPlacement.get()) {
                                             itemsToRemove.add(id);
                                         }
                                         break;
@@ -1788,18 +1873,11 @@
                                 folderInfo.spanX = 1;
                                 folderInfo.spanY = 1;
 
-                                // Skip loading items that are out of bounds
-                                if (container == LauncherSettings.Favorites.CONTAINER_DESKTOP) {
-                                    if (checkItemDimensions(folderInfo)) {
-                                        Log.d(TAG, "Skipped loading out of bounds folder");
-                                        continue;
-                                    }
-                                }
                                 // check & update map of what's occupied
-                                deleteOnItemOverlap.set(false);
+                                deleteOnInvalidPlacement.set(false);
                                 if (!checkItemPlacement(occupied, folderInfo,
-                                        deleteOnItemOverlap)) {
-                                    if (deleteOnItemOverlap.get()) {
+                                        deleteOnInvalidPlacement)) {
+                                    if (deleteOnInvalidPlacement.get()) {
                                         itemsToRemove.add(id);
                                     }
                                     break;
@@ -1855,18 +1933,11 @@
                                     }
 
                                     appWidgetInfo.container = c.getInt(containerIndex);
-                                    // Skip loading items that are out of bounds
-                                    if (container == LauncherSettings.Favorites.CONTAINER_DESKTOP) {
-                                        if (checkItemDimensions(appWidgetInfo)) {
-                                            Log.d(TAG, "Skipped loading out of bounds app widget");
-                                            continue;
-                                        }
-                                    }
                                     // check & update map of what's occupied
-                                    deleteOnItemOverlap.set(false);
+                                    deleteOnInvalidPlacement.set(false);
                                     if (!checkItemPlacement(occupied, appWidgetInfo,
-                                            deleteOnItemOverlap)) {
-                                        if (deleteOnItemOverlap.get()) {
+                                            deleteOnInvalidPlacement)) {
+                                        if (deleteOnInvalidPlacement.get()) {
                                             itemsToRemove.add(id);
                                         }
                                         break;
@@ -1886,7 +1957,7 @@
                                 break;
                             }
                         } catch (Exception e) {
-                            Launcher.addDumpLog(TAG, "Desktop items loading interrupted: " + e, true);
+                            Launcher.addDumpLog(TAG, "Desktop items loading interrupted", e, true);
                         }
                     }
                 } finally {
@@ -1933,6 +2004,10 @@
                         }
                     }
                     Collections.sort(sBgWorkspaceScreens);
+                    // Log to disk
+                    Launcher.addDumpLog(TAG, "11683562 -   maxScreenId: " + maxScreenId, true);
+                    Launcher.addDumpLog(TAG, "11683562 -   sBgWorkspaceScreens: " +
+                            TextUtils.join(", ", sBgWorkspaceScreens), true);
 
                     LauncherAppState.getLauncherProvider().updateMaxScreenId(maxScreenId);
                     updateWorkspaceScreenOrder(context, sBgWorkspaceScreens);
@@ -1949,6 +2024,9 @@
                     for (Integer i : orderedScreens.keySet()) {
                         sBgWorkspaceScreens.add(orderedScreens.get(i));
                     }
+                    // Log to disk
+                    Launcher.addDumpLog(TAG, "11683562 -   sBgWorkspaceScreens: " +
+                            TextUtils.join(", ", sBgWorkspaceScreens), true);
 
                     // Remove any empty screens
                     ArrayList<Long> unusedScreens = new ArrayList<Long>(sBgWorkspaceScreens);
@@ -1962,6 +2040,10 @@
 
                     // If there are any empty screens remove them, and update.
                     if (unusedScreens.size() != 0) {
+                        // Log to disk
+                        Launcher.addDumpLog(TAG, "11683562 -   unusedScreens (to be removed): " +
+                                TextUtils.join(", ", unusedScreens), true);
+
                         sBgWorkspaceScreens.removeAll(unusedScreens);
                         updateWorkspaceScreenOrder(context, sBgWorkspaceScreens);
                     }
@@ -1993,7 +2075,7 @@
 
         /** Filters the set of items who are directly or indirectly (via another container) on the
          * specified screen. */
-        private void filterCurrentWorkspaceItems(int currentScreen,
+        private void filterCurrentWorkspaceItems(long currentScreenId,
                 ArrayList<ItemInfo> allWorkspaceItems,
                 ArrayList<ItemInfo> currentScreenItems,
                 ArrayList<ItemInfo> otherScreenItems) {
@@ -2006,12 +2088,6 @@
                 }
             }
 
-            // If we aren't filtering on a screen, then the set of items to load is the full set of
-            // items given.
-            if (currentScreen < 0) {
-                currentScreenItems.addAll(allWorkspaceItems);
-            }
-
             // Order the set of items by their containers first, this allows use to walk through the
             // list sequentially, build up a list of containers that are in the specified screen,
             // as well as all items in those containers.
@@ -2024,7 +2100,7 @@
             });
             for (ItemInfo info : allWorkspaceItems) {
                 if (info.container == LauncherSettings.Favorites.CONTAINER_DESKTOP) {
-                    if (info.screenId == currentScreen) {
+                    if (info.screenId == currentScreenId) {
                         currentScreenItems.add(info);
                         itemsOnScreen.add(info.id);
                     } else {
@@ -2045,20 +2121,15 @@
         }
 
         /** Filters the set of widgets which are on the specified screen. */
-        private void filterCurrentAppWidgets(int currentScreen,
+        private void filterCurrentAppWidgets(long currentScreenId,
                 ArrayList<LauncherAppWidgetInfo> appWidgets,
                 ArrayList<LauncherAppWidgetInfo> currentScreenWidgets,
                 ArrayList<LauncherAppWidgetInfo> otherScreenWidgets) {
-            // If we aren't filtering on a screen, then the set of items to load is the full set of
-            // widgets given.
-            if (currentScreen < 0) {
-                currentScreenWidgets.addAll(appWidgets);
-            }
 
             for (LauncherAppWidgetInfo widget : appWidgets) {
                 if (widget == null) continue;
                 if (widget.container == LauncherSettings.Favorites.CONTAINER_DESKTOP &&
-                        widget.screenId == currentScreen) {
+                        widget.screenId == currentScreenId) {
                     currentScreenWidgets.add(widget);
                 } else {
                     otherScreenWidgets.add(widget);
@@ -2067,23 +2138,18 @@
         }
 
         /** Filters the set of folders which are on the specified screen. */
-        private void filterCurrentFolders(int currentScreen,
+        private void filterCurrentFolders(long currentScreenId,
                 HashMap<Long, ItemInfo> itemsIdMap,
                 HashMap<Long, FolderInfo> folders,
                 HashMap<Long, FolderInfo> currentScreenFolders,
                 HashMap<Long, FolderInfo> otherScreenFolders) {
-            // If we aren't filtering on a screen, then the set of items to load is the full set of
-            // widgets given.
-            if (currentScreen < 0) {
-                currentScreenFolders.putAll(folders);
-            }
 
             for (long id : folders.keySet()) {
                 ItemInfo info = itemsIdMap.get(id);
                 FolderInfo folder = folders.get(id);
                 if (info == null || folder == null) continue;
                 if (info.container == LauncherSettings.Favorites.CONTAINER_DESKTOP &&
-                        info.screenId == currentScreen) {
+                        info.screenId == currentScreenId) {
                     currentScreenFolders.put(id, folder);
                 } else {
                     otherScreenFolders.put(id, folder);
@@ -2210,13 +2276,7 @@
                 return;
             }
 
-            final boolean isLoadingSynchronously = (synchronizeBindPage > -1);
-            final int currentScreen = isLoadingSynchronously ? synchronizeBindPage :
-                oldCallbacks.getCurrentWorkspaceScreen();
-
-            // Load all the items that are on the current page first (and in the process, unbind
-            // all the existing workspace items before we call startBinding() below.
-            unbindWorkspaceItemsOnMainThread();
+            // Save a copy of all the bg-thread collections
             ArrayList<ItemInfo> workspaceItems = new ArrayList<ItemInfo>();
             ArrayList<LauncherAppWidgetInfo> appWidgets =
                     new ArrayList<LauncherAppWidgetInfo>();
@@ -2231,6 +2291,23 @@
                 orderedScreenIds.addAll(sBgWorkspaceScreens);
             }
 
+            final boolean isLoadingSynchronously =
+                    synchronizeBindPage != PagedView.INVALID_RESTORE_PAGE;
+            int currScreen = isLoadingSynchronously ? synchronizeBindPage :
+                oldCallbacks.getCurrentWorkspaceScreen();
+            if (currScreen >= orderedScreenIds.size()) {
+                // There may be no workspace screens (just hotseat items and an empty page).
+                currScreen = PagedView.INVALID_RESTORE_PAGE;
+            }
+            final int currentScreen = currScreen;
+            final long currentScreenId = currentScreen < 0
+                    ? INVALID_SCREEN_ID : orderedScreenIds.get(currentScreen);
+
+            // Load all the items that are on the current page first (and in the process, unbind
+            // all the existing workspace items before we call startBinding() below.
+            unbindWorkspaceItemsOnMainThread();
+
+            // Separate the items that are on the current screen, and all the other remaining items
             ArrayList<ItemInfo> currentWorkspaceItems = new ArrayList<ItemInfo>();
             ArrayList<ItemInfo> otherWorkspaceItems = new ArrayList<ItemInfo>();
             ArrayList<LauncherAppWidgetInfo> currentAppWidgets =
@@ -2240,12 +2317,11 @@
             HashMap<Long, FolderInfo> currentFolders = new HashMap<Long, FolderInfo>();
             HashMap<Long, FolderInfo> otherFolders = new HashMap<Long, FolderInfo>();
 
-            // Separate the items that are on the current screen, and all the other remaining items
-            filterCurrentWorkspaceItems(currentScreen, workspaceItems, currentWorkspaceItems,
+            filterCurrentWorkspaceItems(currentScreenId, workspaceItems, currentWorkspaceItems,
                     otherWorkspaceItems);
-            filterCurrentAppWidgets(currentScreen, appWidgets, currentAppWidgets,
+            filterCurrentAppWidgets(currentScreenId, appWidgets, currentAppWidgets,
                     otherAppWidgets);
-            filterCurrentFolders(currentScreen, itemsIdMap, folders, currentFolders,
+            filterCurrentFolders(currentScreenId, itemsIdMap, folders, currentFolders,
                     otherFolders);
             sortWorkspaceItemsSpatially(currentWorkspaceItems);
             sortWorkspaceItemsSpatially(otherWorkspaceItems);
@@ -2270,7 +2346,7 @@
                 r = new Runnable() {
                     public void run() {
                         Callbacks callbacks = tryGetCallbacks(oldCallbacks);
-                        if (callbacks != null) {
+                        if (callbacks != null && currentScreen != PagedView.INVALID_RESTORE_PAGE) {
                             callbacks.onPageBoundSynchronously(currentScreen);
                         }
                     }
@@ -2519,7 +2595,7 @@
             if (added != null) {
                 // Ensure that we add all the workspace applications to the db
                 Callbacks cb = mCallbacks != null ? mCallbacks.get() : null;
-                if (!AppsCustomizePagedView.DISABLE_ALL_APPS) {
+                if (!LauncherAppState.isDisableAllApps()) {
                     addAndBindAddedApps(context, new ArrayList<ItemInfo>(), cb, added);
                 } else {
                     final ArrayList<ItemInfo> addedInfos = new ArrayList<ItemInfo>(added);
@@ -2551,43 +2627,47 @@
                     }
                 });
             }
-            // If a package has been removed, or an app has been removed as a result of
-            // an update (for example), make the removed callback.
-            if (mOp == OP_REMOVE || !removedApps.isEmpty()) {
-                final boolean packageRemoved = (mOp == OP_REMOVE);
-                final ArrayList<String> removedPackageNames =
-                        new ArrayList<String>(Arrays.asList(packages));
 
-                // Update the launcher db to reflect the removal of apps
-                if (packageRemoved) {
-                    for (String pn : removedPackageNames) {
-                        ArrayList<ItemInfo> infos = getItemInfoForPackageName(pn);
-                        for (ItemInfo i : infos) {
-                            deleteItemFromDatabase(context, i);
-                        }
-                    }
-
-                    // Remove any queued items from the install queue
-                    String spKey = LauncherAppState.getSharedPreferencesKey();
-                    SharedPreferences sp =
-                            context.getSharedPreferences(spKey, Context.MODE_PRIVATE);
-                    InstallShortcutReceiver.removeFromInstallQueue(sp, removedPackageNames);
-                } else {
-                    for (AppInfo a : removedApps) {
-                        ArrayList<ItemInfo> infos =
-                                getItemInfoForComponentName(a.componentName);
-                        for (ItemInfo i : infos) {
-                            deleteItemFromDatabase(context, i);
-                        }
+            final ArrayList<String> removedPackageNames =
+                    new ArrayList<String>();
+            if (mOp == OP_REMOVE) {
+                // Mark all packages in the broadcast to be removed
+                removedPackageNames.addAll(Arrays.asList(packages));
+            } else if (mOp == OP_UPDATE) {
+                // Mark disabled packages in the broadcast to be removed
+                final PackageManager pm = context.getPackageManager();
+                for (int i=0; i<N; i++) {
+                    if (isPackageDisabled(pm, packages[i])) {
+                        removedPackageNames.add(packages[i]);
                     }
                 }
-
+            }
+            // Remove all the components associated with this package
+            for (String pn : removedPackageNames) {
+                ArrayList<ItemInfo> infos = getItemInfoForPackageName(pn);
+                for (ItemInfo i : infos) {
+                    deleteItemFromDatabase(context, i);
+                }
+            }
+            // Remove all the specific components
+            for (AppInfo a : removedApps) {
+                ArrayList<ItemInfo> infos = getItemInfoForComponentName(a.componentName);
+                for (ItemInfo i : infos) {
+                    deleteItemFromDatabase(context, i);
+                }
+            }
+            if (!removedPackageNames.isEmpty() || !removedApps.isEmpty()) {
+                // Remove any queued items from the install queue
+                String spKey = LauncherAppState.getSharedPreferencesKey();
+                SharedPreferences sp =
+                        context.getSharedPreferences(spKey, Context.MODE_PRIVATE);
+                InstallShortcutReceiver.removeFromInstallQueue(sp, removedPackageNames);
+                // Call the components-removed callback
                 mHandler.post(new Runnable() {
                     public void run() {
                         Callbacks cb = mCallbacks != null ? mCallbacks.get() : null;
                         if (callbacks == cb && cb != null) {
-                            callbacks.bindComponentsRemoved(removedPackageNames,
-                                    removedApps, packageRemoved);
+                            callbacks.bindComponentsRemoved(removedPackageNames, removedApps);
                         }
                     }
                 });
@@ -2629,19 +2709,27 @@
         return widgetsAndShortcuts;
     }
 
-    private boolean isValidPackageComponent(PackageManager pm, ComponentName cn) {
+    private static boolean isPackageDisabled(PackageManager pm, String packageName) {
+        try {
+            PackageInfo pi = pm.getPackageInfo(packageName, 0);
+            return !pi.applicationInfo.enabled;
+        } catch (NameNotFoundException e) {
+            // Fall through
+        }
+        return false;
+    }
+
+    public static boolean isValidPackageComponent(PackageManager pm, ComponentName cn) {
         if (cn == null) {
             return false;
         }
+        if (isPackageDisabled(pm, cn.getPackageName())) {
+            return false;
+        }
 
         try {
-            // Skip if the application is disabled
-            PackageInfo pi = pm.getPackageInfo(cn.getPackageName(), 0);
-            if (!pi.applicationInfo.enabled) {
-                return false;
-            }
-
             // Check the activity
+            PackageInfo pi = pm.getPackageInfo(cn.getPackageName(), 0);
             return (pm.getActivityInfo(cn, 0) != null);
         } catch (NameNotFoundException e) {
             return false;
diff --git a/src/com/android/launcher3/LauncherPreferencesBackupHelper.java b/src/com/android/launcher3/LauncherPreferencesBackupHelper.java
new file mode 100644
index 0000000..6f9c05c
--- /dev/null
+++ b/src/com/android/launcher3/LauncherPreferencesBackupHelper.java
@@ -0,0 +1,44 @@
+/*
+ * Copyright (C) 2014 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.launcher3;
+
+import android.app.backup.BackupDataInputStream;
+import android.app.backup.SharedPreferencesBackupHelper;
+import android.content.Context;
+import android.util.Log;
+
+public class LauncherPreferencesBackupHelper extends SharedPreferencesBackupHelper {
+
+    private static final String TAG = "LauncherPreferencesBackupHelper";
+    private static final boolean VERBOSE = LauncherBackupAgentHelper.VERBOSE;
+
+    private final boolean mRestoreEnabled;
+
+    public LauncherPreferencesBackupHelper(Context context,  String sharedPreferencesKey,
+            boolean restoreEnabled) {
+        super(context, sharedPreferencesKey);
+        mRestoreEnabled = restoreEnabled;
+    }
+
+    @Override
+    public void restoreEntity(BackupDataInputStream data) {
+        if (mRestoreEnabled) {
+            if (VERBOSE) Log.v(TAG, "restoring preferences");
+            super.restoreEntity(data);
+        }
+    }
+}
diff --git a/src/com/android/launcher3/LauncherProvider.java b/src/com/android/launcher3/LauncherProvider.java
index d0f6770..52bcf98 100644
--- a/src/com/android/launcher3/LauncherProvider.java
+++ b/src/com/android/launcher3/LauncherProvider.java
@@ -55,9 +55,11 @@
 import org.xmlpull.v1.XmlPullParser;
 import org.xmlpull.v1.XmlPullParserException;
 
+import java.io.File;
 import java.io.IOException;
 import java.net.URISyntaxException;
 import java.util.ArrayList;
+import java.util.HashSet;
 import java.util.List;
 
 public class LauncherProvider extends ContentProvider {
@@ -71,6 +73,9 @@
     static final String OLD_AUTHORITY = "com.android.launcher2.settings";
     static final String AUTHORITY = ProviderConfig.AUTHORITY;
 
+    // Should we attempt to load anything from the com.android.launcher2 provider?
+    static final boolean IMPORT_LAUNCHER2_DATABASE = false;
+
     static final String TABLE_FAVORITES = "favorites";
     static final String TABLE_WORKSPACE_SCREENS = "workspaceScreens";
     static final String PARAMETER_NOTIFY = "notify";
@@ -103,6 +108,10 @@
         return true;
     }
 
+    public boolean wasNewDbCreated() {
+        return mOpenHelper.wasNewDbCreated();
+    }
+
     @Override
     public String getType(Uri uri) {
         SqlArguments args = new SqlArguments(uri, null, null);
@@ -130,9 +139,13 @@
 
     private static long dbInsertAndCheck(DatabaseHelper helper,
             SQLiteDatabase db, String table, String nullColumnHack, ContentValues values) {
-        if (!values.containsKey(LauncherSettings.Favorites._ID)) {
+        if (values == null) {
+            throw new RuntimeException("Error: attempting to insert null values");
+        }
+        if (!values.containsKey(LauncherSettings.BaseLauncherColumns._ID)) {
             throw new RuntimeException("Error: attempting to add item without specifying an id");
         }
+        helper.checkId(table, values);
         return db.insert(table, nullColumnHack, values);
     }
 
@@ -263,11 +276,13 @@
         SharedPreferences sp = getContext().getSharedPreferences(spKey, Context.MODE_PRIVATE);
 
         if (sp.getBoolean(EMPTY_DATABASE_CREATED, false)) {
+            Log.d(TAG, "loading default workspace");
             int workspaceResId = origWorkspaceResId;
 
             // Use default workspace resource if none provided
             if (workspaceResId == 0) {
-                workspaceResId = sp.getInt(DEFAULT_WORKSPACE_RESOURCE_ID, R.xml.default_workspace);
+                workspaceResId =
+                        sp.getInt(DEFAULT_WORKSPACE_RESOURCE_ID, getDefaultWorkspaceResourceId());
             }
 
             // Populate favorites table with initial favorites
@@ -283,10 +298,41 @@
         }
     }
 
+    public void migrateLauncher2Shortcuts() {
+        mOpenHelper.migrateLauncher2Shortcuts(mOpenHelper.getWritableDatabase(),
+                LauncherSettings.Favorites.OLD_CONTENT_URI);
+    }
+
+    private static int getDefaultWorkspaceResourceId() {
+        if (LauncherAppState.isDisableAllApps()) {
+            return R.xml.default_workspace_no_all_apps;
+        } else {
+            return R.xml.default_workspace;
+        }
+    }
+
     private static interface ContentValuesCallback {
         public void onRow(ContentValues values);
     }
 
+    private static boolean shouldImportLauncher2Database(Context context) {
+        boolean isTablet = context.getResources().getBoolean(R.bool.is_tablet);
+
+        // We don't import the old databse for tablets, as the grid size has changed.
+        return !isTablet && IMPORT_LAUNCHER2_DATABASE;
+    }
+
+    public void deleteDatabase() {
+        // Are you sure? (y/n)
+        final SQLiteDatabase db = mOpenHelper.getWritableDatabase();
+        final File dbFile = new File(db.getPath());
+        mOpenHelper.close();
+        if (dbFile.exists()) {
+            SQLiteDatabase.deleteDatabase(dbFile);
+        }
+        mOpenHelper = new DatabaseHelper(getContext());
+    }
+
     private static class DatabaseHelper extends SQLiteOpenHelper {
         private static final String TAG_FAVORITES = "favorites";
         private static final String TAG_FAVORITE = "favorite";
@@ -303,6 +349,8 @@
         private long mMaxItemId = -1;
         private long mMaxScreenId = -1;
 
+        private boolean mNewDbCreated = false;
+
         DatabaseHelper(Context context) {
             super(context, DATABASE_NAME, null, DATABASE_VERSION);
             mContext = context;
@@ -318,6 +366,10 @@
             }
         }
 
+        public boolean wasNewDbCreated() {
+            return mNewDbCreated;
+        }
+
         /**
          * Send notification that we've deleted the {@link AppWidgetHost},
          * probably as part of the initial database creation. The receiver may
@@ -335,6 +387,7 @@
 
             mMaxItemId = 1;
             mMaxScreenId = 0;
+            mNewDbCreated = true;
 
             db.execSQL("CREATE TABLE favorites (" +
                     "_id INTEGER PRIMARY KEY," +
@@ -366,32 +419,38 @@
                 sendAppWidgetResetNotify();
             }
 
-            // Try converting the old database
-            ContentValuesCallback permuteScreensCb = new ContentValuesCallback() {
-                public void onRow(ContentValues values) {
-                    int container = values.getAsInteger(LauncherSettings.Favorites.CONTAINER);
-                    if (container == Favorites.CONTAINER_DESKTOP) {
-                        int screen = values.getAsInteger(LauncherSettings.Favorites.SCREEN);
-                        screen = (int) upgradeLauncherDb_permuteScreens(screen);
-                        values.put(LauncherSettings.Favorites.SCREEN, screen);
+            if (shouldImportLauncher2Database(mContext)) {
+                // Try converting the old database
+                ContentValuesCallback permuteScreensCb = new ContentValuesCallback() {
+                    public void onRow(ContentValues values) {
+                        int container = values.getAsInteger(LauncherSettings.Favorites.CONTAINER);
+                        if (container == Favorites.CONTAINER_DESKTOP) {
+                            int screen = values.getAsInteger(LauncherSettings.Favorites.SCREEN);
+                            screen = (int) upgradeLauncherDb_permuteScreens(screen);
+                            values.put(LauncherSettings.Favorites.SCREEN, screen);
+                        }
+                    }
+                };
+                Uri uri = Uri.parse("content://" + Settings.AUTHORITY +
+                        "/old_favorites?notify=true");
+                if (!convertDatabase(db, uri, permuteScreensCb, true)) {
+                    // Try and upgrade from the Launcher2 db
+                    uri = LauncherSettings.Favorites.OLD_CONTENT_URI;
+                    if (!convertDatabase(db, uri, permuteScreensCb, false)) {
+                        // If we fail, then set a flag to load the default workspace
+                        setFlagEmptyDbCreated();
+                        return;
                     }
                 }
-            };
-            Uri uri = Uri.parse("content://" + Settings.AUTHORITY +
-                    "/old_favorites?notify=true");
-            if (!convertDatabase(db, uri, permuteScreensCb, true)) {
-                // Try and upgrade from the Launcher2 db
-                uri = LauncherSettings.Favorites.OLD_CONTENT_URI;
-                if (!convertDatabase(db, uri, permuteScreensCb, false)) {
-                    // If we fail, then set a flag to load the default workspace
-                    setFlagEmptyDbCreated();
-                    return;
-                }
+                // Right now, in non-default workspace cases, we want to run the final
+                // upgrade code (ie. to fix workspace screen indices -> ids, etc.), so
+                // set that flag too.
+                setFlagJustLoadedOldDb();
+            } else {
+                // Fresh and clean launcher DB.
+                mMaxItemId = initializeMaxItemId(db);
+                setFlagEmptyDbCreated();
             }
-            // Right now, in non-default workspace cases, we want to run the final
-            // upgrade code (ie. to fix workspace screen indices -> ids, etc.), so
-            // set that flag too.
-            setFlagJustLoadedOldDb();
         }
 
         private void addWorkspacesTable(SQLiteDatabase db) {
@@ -838,6 +897,15 @@
             mMaxItemId = id + 1;
         }
 
+        public void checkId(String table, ContentValues values) {
+            long id = values.getAsLong(LauncherSettings.BaseLauncherColumns._ID);
+            if (table == LauncherProvider.TABLE_WORKSPACE_SCREENS) {
+                mMaxScreenId = Math.max(id, mMaxScreenId);
+            }  else {
+                mMaxItemId = Math.max(id, mMaxItemId);
+            }
+        }
+
         private long initializeMaxItemId(SQLiteDatabase db) {
             Cursor c = db.rawQuery("SELECT MAX(_id) FROM favorites", null);
 
@@ -868,10 +936,14 @@
                 throw new RuntimeException("Error: max screen id was not initialized");
             }
             mMaxScreenId += 1;
+            // Log to disk
+            Launcher.addDumpLog(TAG, "11683562 - generateNewScreenId(): " + mMaxScreenId, true);
             return mMaxScreenId;
         }
 
         public void updateMaxScreenId(long maxScreenId) {
+            // Log to disk
+            Launcher.addDumpLog(TAG, "11683562 - updateMaxScreenId(): " + maxScreenId, true);
             mMaxScreenId = maxScreenId;
         }
 
@@ -892,6 +964,8 @@
                 throw new RuntimeException("Error: could not query max screen id");
             }
 
+            // Log to disk
+            Launcher.addDumpLog(TAG, "11683562 - initializeMaxScreenId(): " + id, true);
             return id;
         }
 
@@ -1046,7 +1120,6 @@
                             // recursively load some more favorites, why not?
                             i += loadFavorites(db, resId);
                             added = false;
-                            mMaxItemId = -1;
                         } else {
                             Log.w(TAG, String.format("Skipping <include workspace=0x%08x>", resId));
                         }
@@ -1401,6 +1474,246 @@
             }
             return id;
         }
+
+        public void migrateLauncher2Shortcuts(SQLiteDatabase db, Uri uri) {
+            final ContentResolver resolver = mContext.getContentResolver();
+            Cursor c = null;
+            int count = 0;
+            int curScreen = 0;
+
+            try {
+                c = resolver.query(uri, null, null, null, "title ASC");
+            } catch (Exception e) {
+                // Ignore
+            }
+
+            // We already have a favorites database in the old provider
+            if (c != null) {
+                try {
+                    if (c.getCount() > 0) {
+                        final int idIndex = c.getColumnIndexOrThrow(LauncherSettings.Favorites._ID);
+                        final int intentIndex
+                                = c.getColumnIndexOrThrow(LauncherSettings.Favorites.INTENT);
+                        final int titleIndex
+                                = c.getColumnIndexOrThrow(LauncherSettings.Favorites.TITLE);
+                        final int iconTypeIndex
+                                = c.getColumnIndexOrThrow(LauncherSettings.Favorites.ICON_TYPE);
+                        final int iconIndex
+                                = c.getColumnIndexOrThrow(LauncherSettings.Favorites.ICON);
+                        final int iconPackageIndex
+                                = c.getColumnIndexOrThrow(LauncherSettings.Favorites.ICON_PACKAGE);
+                        final int iconResourceIndex
+                                = c.getColumnIndexOrThrow(LauncherSettings.Favorites.ICON_RESOURCE);
+                        final int containerIndex
+                                = c.getColumnIndexOrThrow(LauncherSettings.Favorites.CONTAINER);
+                        final int itemTypeIndex
+                                = c.getColumnIndexOrThrow(LauncherSettings.Favorites.ITEM_TYPE);
+                        final int screenIndex
+                                = c.getColumnIndexOrThrow(LauncherSettings.Favorites.SCREEN);
+                        final int cellXIndex
+                                = c.getColumnIndexOrThrow(LauncherSettings.Favorites.CELLX);
+                        final int cellYIndex
+                                = c.getColumnIndexOrThrow(LauncherSettings.Favorites.CELLY);
+                        final int uriIndex
+                                = c.getColumnIndexOrThrow(LauncherSettings.Favorites.URI);
+                        final int displayModeIndex
+                                = c.getColumnIndexOrThrow(LauncherSettings.Favorites.DISPLAY_MODE);
+
+                        int i = 0;
+                        int curX = 0;
+                        int curY = 0;
+
+                        final LauncherAppState app = LauncherAppState.getInstance();
+                        final DeviceProfile grid = app.getDynamicGrid().getDeviceProfile();
+                        final int width = (int) grid.numColumns;
+                        final int height = (int) grid.numRows;
+                        final int hotseatWidth = (int) grid.numHotseatIcons;
+                        PackageManager pm = mContext.getPackageManager();
+
+                        final HashSet<String> seenIntents = new HashSet<String>(c.getCount());
+
+                        final ArrayList<ContentValues> shortcuts = new ArrayList<ContentValues>();
+                        final ArrayList<ContentValues> folders = new ArrayList<ContentValues>();
+
+                        while (c.moveToNext()) {
+                            final int itemType = c.getInt(itemTypeIndex);
+                            if (itemType != Favorites.ITEM_TYPE_APPLICATION
+                                    && itemType != Favorites.ITEM_TYPE_SHORTCUT
+                                    && itemType != Favorites.ITEM_TYPE_FOLDER) {
+                                continue;
+                            }
+
+                            final int cellX = c.getInt(cellXIndex);
+                            final int cellY = c.getInt(cellYIndex);
+                            final int screen = c.getInt(screenIndex);
+                            int container = c.getInt(containerIndex);
+                            final String intentStr = c.getString(intentIndex);
+                            Launcher.addDumpLog(TAG, "migrating \""
+                                + c.getString(titleIndex) + "\": " + intentStr, true);
+
+                            if (itemType != Favorites.ITEM_TYPE_FOLDER) {
+
+                                final Intent intent;
+                                final ComponentName cn;
+                                try {
+                                    intent = Intent.parseUri(intentStr, 0);
+                                } catch (URISyntaxException e) {
+                                    // bogus intent?
+                                    Launcher.addDumpLog(TAG,
+                                            "skipping invalid intent uri", true);
+                                    continue;
+                                }
+
+                                cn = intent.getComponent();
+                                if (TextUtils.isEmpty(intentStr)) {
+                                    // no intent? no icon
+                                    Launcher.addDumpLog(TAG, "skipping empty intent", true);
+                                    continue;
+                                } else if (cn != null &&
+                                        !LauncherModel.isValidPackageComponent(pm, cn)) {
+                                    // component no longer exists.
+                                    Launcher.addDumpLog(TAG, "skipping item whose component " +
+                                            "no longer exists.", true);
+                                    continue;
+                                } else if (container ==
+                                        LauncherSettings.Favorites.CONTAINER_DESKTOP) {
+                                    // Dedupe icons directly on the workspace
+
+                                    // Canonicalize
+                                    // the Play Store sets the package parameter, but Launcher
+                                    // does not, so we clear that out to keep them the same
+                                    intent.setPackage(null);
+                                    final String key = intent.toUri(0);
+                                    if (seenIntents.contains(key)) {
+                                        Launcher.addDumpLog(TAG, "skipping duplicate", true);
+                                        continue;
+                                    } else {
+                                        seenIntents.add(key);
+                                    }
+                                }
+                            }
+
+                            ContentValues values = new ContentValues(c.getColumnCount());
+                            values.put(LauncherSettings.Favorites._ID, c.getInt(idIndex));
+                            values.put(LauncherSettings.Favorites.INTENT, intentStr);
+                            values.put(LauncherSettings.Favorites.TITLE, c.getString(titleIndex));
+                            values.put(LauncherSettings.Favorites.ICON_TYPE,
+                                    c.getInt(iconTypeIndex));
+                            values.put(LauncherSettings.Favorites.ICON, c.getBlob(iconIndex));
+                            values.put(LauncherSettings.Favorites.ICON_PACKAGE,
+                                    c.getString(iconPackageIndex));
+                            values.put(LauncherSettings.Favorites.ICON_RESOURCE,
+                                    c.getString(iconResourceIndex));
+                            values.put(LauncherSettings.Favorites.ITEM_TYPE, itemType);
+                            values.put(LauncherSettings.Favorites.APPWIDGET_ID, -1);
+                            values.put(LauncherSettings.Favorites.URI, c.getString(uriIndex));
+                            values.put(LauncherSettings.Favorites.DISPLAY_MODE,
+                                    c.getInt(displayModeIndex));
+
+                            if (container == LauncherSettings.Favorites.CONTAINER_HOTSEAT
+                                    && (screen >= hotseatWidth ||
+                                        screen == grid.hotseatAllAppsRank)) {
+                                // no room for you in the hotseat? it's off to the desktop with you
+                                container = Favorites.CONTAINER_DESKTOP;
+                            }
+
+                            if (container != LauncherSettings.Favorites.CONTAINER_DESKTOP) {
+                                // In a folder or in the hotseat, preserve position
+                                values.put(LauncherSettings.Favorites.SCREEN, screen);
+                                values.put(LauncherSettings.Favorites.CELLX, cellX);
+                                values.put(LauncherSettings.Favorites.CELLY, cellY);
+                            } else {
+                                // For items contained directly on one of the workspace screen,
+                                // we'll determine their location (screen, x, y) in a second pass.
+                            }
+
+                            values.put(LauncherSettings.Favorites.CONTAINER, container);
+
+                            if (itemType != Favorites.ITEM_TYPE_FOLDER) {
+                                shortcuts.add(values);
+                            } else {
+                                folders.add(values);
+                            }
+                        }
+
+                        final ArrayList<ContentValues> allItems = new ArrayList<ContentValues>();
+                        // Folders first
+                        allItems.addAll(folders);
+                        // Then shortcuts
+                        allItems.addAll(shortcuts);
+
+                        // Layout all the folders
+                        for (ContentValues values: allItems) {
+                            if (values.getAsInteger(LauncherSettings.Favorites.CONTAINER) !=
+                                    LauncherSettings.Favorites.CONTAINER_DESKTOP) {
+                                // Hotseat items and folder items have already had their
+                                // location information set. Nothing to be done here.
+                                continue;
+                            }
+                            values.put(LauncherSettings.Favorites.SCREEN, curScreen);
+                            values.put(LauncherSettings.Favorites.CELLX, curX);
+                            values.put(LauncherSettings.Favorites.CELLY, curY);
+                            curX = (curX + 1) % width;
+                            if (curX == 0) {
+                                curY = (curY + 1);
+                            }
+                            // Leave the last row of icons blank on every screen
+                            if (curY == height - 1) {
+                                curScreen = (int) generateNewScreenId();
+                                curY = 0;
+                            }
+                        }
+
+                        if (allItems.size() > 0) {
+                            db.beginTransaction();
+                            try {
+                                for (ContentValues row: allItems) {
+                                    if (row == null) continue;
+                                    if (dbInsertAndCheck(this, db, TABLE_FAVORITES, null, row)
+                                            < 0) {
+                                        return;
+                                    } else {
+                                        count++;
+                                    }
+                                }
+                                db.setTransactionSuccessful();
+                            } finally {
+                                db.endTransaction();
+                            }
+                        }
+
+                        db.beginTransaction();
+                        try {
+                            for (i=0; i<=curScreen; i++) {
+                                final ContentValues values = new ContentValues();
+                                values.put(LauncherSettings.WorkspaceScreens._ID, i);
+                                values.put(LauncherSettings.WorkspaceScreens.SCREEN_RANK, i);
+                                if (dbInsertAndCheck(this, db, TABLE_WORKSPACE_SCREENS, null, values)
+                                        < 0) {
+                                    return;
+                                }
+                            }
+                            db.setTransactionSuccessful();
+                        } finally {
+                            db.endTransaction();
+                        }
+                    }
+                } finally {
+                    c.close();
+                }
+            }
+
+            Launcher.addDumpLog(TAG, "migrated " + count + " icons from Launcher2 into "
+                    + (curScreen+1) + " screens", true);
+
+            // ensure that new screens are created to hold these icons
+            setFlagJustLoadedOldDb();
+
+            // Update max IDs; very important since we just grabbed IDs from another database
+            mMaxItemId = initializeMaxItemId(db);
+            mMaxScreenId = initializeMaxScreenId(db);
+            if (LOGD) Log.d(TAG, "mMaxItemId: " + mMaxItemId + " mMaxScreenId: " + mMaxScreenId);
+        }
     }
 
     /**
diff --git a/src/com/android/launcher3/LauncherScroller.java b/src/com/android/launcher3/LauncherScroller.java
new file mode 100644
index 0000000..3bd0a78
--- /dev/null
+++ b/src/com/android/launcher3/LauncherScroller.java
@@ -0,0 +1,559 @@
+/*
+ * Copyright (C) 2006 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.launcher3;
+
+import android.animation.TimeInterpolator;
+import android.content.Context;
+import android.hardware.SensorManager;
+import android.os.Build;
+import android.util.FloatMath;
+import android.view.ViewConfiguration;
+import android.view.animation.AnimationUtils;
+import android.view.animation.Interpolator;
+
+/**
+ * This class differs from the framework {@link android.widget.Scroller} in that
+ * you can modify the Interpolator post-construction.
+ */
+public class LauncherScroller  {
+    private int mMode;
+
+    private int mStartX;
+    private int mStartY;
+    private int mFinalX;
+    private int mFinalY;
+
+    private int mMinX;
+    private int mMaxX;
+    private int mMinY;
+    private int mMaxY;
+
+    private int mCurrX;
+    private int mCurrY;
+    private long mStartTime;
+    private int mDuration;
+    private float mDurationReciprocal;
+    private float mDeltaX;
+    private float mDeltaY;
+    private boolean mFinished;
+    private TimeInterpolator mInterpolator;
+    private boolean mFlywheel;
+
+    private float mVelocity;
+    private float mCurrVelocity;
+    private int mDistance;
+
+    private float mFlingFriction = ViewConfiguration.getScrollFriction();
+
+    private static final int DEFAULT_DURATION = 250;
+    private static final int SCROLL_MODE = 0;
+    private static final int FLING_MODE = 1;
+
+    private static float DECELERATION_RATE = (float) (Math.log(0.78) / Math.log(0.9));
+    private static final float INFLEXION = 0.35f; // Tension lines cross at (INFLEXION, 1)
+    private static final float START_TENSION = 0.5f;
+    private static final float END_TENSION = 1.0f;
+    private static final float P1 = START_TENSION * INFLEXION;
+    private static final float P2 = 1.0f - END_TENSION * (1.0f - INFLEXION);
+
+    private static final int NB_SAMPLES = 100;
+    private static final float[] SPLINE_POSITION = new float[NB_SAMPLES + 1];
+    private static final float[] SPLINE_TIME = new float[NB_SAMPLES + 1];
+
+    private float mDeceleration;
+    private final float mPpi;
+
+    // A context-specific coefficient adjusted to physical values.
+    private float mPhysicalCoeff;
+
+    static {
+        float x_min = 0.0f;
+        float y_min = 0.0f;
+        for (int i = 0; i < NB_SAMPLES; i++) {
+            final float alpha = (float) i / NB_SAMPLES;
+
+            float x_max = 1.0f;
+            float x, tx, coef;
+            while (true) {
+                x = x_min + (x_max - x_min) / 2.0f;
+                coef = 3.0f * x * (1.0f - x);
+                tx = coef * ((1.0f - x) * P1 + x * P2) + x * x * x;
+                if (Math.abs(tx - alpha) < 1E-5) break;
+                if (tx > alpha) x_max = x;
+                else x_min = x;
+            }
+            SPLINE_POSITION[i] = coef * ((1.0f - x) * START_TENSION + x) + x * x * x;
+
+            float y_max = 1.0f;
+            float y, dy;
+            while (true) {
+                y = y_min + (y_max - y_min) / 2.0f;
+                coef = 3.0f * y * (1.0f - y);
+                dy = coef * ((1.0f - y) * START_TENSION + y) + y * y * y;
+                if (Math.abs(dy - alpha) < 1E-5) break;
+                if (dy > alpha) y_max = y;
+                else y_min = y;
+            }
+            SPLINE_TIME[i] = coef * ((1.0f - y) * P1 + y * P2) + y * y * y;
+        }
+        SPLINE_POSITION[NB_SAMPLES] = SPLINE_TIME[NB_SAMPLES] = 1.0f;
+
+        // This controls the viscous fluid effect (how much of it)
+        sViscousFluidScale = 8.0f;
+        // must be set to 1.0 (used in viscousFluid())
+        sViscousFluidNormalize = 1.0f;
+        sViscousFluidNormalize = 1.0f / viscousFluid(1.0f);
+
+    }
+
+    private static float sViscousFluidScale;
+    private static float sViscousFluidNormalize;
+
+    public void setInterpolator(TimeInterpolator interpolator) {
+        mInterpolator = interpolator;
+    }
+
+    /**
+     * Create a Scroller with the default duration and interpolator.
+     */
+    public LauncherScroller(Context context) {
+        this(context, null);
+    }
+
+    /**
+     * Create a Scroller with the specified interpolator. If the interpolator is
+     * null, the default (viscous) interpolator will be used. "Flywheel" behavior will
+     * be in effect for apps targeting Honeycomb or newer.
+     */
+    public LauncherScroller(Context context, Interpolator interpolator) {
+        this(context, interpolator,
+                context.getApplicationInfo().targetSdkVersion >= Build.VERSION_CODES.HONEYCOMB);
+    }
+
+    /**
+     * Create a Scroller with the specified interpolator. If the interpolator is
+     * null, the default (viscous) interpolator will be used. Specify whether or
+     * not to support progressive "flywheel" behavior in flinging.
+     */
+    public LauncherScroller(Context context, Interpolator interpolator, boolean flywheel) {
+        mFinished = true;
+        mInterpolator = interpolator;
+        mPpi = context.getResources().getDisplayMetrics().density * 160.0f;
+        mDeceleration = computeDeceleration(ViewConfiguration.getScrollFriction());
+        mFlywheel = flywheel;
+
+        mPhysicalCoeff = computeDeceleration(0.84f); // look and feel tuning
+    }
+
+    /**
+     * The amount of friction applied to flings. The default value
+     * is {@link ViewConfiguration#getScrollFriction}.
+     *
+     * @param friction A scalar dimension-less value representing the coefficient of
+     *         friction.
+     */
+    public final void setFriction(float friction) {
+        mDeceleration = computeDeceleration(friction);
+        mFlingFriction = friction;
+    }
+
+    private float computeDeceleration(float friction) {
+        return SensorManager.GRAVITY_EARTH   // g (m/s^2)
+                      * 39.37f               // inch/meter
+                      * mPpi                 // pixels per inch
+                      * friction;
+    }
+
+    /**
+     *
+     * Returns whether the scroller has finished scrolling.
+     *
+     * @return True if the scroller has finished scrolling, false otherwise.
+     */
+    public final boolean isFinished() {
+        return mFinished;
+    }
+
+    /**
+     * Force the finished field to a particular value.
+     *
+     * @param finished The new finished value.
+     */
+    public final void forceFinished(boolean finished) {
+        mFinished = finished;
+    }
+
+    /**
+     * Returns how long the scroll event will take, in milliseconds.
+     *
+     * @return The duration of the scroll in milliseconds.
+     */
+    public final int getDuration() {
+        return mDuration;
+    }
+
+    /**
+     * Returns the current X offset in the scroll.
+     *
+     * @return The new X offset as an absolute distance from the origin.
+     */
+    public final int getCurrX() {
+        return mCurrX;
+    }
+
+    /**
+     * Returns the current Y offset in the scroll.
+     *
+     * @return The new Y offset as an absolute distance from the origin.
+     */
+    public final int getCurrY() {
+        return mCurrY;
+    }
+
+    /**
+     * Returns the current velocity.
+     *
+     * @return The original velocity less the deceleration. Result may be
+     * negative.
+     */
+    public float getCurrVelocity() {
+        return mMode == FLING_MODE ?
+                mCurrVelocity : mVelocity - mDeceleration * timePassed() / 2000.0f;
+    }
+
+    /**
+     * Returns the start X offset in the scroll.
+     *
+     * @return The start X offset as an absolute distance from the origin.
+     */
+    public final int getStartX() {
+        return mStartX;
+    }
+
+    /**
+     * Returns the start Y offset in the scroll.
+     *
+     * @return The start Y offset as an absolute distance from the origin.
+     */
+    public final int getStartY() {
+        return mStartY;
+    }
+
+    /**
+     * Returns where the scroll will end. Valid only for "fling" scrolls.
+     *
+     * @return The final X offset as an absolute distance from the origin.
+     */
+    public final int getFinalX() {
+        return mFinalX;
+    }
+
+    /**
+     * Returns where the scroll will end. Valid only for "fling" scrolls.
+     *
+     * @return The final Y offset as an absolute distance from the origin.
+     */
+    public final int getFinalY() {
+        return mFinalY;
+    }
+
+    /**
+     * Call this when you want to know the new location.  If it returns true,
+     * the animation is not yet finished.
+     */
+    public boolean computeScrollOffset() {
+        if (mFinished) {
+            return false;
+        }
+
+        int timePassed = (int)(AnimationUtils.currentAnimationTimeMillis() - mStartTime);
+
+        if (timePassed < mDuration) {
+            switch (mMode) {
+            case SCROLL_MODE:
+                float x = timePassed * mDurationReciprocal;
+
+                if (mInterpolator == null)
+                    x = viscousFluid(x);
+                else
+                    x = mInterpolator.getInterpolation(x);
+
+                mCurrX = mStartX + Math.round(x * mDeltaX);
+                mCurrY = mStartY + Math.round(x * mDeltaY);
+                break;
+            case FLING_MODE:
+                final float t = (float) timePassed / mDuration;
+                final int index = (int) (NB_SAMPLES * t);
+                float distanceCoef = 1.f;
+                float velocityCoef = 0.f;
+                if (index < NB_SAMPLES) {
+                    final float t_inf = (float) index / NB_SAMPLES;
+                    final float t_sup = (float) (index + 1) / NB_SAMPLES;
+                    final float d_inf = SPLINE_POSITION[index];
+                    final float d_sup = SPLINE_POSITION[index + 1];
+                    velocityCoef = (d_sup - d_inf) / (t_sup - t_inf);
+                    distanceCoef = d_inf + (t - t_inf) * velocityCoef;
+                }
+
+                mCurrVelocity = velocityCoef * mDistance / mDuration * 1000.0f;
+
+                mCurrX = mStartX + Math.round(distanceCoef * (mFinalX - mStartX));
+                // Pin to mMinX <= mCurrX <= mMaxX
+                mCurrX = Math.min(mCurrX, mMaxX);
+                mCurrX = Math.max(mCurrX, mMinX);
+
+                mCurrY = mStartY + Math.round(distanceCoef * (mFinalY - mStartY));
+                // Pin to mMinY <= mCurrY <= mMaxY
+                mCurrY = Math.min(mCurrY, mMaxY);
+                mCurrY = Math.max(mCurrY, mMinY);
+
+                if (mCurrX == mFinalX && mCurrY == mFinalY) {
+                    mFinished = true;
+                }
+
+                break;
+            }
+        }
+        else {
+            mCurrX = mFinalX;
+            mCurrY = mFinalY;
+            mFinished = true;
+        }
+        return true;
+    }
+
+    /**
+     * Start scrolling by providing a starting point and the distance to travel.
+     * The scroll will use the default value of 250 milliseconds for the
+     * duration.
+     *
+     * @param startX Starting horizontal scroll offset in pixels. Positive
+     *        numbers will scroll the content to the left.
+     * @param startY Starting vertical scroll offset in pixels. Positive numbers
+     *        will scroll the content up.
+     * @param dx Horizontal distance to travel. Positive numbers will scroll the
+     *        content to the left.
+     * @param dy Vertical distance to travel. Positive numbers will scroll the
+     *        content up.
+     */
+    public void startScroll(int startX, int startY, int dx, int dy) {
+        startScroll(startX, startY, dx, dy, DEFAULT_DURATION);
+    }
+
+    /**
+     * Start scrolling by providing a starting point, the distance to travel,
+     * and the duration of the scroll.
+     *
+     * @param startX Starting horizontal scroll offset in pixels. Positive
+     *        numbers will scroll the content to the left.
+     * @param startY Starting vertical scroll offset in pixels. Positive numbers
+     *        will scroll the content up.
+     * @param dx Horizontal distance to travel. Positive numbers will scroll the
+     *        content to the left.
+     * @param dy Vertical distance to travel. Positive numbers will scroll the
+     *        content up.
+     * @param duration Duration of the scroll in milliseconds.
+     */
+    public void startScroll(int startX, int startY, int dx, int dy, int duration) {
+        mMode = SCROLL_MODE;
+        mFinished = false;
+        mDuration = duration;
+        mStartTime = AnimationUtils.currentAnimationTimeMillis();
+        mStartX = startX;
+        mStartY = startY;
+        mFinalX = startX + dx;
+        mFinalY = startY + dy;
+        mDeltaX = dx;
+        mDeltaY = dy;
+        mDurationReciprocal = 1.0f / (float) mDuration;
+    }
+
+    /**
+     * Start scrolling based on a fling gesture. The distance travelled will
+     * depend on the initial velocity of the fling.
+     *
+     * @param startX Starting point of the scroll (X)
+     * @param startY Starting point of the scroll (Y)
+     * @param velocityX Initial velocity of the fling (X) measured in pixels per
+     *        second.
+     * @param velocityY Initial velocity of the fling (Y) measured in pixels per
+     *        second
+     * @param minX Minimum X value. The scroller will not scroll past this
+     *        point.
+     * @param maxX Maximum X value. The scroller will not scroll past this
+     *        point.
+     * @param minY Minimum Y value. The scroller will not scroll past this
+     *        point.
+     * @param maxY Maximum Y value. The scroller will not scroll past this
+     *        point.
+     */
+    public void fling(int startX, int startY, int velocityX, int velocityY,
+            int minX, int maxX, int minY, int maxY) {
+        // Continue a scroll or fling in progress
+        if (mFlywheel && !mFinished) {
+            float oldVel = getCurrVelocity();
+
+            float dx = (float) (mFinalX - mStartX);
+            float dy = (float) (mFinalY - mStartY);
+            float hyp = FloatMath.sqrt(dx * dx + dy * dy);
+
+            float ndx = dx / hyp;
+            float ndy = dy / hyp;
+
+            float oldVelocityX = ndx * oldVel;
+            float oldVelocityY = ndy * oldVel;
+            if (Math.signum(velocityX) == Math.signum(oldVelocityX) &&
+                    Math.signum(velocityY) == Math.signum(oldVelocityY)) {
+                velocityX += oldVelocityX;
+                velocityY += oldVelocityY;
+            }
+        }
+
+        mMode = FLING_MODE;
+        mFinished = false;
+
+        float velocity = FloatMath.sqrt(velocityX * velocityX + velocityY * velocityY);
+
+        mVelocity = velocity;
+        mDuration = getSplineFlingDuration(velocity);
+        mStartTime = AnimationUtils.currentAnimationTimeMillis();
+        mStartX = startX;
+        mStartY = startY;
+
+        float coeffX = velocity == 0 ? 1.0f : velocityX / velocity;
+        float coeffY = velocity == 0 ? 1.0f : velocityY / velocity;
+
+        double totalDistance = getSplineFlingDistance(velocity);
+        mDistance = (int) (totalDistance * Math.signum(velocity));
+
+        mMinX = minX;
+        mMaxX = maxX;
+        mMinY = minY;
+        mMaxY = maxY;
+
+        mFinalX = startX + (int) Math.round(totalDistance * coeffX);
+        // Pin to mMinX <= mFinalX <= mMaxX
+        mFinalX = Math.min(mFinalX, mMaxX);
+        mFinalX = Math.max(mFinalX, mMinX);
+
+        mFinalY = startY + (int) Math.round(totalDistance * coeffY);
+        // Pin to mMinY <= mFinalY <= mMaxY
+        mFinalY = Math.min(mFinalY, mMaxY);
+        mFinalY = Math.max(mFinalY, mMinY);
+    }
+
+    private double getSplineDeceleration(float velocity) {
+        return Math.log(INFLEXION * Math.abs(velocity) / (mFlingFriction * mPhysicalCoeff));
+    }
+
+    private int getSplineFlingDuration(float velocity) {
+        final double l = getSplineDeceleration(velocity);
+        final double decelMinusOne = DECELERATION_RATE - 1.0;
+        return (int) (1000.0 * Math.exp(l / decelMinusOne));
+    }
+
+    private double getSplineFlingDistance(float velocity) {
+        final double l = getSplineDeceleration(velocity);
+        final double decelMinusOne = DECELERATION_RATE - 1.0;
+        return mFlingFriction * mPhysicalCoeff * Math.exp(DECELERATION_RATE / decelMinusOne * l);
+    }
+
+    static float viscousFluid(float x)
+    {
+        x *= sViscousFluidScale;
+        if (x < 1.0f) {
+            x -= (1.0f - (float)Math.exp(-x));
+        } else {
+            float start = 0.36787944117f;   // 1/e == exp(-1)
+            x = 1.0f - (float)Math.exp(1.0f - x);
+            x = start + x * (1.0f - start);
+        }
+        x *= sViscousFluidNormalize;
+        return x;
+    }
+
+    /**
+     * Stops the animation. Contrary to {@link #forceFinished(boolean)},
+     * aborting the animating cause the scroller to move to the final x and y
+     * position
+     *
+     * @see #forceFinished(boolean)
+     */
+    public void abortAnimation() {
+        mCurrX = mFinalX;
+        mCurrY = mFinalY;
+        mFinished = true;
+    }
+
+    /**
+     * Extend the scroll animation. This allows a running animation to scroll
+     * further and longer, when used with {@link #setFinalX(int)} or {@link #setFinalY(int)}.
+     *
+     * @param extend Additional time to scroll in milliseconds.
+     * @see #setFinalX(int)
+     * @see #setFinalY(int)
+     */
+    public void extendDuration(int extend) {
+        int passed = timePassed();
+        mDuration = passed + extend;
+        mDurationReciprocal = 1.0f / mDuration;
+        mFinished = false;
+    }
+
+    /**
+     * Returns the time elapsed since the beginning of the scrolling.
+     *
+     * @return The elapsed time in milliseconds.
+     */
+    public int timePassed() {
+        return (int)(AnimationUtils.currentAnimationTimeMillis() - mStartTime);
+    }
+
+    /**
+     * Sets the final position (X) for this scroller.
+     *
+     * @param newX The new X offset as an absolute distance from the origin.
+     * @see #extendDuration(int)
+     * @see #setFinalY(int)
+     */
+    public void setFinalX(int newX) {
+        mFinalX = newX;
+        mDeltaX = mFinalX - mStartX;
+        mFinished = false;
+    }
+
+    /**
+     * Sets the final position (Y) for this scroller.
+     *
+     * @param newY The new Y offset as an absolute distance from the origin.
+     * @see #extendDuration(int)
+     * @see #setFinalX(int)
+     */
+    public void setFinalY(int newY) {
+        mFinalY = newY;
+        mDeltaY = mFinalY - mStartY;
+        mFinished = false;
+    }
+
+    /**
+     * @hide
+     */
+    public boolean isScrollingInDirection(float xvel, float yvel) {
+        return !mFinished && Math.signum(xvel) == Math.signum(mFinalX - mStartX) &&
+                Math.signum(yvel) == Math.signum(mFinalY - mStartY);
+    }
+}
diff --git a/src/com/android/launcher3/LauncherWallpaperPickerActivity.java b/src/com/android/launcher3/LauncherWallpaperPickerActivity.java
new file mode 100644
index 0000000..10fe013
--- /dev/null
+++ b/src/com/android/launcher3/LauncherWallpaperPickerActivity.java
@@ -0,0 +1,30 @@
+/*
+ * Copyright (C) 2013 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.launcher3;
+
+import android.content.Intent;
+
+public class LauncherWallpaperPickerActivity extends WallpaperPickerActivity {
+    @Override
+    public void startActivityForResultSafely(Intent intent, int requestCode) {
+        Utilities.startActivityForResultSafely(this, intent, requestCode);
+    }
+    @Override
+    public boolean enableRotation() {
+        return Utilities.isRotationEnabled(this);
+    }
+}
diff --git a/src/com/android/launcher3/OnAlarmListener.java b/src/com/android/launcher3/OnAlarmListener.java
new file mode 100644
index 0000000..b5ef83e
--- /dev/null
+++ b/src/com/android/launcher3/OnAlarmListener.java
@@ -0,0 +1,5 @@
+package com.android.launcher3;
+
+public interface OnAlarmListener {
+    public void onAlarm(Alarm alarm);
+}
diff --git a/src/com/android/launcher3/PageIndicator.java b/src/com/android/launcher3/PageIndicator.java
index 08e5f72..62ea03b 100644
--- a/src/com/android/launcher3/PageIndicator.java
+++ b/src/com/android/launcher3/PageIndicator.java
@@ -16,22 +16,12 @@
 
 package com.android.launcher3;
 
-import android.animation.Animator;
-import android.animation.AnimatorListenerAdapter;
 import android.animation.LayoutTransition;
-import android.animation.TimeInterpolator;
-import android.content.ComponentName;
 import android.content.Context;
-import android.content.res.Configuration;
-import android.content.res.Resources;
 import android.content.res.TypedArray;
 import android.util.AttributeSet;
-import android.util.Log;
 import android.view.LayoutInflater;
-import android.view.View;
-import android.view.ViewGroup;
 import android.widget.LinearLayout;
-import com.android.launcher3.R;
 
 import java.util.ArrayList;
 
diff --git a/src/com/android/launcher3/PageIndicatorMarker.java b/src/com/android/launcher3/PageIndicatorMarker.java
index b1025d6..f012db7 100644
--- a/src/com/android/launcher3/PageIndicatorMarker.java
+++ b/src/com/android/launcher3/PageIndicatorMarker.java
@@ -16,17 +16,11 @@
 
 package com.android.launcher3;
 
-import android.animation.AnimatorListenerAdapter;
-import android.animation.LayoutTransition;
 import android.content.Context;
 import android.content.res.Resources;
 import android.util.AttributeSet;
-import android.view.LayoutInflater;
-import android.view.View;
-import android.view.ViewGroup;
-import android.widget.ImageView;
 import android.widget.FrameLayout;
-import com.android.launcher3.R;
+import android.widget.ImageView;
 
 public class PageIndicatorMarker extends FrameLayout {
     @SuppressWarnings("unused")
diff --git a/src/com/android/launcher3/PagedView.java b/src/com/android/launcher3/PagedView.java
index e982985..8d5d8dd 100644
--- a/src/com/android/launcher3/PagedView.java
+++ b/src/com/android/launcher3/PagedView.java
@@ -32,7 +32,6 @@
 import android.os.Bundle;
 import android.os.Parcel;
 import android.os.Parcelable;
-import android.support.v4.view.accessibility.AccessibilityEventCompat;
 import android.util.AttributeSet;
 import android.util.DisplayMetrics;
 import android.util.Log;
@@ -51,7 +50,6 @@
 import android.view.animation.DecelerateInterpolator;
 import android.view.animation.Interpolator;
 import android.view.animation.LinearInterpolator;
-import android.widget.Scroller;
 
 import java.util.ArrayList;
 
@@ -122,8 +120,10 @@
 
     protected int mNextPage = INVALID_PAGE;
     protected int mMaxScrollX;
-    protected Scroller mScroller;
+    protected LauncherScroller mScroller;
+    private Interpolator mDefaultInterpolator;
     private VelocityTracker mVelocityTracker;
+    private int mPageSpacing = 0;
 
     private float mParentDownMotionX;
     private float mParentDownMotionY;
@@ -152,12 +152,12 @@
     protected int mTouchState = TOUCH_STATE_REST;
     protected boolean mForceScreenScrolled = false;
 
+
     protected OnLongClickListener mLongClickListener;
 
     protected int mTouchSlop;
     private int mPagingTouchSlop;
     private int mMaximumVelocity;
-    protected int mPageSpacing;
     protected int mPageLayoutPaddingTop;
     protected int mPageLayoutPaddingBottom;
     protected int mPageLayoutPaddingLeft;
@@ -260,16 +260,11 @@
     // Drop to delete
     private View mDeleteDropTarget;
 
-    private boolean mAutoComputePageSpacing = false;
-    private boolean mRecomputePageSpacing = false;
-
     // Bouncer
     private boolean mTopAlignPageWhenShrinkingForBouncer = false;
 
     protected final Rect mInsets = new Rect();
 
-    protected int mFirstChildLeft;
-
     public interface PageSwitchListener {
         void onPageSwitch(View newPage, int newPageIndex);
     }
@@ -287,10 +282,7 @@
 
         TypedArray a = context.obtainStyledAttributes(attrs,
                 R.styleable.PagedView, defStyle, 0);
-        setPageSpacing(a.getDimensionPixelSize(R.styleable.PagedView_pageSpacing, 0));
-        if (mPageSpacing < 0) {
-            mAutoComputePageSpacing = mRecomputePageSpacing = true;
-        }
+
         mPageLayoutPaddingTop = a.getDimensionPixelSize(
                 R.styleable.PagedView_pageLayoutPaddingTop, 0);
         mPageLayoutPaddingBottom = a.getDimensionPixelSize(
@@ -316,7 +308,8 @@
     protected void init() {
         mDirtyPageContent = new ArrayList<Boolean>();
         mDirtyPageContent.ensureCapacity(32);
-        mScroller = new Scroller(getContext(), new ScrollInterpolator());
+        mScroller = new LauncherScroller(getContext());
+        setDefaultInterpolator(new ScrollInterpolator());
         mCurrentPage = 0;
         mCenterPagesVertically = true;
 
@@ -336,6 +329,11 @@
         setOnHierarchyChangeListener(this);
     }
 
+    protected void setDefaultInterpolator(Interpolator interpolator) {
+        mDefaultInterpolator = interpolator;
+        mScroller.setInterpolator(mDefaultInterpolator);
+    }
+
     protected void onAttachedToWindow() {
         super.onAttachedToWindow();
 
@@ -451,6 +449,10 @@
         return new PageIndicator.PageMarkerResources();
     }
 
+    /**
+     * Add a page change listener which will be called when a page is _finished_ listening.
+     *
+     */
     public void setPageSwitchListener(PageSwitchListener pageSwitchListener) {
         mPageSwitchListener = pageSwitchListener;
         if (mPageSwitchListener != null) {
@@ -515,33 +517,42 @@
         }
         scrollTo(newX, 0);
         mScroller.setFinalX(newX);
-        mScroller.forceFinished(true);
+        forceFinishScroller();
     }
 
     /**
      * Called during AllApps/Home transitions to avoid unnecessary work. When that other animation
-     * ends, {@link #resumeScrolling()} should be called, along with
-     * {@link #updateCurrentPageScroll()} to correctly set the final state and re-enable scrolling.
+     * {@link #updateCurrentPageScroll()} should be called, to correctly set the final state and
+     * re-enable scrolling.
      */
-    void pauseScrolling() {
-        mScroller.forceFinished(true);
+    void stopScrolling() {
+        mCurrentPage = getNextPage();
+        notifyPageSwitchListener();
+        forceFinishScroller();
     }
 
-    /**
-     * Enables scrolling again.
-     * @see #pauseScrolling()
-     */
-    void resumeScrolling() {
+    private void abortScrollerAnimation(boolean resetNextPage) {
+        mScroller.abortAnimation();
+        // We need to clean up the next page here to avoid computeScrollHelper from
+        // updating current page on the pass.
+        if (resetNextPage) {
+            mNextPage = INVALID_PAGE;
+        }
     }
+
+    private void forceFinishScroller() {
+        mScroller.forceFinished(true);
+        // We need to clean up the next page here to avoid computeScrollHelper from
+        // updating current page on the pass.
+        mNextPage = INVALID_PAGE;
+    }
+
     /**
      * Sets the current page.
      */
     void setCurrentPage(int currentPage) {
         if (!mScroller.isFinished()) {
-            mScroller.abortAnimation();
-            // We need to clean up the next page here to avoid computeScrollHelper from
-            // updating current page on the pass.
-            mNextPage = INVALID_PAGE;
+            abortScrollerAnimation(true);
         }
         // don't introduce any checks like mCurrentPage == currentPage here-- if we change the
         // the default
@@ -562,12 +573,23 @@
     void setRestorePage(int restorePage) {
         mRestorePage = restorePage;
     }
+    int getRestorePage() {
+        return mRestorePage;
+    }
 
+    /**
+     * Should be called whenever the page changes. In the case of a scroll, we wait until the page
+     * has settled.
+     */
     protected void notifyPageSwitchListener() {
         if (mPageSwitchListener != null) {
-            mPageSwitchListener.onPageSwitch(getPageAt(mCurrentPage), mCurrentPage);
+            mPageSwitchListener.onPageSwitch(getPageAt(getNextPage()), getNextPage());
         }
 
+        updatePageIndicator();
+    }
+
+    private void updatePageIndicator() {
         // Update the page indicator (when we aren't reordering)
         if (mPageIndicator != null && !isReordering(false)) {
             mPageIndicator.setActiveMarker(getNextPage());
@@ -675,6 +697,7 @@
                     AccessibilityEvent.obtain(AccessibilityEvent.TYPE_VIEW_SCROLLED);
             ev.setItemCount(getChildCount());
             ev.setFromIndex(mCurrentPage);
+            ev.setToIndex(getNextPage());
 
             final int action;
             if (getNextPage() >= mCurrentPage) {
@@ -783,16 +806,16 @@
         int widthSize = MeasureSpec.getSize(widthMeasureSpec);
         int heightMode = MeasureSpec.getMode(heightMeasureSpec);
         int heightSize = MeasureSpec.getSize(heightMeasureSpec);
-        // NOTE: We multiply by 1.5f to account for the fact that depending on the offset of the
+        // NOTE: We multiply by 2f to account for the fact that depending on the offset of the
         // viewport, we can be at most one and a half screens offset once we scale down
         DisplayMetrics dm = getResources().getDisplayMetrics();
-        int maxSize = Math.max(dm.widthPixels, dm.heightPixels + mInsets.top + mInsets.bottom);
+        int maxSize = Math.max(dm.widthPixels + mInsets.left + mInsets.right,
+                dm.heightPixels + mInsets.top + mInsets.bottom);
 
-        int parentWidthSize, parentHeightSize;
+        int parentWidthSize = (int) (2f * maxSize);
+        int parentHeightSize = (int) (2f * maxSize);
         int scaledWidthSize, scaledHeightSize;
         if (mUseMinScale) {
-            parentWidthSize = (int) (1.5f * maxSize);
-            parentHeightSize = maxSize;
             scaledWidthSize = (int) (parentWidthSize / mMinScale);
             scaledHeightSize = (int) (parentHeightSize / mMinScale);
         } else {
@@ -852,21 +875,17 @@
                         childHeightMode = MeasureSpec.EXACTLY;
                     }
 
-                    childWidth = widthSize - horizontalPadding;
-                    childHeight = heightSize - verticalPadding - mInsets.top - mInsets.bottom;
+                    childWidth = getViewportWidth() - horizontalPadding
+                            - mInsets.left - mInsets.right;
+                    childHeight = getViewportHeight() - verticalPadding
+                            - mInsets.top - mInsets.bottom;
                     mNormalChildHeight = childHeight;
-
                 } else {
                     childWidthMode = MeasureSpec.EXACTLY;
                     childHeightMode = MeasureSpec.EXACTLY;
 
-                    if (mUseMinScale) {
-                        childWidth = getViewportWidth();
-                        childHeight = getViewportHeight();
-                    } else {
-                        childWidth = widthSize - getPaddingLeft() - getPaddingRight();
-                        childHeight = heightSize - getPaddingTop() - getPaddingBottom();
-                    }
+                    childWidth = getViewportWidth() - mInsets.left - mInsets.right;
+                    childHeight = getViewportHeight();
                 }
 
                 final int childWidthMeasureSpec =
@@ -877,30 +896,6 @@
             }
         }
         setMeasuredDimension(scaledWidthSize, scaledHeightSize);
-
-        if (childCount > 0) {
-            // Calculate the variable page spacing if necessary
-            if (mAutoComputePageSpacing && mRecomputePageSpacing) {
-                // The gap between pages in the PagedView should be equal to the gap from the page
-                // to the edge of the screen (so it is not visible in the current screen).  To
-                // account for unequal padding on each side of the paged view, we take the maximum
-                // of the left/right gap and use that as the gap between each page.
-                int offset = (getViewportWidth() - getChildWidth(0)) / 2;
-                int spacing = Math.max(offset, widthSize - offset -
-                        getChildAt(0).getMeasuredWidth());
-                setPageSpacing(spacing);
-                mRecomputePageSpacing = false;
-            }
-        }
-    }
-
-    public void setPageSpacing(int pageSpacing) {
-        mPageSpacing = pageSpacing;
-        requestLayout();
-    }
-
-    protected int getFirstChildLeft() {
-        return mFirstChildLeft;
     }
 
     @Override
@@ -912,8 +907,6 @@
         if (DEBUG) Log.d(TAG, "PagedView.onLayout()");
         final int childCount = getChildCount();
 
-        int screenWidth = getViewportWidth();
-
         int offsetX = getViewportOffsetX();
         int offsetY = getViewportOffsetY();
 
@@ -928,7 +921,10 @@
 
         int verticalPadding = getPaddingTop() + getPaddingBottom();
 
-        int childLeft = mFirstChildLeft = offsetX + (screenWidth - getChildWidth(startIndex)) / 2;
+        LayoutParams lp = (LayoutParams) getChildAt(startIndex).getLayoutParams();
+        LayoutParams nextLp;
+
+        int childLeft = offsetX + (lp.isFullScreenPage ? 0 : getPaddingLeft());
         if (mPageScrolls == null || getChildCount() != mChildCountOnLastLayout) {
             mPageScrolls = new int[getChildCount()];
         }
@@ -936,7 +932,7 @@
         for (int i = startIndex; i != endIndex; i += delta) {
             final View child = getPageAt(i);
             if (child.getVisibility() != View.GONE) {
-                LayoutParams lp = (LayoutParams) child.getLayoutParams();
+                lp = (LayoutParams) child.getLayoutParams();
                 int childTop;
                 if (lp.isFullScreenPage) {
                     childTop = offsetY;
@@ -954,16 +950,26 @@
                 child.layout(childLeft, childTop,
                         childLeft + child.getMeasuredWidth(), childTop + childHeight);
 
-                // We assume the left and right padding are equal, and hence center the pages
-                // horizontally
-                int scrollOffset = (getViewportWidth() - childWidth) / 2;
-                mPageScrolls[i] = childLeft - scrollOffset - offsetX;
+                int scrollOffsetLeft = lp.isFullScreenPage ? 0 : getPaddingLeft();
+                mPageScrolls[i] = childLeft - scrollOffsetLeft - offsetX;
 
-                if (i != endIndex - delta) {
-                    childLeft += childWidth + scrollOffset;
-                    int nextScrollOffset = (getViewportWidth() - getChildWidth(i + delta)) / 2;
-                    childLeft += nextScrollOffset;
+                int pageGap = mPageSpacing;
+                int next = i + delta;
+                if (next != endIndex) {
+                    nextLp = (LayoutParams) getPageAt(next).getLayoutParams();
+                } else {
+                    nextLp = null;
                 }
+
+                // Prevent full screen pages from showing in the viewport
+                // when they are not the current page.
+                if (lp.isFullScreenPage) {
+                    pageGap = getPaddingLeft();
+                } else if (nextLp != null && nextLp.isFullScreenPage) {
+                    pageGap = getPaddingRight();
+                }
+
+                childLeft += childWidth + pageGap;
             }
         }
 
@@ -997,6 +1003,11 @@
         }
     }
 
+    public void setPageSpacing(int pageSpacing) {
+        mPageSpacing = pageSpacing;
+        requestLayout();
+    }
+
     protected void screenScrolled(int screenCenter) {
         boolean isInOverscroll = mOverScrollX < 0 || mOverScrollX > mMaxScrollX;
 
@@ -1035,7 +1046,6 @@
         // This ensures that when children are added, they get the correct transforms / alphas
         // in accordance with any scroll effects.
         mForceScreenScrolled = true;
-        mRecomputePageSpacing = true;
         updateFreescrollBounds();
         invalidate();
     }
@@ -1153,22 +1163,22 @@
 
     @Override
     protected void dispatchDraw(Canvas canvas) {
-        int halfScreenSize = getViewportWidth() / 2;
-        // mOverScrollX is equal to getScrollX() when we're within the normal scroll range.
-        // Otherwise it is equal to the scaled overscroll position.
-        int screenCenter = mOverScrollX + halfScreenSize;
-
-        if (screenCenter != mLastScreenCenter || mForceScreenScrolled) {
-            // set mForceScreenScrolled before calling screenScrolled so that screenScrolled can
-            // set it for the next frame
-            mForceScreenScrolled = false;
-            screenScrolled(screenCenter);
-            mLastScreenCenter = screenCenter;
-        }
-
         // Find out which screens are visible; as an optimization we only call draw on them
         final int pageCount = getChildCount();
         if (pageCount > 0) {
+            int halfScreenSize = getViewportWidth() / 2;
+            // mOverScrollX is equal to getScrollX() when we're within the normal scroll range.
+            // Otherwise it is equal to the scaled overscroll position.
+            int screenCenter = mOverScrollX + halfScreenSize;
+
+            if (screenCenter != mLastScreenCenter || mForceScreenScrolled) {
+                // set mForceScreenScrolled before calling screenScrolled so that screenScrolled can
+                // set it for the next frame
+                mForceScreenScrolled = false;
+                screenScrolled(screenCenter);
+                mLastScreenCenter = screenCenter;
+            }
+
             getVisiblePages(mTempVisiblePagesRange);
             final int leftScreen = mTempVisiblePagesRange[0];
             final int rightScreen = mTempVisiblePagesRange[1];
@@ -1304,24 +1314,22 @@
      * Return true if a tap at (x, y) should trigger a flip to the previous page.
      */
     protected boolean hitsPreviousPage(float x, float y) {
-        int offset = (getViewportWidth() - getChildWidth(mCurrentPage)) / 2;
         if (isLayoutRtl()) {
             return (x > (getViewportOffsetX() + getViewportWidth() -
-                    offset + mPageSpacing));
+                    getPaddingRight() - mPageSpacing));
         }
-        return (x < getViewportOffsetX() + offset - mPageSpacing);
+        return (x < getViewportOffsetX() + getPaddingLeft() + mPageSpacing);
     }
 
     /**
      * Return true if a tap at (x, y) should trigger a flip to the next page.
      */
     protected boolean hitsNextPage(float x, float y) {
-        int offset = (getViewportWidth() - getChildWidth(mCurrentPage)) / 2;
         if (isLayoutRtl()) {
-            return (x < getViewportOffsetX() + offset - mPageSpacing);
+            return (x < getViewportOffsetX() + getPaddingLeft() + mPageSpacing);
         }
         return  (x > (getViewportOffsetX() + getViewportWidth() -
-                offset + mPageSpacing));
+                getPaddingRight() - mPageSpacing));
     }
 
     /** Returns whether x and y originated within the buffered viewport */
@@ -1397,10 +1405,14 @@
                  * being flinged.
                  */
                 final int xDist = Math.abs(mScroller.getFinalX() - mScroller.getCurrX());
-                final boolean finishedScrolling = (mScroller.isFinished() || xDist < mTouchSlop);
+                final boolean finishedScrolling = (mScroller.isFinished() || xDist < mTouchSlop / 3);
+
                 if (finishedScrolling) {
                     mTouchState = TOUCH_STATE_REST;
-                    mScroller.abortAnimation();
+                    if (!mScroller.isFinished() && !mFreeScroll) {
+                        setCurrentPage(getNextPage());
+                        pageEndMoving();
+                    }
                 } else {
                     if (isTouchPointInViewportWithBuffer((int) mDownMotionX, (int) mDownMotionY)) {
                         mTouchState = TOUCH_STATE_SCROLLING;
@@ -1512,8 +1524,21 @@
     protected float getScrollProgress(int screenCenter, View v, int page) {
         final int halfScreenSize = getViewportWidth() / 2;
 
-        int totalDistance = v.getMeasuredWidth() + mPageSpacing;
         int delta = screenCenter - (getScrollForPage(page) + halfScreenSize);
+        int count = getChildCount();
+
+        final int totalDistance;
+
+        int adjacentPage = page + 1;
+        if ((delta < 0 && !isLayoutRtl()) || (delta > 0 && isLayoutRtl())) {
+            adjacentPage = page - 1;
+        }
+
+        if (adjacentPage < 0 || adjacentPage > count - 1) {
+            totalDistance = v.getMeasuredWidth() + mPageSpacing;
+        } else {
+            totalDistance = Math.abs(getScrollForPage(adjacentPage) - getScrollForPage(page));
+        }
 
         float scrollProgress = delta / (totalDistance * 1.0f);
         scrollProgress = Math.min(scrollProgress, getMaxScrollProgress());
@@ -1536,7 +1561,13 @@
             return 0;
         } else {
             View child = getChildAt(index);
-            int scrollOffset = (getViewportWidth() - child.getMeasuredWidth()) / 2;
+
+            int scrollOffset = 0;
+            LayoutParams lp = (LayoutParams) child.getLayoutParams();
+            if (!lp.isFullScreenPage) {
+                scrollOffset = isLayoutRtl() ? getPaddingRight() : getPaddingLeft();
+            }
+
             int baselineX = mPageScrolls[index] + scrollOffset + getViewportOffsetX();
             return (int) (child.getX() - baselineX);
         }
@@ -1611,11 +1642,11 @@
     }
 
     protected void enableFreeScroll() {
-        setEnableFreeScroll(true, -1);
+        setEnableFreeScroll(true);
     }
 
-    protected void disableFreeScroll(int snapPage) {
-        setEnableFreeScroll(false, snapPage);
+    protected void disableFreeScroll() {
+        setEnableFreeScroll(false);
     }
 
     void updateFreescrollBounds() {
@@ -1629,16 +1660,10 @@
         }
     }
 
-    private void setEnableFreeScroll(boolean freeScroll, int snapPage) {
+    private void setEnableFreeScroll(boolean freeScroll) {
         mFreeScroll = freeScroll;
 
-        if (snapPage == -1) {
-            snapPage = getPageNearestToCenterOfScreen();
-        }
-
-        if (!mFreeScroll) {
-            snapToPage(snapPage);
-        } else {
+        if (mFreeScroll) {
             updateFreescrollBounds();
             getOverviewModePages(mTempVisiblePagesRange);
             if (getCurrentPage() < mTempVisiblePagesRange[0]) {
@@ -1698,7 +1723,7 @@
              * will be false if being flinged.
              */
             if (!mScroller.isFinished()) {
-                mScroller.abortAnimation();
+                abortScrollerAnimation(false);
             }
 
             // Remember where the motion event started
@@ -1824,7 +1849,9 @@
                                 addView(mDragView, pageUnderPointIndex);
                                 onAddView(mDragView, pageUnderPointIndex);
                                 mSidePageHoverIndex = -1;
-                                mPageIndicator.setActiveMarker(getNextPage());
+                                if (mPageIndicator != null) {
+                                    mPageIndicator.setActiveMarker(getNextPage());
+                                }
                             }
                         };
                         postDelayed(mSidePageHoverRunnable, REORDERING_SIDE_PAGE_HOVER_TIMEOUT);
@@ -1884,29 +1911,31 @@
                         snapToPageWithVelocity(finalPage, velocityX);
                     } else {
                         snapToDestination();
-                    }            } else if (mTouchState == TOUCH_STATE_PREV_PAGE) {
-                    // at this point we have not moved beyond the touch slop
-                    // (otherwise mTouchState would be TOUCH_STATE_SCROLLING), so
-                    // we can just page
-                    int nextPage = Math.max(0, mCurrentPage - 1);
-                    if (nextPage != mCurrentPage) {
-                        snapToPage(nextPage);
-                    } else {
-                        snapToDestination();
                     }
                 } else {
                     if (!mScroller.isFinished()) {
-                        mScroller.abortAnimation();
+                        abortScrollerAnimation(true);
                     }
 
                     float scaleX = getScaleX();
                     int vX = (int) (-velocityX * scaleX);
                     int initialScrollX = (int) (getScrollX() * scaleX);
 
+                    mScroller.setInterpolator(mDefaultInterpolator);
                     mScroller.fling(initialScrollX,
                             getScrollY(), vX, 0, Integer.MIN_VALUE, Integer.MAX_VALUE, 0, 0);
                     invalidate();
                 }
+            } else if (mTouchState == TOUCH_STATE_PREV_PAGE) {
+                // at this point we have not moved beyond the touch slop
+                // (otherwise mTouchState would be TOUCH_STATE_SCROLLING), so
+                // we can just page
+                int nextPage = Math.max(0, mCurrentPage - 1);
+                if (nextPage != mCurrentPage) {
+                    snapToPage(nextPage);
+                } else {
+                    snapToDestination();
+                }
             } else if (mTouchState == TOUCH_STATE_NEXT_PAGE) {
                 // at this point we have not moved beyond the touch slop
                 // (otherwise mTouchState would be TOUCH_STATE_SCROLLING), so
@@ -2158,27 +2187,33 @@
     }
 
     protected void snapToPageImmediately(int whichPage) {
-        snapToPage(whichPage, PAGE_SNAP_ANIMATION_DURATION, true);
+        snapToPage(whichPage, PAGE_SNAP_ANIMATION_DURATION, true, null);
     }
 
     protected void snapToPage(int whichPage, int duration) {
-        snapToPage(whichPage, duration, false);
+        snapToPage(whichPage, duration, false, null);
     }
 
-    protected void snapToPage(int whichPage, int duration, boolean immediate) {
+    protected void snapToPage(int whichPage, int duration, TimeInterpolator interpolator) {
+        snapToPage(whichPage, duration, false, interpolator);
+    }
+
+    protected void snapToPage(int whichPage, int duration, boolean immediate,
+            TimeInterpolator interpolator) {
         whichPage = Math.max(0, Math.min(whichPage, getPageCount() - 1));
 
         int newX = getScrollForPage(whichPage);
         final int sX = mUnboundedScrollX;
         final int delta = newX - sX;
-        snapToPage(whichPage, delta, duration, immediate);
+        snapToPage(whichPage, delta, duration, immediate, interpolator);
     }
 
     protected void snapToPage(int whichPage, int delta, int duration) {
-        snapToPage(whichPage, delta, duration, false);
+        snapToPage(whichPage, delta, duration, false, null);
     }
 
-    protected void snapToPage(int whichPage, int delta, int duration, boolean immediate) {
+    protected void snapToPage(int whichPage, int delta, int duration, boolean immediate,
+            TimeInterpolator interpolator) {
         mNextPage = whichPage;
         View focusedChild = getFocusedChild();
         if (focusedChild != null && whichPage != mCurrentPage &&
@@ -2197,11 +2232,18 @@
         }
 
         if (!mScroller.isFinished()) {
-            mScroller.abortAnimation();
+            abortScrollerAnimation(false);
         }
+
+        if (interpolator != null) {
+            mScroller.setInterpolator(interpolator);
+        } else {
+            mScroller.setInterpolator(mDefaultInterpolator);
+        }
+
         mScroller.startScroll(mUnboundedScrollX, 0, delta, 0, duration);
 
-        notifyPageSwitchListener();
+        updatePageIndicator();
 
         // Trigger a compute() to finish switching pages if necessary
         if (immediate) {
@@ -2360,8 +2402,7 @@
 
         if (mContentIsRefreshable) {
             // Force all scrolling-related behavior to end
-            mScroller.forceFinished(true);
-            mNextPage = INVALID_PAGE;
+            forceFinishScroller();
 
             // Update all the pages
             syncPages();
@@ -2455,7 +2496,8 @@
             mDragView = getChildAt(dragViewIndex);
             mDragView.animate().scaleX(1.15f).scaleY(1.15f).setDuration(100).start();
             mDragViewBaselineLeft = mDragView.getLeft();
-            disableFreeScroll(-1);
+            snapToPage(getPageNearestToCenterOfScreen());
+            disableFreeScroll();
             onStartReordering();
             return true;
         }
diff --git a/src/com/android/launcher3/PagedViewIcon.java b/src/com/android/launcher3/PagedViewIcon.java
index 8bfe42d..f7cb997 100644
--- a/src/com/android/launcher3/PagedViewIcon.java
+++ b/src/com/android/launcher3/PagedViewIcon.java
@@ -20,7 +20,7 @@
 import android.graphics.Bitmap;
 import android.graphics.Canvas;
 import android.graphics.Region;
-import android.graphics.Region.Op;
+import android.graphics.drawable.Drawable;
 import android.util.AttributeSet;
 import android.util.TypedValue;
 import android.widget.TextView;
@@ -62,15 +62,20 @@
         // Ensure we are using the right text size
         LauncherAppState app = LauncherAppState.getInstance();
         DeviceProfile grid = app.getDynamicGrid().getDeviceProfile();
-        setTextSize(TypedValue.COMPLEX_UNIT_SP, grid.iconTextSize);
+        setTextSize(TypedValue.COMPLEX_UNIT_PX, grid.allAppsIconTextSizePx);
     }
 
     public void applyFromApplicationInfo(AppInfo info, boolean scaleUp,
             PagedViewIcon.PressedCallback cb) {
+        LauncherAppState app = LauncherAppState.getInstance();
+        DeviceProfile grid = app.getDynamicGrid().getDeviceProfile();
+
         mIcon = info.iconBitmap;
         mPressedCallback = cb;
-        setCompoundDrawables(null, Utilities.createIconDrawable(mIcon),
-                null, null);
+        Drawable icon = Utilities.createIconDrawable(mIcon);
+        icon.setBounds(0, 0, grid.allAppsIconSizePx, grid.allAppsIconSizePx);
+        setCompoundDrawables(null, icon, null, null);
+        setCompoundDrawablePadding(grid.iconDrawablePaddingPx);
         setText(info.title);
         setTag(info);
     }
diff --git a/src/com/android/launcher3/PagedViewIconCache.java b/src/com/android/launcher3/PagedViewIconCache.java
index 8d8924b..93887ea 100644
--- a/src/com/android/launcher3/PagedViewIconCache.java
+++ b/src/com/android/launcher3/PagedViewIconCache.java
@@ -16,17 +16,17 @@
 
 package com.android.launcher3;
 
-import java.util.ArrayList;
-import java.util.HashMap;
-import java.util.HashSet;
-import java.util.List;
-
 import android.appwidget.AppWidgetProviderInfo;
 import android.content.ComponentName;
 import android.content.pm.ComponentInfo;
 import android.content.pm.ResolveInfo;
 import android.graphics.Bitmap;
 
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.List;
+
 /**
  * Simple cache mechanism for PagedView outlines.
  */
diff --git a/src/com/android/launcher3/PagedViewWidget.java b/src/com/android/launcher3/PagedViewWidget.java
index 45320a4..db4aeb9 100644
--- a/src/com/android/launcher3/PagedViewWidget.java
+++ b/src/com/android/launcher3/PagedViewWidget.java
@@ -30,8 +30,6 @@
 import android.widget.LinearLayout;
 import android.widget.TextView;
 
-import com.android.launcher3.R;
-
 /**
  * The linear layout used strictly for the widget/wallpaper tab of the customization tray
  */
@@ -84,11 +82,11 @@
         DeviceProfile grid = app.getDynamicGrid().getDeviceProfile();
         TextView name = (TextView) findViewById(R.id.widget_name);
         if (name != null) {
-            name.setTextSize(TypedValue.COMPLEX_UNIT_SP, grid.iconTextSize);
+            name.setTextSize(TypedValue.COMPLEX_UNIT_PX, grid.iconTextSizePx);
         }
         TextView dims = (TextView) findViewById(R.id.widget_dims);
         if (dims != null) {
-            dims.setTextSize(TypedValue.COMPLEX_UNIT_SP, grid.iconTextSize);
+            dims.setTextSize(TypedValue.COMPLEX_UNIT_PX, grid.iconTextSizePx);
         }
     }
 
diff --git a/src/com/android/launcher3/PreloadReceiver.java b/src/com/android/launcher3/PreloadReceiver.java
index 75e5c98..ca25746 100644
--- a/src/com/android/launcher3/PreloadReceiver.java
+++ b/src/com/android/launcher3/PreloadReceiver.java
@@ -19,6 +19,7 @@
 import android.content.BroadcastReceiver;
 import android.content.Context;
 import android.content.Intent;
+import android.os.AsyncTask;
 import android.text.TextUtils;
 import android.util.Log;
 
@@ -39,12 +40,12 @@
             if (LOGD) {
                 Log.d(TAG, "workspace name: " + name + " id: " + workspaceResId);
             }
-            new Thread(new Runnable() {
-                @Override
-                public void run() {
+            new AsyncTask<Void, Void, Void>() {
+                public Void doInBackground(Void ... args) {
                     provider.loadDefaultFavoritesIfNecessary(workspaceResId);
+                    return null;
                 }
-            }).start();
+            }.executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR, (Void) null);
         }
     }
 }
diff --git a/src/com/android/launcher3/RampUpScroller.java b/src/com/android/launcher3/RampUpScroller.java
deleted file mode 100644
index 89eb579..0000000
--- a/src/com/android/launcher3/RampUpScroller.java
+++ /dev/null
@@ -1,120 +0,0 @@
-/*
- * Copyright (C) 2013 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.launcher3;
-
-import android.view.animation.AccelerateInterpolator;
-import android.view.animation.AnimationUtils;
-import android.view.animation.Interpolator;
-
-/**
- * Scroller that gradually reaches a target velocity.
- */
-class RampUpScroller {
-    private final Interpolator mInterpolator;
-    private final long mRampUpTime;
-
-    private long mStartTime;
-    private long mDeltaTime;
-    private float mTargetVelocityX;
-    private float mTargetVelocityY;
-    private int mDeltaX;
-    private int mDeltaY;
-
-    /**
-     * Creates a new ramp-up scroller that reaches full velocity after a
-     * specified duration.
-     *
-     * @param rampUpTime Duration before the scroller reaches target velocity.
-     */
-    public RampUpScroller(long rampUpTime) {
-        mInterpolator = new AccelerateInterpolator();
-        mRampUpTime = rampUpTime;
-    }
-
-    /**
-     * Starts the scroller at the current animation time.
-     */
-    public void start() {
-        mStartTime = AnimationUtils.currentAnimationTimeMillis();
-        mDeltaTime = mStartTime;
-    }
-
-    /**
-     * Computes the current scroll deltas. This usually only be called after
-     * starting the scroller with {@link #start()}.
-     *
-     * @see #getDeltaX()
-     * @see #getDeltaY()
-     */
-    public void computeScrollDelta() {
-        final long currentTime = AnimationUtils.currentAnimationTimeMillis();
-        final long elapsedSinceStart = currentTime - mStartTime;
-        final float scale;
-        if (elapsedSinceStart < mRampUpTime) {
-            scale = mInterpolator.getInterpolation((float) elapsedSinceStart / mRampUpTime);
-        } else {
-            scale = 1f;
-        }
-
-        final long elapsedSinceDelta = currentTime - mDeltaTime;
-        mDeltaTime = currentTime;
-
-        mDeltaX = (int) (elapsedSinceDelta * scale * mTargetVelocityX);
-        mDeltaY = (int) (elapsedSinceDelta * scale * mTargetVelocityY);
-    }
-
-    /**
-     * Sets the target velocity for this scroller.
-     *
-     * @param x The target X velocity in pixels per millisecond.
-     * @param y The target Y velocity in pixels per millisecond.
-     */
-    public void setTargetVelocity(float x, float y) {
-        mTargetVelocityX = x;
-        mTargetVelocityY = y;
-    }
-
-    /**
-     * @return The target X velocity for this scroller.
-     */
-    public float getTargetVelocityX() {
-        return mTargetVelocityX;
-    }
-
-    /**
-     * @return The target Y velocity for this scroller.
-     */
-    public float getTargetVelocityY() {
-        return mTargetVelocityY;
-    }
-
-    /**
-     * The distance traveled in the X-coordinate computed by the last call to
-     * {@link #computeScrollDelta()}.
-     */
-    public int getDeltaX() {
-        return mDeltaX;
-    }
-
-    /**
-     * The distance traveled in the Y-coordinate computed by the last call to
-     * {@link #computeScrollDelta()}.
-     */
-    public int getDeltaY() {
-        return mDeltaY;
-    }
-}
diff --git a/src/com/android/launcher3/ScrimView.java b/src/com/android/launcher3/ScrimView.java
index 6831fe3..68200fe 100644
--- a/src/com/android/launcher3/ScrimView.java
+++ b/src/com/android/launcher3/ScrimView.java
@@ -17,11 +17,8 @@
 package com.android.launcher3;
 
 import android.content.Context;
-import android.content.res.Resources;
-import android.content.res.TypedArray;
 import android.graphics.Rect;
 import android.util.AttributeSet;
-import android.view.View;
 import android.widget.FrameLayout;
 
 public class ScrimView extends FrameLayout implements Insettable {
diff --git a/src/com/android/launcher3/ShortcutInfo.java b/src/com/android/launcher3/ShortcutInfo.java
index dafabb8..660f32c 100644
--- a/src/com/android/launcher3/ShortcutInfo.java
+++ b/src/com/android/launcher3/ShortcutInfo.java
@@ -20,9 +20,9 @@
 import android.content.ContentValues;
 import android.content.Context;
 import android.content.Intent;
+import android.content.pm.PackageInfo;
 import android.content.pm.PackageManager;
 import android.content.pm.PackageManager.NameNotFoundException;
-import android.content.pm.PackageInfo;
 import android.graphics.Bitmap;
 import android.util.Log;
 
@@ -71,7 +71,14 @@
     protected Intent getIntent() {
         return intent;
     }
-    
+
+    ShortcutInfo(Intent intent, CharSequence title, Bitmap icon) {
+        this();
+        this.intent = intent;
+        this.title = title;
+        mIcon = icon;
+    }
+
     public ShortcutInfo(Context context, ShortcutInfo info) {
         super(info);
         title = info.title.toString();
diff --git a/src/com/android/launcher3/SmoothPagedView.java b/src/com/android/launcher3/SmoothPagedView.java
index a45dbbf..4e331aa 100644
--- a/src/com/android/launcher3/SmoothPagedView.java
+++ b/src/com/android/launcher3/SmoothPagedView.java
@@ -19,7 +19,6 @@
 import android.content.Context;
 import android.util.AttributeSet;
 import android.view.animation.Interpolator;
-import android.widget.Scroller;
 
 public abstract class SmoothPagedView extends PagedView {
     private static final float SMOOTHING_SPEED = 0.75f;
@@ -52,8 +51,6 @@
         }
 
         public float getInterpolation(float t) {
-            // _o(t) = t * t * ((tension + 1) * t + tension)
-            // o(t) = _o(t - 1) + 1
             t -= 1.0f;
             return t * t * ((mTension + 1) * t + mTension) + 1.0f;
         }
@@ -102,7 +99,7 @@
             mBaseLineFlingVelocity = 2500.0f;
             mFlingVelocityInfluence = 0.4f;
             mScrollInterpolator = new OvershootInterpolator();
-            mScroller = new Scroller(getContext(), mScrollInterpolator);
+            setDefaultInterpolator(mScrollInterpolator);
         }
     }
 
diff --git a/src/com/android/launcher3/Utilities.java b/src/com/android/launcher3/Utilities.java
index 21c546d..cbc9785 100644
--- a/src/com/android/launcher3/Utilities.java
+++ b/src/com/android/launcher3/Utilities.java
@@ -43,7 +43,7 @@
 /**
  * Various utilities shared amongst the Launcher's classes.
  */
-final class Utilities {
+public final class Utilities {
     private static final String TAG = "Launcher.Utilities";
 
     private static int sIconWidth = -1;
@@ -65,6 +65,12 @@
     static int sColors[] = { 0xffff0000, 0xff00ff00, 0xff0000ff };
     static int sColorIndex = 0;
 
+
+    // To turn on these properties, type
+    // adb shell setprop log.tag.PROPERTY_NAME [VERBOSE | SUPPRESS]
+    static final String FORCE_ENABLE_ROTATION_PROPERTY = "launcher_force_rotate";
+    public static boolean sForceEnableRotation = isPropertyEnabled(FORCE_ENABLE_ROTATION_PROPERTY);
+
     /**
      * Returns a FastBitmapDrawable with the icon, accurately sized.
      */
@@ -82,6 +88,16 @@
         icon.setBounds(0, 0, sIconTextureWidth, sIconTextureHeight);
     }
 
+    private static boolean isPropertyEnabled(String propertyName) {
+        return Log.isLoggable(propertyName, Log.VERBOSE);
+    }
+
+    public static boolean isRotationEnabled(Context c) {
+        boolean enableRotation = sForceEnableRotation ||
+                c.getResources().getBoolean(R.bool.allow_rotation);
+        return enableRotation;
+    }
+
     /**
      * 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)
@@ -111,7 +127,7 @@
     /**
      * Returns a bitmap suitable for the all apps view.
      */
-    static Bitmap createIconBitmap(Drawable icon, Context context) {
+    public static Bitmap createIconBitmap(Drawable icon, Context context) {
         synchronized (sCanvas) { // we share the statics :-(
             if (sIconWidth == -1) {
                 initStatics(context);
diff --git a/src/com/android/launcher3/WallpaperChangedReceiver.java b/src/com/android/launcher3/WallpaperChangedReceiver.java
new file mode 100644
index 0000000..2d5612f
--- /dev/null
+++ b/src/com/android/launcher3/WallpaperChangedReceiver.java
@@ -0,0 +1,29 @@
+/*
+ * Copyright (C) 2013 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.launcher3;
+
+import android.content.BroadcastReceiver;
+import android.content.Context;
+import android.content.Intent;
+
+public class WallpaperChangedReceiver extends BroadcastReceiver {
+    public void onReceive(Context context, Intent data) {
+        LauncherAppState.setApplicationContext(context.getApplicationContext());
+        LauncherAppState appState = LauncherAppState.getInstance();
+        appState.onWallpaperChanged();
+    }
+}
diff --git a/src/com/android/launcher3/WidgetPreviewLoader.java b/src/com/android/launcher3/WidgetPreviewLoader.java
index 07b4f6f..3db0b51 100644
--- a/src/com/android/launcher3/WidgetPreviewLoader.java
+++ b/src/com/android/launcher3/WidgetPreviewLoader.java
@@ -4,11 +4,13 @@
 import android.content.ComponentName;
 import android.content.ContentValues;
 import android.content.Context;
+import android.content.SharedPreferences;
 import android.content.pm.PackageManager;
 import android.content.pm.ResolveInfo;
 import android.content.res.Resources;
 import android.database.Cursor;
 import android.database.sqlite.SQLiteDatabase;
+import android.database.sqlite.SQLiteDiskIOException;
 import android.database.sqlite.SQLiteOpenHelper;
 import android.graphics.Bitmap;
 import android.graphics.Bitmap.Config;
@@ -100,6 +102,7 @@
 
 public class WidgetPreviewLoader {
     static final String TAG = "WidgetPreviewLoader";
+    static final String ANDROID_INCREMENTAL_VERSION_NAME_KEY = "android.incremental.version";
 
     private int mPreviewBitmapWidth;
     private int mPreviewBitmapHeight;
@@ -147,6 +150,26 @@
         mDb = app.getWidgetPreviewCacheDb();
         mLoadedPreviews = new HashMap<String, WeakReference<Bitmap>>();
         mUnusedBitmaps = new ArrayList<SoftReference<Bitmap>>();
+
+        SharedPreferences sp = context.getSharedPreferences(
+                LauncherAppState.getSharedPreferencesKey(), Context.MODE_PRIVATE);
+        final String lastVersionName = sp.getString(ANDROID_INCREMENTAL_VERSION_NAME_KEY, null);
+        final String versionName = android.os.Build.VERSION.INCREMENTAL;
+        if (!versionName.equals(lastVersionName)) {
+            // clear all the previews whenever the system version changes, to ensure that previews
+            // are up-to-date for any apps that might have been updated with the system
+            clearDb();
+
+            SharedPreferences.Editor editor = sp.edit();
+            editor.putString(ANDROID_INCREMENTAL_VERSION_NAME_KEY, versionName);
+            editor.commit();
+        }
+    }
+    
+    public void recreateDb() {
+        LauncherAppState app = LauncherAppState.getInstance();
+        app.recreateWidgetPreviewDb();
+        mDb = app.getWidgetPreviewCacheDb();
     }
 
     public void setPreviewSize(int previewWidth, int previewHeight,
@@ -331,7 +354,20 @@
         preview.compress(Bitmap.CompressFormat.PNG, 100, stream);
         values.put(CacheDb.COLUMN_PREVIEW_BITMAP, stream.toByteArray());
         values.put(CacheDb.COLUMN_SIZE, mSize);
-        db.insert(CacheDb.TABLE_NAME, null, values);
+        try {
+            db.insert(CacheDb.TABLE_NAME, null, values);
+        } catch (SQLiteDiskIOException e) {
+            recreateDb();
+        }
+    }
+
+    private void clearDb() {
+        SQLiteDatabase db = mDb.getWritableDatabase();
+        // Delete everything
+        try {
+            db.delete(CacheDb.TABLE_NAME, null, null);
+        } catch (SQLiteDiskIOException e) {
+        }
     }
 
     public static void removePackageFromDb(final CacheDb cacheDb, final String packageName) {
@@ -341,13 +377,17 @@
         new AsyncTask<Void, Void, Void>() {
             public Void doInBackground(Void ... args) {
                 SQLiteDatabase db = cacheDb.getWritableDatabase();
-                db.delete(CacheDb.TABLE_NAME,
-                        CacheDb.COLUMN_NAME + " LIKE ? OR " +
-                        CacheDb.COLUMN_NAME + " LIKE ?", // SELECT query
-                        new String[] {
-                            WIDGET_PREFIX + packageName + "/%",
-                            SHORTCUT_PREFIX + packageName + "/%"} // args to SELECT query
-                            );
+                try {
+                    db.delete(CacheDb.TABLE_NAME,
+                            CacheDb.COLUMN_NAME + " LIKE ? OR " +
+                            CacheDb.COLUMN_NAME + " LIKE ?", // SELECT query
+                            new String[] {
+                                    WIDGET_PREFIX + packageName + "/%",
+                                    SHORTCUT_PREFIX + packageName + "/%"
+                            } // args to SELECT query
+                    );
+                } catch (SQLiteDiskIOException e) {
+                }
                 synchronized(sInvalidPackages) {
                     sInvalidPackages.remove(packageName);
                 }
@@ -360,9 +400,12 @@
         new AsyncTask<Void, Void, Void>() {
             public Void doInBackground(Void ... args) {
                 SQLiteDatabase db = cacheDb.getWritableDatabase();
-                db.delete(CacheDb.TABLE_NAME,
-                        CacheDb.COLUMN_NAME + " = ? ", // SELECT query
-                        new String[] { objectName }); // args to SELECT query
+                try {
+                    db.delete(CacheDb.TABLE_NAME,
+                            CacheDb.COLUMN_NAME + " = ? ", // SELECT query
+                            new String[] { objectName }); // args to SELECT query
+                } catch (SQLiteDiskIOException e) {
+                }
                 return null;
             }
         }.executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR, (Void) null);
@@ -374,14 +417,20 @@
                     CacheDb.COLUMN_SIZE + " = ?";
         }
         SQLiteDatabase db = mDb.getReadableDatabase();
-        Cursor result = db.query(CacheDb.TABLE_NAME,
-                new String[] { CacheDb.COLUMN_PREVIEW_BITMAP }, // cols to return
-                mCachedSelectQuery, // select query
-                new String[] { name, mSize }, // args to select query
-                null,
-                null,
-                null,
-                null);
+        Cursor result;
+        try {
+            result = db.query(CacheDb.TABLE_NAME,
+                    new String[] { CacheDb.COLUMN_PREVIEW_BITMAP }, // cols to return
+                    mCachedSelectQuery, // select query
+                    new String[] { name, mSize }, // args to select query
+                    null,
+                    null,
+                    null,
+                    null);
+        } catch (SQLiteDiskIOException e) {
+            recreateDb();
+            return null;
+        }
         if (result.getCount() > 0) {
             result.moveToFirst();
             byte[] blob = result.getBlob(0);
diff --git a/src/com/android/launcher3/Workspace.java b/src/com/android/launcher3/Workspace.java
index f6416c8..359fd86 100644
--- a/src/com/android/launcher3/Workspace.java
+++ b/src/com/android/launcher3/Workspace.java
@@ -22,6 +22,7 @@
 import android.animation.AnimatorSet;
 import android.animation.LayoutTransition;
 import android.animation.ObjectAnimator;
+import android.animation.PropertyValuesHolder;
 import android.animation.TimeInterpolator;
 import android.animation.ValueAnimator;
 import android.animation.ValueAnimator.AnimatorUpdateListener;
@@ -30,7 +31,6 @@
 import android.appwidget.AppWidgetProviderInfo;
 import android.content.ComponentName;
 import android.content.Context;
-import android.content.Intent;
 import android.content.SharedPreferences;
 import android.content.res.Resources;
 import android.content.res.TypedArray;
@@ -43,6 +43,7 @@
 import android.graphics.Region.Op;
 import android.graphics.drawable.Drawable;
 import android.net.Uri;
+import android.os.AsyncTask;
 import android.os.IBinder;
 import android.os.Parcelable;
 import android.support.v4.view.ViewCompat;
@@ -54,10 +55,7 @@
 import android.view.MotionEvent;
 import android.view.View;
 import android.view.ViewGroup;
-import android.view.View.OnClickListener;
-import android.view.accessibility.AccessibilityEvent;
 import android.view.accessibility.AccessibilityManager;
-import android.view.accessibility.AccessibilityNodeInfo;
 import android.view.animation.DecelerateInterpolator;
 import android.view.animation.Interpolator;
 import android.widget.TextView;
@@ -89,6 +87,9 @@
     private static final int CHILDREN_OUTLINE_FADE_OUT_DURATION = 375;
     private static final int CHILDREN_OUTLINE_FADE_IN_DURATION = 100;
 
+    protected static final int SNAP_OFF_EMPTY_SCREEN_DURATION = 400;
+    protected static final int FADE_EMPTY_SCREEN_DURATION = 150;
+
     private static final int BACKGROUND_FADE_OUT_DURATION = 350;
     private static final int ADJACENT_SCREEN_DROP_DURATION = 300;
     private static final int FLING_THRESHOLD_VELOCITY = 500;
@@ -128,6 +129,8 @@
     private HashMap<Long, CellLayout> mWorkspaceScreens = new HashMap<Long, CellLayout>();
     private ArrayList<Long> mScreenOrder = new ArrayList<Long>();
 
+    private Runnable mRemoveEmptyScreenRunnable;
+
     /**
      * CellInfo for the cell that is currently being dragged
      */
@@ -178,7 +181,6 @@
     private SpringLoadedDragController mSpringLoadedDragController;
     private float mSpringLoadedShrinkFactor;
     private float mOverviewModeShrinkFactor;
-    private int mOverviewModePageOffset;
 
     // State variable that indicates whether the pages are small (ie when you're
     // in all apps or customize mode)
@@ -214,7 +216,7 @@
 
     // Variables relating to the creation of user folders by hovering shortcuts over shortcuts
     private static final int FOLDER_CREATION_TIMEOUT = 0;
-    private static final int REORDER_TIMEOUT = 250;
+    public static final int REORDER_TIMEOUT = 350;
     private final Alarm mFolderCreationAlarm = new Alarm();
     private final Alarm mReorderAlarm = new Alarm();
     private FolderRingAnimator mDragFolderRingAnimator = null;
@@ -304,17 +306,18 @@
 
         mLauncher = (Launcher) context;
         final Resources res = getResources();
-        mWorkspaceFadeInAdjacentScreens = res.getBoolean(R.bool.config_workspaceFadeAdjacentScreens);
+        mWorkspaceFadeInAdjacentScreens = LauncherAppState.getInstance().getDynamicGrid().
+                getDeviceProfile().shouldFadeAdjacentWorkspaceScreens();
         mFadeInAdjacentScreens = false;
         mWallpaperManager = WallpaperManager.getInstance(context);
 
+        LauncherAppState app = LauncherAppState.getInstance();
+        DeviceProfile grid = app.getDynamicGrid().getDeviceProfile();
         TypedArray a = context.obtainStyledAttributes(attrs,
                 R.styleable.Workspace, defStyle, 0);
         mSpringLoadedShrinkFactor =
             res.getInteger(R.integer.config_workspaceSpringLoadShrinkPercentage) / 100.0f;
-        mOverviewModeShrinkFactor =
-                res.getInteger(R.integer.config_workspaceOverviewShrinkPercentage) / 100.0f;
-        mOverviewModePageOffset = res.getDimensionPixelSize(R.dimen.overview_mode_page_offset);
+        mOverviewModeShrinkFactor = grid.getOverviewModeScale();
         mCameraDistance = res.getInteger(R.integer.config_cameraDistance);
         mOriginalDefaultPage = mDefaultPage = a.getInt(R.styleable.Workspace_defaultScreen, 1);
         a.recycle();
@@ -332,6 +335,14 @@
     @Override
     public void setInsets(Rect insets) {
         mInsets.set(insets);
+
+        CellLayout customScreen = getScreenWithId(CUSTOM_CONTENT_SCREEN_ID);
+        if (customScreen != null) {
+            View customContent = customScreen.getShortcutsAndWidgets().getChildAt(0);
+            if (customContent instanceof Insettable) {
+                ((Insettable) customContent).setInsets(mInsets);
+            }
+        }
     }
 
     // estimate the size of a widget with spans hSpan, vSpan. return MAX_VALUE for each
@@ -392,7 +403,6 @@
         InstallShortcutReceiver.disableAndFlushInstallQueue(getContext());
         UninstallShortcutReceiver.disableAndFlushUninstallQueue(getContext());
 
-        removeExtraEmptyScreen();
         mDragSourceInternal = null;
         mLauncher.onInteractionEnd();
     }
@@ -411,10 +421,8 @@
         setClipChildren(false);
         setClipToPadding(false);
         setChildrenDrawnWithCacheEnabled(true);
-
-        // This is a bit of a hack to account for the fact that we translate the workspace
-        // up a bit, and still need to draw the background covering the whole screen.
-        setMinScale(mOverviewModeShrinkFactor - 0.2f);
+        
+        setMinScale(mOverviewModeShrinkFactor);
         setupLayoutTransition();
 
         final Resources res = getResources();
@@ -430,6 +438,9 @@
 
         mMaxDistanceForFolderCreation = (0.55f * grid.iconSizePx);
         mFlingThresholdVelocity = (int) (FLING_THRESHOLD_VELOCITY * mDensity);
+
+        // Set the wallpaper dimensions when Launcher starts up
+        setWallpaperDimension();
     }
 
     private void setupLayoutTransition() {
@@ -531,6 +542,10 @@
     }
 
     public long insertNewWorkspaceScreen(long screenId, int insertIndex) {
+        // Log to disk
+        Launcher.addDumpLog(TAG, "11683562 - insertNewWorkspaceScreen(): " + screenId +
+                " at index: " + insertIndex, true);
+
         if (mWorkspaceScreens.containsKey(screenId)) {
             throw new RuntimeException("Screen id " + screenId + " already exists!");
         }
@@ -550,6 +565,7 @@
     public void createCustomContentPage() {
         CellLayout customScreen = (CellLayout)
                 mLauncher.getLayoutInflater().inflate(R.layout.workspace_screen, null);
+        customScreen.disableBackground();
 
         mWorkspaceScreens.put(CUSTOM_CONTENT_SCREEN_ID, customScreen);
         mScreenOrder.add(0, CUSTOM_CONTENT_SCREEN_ID);
@@ -563,7 +579,7 @@
         mDefaultPage = mOriginalDefaultPage + 1;
 
         // Update the custom content hint
-        mLauncher.updateCustomContentHintVisibility();
+        mLauncher.getLauncherClings().updateCustomContentHintVisibility();
         if (mRestorePage != INVALID_RESTORE_PAGE) {
             mRestorePage = mRestorePage + 1;
         } else {
@@ -592,7 +608,7 @@
         mDefaultPage = mOriginalDefaultPage - 1;
 
         // Update the custom content hint
-        mLauncher.updateCustomContentHintVisibility();
+        mLauncher.getLauncherClings().updateCustomContentHintVisibility();
         if (mRestorePage != INVALID_RESTORE_PAGE) {
             mRestorePage = mRestorePage - 1;
         } else {
@@ -616,6 +632,12 @@
         if (customContent instanceof Insettable) {
             ((Insettable)customContent).setInsets(mInsets);
         }
+
+        // Verify that the child is removed from any existing parent.
+        if (customContent.getParent() instanceof ViewGroup) {
+            ViewGroup parent = (ViewGroup) customContent.getParent();
+            parent.removeView(customContent);
+        }
         customScreen.removeAllViews();
         customScreen.addViewToCellLayout(customContent, 0, 0, lp, true);
         mCustomContentDescription = description;
@@ -624,9 +646,15 @@
     }
 
     public void addExtraEmptyScreenOnDrag() {
+        // Log to disk
+        Launcher.addDumpLog(TAG, "11683562 - addExtraEmptyScreenOnDrag()", true);
+
         boolean lastChildOnScreen = false;
         boolean childOnFinalScreen = false;
 
+        // Cancel any pending removal of empty screen
+        mRemoveEmptyScreenRunnable = null;
+
         if (mDragSourceInternal != null) {
             if (mDragSourceInternal.getChildCount() == 1) {
                 lastChildOnScreen = true;
@@ -647,6 +675,9 @@
     }
 
     public boolean addExtraEmptyScreen() {
+        // Log to disk
+        Launcher.addDumpLog(TAG, "11683562 - addExtraEmptyScreen()", true);
+
         if (!mWorkspaceScreens.containsKey(EXTRA_EMPTY_SCREEN_ID)) {
             insertNewWorkspaceScreen(EXTRA_EMPTY_SCREEN_ID);
             return true;
@@ -654,15 +685,115 @@
         return false;
     }
 
-    public void removeExtraEmptyScreen() {
-        if (hasExtraEmptyScreen()) {
-            CellLayout cl = mWorkspaceScreens.get(EXTRA_EMPTY_SCREEN_ID);
-            mWorkspaceScreens.remove(EXTRA_EMPTY_SCREEN_ID);
-            mScreenOrder.remove(EXTRA_EMPTY_SCREEN_ID);
-            removeView(cl);
+    private void convertFinalScreenToEmptyScreenIfNecessary() {
+        // Log to disk
+        Launcher.addDumpLog(TAG, "11683562 - convertFinalScreenToEmptyScreenIfNecessary()", true);
+
+        if (hasExtraEmptyScreen() || mScreenOrder.size() == 0) return;
+        long finalScreenId = mScreenOrder.get(mScreenOrder.size() - 1);
+
+        if (finalScreenId == CUSTOM_CONTENT_SCREEN_ID) return;
+        CellLayout finalScreen = mWorkspaceScreens.get(finalScreenId);
+
+        // If the final screen is empty, convert it to the extra empty screen
+        if (finalScreen.getShortcutsAndWidgets().getChildCount() == 0 &&
+                !finalScreen.isDropPending()) {
+            mWorkspaceScreens.remove(finalScreenId);
+            mScreenOrder.remove(finalScreenId);
+
+            // if this is the last non-custom content screen, convert it to the empty screen
+            mWorkspaceScreens.put(EXTRA_EMPTY_SCREEN_ID, finalScreen);
+            mScreenOrder.add(EXTRA_EMPTY_SCREEN_ID);
+
+            // Update the model if we have changed any screens
+            mLauncher.getModel().updateWorkspaceScreenOrder(mLauncher, mScreenOrder);
+            Launcher.addDumpLog(TAG, "11683562 -   extra empty screen: " + finalScreenId, true);
         }
     }
 
+    public void removeExtraEmptyScreen(final boolean animate, final Runnable onComplete) {
+        removeExtraEmptyScreen(animate, onComplete, 0, false);
+    }
+
+    public void removeExtraEmptyScreen(final boolean animate, final Runnable onComplete,
+            final int delay, final boolean stripEmptyScreens) {
+        // Log to disk
+        Launcher.addDumpLog(TAG, "11683562 - removeExtraEmptyScreen()", true);
+        if (delay > 0) {
+            postDelayed(new Runnable() {
+                @Override
+                public void run() {
+                    removeExtraEmptyScreen(animate, onComplete, 0, stripEmptyScreens);
+                }
+
+            }, delay);
+            return;
+        }
+
+        convertFinalScreenToEmptyScreenIfNecessary();
+        if (hasExtraEmptyScreen()) {
+            int emptyIndex = mScreenOrder.indexOf(EXTRA_EMPTY_SCREEN_ID);
+            if (getNextPage() == emptyIndex) {
+                snapToPage(getNextPage() - 1, SNAP_OFF_EMPTY_SCREEN_DURATION);
+                fadeAndRemoveEmptyScreen(SNAP_OFF_EMPTY_SCREEN_DURATION, FADE_EMPTY_SCREEN_DURATION,
+                        onComplete, stripEmptyScreens);
+            } else {
+                fadeAndRemoveEmptyScreen(0, FADE_EMPTY_SCREEN_DURATION,
+                        onComplete, stripEmptyScreens);
+            }
+            return;
+        } else if (stripEmptyScreens) {
+            // If we're not going to strip the empty screens after removing
+            // the extra empty screen, do it right away.
+            stripEmptyScreens();
+        }
+
+        if (onComplete != null) {
+            onComplete.run();
+        }
+    }
+
+    private void fadeAndRemoveEmptyScreen(int delay, int duration, final Runnable onComplete,
+            final boolean stripEmptyScreens) {
+        // Log to disk
+        // XXX: Do we need to update LM workspace screens below?
+        Launcher.addDumpLog(TAG, "11683562 - fadeAndRemoveEmptyScreen()", true);
+        PropertyValuesHolder alpha = PropertyValuesHolder.ofFloat("alpha", 0f);
+        PropertyValuesHolder bgAlpha = PropertyValuesHolder.ofFloat("backgroundAlpha", 0f);
+
+        final CellLayout cl = mWorkspaceScreens.get(EXTRA_EMPTY_SCREEN_ID);
+
+        mRemoveEmptyScreenRunnable = new Runnable() {
+            @Override
+            public void run() {
+                if (hasExtraEmptyScreen()) {
+                    mWorkspaceScreens.remove(EXTRA_EMPTY_SCREEN_ID);
+                    mScreenOrder.remove(EXTRA_EMPTY_SCREEN_ID);
+                    removeView(cl);
+                    if (stripEmptyScreens) {
+                        stripEmptyScreens();
+                    }
+                }
+            }
+        };
+
+        ObjectAnimator oa = ObjectAnimator.ofPropertyValuesHolder(cl, alpha, bgAlpha);
+        oa.setDuration(duration);
+        oa.setStartDelay(delay);
+        oa.addListener(new AnimatorListenerAdapter() {
+            @Override
+            public void onAnimationEnd(Animator animation) {
+                if (mRemoveEmptyScreenRunnable != null) {
+                    mRemoveEmptyScreenRunnable.run();
+                }
+                if (onComplete != null) {
+                    onComplete.run();
+                }
+            }
+        });
+        oa.start();
+    }
+
     public boolean hasExtraEmptyScreen() {
         int nScreens = getChildCount();
         nScreens = nScreens - numCustomPages();
@@ -670,6 +801,9 @@
     }
 
     public long commitExtraEmptyScreen() {
+        // Log to disk
+        Launcher.addDumpLog(TAG, "11683562 - commitExtraEmptyScreen()", true);
+
         int index = getPageIndexForScreenId(EXTRA_EMPTY_SCREEN_ID);
         CellLayout cl = mWorkspaceScreens.get(EXTRA_EMPTY_SCREEN_ID);
         mWorkspaceScreens.remove(EXTRA_EMPTY_SCREEN_ID);
@@ -722,6 +856,9 @@
     }
 
     public void stripEmptyScreens() {
+        // Log to disk
+        Launcher.addDumpLog(TAG, "11683562 - stripEmptyScreens()", true);
+
         if (isPageMoving()) {
             mStripScreensOnPageStopMoving = true;
             return;
@@ -742,6 +879,7 @@
 
         int pageShift = 0;
         for (Long id: removeScreens) {
+            Launcher.addDumpLog(TAG, "11683562 -   removing id: " + id, true);
             CellLayout cl = mWorkspaceScreens.get(id);
             mWorkspaceScreens.remove(id);
             mScreenOrder.remove(id);
@@ -753,6 +891,7 @@
                 removeView(cl);
             } else {
                 // if this is the last non-custom content screen, convert it to the empty screen
+                mRemoveEmptyScreenRunnable = null;
                 mWorkspaceScreens.put(EXTRA_EMPTY_SCREEN_ID, cl);
                 mScreenOrder.add(EXTRA_EMPTY_SCREEN_ID);
             }
@@ -859,7 +998,9 @@
         }
 
         // Get the canonical child id to uniquely represent this view in this screen
-        int childId = LauncherModel.getCellLayoutChildId(container, screenId, x, y, spanX, spanY);
+        ItemInfo info = (ItemInfo) child.getTag();
+        int childId = mLauncher.getViewIdForItem(info);
+
         boolean markCellsAsOccupied = !(child instanceof Folder);
         if (!layout.addViewToCellLayout(child, insert ? 0 : -1, childId, lp, markCellsAsOccupied)) {
             // TODO: This branch occurs when the workspace is adding views
@@ -1015,11 +1156,6 @@
             }
         }
 
-        // Only show page outlines as we pan if we are on large screen
-        if (LauncherAppState.getInstance().isScreenLarge()) {
-            showOutlines();
-        }
-
         // If we are not fading in adjacent screens, we still need to restore the alpha in case the
         // user scrolls while we are transitioning (should not affect dispatchDraw optimizations)
         if (!mWorkspaceFadeInAdjacentScreens) {
@@ -1044,11 +1180,6 @@
                 // is under a new page (to scroll to)
                 mDragController.forceTouchMove();
             }
-        } else {
-            // If we are not mid-dragging, hide the page outlines if we are on a large screen
-            if (LauncherAppState.getInstance().isScreenLarge()) {
-                hideOutlines();
-            }
         }
 
         if (mDelayedResizeRunnable != null) {
@@ -1069,7 +1200,7 @@
     @Override
     protected void notifyPageSwitchListener() {
         super.notifyPageSwitchListener();
-        Launcher.setScreen(mCurrentPage);
+        Launcher.setScreen(getNextPage());
 
         if (hasCustomContent() && getNextPage() == 0 && !mCustomContentShowing) {
             mCustomContentShowing = true;
@@ -1096,18 +1227,28 @@
     }
 
     protected void setWallpaperDimension() {
-        String spKey = WallpaperCropActivity.getSharedPreferencesKey();
-        SharedPreferences sp = mLauncher.getSharedPreferences(spKey, Context.MODE_PRIVATE);
-        WallpaperPickerActivity.suggestWallpaperDimension(mLauncher.getResources(),
-                sp, mLauncher.getWindowManager(), mWallpaperManager);
+        new AsyncTask<Void, Void, Void>() {
+            public Void doInBackground(Void ... args) {
+                String spKey = WallpaperCropActivity.getSharedPreferencesKey();
+                SharedPreferences sp =
+                        mLauncher.getSharedPreferences(spKey, Context.MODE_MULTI_PROCESS);
+                LauncherWallpaperPickerActivity.suggestWallpaperDimension(mLauncher.getResources(),
+                        sp, mLauncher.getWindowManager(), mWallpaperManager);
+                return null;
+            }
+        }.executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR, (Void) null);
     }
 
     protected void snapToPage(int whichPage, Runnable r) {
+        snapToPage(whichPage, SLOW_PAGE_SNAP_ANIMATION_DURATION, r);
+    }
+
+    protected void snapToPage(int whichPage, int duration, Runnable r) {
         if (mDelayedSnapToPageRunnable != null) {
             mDelayedSnapToPageRunnable.run();
         }
         mDelayedSnapToPageRunnable = r;
-        snapToPage(whichPage, SLOW_PAGE_SNAP_ANIMATION_DURATION);
+        snapToPage(whichPage, duration);
     }
 
     protected void snapToScreenId(long screenId, Runnable r) {
@@ -1199,10 +1340,8 @@
                 // TODO: do different behavior if it's  a live wallpaper?
                 // Sometimes the left parameter of the pages is animated during a layout transition;
                 // this parameter offsets it to keep the wallpaper from animating as well
-                int offsetForLayoutTransitionAnimation = isLayoutRtl() ?
-                        getPageAt(getChildCount() - 1).getLeft() - getFirstChildLeft() : 0;
                 int adjustedScroll =
-                        getScrollX() - firstPageScrollX - offsetForLayoutTransitionAnimation;
+                        getScrollX() - firstPageScrollX - getLayoutTransitionOffsetForPage(0);
                 float offset = Math.min(1, adjustedScroll / (float) scrollRange);
                 offset = Math.max(0, offset);
                 // Don't use up all the wallpaper parallax until you have at least
@@ -1389,18 +1528,12 @@
                 mState == State.NORMAL &&
                 !mIsSwitchingState &&
                 !isInOverscroll) {
-            for (int i = 0; i < getChildCount(); i++) {
+            for (int i = numCustomPages(); i < getChildCount(); i++) {
                 CellLayout child = (CellLayout) getChildAt(i);
                 if (child != null) {
                     float scrollProgress = getScrollProgress(screenCenter, child, i);
                     float alpha = 1 - Math.abs(scrollProgress);
                     child.getShortcutsAndWidgets().setAlpha(alpha);
-                    if (!mIsDragOccuring) {
-                        child.setBackgroundAlphaMultiplier(
-                                backgroundAlphaInterpolator(Math.abs(scrollProgress)));
-                    } else {
-                        child.setBackgroundAlphaMultiplier(1f);
-                    }
                 }
             }
         }
@@ -1524,7 +1657,7 @@
                 cl.setOverscrollTransformsDirty(true);
             }
         } else {
-            if (mOverscrollTransformsSet) {
+            if (mOverscrollTransformsSet && getChildCount() > 0) {
                 mOverscrollTransformsSet = false;
                 ((CellLayout) getChildAt(0)).resetOverscrollTransforms();
                 ((CellLayout) getChildAt(getChildCount() - 1)).resetOverscrollTransforms();
@@ -1561,6 +1694,12 @@
         AccessibilityManager am = (AccessibilityManager)
                 getContext().getSystemService(Context.ACCESSIBILITY_SERVICE);
         sAccessibilityEnabled = am.isEnabled();
+
+        // Update wallpaper dimensions if they were changed since last onResume
+        // (we also always set the wallpaper dimensions in the constructor)
+        if (LauncherAppState.getInstance().hasWallpaperChangedSinceLastCheck()) {
+            setWallpaperDimension();
+        }
     }
 
     @Override
@@ -1909,14 +2048,17 @@
     }
 
     int getOverviewModeTranslationY() {
-        int childHeight = getNormalChildHeight();
-        int viewPortHeight = getViewportHeight();
-        int scaledChildHeight = (int) (mOverviewModeShrinkFactor * childHeight);
+        LauncherAppState app = LauncherAppState.getInstance();
+        DeviceProfile grid = app.getDynamicGrid().getDeviceProfile();
+        Rect overviewBar = grid.getOverviewModeButtonBarRect();
 
-        int offset = (viewPortHeight - scaledChildHeight) / 2;
-        int offsetDelta = mOverviewModePageOffset - offset + mInsets.top;
+        int availableHeight = getViewportHeight();
+        int scaledHeight = (int) (mOverviewModeShrinkFactor * getNormalChildHeight());
+        int offsetFromTopEdge = (availableHeight - scaledHeight) / 2;
+        int offsetToCenterInOverview = (availableHeight - mInsets.top - overviewBar.height()
+                - scaledHeight) / 2;
 
-        return offsetDelta;
+        return -offsetFromTopEdge + mInsets.top + offsetToCenterInOverview;
     }
 
     boolean shouldVoiceButtonProxyBeVisible() {
@@ -1984,7 +2126,7 @@
         mNewScale = 1.0f;
 
         if (oldStateIsOverview) {
-            disableFreeScroll(snapPage);
+            disableFreeScroll();
         } else if (stateIsOverview) {
             enableFreeScroll();
         }
@@ -2011,11 +2153,23 @@
             duration = getResources().getInteger(R.integer.config_appsCustomizeWorkspaceShrinkTime);
         }
 
+        if (snapPage == -1) {
+            snapPage = getPageNearestToCenterOfScreen();
+        }
+        snapToPage(snapPage, duration, mZoomInInterpolator);
+
         for (int i = 0; i < getChildCount(); i++) {
             final CellLayout cl = (CellLayout) getChildAt(i);
-            boolean isCurrentPage = (i == getNextPage());
+            boolean isCurrentPage = (i == snapPage);
             float initialAlpha = cl.getShortcutsAndWidgets().getAlpha();
-            float finalAlpha = stateIsSmall ? 0f : 1f;
+            float finalAlpha;
+            if (stateIsSmall) {
+                finalAlpha = 0f;
+            } else if (stateIsNormal && mWorkspaceFadeInAdjacentScreens) {
+                finalAlpha = (i == snapPage || i < numCustomPages()) ? 1f : 0f;
+            } else {
+                finalAlpha = 1f;
+            }
 
             // If we are animating to/from the small state, then hide the side pages and fade the
             // current page in
@@ -2044,6 +2198,7 @@
         final View searchBar = mLauncher.getQsbBar();
         final View overviewPanel = mLauncher.getOverviewPanel();
         final View hotseat = mLauncher.getHotseat();
+        final View pageIndicator = getPageIndicator();
         if (animated) {
             anim.setDuration(duration);
             LauncherViewPropertyAnimator scale = new LauncherViewPropertyAnimator(this);
@@ -2083,31 +2238,38 @@
                     }
                 }
             }
-            ObjectAnimator pageIndicatorAlpha = null;
-            if (getPageIndicator() != null) {
-                pageIndicatorAlpha = ObjectAnimator.ofFloat(getPageIndicator(), "alpha",
-                        finalHotseatAndPageIndicatorAlpha);
+            Animator pageIndicatorAlpha = null;
+            if (pageIndicator != null) {
+                pageIndicatorAlpha = new LauncherViewPropertyAnimator(pageIndicator)
+                    .alpha(finalHotseatAndPageIndicatorAlpha).withLayer();
+                pageIndicatorAlpha.addListener(new AlphaUpdateListener(pageIndicator));
+            } else {
+                // create a dummy animation so we don't need to do null checks later
+                pageIndicatorAlpha = ValueAnimator.ofFloat(0, 0);
             }
-            ObjectAnimator hotseatAlpha = ObjectAnimator.ofFloat(hotseat, "alpha",
-                    finalHotseatAndPageIndicatorAlpha);
-            ObjectAnimator searchBarAlpha = ObjectAnimator.ofFloat(searchBar,
-                    "alpha", finalSearchBarAlpha);
-            ObjectAnimator overviewPanelAlpha = ObjectAnimator.ofFloat(overviewPanel,
-                    "alpha", finalOverviewPanelAlpha);
 
-            overviewPanelAlpha.addListener(new AlphaUpdateListener(overviewPanel));
+            Animator hotseatAlpha = new LauncherViewPropertyAnimator(hotseat)
+                .alpha(finalHotseatAndPageIndicatorAlpha).withLayer();
             hotseatAlpha.addListener(new AlphaUpdateListener(hotseat));
+
+            Animator searchBarAlpha = new LauncherViewPropertyAnimator(searchBar)
+                .alpha(finalSearchBarAlpha).withLayer();
             searchBarAlpha.addListener(new AlphaUpdateListener(searchBar));
 
+            Animator overviewPanelAlpha = new LauncherViewPropertyAnimator(overviewPanel)
+                .alpha(finalOverviewPanelAlpha).withLayer();
+            overviewPanelAlpha.addListener(new AlphaUpdateListener(overviewPanel));
+
             if (workspaceToOverview) {
+                pageIndicatorAlpha.setInterpolator(new DecelerateInterpolator(2));
                 hotseatAlpha.setInterpolator(new DecelerateInterpolator(2));
+                overviewPanelAlpha.setInterpolator(null);
             } else if (overviewToWorkspace) {
+                pageIndicatorAlpha.setInterpolator(null);
+                hotseatAlpha.setInterpolator(null);
                 overviewPanelAlpha.setInterpolator(new DecelerateInterpolator(2));
             }
-
-            if (getPageIndicator() != null) {
-                pageIndicatorAlpha.addListener(new AlphaUpdateListener(getPageIndicator()));
-            }
+            searchBarAlpha.setInterpolator(null);
 
             anim.play(overviewPanelAlpha);
             anim.play(hotseatAlpha);
@@ -2119,9 +2281,9 @@
             AlphaUpdateListener.updateVisibility(overviewPanel);
             hotseat.setAlpha(finalHotseatAndPageIndicatorAlpha);
             AlphaUpdateListener.updateVisibility(hotseat);
-            if (getPageIndicator() != null) {
-                getPageIndicator().setAlpha(finalHotseatAndPageIndicatorAlpha);
-                AlphaUpdateListener.updateVisibility(getPageIndicator());
+            if (pageIndicator != null) {
+                pageIndicator.setAlpha(finalHotseatAndPageIndicatorAlpha);
+                AlphaUpdateListener.updateVisibility(pageIndicator);
             }
             searchBar.setAlpha(finalSearchBarAlpha);
             AlphaUpdateListener.updateVisibility(searchBar);
@@ -2237,7 +2399,9 @@
     void hideCustomContentIfNecessary() {
         boolean hide  = mState != Workspace.State.NORMAL;
         if (hide && hasCustomContent()) {
+            disableLayoutTransitions();
             mWorkspaceScreens.get(CUSTOM_CONTENT_SCREEN_ID).setVisibility(INVISIBLE);
+            enableLayoutTransitions();
         }
     }
 
@@ -2253,6 +2417,11 @@
                 final CellLayout cl = (CellLayout) getChildAt(i);
                 cl.setShortcutAndWidgetAlpha(1f);
             }
+        } else {
+            for (int i = 0; i < numCustomPages(); i++) {
+                final CellLayout cl = (CellLayout) getChildAt(i);
+                cl.setShortcutAndWidgetAlpha(1f);
+            }
         }
         showCustomContentIfNecessary();
     }
@@ -2440,8 +2609,16 @@
             icon.clearPressedOrFocusedBackground();
         }
 
-        mDragController.startDrag(b, dragLayerX, dragLayerY, source, child.getTag(),
+        if (child.getTag() == null || !(child.getTag() instanceof ItemInfo)) {
+            String msg = "Drag started with a view that has no tag set. This "
+                    + "will cause a crash (issue 11627249) down the line. "
+                    + "View: " + child + "  tag: " + child.getTag();
+            throw new IllegalStateException(msg);
+        }
+
+        DragView dv = mDragController.startDrag(b, dragLayerX, dragLayerY, source, child.getTag(),
                 DragController.DRAG_ACTION_MOVE, dragVisualizeOffset, dragRect, scale);
+        dv.setIntrinsicIconScaleFactor(source.getIntrinsicIconScaleFactor());
 
         if (child.getParent() instanceof ShortcutAndWidgetContainer) {
             mDragSourceInternal = (ShortcutAndWidgetContainer) child.getParent();
@@ -2523,7 +2700,7 @@
             }
 
             int[] resultSpan = new int[2];
-            mTargetCell = dropTargetLayout.createArea((int) mDragViewVisualCenter[0],
+            mTargetCell = dropTargetLayout.performReorder((int) mDragViewVisualCenter[0],
                     (int) mDragViewVisualCenter[1], minSpanX, minSpanY, spanX, spanY,
                     null, mTargetCell, resultSpan, CellLayout.MODE_ACCEPT_DROP);
             boolean foundCell = mTargetCell[0] >= 0 && mTargetCell[1] >= 0;
@@ -2728,13 +2905,13 @@
                 // cell also contains a shortcut, then create a folder with the two shortcuts.
                 if (!mInScrollArea && createUserFolderIfNecessary(cell, container,
                         dropTargetLayout, mTargetCell, distance, false, d.dragView, null)) {
-                    stripEmptyScreens();
+                    removeExtraEmptyScreen(true, null, 0, true);
                     return;
                 }
 
                 if (addToExistingFolderIfNecessary(cell, dropTargetLayout, mTargetCell,
                         distance, d, false)) {
-                    stripEmptyScreens();
+                    removeExtraEmptyScreen(true, null, 0, true);
                     return;
                 }
 
@@ -2749,7 +2926,7 @@
                 }
 
                 int[] resultSpan = new int[2];
-                mTargetCell = dropTargetLayout.createArea((int) mDragViewVisualCenter[0],
+                mTargetCell = dropTargetLayout.performReorder((int) mDragViewVisualCenter[0],
                         (int) mDragViewVisualCenter[1], minSpanX, minSpanY, spanX, spanY, cell,
                         mTargetCell, resultSpan, CellLayout.MODE_ON_DROP);
 
@@ -2787,8 +2964,6 @@
                     lp.cellHSpan = item.spanX;
                     lp.cellVSpan = item.spanY;
                     lp.isLockedToGrid = true;
-                    cell.setId(LauncherModel.getCellLayoutChildId(container, mDragInfo.screenId,
-                            mTargetCell[0], mTargetCell[1], mDragInfo.spanX, mDragInfo.spanY));
 
                     if (container != LauncherSettings.Favorites.CONTAINER_HOTSEAT &&
                             cell instanceof LauncherAppWidgetHostView) {
@@ -2842,7 +3017,7 @@
                     if (finalResizeRunnable != null) {
                         finalResizeRunnable.run();
                     }
-                    stripEmptyScreens();
+                    removeExtraEmptyScreen(true, null, 0, true);
                 }
             };
             mAnimatingViewIntoPlace = true;
@@ -2931,13 +3106,11 @@
         display.getCurrentSizeRange(smallestSize, largestSize);
         int countX = (int) grid.numColumns;
         int countY = (int) grid.numRows;
-        int constrainedLongEdge = largestSize.y;
-        int constrainedShortEdge = smallestSize.y;
         if (orientation == CellLayout.LANDSCAPE) {
             if (mLandscapeCellLayoutMetrics == null) {
                 Rect padding = grid.getWorkspacePadding(CellLayout.LANDSCAPE);
-                int width = constrainedLongEdge - padding.left - padding.right;
-                int height = constrainedShortEdge - padding.top - padding.bottom;
+                int width = largestSize.x - padding.left - padding.right;
+                int height = smallestSize.y - padding.top - padding.bottom;
                 mLandscapeCellLayoutMetrics = new Rect();
                 mLandscapeCellLayoutMetrics.set(
                         grid.calculateCellWidth(width, countX),
@@ -2947,8 +3120,8 @@
         } else if (orientation == CellLayout.PORTRAIT) {
             if (mPortraitCellLayoutMetrics == null) {
                 Rect padding = grid.getWorkspacePadding(CellLayout.PORTRAIT);
-                int width = constrainedShortEdge - padding.left - padding.right;
-                int height = constrainedLongEdge - padding.top - padding.bottom;
+                int width = smallestSize.x - padding.left - padding.right;
+                int height = largestSize.y - padding.top - padding.bottom;
                 mPortraitCellLayoutMetrics = new Rect();
                 mPortraitCellLayoutMetrics.set(
                         grid.calculateCellWidth(width, countX),
@@ -3333,6 +3506,11 @@
                     && !mReorderAlarm.alarmPending() && (mLastReorderX != reorderX ||
                     mLastReorderY != reorderY)) {
 
+                int[] resultSpan = new int[2];
+                mDragTargetLayout.performReorder((int) mDragViewVisualCenter[0],
+                        (int) mDragViewVisualCenter[1], minSpanX, minSpanY, item.spanX, item.spanY,
+                        child, mTargetCell, resultSpan, CellLayout.MODE_SHOW_REORDER_HINT);
+
                 // Otherwise, if we aren't adding to or creating a folder and there's no pending
                 // reorder, then we schedule a reorder
                 ReorderAlarmListener listener = new ReorderAlarmListener(mDragViewVisualCenter,
@@ -3437,7 +3615,7 @@
             mLastReorderX = mTargetCell[0];
             mLastReorderY = mTargetCell[1];
 
-            mTargetCell = mDragTargetLayout.createArea((int) mDragViewVisualCenter[0],
+            mTargetCell = mDragTargetLayout.performReorder((int) mDragViewVisualCenter[0],
                 (int) mDragViewVisualCenter[1], minSpanX, minSpanY, spanX, spanY,
                 child, mTargetCell, resultSpan, CellLayout.MODE_DRAG_OVER);
 
@@ -3493,7 +3671,13 @@
         final Runnable exitSpringLoadedRunnable = new Runnable() {
             @Override
             public void run() {
-                mLauncher.exitSpringLoadedDragModeDelayed(true, false, null);
+                removeExtraEmptyScreen(false, new Runnable() {
+                    @Override
+                    public void run() {
+                        mLauncher.exitSpringLoadedDragModeDelayed(true,
+                                Launcher.EXIT_SPRINGLOADED_MODE_SHORT_TIMEOUT, null);
+                    }
+                });
             }
         };
 
@@ -3541,7 +3725,7 @@
                     minSpanY = item.minSpanY;
                 }
                 int[] resultSpan = new int[2];
-                mTargetCell = cellLayout.createArea((int) mDragViewVisualCenter[0],
+                mTargetCell = cellLayout.performReorder((int) mDragViewVisualCenter[0],
                         (int) mDragViewVisualCenter[1], minSpanX, minSpanY, info.spanX, info.spanY,
                         null, mTargetCell, resultSpan, CellLayout.MODE_ON_DROP_EXTERNAL);
 
@@ -3633,7 +3817,7 @@
 
             if (touchXY != null) {
                 // when dragging and dropping, just find the closest free spot
-                mTargetCell = cellLayout.createArea((int) mDragViewVisualCenter[0],
+                mTargetCell = cellLayout.performReorder((int) mDragViewVisualCenter[0],
                         (int) mDragViewVisualCenter[1], 1, 1, 1, 1,
                         null, mTargetCell, null, CellLayout.MODE_ON_DROP_EXTERNAL);
             } else {
@@ -3654,7 +3838,7 @@
                 // the correct final location.
                 setFinalTransitionTransform(cellLayout);
                 mLauncher.getDragLayer().animateViewIntoPosition(d.dragView, view,
-                        exitSpringLoadedRunnable);
+                        exitSpringLoadedRunnable, this);
                 resetTransitionTransform(cellLayout);
             }
         }
@@ -3729,7 +3913,7 @@
                 external, scalePreview);
 
         Resources res = mLauncher.getResources();
-        int duration = res.getInteger(R.integer.config_dropAnimMaxDuration) - 200;
+        final int duration = res.getInteger(R.integer.config_dropAnimMaxDuration) - 200;
 
         // In the case where we've prebound the widget, we remove it from the DragLayer
         if (finalView instanceof AppWidgetHostView && external) {
@@ -3805,7 +3989,7 @@
         return mDragInfo;
     }
 
-    public int getRestorePage() {
+    public int getCurrentPageOffsetFromCustomContent() {
         return getNextPage() - numCustomPages();
     }
 
@@ -3827,7 +4011,6 @@
         // hardware layers on children are enabled on startup, but should be disabled until
         // needed
         updateChildrenLayersEnabled(false);
-        setWallpaperDimension();
     }
 
     /**
@@ -3837,11 +4020,11 @@
             final boolean isFlingToDelete, final boolean success) {
         if (mDeferDropAfterUninstall) {
             mDeferredAction = new Runnable() {
-                    public void run() {
-                        onDropCompleted(target, d, isFlingToDelete, success);
-                        mDeferredAction = null;
-                    }
-                };
+                public void run() {
+                    onDropCompleted(target, d, isFlingToDelete, success);
+                    mDeferredAction = null;
+                }
+            };
             return;
         }
 
@@ -3859,7 +4042,7 @@
                 // If we move the item to anything not on the Workspace, check if any empty
                 // screens need to be removed. If we dropped back on the workspace, this will
                 // be done post drop animation.
-                stripEmptyScreens();
+                removeExtraEmptyScreen(true, null, 0, true);
             }
         } else if (mDragInfo != null) {
             CellLayout cellLayout;
@@ -3868,7 +4051,13 @@
             } else {
                 cellLayout = getScreenWithId(mDragInfo.screenId);
             }
-            cellLayout.onDropChild(mDragInfo.cell);
+            if (cellLayout == null && LauncherAppState.isDogfoodBuild()) {
+                throw new RuntimeException("Invalid state: cellLayout == null in "
+                        + "Workspace#onDropCompleted. Please file a bug. ");
+            }
+            if (cellLayout != null) {
+                cellLayout.onDropChild(mDragInfo.cell);
+            }
         }
         if ((d.cancelled || (beingCalledAfterUninstall && !mUninstallSuccessful))
                 && mDragInfo.cell != null) {
@@ -4039,11 +4228,26 @@
     }
 
     @Override
+    public float getIntrinsicIconScaleFactor() {
+        return 1f;
+    }
+
+    @Override
     public boolean supportsFlingToDelete() {
         return true;
     }
 
     @Override
+    public boolean supportsAppInfoDropTarget() {
+        return false;
+    }
+
+    @Override
+    public boolean supportsDeleteDropTarget() {
+        return true;
+    }
+
+    @Override
     public void onFlingToDelete(DragObject d, int x, int y, PointF vec) {
         // Do nothing
     }
@@ -4075,7 +4279,9 @@
         if (mSavedStates != null) {
             mRestoredPages.add(child);
             CellLayout cl = (CellLayout) getChildAt(child);
-            cl.restoreInstanceState(mSavedStates);
+            if (cl != null) {
+                cl.restoreInstanceState(mSavedStates);
+            }
         }
     }
 
@@ -4384,29 +4590,45 @@
         stripEmptyScreens();
     }
 
+    private void updateShortcut(HashMap<ComponentName, AppInfo> appsMap, ItemInfo info,
+                                View child) {
+        ComponentName cn = info.getIntent().getComponent();
+        if (cn != null) {
+            AppInfo appInfo = appsMap.get(info.getIntent().getComponent());
+            if ((appInfo != null) && LauncherModel.isShortcutInfoUpdateable(info)) {
+                ShortcutInfo shortcutInfo = (ShortcutInfo) info;
+                BubbleTextView shortcut = (BubbleTextView) child;
+                shortcutInfo.updateIcon(mIconCache);
+                shortcutInfo.title = appInfo.title.toString();
+                shortcut.applyFromShortcutInfo(shortcutInfo, mIconCache);
+            }
+        }
+    }
+
     void updateShortcuts(ArrayList<AppInfo> apps) {
+        // Create a map of the apps to test against
+        final HashMap<ComponentName, AppInfo> appsMap = new HashMap<ComponentName, AppInfo>();
+        for (AppInfo ai : apps) {
+            appsMap.put(ai.componentName, ai);
+        }
+
         ArrayList<ShortcutAndWidgetContainer> childrenLayouts = getAllShortcutAndWidgetContainers();
         for (ShortcutAndWidgetContainer layout: childrenLayouts) {
-            int childCount = layout.getChildCount();
-            for (int j = 0; j < childCount; j++) {
-                final View view = layout.getChildAt(j);
-                Object tag = view.getTag();
-
-                if (LauncherModel.isShortcutInfoUpdateable((ItemInfo) tag)) {
-                    ShortcutInfo info = (ShortcutInfo) tag;
-
-                    final Intent intent = info.intent;
-                    final ComponentName name = intent.getComponent();
-                    final int appCount = apps.size();
-                    for (int k = 0; k < appCount; k++) {
-                        AppInfo app = apps.get(k);
-                        if (app.componentName.equals(name)) {
-                            BubbleTextView shortcut = (BubbleTextView) view;
-                            info.updateIcon(mIconCache);
-                            info.title = app.title.toString();
-                            shortcut.applyFromShortcutInfo(info, mIconCache);
-                        }
+            // Update all the children shortcuts
+            final HashMap<ItemInfo, View> children = new HashMap<ItemInfo, View>();
+            for (int j = 0; j < layout.getChildCount(); j++) {
+                View v = layout.getChildAt(j);
+                ItemInfo info = (ItemInfo) v.getTag();
+                if (info instanceof FolderInfo && v instanceof FolderIcon) {
+                    FolderIcon folder = (FolderIcon) v;
+                    ArrayList<View> folderChildren = folder.getFolder().getItemsInReadingOrder();
+                    for (View fv : folderChildren) {
+                        info = (ItemInfo) fv.getTag();
+                        updateShortcut(appsMap, info, fv);
                     }
+                    folder.invalidate();
+                } else if (info instanceof ShortcutInfo) {
+                    updateShortcut(appsMap, info, v);
                 }
             }
         }
@@ -4443,6 +4665,7 @@
                 child.requestFocus();
             }
          }
+        exitWidgetResizeMode();
     }
 
     @Override
diff --git a/src/com/android/photos/BitmapRegionTileSource.java b/src/com/android/photos/BitmapRegionTileSource.java
deleted file mode 100644
index 5f64018..0000000
--- a/src/com/android/photos/BitmapRegionTileSource.java
+++ /dev/null
@@ -1,260 +0,0 @@
-/*
- * Copyright (C) 2013 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.photos;
-
-import android.annotation.TargetApi;
-import android.content.Context;
-import android.content.res.Resources;
-import android.graphics.Bitmap;
-import android.graphics.Bitmap.Config;
-import android.graphics.BitmapFactory;
-import android.graphics.BitmapRegionDecoder;
-import android.graphics.Canvas;
-import android.graphics.Rect;
-import android.net.Uri;
-import android.os.Build;
-import android.os.Build.VERSION_CODES;
-import android.util.Log;
-
-import com.android.gallery3d.common.BitmapUtils;
-import com.android.gallery3d.glrenderer.BasicTexture;
-import com.android.gallery3d.glrenderer.BitmapTexture;
-import com.android.photos.views.TiledImageRenderer;
-
-import java.io.BufferedInputStream;
-import java.io.IOException;
-import java.io.InputStream;
-
-/**
- * A {@link com.android.photos.views.TiledImageRenderer.TileSource} using
- * {@link BitmapRegionDecoder} to wrap a local file
- */
-@TargetApi(Build.VERSION_CODES.ICE_CREAM_SANDWICH_MR1)
-public class BitmapRegionTileSource implements TiledImageRenderer.TileSource {
-
-    private static final String TAG = "BitmapRegionTileSource";
-
-    private static final boolean REUSE_BITMAP =
-            Build.VERSION.SDK_INT >= VERSION_CODES.JELLY_BEAN;
-    private static final int GL_SIZE_LIMIT = 2048;
-    // This must be no larger than half the size of the GL_SIZE_LIMIT
-    // due to decodePreview being allowed to be up to 2x the size of the target
-    private static final int MAX_PREVIEW_SIZE = 1024;
-
-    BitmapRegionDecoder mDecoder;
-    int mWidth;
-    int mHeight;
-    int mTileSize;
-    private BasicTexture mPreview;
-    private final int mRotation;
-
-    // For use only by getTile
-    private Rect mWantRegion = new Rect();
-    private Rect mOverlapRegion = new Rect();
-    private BitmapFactory.Options mOptions;
-    private Canvas mCanvas;
-
-    public BitmapRegionTileSource(Context context, String path, int previewSize, int rotation) {
-        this(null, context, path, null, 0, previewSize, rotation);
-    }
-
-    public BitmapRegionTileSource(Context context, Uri uri, int previewSize, int rotation) {
-        this(null, context, null, uri, 0, previewSize, rotation);
-    }
-
-    public BitmapRegionTileSource(Resources res,
-            Context context, int resId, int previewSize, int rotation) {
-        this(res, context, null, null, resId, previewSize, rotation);
-    }
-
-    private BitmapRegionTileSource(Resources res,
-            Context context, String path, Uri uri, int resId, int previewSize, int rotation) {
-        mTileSize = TiledImageRenderer.suggestedTileSize(context);
-        mRotation = rotation;
-        try {
-            if (path != null) {
-                mDecoder = BitmapRegionDecoder.newInstance(path, true);
-            } else if (uri != null) {
-                InputStream is = context.getContentResolver().openInputStream(uri);
-                BufferedInputStream bis = new BufferedInputStream(is);
-                mDecoder = BitmapRegionDecoder.newInstance(bis, true);
-            } else {
-                InputStream is = res.openRawResource(resId);
-                BufferedInputStream bis = new BufferedInputStream(is);
-                mDecoder = BitmapRegionDecoder.newInstance(bis, true);
-            }
-            mWidth = mDecoder.getWidth();
-            mHeight = mDecoder.getHeight();
-        } catch (IOException e) {
-            Log.w("BitmapRegionTileSource", "ctor failed", e);
-        }
-        mOptions = new BitmapFactory.Options();
-        mOptions.inPreferredConfig = Bitmap.Config.ARGB_8888;
-        mOptions.inPreferQualityOverSpeed = true;
-        mOptions.inTempStorage = new byte[16 * 1024];
-        if (previewSize != 0) {
-            previewSize = Math.min(previewSize, MAX_PREVIEW_SIZE);
-            // Although this is the same size as the Bitmap that is likely already
-            // loaded, the lifecycle is different and interactions are on a different
-            // thread. Thus to simplify, this source will decode its own bitmap.
-            Bitmap preview = decodePreview(res, context, path, uri, resId, previewSize);
-            if (preview.getWidth() <= GL_SIZE_LIMIT && preview.getHeight() <= GL_SIZE_LIMIT) {
-                mPreview = new BitmapTexture(preview);
-            } else {
-                Log.w(TAG, String.format(
-                        "Failed to create preview of apropriate size! "
-                        + " in: %dx%d, out: %dx%d",
-                        mWidth, mHeight,
-                        preview.getWidth(), preview.getHeight()));
-            }
-        }
-    }
-
-    @Override
-    public int getTileSize() {
-        return mTileSize;
-    }
-
-    @Override
-    public int getImageWidth() {
-        return mWidth;
-    }
-
-    @Override
-    public int getImageHeight() {
-        return mHeight;
-    }
-
-    @Override
-    public BasicTexture getPreview() {
-        return mPreview;
-    }
-
-    @Override
-    public int getRotation() {
-        return mRotation;
-    }
-
-    @Override
-    public Bitmap getTile(int level, int x, int y, Bitmap bitmap) {
-        int tileSize = getTileSize();
-        if (!REUSE_BITMAP) {
-            return getTileWithoutReusingBitmap(level, x, y, tileSize);
-        }
-
-        int t = tileSize << level;
-        mWantRegion.set(x, y, x + t, y + t);
-
-        if (bitmap == null) {
-            bitmap = Bitmap.createBitmap(tileSize, tileSize, Bitmap.Config.ARGB_8888);
-        }
-
-        mOptions.inSampleSize = (1 << level);
-        mOptions.inBitmap = bitmap;
-
-        try {
-            bitmap = mDecoder.decodeRegion(mWantRegion, mOptions);
-        } finally {
-            if (mOptions.inBitmap != bitmap && mOptions.inBitmap != null) {
-                mOptions.inBitmap = null;
-            }
-        }
-
-        if (bitmap == null) {
-            Log.w("BitmapRegionTileSource", "fail in decoding region");
-        }
-        return bitmap;
-    }
-
-    private Bitmap getTileWithoutReusingBitmap(
-            int level, int x, int y, int tileSize) {
-
-        int t = tileSize << level;
-        mWantRegion.set(x, y, x + t, y + t);
-
-        mOverlapRegion.set(0, 0, mWidth, mHeight);
-
-        mOptions.inSampleSize = (1 << level);
-        Bitmap bitmap = mDecoder.decodeRegion(mOverlapRegion, mOptions);
-
-        if (bitmap == null) {
-            Log.w(TAG, "fail in decoding region");
-        }
-
-        if (mWantRegion.equals(mOverlapRegion)) {
-            return bitmap;
-        }
-
-        Bitmap result = Bitmap.createBitmap(tileSize, tileSize, Config.ARGB_8888);
-        if (mCanvas == null) {
-            mCanvas = new Canvas();
-        }
-        mCanvas.setBitmap(result);
-        mCanvas.drawBitmap(bitmap,
-                (mOverlapRegion.left - mWantRegion.left) >> level,
-                (mOverlapRegion.top - mWantRegion.top) >> level, null);
-        mCanvas.setBitmap(null);
-        return result;
-    }
-
-    /**
-     * Note that the returned bitmap may have a long edge that's longer
-     * than the targetSize, but it will always be less than 2x the targetSize
-     */
-    private Bitmap decodePreview(
-            Resources res, Context context, String file, Uri uri, int resId, int targetSize) {
-        float scale = (float) targetSize / Math.max(mWidth, mHeight);
-        mOptions.inSampleSize = BitmapUtils.computeSampleSizeLarger(scale);
-        mOptions.inJustDecodeBounds = false;
-
-        Bitmap result = null;
-        if (file != null) {
-            result = BitmapFactory.decodeFile(file, mOptions);
-        } else if (uri != null) {
-            try {
-                InputStream is = context.getContentResolver().openInputStream(uri);
-                BufferedInputStream bis = new BufferedInputStream(is);
-                result = BitmapFactory.decodeStream(bis, null, mOptions);
-            } catch (IOException e) {
-                Log.w("BitmapRegionTileSource", "getting preview failed", e);
-            }
-        } else {
-            result = BitmapFactory.decodeResource(res, resId, mOptions);
-        }
-        if (result == null) {
-            return null;
-        }
-
-        // We need to resize down if the decoder does not support inSampleSize
-        // or didn't support the specified inSampleSize (some decoders only do powers of 2)
-        scale = (float) targetSize / (float) (Math.max(result.getWidth(), result.getHeight()));
-
-        if (scale <= 0.5) {
-            result = BitmapUtils.resizeBitmapByScale(result, scale, true);
-        }
-        return ensureGLCompatibleBitmap(result);
-    }
-
-    private static Bitmap ensureGLCompatibleBitmap(Bitmap bitmap) {
-        if (bitmap == null || bitmap.getConfig() != null) {
-            return bitmap;
-        }
-        Bitmap newBitmap = bitmap.copy(Config.ARGB_8888, false);
-        bitmap.recycle();
-        return newBitmap;
-    }
-}
diff --git a/update_gallery_files.py b/update_gallery_files.py
index ef4e8c9..738d225 100644
--- a/update_gallery_files.py
+++ b/update_gallery_files.py
@@ -49,6 +49,6 @@
     dir = os.path.dirname(file_path)
     if file_path.find('exif') != -1 or file_path.find('common') != -1:
         file_path = 'gallerycommon/' + file_path
-    cmd = 'cp %s/%s %s/' % (gallery_dir, file_path, dir)
+    cmd = 'cp %s/%s WallpaperPicker/%s/' % (gallery_dir, file_path, dir)
     print cmd
     os.system(cmd)
diff --git a/update_system_wallpaper_cropper.py b/update_system_wallpaper_cropper.py
new file mode 100644
index 0000000..44cbcc9
--- /dev/null
+++ b/update_system_wallpaper_cropper.py
@@ -0,0 +1,58 @@
+# This script is used to push the most up-to-date files from
+# Launcher into frameworks' version of the WallpaperCropActivity
+# (and supporting files)
+# The framework versions have some small modifications that are
+# necessary so do this with care
+import os
+import sys
+src_dir = "WallpaperPicker/src/"
+files = """
+src/android/util/Pools.java
+com/android/gallery3d/util/IntArray.java
+com/android/gallery3d/common/Utils.java
+com/android/gallery3d/exif/ByteBufferInputStream.java
+com/android/gallery3d/exif/CountedDataInputStream.java
+com/android/gallery3d/exif/ExifData.java
+com/android/gallery3d/exif/ExifInterface.java
+com/android/gallery3d/exif/ExifInvalidFormatException.java
+com/android/gallery3d/exif/ExifModifier.java
+com/android/gallery3d/exif/ExifOutputStream.java
+com/android/gallery3d/exif/ExifParser.java
+com/android/gallery3d/exif/ExifReader.java
+com/android/gallery3d/exif/ExifTag.java
+com/android/gallery3d/exif/IfdData.java
+com/android/gallery3d/exif/IfdId.java
+com/android/gallery3d/exif/JpegHeader.java
+com/android/gallery3d/exif/OrderedDataOutputStream.java
+com/android/gallery3d/exif/Rational.java
+com/android/gallery3d/glrenderer/BasicTexture.java
+com/android/gallery3d/glrenderer/BitmapTexture.java
+com/android/gallery3d/glrenderer/GLCanvas.java
+com/android/gallery3d/glrenderer/GLES20Canvas.java
+com/android/gallery3d/glrenderer/GLES20IdImpl.java
+com/android/gallery3d/glrenderer/GLId.java
+com/android/gallery3d/glrenderer/GLPaint.java
+com/android/gallery3d/glrenderer/RawTexture.java
+com/android/gallery3d/glrenderer/Texture.java
+com/android/gallery3d/glrenderer/UploadedTexture.java
+com/android/photos/BitmapRegionTileSource.java
+com/android/photos/views/BlockingGLTextureView.java
+com/android/photos/views/TiledImageRenderer.java
+com/android/photos/views/TiledImageView.java
+com/android/gallery3d/common/BitmapUtils.java
+com/android/launcher3/CropView.java
+com/android/launcher3/WallpaperCropActivity.java
+"""
+
+if len(sys.argv) != 2:
+    print "Usage: python update_sytem_wallpaper_cropper.py <framework_dir>"
+    exit()
+framework_dir = sys.argv[1] + "/packages/WallpaperCropper"
+for file_path in files.split():
+    file_path = src_dir + file_path
+    dir = os.path.dirname(file_path)
+    dir = dir.replace("launcher3", "wallpapercropper")
+    dir = dir.replace(src_dir, "src/")
+    cmd = 'cp %s %s/%s' % (file_path, framework_dir, dir)
+    print cmd
+    os.system(cmd)
diff --git a/util/com/android/launcher3/DecoderRing.java b/util/com/android/launcher3/DecoderRing.java
index 1d9e0de..86431d9 100644
--- a/util/com/android/launcher3/DecoderRing.java
+++ b/util/com/android/launcher3/DecoderRing.java
@@ -34,159 +34,283 @@
 import java.io.FileOutputStream;
 import java.io.IOException;
 import java.lang.System;
+import java.util.LinkedList;
+import java.util.List;
 import java.util.zip.CRC32;
 
+import javax.xml.bind.DatatypeConverter;
+
+
 /**
- * Commandline utility for decoding protos written to the android logs during debugging.
+ * Commandline utility for decoding Launcher3 backup protocol buffers.
  *
- * base64 -D icon.log > icon.bin
- * java -classpath $ANDROID_HOST_OUT/framework/protoutil.jar:$ANDROID_HOST_OUT/../common/obj/JAVA_LIBRARIES/host-libprotobuf-java-2.3.0-nano_intermediates/javalib.jar \
- *   com.android.launcher3.DecoderRing -i icon.bin
+ * <P>When using com.android.internal.backup.LocalTransport, the file names are base64-encoded Key
+ * protocol buffers with a prefix, that have been base64-encoded again by the transport:
+ * <pre>
+ *     echo "TDpDQUlnL0pxVTVnOD0=" | launcher_protoutil -k
+ * </pre>
  *
- * TODO: write a wrapper to setup the classpath
+ * <P>This tool understands these file names and will use the embedded Key to detect the type and
+ * extract the payload automatically:
+ * <pre>
+ *     launcher_protoutil /tmp/TDpDQUlnL0pxVTVnOD0=
+ * </pre>
+ *
+ * <P>With payload debugging enabled, base64-encoded protocol buffers will be written to the logs.
+ * Copy the encoded snippet from the log, and specify the type explicitly, with the Logs flags:
+ * <pre>
+ *    echo "CAEYLiCJ9JKsDw==" | launcher_protoutil -L -k
+ * </pre>
+ * For backup payloads it is more convenient to copy the log snippet to a file:
+ * <pre>
+ *    launcher_protoutil -L -f favorite.log
+ * </pre>
  */
 class DecoderRing {
+
+    public static final String STANDARD_IN = "**stdin**";
+
+    private static Class[] TYPES = {
+            Key.class,
+            Favorite.class,
+            Screen.class,
+            Resource.class,
+            Widget.class
+    };
+    static final int ICON_TYPE_BITMAP = 1;
+
     public static void main(String[ ] args)
             throws Exception {
-        File source = null;
-        Class type = Key.class;
+        Class defaultType = null;
+        boolean extractImages = false;
+        boolean fromLogs = false;
         int skip = 0;
+        List<File> files = new LinkedList<File>();
+        boolean verbose = false;
 
         for (int i = 0; i < args.length; i++) {
             if ("-k".equals(args[i])) {
-                type = Key.class;
+                defaultType = Key.class;
             } else if ("-f".equals(args[i])) {
-                type = Favorite.class;
+                defaultType = Favorite.class;
             } else if ("-j".equals(args[i])) {
-                type = Journal.class;
+                defaultType = Journal.class;
             } else if ("-i".equals(args[i])) {
-                type = Resource.class;
+                defaultType = Resource.class;
             } else if ("-s".equals(args[i])) {
-                type = Screen.class;
+                defaultType = Screen.class;
             } else if ("-w".equals(args[i])) {
-                type = Widget.class;
+                defaultType = Widget.class;
             } else if ("-S".equals(args[i])) {
                 if ((i + 1) < args.length) {
                     skip = Integer.valueOf(args[++i]);
                 } else {
                     usage(args);
                 }
+            } else if ("-x".equals(args[i])) {
+                extractImages = true;
+            } else if ("-v".equals(args[i])) {
+                verbose = true;
+            } else if ("-L".equals(args[i])) {
+                fromLogs = true;
             } else if (args[i] != null && !args[i].startsWith("-")) {
-                source = new File(args[i]);
+                files.add(new File(args[i]));
             } else {
                 System.err.println("Unsupported flag: " + args[i]);
                 usage(args);
             }
         }
 
+        if (defaultType == null && files.isEmpty()) {
+            // can't infer file type without the key
+            usage(args);
+        }
 
-        // read in the bytes
-        ByteArrayOutputStream byteStream = new ByteArrayOutputStream();
-        BufferedInputStream input = null;
-        if (source == null) {
-            input = new BufferedInputStream(System.in);
-        } else {
+        if (files.size() > 1 && defaultType != null) {
+            System.err.println("Explicit type ignored for multiple files.");
+            defaultType = null;
+        }
+
+        if (files.isEmpty()) {
+            files.add(new File(STANDARD_IN));
+        }
+
+        for (File source : files) {
+            Class type = null;
+            if (defaultType == null) {
+                Key key = decodeKey(source.getName().getBytes(), fromLogs);
+                if (key != null) {
+                    type = TYPES[key.type];
+                    if (verbose) {
+                        System.err.println(source.getName() + " is a " + type.getSimpleName());
+                        System.out.println(key.toString());
+                    }
+                }
+            } else {
+                type = defaultType;
+            }
+
+            // read in the bytes
+            ByteArrayOutputStream byteStream = new ByteArrayOutputStream();
+            BufferedInputStream input = null;
+            if (source.getName() == STANDARD_IN) {
+                input = new BufferedInputStream(System.in);
+            } else {
+                try {
+                    input = new BufferedInputStream(new FileInputStream(source));
+                } catch (FileNotFoundException e) {
+                    System.err.println("failed to open file: " + source + ", " + e);
+                    System.exit(1);
+                }
+            }
+            byte[] buffer = new byte[1024];
             try {
-                input = new BufferedInputStream(new FileInputStream(source));
-            } catch (FileNotFoundException e) {
-                System.err.println("failed to open file: " + source + ", " + e);
+                while (input.available() > 0) {
+                    int n = input.read(buffer);
+                    int offset = 0;
+                    if (skip > 0) {
+                        offset = Math.min(skip, n);
+                        n -= offset;
+                        skip -= offset;
+                    }
+                    if (n > 0) {
+                        byteStream.write(buffer, offset, n);
+                    }
+                }
+            } catch (IOException e) {
+                System.err.println("failed to read input: " + e);
                 System.exit(1);
             }
-        }
-        byte[] buffer = new byte[1024];
-        try {
-            while (input.available() > 0) {
-                int n = input.read(buffer);
-                int offset = 0;
-                if (skip > 0) {
-                    offset = Math.min(skip, n);
-                    n -= offset;
-                    skip -= offset;
+
+            MessageNano proto = null;
+            byte[] payload = byteStream.toByteArray();
+            if (type == Key.class) {
+                proto = decodeKey(payload, fromLogs);
+            } else if (type != null) {
+                proto = decodeBackupData(payload, type, fromLogs);
+            }
+
+            // Generic string output
+            if (proto != null) {
+                System.out.println(proto.toString());
+            }
+
+            if (extractImages) {
+                String prefix = "stdin";
+                if (source != null) {
+                    prefix = source.getName();
                 }
-                if (n > 0) {
-                    byteStream.write(buffer, offset, n);
+                // save off the icon bits in a file for inspection
+                if (proto instanceof Resource) {
+                    Resource icon = (Resource) proto;
+                    writeImageData(icon.data, prefix + ".png");
+                }
+
+                // save off the icon bits in a file for inspection
+                if (proto instanceof Favorite) {
+                    Favorite favorite = (Favorite) proto;
+                    if (favorite.iconType == ICON_TYPE_BITMAP) {
+                        writeImageData(favorite.icon, prefix + ".png");
+                    }
+                }
+
+                // save off the widget icon and preview bits in files for inspection
+                if (proto instanceof Widget) {
+                    Widget widget = (Widget) proto;
+                    if (widget.icon != null) {
+                        writeImageData(widget.icon.data, prefix + "_icon.png");
+                    }
+                    if (widget.preview != null) {
+                        writeImageData(widget.preview.data, prefix + "_preview.png");
+                    }
                 }
             }
-        } catch (IOException e) {
-            System.err.println("failed to read input: " + e);
+        }
+        System.exit(0);
+    }
+
+    // In logcat, backup data is base64 encoded, but in localtransport files it is raw
+    private static MessageNano decodeBackupData(byte[] payload, Class type, boolean fromLogs)
+            throws InstantiationException, IllegalAccessException {
+        MessageNano proto;// other types are wrapped in a checksum message
+        CheckedMessage wrapper = new CheckedMessage();
+        try {
+            if (fromLogs) {
+                payload = DatatypeConverter.parseBase64Binary(new String(payload));
+            }
+            MessageNano.mergeFrom(wrapper, payload);
+        } catch (InvalidProtocolBufferNanoException e) {
+            System.err.println("failed to parse wrapper: " + e);
             System.exit(1);
         }
-        System.err.println("read this many bytes: " + byteStream.size());
 
-        MessageNano proto = null;
-        if (type == Key.class) {
-            Key key = new Key();
-            try {
-                key = Key.parseFrom(byteStream.toByteArray());
-            } catch (InvalidProtocolBufferNanoException e) {
-                System.err.println("failed to parse proto: " + e);
-                System.exit(1);
-            }
-            // keys are self-checked
-            if (key.checksum != checkKey(key)) {
-                System.err.println("key ckecksum failed");
-                System.exit(1);
-            }
-            proto = key;
-        } else {
-            // other types are wrapped in a checksum message
-            CheckedMessage wrapper = new CheckedMessage();
-            try {
-                MessageNano.mergeFrom(wrapper, byteStream.toByteArray());
-            } catch (InvalidProtocolBufferNanoException e) {
-                System.err.println("failed to parse wrapper: " + e);
-                System.exit(1);
-            }
-            CRC32 checksum = new CRC32();
-            checksum.update(wrapper.payload);
-            if (wrapper.checksum != checksum.getValue()) {
-                System.err.println("wrapper ckecksum failed");
-                System.exit(1);
-            }
-            // decode the actual message
-            proto = (MessageNano) type.newInstance();
-            try {
-                MessageNano.mergeFrom(proto, wrapper.payload);
-            } catch (InvalidProtocolBufferNanoException e) {
-                System.err.println("failed to parse proto: " + e);
-                System.exit(1);
-            }
+        CRC32 checksum = new CRC32();
+        checksum.update(wrapper.payload);
+        if (wrapper.checksum != checksum.getValue()) {
+            System.err.println("wrapper checksum failed");
+            System.exit(1);
         }
 
-        // Generic string output
-        System.out.println(proto.toString());
+        // decode the actual message
+        proto = (MessageNano) type.newInstance();
+        try {
+            MessageNano.mergeFrom(proto, wrapper.payload);
+        } catch (InvalidProtocolBufferNanoException e) {
+            System.err.println("failed to parse proto: " + e);
+            System.exit(1);
+        }
+        return proto;
+    }
 
-        // save off the icon bits in a file for inspection
-        if (proto instanceof Resource) {
-            Resource icon = (Resource) proto;
-            final String path = "icon.webp";
-            FileOutputStream iconFile = new FileOutputStream(path);
-            iconFile.write(icon.data);
-            iconFile.close();
+    // In logcat, keys are base64 encoded with no prefix.
+    // The localtransport adds a prefix and the base64 encodes the whole thing again.
+    private static Key decodeKey(byte[] payload, boolean fromLogs) {
+        Key key = new Key();
+        try {
+            String encodedKey = new String(payload);
+            if (!fromLogs) {
+                byte[] rawKey = DatatypeConverter.parseBase64Binary(encodedKey);
+                if (rawKey[0] != 'L' || rawKey[1] != ':') {
+                    System.err.println(encodedKey + " is not a launcher backup key.");
+                    return null;
+                }
+                encodedKey = new String(rawKey, 2, rawKey.length - 2);
+            }
+            byte[] keyProtoData = DatatypeConverter.parseBase64Binary(encodedKey);
+            key = Key.parseFrom(keyProtoData);
+        } catch (InvalidProtocolBufferNanoException protoException) {
+            System.err.println("failed to extract key from filename: " + protoException);
+            return null;
+        } catch (IllegalArgumentException base64Exception) {
+            System.err.println("failed to extract key from filename: " + base64Exception);
+            return null;
+        }
+
+        // keys are self-checked
+        if (key.checksum != checkKey(key)) {
+            System.err.println("key ckecksum failed");
+            return null;
+        }
+        return key;
+    }
+
+    private static void writeImageData(byte[] data, String path) {
+        FileOutputStream iconFile = null;
+        try {
+            iconFile = new FileOutputStream(path);
+            iconFile.write(data);
             System.err.println("wrote " + path);
-        }
-
-        // save off the widget icon and preview bits in files for inspection
-        if (proto instanceof Widget) {
-            Widget widget = (Widget) proto;
-            if (widget.icon != null) {
-                final String path = "widget_icon.webp";
-                FileOutputStream iconFile = new FileOutputStream(path);
-                iconFile.write(widget.icon.data);
-                iconFile.close();
-                System.err.println("wrote " + path);
-            }
-            if (widget.preview != null) {
-                final String path = "widget_preview.webp";
-                FileOutputStream iconFile = new FileOutputStream(path);
-                iconFile.write(widget.preview.data);
-                iconFile.close();
-                System.err.println("wrote " + path);
+        } catch (IOException e) {
+            System.err.println("failed to write image file: " + e);
+        } finally {
+            if (iconFile != null) {
+                try {
+                    iconFile.close();
+                } catch (IOException e) {
+                    System.err.println("failed to close the image file: " + e);
+                }
             }
         }
-
-        // success
-        System.exit(0);
     }
 
     private static long checkKey(Key key) {
@@ -201,13 +325,16 @@
     }
 
     private static void usage(String[] args) {
-        System.err.println("DecoderRing type [input]");
+        System.err.println("launcher_protoutil [-x] [-S b] [-k|-f|-i|-s|-w] [filename]");
         System.err.println("\t-k\tdecode a key");
         System.err.println("\t-f\tdecode a favorite");
         System.err.println("\t-i\tdecode a icon");
         System.err.println("\t-s\tdecode a screen");
         System.err.println("\t-w\tdecode a widget");
-        System.err.println("\t-s b\tskip b bytes");
+        System.err.println("\t-S b\tskip b bytes");
+        System.err.println("\t-x\textract image data to files");
+        System.err.println("\t-v\tprint key type data, as well as payload");
+        System.err.println("\t-l\texpect data from logcat, instead of the local transport");
         System.err.println("\tfilename\tread from filename, not stdin");
         System.exit(1);
     }
diff --git a/util/etc/launcher_protoutil b/util/etc/launcher_protoutil
new file mode 100644
index 0000000..833b583
--- /dev/null
+++ b/util/etc/launcher_protoutil
@@ -0,0 +1,83 @@
+#!/bin/bash
+#
+# Copyright (C) 2013 The Android Open Source Project
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+#     http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+# Set up prog to be the path of this script, including following symlinks,
+# and set up progdir to be the fully-qualified pathname of its directory.
+prog="$0"
+while [ -h "${prog}" ]; do
+    newProg=`/bin/ls -ld "${prog}"`
+    newProg=`expr "${newProg}" : ".* -> \(.*\)$"`
+    if expr "x${newProg}" : 'x/' >/dev/null; then
+        prog="${newProg}"
+    else
+        progdir=`dirname "${prog}"`
+        prog="${progdir}/${newProg}"
+    fi
+done
+oldwd=`pwd`
+progdir=`dirname "${prog}"`
+cd "${progdir}"
+progdir=`pwd`
+prog="${progdir}"/`basename "${prog}"`
+cd "${oldwd}"
+
+jarfile=launcher_protoutil_lib.jar
+libdir="$progdir"
+
+if [ ! -r "$libdir/$jarfile" ]; then
+    # set jar location for the Android tree case
+    libdir=`dirname "$progdir"`/framework
+fi
+
+if [ ! -r "$libdir/$jarfile" ]; then
+    echo `basename "$prog"`": can't find $jarfile"
+    exit 1
+fi
+
+# By default, give decoder a max heap size of 1 gig. This can be overridden
+# by using a "-J" option (see below).
+defaultMx="-Xmx1024M"
+
+# The following will extract any initial parameters of the form
+# "-J<stuff>" from the command line and pass them to the Java
+# invocation (instead of to the decoder). This makes it possible for
+# you to add a command-line parameter such as "-JXmx256M" in your
+# scripts, for example. "java" (with no args) and "java -X" give a
+# summary of available options.
+
+javaOpts=""
+
+while expr "x$1" : 'x-J' >/dev/null; do
+    opt=`expr "x$1" : 'x-J\(.*\)'`
+    javaOpts="${javaOpts} -${opt}"
+    if expr "x${opt}" : "xXmx[0-9]" >/dev/null; then
+        defaultMx="no"
+    fi
+    shift
+done
+
+if [ "${defaultMx}" != "no" ]; then
+    javaOpts="${javaOpts} ${defaultMx}"
+fi
+
+if [ "$OSTYPE" = "cygwin" ]; then
+    # For Cygwin, convert the jarfile path into native Windows style.
+    jarpath=`cygpath -w "$libdir/$jarfile"`
+else
+    jarpath="$libdir/$jarfile"
+fi
+
+exec java $javaOpts -jar "$jarpath" "$@"
diff --git a/util/etc/manifest.txt b/util/etc/manifest.txt
new file mode 100644
index 0000000..84842ed
--- /dev/null
+++ b/util/etc/manifest.txt
@@ -0,0 +1 @@
+Main-Class: com.android.launcher3.DecoderRing