Merge "Scale wallpaper thumbnails without altering aspect ratio" into jb-ub-now-indigo-rose
diff --git a/AndroidManifest.xml b/AndroidManifest.xml
index 996bef7..14fb044 100644
--- a/AndroidManifest.xml
+++ b/AndroidManifest.xml
@@ -104,28 +104,28 @@
 
         <activity
             android:name="com.android.launcher3.WallpaperPickerActivity"
-            android:theme="@style/Theme.WallpaperPicker"
+            android:theme="@style/Theme.WallpaperCropper"
             android:label="@string/pick_wallpaper"
             android:icon="@mipmap/ic_launcher_wallpaper"
             android:finishOnCloseSystemDialogs="true"
             android:process=":wallpaper_chooser">
             <intent-filter>
-                <action android:name="android.intent.action.CROP_AND_SET_WALLPAPER" />
+                <action android:name="android.intent.action.SET_WALLPAPER" />
                 <category android:name="android.intent.category.DEFAULT" />
-                <data android:mimeType="image/*" />
             </intent-filter>
         </activity>
 
         <activity
             android:name="com.android.launcher3.WallpaperCropActivity"
-            android:theme="@style/Theme.WallpaperPicker"
-            android:label="@string/pick_wallpaper"
+            android:theme="@style/Theme.WallpaperCropper"
+            android:label="@string/crop_wallpaper"
             android:icon="@mipmap/ic_launcher_wallpaper"
             android:finishOnCloseSystemDialogs="true"
             android:process=":wallpaper_chooser">
             <intent-filter>
-                <action android:name="com.android.launcher3.action.CROP_AND_SET_WALLPAPER" />
+                <action android:name="android.service.wallpaper.CROP_AND_SET_WALLPAPER" />
                 <category android:name="android.intent.category.DEFAULT" />
+                <data android:mimeType="image/*" />
             </intent-filter>
         </activity>
 
diff --git a/res/drawable-hdpi/flying_icon_bg_pressed.9.png b/res/drawable-hdpi/flying_icon_bg_pressed.9.png
deleted file mode 100644
index 700fadc..0000000
--- a/res/drawable-hdpi/flying_icon_bg_pressed.9.png
+++ /dev/null
Binary files differ
diff --git a/res/drawable-land-xxhdpi/bg_cling1.png b/res/drawable-land-xxhdpi/bg_cling1.png
new file mode 100644
index 0000000..78943f0
--- /dev/null
+++ b/res/drawable-land-xxhdpi/bg_cling1.png
Binary files differ
diff --git a/res/drawable-land-xxhdpi/bg_cling2.png b/res/drawable-land-xxhdpi/bg_cling2.png
new file mode 100644
index 0000000..98b6568
--- /dev/null
+++ b/res/drawable-land-xxhdpi/bg_cling2.png
Binary files differ
diff --git a/res/drawable-land-xxhdpi/bg_cling3.png b/res/drawable-land-xxhdpi/bg_cling3.png
new file mode 100644
index 0000000..e249fe5
--- /dev/null
+++ b/res/drawable-land-xxhdpi/bg_cling3.png
Binary files differ
diff --git a/res/drawable-land-xxhdpi/ic_home_voice_search_holo.png b/res/drawable-land-xxhdpi/ic_home_voice_search_holo.png
new file mode 100644
index 0000000..6ea7368
--- /dev/null
+++ b/res/drawable-land-xxhdpi/ic_home_voice_search_holo.png
Binary files differ
diff --git a/res/drawable-land-xxhdpi/workspace_bg.9.png b/res/drawable-land-xxhdpi/workspace_bg.9.png
new file mode 100644
index 0000000..b0b4561
--- /dev/null
+++ b/res/drawable-land-xxhdpi/workspace_bg.9.png
Binary files differ
diff --git a/res/drawable-mdpi/flying_icon_bg_pressed.9.png b/res/drawable-mdpi/flying_icon_bg_pressed.9.png
deleted file mode 100644
index fb74449..0000000
--- a/res/drawable-mdpi/flying_icon_bg_pressed.9.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
new file mode 100644
index 0000000..c661f68
--- /dev/null
+++ b/res/drawable-sw600dp-xxhdpi/homescreen_blue_normal_holo.9.png
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
new file mode 100644
index 0000000..bf6ab97
--- /dev/null
+++ b/res/drawable-sw600dp-xxhdpi/homescreen_blue_strong_holo.9.png
Binary files differ
diff --git a/res/drawable-sw600dp-xxhdpi/ic_allapps.png b/res/drawable-sw600dp-xxhdpi/ic_allapps.png
new file mode 100644
index 0000000..2429656
--- /dev/null
+++ b/res/drawable-sw600dp-xxhdpi/ic_allapps.png
Binary files differ
diff --git a/res/drawable-sw600dp-xxhdpi/ic_allapps_pressed.png b/res/drawable-sw600dp-xxhdpi/ic_allapps_pressed.png
new file mode 100644
index 0000000..b93a51b
--- /dev/null
+++ b/res/drawable-sw600dp-xxhdpi/ic_allapps_pressed.png
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
new file mode 100644
index 0000000..472c3f9
--- /dev/null
+++ b/res/drawable-sw600dp-xxhdpi/overscroll_glow_left.9.png
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
new file mode 100644
index 0000000..e30cc97
--- /dev/null
+++ b/res/drawable-sw600dp-xxhdpi/overscroll_glow_right.9.png
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
new file mode 100644
index 0000000..65b2541
--- /dev/null
+++ b/res/drawable-sw600dp-xxhdpi/portal_ring_inner_holo.png
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
new file mode 100644
index 0000000..5068646
--- /dev/null
+++ b/res/drawable-sw600dp-xxhdpi/portal_ring_inner_nolip_holo.png
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
new file mode 100644
index 0000000..6628425
--- /dev/null
+++ b/res/drawable-sw600dp-xxhdpi/portal_ring_outer_holo.png
Binary files differ
diff --git a/res/drawable-xhdpi/flying_icon_bg_pressed.9.png b/res/drawable-xhdpi/flying_icon_bg_pressed.9.png
deleted file mode 100644
index e678927..0000000
--- a/res/drawable-xhdpi/flying_icon_bg_pressed.9.png
+++ /dev/null
Binary files differ
diff --git a/res/drawable-xxhdpi/arrow_dashed.png b/res/drawable-xxhdpi/arrow_dashed.png
new file mode 100644
index 0000000..b64f4d0
--- /dev/null
+++ b/res/drawable-xxhdpi/arrow_dashed.png
Binary files differ
diff --git a/res/drawable-xxhdpi/bg_cling1.png b/res/drawable-xxhdpi/bg_cling1.png
new file mode 100644
index 0000000..0777856
--- /dev/null
+++ b/res/drawable-xxhdpi/bg_cling1.png
Binary files differ
diff --git a/res/drawable-xxhdpi/bg_cling2.png b/res/drawable-xxhdpi/bg_cling2.png
new file mode 100644
index 0000000..1797a1b
--- /dev/null
+++ b/res/drawable-xxhdpi/bg_cling2.png
Binary files differ
diff --git a/res/drawable-xxhdpi/bg_cling3.png b/res/drawable-xxhdpi/bg_cling3.png
new file mode 100644
index 0000000..a87be63
--- /dev/null
+++ b/res/drawable-xxhdpi/bg_cling3.png
Binary files differ
diff --git a/res/drawable-xxhdpi/bg_cling4.png b/res/drawable-xxhdpi/bg_cling4.png
new file mode 100644
index 0000000..cabe919
--- /dev/null
+++ b/res/drawable-xxhdpi/bg_cling4.png
Binary files differ
diff --git a/res/drawable-xxhdpi/bg_cling_home.png b/res/drawable-xxhdpi/bg_cling_home.png
new file mode 100644
index 0000000..1ae93e7
--- /dev/null
+++ b/res/drawable-xxhdpi/bg_cling_home.png
Binary files differ
diff --git a/res/drawable-xxhdpi/bg_cling_nakasi3.png b/res/drawable-xxhdpi/bg_cling_nakasi3.png
new file mode 100644
index 0000000..f47236c
--- /dev/null
+++ b/res/drawable-xxhdpi/bg_cling_nakasi3.png
Binary files differ
diff --git a/res/drawable-xxhdpi/btn_cling_normal.9.png b/res/drawable-xxhdpi/btn_cling_normal.9.png
new file mode 100644
index 0000000..f5e8032
--- /dev/null
+++ b/res/drawable-xxhdpi/btn_cling_normal.9.png
Binary files differ
diff --git a/res/drawable-xxhdpi/btn_cling_pressed.9.png b/res/drawable-xxhdpi/btn_cling_pressed.9.png
new file mode 100644
index 0000000..c507dd7
--- /dev/null
+++ b/res/drawable-xxhdpi/btn_cling_pressed.9.png
Binary files differ
diff --git a/res/drawable-xxhdpi/cling.png b/res/drawable-xxhdpi/cling.png
new file mode 100644
index 0000000..9446ea4
--- /dev/null
+++ b/res/drawable-xxhdpi/cling.png
Binary files differ
diff --git a/res/drawable-xxhdpi/default_widget_preview_holo.9.png b/res/drawable-xxhdpi/default_widget_preview_holo.9.png
new file mode 100644
index 0000000..0f62097
--- /dev/null
+++ b/res/drawable-xxhdpi/default_widget_preview_holo.9.png
Binary files differ
diff --git a/res/drawable-xxhdpi/grid_focused.9.png b/res/drawable-xxhdpi/grid_focused.9.png
new file mode 100644
index 0000000..a8dff7a
--- /dev/null
+++ b/res/drawable-xxhdpi/grid_focused.9.png
Binary files differ
diff --git a/res/drawable-xxhdpi/grid_pressed.9.png b/res/drawable-xxhdpi/grid_pressed.9.png
new file mode 100644
index 0000000..cbc83d1
--- /dev/null
+++ b/res/drawable-xxhdpi/grid_pressed.9.png
Binary files differ
diff --git a/res/drawable-xxhdpi/grid_selected.9.png b/res/drawable-xxhdpi/grid_selected.9.png
new file mode 100644
index 0000000..f8cd673
--- /dev/null
+++ b/res/drawable-xxhdpi/grid_selected.9.png
Binary files differ
diff --git a/res/drawable-xxhdpi/hand.png b/res/drawable-xxhdpi/hand.png
new file mode 100644
index 0000000..88c2a88
--- /dev/null
+++ b/res/drawable-xxhdpi/hand.png
Binary files differ
diff --git a/res/drawable-xxhdpi/homescreen_blue_normal_holo.9.png b/res/drawable-xxhdpi/homescreen_blue_normal_holo.9.png
new file mode 100644
index 0000000..040748a
--- /dev/null
+++ b/res/drawable-xxhdpi/homescreen_blue_normal_holo.9.png
Binary files differ
diff --git a/res/drawable-xxhdpi/homescreen_blue_strong_holo.9.png b/res/drawable-xxhdpi/homescreen_blue_strong_holo.9.png
new file mode 100644
index 0000000..b75b322
--- /dev/null
+++ b/res/drawable-xxhdpi/homescreen_blue_strong_holo.9.png
Binary files differ
diff --git a/res/drawable-xxhdpi/hotseat_bg_panel.9.png b/res/drawable-xxhdpi/hotseat_bg_panel.9.png
new file mode 100644
index 0000000..40fc076
--- /dev/null
+++ b/res/drawable-xxhdpi/hotseat_bg_panel.9.png
Binary files differ
diff --git a/res/drawable-xxhdpi/hotseat_scrubber_holo.9.png b/res/drawable-xxhdpi/hotseat_scrubber_holo.9.png
new file mode 100644
index 0000000..8a77536
--- /dev/null
+++ b/res/drawable-xxhdpi/hotseat_scrubber_holo.9.png
Binary files differ
diff --git a/res/drawable-xxhdpi/hotseat_track_holo.9.png b/res/drawable-xxhdpi/hotseat_track_holo.9.png
new file mode 100644
index 0000000..dd2216f
--- /dev/null
+++ b/res/drawable-xxhdpi/hotseat_track_holo.9.png
Binary files differ
diff --git a/res/drawable-xxhdpi/ic_allapps.png b/res/drawable-xxhdpi/ic_allapps.png
new file mode 100644
index 0000000..0cd0f14
--- /dev/null
+++ b/res/drawable-xxhdpi/ic_allapps.png
Binary files differ
diff --git a/res/drawable-xxhdpi/ic_allapps_pressed.png b/res/drawable-xxhdpi/ic_allapps_pressed.png
new file mode 100644
index 0000000..99494d8
--- /dev/null
+++ b/res/drawable-xxhdpi/ic_allapps_pressed.png
Binary files differ
diff --git a/res/drawable-xxhdpi/ic_home_all_apps_holo_dark.png b/res/drawable-xxhdpi/ic_home_all_apps_holo_dark.png
new file mode 100644
index 0000000..0b8e88c
--- /dev/null
+++ b/res/drawable-xxhdpi/ic_home_all_apps_holo_dark.png
Binary files differ
diff --git a/res/drawable-xxhdpi/ic_home_google_logo_normal_holo.png b/res/drawable-xxhdpi/ic_home_google_logo_normal_holo.png
new file mode 100644
index 0000000..a47b2ba
--- /dev/null
+++ b/res/drawable-xxhdpi/ic_home_google_logo_normal_holo.png
Binary files differ
diff --git a/res/drawable-xxhdpi/ic_home_google_logo_pressed_holo.png b/res/drawable-xxhdpi/ic_home_google_logo_pressed_holo.png
new file mode 100644
index 0000000..75625d1
--- /dev/null
+++ b/res/drawable-xxhdpi/ic_home_google_logo_pressed_holo.png
Binary files differ
diff --git a/res/drawable-xxhdpi/ic_home_search_normal_holo.png b/res/drawable-xxhdpi/ic_home_search_normal_holo.png
new file mode 100644
index 0000000..a9523d3
--- /dev/null
+++ b/res/drawable-xxhdpi/ic_home_search_normal_holo.png
Binary files differ
diff --git a/res/drawable-xxhdpi/ic_home_search_pressed_holo.png b/res/drawable-xxhdpi/ic_home_search_pressed_holo.png
new file mode 100644
index 0000000..800d994
--- /dev/null
+++ b/res/drawable-xxhdpi/ic_home_search_pressed_holo.png
Binary files differ
diff --git a/res/drawable-xxhdpi/ic_home_voice_search_holo.png b/res/drawable-xxhdpi/ic_home_voice_search_holo.png
new file mode 100644
index 0000000..c9c0b50
--- /dev/null
+++ b/res/drawable-xxhdpi/ic_home_voice_search_holo.png
Binary files differ
diff --git a/res/drawable-xxhdpi/ic_home_voice_search_pressed_holo.png b/res/drawable-xxhdpi/ic_home_voice_search_pressed_holo.png
new file mode 100644
index 0000000..27a5897
--- /dev/null
+++ b/res/drawable-xxhdpi/ic_home_voice_search_pressed_holo.png
Binary files differ
diff --git a/res/drawable-xxhdpi/ic_launcher_clear_active_holo.png b/res/drawable-xxhdpi/ic_launcher_clear_active_holo.png
new file mode 100644
index 0000000..95cf841
--- /dev/null
+++ b/res/drawable-xxhdpi/ic_launcher_clear_active_holo.png
Binary files differ
diff --git a/res/drawable-xxhdpi/ic_launcher_clear_normal_holo.png b/res/drawable-xxhdpi/ic_launcher_clear_normal_holo.png
new file mode 100644
index 0000000..b0f5a27
--- /dev/null
+++ b/res/drawable-xxhdpi/ic_launcher_clear_normal_holo.png
Binary files differ
diff --git a/res/drawable-xxhdpi/ic_launcher_info_active_holo.png b/res/drawable-xxhdpi/ic_launcher_info_active_holo.png
new file mode 100644
index 0000000..57f332a
--- /dev/null
+++ b/res/drawable-xxhdpi/ic_launcher_info_active_holo.png
Binary files differ
diff --git a/res/drawable-xxhdpi/ic_launcher_info_normal_holo.png b/res/drawable-xxhdpi/ic_launcher_info_normal_holo.png
new file mode 100644
index 0000000..94f0955
--- /dev/null
+++ b/res/drawable-xxhdpi/ic_launcher_info_normal_holo.png
Binary files differ
diff --git a/res/drawable-xxhdpi/ic_launcher_trashcan_active_holo.png b/res/drawable-xxhdpi/ic_launcher_trashcan_active_holo.png
new file mode 100644
index 0000000..3bb098c
--- /dev/null
+++ b/res/drawable-xxhdpi/ic_launcher_trashcan_active_holo.png
Binary files differ
diff --git a/res/drawable-xxhdpi/ic_launcher_trashcan_normal_holo.png b/res/drawable-xxhdpi/ic_launcher_trashcan_normal_holo.png
new file mode 100644
index 0000000..550cc5b
--- /dev/null
+++ b/res/drawable-xxhdpi/ic_launcher_trashcan_normal_holo.png
Binary files differ
diff --git a/res/drawable-xxhdpi/ic_qs_remote_display.png b/res/drawable-xxhdpi/ic_qs_remote_display.png
new file mode 100644
index 0000000..25ea9fa
--- /dev/null
+++ b/res/drawable-xxhdpi/ic_qs_remote_display.png
Binary files differ
diff --git a/res/drawable-xxhdpi/ic_qs_remote_display_connected.png b/res/drawable-xxhdpi/ic_qs_remote_display_connected.png
new file mode 100644
index 0000000..33a8d2d
--- /dev/null
+++ b/res/drawable-xxhdpi/ic_qs_remote_display_connected.png
Binary files differ
diff --git a/res/drawable-xxhdpi/overscroll_glow_left.9.png b/res/drawable-xxhdpi/overscroll_glow_left.9.png
new file mode 100644
index 0000000..ae20624
--- /dev/null
+++ b/res/drawable-xxhdpi/overscroll_glow_left.9.png
Binary files differ
diff --git a/res/drawable-xxhdpi/overscroll_glow_right.9.png b/res/drawable-xxhdpi/overscroll_glow_right.9.png
new file mode 100644
index 0000000..b083720
--- /dev/null
+++ b/res/drawable-xxhdpi/overscroll_glow_right.9.png
Binary files differ
diff --git a/res/drawable-xxhdpi/page_hover_left_holo.9.png b/res/drawable-xxhdpi/page_hover_left_holo.9.png
new file mode 100644
index 0000000..cfe5a53
--- /dev/null
+++ b/res/drawable-xxhdpi/page_hover_left_holo.9.png
Binary files differ
diff --git a/res/drawable-xxhdpi/page_hover_right_holo.9.png b/res/drawable-xxhdpi/page_hover_right_holo.9.png
new file mode 100644
index 0000000..481e791
--- /dev/null
+++ b/res/drawable-xxhdpi/page_hover_right_holo.9.png
Binary files differ
diff --git a/res/drawable-xxhdpi/portal_container_holo.9.png b/res/drawable-xxhdpi/portal_container_holo.9.png
new file mode 100644
index 0000000..2a28f4a
--- /dev/null
+++ b/res/drawable-xxhdpi/portal_container_holo.9.png
Binary files differ
diff --git a/res/drawable-xxhdpi/portal_ring_inner_holo.png b/res/drawable-xxhdpi/portal_ring_inner_holo.png
new file mode 100644
index 0000000..3b93f83
--- /dev/null
+++ b/res/drawable-xxhdpi/portal_ring_inner_holo.png
Binary files differ
diff --git a/res/drawable-xxhdpi/portal_ring_inner_nolip_holo.png b/res/drawable-xxhdpi/portal_ring_inner_nolip_holo.png
new file mode 100644
index 0000000..01f330c
--- /dev/null
+++ b/res/drawable-xxhdpi/portal_ring_inner_nolip_holo.png
Binary files differ
diff --git a/res/drawable-xxhdpi/portal_ring_outer_holo.png b/res/drawable-xxhdpi/portal_ring_outer_holo.png
new file mode 100644
index 0000000..281e9b5
--- /dev/null
+++ b/res/drawable-xxhdpi/portal_ring_outer_holo.png
Binary files differ
diff --git a/res/drawable-xxhdpi/portal_ring_rest.png b/res/drawable-xxhdpi/portal_ring_rest.png
new file mode 100644
index 0000000..947d7db
--- /dev/null
+++ b/res/drawable-xxhdpi/portal_ring_rest.png
Binary files differ
diff --git a/res/drawable-xxhdpi/search_bg_panel.9.png b/res/drawable-xxhdpi/search_bg_panel.9.png
new file mode 100644
index 0000000..85cae17
--- /dev/null
+++ b/res/drawable-xxhdpi/search_bg_panel.9.png
Binary files differ
diff --git a/res/drawable-xxhdpi/search_frame.9.png b/res/drawable-xxhdpi/search_frame.9.png
new file mode 100644
index 0000000..f297bf1
--- /dev/null
+++ b/res/drawable-xxhdpi/search_frame.9.png
Binary files differ
diff --git a/res/drawable-xxhdpi/tab_selected_focused_holo.9.png b/res/drawable-xxhdpi/tab_selected_focused_holo.9.png
new file mode 100644
index 0000000..2400c65
--- /dev/null
+++ b/res/drawable-xxhdpi/tab_selected_focused_holo.9.png
Binary files differ
diff --git a/res/drawable-xxhdpi/tab_selected_holo.9.png b/res/drawable-xxhdpi/tab_selected_holo.9.png
new file mode 100644
index 0000000..5067cbb
--- /dev/null
+++ b/res/drawable-xxhdpi/tab_selected_holo.9.png
Binary files differ
diff --git a/res/drawable-xxhdpi/tab_selected_pressed_holo.9.png b/res/drawable-xxhdpi/tab_selected_pressed_holo.9.png
new file mode 100644
index 0000000..84c246d
--- /dev/null
+++ b/res/drawable-xxhdpi/tab_selected_pressed_holo.9.png
Binary files differ
diff --git a/res/drawable-xxhdpi/tab_unselected_focused_holo.9.png b/res/drawable-xxhdpi/tab_unselected_focused_holo.9.png
new file mode 100644
index 0000000..939e0c3
--- /dev/null
+++ b/res/drawable-xxhdpi/tab_unselected_focused_holo.9.png
Binary files differ
diff --git a/res/drawable-xxhdpi/tab_unselected_holo.9.png b/res/drawable-xxhdpi/tab_unselected_holo.9.png
new file mode 100644
index 0000000..62ca6cf
--- /dev/null
+++ b/res/drawable-xxhdpi/tab_unselected_holo.9.png
Binary files differ
diff --git a/res/drawable-xxhdpi/tab_unselected_pressed_holo.9.png b/res/drawable-xxhdpi/tab_unselected_pressed_holo.9.png
new file mode 100644
index 0000000..58ac0d6
--- /dev/null
+++ b/res/drawable-xxhdpi/tab_unselected_pressed_holo.9.png
Binary files differ
diff --git a/res/drawable-xxhdpi/widget_container_holo.9.png b/res/drawable-xxhdpi/widget_container_holo.9.png
new file mode 100644
index 0000000..8f79920
--- /dev/null
+++ b/res/drawable-xxhdpi/widget_container_holo.9.png
Binary files differ
diff --git a/res/drawable-xxhdpi/widget_resize_frame_holo.9.png b/res/drawable-xxhdpi/widget_resize_frame_holo.9.png
new file mode 100644
index 0000000..a38e7d5
--- /dev/null
+++ b/res/drawable-xxhdpi/widget_resize_frame_holo.9.png
Binary files differ
diff --git a/res/drawable-xxhdpi/widget_resize_handle_bottom.png b/res/drawable-xxhdpi/widget_resize_handle_bottom.png
new file mode 100644
index 0000000..a241c59
--- /dev/null
+++ b/res/drawable-xxhdpi/widget_resize_handle_bottom.png
Binary files differ
diff --git a/res/drawable-xxhdpi/widget_resize_handle_left.png b/res/drawable-xxhdpi/widget_resize_handle_left.png
new file mode 100644
index 0000000..24046ea
--- /dev/null
+++ b/res/drawable-xxhdpi/widget_resize_handle_left.png
Binary files differ
diff --git a/res/drawable-xxhdpi/widget_resize_handle_right.png b/res/drawable-xxhdpi/widget_resize_handle_right.png
new file mode 100644
index 0000000..968ffe2
--- /dev/null
+++ b/res/drawable-xxhdpi/widget_resize_handle_right.png
Binary files differ
diff --git a/res/drawable-xxhdpi/widget_resize_handle_top.png b/res/drawable-xxhdpi/widget_resize_handle_top.png
new file mode 100644
index 0000000..a2bab29
--- /dev/null
+++ b/res/drawable-xxhdpi/widget_resize_handle_top.png
Binary files differ
diff --git a/res/drawable-xxhdpi/widget_tile_jb.png b/res/drawable-xxhdpi/widget_tile_jb.png
new file mode 100644
index 0000000..363fe84
--- /dev/null
+++ b/res/drawable-xxhdpi/widget_tile_jb.png
Binary files differ
diff --git a/res/drawable-xxhdpi/workspace_bg.9.png b/res/drawable-xxhdpi/workspace_bg.9.png
new file mode 100644
index 0000000..efc9b04
--- /dev/null
+++ b/res/drawable-xxhdpi/workspace_bg.9.png
Binary files differ
diff --git a/res/drawable/flying_icon_bg.xml b/res/drawable/flying_icon_bg.xml
deleted file mode 100644
index 167c3ba..0000000
--- a/res/drawable/flying_icon_bg.xml
+++ /dev/null
@@ -1,20 +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.
--->
-
-<selector xmlns:android="http://schemas.android.com/apk/res/android">
-    <item android:state_pressed="true" android:drawable="@drawable/flying_icon_bg_pressed" />
-    <item android:drawable="@android:color/transparent" />
-</selector>
diff --git a/res/values/strings.xml b/res/values/strings.xml
index bd803c6..e04902a 100644
--- a/res/values/strings.xml
+++ b/res/values/strings.xml
@@ -45,6 +45,8 @@
     <string name="gallery">Gallery</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 -->
diff --git a/res/values/styles.xml b/res/values/styles.xml
index 6eb044c..618bb47 100644
--- a/res/values/styles.xml
+++ b/res/values/styles.xml
@@ -18,13 +18,13 @@
 -->
 
 <resources>
-    <style name="Theme.WallpaperPicker" parent="@android:style/Theme.Holo">
-        <item name="android:actionBarStyle">@style/WallpaperPickerActionBar</item>
+    <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>
     </style>
 
-    <style name="WallpaperPickerActionBar" parent="android:style/Widget.Holo.ActionBar">
+    <style name="WallpaperCropperActionBar" parent="android:style/Widget.Holo.ActionBar">
         <item name="android:displayOptions">showCustom</item>
         <item name="android:background">#88000000</item>
     </style>
diff --git a/src/com/android/launcher3/CellLayout.java b/src/com/android/launcher3/CellLayout.java
index 682c2ed..04f4d81 100644
--- a/src/com/android/launcher3/CellLayout.java
+++ b/src/com/android/launcher3/CellLayout.java
@@ -64,6 +64,8 @@
     private Launcher mLauncher;
     private int mCellWidth;
     private int mCellHeight;
+    private int mFixedCellWidth;
+    private int mFixedCellHeight;
 
     private int mCountX;
     private int mCountY;
@@ -193,8 +195,8 @@
         DeviceProfile grid = app.getDynamicGrid().getDeviceProfile();
         TypedArray a = context.obtainStyledAttributes(attrs, R.styleable.CellLayout, defStyle, 0);
 
-        mCellWidth = -1;
-        mCellHeight = -1;
+        mCellWidth = mCellHeight = -1;
+        mFixedCellHeight = mFixedCellHeight = -1;
         mWidthGap = mOriginalWidthGap = 0;
         mHeightGap = mOriginalHeightGap = 0;
         mMaxGap = Integer.MAX_VALUE;
@@ -310,8 +312,8 @@
     }
 
     public void setCellDimensions(int width, int height) {
-        mCellWidth = width;
-        mCellHeight = height;
+        mFixedCellWidth = mCellWidth = width;
+        mFixedCellHeight = mCellHeight = height;
         mShortcutsAndWidgets.setCellDimensions(mCellWidth, mCellHeight, mWidthGap, mHeightGap,
                 mCountX, mCountY);
     }
@@ -947,13 +949,15 @@
         int heightSpecMode = MeasureSpec.getMode(heightMeasureSpec);
         int widthSize = MeasureSpec.getSize(widthMeasureSpec);
         int heightSize =  MeasureSpec.getSize(heightMeasureSpec);
-        int cw = grid.calculateCellWidth(widthSize, mCountX);
-        int ch = grid.calculateCellHeight(heightSize, mCountY);
-        if (cw != mCellWidth || ch != mCellHeight) {
-            mCellWidth = cw;
-            mCellHeight = ch;
-            mShortcutsAndWidgets.setCellDimensions(mCellWidth, mCellHeight, mWidthGap,
-                    mHeightGap, mCountX, mCountY);
+        if (mFixedCellWidth < 0 || mFixedCellHeight < 0) {
+            int cw = grid.calculateCellWidth(widthSize, mCountX);
+            int ch = grid.calculateCellHeight(heightSize, mCountY);
+            if (cw != mCellWidth || ch != mCellHeight) {
+                mCellWidth = cw;
+                mCellHeight = ch;
+                mShortcutsAndWidgets.setCellDimensions(mCellWidth, mCellHeight, mWidthGap,
+                        mHeightGap, mCountX, mCountY);
+            }
         }
 
         int newWidth = widthSize;
diff --git a/src/com/android/launcher3/DynamicGrid.java b/src/com/android/launcher3/DynamicGrid.java
index f43af61..70f0000 100644
--- a/src/com/android/launcher3/DynamicGrid.java
+++ b/src/com/android/launcher3/DynamicGrid.java
@@ -223,17 +223,16 @@
         availableWidthPx = awPx;
         availableHeightPx = ahPx;
 
-        if (isLandscape) {
-            allAppsNumRows = (int) numRows - 1;
-        } else {
-            allAppsNumRows = (int) numRows + 1;
-        }
         Rect padding = getWorkspacePadding(isLandscape ?
                 CellLayout.LANDSCAPE : CellLayout.PORTRAIT);
         int pageIndicatorOffset =
             resources.getDimensionPixelSize(R.dimen.apps_customize_page_indicator_offset);
-        allAppsNumRows = (availableHeightPx - pageIndicatorOffset - 4 * edgeMarginPx) /
-                (iconSizePx + iconTextSizePx + 2 * edgeMarginPx);
+        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);
     }
diff --git a/src/com/android/launcher3/Hotseat.java b/src/com/android/launcher3/Hotseat.java
index ec787614..fbbb09f 100644
--- a/src/com/android/launcher3/Hotseat.java
+++ b/src/com/android/launcher3/Hotseat.java
@@ -69,6 +69,14 @@
     CellLayout getLayout() {
         return mContent;
     }
+
+    /**
+     * Registers the specified listener on the cell layout of the hotseat.
+     */
+    @Override
+    public void setOnLongClickListener(OnLongClickListener l) {
+        mContent.setOnLongClickListener(l);
+    }
   
     private boolean hasVerticalHotseat() {
         return (mIsLandscape && mTransposeLayoutWithOrientation);
diff --git a/src/com/android/launcher3/Launcher.java b/src/com/android/launcher3/Launcher.java
index 29c4e3e..0a92f35 100644
--- a/src/com/android/launcher3/Launcher.java
+++ b/src/com/android/launcher3/Launcher.java
@@ -660,9 +660,6 @@
                 completeAddAppWidget(appWidgetId, args.container, args.screenId, null, null);
                 result = true;
                 break;
-            case REQUEST_PICK_WALLPAPER:
-                // We just wanted the activity result here so we can clear mWaitingForResult
-                break;
         }
         // Before adding this resetAddInfo(), after a shortcut was added to a workspace screen,
         // if you turned the screen off and then back while in All Apps, Launcher would not
@@ -686,7 +683,13 @@
                 addAppWidgetImpl(appWidgetId, mPendingAddInfo, null, mPendingAddWidgetInfo);
             }
             return;
+        } else if (requestCode == REQUEST_PICK_WALLPAPER) {
+            if (resultCode == RESULT_OK && mWorkspace.isInOverviewMode()) {
+                mWorkspace.exitOverviewMode(false);
+            }
+            return;
         }
+
         boolean delayExitSpringLoadedMode = false;
         boolean isWidgetDrop = (requestCode == REQUEST_PICK_APPWIDGET ||
                 requestCode == REQUEST_CREATE_APPWIDGET);
@@ -1114,6 +1117,7 @@
         mHotseat = (Hotseat) findViewById(R.id.hotseat);
         if (mHotseat != null) {
             mHotseat.setup(this);
+            mHotseat.setOnLongClickListener(this);
         }
 
         mOverviewPanel = findViewById(R.id.overview_panel);
@@ -1630,10 +1634,7 @@
                     // If we are already on home, then just animate back to the workspace,
                     // otherwise, just wait until onResume to set the state back to Workspace
                     if (alreadyOnHome) {
-                        showWorkspace(true);
-                        if (mWorkspace.isInOverviewMode()) {
-                            mWorkspace.exitOverviewMode();
-                        }
+                        showWorkspaceAndExitOverviewMode();
                     } else {
                         mOnResumeState = State.WORKSPACE;
                     }
@@ -1667,6 +1668,13 @@
         }
     }
 
+    protected void showWorkspaceAndExitOverviewMode() {
+        showWorkspace(true);
+        if (mWorkspace.isInOverviewMode()) {
+            mWorkspace.exitOverviewMode(true);
+        }
+    }
+
     @Override
     public void onRestoreInstanceState(Bundle state) {
         super.onRestoreInstanceState(state);
@@ -1940,6 +1948,9 @@
         }
     }
 
+    protected void moveToCustomContentScreen(boolean animate) {
+        mWorkspace.moveToCustomContentScreen(animate);
+    }
     /**
      * Process a shortcut drop.
      *
@@ -2120,7 +2131,7 @@
         if (isAllAppsVisible()) {
             showWorkspace(true);
         } else if (mWorkspace.isInOverviewMode()) {
-            mWorkspace.exitOverviewMode();
+            mWorkspace.exitOverviewMode(true);
         } else if (mWorkspace.getOpenFolder() != null) {
             Folder openFolder = mWorkspace.getOpenFolder();
             if (openFolder.isEditingName()) {
@@ -2170,7 +2181,7 @@
 
         if (v instanceof CellLayout) {
             if (mWorkspace.isInOverviewMode()) {
-                mWorkspace.exitOverviewMode(mWorkspace.indexOfChild(v));
+                mWorkspace.exitOverviewMode(mWorkspace.indexOfChild(v), true);
             }
         }
 
@@ -3560,8 +3571,10 @@
     public void bindScreens(ArrayList<Long> orderedScreenIds) {
         bindAddScreens(orderedScreenIds);
 
-        // Create the new empty page
-        mWorkspace.addExtraEmptyScreen();
+        // If there are no screens, we need to have an empty screen
+        if (orderedScreenIds.size() == 0) {
+            mWorkspace.addExtraEmptyScreen();
+        }
 
         // Create the custom content page (this call updates mDefaultScreen which calls
         // setCurrentPage() so ensure that all pages are added before calling this)
diff --git a/src/com/android/launcher3/LauncherModel.java b/src/com/android/launcher3/LauncherModel.java
index 18e1c85..179c8aa 100644
--- a/src/com/android/launcher3/LauncherModel.java
+++ b/src/com/android/launcher3/LauncherModel.java
@@ -2428,9 +2428,6 @@
         private void loadAllApps() {
             final long loadTime = DEBUG_LOADERS ? SystemClock.uptimeMillis() : 0;
 
-            // "two variables"?
-            // Don't use these two variables in any of the callback runnables.
-            // Otherwise we hold a reference to them.
             final Callbacks oldCallbacks = mCallbacks.get();
             if (oldCallbacks == null) {
                 // This launcher has exited and nobody bothered to tell us.  Just bail.
@@ -2477,7 +2474,6 @@
             }
 
             // Huh? Shouldn't this be inside the Runnable below?
-            final Callbacks callbacks = tryGetCallbacks(oldCallbacks);
             final ArrayList<AppInfo> added = mBgAllAppsList.added;
             mBgAllAppsList.added = new ArrayList<AppInfo>();
 
@@ -2485,6 +2481,7 @@
             mHandler.post(new Runnable() {
                 public void run() {
                     final long bindTime = SystemClock.uptimeMillis();
+                    final Callbacks callbacks = tryGetCallbacks(oldCallbacks);
                     if (callbacks != null) {
                         callbacks.bindAllApplications(added);
                         if (DEBUG_LOADERS) {
diff --git a/src/com/android/launcher3/PagedView.java b/src/com/android/launcher3/PagedView.java
index bdb0d58..dcb71d2 100644
--- a/src/com/android/launcher3/PagedView.java
+++ b/src/com/android/launcher3/PagedView.java
@@ -2718,4 +2718,4 @@
     public boolean onHoverEvent(android.view.MotionEvent event) {
         return true;
     }
-}
\ No newline at end of file
+}
diff --git a/src/com/android/launcher3/WallpaperCropActivity.java b/src/com/android/launcher3/WallpaperCropActivity.java
index dee9fe9..f5a6b80 100644
--- a/src/com/android/launcher3/WallpaperCropActivity.java
+++ b/src/com/android/launcher3/WallpaperCropActivity.java
@@ -22,6 +22,7 @@
 import android.content.Context;
 import android.content.Intent;
 import android.content.SharedPreferences;
+import android.content.res.Configuration;
 import android.content.res.Resources;
 import android.graphics.Bitmap;
 import android.graphics.Bitmap.CompressFormat;
@@ -100,6 +101,10 @@
                 });
     }
 
+    public static String getSharedPreferencesKey() {
+        return WallpaperCropActivity.class.getName();
+    }
+
     // As a ratio of screen height, the total distance we want the parallax effect to span
     // horizontally
     private static float wallpaperTravelToScreenWidthRatio(int width, int height) {
@@ -145,7 +150,7 @@
         // for the intended
         // parallax effects
         final int defaultWidth, defaultHeight;
-        if (LauncherAppState.isScreenLarge(res)) {
+        if (isScreenLarge(res)) {
             defaultWidth = (int) (maxDim * wallpaperTravelToScreenWidthRatio(maxDim, minDim));
             defaultHeight = maxDim;
         } else {
@@ -200,6 +205,11 @@
         cropTask.execute();
     }
 
+    private static boolean isScreenLarge(Resources res) {
+        Configuration config = res.getConfiguration();
+        return config.smallestScreenWidthDp >= 720;
+    }
+
     protected void cropImageAndSetWallpaper(Uri uri,
             OnBitmapCroppedHandler onBitmapCroppedHandler, final boolean finishActivityWhenDone) {
      // Get the crop
@@ -216,7 +226,7 @@
         int maxDim = Math.max(maxDims.x, maxDims.y);
         final int minDim = Math.min(minDims.x, minDims.y);
         int defaultWidth;
-        if (LauncherAppState.isScreenLarge(getResources())) {
+        if (isScreenLarge(getResources())) {
             defaultWidth = (int) (maxDim *
                     wallpaperTravelToScreenWidthRatio(maxDim, minDim));
         } else {
@@ -564,7 +574,7 @@
     }
 
     protected void updateWallpaperDimensions(int width, int height) {
-        String spKey = LauncherAppState.getSharedPreferencesKey();
+        String spKey = getSharedPreferencesKey();
         SharedPreferences sp = getSharedPreferences(spKey, Context.MODE_PRIVATE);
         SharedPreferences.Editor editor = sp.edit();
         if (width != 0 && height != 0) {
diff --git a/src/com/android/launcher3/WallpaperPickerActivity.java b/src/com/android/launcher3/WallpaperPickerActivity.java
index a0b9e6e..fe7525a 100644
--- a/src/com/android/launcher3/WallpaperPickerActivity.java
+++ b/src/com/android/launcher3/WallpaperPickerActivity.java
@@ -306,27 +306,27 @@
             // Called when the user selects a contextual menu item
             @Override
             public boolean onActionItemClicked(ActionMode mode, MenuItem item) {
-                switch (item.getItemId()) {
-                    case R.id.menu_delete:
-                        int childCount = mWallpapersView.getChildCount();
-                        ArrayList<View> viewsToRemove = new ArrayList<View>();
-                        for (int i = 0; i < childCount; i++) {
-                            CheckableFrameLayout c =
-                                    (CheckableFrameLayout) mWallpapersView.getChildAt(i);
-                            if (c.isChecked()) {
-                                ThumbnailMetaData meta = (ThumbnailMetaData) c.getTag();
-                                mSavedImages.deleteImage(meta.mSavedWallpaperDbId);
-                                viewsToRemove.add(c);
-                            }
+                int itemId = item.getItemId();
+                if (itemId == R.id.menu_delete) {
+                    int childCount = mWallpapersView.getChildCount();
+                    ArrayList<View> viewsToRemove = new ArrayList<View>();
+                    for (int i = 0; i < childCount; i++) {
+                        CheckableFrameLayout c =
+                                (CheckableFrameLayout) mWallpapersView.getChildAt(i);
+                        if (c.isChecked()) {
+                            ThumbnailMetaData meta = (ThumbnailMetaData) c.getTag();
+                            mSavedImages.deleteImage(meta.mSavedWallpaperDbId);
+                            viewsToRemove.add(c);
                         }
-                        for (View v : viewsToRemove) {
-                            mWallpapersView.removeView(v);
-                        }
-                        ///xxxxx DESTROYING
-                        mode.finish(); // Action picked, so close the CAB
-                        return true;
-                    default:
-                        return false;
+                    }
+                    for (View v : viewsToRemove) {
+                        mWallpapersView.removeView(v);
+                    }
+                    ///xxxxx DESTROYING
+                    mode.finish(); // Action picked, so close the CAB
+                    return true;
+                } else {
+                    return false;
                 }
             }
 
diff --git a/src/com/android/launcher3/Workspace.java b/src/com/android/launcher3/Workspace.java
index 3f63d74..1818ade 100644
--- a/src/com/android/launcher3/Workspace.java
+++ b/src/com/android/launcher3/Workspace.java
@@ -30,6 +30,7 @@
 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;
 import android.graphics.Bitmap;
@@ -51,6 +52,7 @@
 import android.view.MotionEvent;
 import android.view.View;
 import android.view.ViewGroup;
+import android.view.ViewParent;
 import android.view.animation.DecelerateInterpolator;
 import android.view.animation.Interpolator;
 import android.widget.TextView;
@@ -111,6 +113,8 @@
     private int mOriginalDefaultPage;
     private int mDefaultPage;
 
+    private ShortcutAndWidgetContainer mDragSourceInternal;
+
     // The screen id used for the empty screen always present to the right.
     private final static long EXTRA_EMPTY_SCREEN_ID = -201;
     private final static long CUSTOM_CONTENT_SCREEN_ID = -301;
@@ -353,7 +357,7 @@
         return r;
     }
 
-    public void onDragStart(DragSource source, Object info, int dragAction) {
+    public void onDragStart(final DragSource source, Object info, int dragAction) {
         mIsDragOccuring = true;
         updateChildrenLayersEnabled(false);
         mLauncher.lockScreenOrientation();
@@ -361,6 +365,14 @@
         // Prevent any Un/InstallShortcutReceivers from updating the db while we are dragging
         InstallShortcutReceiver.enableInstallQueue();
         UninstallShortcutReceiver.enableUninstallQueue();
+        post(new Runnable() {
+            @Override
+            public void run() {
+                if (mIsDragOccuring) {
+                    addExtraEmptyScreenOnDrag();
+                }
+            }
+        });
     }
 
     public void onDragEnd() {
@@ -371,6 +383,9 @@
         // Re-enable any Un/InstallShortcutReceiver and now process any queued items
         InstallShortcutReceiver.disableAndFlushInstallQueue(getContext());
         UninstallShortcutReceiver.disableAndFlushUninstallQueue(getContext());
+
+        removeExtraEmptyScreen();
+        mDragSourceInternal = null;
     }
 
     /**
@@ -489,6 +504,10 @@
         String log = "10249126 - insertNewWorkspaceScreen(" + screenId + ", " + insertIndex + ")";
         Launcher.addDumpLog(TAG, log, true);
 
+        if (mWorkspaceScreens.containsKey(screenId)) {
+            throw new RuntimeException("Screen id " + screenId + " already exists!");
+        }
+
         CellLayout newScreen = (CellLayout)
                 mLauncher.getLayoutInflater().inflate(R.layout.workspace_screen, null);
 
@@ -539,6 +558,49 @@
         mCustomContentCallbacks = callbacks;
     }
 
+    public void addExtraEmptyScreenOnDrag() {
+        boolean lastChildOnScreen = false;
+        boolean childOnFinalScreen = false;
+
+        if (mDragSourceInternal != null) {
+            if (mDragSourceInternal.getChildCount() == 1) {
+                lastChildOnScreen = true;
+            }
+            CellLayout cl = (CellLayout) mDragSourceInternal.getParent();
+            if (indexOfChild(cl) == getChildCount() - 1) {
+                childOnFinalScreen = true;
+            }
+        }
+
+        // If this is the last item on the final screen
+        if (lastChildOnScreen && childOnFinalScreen) {
+            return;
+        }
+        if (!mWorkspaceScreens.containsKey(EXTRA_EMPTY_SCREEN_ID)) {
+            insertNewWorkspaceScreen(EXTRA_EMPTY_SCREEN_ID);
+        }
+    }
+
+    public boolean addExtraEmptyScreen() {
+        if (!mWorkspaceScreens.containsKey(EXTRA_EMPTY_SCREEN_ID)) {
+            insertNewWorkspaceScreen(EXTRA_EMPTY_SCREEN_ID);
+            return true;
+        }
+        return false;
+    }
+
+    public void removeExtraEmptyScreen() {
+        int nScreens = getChildCount();
+        nScreens = hasCustomContent() ? nScreens - 1 : nScreens;
+
+        if (mWorkspaceScreens.containsKey(EXTRA_EMPTY_SCREEN_ID) && nScreens > 1) {
+            CellLayout cl = mWorkspaceScreens.get(EXTRA_EMPTY_SCREEN_ID);
+            mWorkspaceScreens.remove(EXTRA_EMPTY_SCREEN_ID);
+            mScreenOrder.remove(EXTRA_EMPTY_SCREEN_ID);
+            removeView(cl);
+        }
+    }
+
     public long commitExtraEmptyScreen() {
         Launcher.addDumpLog(TAG, "10249126 - commitExtraEmptyScreen()", true);
 
@@ -554,17 +616,12 @@
         mWorkspaceScreens.put(newId, cl);
         mScreenOrder.add(newId);
 
-        addExtraEmptyScreen();
-
         // Update the model for the new screen
         mLauncher.getModel().updateWorkspaceScreenOrder(mLauncher, mScreenOrder);
 
         return newId;
     }
 
-    public void addExtraEmptyScreen() {
-        insertNewWorkspaceScreen(EXTRA_EMPTY_SCREEN_ID);
-    }
 
     public CellLayout getScreenWithId(long screenId) {
         Launcher.addDumpLog(TAG, "10249126 - getScreenWithId(" + screenId + ")", true);
@@ -629,16 +686,27 @@
             }
         }
 
+        // We enforce at least one page to add new items to. In the case that we remove the last
+        // such screen, we convert the last screen to the empty screen
+        int minScreens = hasCustomContent() ? 2 : 1;
+
         int pageShift = 0;
         for (Long id: removeScreens) {
             Launcher.addDumpLog(TAG, "10249126 - \tremove(" + id + ")", true);
             CellLayout cl = mWorkspaceScreens.get(id);
             mWorkspaceScreens.remove(id);
             mScreenOrder.remove(id);
-            if (indexOfChild(cl) < currentPage) {
-                pageShift++;
+
+            if (getChildCount() > minScreens) {
+                if (indexOfChild(cl) < currentPage) {
+                    pageShift++;
+                }
+                removeView(cl);
+            } else {
+                // if this is the last non-custom content screen, convert it to the empty screen
+                mWorkspaceScreens.put(EXTRA_EMPTY_SCREEN_ID, cl);
+                mScreenOrder.add(EXTRA_EMPTY_SCREEN_ID);
             }
-            removeView(cl);
         }
 
         if (!removeScreens.isEmpty()) {
@@ -977,8 +1045,10 @@
     };
 
     protected void setWallpaperDimension() {
+        String spKey = WallpaperCropActivity.getSharedPreferencesKey();
+        SharedPreferences sp = mLauncher.getSharedPreferences(spKey, Context.MODE_PRIVATE);
         WallpaperPickerActivity.suggestWallpaperDimension(mLauncher.getResources(),
-                mLauncher.getSharedPrefs(), mLauncher.getWindowManager(), mWallpaperManager);
+                sp, mLauncher.getWindowManager(), mWallpaperManager);
     }
 
 
@@ -1266,9 +1336,10 @@
     }
 
     private void updateStateForCustomContent(int screenCenter) {
-        if (hasCustomContent() && !isSmall() && !isSwitchingState()) {
+        if (hasCustomContent()) {
             int index = mScreenOrder.indexOf(CUSTOM_CONTENT_SCREEN_ID);
             int scrollDelta = getScrollForPage(index + 1) - getScrollX();
+            float translationX = Math.max(scrollDelta, 0);
             float progress = (1.0f * scrollDelta) /
                     (getScrollForPage(index + 1) - getScrollForPage(index));
             progress = Math.max(0, progress);
@@ -1277,28 +1348,13 @@
             mLastCustomContentScrollProgress = progress;
 
             setBackgroundAlpha(progress * 0.8f);
-            float height = getViewportHeight();
-            if (getPageIndicator() != null) {
-                height -= getPageIndicator().getTop();
-            } else if (mLauncher.getHotseat() != null) {
-                height -= mLauncher.getHotseat().getTop();
-            }
-            float transY = progress * height;
 
             if (mLauncher.getHotseat() != null) {
-                mLauncher.getHotseat().setTranslationY(transY);
-                mLauncher.getHotseat().setAlpha(1 - progress);
+                mLauncher.getHotseat().setTranslationX(translationX);
             }
 
             if (getPageIndicator() != null) {
-                final float alpha = 1 - progress;
-                final View pi = getPageIndicator();
-                getPageIndicator().setAlpha(alpha);
-                if (alpha < ALPHA_CUTOFF_THRESHOLD && pi.getVisibility() != INVISIBLE) {
-                    pi.setVisibility(INVISIBLE);
-                } else if (alpha > ALPHA_CUTOFF_THRESHOLD && pi.getVisibility() != VISIBLE) {
-                    pi.setVisibility(VISIBLE);
-                }
+                getPageIndicator().setTranslationX(translationX);
             }
 
             if (mCustomContentCallbacks != null) {
@@ -1701,35 +1757,37 @@
     }
 
     public void enterOverviewMode() {
-        enableOverviewMode(true, -1);
+        enableOverviewMode(true, -1, true);
     }
 
-    public void exitOverviewMode() {
-        exitOverviewMode(-1);
+    public void exitOverviewMode(boolean animated) {
+        exitOverviewMode(-1, animated);
     }
 
-    public void exitOverviewMode(int snapPage) {
-        enableOverviewMode(false, snapPage);
+    public void exitOverviewMode(int snapPage, boolean animated) {
+        enableOverviewMode(false, snapPage, animated);
     }
 
-    private void enableOverviewMode(boolean enable, int snapPage) {
+    private void enableOverviewMode(boolean enable, int snapPage, boolean animated) {
         State finalState = Workspace.State.OVERVIEW;
         if (!enable) {
             finalState = Workspace.State.NORMAL;
         }
 
-        Animator workspaceAnim = getChangeStateAnimation(finalState, true, 0, snapPage);
-        workspaceAnim.addListener(new AnimatorListenerAdapter() {
-            @Override
-            public void onAnimationEnd(Animator arg0) {
-                mIsSwitchingState = false;
-            }
-            @Override
-            public void onAnimationStart(Animator arg0) {
-                mIsSwitchingState = true;
-            }
-        });
-        workspaceAnim.start();
+        Animator workspaceAnim = getChangeStateAnimation(finalState, animated, 0, snapPage);
+        if (workspaceAnim != null) {
+            workspaceAnim.addListener(new AnimatorListenerAdapter() {
+                @Override
+                public void onAnimationEnd(Animator arg0) {
+                    mIsSwitchingState = false;
+                }
+                @Override
+                public void onAnimationStart(Animator arg0) {
+                    mIsSwitchingState = true;
+                }
+            });
+            workspaceAnim.start();
+        }
     }
 
     Animator getChangeStateAnimation(final State state, boolean animated, int delay, int snapPage) {
@@ -1877,9 +1935,12 @@
             anim.setStartDelay(delay);
         } else {
             mLauncher.getOverviewPanel().setAlpha(finalOverviewPanelAlpha);
+            AlphaUpdateListener.updateVisibility(mLauncher.getOverviewPanel());
             mLauncher.getHotseat().setAlpha(finalHotseatAndPageIndicatorAlpha);
+            AlphaUpdateListener.updateVisibility(mLauncher.getHotseat());
             if (getPageIndicator() != null) {
                 getPageIndicator().setAlpha(finalHotseatAndPageIndicatorAlpha);
+                AlphaUpdateListener.updateVisibility(getPageIndicator());
             }
         }
 
@@ -1896,7 +1957,7 @@
         return anim;
     }
 
-    class AlphaUpdateListener implements AnimatorUpdateListener {
+    static class AlphaUpdateListener implements AnimatorUpdateListener {
         View view;
         public AlphaUpdateListener(View v) {
             view = v;
@@ -1904,6 +1965,10 @@
 
         @Override
         public void onAnimationUpdate(ValueAnimator arg0) {
+            updateVisibility(view);
+        }
+
+        public static void updateVisibility(View view) {
             if (view.getAlpha() < ALPHA_CUTOFF_THRESHOLD && view.getVisibility() != INVISIBLE) {
                 view.setVisibility(INVISIBLE);
             } else if (view.getAlpha() > ALPHA_CUTOFF_THRESHOLD
@@ -2130,6 +2195,11 @@
 
         mDragController.startDrag(b, dragLayerX, dragLayerY, source, child.getTag(),
                 DragController.DRAG_ACTION_MOVE, dragVisualizeOffset, dragRect, scale);
+
+        if (child.getParent() instanceof ShortcutAndWidgetContainer) {
+            mDragSourceInternal = (ShortcutAndWidgetContainer) child.getParent();
+        }
+
         b.recycle();
     }
 
@@ -4069,20 +4139,39 @@
         }
     }
 
-    void moveToDefaultScreen(boolean animate) {
+    private void moveToScreen(int page, boolean animate) {
         if (!isSmall()) {
             if (animate) {
-                snapToPage(mDefaultPage);
+                snapToPage(page);
             } else {
-                setCurrentPage(mDefaultPage);
+                setCurrentPage(page);
             }
         }
-        View child = getChildAt(mDefaultPage);
+        View child = getChildAt(page);
         if (child != null) {
             child.requestFocus();
         }
     }
 
+    void moveToDefaultScreen(boolean animate) {
+        moveToScreen(mDefaultPage, animate);
+    }
+
+    void moveToCustomContentScreen(boolean animate) {
+        if (hasCustomContent()) {
+            int ccIndex = getPageIndexForScreenId(CUSTOM_CONTENT_SCREEN_ID);
+            if (animate) {
+                snapToPage(ccIndex);
+            } else {
+                setCurrentPage(ccIndex);
+            }
+            View child = getChildAt(ccIndex);
+            if (child != null) {
+                child.requestFocus();
+            }
+         }
+    }
+
     @Override
     protected int getPageIndicatorMarker(int pageIndex) {
         if (getScreenIdForPageIndex(pageIndex) == CUSTOM_CONTENT_SCREEN_ID) {