Initial changes to merged AllApps/Customize pane in the Phone UI.

Change-Id: Ifa1676736033fe617dd0cca965156c38fa452948
diff --git a/res/anim/all_apps_2d_fade_in.xml b/res/anim/all_apps_2d_fade_in.xml
index 0f1e4f4..9d2171a 100644
--- a/res/anim/all_apps_2d_fade_in.xml
+++ b/res/anim/all_apps_2d_fade_in.xml
@@ -20,4 +20,4 @@
     android:fromAlpha="0.0"
     android:toAlpha="1.0"
 
-    android:duration="@integer/config_allAppsFadeInTime" />
+    android:duration="@integer/config_appsCustomizeFadeInTime" />
diff --git a/res/anim/all_apps_2d_fade_out.xml b/res/anim/all_apps_2d_fade_out.xml
index cc47691..90520c7 100644
--- a/res/anim/all_apps_2d_fade_out.xml
+++ b/res/anim/all_apps_2d_fade_out.xml
@@ -20,4 +20,4 @@
     android:fromAlpha="1.0"
     android:toAlpha="0.0"
 
-    android:duration="@integer/config_allAppsFadeOutTime" />
+    android:duration="@integer/config_appsCustomizeFadeOutTime" />
diff --git a/res/anim/fade_in_slow.xml b/res/anim/fade_in_slow.xml
index 0f1e4f4..9d2171a 100644
--- a/res/anim/fade_in_slow.xml
+++ b/res/anim/fade_in_slow.xml
@@ -20,4 +20,4 @@
     android:fromAlpha="0.0"
     android:toAlpha="1.0"
 
-    android:duration="@integer/config_allAppsFadeInTime" />
+    android:duration="@integer/config_appsCustomizeFadeInTime" />
diff --git a/res/anim/fade_out_slow.xml b/res/anim/fade_out_slow.xml
index cc47691..90520c7 100644
--- a/res/anim/fade_out_slow.xml
+++ b/res/anim/fade_out_slow.xml
@@ -20,4 +20,4 @@
     android:fromAlpha="1.0"
     android:toAlpha="0.0"
 
-    android:duration="@integer/config_allAppsFadeOutTime" />
+    android:duration="@integer/config_appsCustomizeFadeOutTime" />
diff --git a/res/drawable-xlarge-mdpi/focused_bg.9.png b/res/drawable-hdpi/focused_bg.9.png
similarity index 100%
copy from res/drawable-xlarge-mdpi/focused_bg.9.png
copy to res/drawable-hdpi/focused_bg.9.png
Binary files differ
diff --git a/res/drawable-xlarge-hdpi/home_press.9.png b/res/drawable-hdpi/home_press.9.png
similarity index 100%
rename from res/drawable-xlarge-hdpi/home_press.9.png
rename to res/drawable-hdpi/home_press.9.png
Binary files differ
diff --git a/res/drawable-xlarge-hdpi/ic_home_delete_holo_dark.png b/res/drawable-hdpi/ic_home_delete_holo_dark.png
similarity index 100%
rename from res/drawable-xlarge-hdpi/ic_home_delete_holo_dark.png
rename to res/drawable-hdpi/ic_home_delete_holo_dark.png
Binary files differ
diff --git a/res/drawable-xlarge-hdpi/ic_home_delete_hover_holo_dark.png b/res/drawable-hdpi/ic_home_delete_hover_holo_dark.png
similarity index 100%
rename from res/drawable-xlarge-hdpi/ic_home_delete_hover_holo_dark.png
rename to res/drawable-hdpi/ic_home_delete_hover_holo_dark.png
Binary files differ
diff --git a/res/drawable-hdpi/ic_home_info_holo_dark.png b/res/drawable-hdpi/ic_home_info_holo_dark.png
new file mode 100644
index 0000000..02df4e1
--- /dev/null
+++ b/res/drawable-hdpi/ic_home_info_holo_dark.png
Binary files differ
diff --git a/res/drawable-xlarge-mdpi/focused_bg.9.png b/res/drawable-mdpi/focused_bg.9.png
similarity index 100%
rename from res/drawable-xlarge-mdpi/focused_bg.9.png
rename to res/drawable-mdpi/focused_bg.9.png
Binary files differ
diff --git a/res/drawable-xlarge-mdpi/home_press.9.png b/res/drawable-mdpi/home_press.9.png
similarity index 100%
rename from res/drawable-xlarge-mdpi/home_press.9.png
rename to res/drawable-mdpi/home_press.9.png
Binary files differ
diff --git a/res/drawable-xlarge-mdpi/ic_home_delete_holo_dark.png b/res/drawable-mdpi/ic_home_delete_holo_dark.png
similarity index 100%
rename from res/drawable-xlarge-mdpi/ic_home_delete_holo_dark.png
rename to res/drawable-mdpi/ic_home_delete_holo_dark.png
Binary files differ
diff --git a/res/drawable-xlarge-mdpi/ic_home_delete_hover_holo_dark.png b/res/drawable-mdpi/ic_home_delete_hover_holo_dark.png
similarity index 100%
rename from res/drawable-xlarge-mdpi/ic_home_delete_hover_holo_dark.png
rename to res/drawable-mdpi/ic_home_delete_hover_holo_dark.png
Binary files differ
diff --git a/res/drawable-xlarge-mdpi/ic_home_info_holo_dark.png b/res/drawable-mdpi/ic_home_info_holo_dark.png
similarity index 100%
rename from res/drawable-xlarge-mdpi/ic_home_info_holo_dark.png
rename to res/drawable-mdpi/ic_home_info_holo_dark.png
Binary files differ
diff --git a/res/drawable-nodpi/apps_customize_bg_gradient.9.png b/res/drawable-nodpi/apps_customize_bg_gradient.9.png
new file mode 100644
index 0000000..e766bd6
--- /dev/null
+++ b/res/drawable-nodpi/apps_customize_bg_gradient.9.png
Binary files differ
diff --git a/res/drawable-xlarge/button_bg.xml b/res/drawable/button_bg.xml
similarity index 93%
rename from res/drawable-xlarge/button_bg.xml
rename to res/drawable/button_bg.xml
index 2cb7926..a830594 100644
--- a/res/drawable-xlarge/button_bg.xml
+++ b/res/drawable/button_bg.xml
@@ -1,5 +1,5 @@
 <?xml version="1.0" encoding="utf-8"?>
-<!-- Copyright (C) 2010 The Android Open Source Project
+<!-- 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.
diff --git a/res/drawable/delete_zone_selector.xml b/res/drawable/delete_zone_selector.xml
index 0c54b1d..e2b37f4 100644
--- a/res/drawable/delete_zone_selector.xml
+++ b/res/drawable/delete_zone_selector.xml
@@ -19,6 +19,6 @@
 -->
 
 <transition xmlns:android="http://schemas.android.com/apk/res/android">
-    <item android:drawable="@drawable/trashcan"  />
-    <item android:drawable="@drawable/trashcan_hover"  />
+    <item android:drawable="@drawable/ic_home_delete_holo_dark"  />
+    <item android:drawable="@drawable/ic_home_delete_hover_holo_dark"  />
 </transition>
diff --git a/res/drawable-xlarge/focusable_view_bg.xml b/res/drawable/focusable_view_bg.xml
similarity index 93%
rename from res/drawable-xlarge/focusable_view_bg.xml
rename to res/drawable/focusable_view_bg.xml
index fb36bfc..66661e2 100644
--- a/res/drawable-xlarge/focusable_view_bg.xml
+++ b/res/drawable/focusable_view_bg.xml
@@ -1,5 +1,5 @@
 <?xml version="1.0" encoding="utf-8"?>
-<!-- Copyright (C) 2010 The Android Open Source Project
+<!-- 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.
diff --git a/res/layout-land/launcher.xml b/res/layout-land/launcher.xml
index 6e797f8..b525a4b 100644
--- a/res/layout-land/launcher.xml
+++ b/res/layout-land/launcher.xml
@@ -22,8 +22,6 @@
     android:layout_width="match_parent"
     android:layout_height="match_parent">
 
-    <include layout="@layout/all_apps" />
-
     <!-- The workspace contains 5 screens of cells -->
     <com.android.launcher2.Workspace
         android:id="@+id/workspace"
@@ -43,6 +41,12 @@
 
     </com.android.launcher2.Workspace>
 
+    <include layout="@layout/apps_customize_pane"
+        android:id="@+id/apps_customize_pane"
+        android:layout_width="match_parent"
+        android:layout_height="match_parent"
+        android:visibility="invisible" />
+
     <com.android.launcher2.ClippedImageView
         android:id="@+id/previous_screen"
         android:layout_width="93dip"
diff --git a/res/layout-port/launcher.xml b/res/layout-port/launcher.xml
index b7c61d8..b10b56d 100644
--- a/res/layout-port/launcher.xml
+++ b/res/layout-port/launcher.xml
@@ -22,8 +22,6 @@
     android:layout_width="match_parent"
     android:layout_height="match_parent">
 
-    <include layout="@layout/all_apps" />
-
     <!-- The workspace contains 5 screens of cells -->
     <com.android.launcher2.Workspace
         android:id="@+id/workspace"
@@ -41,6 +39,12 @@
                 
     </com.android.launcher2.Workspace>
 
+    <include layout="@layout/apps_customize_pane"
+        android:id="@+id/apps_customize_pane"
+        android:layout_width="match_parent"
+        android:layout_height="match_parent"
+        android:visibility="invisible" />
+
     <ImageView
         android:id="@+id/previous_screen"
         android:layout_width="93dip"
diff --git a/res/layout-xlarge/launcher.xml b/res/layout-xlarge/launcher.xml
index c71d131..6c6fecf 100644
--- a/res/layout-xlarge/launcher.xml
+++ b/res/layout-xlarge/launcher.xml
@@ -53,11 +53,13 @@
         android:id="@+id/all_apps_view"
         android:layout_width="match_parent"
         android:layout_height="match_parent"
-        android:layout_gravity="top" />
+        android:layout_gravity="top"
+        android:visibility="invisible" />
 
     <include layout="@layout/customization_drawer"
         android:id="@+id/customization_drawer"
         android:layout_width="match_parent"
         android:layout_height="@dimen/customization_drawer_height"
-        android:layout_gravity="bottom" />
+        android:layout_gravity="bottom"
+        android:visibility="invisible" />
 </com.android.launcher2.DragLayer>
diff --git a/res/layout-xlarge/tab_widget_indicator.xml b/res/layout-xlarge/tab_widget_indicator.xml
index 8968c2a..c09c853 100644
--- a/res/layout-xlarge/tab_widget_indicator.xml
+++ b/res/layout-xlarge/tab_widget_indicator.xml
@@ -16,4 +16,4 @@
 
 <com.android.launcher2.AccessibleTabView
     xmlns:android="http://schemas.android.com/apk/res/android"
-    style="@style/TabIndicator" />
+    style="@style/TabIndicator.Wide" />
diff --git a/res/layout/apps_customize_application.xml b/res/layout/apps_customize_application.xml
new file mode 100644
index 0000000..4f36326
--- /dev/null
+++ b/res/layout/apps_customize_application.xml
@@ -0,0 +1,32 @@
+<?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.launcher2.PagedViewIcon
+    xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:launcher="http://schemas.android.com/apk/res/com.android.launcher"
+
+    style="@style/WorkspaceIcon.AllApps"
+
+    android:id="@+id/application_icon"
+    android:layout_width="match_parent"
+    android:layout_height="match_parent"
+    android:gravity="center_horizontal"
+
+    launcher:blurColor="#FF6B8CF0"
+    launcher:outlineColor="#FF8CD2FF"
+
+    android:focusable="true"
+    android:background="@drawable/focusable_view_bg" />
diff --git a/res/layout/apps_customize_pane.xml b/res/layout/apps_customize_pane.xml
new file mode 100644
index 0000000..2b768b6
--- /dev/null
+++ b/res/layout/apps_customize_pane.xml
@@ -0,0 +1,96 @@
+<?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.launcher2.AppsCustomizeTabHost
+    xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:launcher="http://schemas.android.com/apk/res/com.android.launcher">
+    <LinearLayout
+        android:orientation="vertical"
+        android:layout_width="match_parent"
+        android:layout_height="match_parent"
+        android:background="@drawable/apps_customize_bg_gradient">
+        <!-- The layout_width of the tab bar gets overriden to align the content
+             with the text in the tabs in AppsCustomizeTabHost. -->
+        <FrameLayout
+            android:layout_width="wrap_content"
+            android:layout_height="@dimen/apps_customize_tab_bar_height"
+            android:layout_gravity="center_horizontal">
+            <com.android.launcher2.FocusOnlyTabWidget
+                android:id="@android:id/tabs"
+                android:layout_width="wrap_content"
+                android:layout_height="match_parent"
+                android:layout_gravity="left"
+                android:background="@drawable/tab_unselected_holo"
+                android:tabStripEnabled="false" />
+            <FrameLayout
+                android:layout_width="wrap_content"
+                android:layout_height="match_parent"
+                android:layout_gravity="right">
+                <LinearLayout
+                    android:layout_width="wrap_content"
+                    android:layout_height="match_parent"
+                    android:visibility="gone">
+                    <com.android.launcher2.ApplicationInfoDropTarget
+                        android:id="@+id/all_apps_info_target"
+                        android:layout_width="wrap_content"
+                        android:layout_height="match_parent"
+                        android:layout_gravity="center"
+                        android:gravity="center"
+                        android:drawableLeft="@drawable/ic_home_info_holo_dark"
+                        android:background="@drawable/focusable_view_bg"
+                        android:focusable="true"
+                        android:visibility="gone" />
+                    <com.android.launcher2.DeleteZone
+                        style="@style/DeleteZone"
+                        android:id="@+id/all_apps_delete_zone"
+                        android:layout_width="wrap_content"
+                        android:layout_height="match_parent"
+                        android:layout_gravity="center"
+                        android:gravity="center"
+                        android:background="@drawable/focusable_view_bg"
+                        android:focusable="true"
+                        android:visibility="gone"
+                        launcher:direction="horizontal" />
+                </LinearLayout>
+                <TextView
+                    style="@style/MarketButton"
+                    android:id="@+id/market_button"
+                    android:layout_width="wrap_content"
+                    android:layout_height="match_parent"
+                    android:layout_gravity="center"
+                    android:gravity="center"
+                    android:background="@drawable/tab_widget_indicator_selector"
+                    android:focusable="true" />
+            </FrameLayout>
+        </FrameLayout>
+        <FrameLayout
+            android:id="@android:id/tabcontent"
+            android:layout_width="match_parent"
+            android:layout_height="match_parent">
+            <com.android.launcher2.AppsCustomizePagedView
+                android:id="@+id/apps_customize_pane_content"
+                android:layout_width="match_parent"
+                android:layout_height="wrap_content"
+                launcher:cellCountX="@integer/all_apps_view_cellCountX"
+                launcher:cellCountY="@integer/all_apps_view_cellCountY"
+                launcher:pageLayoutWidthGap="@dimen/all_apps_view_pageLayoutWidthGap"
+                launcher:pageLayoutHeightGap="@dimen/all_apps_view_pageLayoutHeightGap"
+                launcher:pageLayoutPaddingTop="@dimen/all_apps_view_pageLayoutPaddingTop"
+                launcher:pageLayoutPaddingBottom="@dimen/all_apps_view_pageLayoutPaddingBottom"
+                launcher:pageLayoutPaddingLeft="@dimen/all_apps_view_pageLayoutPaddingLeft"
+                launcher:pageLayoutPaddingRight="@dimen/all_apps_view_pageLayoutPaddingRight" />
+         </FrameLayout>
+      </LinearLayout>
+</com.android.launcher2.AppsCustomizeTabHost>
diff --git a/res/layout-xlarge-port/tab_widget_indicator.xml b/res/layout/tab_widget_indicator.xml
similarity index 83%
rename from res/layout-xlarge-port/tab_widget_indicator.xml
rename to res/layout/tab_widget_indicator.xml
index b113b7b..b3694fe 100644
--- a/res/layout-xlarge-port/tab_widget_indicator.xml
+++ b/res/layout/tab_widget_indicator.xml
@@ -1,5 +1,5 @@
 <?xml version="1.0" encoding="utf-8"?>
-<!-- Copyright (C) 2010 The Android Open Source Project
+<!-- 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.
@@ -14,6 +14,6 @@
      limitations under the License.
 -->
 
-<TextView
+<com.android.launcher2.AccessibleTabView
     xmlns:android="http://schemas.android.com/apk/res/android"
-    style="@style/TabIndicator.Portrait" />
+    style="@style/TabIndicator" />
diff --git a/res/values-land/dimens.xml b/res/values-land/dimens.xml
index 9cb549b..111a706 100644
--- a/res/values-land/dimens.xml
+++ b/res/values-land/dimens.xml
@@ -20,4 +20,13 @@
     <dimen name="folder_cell_width">100dip</dimen>
     <dimen name="folder_cell_height">74dip</dimen>
     <dimen name="button_bar_height">62dip</dimen>
+
+    <integer name="all_apps_view_cellCountX">6</integer>
+    <integer name="all_apps_view_cellCountY">3</integer>
+    <dimen name="all_apps_view_pageLayoutWidthGap">10dp</dimen>
+    <dimen name="all_apps_view_pageLayoutHeightGap">5dp</dimen>
+    <dimen name="all_apps_view_pageLayoutPaddingTop">10dp</dimen>
+    <dimen name="all_apps_view_pageLayoutPaddingBottom">10dp</dimen>
+    <dimen name="all_apps_view_pageLayoutPaddingLeft">2dp</dimen>
+    <dimen name="all_apps_view_pageLayoutPaddingRight">2dp</dimen>
 </resources>
diff --git a/res/values-port/dimens.xml b/res/values-port/dimens.xml
index ad5922d..5bd566f 100644
--- a/res/values-port/dimens.xml
+++ b/res/values-port/dimens.xml
@@ -19,4 +19,13 @@
     <dimen name="workspace_cell_height">100dip</dimen>
     <dimen name="folder_cell_width">74dip</dimen>
     <dimen name="folder_cell_height">86dip</dimen>
+
+    <integer name="all_apps_view_cellCountX">4</integer>
+    <integer name="all_apps_view_cellCountY">5</integer>
+    <dimen name="all_apps_view_pageLayoutWidthGap">3dp</dimen>
+    <dimen name="all_apps_view_pageLayoutHeightGap">12dp</dimen>
+    <dimen name="all_apps_view_pageLayoutPaddingTop">15dp</dimen>
+    <dimen name="all_apps_view_pageLayoutPaddingBottom">15dp</dimen>
+    <dimen name="all_apps_view_pageLayoutPaddingLeft">0dp</dimen>
+    <dimen name="all_apps_view_pageLayoutPaddingRight">0dp</dimen>
 </resources>
diff --git a/res/values-xlarge/config.xml b/res/values-xlarge/config.xml
index b9880e3..99ee1ec 100644
--- a/res/values-xlarge/config.xml
+++ b/res/values-xlarge/config.xml
@@ -1,53 +1,21 @@
 <resources>
-    <!--  NOTE: Many of the all apps values here are also used for the customization drawer -->
-
-    <!-- Duration in milliseconds of the fade-in/out of the icons as they are being dragged
-         from the AllApps or Customization trays -->
-    <integer name="icon_allAppsCustomizeFadeInTime">150</integer>
-    <integer name="icon_allAppsCustomizeFadeOutTime">200</integer>
-    <integer name="icon_allAppsCustomizeFadeAlpha">102</integer>
-
-    <!-- Duration in milliseconds of the all apps / configuration zoom-in animation. -->
-    <!-- NB: This should be less than the workspaceShrinkTime as they happen together. -->
-    <integer name="config_allAppsZoomInTime">1000</integer>
-    <integer name="config_allAppsFadeInTime">250</integer>
-
-    <!-- Duration in milliseconds of the transition between tabs in the all apps/customize
-         tray -->
-    <integer name="config_tabTransitionTime">100</integer>
-
-    <!-- Duration in milliseconds of the all apps zoom-out animation -->
-    <!-- NB: This should be less than the workspaceUnshrinkTime as they happen together. -->
-    <integer name="config_allAppsZoomOutTime">1200</integer>
-
-    <!-- Scaling factor used in the all apps zooming animations -->
-    <integer name="config_allAppsZoomScaleFactor">20</integer>
-
-    <!-- Duration in milliseconds of the all apps / configuration zoom-in animation. -->
-    <!-- NB: This should be less than the workspaceShrinkTime as they happen together. -->
+<!-- AllApps/Customize/AppsCustomize -->
+    <!-- Fade/zoom in/out duration & scale in the Customize transition.
+         Note: This should be less than the workspaceShrinkTime as they happen together. -->
     <integer name="config_customizeZoomInTime">800</integer>
+    <integer name="config_customizeZoomOutTime">600</integer>
+    <integer name="config_customizeZoomScaleFactor">7</integer>
     <integer name="config_customizeFadeInTime">800</integer>
 
-    <!-- Duration in milliseconds of the all apps zoom-out animation -->
-    <!-- NB: This should be less than the workspaceUnshrinkTime as they happen together. -->
-    <integer name="config_customizeZoomOutTime">600</integer>
-
-    <!-- Scaling factor used in the all apps zooming animations -->
-    <integer name="config_customizeZoomScaleFactor">7</integer>
+    <!-- The slope, in percent, of the drag movement needed to drag an item out of
+         Customize (y / x * 100%)  -->
+    <integer name="config_customizationDrawerDragSlopeThreshold">150</integer>
 
     <!-- Duration in milliseconds of the animations between all apps, customize, & home.
          NOTE: If these are changed, the toolbar animation times below should also be. -->
-    <integer name="config_allAppsFadeOutTime">500</integer>
     <integer name="config_customizeWorkspaceShrinkTime">800</integer>
-    <integer name="config_allAppsWorkspaceShrinkTime">1000</integer>
-    <integer name="config_workspaceUnshrinkTime">650</integer>
 
-    <!-- Duration in milliseconds toolbar fade in and fade out animations.
-         NOTE: Fade in and fade out time should together be less the transition
-         animations between all apps, customize, & the workspace. -->
-    <integer name="config_toolbarButtonFadeInTime">350</integer>
-    <integer name="config_toolbarButtonFadeOutTime">200</integer>
-
+<!-- Workspace -->
     <!-- When dragging items on the workspace, how much bigger (in pixels) the dragged view
          should be, as compared to the original view. If 0, it will not be scaled at all.
          Should be an even number, for pixel alignment. -->
@@ -61,13 +29,4 @@
     <integer name="config_screenOnDropScaleDownDuration">200</integer>
     <integer name="config_screenOnDropAlphaFadeDelay">350</integer>
     <integer name="config_screenOnDropAlphaFadeDuration">50</integer>
-
-    <!-- The slope, in percent, of the drag movement needed to drag an item out of the customization
-         drawer (y / x * 100%)  -->
-    <integer name="config_customizationDrawerDragSlopeThreshold">150</integer>
-    <integer name="config_allAppsDrawerDragSlopeThreshold">150</integer>
-
-    <style name="config_orientation">
-        <item name="@android:screenOrientation">unspecified</item>
-    </style>
 </resources>
diff --git a/res/values-xlarge/dimens.xml b/res/values-xlarge/dimens.xml
index fffa0f2..11f85ab 100644
--- a/res/values-xlarge/dimens.xml
+++ b/res/values-xlarge/dimens.xml
@@ -15,6 +15,8 @@
 -->
 
 <resources>
+    <dimen name="apps_customize_cell_width">96dp</dimen>
+    <dimen name="apps_customize_cell_height">96dp</dimen>
     <dimen name="workspace_cell_width">96dip</dimen>
     <dimen name="workspace_cell_height">96dip</dimen>
 
@@ -40,7 +42,6 @@
     <dimen name="allAppsSmallScreenVerticalMarginLandscape">30dip</dimen>
     <dimen name="allAppsSmallScreenVerticalMarginPortrait">60dip</dimen>
 
-    <dimen name="delete_zone_drawable_padding">8dip</dimen>
     <dimen name="all_apps_button_drawable_padding">0dip</dimen>
     <dimen name="all_apps_button_vertical_padding">4dip</dimen>
 
diff --git a/res/values-xlarge/styles.xml b/res/values-xlarge/styles.xml
index 7208d97..96d9cc9 100644
--- a/res/values-xlarge/styles.xml
+++ b/res/values-xlarge/styles.xml
@@ -41,4 +41,15 @@
         <item name="android:paddingTop">0dip</item>
         <item name="android:includeFontPadding">false</item>
     </style>
+
+    <style name="TabIndicator.Wide">
+        <item name="android:paddingLeft">40dp</item>
+        <item name="android:paddingRight">40dp</item>
+        <item name="android:paddingTop">15dp</item>
+        <item name="android:paddingBottom">20dp</item>
+    </style>
+
+    <style name="config_orientation">
+        <item name="@android:screenOrientation">unspecified</item>
+    </style>
 </resources>
diff --git a/res/values/config.xml b/res/values/config.xml
index ec01fa8..5d3fb70 100644
--- a/res/values/config.xml
+++ b/res/values/config.xml
@@ -1,10 +1,41 @@
 <resources>
-    <integer name="config_allAppsFadeInTime">700</integer>
-    <integer name="config_allAppsFadeOutTime">700</integer>
-    <integer name="config_allAppsBatchLoadDelay">0</integer>
-    <integer name="config_allAppsBatchSize">0</integer>
+<!-- System -->
     <bool name="config_hardwareAccelerated">false</bool>
 
+<!-- AllApps/Customize/AppsCustomize -->
+    <!-- Fade in/out duration of icons being dragged from the trays -->
+    <integer name="config_dragAppsCustomizeIconFadeInDuration">150</integer>
+    <integer name="config_dragAppsCustomizeIconFadeOutDuration">200</integer>
+    <integer name="config_dragAppsCustomizeIconFadeAlpha">100</integer>
+    <integer name="config_workspaceUnshrinkTime">650</integer>
+
+    <!-- Fade/zoom in/out duration & scale in the AllApps transition.
+         Note: This should be less than the workspaceShrinkTime as they happen together. -->
+    <integer name="config_appsCustomizeZoomInTime">1000</integer>
+    <integer name="config_appsCustomizeZoomOutTime">1200</integer>
+    <integer name="config_appsCustomizeZoomScaleFactor">20</integer>
+    <integer name="config_appsCustomizeFadeInTime">250</integer>
+    <integer name="config_appsCustomizeFadeOutTime">500</integer>
+    <integer name="config_appsCustomizeWorkspaceShrinkTime">1000</integer>
+
+    <!-- Tab transition animation duration -->
+    <integer name="config_tabTransitionDuration">100</integer>
+
+    <!-- The slope, in percent, of the drag movement needed to drag an item out of
+         AppsCustomize (y / x * 100%)  -->
+    <integer name="config_appsCustomizeDragSlopeThreshold">150</integer>
+
+    <!-- Fade in/out duration of toolbar/button bar icons.
+         Note: In + Out duration together should be less the duration of the transition
+               between AllApps, Customize & the Workspace. -->
+    <integer name="config_toolbarButtonFadeInTime">350</integer>
+    <integer name="config_toolbarButtonFadeOutTime">200</integer>
+
+    <!-- Batch loading for loading in LauncherModel -->
+    <integer name="config_allAppsBatchLoadDelay">0</integer>
+    <integer name="config_allAppsBatchSize">0</integer>
+
+<!-- Workspace -->
     <integer name="config_crosshairsFadeInTime">600</integer>
 
     <!--  When dragging an item on the workspace, how much bigger (in pixels) the dragged view
@@ -32,8 +63,4 @@
          than the view itself (workspaceScreenBitmapCacheScale)  -->
     <integer name="config_workspaceScreenBitmapCacheScale">20</integer>
     <integer name="config_maxScaleForUsingWorkspaceScreenBitmapCache">50</integer>
-
-    <style name="config_orientation">
-        <item name="@android:screenOrientation">nosensor</item>
-    </style>
 </resources>
diff --git a/res/values/dimens.xml b/res/values/dimens.xml
index e346c6a..62e55d2 100644
--- a/res/values/dimens.xml
+++ b/res/values/dimens.xml
@@ -15,8 +15,16 @@
 -->
 
 <resources>
+<!-- AllApps/Customize/AppsCustomize -->
+    <!-- Size of icons in Workspace/AppsCustomize -->
+    <dimen name="app_icon_size">50dp</dimen>
+    <dimen name="apps_customize_cell_width">68dp</dimen>
+    <dimen name="apps_customize_cell_height">68dp</dimen>
     <dimen name="title_texture_width">120px</dimen>
 
+    <!-- height of the tab bar in AppsCustomize -->
+    <dimen name="apps_customize_tab_bar_height">56dp</dimen>
+
     <!-- height of the bottom row of controls -->
     <dimen name="button_bar_height">56dip</dimen>
 
@@ -24,6 +32,24 @@
          button_bar_height changes -->
     <dimen name="button_bar_height_portrait">56dip</dimen>
 
+    <!-- extra horizontal spacing between mini screen thumbnails ie. in all
+         apps and in customization mode -->
+    <dimen name="smallScreenExtraSpacing">0dip</dimen>
+
+    <!-- Vertical spacing between edge of screen and mini cell layouts when they
+         are minimized to the bottom in all apps -->
+    <dimen name="allAppsSmallScreenVerticalMarginLandscape">30dip</dimen>
+    <dimen name="allAppsSmallScreenVerticalMarginPortrait">60dip</dimen>
+
+    <!-- height & width of the drop rectangle for the trash icon -->
+    <dimen name="delete_zone_size">70dip</dimen>
+
+    <!-- delete_zone_size_full - button_bar_height_portrait -->
+    <dimen name="delete_zone_padding">14dip</dimen>
+
+    <!-- padding between the delete zone drawable and text -->
+    <dimen name="delete_zone_drawable_padding">8dip</dimen>
+
     <!-- roughly a status bar (for vertically centering the all apps
          home icon in landscape) -->
     <dimen name="status_bar_height">25dip</dimen>
@@ -32,15 +58,7 @@
          button cluster in landscape) -->
     <dimen name="half_status_bar_height">12dip</dimen>
 
-    <!-- Size of icons in workspace -->
-    <dimen name="app_icon_size">50dp</dimen>
-
-    <!-- height & width of the drop rectangle for the trash icon -->
-    <dimen name="delete_zone_size">70dip</dimen>
-    
-    <!-- delete_zone_size_full - button_bar_height_portrait -->
-    <dimen name="delete_zone_padding">14dip</dimen>
-
+<!-- Dragging -->
     <!-- the area at the edge of the screen that makes the workspace go left
          or right while you're dragging. -->
     <dimen name="scroll_zone">20dp</dimen>
diff --git a/res/values/styles.xml b/res/values/styles.xml
index 0c74a6a..ac7d4df 100644
--- a/res/values/styles.xml
+++ b/res/values/styles.xml
@@ -35,17 +35,17 @@
     </style>
     
     <style name="WorkspaceIcon">
-        <item name="android:textSize">13dip</item>
-        <item name="android:singleLine">true</item>
-        <item name="android:ellipsize">marquee</item>
-        <item name="android:shadowColor">#B0000000</item>
-        <item name="android:shadowRadius">2.0</item>
-        <item name="android:textColor">#FFF</item>
-        <item name="android:gravity">center_horizontal</item>
         <item name="android:layout_width">match_parent</item>
         <item name="android:layout_height">match_parent</item>
         <item name="android:paddingLeft">5dip</item>
         <item name="android:paddingRight">5dip</item>
+        <item name="android:gravity">center_horizontal</item>
+        <item name="android:singleLine">true</item>
+        <item name="android:ellipsize">marquee</item>
+        <item name="android:textSize">13dip</item>
+        <item name="android:textColor">#FFF</item>
+        <item name="android:shadowRadius">2.0</item>
+        <item name="android:shadowColor">#B0000000</item>
     </style>
 
     <style name="WorkspaceIcon.AllApps">
@@ -54,7 +54,7 @@
 
     <style name="WorkspaceIcon.Portrait">
         <item name="android:drawablePadding">5dip</item>
-        <item name="android:paddingTop">4dip</item>
+        <item name="android:paddingTop">0dip</item>
         <item name="android:layout_marginLeft">3dip</item>
         <item name="android:layout_marginRight">3dip</item>
         <item name="android:layout_marginTop">13dip</item>
@@ -72,12 +72,12 @@
         <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:paddingLeft">40dp</item>
-        <item name="android:paddingRight">40dp</item>
-        <item name="android:paddingTop">15dp</item>
-        <item name="android:paddingBottom">20dp</item>
-        <item name="android:textColor">@color/tab_widget_indicator_color</item>
+        <item name="android:paddingLeft">30dp</item>
+        <item name="android:paddingRight">30dp</item>
+        <item name="android:paddingTop">10dp</item>
+        <item name="android:paddingBottom">15dp</item>
         <item name="android:background">@drawable/tab_widget_indicator_selector</item>
+        <item name="android:textColor">@color/tab_widget_indicator_color</item>
         <item name="android:textSize">20sp</item>
         <item name="android:shadowColor">#393939</item>
         <item name="android:shadowDx">0.0</item>
@@ -85,11 +85,6 @@
         <item name="android:shadowRadius">1.0</item>
     </style>
 
-    <style name="TabIndicator.Portrait">
-        <item name="android:paddingLeft">20dp</item>
-        <item name="android:paddingRight">20dp</item>
-    </style>
-
     <style name="SearchButton" parent="@android:style/Widget.Button.Small">
         <item name="android:paddingTop">7dip</item>
         <item name="android:paddingBottom">9dip</item>
@@ -97,6 +92,29 @@
         <item name="android:paddingRight">10dip</item>
     </style>
 
+    <style name="MarketButton">
+        <item name="android:paddingRight">20dp</item>
+        <item name="android:text">@string/market</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>
+        <item name="android:shadowDx">0.0</item>
+        <item name="android:shadowDy">0.0</item>
+        <item name="android:shadowRadius">2.0</item>
+    </style>
+
+    <style name="DeleteZone">
+        <item name="android:drawableLeft">@drawable/delete_zone_selector</item>
+        <item name="android:drawablePadding">@dimen/delete_zone_drawable_padding</item>
+        <item name="android:paddingRight">20dp</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>
+        <item name="android:shadowDx">0.0</item>
+        <item name="android:shadowDy">0.0</item>
+        <item name="android:shadowRadius">2.0</item>
+    </style>
+
     <style name="HotseatButton">
         <item name="android:paddingLeft">12dip</item>
         <item name="android:paddingRight">12dip</item>
@@ -116,4 +134,7 @@
         <item name="android:background">@drawable/hotseat_bg_right</item>
     </style>
 
+    <style name="config_orientation">
+        <item name="@android:screenOrientation">nosensor</item>
+    </style>
 </resources>
diff --git a/src/com/android/launcher2/AccessibleTabView.java b/src/com/android/launcher2/AccessibleTabView.java
index a419911..101f139 100644
--- a/src/com/android/launcher2/AccessibleTabView.java
+++ b/src/com/android/launcher2/AccessibleTabView.java
@@ -21,6 +21,9 @@
 import android.view.KeyEvent;
 import android.widget.TextView;
 
+/**
+ * We use a custom tab view to process our own focus traversals.
+ */
 public class AccessibleTabView extends TextView {
     public AccessibleTabView(Context context) {
         super(context);
diff --git a/src/com/android/launcher2/AllApps2D.java b/src/com/android/launcher2/AllApps2D.java
index 854c1ee..44af7b7 100644
--- a/src/com/android/launcher2/AllApps2D.java
+++ b/src/com/android/launcher2/AllApps2D.java
@@ -158,8 +158,10 @@
         this(context, attrs);
     }
 
-    public void setLauncher(Launcher launcher) {
+    @Override
+    public void setup(Launcher launcher, DragController dragController) {
         mLauncher = launcher;
+        mDragController = dragController;
     }
 
     public boolean onKey(View v, int keyCode, KeyEvent event) {
@@ -202,11 +204,6 @@
     }
 
     @Override
-    public void setDragController(DragController dragger) {
-        mDragController = dragger;
-    }
-
-    @Override
     public void onDragViewVisible() {
     }
 
diff --git a/src/com/android/launcher2/AllApps3D.java b/src/com/android/launcher2/AllApps3D.java
index a8aea18..4990254 100644
--- a/src/com/android/launcher2/AllApps3D.java
+++ b/src/com/android/launcher2/AllApps3D.java
@@ -208,8 +208,10 @@
         setSoundEffectsEnabled(old);
     }
 
-    public void setLauncher(Launcher launcher) {
+    @Override
+    public void setup(Launcher launcher, DragController dragController) {
         mLauncher = launcher;
+        mDragController = dragController;
     }
 
     @Override
@@ -739,11 +741,6 @@
     }
 
     @Override
-    public void setDragController(DragController dragger) {
-        mDragController = dragger;
-    }
-
-    @Override
     public void onDragViewVisible() {
     }
 
diff --git a/src/com/android/launcher2/AllAppsPagedView.java b/src/com/android/launcher2/AllAppsPagedView.java
index 3d3c1ff..7af5392 100644
--- a/src/com/android/launcher2/AllAppsPagedView.java
+++ b/src/com/android/launcher2/AllAppsPagedView.java
@@ -90,7 +90,7 @@
 
         Resources r = context.getResources();
         setDragSlopeThreshold(
-                r.getInteger(R.integer.config_allAppsDrawerDragSlopeThreshold) / 100.0f);
+                r.getInteger(R.integer.config_appsCustomizeDragSlopeThreshold) / 100.0f);
 
         // Create a dummy page and set it up to find out the content width (used by our parent)
         PagedViewCellLayout layout = new PagedViewCellLayout(getContext());
@@ -121,14 +121,10 @@
     }
 
     @Override
-    public void setLauncher(Launcher launcher) {
+    public void setup(Launcher launcher, DragController dragController) {
         mLauncher = launcher;
         mLauncher.setAllAppsPagedView(this);
-    }
-
-    @Override
-    public void setDragController(DragController dragger) {
-        mDragController = dragger;
+        mDragController = dragController;
     }
 
     public void setAppFilter(int filterType) {
diff --git a/src/com/android/launcher2/AllAppsTabbed.java b/src/com/android/launcher2/AllAppsTabbed.java
index 2deec8e..96de5a7 100644
--- a/src/com/android/launcher2/AllAppsTabbed.java
+++ b/src/com/android/launcher2/AllAppsTabbed.java
@@ -103,7 +103,7 @@
             public void onTabChanged(String tabId) {
                 // animate the changing of the tab content by fading pages in and out
                 final Resources res = getResources();
-                final int duration = res.getInteger(R.integer.config_tabTransitionTime);
+                final int duration = res.getInteger(R.integer.config_tabTransitionDuration);
                 final float alpha = mAllApps.getAlpha();
                 ValueAnimator alphaAnim = ObjectAnimator.ofFloat(mAllApps, "alpha", alpha, 0.0f).
                         setDuration(duration);
@@ -143,14 +143,9 @@
     }
 
     @Override
-    public void setLauncher(Launcher launcher) {
-        mAllApps.setLauncher(launcher);
+    public void setup(Launcher launcher, DragController dragController) {
         mLauncher = launcher;
-    }
-
-    @Override
-    public void setDragController(DragController dragger) {
-        mAllApps.setDragController(dragger);
+        mAllApps.setup(launcher, dragController);
     }
 
     @Override
diff --git a/src/com/android/launcher2/AllAppsView.java b/src/com/android/launcher2/AllAppsView.java
index 3a74c71..e8ca61f 100644
--- a/src/com/android/launcher2/AllAppsView.java
+++ b/src/com/android/launcher2/AllAppsView.java
@@ -23,9 +23,7 @@
         public void zoomed(float zoom);
     }
 
-    public void setLauncher(Launcher launcher);
-
-    public void setDragController(DragController dragger);
+    public void setup(Launcher launcher, DragController dragController);
 
     public void zoom(float zoom, boolean animate);
 
diff --git a/src/com/android/launcher2/ApplicationInfoDropTarget.java b/src/com/android/launcher2/ApplicationInfoDropTarget.java
index 78a9d2d..ce359d4 100644
--- a/src/com/android/launcher2/ApplicationInfoDropTarget.java
+++ b/src/com/android/launcher2/ApplicationInfoDropTarget.java
@@ -162,10 +162,13 @@
         // Fade in the overlapping views
         if (mOverlappingViews != null) {
             for (View view : mOverlappingViews) {
-                ObjectAnimator oa = ObjectAnimator.ofFloat(view, "alpha", 1.0f);
-                oa.setDuration(sFadeInAnimationDuration);
-                mFadeAnimator.play(oa);
-                view.setVisibility(VISIBLE);
+                // Check whether the views are enabled first, before trying to fade them in
+                if (view.isEnabled()) {
+                    ObjectAnimator oa = ObjectAnimator.ofFloat(view, "alpha", 1.0f);
+                    oa.setDuration(sFadeInAnimationDuration);
+                    mFadeAnimator.play(oa);
+                    view.setVisibility(VISIBLE);
+                }
             }
         }
         mFadeAnimator.start();
diff --git a/src/com/android/launcher2/AppsCustomizePagedView.java b/src/com/android/launcher2/AppsCustomizePagedView.java
new file mode 100644
index 0000000..6dc34ca
--- /dev/null
+++ b/src/com/android/launcher2/AppsCustomizePagedView.java
@@ -0,0 +1,465 @@
+/*
+ * Copyright (C) 2011 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.launcher2;
+
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.List;
+
+import android.appwidget.AppWidgetManager;
+import android.appwidget.AppWidgetProviderInfo;
+import android.content.ComponentName;
+import android.content.Context;
+import android.content.Intent;
+import android.content.pm.PackageManager;
+import android.content.pm.ResolveInfo;
+import android.content.res.Resources;
+import android.content.res.TypedArray;
+import android.graphics.Bitmap;
+import android.graphics.Bitmap.Config;
+import android.graphics.Canvas;
+import android.graphics.Rect;
+import android.graphics.drawable.Drawable;
+import android.util.AttributeSet;
+import android.util.Log;
+import android.view.Gravity;
+import android.view.LayoutInflater;
+import android.view.View;
+import android.widget.Checkable;
+import android.widget.ImageView;
+import android.widget.TextView;
+
+import com.android.launcher.R;
+
+public class AppsCustomizePagedView extends PagedViewWithDraggableItems implements
+        AllAppsView, View.OnClickListener, DragSource {
+    static final String LOG_TAG = "AppsCustomizePagedView";
+
+    /**
+     * The different content types that this paged view can show.
+     */
+    public enum ContentType {
+        Applications,
+        Widgets
+    }
+
+    // Refs
+    private Launcher mLauncher;
+    private DragController mDragController;
+    private final LayoutInflater mLayoutInflater;
+    private final PackageManager mPackageManager;
+
+    // Content
+    private ContentType mContentType;
+    private ArrayList<ApplicationInfo> mApps;
+    private List<AppWidgetProviderInfo> mWidgets;
+    private List<ResolveInfo> mShortcuts;
+
+    // Dimens
+    private int mContentWidth;
+    private float mWidgetScale;
+    private PagedViewCellLayout mWidgetSpacingLayout;
+
+    public AppsCustomizePagedView(Context context, AttributeSet attrs) {
+        super(context, attrs);
+        mLayoutInflater = LayoutInflater.from(context);
+        mPackageManager = context.getPackageManager();
+        mContentType = ContentType.Applications;
+        mApps = new ArrayList<ApplicationInfo>();
+
+        TypedArray a = context.obtainStyledAttributes(attrs, R.styleable.PagedView, 0, 0);
+        mCellCountX = a.getInt(R.styleable.PagedView_cellCountX, 6);
+        mCellCountY = a.getInt(R.styleable.PagedView_cellCountY, 4);
+        a.recycle();
+
+        // Create a dummy page and set it up to find out the content width (used by our parent)
+        PagedViewCellLayout layout = new PagedViewCellLayout(context);
+        setupPage(layout);
+        mContentWidth = layout.getContentWidth();
+
+        // Create a dummy page that we can use to approximate the cell dimensions of widgets
+        mWidgetSpacingLayout = new PagedViewCellLayout(context);
+        mWidgetSpacingLayout.setCellCount(mCellCountX, mCellCountY);
+    }
+
+    @Override
+    protected void init() {
+        super.init();
+        mCenterPagesVertically = false;
+
+        Context context = getContext();
+        Resources r = context.getResources();
+        setDragSlopeThreshold(r.getInteger(R.integer.config_appsCustomizeDragSlopeThreshold)/100f);
+    }
+
+    public void onPackagesUpdated() {
+        // Get the list of widgets
+        mWidgets = AppWidgetManager.getInstance(mLauncher).getInstalledProviders();
+        Collections.sort(mWidgets, LauncherModel.WIDGET_NAME_COMPARATOR);
+
+        // Get the list of shortcuts
+        Intent shortcutsIntent = new Intent(Intent.ACTION_CREATE_SHORTCUT);
+        mShortcuts = mPackageManager.queryIntentActivities(shortcutsIntent, 0);
+        Collections.sort(mShortcuts, new LauncherModel.ShortcutNameComparator(mPackageManager));
+    }
+
+    @Override
+    public void onClick(View v) {
+        // Animate some feedback to the click
+        final ApplicationInfo appInfo = (ApplicationInfo) v.getTag();
+        animateClickFeedback(v, new Runnable() {
+            @Override
+            public void run() {
+                mLauncher.startActivitySafely(appInfo.intent, appInfo);
+            }
+        });
+    }
+
+    /*
+     * PagedViewWithDraggableItems implementation
+     */
+    @Override
+    protected void determineDraggingStart(android.view.MotionEvent ev) {
+        // Disable dragging by pulling an app down for now.
+    }
+    @Override
+    protected boolean beginDragging(View v) {
+        if (!super.beginDragging(v)) return false;
+
+        // Make a copy of the ApplicationInfo
+        ApplicationInfo appInfo = new ApplicationInfo((ApplicationInfo) v.getTag());
+
+        // Show the uninstall button if the app is uninstallable.
+        if ((appInfo.flags & ApplicationInfo.DOWNLOADED_FLAG) != 0) {
+            DeleteZone allAppsDeleteZone = (DeleteZone)
+                    mLauncher.findViewById(R.id.all_apps_delete_zone);
+            allAppsDeleteZone.setDragAndDropEnabled(true);
+
+            if ((appInfo.flags & ApplicationInfo.UPDATED_SYSTEM_APP_FLAG) != 0) {
+                allAppsDeleteZone.setText(R.string.delete_zone_label_all_apps_system_app);
+            } else {
+                allAppsDeleteZone.setText(R.string.delete_zone_label_all_apps);
+            }
+        }
+
+        // Show the info button
+        ApplicationInfoDropTarget allAppsInfoButton =
+            (ApplicationInfoDropTarget) mLauncher.findViewById(R.id.all_apps_info_target);
+        allAppsInfoButton.setDragAndDropEnabled(true);
+
+        // Compose the drag image (top compound drawable, index is 1)
+        final TextView tv = (TextView) v;
+        final Drawable icon = tv.getCompoundDrawables()[1];
+        Bitmap b = Bitmap.createBitmap(v.getWidth(), v.getHeight(),
+                Bitmap.Config.ARGB_8888);
+        Canvas c = new Canvas(b);
+        c.translate((v.getWidth() - icon.getIntrinsicWidth()) / 2, v.getPaddingTop());
+        icon.draw(c);
+
+        // Compose the visible rect of the drag image
+        Rect dragRect = null;
+        if (v instanceof TextView) {
+            int iconSize = getResources().getDimensionPixelSize(R.dimen.app_icon_size);
+            int top = v.getPaddingTop();
+            int left = (b.getWidth() - iconSize) / 2;
+            int right = left + iconSize;
+            int bottom = top + iconSize;
+            dragRect = new Rect(left, top, right, bottom);
+        }
+
+        // Start the drag
+        mLauncher.lockScreenOrientation();
+        mLauncher.getWorkspace().onDragStartedWithItemSpans(1, 1, b);
+        mDragController.startDrag(v, b, this, appInfo, DragController.DRAG_ACTION_COPY, dragRect);
+        b.recycle();
+
+        // Hide the pane so that the user can drop onto the workspace
+        mLauncher.showWorkspace(true);
+        return true;
+    }
+    private void endDragging(boolean success) {
+        post(new Runnable() {
+            // Once the drag operation has fully completed, hence the post, we want to disable the
+            // deleteZone and the appInfoButton in all apps, and re-enable the instance which
+            // live in the workspace
+            public void run() {
+                // if onDestroy was called on Launcher, we might have already deleted the
+                // all apps delete zone / info button, so check if they are null
+                DeleteZone allAppsDeleteZone =
+                        (DeleteZone) mLauncher.findViewById(R.id.all_apps_delete_zone);
+                ApplicationInfoDropTarget allAppsInfoButton =
+                    (ApplicationInfoDropTarget) mLauncher.findViewById(R.id.all_apps_info_target);
+
+                if (allAppsDeleteZone != null) allAppsDeleteZone.setDragAndDropEnabled(false);
+                if (allAppsInfoButton != null) allAppsInfoButton.setDragAndDropEnabled(false);
+            }
+        });
+        mLauncher.getWorkspace().onDragStopped(success);
+        mLauncher.unlockScreenOrientation();
+    }
+
+    /*
+     * DragSource implementation
+     */
+    @Override
+    public void onDragViewVisible() {}
+    @Override
+    public void onDropCompleted(View target, Object dragInfo, boolean success) {
+        endDragging(success);
+    }
+
+    public void setContentType(ContentType type) {
+        mContentType = type;
+        setCurrentPage(0);
+        invalidatePageData();
+    }
+
+    /*
+     * Apps PagedView implementation
+     */
+    private void setupPage(PagedViewCellLayout layout) {
+        layout.setCellCount(mCellCountX, mCellCountY);
+        layout.setGap(mPageLayoutWidthGap, mPageLayoutHeightGap);
+        layout.setPadding(mPageLayoutPaddingLeft, mPageLayoutPaddingTop,
+                mPageLayoutPaddingRight, mPageLayoutPaddingBottom);
+
+        // We force a measure here to get around the fact that when we do layout calculations
+        // immediately after syncing, we don't have a proper width.
+        int widthSpec = MeasureSpec.makeMeasureSpec(getMeasuredWidth(), MeasureSpec.AT_MOST);
+        int heightSpec = MeasureSpec.makeMeasureSpec(getMeasuredHeight(), MeasureSpec.AT_MOST);
+        layout.measure(widthSpec, heightSpec);
+    }
+    public void syncAppsPages() {
+        // Ensure that we have the right number of pages
+        Context context = getContext();
+        int numPages = (int) Math.ceil((float) mApps.size() / (mCellCountX * mCellCountY));
+        for (int i = 0; i < numPages; ++i) {
+            PagedViewCellLayout layout = new PagedViewCellLayout(context);
+            setupPage(layout);
+            addView(layout);
+        }
+    }
+    public void syncAppsPageItems(int page) {
+        // ensure that we have the right number of items on the pages
+        int numPages = getPageCount();
+        int numCells = mCellCountX * mCellCountY;
+        int startIndex = page * numCells;
+        int endIndex = Math.min(startIndex + numCells, mApps.size());
+        PagedViewCellLayout layout = (PagedViewCellLayout) getChildAt(page);
+        layout.removeAllViewsOnPage();
+        for (int i = startIndex; i < endIndex; ++i) {
+            ApplicationInfo info = mApps.get(i);
+            PagedViewIcon icon = (PagedViewIcon) mLayoutInflater.inflate(
+                    R.layout.apps_customize_application, layout, false);
+            icon.applyFromApplicationInfo(info, mPageViewIconCache, true, (numPages > 1));
+            icon.setOnClickListener(this);
+            icon.setOnLongClickListener(this);
+            icon.setOnTouchListener(this);
+
+            int index = i - startIndex;
+            int x = index % mCellCountX;
+            int y = index / mCellCountX;
+            setupPage(layout);
+            layout.addViewToCellLayout(icon, -1, i, new PagedViewCellLayout.LayoutParams(x,y, 1,1));
+        }
+    }
+    /*
+     * Widgets PagedView implementation
+     */
+    private void setupPage(PagedViewExtendedLayout layout) {
+        layout.setGravity(Gravity.LEFT);
+        layout.setPadding(mPageLayoutPaddingLeft, mPageLayoutPaddingTop,
+                mPageLayoutPaddingRight, mPageLayoutPaddingBottom);
+        layout.setMinimumWidth(getPageContentWidth());
+    }
+    private void renderDrawableToBitmap(Drawable d, Bitmap bitmap, int x, int y, int w, int h,
+            float scaleX, float scaleY) {
+        Canvas c = new Canvas();
+        if (bitmap != null) c.setBitmap(bitmap);
+        c.save();
+        c.scale(scaleX, scaleY);
+        Rect oldBounds = d.copyBounds();
+        d.setBounds(x, y, x + w, y + h);
+        d.draw(c);
+        d.setBounds(oldBounds); // Restore the bounds
+        c.restore();
+    }
+    private FastBitmapDrawable getWidgetPreview(AppWidgetProviderInfo info) {
+        // See CustomizePagedView.getWidgetPreview()
+        return null;
+    }
+    public void syncWidgetPages() {
+        // Ensure that we have the right number of pages
+        Context context = getContext();
+        int numPages = mWidgets.size();
+        for (int i = 0; i < numPages; ++i) {
+            PagedViewExtendedLayout layout = new PagedViewExtendedLayout(context);
+            setupPage(layout);
+            addView(layout);
+        }
+    }
+    public void syncWidgetPageItems(int page) {
+        PagedViewExtendedLayout layout = (PagedViewExtendedLayout) getChildAt(page);
+        layout.removeAllViewsOnPage();
+        for (int i = 0; i < 1; ++i) {
+            AppWidgetProviderInfo info = (AppWidgetProviderInfo) mWidgets.get(page);
+            FastBitmapDrawable icon = getWidgetPreview(info);
+
+            ImageView image = new ImageView(getContext());
+            image.setBackgroundColor(0x99FF0000);
+            image.setImageDrawable(icon);
+            layout.addView(image, new PagedViewExtendedLayout.LayoutParams());
+        }
+    }
+    @Override
+    public void syncPages() {
+        removeAllViews();
+        switch (mContentType) {
+        case Applications:
+            syncAppsPages();
+            break;
+        case Widgets:
+            syncWidgetPages();
+            break;
+        }
+    }
+    @Override
+    public void syncPageItems(int page) {
+        switch (mContentType) {
+        case Applications:
+            syncAppsPageItems(page);
+            break;
+        case Widgets:
+            syncWidgetPageItems(page);
+            break;
+        }
+    }
+
+    /**
+     * Used by the parent to get the content width to set the tab bar to
+     * @return
+     */
+    public int getPageContentWidth() {
+        return mContentWidth;
+    }
+
+    /*
+     * AllAppsView implementation
+     */
+    @Override
+    public void setup(Launcher launcher, DragController dragController) {
+        mLauncher = launcher;
+        mDragController = dragController;
+    }
+    @Override
+    public void zoom(float zoom, boolean animate) {
+        // TODO-APPS_CUSTOMIZE: Call back to mLauncher.zoomed()
+    }
+    @Override
+    public boolean isVisible() {
+        return (getVisibility() == VISIBLE);
+    }
+    @Override
+    public boolean isAnimating() {
+        return false;
+    }
+    @Override
+    public void setApps(ArrayList<ApplicationInfo> list) {
+        mApps = list;
+        Collections.sort(mApps, LauncherModel.APP_NAME_COMPARATOR);
+        invalidatePageData();
+    }
+    private void addAppsWithoutInvalidate(ArrayList<ApplicationInfo> list) {
+        // We add it in place, in alphabetical order
+        int count = list.size();
+        for (int i = 0; i < count; ++i) {
+            ApplicationInfo info = list.get(i);
+            int index = Collections.binarySearch(mApps, info, LauncherModel.APP_NAME_COMPARATOR);
+            if (index < 0) {
+                mApps.add(-(index + 1), info);
+            }
+        }
+    }
+    @Override
+    public void addApps(ArrayList<ApplicationInfo> list) {
+        addAppsWithoutInvalidate(list);
+        invalidatePageData();
+    }
+    private int findAppByComponent(List<ApplicationInfo> list, ApplicationInfo item) {
+        ComponentName removeComponent = item.intent.getComponent();
+        int length = list.size();
+        for (int i = 0; i < length; ++i) {
+            ApplicationInfo info = list.get(i);
+            if (info.intent.getComponent().equals(removeComponent)) {
+                return i;
+            }
+        }
+        return -1;
+    }
+    private void removeAppsWithoutInvalidate(ArrayList<ApplicationInfo> list) {
+        // loop through all the apps and remove apps that have the same component
+        int length = list.size();
+        for (int i = 0; i < length; ++i) {
+            ApplicationInfo info = list.get(i);
+            int removeIndex = findAppByComponent(mApps, info);
+            if (removeIndex > -1) {
+                mApps.remove(removeIndex);
+                mPageViewIconCache.removeOutline(new PagedViewIconCache.Key(info));
+            }
+        }
+    }
+    @Override
+    public void removeApps(ArrayList<ApplicationInfo> list) {
+        removeAppsWithoutInvalidate(list);
+        invalidatePageData();
+    }
+    @Override
+    public void updateApps(ArrayList<ApplicationInfo> list) {
+        // 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.
+        removeAppsWithoutInvalidate(list);
+        addAppsWithoutInvalidate(list);
+        invalidatePageData();
+    }
+    @Override
+    public void reset() {
+        setCurrentPage(0);
+        invalidatePageData();
+    }
+    @Override
+    public void dumpState() {
+        // TODO: Dump information related to current list of Applications, Widgets, etc.
+        ApplicationInfo.dumpApplicationInfoList(LOG_TAG, "mApps", mApps);
+        dumpAppWidgetProviderInfoList(LOG_TAG, "mWidgets", mWidgets);
+    }
+    private void dumpAppWidgetProviderInfoList(String tag, String label,
+            List<AppWidgetProviderInfo> list) {
+        Log.d(tag, label + " size=" + list.size());
+        for (AppWidgetProviderInfo info: list) {
+            Log.d(tag, "   label=\"" + info.label + "\" previewImage=" + info.previewImage
+                    + " resizeMode=" + info.resizeMode + " configure=" + info.configure
+                    + " initialLayout=" + info.initialLayout
+                    + " minWidth=" + info.minWidth + " minHeight=" + info.minHeight);
+        }
+    }
+    @Override
+    public void surrender() {
+        // TODO: If we are in the middle of any process (ie. for holographic outlines, etc) we
+        // should stop this now.
+    }
+}
diff --git a/src/com/android/launcher2/AppsCustomizeTabHost.java b/src/com/android/launcher2/AppsCustomizeTabHost.java
new file mode 100644
index 0000000..b484ad2
--- /dev/null
+++ b/src/com/android/launcher2/AppsCustomizeTabHost.java
@@ -0,0 +1,121 @@
+/*
+ * Copyright (C) 2011 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.launcher2;
+
+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.TabHost;
+import android.widget.TabWidget;
+import android.widget.TextView;
+
+import com.android.launcher.R;
+
+public class AppsCustomizeTabHost extends TabHost implements LauncherTransitionable,
+        TabHost.OnTabChangeListener  {
+    static final String LOG_TAG = "AppsCustomizeTabHost";
+
+    private static final String APPS_TAB_TAG = "APPS";
+    private static final String WIDGETS_TAB_TAG = "WIDGETS";
+
+    private final LayoutInflater mLayoutInflater;
+
+    public AppsCustomizeTabHost(Context context, AttributeSet attrs) {
+        super(context, attrs);
+        mLayoutInflater = LayoutInflater.from(context);
+    }
+
+    /**
+     * Setup the tab host and create all necessary tabs.
+     */
+    @Override
+    protected void onFinishInflate() {
+        // Setup the tab host
+        setup();
+
+        final ViewGroup tabs = (ViewGroup) findViewById(com.android.internal.R.id.tabs);
+        final AppsCustomizePagedView content = (AppsCustomizePagedView)
+                findViewById(R.id.apps_customize_pane_content);
+        if (tabs == null || content == null) throw new Resources.NotFoundException();
+
+        // Configure the tabs content factory to return the same paged view (that we change the
+        // content filter on)
+        TabContentFactory contentFactory = new TabContentFactory() {
+            public View createTabContent(String tag) {
+                return content;
+            }
+        };
+
+        // Create the tabs
+        TextView tabView;
+        tabView = (TextView) mLayoutInflater.inflate(R.layout.tab_widget_indicator, tabs, false);
+        tabView.setText(mContext.getString(R.string.all_apps_button_label));
+        addTab(newTabSpec(APPS_TAB_TAG).setIndicator(tabView).setContent(contentFactory));
+        /** TODO-APPS_CUSTOMIZE: Re-enable widgets tab
+        tabView = (TextView) mLayoutInflater.inflate(R.layout.tab_widget_indicator, tabs, false);
+        tabView.setText(mContext.getString(R.string.widgets_tab_label));
+        addTab(newTabSpec(WIDGETS_TAB_TAG).setIndicator(tabView).setContent(contentFactory));
+        */
+        setOnTabChangedListener(this);
+
+        // Set the width of the tab bar to match the content (for now)
+        tabs.getLayoutParams().width = content.getPageContentWidth();
+    }
+
+    @Override
+    public void onTabChanged(String tabId) {
+        final AppsCustomizePagedView content = (AppsCustomizePagedView)
+                findViewById(R.id.apps_customize_pane_content);
+        content.setContentType(getContentTypeForTabTag(tabId));
+    }
+
+    /**
+     * Returns the content type for the specified tab tag.
+     */
+    public AppsCustomizePagedView.ContentType getContentTypeForTabTag(String tag) {
+        if (tag.equals(APPS_TAB_TAG)) {
+            return AppsCustomizePagedView.ContentType.Applications;
+        } else if (tag.equals(WIDGETS_TAB_TAG)) {
+            return AppsCustomizePagedView.ContentType.Widgets;
+        }
+        return AppsCustomizePagedView.ContentType.Applications;
+    }
+
+    /**
+     * Disable focus on anything under this view in the hierarchy if we are not visible.
+     */
+    @Override
+    public int getDescendantFocusability() {
+        if (getVisibility() != View.VISIBLE) {
+            return ViewGroup.FOCUS_BLOCK_DESCENDANTS;
+        }
+        return super.getDescendantFocusability();
+    }
+
+    /* LauncherTransitionable overrides */
+    @Override
+    public void onLauncherTransitionStart(android.animation.Animator animation) {
+        // TODO-APPS_CUSTOMIZE: see AllAppsTabbed.onLauncherTransitionStart();
+    }
+    @Override
+    public void onLauncherTransitionEnd(android.animation.Animator animation) {
+        // TODO-APPS_CUSTOMIZE: see AllAppsTabbed.onLauncherTransitionEnd();
+    }
+}
diff --git a/src/com/android/launcher2/CustomizeTrayTabHost.java b/src/com/android/launcher2/CustomizeTrayTabHost.java
index 5c683c4..2c47895 100644
--- a/src/com/android/launcher2/CustomizeTrayTabHost.java
+++ b/src/com/android/launcher2/CustomizeTrayTabHost.java
@@ -94,7 +94,7 @@
                 if (newType != customizePagedView.getCustomizationFilter()) {
                     // animate the changing of the tab content by fading pages in and out
                     final Resources res = getResources();
-                    final int duration = res.getInteger(R.integer.config_tabTransitionTime);
+                    final int duration = res.getInteger(R.integer.config_tabTransitionDuration);
                     final float alpha = customizePagedView.getAlpha();
                     ValueAnimator alphaAnim = ObjectAnimator.ofFloat(customizePagedView,
                             "alpha", alpha, 0.0f);
diff --git a/src/com/android/launcher2/DragSource.java b/src/com/android/launcher2/DragSource.java
index 4dbdaf7..649120d 100644
--- a/src/com/android/launcher2/DragSource.java
+++ b/src/com/android/launcher2/DragSource.java
@@ -23,8 +23,6 @@
  *
  */
 public interface DragSource {
-    void setDragController(DragController dragger);
-
     /**
      * Callback from the DragController when it begins drawing the drag view.
      * This allows the DragSource to dim or hide the original view.
diff --git a/src/com/android/launcher2/Folder.java b/src/com/android/launcher2/Folder.java
index e00023f..7eb3bb1 100644
--- a/src/com/android/launcher2/Folder.java
+++ b/src/com/android/launcher2/Folder.java
@@ -101,7 +101,6 @@
         return true;
     }
 
-    @Override
     public void setDragController(DragController dragController) {
         mDragController = dragController;
     }
diff --git a/src/com/android/launcher2/Launcher.java b/src/com/android/launcher2/Launcher.java
index 60cab8e..b2ec67c 100644
--- a/src/com/android/launcher2/Launcher.java
+++ b/src/com/android/launcher2/Launcher.java
@@ -169,7 +169,7 @@
     private static final String TOOLBAR_ICON_METADATA_NAME = "com.android.launcher.toolbar_icon";
 
     /** The different states that Launcher can be in. */
-    private enum State { WORKSPACE, ALL_APPS, CUSTOMIZE,
+    private enum State { WORKSPACE, APPS_CUSTOMIZE, ALL_APPS, CUSTOMIZE,
         CUSTOMIZE_SPRING_LOADED, ALL_APPS_SPRING_LOADED };
     private State mState = State.WORKSPACE;
     private AnimatorSet mStateAnimation;
@@ -202,6 +202,8 @@
     private DeleteZone mDeleteZone;
     private HandleView mHandleView;
     private AllAppsView mAllAppsGrid;
+    private AppsCustomizeTabHost mAppsCustomizeTabHost;
+    private AppsCustomizePagedView mAppsCustomizeContent;
     private CustomizeTrayTabHost mHomeCustomizationDrawer;
     private boolean mAutoAdvanceRunning = false;
 
@@ -328,6 +330,9 @@
         if (mCustomizePagedView != null) {
             mCustomizePagedView.update();
         }
+        if (mAppsCustomizeContent != null) {
+            mAppsCustomizeContent.onPackagesUpdated();
+        }
 
         if (PROFILE_STARTUP) {
             android.os.Debug.stopMethodTracing();
@@ -361,21 +366,6 @@
         }
     }
 
-    @Override
-    public boolean dispatchPopulateAccessibilityEvent(AccessibilityEvent event) {
-        super.dispatchPopulateAccessibilityEvent(event);
-
-        // we want to take over text population so it is context dependent
-        event.getText().clear();
-        if (mState == State.ALL_APPS) {
-            event.getText().add(getString(R.string.all_apps_button_label));
-        } else if (mState == State.WORKSPACE) {
-            event.getText().add(getString(R.string.all_apps_home_button_label));
-        }
-
-        return true;
-    }
-
     private void checkForLocaleChange() {
         if (sLocaleConfiguration == null) {
             new AsyncTask<Void, Void, LocaleConfiguration>() {
@@ -736,7 +726,12 @@
     public Object onRetainNonConfigurationInstance() {
         // Flag the loader to stop early before switching
         mModel.stopLoader();
-        mAllAppsGrid.surrender();
+        if (mAllAppsGrid != null) {
+            mAllAppsGrid.surrender();
+        }
+        if (mAppsCustomizeContent != null) {
+            mAppsCustomizeContent.surrender();
+        }
         return Boolean.TRUE;
     }
 
@@ -832,7 +827,7 @@
 
         State state = intToState(savedState.getInt(RUNTIME_STATE, State.WORKSPACE.ordinal()));
 
-        if (state == State.ALL_APPS) {
+        if (state == State.ALL_APPS || state == State.APPS_CUSTOMIZE) {
             showAllApps(false);
         } else if (state == State.CUSTOMIZE) {
             showCustomizationDrawer(false);
@@ -885,6 +880,20 @@
             // Note: currently we do not restore the page for the customization tray because unlike
             // AllApps, the page content can change drastically
         }
+
+        // Restore the AppsCustomize tab
+        if (mAppsCustomizeTabHost != null) {
+            String curTab = savedState.getString("apps_customize_currentTab");
+            if (curTab != null) {
+             // We set this directly so that there is no delay before the tab is set
+                mAppsCustomizeContent.setContentType(
+                        mAppsCustomizeTabHost.getContentTypeForTabTag(curTab));
+                mAppsCustomizeTabHost.setCurrentTabByTag(curTab);
+            }
+
+            // Note: currently we do not restore the page for the AppsCustomize pane because the
+            // change in layout can drastically affect the saved page index
+        }
     }
 
     /**
@@ -896,18 +905,17 @@
         DragLayer dragLayer = (DragLayer) findViewById(R.id.drag_layer);
         dragLayer.setDragController(dragController);
 
-        mAllAppsGrid = (AllAppsView)dragLayer.findViewById(R.id.all_apps_view);
-        mAllAppsGrid.setLauncher(this);
-        mAllAppsGrid.setDragController(dragController);
-        ((View) mAllAppsGrid).setWillNotDraw(false); // We don't want a hole punched in our window.
-        // Manage focusability manually since this thing is always visible (in non-xlarge)
-        ((View) mAllAppsGrid).setFocusable(false);
-
         if (LauncherApplication.isScreenXLarge()) {
-            // They need to be INVISIBLE initially so that they will be measured in the layout.
-            // Otherwise the animations are messed up when we show them for the first time.
-            ((View) mAllAppsGrid).setVisibility(View.INVISIBLE);
-            mHomeCustomizationDrawer.setVisibility(View.INVISIBLE);
+            mAllAppsGrid = (AllAppsView)dragLayer.findViewById(R.id.all_apps_view);
+            mAllAppsGrid.setup(this, dragController);
+            // We don't want a hole punched in our window.
+            ((View) mAllAppsGrid).setWillNotDraw(false);
+        } else {
+            mAppsCustomizeTabHost = (AppsCustomizeTabHost)
+                    findViewById(R.id.apps_customize_pane);
+            mAppsCustomizeContent = (AppsCustomizePagedView)
+                    mAppsCustomizeTabHost.findViewById(R.id.apps_customize_pane_content);
+            mAppsCustomizeContent.setup(this, dragController);
         }
 
         mWorkspace = (Workspace) dragLayer.findViewById(R.id.workspace);
@@ -923,7 +931,6 @@
             // we don't use handle view in xlarge mode
             mHandleView = (HandleView)handleView;
             mHandleView.setLauncher(this);
-            mHandleView.setOnClickListener(this);
             mHandleView.setOnLongClickListener(this);
         }
 
@@ -985,15 +992,17 @@
             allAppsInfoTarget.setLauncher(this);
             dragController.addDragListener(allAppsInfoTarget);
             allAppsInfoTarget.setDragAndDropEnabled(false);
-            View marketButton = findViewById(R.id.market_button);
-            if (marketButton != null) {
+        }
+        View marketButton = findViewById(R.id.market_button);
+        if (marketButton != null) {
+            if (allAppsInfoTarget != null) {
                 allAppsInfoTarget.setOverlappingView(marketButton);
-                marketButton.setOnClickListener(new OnClickListener() {
-                    public void onClick(View v) {
-                        onClickAppMarketButton(v);
-                    }
-                });
             }
+            marketButton.setOnClickListener(new OnClickListener() {
+                public void onClick(View v) {
+                    onClickAppMarketButton(v);
+                }
+            });
         }
 
         dragController.setDragScoller(workspace);
@@ -1048,14 +1057,14 @@
 
     @SuppressWarnings({"UnusedDeclaration"})
     public void previousScreen(View v) {
-        if (mState != State.ALL_APPS) {
+        if (mState != State.ALL_APPS && mState != State.APPS_CUSTOMIZE) {
             mWorkspace.scrollLeft();
         }
     }
 
     @SuppressWarnings({"UnusedDeclaration"})
     public void nextScreen(View v) {
-        if (mState != State.ALL_APPS) {
+        if (mState != State.ALL_APPS && mState != State.APPS_CUSTOMIZE) {
             mWorkspace.scrollRight();
         }
     }
@@ -1263,6 +1272,9 @@
                 if (mAllAppsGrid != null) {
                     mAllAppsGrid.reset();
                 }
+                if (mAppsCustomizeContent != null) {
+                    mAppsCustomizeContent.reset();
+                }
             } else if (Intent.ACTION_USER_PRESENT.equals(action)) {
                 mUserPresent = true;
                 updateRunning();
@@ -1417,11 +1429,7 @@
                         != Intent.FLAG_ACTIVITY_BROUGHT_TO_FRONT);
 
             // In all these cases, only animate if we're already on home
-
-            if (LauncherApplication.isScreenXLarge()) {
-                mWorkspace.unshrink(alreadyOnHome);
-            }
-
+            mWorkspace.unshrink(alreadyOnHome);
             mWorkspace.exitWidgetResizeMode();
             if (alreadyOnHome && mState == State.WORKSPACE && !mWorkspace.isTouchActive()) {
                 mWorkspace.moveToDefaultScreen(true);
@@ -1439,6 +1447,9 @@
             if (mAllAppsGrid != null) {
                 mAllAppsGrid.reset();
             }
+            if (mAppsCustomizeContent != null) {
+                mAppsCustomizeContent.reset();
+            }
         }
     }
 
@@ -1487,7 +1498,6 @@
                 outState.putInt("allapps_currentPage", mAllAppsPagedView.getCurrentPage());
             }
         }
-
         // Save the current customization drawer tab
         if (mHomeCustomizationDrawer != null) {
             String currentTabTag = mHomeCustomizationDrawer.getCurrentTabTag();
@@ -1495,6 +1505,13 @@
                 outState.putString("customize_currentTab", currentTabTag);
             }
         }
+        // Save the current AppsCustomize tab
+        if (mAppsCustomizeTabHost != null) {
+            String currentTabTag = mAppsCustomizeTabHost.getCurrentTabTag();
+            if (currentTabTag != null) {
+                outState.putString("apps_customize_currentTab", currentTabTag);
+            }
+        }
     }
 
     @Override
@@ -1603,22 +1620,28 @@
     public boolean onPrepareOptionsMenu(Menu menu) {
         super.onPrepareOptionsMenu(menu);
 
-        // If all apps is animating, don't show the menu, because we don't know
-        // which one to show.
-        if (mAllAppsGrid.isAnimating()) {
-            return false;
+        if (mAllAppsGrid != null) {
+            // If all apps is animating, don't show the menu, because we don't know
+            // which one to show.
+            if (mAllAppsGrid.isAnimating()) {
+                return false;
+            }
+
+            // Only show the add and wallpaper options when we're not in all apps.
+            boolean visible = !mAllAppsGrid.isVisible();
+            menu.setGroupVisible(MENU_GROUP_ADD, visible);
+            menu.setGroupVisible(MENU_GROUP_WALLPAPER, visible);
+
+            // Disable add if the workspace is full.
+            if (visible) {
+                CellLayout layout = (CellLayout) mWorkspace.getChildAt(mWorkspace.getCurrentPage());
+                menu.setGroupEnabled(MENU_GROUP_ADD, layout.existsEmptyCell());
+            }
         }
 
-        // Only show the add and wallpaper options when we're not in all apps.
-        boolean visible = !mAllAppsGrid.isVisible();
-        menu.setGroupVisible(MENU_GROUP_ADD, visible);
-        menu.setGroupVisible(MENU_GROUP_WALLPAPER, visible);
-
-        // Disable add if the workspace is full.
-        if (visible) {
-            CellLayout layout = (CellLayout) mWorkspace.getChildAt(mWorkspace.getCurrentPage());
-            menu.setGroupEnabled(MENU_GROUP_ADD, layout.existsEmptyCell());
-        }
+        // TODO-APPS_CUSTOMIZE: Remove this for the phone UI at some point, along with all the menu
+        // related code?
+        if (mAppsCustomizeContent != null && mAppsCustomizeContent.isAnimating()) return false;
 
         return true;
     }
@@ -1959,7 +1982,7 @@
 
     @Override
     public void onBackPressed() {
-        if (mState == State.ALL_APPS || mState == State.CUSTOMIZE) {
+        if (mState == State.ALL_APPS || mState == State.CUSTOMIZE || mState == State.APPS_CUSTOMIZE) {
             showWorkspace(true);
         } else if (mWorkspace.getOpenFolder() != null) {
             closeFolder();
@@ -2218,21 +2241,21 @@
 
         switch (v.getId()) {
             case R.id.previous_screen:
-                if (mState != State.ALL_APPS) {
+                if (mState != State.ALL_APPS && mState != State.APPS_CUSTOMIZE) {
                     mWorkspace.performHapticFeedback(HapticFeedbackConstants.LONG_PRESS,
                             HapticFeedbackConstants.FLAG_IGNORE_VIEW_SETTING);
                     showPreviews(v);
                 }
                 return true;
             case R.id.next_screen:
-                if (mState != State.ALL_APPS) {
+                if (mState != State.ALL_APPS && mState != State.APPS_CUSTOMIZE) {
                     mWorkspace.performHapticFeedback(HapticFeedbackConstants.LONG_PRESS,
                             HapticFeedbackConstants.FLAG_IGNORE_VIEW_SETTING);
                     showPreviews(v);
                 }
                 return true;
             case R.id.all_apps_button:
-                if (mState != State.ALL_APPS) {
+                if (mState != State.ALL_APPS && mState != State.APPS_CUSTOMIZE) {
                     mWorkspace.performHapticFeedback(HapticFeedbackConstants.LONG_PRESS,
                             HapticFeedbackConstants.FLAG_IGNORE_VIEW_SETTING);
                     showPreviews(v);
@@ -2569,7 +2592,7 @@
 
     // Now a part of LauncherModel.Callbacks. Used to reorder loading steps.
     public boolean isAllAppsVisible() {
-        return mState == State.ALL_APPS;
+        return (mState == State.ALL_APPS) || (mState == State.APPS_CUSTOMIZE);
     }
 
     // AllAppsView.Watcher
@@ -2582,17 +2605,12 @@
     
     private void showAndEnableToolbarButton(View button) {
         button.setVisibility(View.VISIBLE);
-        button.setClickable(true);
     }
 
     private void hideToolbarButton(View button) {
-        button.setAlpha(0.0f);
         // We can't set it to GONE, otherwise the RelativeLayout gets screwed up
         button.setVisibility(View.INVISIBLE);
-    }
-
-    private void disableToolbarButton(View button) {
-        button.setClickable(false);
+        button.setAlpha(0.0f);
     }
 
     /**
@@ -2623,7 +2641,6 @@
                 @Override
                 public void onAnimationStart(Animator animation) {
                     if (showing) showAndEnableToolbarButton(view);
-                    if (hiding) disableToolbarButton(view);
                 }
                 @Override
                 public void onAnimationEnd(Animator animation) {
@@ -2636,7 +2653,6 @@
                 showAndEnableToolbarButton(view);
                 view.setAlpha(1f);
             } else {
-                disableToolbarButton(view);
                 hideToolbarButton(view);
             }
         }
@@ -2654,15 +2670,18 @@
         switch (newState) {
         case WORKSPACE:
             hideOrShowToolbarButton(true, mButtonCluster, showSeq);
-            mDeleteZone.setOverlappingViews(
-                    new View[] { mAllAppsButton, mDivider, mConfigureButton });
             mDeleteZone.setDragAndDropEnabled(true);
-            mDeleteZone.setText(getResources().getString(R.string.delete_zone_label_workspace));
+            if (LauncherApplication.isScreenXLarge()) {
+                mDeleteZone.setText(getResources().getString(R.string.delete_zone_label_workspace));
+            }
             break;
         case ALL_APPS:
+        case APPS_CUSTOMIZE:
             hideOrShowToolbarButton(false, mButtonCluster, hideSeq);
             mDeleteZone.setDragAndDropEnabled(false);
-            mDeleteZone.setText(getResources().getString(R.string.delete_zone_label_all_apps));
+            if (LauncherApplication.isScreenXLarge()) {
+                mDeleteZone.setText(getResources().getString(R.string.delete_zone_label_all_apps));
+            }
             break;
         case CUSTOMIZE:
             hideOrShowToolbarButton(false, mButtonCluster, hideSeq);
@@ -2684,7 +2703,7 @@
         // Set pivotY so that at the starting zoom factor, the view is partially
         // visible. Modifying initialHeightFactor changes how much of the view is
         // initially showing, and hence the perceived angle from which the view enters.
-        if (state == State.ALL_APPS) {
+        if (state == State.ALL_APPS || state == State.APPS_CUSTOMIZE) {
             final float initialHeightFactor = 0.175f;
             view.setPivotY((1 - initialHeightFactor) * height);
         } else {
@@ -2701,20 +2720,28 @@
      */
     private void cameraZoomOut(State toState, boolean animated, boolean springLoaded) {
         final Resources res = getResources();
-        final boolean toAllApps = (toState == State.ALL_APPS);
+        final boolean toAllApps = (toState == State.ALL_APPS)
+                || (toState == State.APPS_CUSTOMIZE);
 
-        final int duration = toAllApps ?
-                res.getInteger(R.integer.config_allAppsZoomInTime) :
-                res.getInteger(R.integer.config_customizeZoomInTime);
-        final int fadeDuration = toAllApps ?
-                res.getInteger(R.integer.config_allAppsFadeInTime) :
-                res.getInteger(R.integer.config_customizeFadeInTime);
+        final int duration = (toAllApps ?
+                res.getInteger(R.integer.config_appsCustomizeZoomInTime) :
+                res.getInteger(R.integer.config_customizeZoomInTime));
+        final int fadeDuration = (toAllApps ?
+                res.getInteger(R.integer.config_appsCustomizeFadeInTime) :
+                res.getInteger(R.integer.config_customizeFadeInTime));
 
         final float scale = toAllApps ?
-                (float) res.getInteger(R.integer.config_allAppsZoomScaleFactor) :
+                (float) res.getInteger(R.integer.config_appsCustomizeZoomScaleFactor) :
                 (float) res.getInteger(R.integer.config_customizeZoomScaleFactor);
 
-        final View toView = toAllApps ? (View) mAllAppsGrid : mHomeCustomizationDrawer;
+        View tmpView;
+        if (toAllApps) {
+            tmpView = (LauncherApplication.isScreenXLarge())
+                    ? (View) mAllAppsGrid : mAppsCustomizeTabHost;
+        } else {
+            tmpView = mHomeCustomizationDrawer;
+        }
+        final View toView = tmpView;
 
         setPivotsForZoom(toView, toState, scale);
 
@@ -2722,9 +2749,11 @@
             if (!springLoaded) {
                 mWorkspace.shrink(ShrinkState.BOTTOM_HIDDEN, animated);
 
-                // Everytime we launch into AllApps, we reset the successful drop flag which
-                // controls when it should hide/show the mini workspaces
-                mAllAppsPagedView.resetSuccessfulDropFlag();
+                if (LauncherApplication.isScreenXLarge()) {
+                    // Everytime we launch into AllApps, we reset the successful drop flag which
+                    // controls when it should hide/show the mini workspaces
+                    mAllAppsPagedView.resetSuccessfulDropFlag();
+                }
             } else {
                 mWorkspace.shrink(ShrinkState.BOTTOM_VISIBLE, animated);
             }
@@ -2766,6 +2795,7 @@
                     toView.setTranslationX(0.0f);
                     toView.setTranslationY(0.0f);
                     toView.setVisibility(View.VISIBLE);
+                    toView.bringToFront();
                     if (!toAllApps) {
                         toView.setFastAlpha(1.0f);
                     }
@@ -2805,6 +2835,7 @@
             toView.setScaleX(1.0f);
             toView.setScaleY(1.0f);
             toView.setVisibility(View.VISIBLE);
+            toView.bringToFront();
             if (toView instanceof LauncherTransitionable) {
                 ((LauncherTransitionable) toView).onLauncherTransitionStart(null);
                 ((LauncherTransitionable) toView).onLauncherTransitionEnd(null);
@@ -2821,20 +2852,30 @@
      */
     private void cameraZoomIn(State fromState, boolean animated, boolean springLoaded) {
         Resources res = getResources();
-        final boolean fromAllApps = (fromState == State.ALL_APPS);
+        final boolean fromAllApps = (fromState == State.ALL_APPS)
+                || (fromState == State.APPS_CUSTOMIZE);
 
         int duration = fromAllApps ?
-            res.getInteger(R.integer.config_allAppsZoomOutTime) :
+            res.getInteger(R.integer.config_appsCustomizeZoomOutTime) :
             res.getInteger(R.integer.config_customizeZoomOutTime);
 
         final float scaleFactor = fromAllApps ?
-            (float) res.getInteger(R.integer.config_allAppsZoomScaleFactor) :
+            (float) res.getInteger(R.integer.config_appsCustomizeZoomScaleFactor) :
             (float) res.getInteger(R.integer.config_customizeZoomScaleFactor);
 
-        final View fromView = fromAllApps ? (View) mAllAppsGrid : mHomeCustomizationDrawer;
+        View tmpView;
+        if (fromAllApps) {
+            tmpView = (LauncherApplication.isScreenXLarge())
+                    ? (View) mAllAppsGrid : mAppsCustomizeTabHost;
+        } else {
+            tmpView = mHomeCustomizationDrawer;
+        }
+        final View fromView = tmpView;
 
-        mCustomizePagedView.endChoiceMode();
-        mAllAppsPagedView.endChoiceMode();
+        if (LauncherApplication.isScreenXLarge()) {
+            mCustomizePagedView.endChoiceMode();
+            mAllAppsPagedView.endChoiceMode();
+        }
 
         setPivotsForZoom(fromView, fromState, scaleFactor);
 
@@ -2858,7 +2899,7 @@
                 }
             });
             final ValueAnimator alphaAnim = ValueAnimator.ofFloat(0f, 1f);
-            alphaAnim.setDuration(res.getInteger(R.integer.config_allAppsFadeOutTime));
+            alphaAnim.setDuration(res.getInteger(R.integer.config_appsCustomizeFadeOutTime));
             alphaAnim.setInterpolator(new DecelerateInterpolator(1.5f));
             alphaAnim.addUpdateListener(new LauncherAnimatorUpdateListener() {
                 public void onAnimationUpdate(float a, float b) {
@@ -2904,34 +2945,6 @@
         }
     }
 
-    void showAllApps(boolean animated) {
-        if (mState != State.WORKSPACE) {
-            return;
-        }
-
-        if (LauncherApplication.isScreenXLarge()) {
-            cameraZoomOut(State.ALL_APPS, animated, false);
-        } else {
-            mAllAppsGrid.zoom(1.0f, animated);
-        }
-
-        ((View) mAllAppsGrid).setFocusable(true);
-        ((View) mAllAppsGrid).requestFocus();
-
-        // TODO: fade these two too
-        mDeleteZone.setVisibility(View.GONE);
-
-        // Change the state *after* we've called all the transition code
-        mState = State.ALL_APPS;
-
-        // Pause the auto-advance of widgets until we are out of AllApps
-        mUserPresent = false;
-        updateRunning();
-
-        // send an accessibility event to announce the context change
-        getWindow().getDecorView().sendAccessibilityEvent(AccessibilityEvent.TYPE_VIEW_SELECTED);
-    }
-
     void showWorkspace(boolean animated) {
         showWorkspace(animated, null);
     }
@@ -2944,7 +2957,7 @@
         } else {
             mWorkspace.unshrink(animated);
         }
-        if (mState == State.ALL_APPS) {
+        if (mState == State.ALL_APPS || mState == State.APPS_CUSTOMIZE) {
             closeAllApps(animated);
         } else if (mState == State.CUSTOMIZE) {
             hideCustomizationDrawer(animated);
@@ -2963,9 +2976,13 @@
 
     void enterSpringLoadedDragMode(CellLayout layout) {
         mWorkspace.enterSpringLoadedDragMode(layout);
-        if (mState == State.ALL_APPS) {
+        if (mState == State.ALL_APPS || mState == State.APPS_CUSTOMIZE) {
             mState = State.ALL_APPS_SPRING_LOADED;
-            cameraZoomIn(State.ALL_APPS, true, true);
+            if (LauncherApplication.isScreenXLarge()) {
+                cameraZoomIn(State.ALL_APPS, true, true);
+            } else {
+                cameraZoomIn(State.APPS_CUSTOMIZE, true, true);
+            }
         } else if (mState == State.CUSTOMIZE) {
             mState = State.CUSTOMIZE_SPRING_LOADED;
             cameraZoomIn(State.CUSTOMIZE, true, true);
@@ -2977,8 +2994,13 @@
     void exitSpringLoadedDragMode() {
         if (mState == State.ALL_APPS_SPRING_LOADED) {
             mWorkspace.exitSpringLoadedDragMode(Workspace.ShrinkState.BOTTOM_VISIBLE);
-            cameraZoomOut(State.ALL_APPS, true, true);
-            mState = State.ALL_APPS;
+            if (LauncherApplication.isScreenXLarge()) {
+                cameraZoomOut(State.ALL_APPS, true, true);
+                mState = State.ALL_APPS;
+            } else {
+                cameraZoomOut(State.APPS_CUSTOMIZE, true, true);
+                mState = State.APPS_CUSTOMIZE;
+            }
         } else if (mState == State.CUSTOMIZE_SPRING_LOADED) {
             mWorkspace.exitSpringLoadedDragMode(Workspace.ShrinkState.TOP);
             cameraZoomOut(State.CUSTOMIZE, true, true);
@@ -2988,6 +3010,34 @@
         }*/
     }
 
+    void showAllApps(boolean animated) {
+        if (mState != State.WORKSPACE) return;
+        if (LauncherApplication.isScreenXLarge()) {
+            cameraZoomOut(State.ALL_APPS, animated, false);
+            ((View) mAllAppsGrid).requestFocus();
+
+            // TODO: fade these two too
+            mDeleteZone.setVisibility(View.GONE);
+
+            // Change the state *after* we've called all the transition code
+            mState = State.ALL_APPS;
+        } else {
+            View appsCustomizePane = findViewById(R.id.apps_customize_pane);
+            cameraZoomOut(State.APPS_CUSTOMIZE, animated, false);
+            appsCustomizePane.requestFocus();
+
+            // Change the state *after* we've called all the transition code
+            mState = State.APPS_CUSTOMIZE;
+        }
+
+        // Pause the auto-advance of widgets until we are out of AllApps
+        mUserPresent = false;
+        updateRunning();
+
+        // Send an accessibility event to announce the context change
+        getWindow().getDecorView().sendAccessibilityEvent(AccessibilityEvent.TYPE_VIEW_SELECTED);
+    }
+
     /**
      * Things to test when changing this code.
      *   - Home from workspace
@@ -3028,15 +3078,22 @@
      *          - From another workspace
      */
     void closeAllApps(boolean animated) {
-        if (mState == State.ALL_APPS || mState == State.ALL_APPS_SPRING_LOADED) {
-            mWorkspace.setVisibility(View.VISIBLE);
-            if (LauncherApplication.isScreenXLarge()) {
+        if (LauncherApplication.isScreenXLarge()) {
+            if (mState == State.ALL_APPS || mState == State.ALL_APPS_SPRING_LOADED) {
+                mWorkspace.setVisibility(View.VISIBLE);
                 cameraZoomIn(State.ALL_APPS, animated, false);
-            } else {
-                mAllAppsGrid.zoom(0.0f, animated);
+
+                // Set focus to the AllApps button
+                findViewById(R.id.all_apps_button).requestFocus();
             }
-            ((View)mAllAppsGrid).setFocusable(false);
-            ((CellLayout) mWorkspace.getChildAt(mWorkspace.getCurrentPage())).getChildrenLayout().requestFocus();
+        } else {
+            if (mState == State.APPS_CUSTOMIZE || mState == State.ALL_APPS_SPRING_LOADED) {
+                mWorkspace.setVisibility(View.VISIBLE);
+                cameraZoomIn(State.APPS_CUSTOMIZE, animated, false);
+
+                // Set focus to the AllApps button
+                findViewById(R.id.all_apps_button).requestFocus();
+            }
         }
     }
 
@@ -3068,6 +3125,9 @@
     void hideCustomizationDrawer(boolean animated) {
         if (mState == State.CUSTOMIZE || mState == State.CUSTOMIZE_SPRING_LOADED) {
             cameraZoomIn(State.CUSTOMIZE, animated, false);
+
+            // Set focus to the customize button
+            findViewById(R.id.configure_button).requestFocus();
         }
     }
 
@@ -3199,16 +3259,21 @@
      * Sets the app market icon (shown when all apps is visible on x-large screens)
      */
     private void updateAppMarketIcon() {
-        if (LauncherApplication.isScreenXLarge()) {
-            Intent intent = new Intent(Intent.ACTION_MAIN).addCategory(Intent.CATEGORY_APP_MARKET);
-            // Find the app market activity by resolving an intent.
-            // (If multiple app markets are installed, it will return the ResolverActivity.)
-            ComponentName activityName = intent.resolveActivity(getPackageManager());
-            if (activityName != null) {
-                mAppMarketIntent = intent;
-                sAppMarketIcon = updateTextButtonWithIconFromExternalActivity(
-                        R.id.market_button, activityName, R.drawable.app_market_generic);
-            }
+        final View marketButton = findViewById(R.id.market_button);
+        Intent intent = new Intent(Intent.ACTION_MAIN).addCategory(Intent.CATEGORY_APP_MARKET);
+        // Find the app market activity by resolving an intent.
+        // (If multiple app markets are installed, it will return the ResolverActivity.)
+        ComponentName activityName = intent.resolveActivity(getPackageManager());
+        if (activityName != null) {
+            mAppMarketIntent = intent;
+            sAppMarketIcon = updateTextButtonWithIconFromExternalActivity(
+                    R.id.market_button, activityName, R.drawable.app_market_generic);
+            marketButton.setVisibility(View.VISIBLE);
+        } else {
+            // We should hide and disable the view so that we don't try and restore the visibility
+            // of it when we swap between drag & normal states from IconDropTarget subclasses.
+            marketButton.setVisibility(View.GONE);
+            marketButton.setEnabled(false);
         }
     }
 
@@ -3584,7 +3649,12 @@
      * Implementation of the method from LauncherModel.Callbacks.
      */
     public void bindAllApplications(ArrayList<ApplicationInfo> apps) {
-        mAllAppsGrid.setApps(apps);
+        if (mAllAppsGrid != null) {
+            mAllAppsGrid.setApps(apps);
+        }
+        if (mAppsCustomizeContent != null) {
+            mAppsCustomizeContent.setApps(apps);
+        }
         if (mCustomizePagedView != null) {
             mCustomizePagedView.setApps(apps);
         }
@@ -3599,7 +3669,12 @@
     public void bindAppsAdded(ArrayList<ApplicationInfo> apps) {
         setLoadOnResume();
         removeDialog(DIALOG_CREATE_SHORTCUT);
-        mAllAppsGrid.addApps(apps);
+        if (mAllAppsGrid != null) {
+            mAllAppsGrid.addApps(apps);
+        }
+        if (mAppsCustomizeContent != null) {
+            mAppsCustomizeContent.addApps(apps);
+        }
         if (mCustomizePagedView != null) {
             mCustomizePagedView.addApps(apps);
         }
@@ -3620,6 +3695,9 @@
         if (mAllAppsGrid != null) {
             mAllAppsGrid.updateApps(apps);
         }
+        if (mAppsCustomizeContent != null) {
+            mAppsCustomizeContent.updateApps(apps);
+        }
         if (mCustomizePagedView != null) {
             mCustomizePagedView.updateApps(apps);
         }
@@ -3636,7 +3714,12 @@
         if (permanent) {
             mWorkspace.removeItems(apps);
         }
-        mAllAppsGrid.removeApps(apps);
+        if (mAllAppsGrid != null) {
+            mAllAppsGrid.removeApps(apps);
+        }
+        if (mAppsCustomizeContent != null) {
+            mAppsCustomizeContent.removeApps(apps);
+        }
         if (mCustomizePagedView != null) {
             mCustomizePagedView.removeApps(apps);
         }
@@ -3651,6 +3734,9 @@
         if (mCustomizePagedView != null) {
             mCustomizePagedView.update();
         }
+        if (mAppsCustomizeContent != null) {
+            mAppsCustomizeContent.onPackagesUpdated();
+        }
     }
 
     private int mapConfigurationOriActivityInfoOri(int configOri) {
@@ -3709,7 +3795,12 @@
         Log.d(TAG, "mDesktopItems.size=" + mDesktopItems.size());
         Log.d(TAG, "sFolders.size=" + sFolders.size());
         mModel.dumpState();
-        mAllAppsGrid.dumpState();
+        if (mAllAppsGrid != null) {
+            mAllAppsGrid.dumpState();
+        }
+        if (mAppsCustomizeContent != null) {
+            mAppsCustomizeContent.dumpState();
+        }
         Log.d(TAG, "END launcher2 dump state");
     }
 }
diff --git a/src/com/android/launcher2/LauncherModel.java b/src/com/android/launcher2/LauncherModel.java
index e432733..9bf8838 100644
--- a/src/com/android/launcher2/LauncherModel.java
+++ b/src/com/android/launcher2/LauncherModel.java
@@ -1789,6 +1789,28 @@
             return 0;
         }
     };
+    public static final Comparator<AppWidgetProviderInfo> WIDGET_NAME_COMPARATOR
+            = new Comparator<AppWidgetProviderInfo>() {
+        public final int compare(AppWidgetProviderInfo a, AppWidgetProviderInfo b) {
+            return sCollator.compare(a.label.toString(), b.label.toString());
+        }
+    };
+    public static class ShortcutNameComparator implements Comparator<ResolveInfo> {
+        private PackageManager mPackageManager;
+        private HashMap<Object, String> mLabelCache;
+        ShortcutNameComparator(PackageManager pm) {
+            mPackageManager = pm;
+            mLabelCache = new HashMap<Object, String>();
+        }
+        public final int compare(ResolveInfo a, ResolveInfo b) {
+            String labelA, labelB;
+            if (mLabelCache.containsKey(a)) labelA = mLabelCache.get(a);
+            else labelA = a.loadLabel(mPackageManager).toString();
+            if (mLabelCache.containsKey(b)) labelB = mLabelCache.get(b);
+            else labelB = b.loadLabel(mPackageManager).toString();
+            return sCollator.compare(labelA, labelB);
+        }
+    };
 
     public void dumpState() {
         Log.d(TAG, "mCallbacks=" + mCallbacks);
diff --git a/src/com/android/launcher2/PagedView.java b/src/com/android/launcher2/PagedView.java
index 9eae647..3bef69e 100644
--- a/src/com/android/launcher2/PagedView.java
+++ b/src/com/android/launcher2/PagedView.java
@@ -29,6 +29,7 @@
 import android.os.Parcel;
 import android.os.Parcelable;
 import android.util.AttributeSet;
+import android.util.Log;
 import android.view.ActionMode;
 import android.view.InputDevice;
 import android.view.KeyEvent;
@@ -50,6 +51,7 @@
  */
 public abstract class PagedView extends ViewGroup {
     private static final String TAG = "PagedView";
+    private static final boolean DEBUG = false;
     protected static final int INVALID_PAGE = -1;
 
     // the min drag distance for a fling to register, to prevent random page shifts
@@ -397,6 +399,7 @@
 
         // The children are given the same width and height as the workspace
         // unless they were set to WRAP_CONTENT
+        if (DEBUG) Log.d(TAG, "PagedView.onMeasure(): " + widthSize + ", " + heightSize);
         final int childCount = getChildCount();
         for (int i = 0; i < childCount; i++) {
             // disallowing padding in paged view (just pass 0)
@@ -424,6 +427,8 @@
 
             child.measure(childWidthMeasureSpec, childHeightMeasureSpec);
             maxChildHeight = Math.max(maxChildHeight, child.getMeasuredHeight());
+            if (DEBUG) Log.d(TAG, "\tmeasure-child" + i + ": " + child.getMeasuredWidth() + ", "
+                    + child.getMeasuredHeight());
         }
 
         if (heightMode == MeasureSpec.AT_MOST) {
@@ -478,6 +483,7 @@
 
     @Override
     protected void onLayout(boolean changed, int left, int top, int right, int bottom) {
+        if (DEBUG) Log.d(TAG, "PagedView.onLayout()");
         if (mFirstLayout && mCurrentPage >= 0 && mCurrentPage < getChildCount()) {
             setHorizontalScrollBarEnabled(false);
             int newX = getChildOffset(mCurrentPage) - getRelativeChildOffset(mCurrentPage);
@@ -491,6 +497,8 @@
         final int childCount = getChildCount();
         int childLeft = 0;
         if (childCount > 0) {
+            if (DEBUG) Log.d(TAG, "getRelativeChildOffset(): " + getMeasuredWidth() + ", "
+                    + getChildWidth(0));
             childLeft = getRelativeChildOffset(0);
         }
 
@@ -504,6 +512,7 @@
                     childTop += ((getMeasuredHeight() - verticalPadding) - childHeight) / 2;
                 }
 
+                if (DEBUG) Log.d(TAG, "\tlayout-child" + i + ": " + childLeft + ", " + childTop);
                 child.layout(childLeft, childTop,
                         childLeft + child.getMeasuredWidth(), childTop + childHeight);
                 childLeft += childWidth + mPageSpacing;
@@ -993,6 +1002,7 @@
                     mSmoothingTime = System.nanoTime() / NANOTIME_DIV;
                     if (!mDeferScrollUpdate) {
                         scrollBy((int) deltaX, 0);
+                        if (DEBUG) Log.d(TAG, "onTouchEvent().Scrolling: " + deltaX);
                     } else {
                         invalidate();
                     }
@@ -1262,6 +1272,9 @@
         whichPage = Math.max(0, Math.min(whichPage, getChildCount() - 1));
         int halfScreenSize = getMeasuredWidth() / 2;
 
+        if (DEBUG) Log.d(TAG, "snapToPage.getChildOffset(): " + getChildOffset(whichPage));
+        if (DEBUG) Log.d(TAG, "snapToPageWithVelocity.getRelativeChildOffset(): "
+                + getMeasuredWidth() + ", " + getChildWidth(whichPage));
         final int newX = getChildOffset(whichPage) - getRelativeChildOffset(whichPage);
         int delta = newX - mUnboundedScrollX;
         int duration = 0;
@@ -1299,6 +1312,9 @@
     protected void snapToPage(int whichPage, int duration) {
         whichPage = Math.max(0, Math.min(whichPage, getPageCount() - 1));
 
+        if (DEBUG) Log.d(TAG, "snapToPage.getChildOffset(): " + getChildOffset(whichPage));
+        if (DEBUG) Log.d(TAG, "snapToPage.getRelativeChildOffset(): " + getMeasuredWidth() + ", "
+                + getChildWidth(whichPage));
         int newX = getChildOffset(whichPage) - getRelativeChildOffset(whichPage);
         final int sX = mUnboundedScrollX;
         final int delta = newX - sX;
@@ -1410,6 +1426,8 @@
             if (page < count) {
                 int lowerPageBound = getAssociatedLowerPageBound(page);
                 int upperPageBound = getAssociatedUpperPageBound(page);
+                if (DEBUG) Log.d(TAG, "loadAssociatedPages: " + lowerPageBound + "/"
+                        + upperPageBound);
                 for (int i = 0; i < count; ++i) {
                     Page layout = (Page) getChildAt(i);
                     final int childCount = layout.getPageChildCount();
diff --git a/src/com/android/launcher2/PagedViewCellLayout.java b/src/com/android/launcher2/PagedViewCellLayout.java
index 28e092e..196063d 100644
--- a/src/com/android/launcher2/PagedViewCellLayout.java
+++ b/src/com/android/launcher2/PagedViewCellLayout.java
@@ -17,12 +17,15 @@
 package com.android.launcher2;
 
 import android.content.Context;
+import android.content.res.Resources;
 import android.util.AttributeSet;
 import android.view.MotionEvent;
 import android.view.View;
 import android.view.ViewDebug;
 import android.view.ViewGroup;
 
+import com.android.launcher.R;
+
 /**
  * An abstraction of the original CellLayout which supports laying out items
  * which span multiple cells into a grid-like layout.  Also supports dimming
@@ -37,7 +40,6 @@
     private int mCellHeight;
     private int mWidthGap;
     private int mHeightGap;
-    private static int sDefaultCellDimensions = 96;
     protected PagedViewCellLayoutChildren mChildren;
     private PagedViewCellLayoutChildren mHolographicChildren;
     private boolean mAllowHardwareLayerCreation = false;
@@ -57,7 +59,9 @@
         setAlwaysDrawnWithCacheEnabled(false);
 
         // setup default cell parameters
-        mCellWidth = mCellHeight = sDefaultCellDimensions;
+        Resources resources = context.getResources();
+        mCellWidth = resources.getDimensionPixelSize(R.dimen.apps_customize_cell_width);
+        mCellHeight = resources.getDimensionPixelSize(R.dimen.apps_customize_cell_height);
         mCellCountX = LauncherModel.getCellCountX();
         mCellCountY = LauncherModel.getCellCountY();
         mWidthGap = mHeightGap = -1;
@@ -252,11 +256,15 @@
     }
 
     int getContentWidth() {
-        // Return the distance from the left edge of the content of the leftmost icon to
-        // the right edge of the content of the rightmost icon
+        if (LauncherApplication.isScreenXLarge()) {
+            // Return the distance from the left edge of the content of the leftmost icon to
+            // the right edge of the content of the rightmost icon
 
-        // icons are centered within cells, find out how much padding that accounts for
-        return getWidthBeforeFirstLayout() - (mCellWidth - Utilities.getIconContentSize());
+            // icons are centered within cells, find out how much padding that accounts for
+            return getWidthBeforeFirstLayout() - (mCellWidth - Utilities.getIconContentSize());
+        } else {
+            return getWidthBeforeFirstLayout() + mPaddingLeft + mPaddingRight;
+        }
     }
 
     int getWidthBeforeFirstLayout() {
@@ -268,7 +276,12 @@
         int count = getChildCount();
         for (int i = 0; i < count; i++) {
             View child = getChildAt(i);
-            child.layout(0, 0, r - l, b - t);
+            if (LauncherApplication.isScreenXLarge()) {
+                child.layout(0, 0, r - l, b - t);
+            } else {
+                child.layout(mPaddingLeft, mPaddingTop, getMeasuredWidth() - mPaddingRight,
+                        getMeasuredHeight() - mPaddingBottom);
+            }
         }
     }
 
@@ -457,8 +470,13 @@
             height = myCellVSpan * cellHeight + ((myCellVSpan - 1) * heightGap) -
                     topMargin - bottomMargin;
 
-            x = hStartPadding + myCellX * (cellWidth + widthGap) + leftMargin;
-            y = vStartPadding + myCellY * (cellHeight + heightGap) + topMargin;
+            if (LauncherApplication.isScreenXLarge()) {
+                x = hStartPadding + myCellX * (cellWidth + widthGap) + leftMargin;
+                y = vStartPadding + myCellY * (cellHeight + heightGap) + topMargin;
+            } else {
+                x = myCellX * (cellWidth + widthGap) + leftMargin;
+                y = myCellY * (cellHeight + heightGap) + topMargin;
+            }
         }
 
         public Object getTag() {
diff --git a/src/com/android/launcher2/PagedViewExtendedLayout.java b/src/com/android/launcher2/PagedViewExtendedLayout.java
index 81f1498..776b99f 100644
--- a/src/com/android/launcher2/PagedViewExtendedLayout.java
+++ b/src/com/android/launcher2/PagedViewExtendedLayout.java
@@ -40,6 +40,22 @@
         super(context, attrs, defStyle);
     }
 
+    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
+        if (LauncherApplication.isScreenXLarge()) {
+            super.onMeasure(widthMeasureSpec, heightMeasureSpec);
+        } else {
+            // PagedView currently has issues with different-sized pages since it calculates the
+            // offset of each page to scroll to before it updates the actual size of each page
+            // (which canchange depending on the content if the contains aren't a fixed size).
+            // We work around this by having a minimum size on each widget page).
+            int widthSpecSize = Math.max(getSuggestedMinimumWidth(),
+                    MeasureSpec.getSize(widthMeasureSpec));
+            int widthSpecMode = MeasureSpec.AT_MOST;
+            super.onMeasure(MeasureSpec.makeMeasureSpec(widthSpecSize, widthSpecMode),
+                    heightMeasureSpec);
+        }
+    }
+
     @Override
     public boolean onTouchEvent(MotionEvent event) {
         // We eat up the touch events here, since the PagedView (which uses the same swiping
@@ -94,4 +110,11 @@
     public int indexOfChildOnPage(View v) {
         return indexOfChild(v);
     }
+
+    public static class LayoutParams extends LinearLayout.LayoutParams {
+        public LayoutParams() {
+            super(LinearLayout.LayoutParams.WRAP_CONTENT,
+                    LinearLayout.LayoutParams.MATCH_PARENT);
+        }
+    }
 }
diff --git a/src/com/android/launcher2/PagedViewIcon.java b/src/com/android/launcher2/PagedViewIcon.java
index f46b63c..f1b8a01 100644
--- a/src/com/android/launcher2/PagedViewIcon.java
+++ b/src/com/android/launcher2/PagedViewIcon.java
@@ -122,11 +122,13 @@
 
         // Set up fade in/out constants
         final Resources r = context.getResources();
-        final int alpha = r.getInteger(R.integer.icon_allAppsCustomizeFadeAlpha);
+        final int alpha = r.getInteger(R.integer.config_dragAppsCustomizeIconFadeAlpha);
         if (alpha > 0) {
-            mCheckedAlpha = r.getInteger(R.integer.icon_allAppsCustomizeFadeAlpha) / 256.0f;
-            mCheckedFadeInDuration = r.getInteger(R.integer.icon_allAppsCustomizeFadeInTime);
-            mCheckedFadeOutDuration = r.getInteger(R.integer.icon_allAppsCustomizeFadeOutTime);
+            mCheckedAlpha = r.getInteger(R.integer.config_dragAppsCustomizeIconFadeAlpha) / 256.0f;
+            mCheckedFadeInDuration =
+                r.getInteger(R.integer.config_dragAppsCustomizeIconFadeInDuration);
+            mCheckedFadeOutDuration =
+                r.getInteger(R.integer.config_dragAppsCustomizeIconFadeOutDuration);
         }
 
         mHolographicOutlineView = new HolographicPagedViewIcon(context, this);
diff --git a/src/com/android/launcher2/PagedViewWidget.java b/src/com/android/launcher2/PagedViewWidget.java
index c2d609e..2dcceae 100644
--- a/src/com/android/launcher2/PagedViewWidget.java
+++ b/src/com/android/launcher2/PagedViewWidget.java
@@ -154,14 +154,15 @@
 
         // Set up fade in/out constants
         final Resources r = context.getResources();
-        final int alpha = r.getInteger(R.integer.icon_allAppsCustomizeFadeAlpha);
+        final int alpha = r.getInteger(R.integer.config_dragAppsCustomizeIconFadeAlpha);
         if (alpha > 0) {
-            mCheckedAlpha = r.getInteger(R.integer.icon_allAppsCustomizeFadeAlpha) / 256.0f;
-            mCheckedFadeInDuration = r.getInteger(R.integer.icon_allAppsCustomizeFadeInTime);
-            mCheckedFadeOutDuration = r.getInteger(R.integer.icon_allAppsCustomizeFadeOutTime);
+            mCheckedAlpha = r.getInteger(R.integer.config_dragAppsCustomizeIconFadeAlpha) / 256.0f;
+            mCheckedFadeInDuration =
+                r.getInteger(R.integer.config_dragAppsCustomizeIconFadeInDuration);
+            mCheckedFadeOutDuration =
+                r.getInteger(R.integer.config_dragAppsCustomizeIconFadeOutDuration);
         }
 
-        setFocusable(true);
         setWillNotDraw(false);
         setClipToPadding(false);
     }
diff --git a/src/com/android/launcher2/Workspace.java b/src/com/android/launcher2/Workspace.java
index b1aa410..49cab80 100644
--- a/src/com/android/launcher2/Workspace.java
+++ b/src/com/android/launcher2/Workspace.java
@@ -1059,6 +1059,8 @@
     @Override
     protected void screenScrolled(int screenCenter) {
         // If the screen is not xlarge, then don't rotate the CellLayouts
+        // NOTE: If we don't update the side pages alpha, then we should not hide the side pages.
+        //       see unshrink().
         if (!LauncherApplication.isScreenXLarge()) return;
 
         final int halfScreenSize = getMeasuredWidth() / 2;
@@ -1257,19 +1259,6 @@
         }
     }
 
-    @Override
-    public boolean dispatchTouchEvent(MotionEvent ev) {
-        if (ev.getAction() == MotionEvent.ACTION_DOWN) {
-            // (In XLarge mode, the workspace is shrunken below all apps, and responds to taps
-            // ie when you click on a mini-screen, it zooms back to that screen)
-            if (!LauncherApplication.isScreenXLarge() && mLauncher.isAllAppsVisible()) {
-                return false;
-            }
-        }
-
-        return super.dispatchTouchEvent(ev);
-    }
-
     void enableChildrenCache(int fromPage, int toPage) {
         if (fromPage > toPage) {
             final int temp = fromPage;
@@ -1299,27 +1288,32 @@
 
     @Override
     public boolean onTouchEvent(MotionEvent ev) {
-        AllAppsPagedView allApps = (AllAppsPagedView)
-                mLauncher.findViewById(R.id.all_apps_paged_view);
-
-        if (mLauncher.isAllAppsVisible() && mShrinkState == ShrinkState.BOTTOM_HIDDEN
-                && allApps != null) {
-            if (ev.getAction() == MotionEvent.ACTION_UP &&
-                    allApps.getTouchState() == TOUCH_STATE_REST) {
-
-                // Cancel any scrolling that is in progress.
-                if (!mScroller.isFinished()) {
-                    mScroller.abortAnimation();
-                }
-                setCurrentPage(mCurrentPage);
-
-                if (mShrinkState == ShrinkState.BOTTOM_HIDDEN) {
-                    mLauncher.showWorkspace(true);
-                }
-                allApps.onTouchEvent(ev);
-                return true;
+        if (mLauncher.isAllAppsVisible() && mShrinkState == ShrinkState.BOTTOM_HIDDEN) {
+            PagedView appsPane;
+            if (LauncherApplication.isScreenXLarge()) {
+                appsPane = (PagedView) mLauncher.findViewById(R.id.all_apps_paged_view);
             } else {
-                return allApps.onTouchEvent(ev);
+                appsPane = (PagedView) mLauncher.findViewById(R.id.apps_customize_pane_content);
+            }
+
+            if (appsPane != null) {
+                if (ev.getAction() == MotionEvent.ACTION_UP &&
+                        appsPane.getTouchState() == TOUCH_STATE_REST) {
+
+                    // Cancel any scrolling that is in progress.
+                    if (!mScroller.isFinished()) {
+                        mScroller.abortAnimation();
+                    }
+                    setCurrentPage(mCurrentPage);
+
+                    if (mShrinkState == ShrinkState.BOTTOM_HIDDEN) {
+                        mLauncher.showWorkspace(true);
+                    }
+                    appsPane.onTouchEvent(ev);
+                    return true;
+                } else {
+                    return appsPane.onTouchEvent(ev);
+                }
             }
         }
         return super.onTouchEvent(ev);
@@ -1465,7 +1459,7 @@
 
         int duration;
         if (shrinkState == ShrinkState.BOTTOM_HIDDEN || shrinkState == ShrinkState.BOTTOM_VISIBLE) {
-            duration = res.getInteger(R.integer.config_allAppsWorkspaceShrinkTime);
+            duration = res.getInteger(R.integer.config_appsCustomizeWorkspaceShrinkTime);
         } else {
             duration = res.getInteger(R.integer.config_customizeWorkspaceShrinkTime);
         }
@@ -1859,17 +1853,24 @@
 
             for (int i = 0; i < screenCount; i++) {
                 final CellLayout cl = (CellLayout)getChildAt(i);
-                float finalAlphaValue = (i == mCurrentPage) ? 1.0f : 0.0f;
+                float finalAlphaValue = 0f;
+                float rotation = 0f;
+                if (LauncherApplication.isScreenXLarge()) {
+                    finalAlphaValue = (i == mCurrentPage) ? 1.0f : 0.0f;
+
+                    if (i < mCurrentPage) {
+                        rotation = WORKSPACE_ROTATION;
+                    } else if (i > mCurrentPage) {
+                        rotation = -WORKSPACE_ROTATION;
+                    }
+                } else {
+                    // Don't hide the side panes on the phone if we don't also update the side pages
+                    // alpha.  See screenScrolled().
+                    finalAlphaValue = 1f;
+                }
                 float finalAlphaMultiplierValue =
                         ((i == mCurrentPage) && (mShrinkState != ShrinkState.SPRING_LOADED)) ?
                         0.0f : 1.0f;
-                float rotation = 0.0f;
-
-                if (i < mCurrentPage) {
-                    rotation = WORKSPACE_ROTATION;
-                } else if (i > mCurrentPage) {
-                    rotation = -WORKSPACE_ROTATION;
-                }
 
                 float translation = getOffsetXForRotation(rotation, cl.getWidth(), cl.getHeight());
 
@@ -2878,16 +2879,21 @@
                         mSpringLoadedDragController.onDragExit();
                     }
                     mDragTargetLayout = layout;
-                    // In spring-loaded mode, we still want the user to be able to hover over a
-                    // full screen (which is traditionally set to not accept drops) if they want to
-                    // get to pages beyond the screen that is full.
-                    boolean allowDragOver = (mDragTargetLayout != null) &&
-                            (mDragTargetLayout.getAcceptsDrops() ||
-                                    (mShrinkState == ShrinkState.SPRING_LOADED));
-                    if (allowDragOver) {
-                        mDragTargetLayout.setIsDragOverlapping(true);
-                        mSpringLoadedDragController.onDragEnter(
-                                mDragTargetLayout, mShrinkState == ShrinkState.SPRING_LOADED);
+
+                    // Workaround the fact that we don't actually want spring-loaded mode in phone
+                    // UI yet.
+                    if (LauncherApplication.isScreenXLarge()) {
+                        // In spring-loaded mode, we still want the user to be able to hover over a
+                        // full screen (which is traditionally set to not accept drops) if they want
+                        // to get to pages beyond the screen that is full.
+                        boolean allowDragOver = (mDragTargetLayout != null) &&
+                                (mDragTargetLayout.getAcceptsDrops() ||
+                                        (mShrinkState == ShrinkState.SPRING_LOADED));
+                        if (allowDragOver) {
+                            mDragTargetLayout.setIsDragOverlapping(true);
+                            mSpringLoadedDragController.onDragEnter(
+                                    mDragTargetLayout, mShrinkState == ShrinkState.SPRING_LOADED);
+                        }
                     }
                 }
             } else {