Merge "Add widgets to default home screens." into froyo
diff --git a/res/drawable-hdpi/all_apps_button_focused.png b/res/drawable-hdpi/all_apps_button_focused.png
index 94f7b08..55574ed 100644
--- a/res/drawable-hdpi/all_apps_button_focused.png
+++ b/res/drawable-hdpi/all_apps_button_focused.png
Binary files differ
diff --git a/res/drawable-hdpi/all_apps_button_normal.png b/res/drawable-hdpi/all_apps_button_normal.png
index 188d528..7e7ec86 100644
--- a/res/drawable-hdpi/all_apps_button_normal.png
+++ b/res/drawable-hdpi/all_apps_button_normal.png
Binary files differ
diff --git a/res/drawable-hdpi/all_apps_button_pressed.png b/res/drawable-hdpi/all_apps_button_pressed.png
index 600dea9..3ccb5af 100644
--- a/res/drawable-hdpi/all_apps_button_pressed.png
+++ b/res/drawable-hdpi/all_apps_button_pressed.png
Binary files differ
diff --git a/res/drawable-hdpi/hotseat_bg_center.9.png b/res/drawable-hdpi/hotseat_bg_center.9.png
new file mode 100644
index 0000000..0567b77
--- /dev/null
+++ b/res/drawable-hdpi/hotseat_bg_center.9.png
Binary files differ
diff --git a/res/drawable-hdpi/hotseat_bg_left.9.png b/res/drawable-hdpi/hotseat_bg_left.9.png
new file mode 100644
index 0000000..aaf42c4
--- /dev/null
+++ b/res/drawable-hdpi/hotseat_bg_left.9.png
Binary files differ
diff --git a/res/drawable-hdpi/hotseat_bg_right.9.png b/res/drawable-hdpi/hotseat_bg_right.9.png
new file mode 100644
index 0000000..2b8149b
--- /dev/null
+++ b/res/drawable-hdpi/hotseat_bg_right.9.png
Binary files differ
diff --git a/res/drawable-hdpi/hotseat_browser_focused.png b/res/drawable-hdpi/hotseat_browser_focused.png
new file mode 100644
index 0000000..6044238
--- /dev/null
+++ b/res/drawable-hdpi/hotseat_browser_focused.png
Binary files differ
diff --git a/res/drawable-hdpi/hotseat_browser_normal.png b/res/drawable-hdpi/hotseat_browser_normal.png
new file mode 100644
index 0000000..e6eb94e
--- /dev/null
+++ b/res/drawable-hdpi/hotseat_browser_normal.png
Binary files differ
diff --git a/res/drawable-hdpi/hotseat_browser_pressed.png b/res/drawable-hdpi/hotseat_browser_pressed.png
new file mode 100644
index 0000000..918afb4
--- /dev/null
+++ b/res/drawable-hdpi/hotseat_browser_pressed.png
Binary files differ
diff --git a/res/drawable-hdpi/hotseat_left.png b/res/drawable-hdpi/hotseat_left.png
new file mode 100644
index 0000000..5dabf57e
--- /dev/null
+++ b/res/drawable-hdpi/hotseat_left.png
Binary files differ
diff --git a/res/drawable-hdpi/hotseat_phone_focused.png b/res/drawable-hdpi/hotseat_phone_focused.png
new file mode 100644
index 0000000..3e84a58
--- /dev/null
+++ b/res/drawable-hdpi/hotseat_phone_focused.png
Binary files differ
diff --git a/res/drawable-hdpi/hotseat_phone_normal.png b/res/drawable-hdpi/hotseat_phone_normal.png
new file mode 100644
index 0000000..e8a869c
--- /dev/null
+++ b/res/drawable-hdpi/hotseat_phone_normal.png
Binary files differ
diff --git a/res/drawable-hdpi/hotseat_phone_pressed.png b/res/drawable-hdpi/hotseat_phone_pressed.png
new file mode 100644
index 0000000..dc4ad6e
--- /dev/null
+++ b/res/drawable-hdpi/hotseat_phone_pressed.png
Binary files differ
diff --git a/res/drawable-hdpi/hotseat_right.png b/res/drawable-hdpi/hotseat_right.png
new file mode 100644
index 0000000..114bcb5
--- /dev/null
+++ b/res/drawable-hdpi/hotseat_right.png
Binary files differ
diff --git a/res/drawable-hdpi/trashcan.png b/res/drawable-hdpi/trashcan.png
index d356f45..482fbd8 100644
--- a/res/drawable-hdpi/trashcan.png
+++ b/res/drawable-hdpi/trashcan.png
Binary files differ
diff --git a/res/drawable-hdpi/trashcan_hover.png b/res/drawable-hdpi/trashcan_hover.png
index 7dda19e..484acef 100644
--- a/res/drawable-hdpi/trashcan_hover.png
+++ b/res/drawable-hdpi/trashcan_hover.png
Binary files differ
diff --git a/res/drawable-land-hdpi/hotseat_bg_center.9.png b/res/drawable-land-hdpi/hotseat_bg_center.9.png
new file mode 100644
index 0000000..f6a59fa
--- /dev/null
+++ b/res/drawable-land-hdpi/hotseat_bg_center.9.png
Binary files differ
diff --git a/res/drawable-land-hdpi/hotseat_bg_left.9.png b/res/drawable-land-hdpi/hotseat_bg_left.9.png
new file mode 100644
index 0000000..8320e73
--- /dev/null
+++ b/res/drawable-land-hdpi/hotseat_bg_left.9.png
Binary files differ
diff --git a/res/drawable-land-hdpi/hotseat_bg_right.9.png b/res/drawable-land-hdpi/hotseat_bg_right.9.png
new file mode 100644
index 0000000..2d74f2bb
--- /dev/null
+++ b/res/drawable-land-hdpi/hotseat_bg_right.9.png
Binary files differ
diff --git a/res/drawable-mdpi/all_apps_button_focused.png b/res/drawable-mdpi/all_apps_button_focused.png
index f026ee4..a9d5a3f 100644
--- a/res/drawable-mdpi/all_apps_button_focused.png
+++ b/res/drawable-mdpi/all_apps_button_focused.png
Binary files differ
diff --git a/res/drawable-mdpi/all_apps_button_normal.png b/res/drawable-mdpi/all_apps_button_normal.png
index eb3c85d..227215b 100644
--- a/res/drawable-mdpi/all_apps_button_normal.png
+++ b/res/drawable-mdpi/all_apps_button_normal.png
Binary files differ
diff --git a/res/drawable-mdpi/all_apps_button_pressed.png b/res/drawable-mdpi/all_apps_button_pressed.png
index 1f44aa1..e243252 100644
--- a/res/drawable-mdpi/all_apps_button_pressed.png
+++ b/res/drawable-mdpi/all_apps_button_pressed.png
Binary files differ
diff --git a/res/drawable-mdpi/home_button_focused.png b/res/drawable-mdpi/home_button_focused.png
index 75767ef..29fcbd0 100644
--- a/res/drawable-mdpi/home_button_focused.png
+++ b/res/drawable-mdpi/home_button_focused.png
Binary files differ
diff --git a/res/drawable-mdpi/home_button_normal.png b/res/drawable-mdpi/home_button_normal.png
index 8229bee..58ff958 100644
--- a/res/drawable-mdpi/home_button_normal.png
+++ b/res/drawable-mdpi/home_button_normal.png
Binary files differ
diff --git a/res/drawable-mdpi/home_button_pressed.png b/res/drawable-mdpi/home_button_pressed.png
index 1ff1a30..32337d6 100644
--- a/res/drawable-mdpi/home_button_pressed.png
+++ b/res/drawable-mdpi/home_button_pressed.png
Binary files differ
diff --git a/res/drawable-mdpi/hotseat_bg_center.9.png b/res/drawable-mdpi/hotseat_bg_center.9.png
new file mode 100644
index 0000000..fd36361
--- /dev/null
+++ b/res/drawable-mdpi/hotseat_bg_center.9.png
Binary files differ
diff --git a/res/drawable-mdpi/hotseat_bg_left.9.png b/res/drawable-mdpi/hotseat_bg_left.9.png
new file mode 100644
index 0000000..180bcbb
--- /dev/null
+++ b/res/drawable-mdpi/hotseat_bg_left.9.png
Binary files differ
diff --git a/res/drawable-mdpi/hotseat_bg_right.9.png b/res/drawable-mdpi/hotseat_bg_right.9.png
new file mode 100644
index 0000000..88967a0
--- /dev/null
+++ b/res/drawable-mdpi/hotseat_bg_right.9.png
Binary files differ
diff --git a/res/drawable-mdpi/hotseat_browser_focused.png b/res/drawable-mdpi/hotseat_browser_focused.png
new file mode 100644
index 0000000..de8defc
--- /dev/null
+++ b/res/drawable-mdpi/hotseat_browser_focused.png
Binary files differ
diff --git a/res/drawable-mdpi/hotseat_browser_normal.png b/res/drawable-mdpi/hotseat_browser_normal.png
new file mode 100644
index 0000000..35205a2
--- /dev/null
+++ b/res/drawable-mdpi/hotseat_browser_normal.png
Binary files differ
diff --git a/res/drawable-mdpi/hotseat_browser_pressed.png b/res/drawable-mdpi/hotseat_browser_pressed.png
new file mode 100644
index 0000000..d0a072e
--- /dev/null
+++ b/res/drawable-mdpi/hotseat_browser_pressed.png
Binary files differ
diff --git a/res/drawable-mdpi/hotseat_phone_focused.png b/res/drawable-mdpi/hotseat_phone_focused.png
new file mode 100644
index 0000000..15ec1c6
--- /dev/null
+++ b/res/drawable-mdpi/hotseat_phone_focused.png
Binary files differ
diff --git a/res/drawable-mdpi/hotseat_phone_normal.png b/res/drawable-mdpi/hotseat_phone_normal.png
new file mode 100644
index 0000000..d759b1f
--- /dev/null
+++ b/res/drawable-mdpi/hotseat_phone_normal.png
Binary files differ
diff --git a/res/drawable-mdpi/hotseat_phone_pressed.png b/res/drawable-mdpi/hotseat_phone_pressed.png
new file mode 100644
index 0000000..fcdf073
--- /dev/null
+++ b/res/drawable-mdpi/hotseat_phone_pressed.png
Binary files differ
diff --git a/res/drawable-mdpi/trashcan.png b/res/drawable-mdpi/trashcan.png
index a8c0fb5..4f01d76 100644
--- a/res/drawable-mdpi/trashcan.png
+++ b/res/drawable-mdpi/trashcan.png
Binary files differ
diff --git a/res/drawable-mdpi/trashcan_hover.png b/res/drawable-mdpi/trashcan_hover.png
index d4fe3a4..fb7474a 100644
--- a/res/drawable-mdpi/trashcan_hover.png
+++ b/res/drawable-mdpi/trashcan_hover.png
Binary files differ
diff --git a/res/drawable/hotseat_browser.xml b/res/drawable/hotseat_browser.xml
new file mode 100644
index 0000000..3c327bf
--- /dev/null
+++ b/res/drawable/hotseat_browser.xml
@@ -0,0 +1,23 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2008 The Android Open Source Project
+
+     Licensed under the Apache License, Version 2.0 (the "License");
+     you may not use this file except in compliance with the License.
+     You may obtain a copy of the License at
+
+          http://www.apache.org/licenses/LICENSE-2.0
+
+     Unless required by applicable law or agreed to in writing, software
+     distributed under the License is distributed on an "AS IS" BASIS,
+     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+     See the License for the specific language governing permissions and
+     limitations under the License.
+-->
+
+<selector xmlns:android="http://schemas.android.com/apk/res/android">
+    <item android:state_pressed="true" android:drawable="@drawable/hotseat_browser_pressed" />
+    <item android:state_focused="true" android:state_window_focused="true" android:drawable="@drawable/hotseat_browser_focused" />
+    <item android:state_focused="true" android:state_window_focused="false" android:drawable="@drawable/hotseat_browser_normal" />
+    <item android:drawable="@drawable/hotseat_browser_normal" />
+</selector>
+
diff --git a/res/drawable/hotseat_phone.xml b/res/drawable/hotseat_phone.xml
new file mode 100644
index 0000000..318a81e
--- /dev/null
+++ b/res/drawable/hotseat_phone.xml
@@ -0,0 +1,23 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2008 The Android Open Source Project
+
+     Licensed under the Apache License, Version 2.0 (the "License");
+     you may not use this file except in compliance with the License.
+     You may obtain a copy of the License at
+
+          http://www.apache.org/licenses/LICENSE-2.0
+
+     Unless required by applicable law or agreed to in writing, software
+     distributed under the License is distributed on an "AS IS" BASIS,
+     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+     See the License for the specific language governing permissions and
+     limitations under the License.
+-->
+
+<selector xmlns:android="http://schemas.android.com/apk/res/android">
+    <item android:state_pressed="true" android:drawable="@drawable/hotseat_phone_pressed" />
+    <item android:state_focused="true" android:state_window_focused="true" android:drawable="@drawable/hotseat_phone_focused" />
+    <item android:state_focused="true" android:state_window_focused="false" android:drawable="@drawable/hotseat_phone_normal" />
+    <item android:drawable="@drawable/hotseat_phone_normal" />
+</selector>
+
diff --git a/res/layout-land/launcher.xml b/res/layout-land/launcher.xml
index 44e1cfb..22b4825 100644
--- a/res/layout-land/launcher.xml
+++ b/res/layout-land/launcher.xml
@@ -75,24 +75,11 @@
         android:focusable="true"
         android:clickable="true" />
 
-    <com.android.launcher2.HandleView
-        android:id="@+id/all_apps_button"
-        android:layout_width="@dimen/button_bar_height"
-        android:layout_height="wrap_content"
-        android:layout_gravity="right|center_vertical"
-
-        android:focusable="true"
-        android:clickable="true"
-
-        android:scaleType="center"
-        android:src="@drawable/all_apps_button"
-        launcher:direction="vertical"
-        />
-
     <com.android.launcher2.DeleteZone
         android:id="@+id/delete_zone"
-        android:layout_width="@dimen/button_bar_height"
+        android:layout_width="@dimen/button_bar_height_portrait"
         android:layout_height="match_parent"
+        android:layout_marginBottom="@dimen/half_status_bar_height"
         android:layout_gravity="right|center_vertical"
 
         android:scaleType="center"
@@ -101,4 +88,43 @@
         launcher:direction="vertical"
         />
 
+    <RelativeLayout
+        android:id="@+id/all_apps_button_cluster"
+        android:layout_height="fill_parent"
+        android:layout_width="@dimen/button_bar_height_portrait"
+        android:layout_gravity="right|center_vertical"
+        android:layout_marginBottom="@dimen/half_status_bar_height"
+        android:padding="4dip"
+        >
+
+        <com.android.launcher2.HandleView
+            style="@style/HotseatButton"
+            android:id="@+id/all_apps_button"
+            android:layout_centerInParent="true"
+
+            android:src="@drawable/all_apps_button"
+            launcher:direction="vertical"
+            />
+
+        <ImageView
+            android:id="@+id/hotseat_left"
+            style="@style/HotseatButton.Left"
+            android:layout_below="@id/all_apps_button"
+
+            android:src="@drawable/hotseat_phone"
+
+            android:onClick="launchHotSeat"
+            />
+
+        <ImageView
+            android:id="@+id/hotseat_right"
+            style="@style/HotseatButton.Right"
+            android:layout_above="@id/all_apps_button"
+
+            android:src="@drawable/hotseat_browser"
+
+            android:onClick="launchHotSeat"
+            />
+
+    </RelativeLayout>
 </com.android.launcher2.DragLayer>
diff --git a/res/layout-port/launcher.xml b/res/layout-port/launcher.xml
index b1b1736..3b181d1 100644
--- a/res/layout-port/launcher.xml
+++ b/res/layout-port/launcher.xml
@@ -63,26 +63,12 @@
 
         android:scaleType="center"
         android:src="@drawable/home_arrows_right"
-        
+
         android:onClick="nextScreen"
-        
+
         android:focusable="true"
         android:clickable="true" />
 
-    <com.android.launcher2.HandleView
-        android:id="@+id/all_apps_button"
-        android:layout_width="wrap_content"
-        android:layout_height="@dimen/button_bar_height"
-        android:layout_gravity="bottom|center_horizontal"
-
-        android:focusable="true"
-        android:clickable="true"
-
-        android:scaleType="center"
-        android:src="@drawable/all_apps_button"
-        launcher:direction="horizontal"
-        />
-
     <com.android.launcher2.DeleteZone
         android:id="@+id/delete_zone"
         android:layout_width="wrap_content"
@@ -95,4 +81,43 @@
         launcher:direction="horizontal"
         />
 
+    <RelativeLayout
+        android:id="@+id/all_apps_button_cluster"
+        android:layout_width="fill_parent"
+        android:layout_height="@dimen/button_bar_height"
+        android:layout_gravity="bottom|center_horizontal"
+        android:padding="4dip"
+        >
+
+        <com.android.launcher2.HandleView
+            style="@style/HotseatButton"
+            android:id="@+id/all_apps_button"
+            android:layout_centerInParent="true"
+
+            android:src="@drawable/all_apps_button"
+            launcher:direction="horizontal"
+            />
+
+        <ImageView
+            android:id="@+id/hotseat_left"
+            style="@style/HotseatButton.Left"
+            android:layout_toLeftOf="@id/all_apps_button"
+
+            android:src="@drawable/hotseat_phone"
+
+            android:onClick="launchHotSeat"
+            />
+
+        <ImageView
+            android:id="@+id/hotseat_right"
+            style="@style/HotseatButton.Right"
+            android:layout_toRightOf="@id/all_apps_button"
+
+            android:src="@drawable/hotseat_browser"
+
+            android:onClick="launchHotSeat"
+            />
+
+    </RelativeLayout>
+
 </com.android.launcher2.DragLayer>
diff --git a/res/values-land/styles.xml b/res/values-land/styles.xml
new file mode 100644
index 0000000..251c717
--- /dev/null
+++ b/res/values-land/styles.xml
@@ -0,0 +1,41 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+/*
+* Copyright (C) 2008 The Android Open Source Project
+*
+* Licensed under the Apache License, Version 2.0 (the "License");
+* you may not use this file except in compliance with the License.
+* You may obtain a copy of the License at
+*
+*      http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.
+*/
+-->
+
+<resources>
+    <style name="HotseatButton">
+        <item name="android:paddingTop">12dip</item>
+        <item name="android:paddingBottom">12dip</item>
+        <item name="android:background">@drawable/hotseat_bg_center</item>
+        <item name="android:layout_height">wrap_content</item>
+        <item name="android:layout_width">fill_parent</item>
+        <item name="android:scaleType">center</item>
+        <item name="android:focusable">true</item>
+        <item name="android:clickable">true</item>
+    </style>
+    <style name="HotseatButton.Left">
+        <item name="android:layout_marginBottom">4dip</item>
+        <item name="android:background">@drawable/hotseat_bg_left</item>
+    </style>
+    <style name="HotseatButton.Right">
+        <item name="android:layout_marginTop">4dip</item>
+        <item name="android:background">@drawable/hotseat_bg_right</item>
+    </style>
+
+</resources>
+
diff --git a/res/values/dimens.xml b/res/values/dimens.xml
index 132a1ce..5e3bb98 100644
--- a/res/values/dimens.xml
+++ b/res/values/dimens.xml
@@ -16,5 +16,15 @@
 
 <resources>
     <dimen name="title_texture_width">120px</dimen>
+
+    <!-- height of the bottom row of controls -->
     <dimen name="button_bar_height">56dip</dimen>
+
+    <!-- so we have access to this dimension in landscape mode even though
+         button_bar_height changes -->
+    <dimen name="button_bar_height_portrait">56dip</dimen>
+
+    <!-- roughly half a status bar (for vertically centering the right-hand
+         button cluster in landscape) -->
+    <dimen name="half_status_bar_height">12dip</dimen>
 </resources>
diff --git a/res/values/styles.xml b/res/values/styles.xml
index f90810f..c208211 100644
--- a/res/values/styles.xml
+++ b/res/values/styles.xml
@@ -65,4 +65,23 @@
         <item name="android:paddingRight">10dip</item>
     </style>
 
+    <style name="HotseatButton">
+        <item name="android:paddingLeft">12dip</item>
+        <item name="android:paddingRight">12dip</item>
+        <item name="android:background">@drawable/hotseat_bg_center</item>
+        <item name="android:layout_width">wrap_content</item>
+        <item name="android:layout_height">fill_parent</item>
+        <item name="android:scaleType">center</item>
+        <item name="android:focusable">true</item>
+        <item name="android:clickable">true</item>
+    </style>
+    <style name="HotseatButton.Left">
+        <item name="android:layout_marginLeft">4dip</item>
+        <item name="android:background">@drawable/hotseat_bg_left</item>
+    </style>
+    <style name="HotseatButton.Right">
+        <item name="android:layout_marginRight">4dip</item>
+        <item name="android:background">@drawable/hotseat_bg_right</item>
+    </style>
+
 </resources>
diff --git a/src/com/android/launcher2/DeleteZone.java b/src/com/android/launcher2/DeleteZone.java
index 9065de4..3a6c63d 100644
--- a/src/com/android/launcher2/DeleteZone.java
+++ b/src/com/android/launcher2/DeleteZone.java
@@ -183,15 +183,7 @@
             animationSet.setDuration(ANIMATION_DURATION);
         }
         if (mHandleInAnimation == null) {
-            if (mOrientation == ORIENTATION_HORIZONTAL) {
-                mHandleInAnimation = new TranslateAnimation(Animation.ABSOLUTE, 0.0f,
-                        Animation.ABSOLUTE, 0.0f, Animation.RELATIVE_TO_SELF, 1.0f,
-                        Animation.RELATIVE_TO_SELF, 0.0f);
-            } else {
-                mHandleInAnimation = new TranslateAnimation(Animation.RELATIVE_TO_SELF,
-                        1.0f, Animation.RELATIVE_TO_SELF, 0.0f, Animation.ABSOLUTE, 0.0f,
-                        Animation.ABSOLUTE, 0.0f);
-            }
+            mHandleInAnimation = new AlphaAnimation(0.0f, 1.0f);
             mHandleInAnimation.setDuration(ANIMATION_DURATION);
         }
         if (mOutAnimation == null) {
@@ -211,15 +203,7 @@
             animationSet.setDuration(ANIMATION_DURATION);
         }
         if (mHandleOutAnimation == null) {
-            if (mOrientation == ORIENTATION_HORIZONTAL) {
-                mHandleOutAnimation = new FastTranslateAnimation(Animation.ABSOLUTE, 0.0f,
-                        Animation.ABSOLUTE, 0.0f, Animation.RELATIVE_TO_SELF, 0.0f,
-                        Animation.RELATIVE_TO_SELF, 1.0f);
-            } else {
-                mHandleOutAnimation = new FastTranslateAnimation(Animation.RELATIVE_TO_SELF,
-                        0.0f, Animation.RELATIVE_TO_SELF, 1.0f, Animation.ABSOLUTE, 0.0f,
-                        Animation.ABSOLUTE, 0.0f);
-            }
+            mHandleOutAnimation = new AlphaAnimation(1.0f, 0.0f);
             mHandleOutAnimation.setFillAfter(true);
             mHandleOutAnimation.setDuration(ANIMATION_DURATION);
         }
diff --git a/src/com/android/launcher2/Launcher.java b/src/com/android/launcher2/Launcher.java
index 868a9d1..5a2a7d3 100644
--- a/src/com/android/launcher2/Launcher.java
+++ b/src/com/android/launcher2/Launcher.java
@@ -26,12 +26,14 @@
 import android.app.WallpaperManager;
 import android.content.ActivityNotFoundException;
 import android.content.BroadcastReceiver;
+import android.content.ComponentName;
 import android.content.ContentResolver;
 import android.content.Context;
 import android.content.DialogInterface;
 import android.content.Intent;
 import android.content.Intent.ShortcutIconResource;
 import android.content.IntentFilter;
+import android.content.pm.ActivityInfo;
 import android.content.pm.PackageManager;
 import android.content.res.Configuration;
 import android.content.res.Resources;
@@ -41,6 +43,7 @@
 import android.graphics.Canvas;
 import android.graphics.drawable.Drawable;
 import android.graphics.drawable.ColorDrawable;
+import android.net.Uri;
 import android.os.Bundle;
 import android.os.Handler;
 import android.os.Parcelable;
@@ -197,6 +200,17 @@
     private ImageView mPreviousView;
     private ImageView mNextView;
 
+    // Hotseats (quick-launch icons next to AllApps)
+    // TODO: move these intial intents out to Uris in an XML resource
+    private static final int NUM_HOTSEATS = 2;
+    private Intent[] mHotseats = new Intent[] {
+        new Intent(Intent.ACTION_MAIN)
+            .setComponent(ComponentName.unflattenFromString(
+                "com.android.contacts/.ContactsLaunchActivity")),
+        new Intent(Intent.ACTION_WEB_SEARCH, Uri.EMPTY),
+    };
+    private CharSequence[] mHotseatLabels = new CharSequence[2];
+
     @Override
     protected void onCreate(Bundle savedInstanceState) {
         super.onCreate(savedInstanceState);
@@ -215,6 +229,7 @@
             android.os.Debug.startMethodTracing("/sdcard/launcher");
         }
 
+        loadHotseats();
         checkForLocaleChange();
         setWallpaperDimension();
 
@@ -273,6 +288,8 @@
 
             writeConfiguration(this, localeConfiguration);
             mIconCache.flush();
+
+            loadHotseats();
         }
     }
 
@@ -351,6 +368,44 @@
         wpm.suggestDesiredDimensions(width * WALLPAPER_SCREENS_SPAN, height);
     }
 
+    private void loadHotseats() {
+        PackageManager pm = getPackageManager();
+        for (int i=0; i<mHotseats.length; i++) {
+            Intent intent = mHotseats[i];
+
+            if (LOGD) {
+                Log.d(TAG, "loadHotseats: hotseat " + i 
+                    + " initial intent=[" + intent.toUri(Intent.URI_INTENT_SCHEME)
+                    + "]");
+            }
+
+            // fix up the default intents
+            if (intent.getAction().equals(Intent.ACTION_WEB_SEARCH)
+                    && intent.getData().equals(Uri.EMPTY)) {
+                // use this to represent "default web browser"
+                intent = new Intent(Intent.ACTION_VIEW, Uri.parse("http://www.google.com/"));
+            }
+            ComponentName com = intent.resolveActivity(pm);
+            mHotseats[i] = new Intent(Intent.ACTION_MAIN).setComponent(com);
+
+            // load the labels for accessibility
+            try {
+                ActivityInfo ai = pm.getActivityInfo(com, 0);
+                mHotseatLabels[i] = ai.loadLabel(pm);
+            } catch (PackageManager.NameNotFoundException ex) {
+                mHotseatLabels[i] = "";
+            }
+
+            if (LOGD) {
+                Log.d(TAG, "loadHotseats: hotseat " + i 
+                    + " intent=[" + mHotseats[i].toUri(Intent.URI_INTENT_SCHEME)
+                    + "] label=[" + mHotseatLabels[i]
+                    + "]"
+                    );
+            }
+        }
+    }
+
     @Override
     protected void onActivityResult(int requestCode, int resultCode, Intent data) {
         mWaitingForResult = false;
@@ -567,6 +622,9 @@
         mHandleView.setOnClickListener(this);
         mHandleView.setOnLongClickListener(this);
 
+        findViewById(R.id.hotseat_left).setContentDescription(mHotseatLabels[0]);
+        findViewById(R.id.hotseat_right).setContentDescription(mHotseatLabels[1]);
+
         mPreviousView = (ImageView) dragLayer.findViewById(R.id.previous_screen);
         mNextView = (ImageView) dragLayer.findViewById(R.id.next_screen);
 
@@ -585,7 +643,7 @@
 
         deleteZone.setLauncher(this);
         deleteZone.setDragController(dragController);
-        deleteZone.setHandle(mHandleView);
+        deleteZone.setHandle(findViewById(R.id.all_apps_button_cluster));
 
         dragController.setDragScoller(workspace);
         dragController.setDragListener(deleteZone);
@@ -610,6 +668,23 @@
             mWorkspace.scrollRight();
         }
     }
+
+    @SuppressWarnings({"UnusedDeclaration"})
+    public void launchHotSeat(View v) {
+        int index = -1;
+        if (v.getId() == R.id.hotseat_left) {
+            index = 0;
+        } else if (v.getId() == R.id.hotseat_right) {
+            index = 1;
+        }
+
+        if (index >= 0 && mHotseats[index] != null) {
+            startActivitySafely(
+                mHotseats[index],
+                "hotseat"
+            );
+        }
+    }
     
     /**
      * Creates a view representing a shortcut.
@@ -1280,7 +1355,7 @@
             startActivity(intent);
         } catch (ActivityNotFoundException e) {
             Toast.makeText(this, R.string.activity_not_found, Toast.LENGTH_SHORT).show();
-            Log.e(TAG, "Unable to launch. tag=" + tag + " intent=" + intent);
+            Log.e(TAG, "Unable to launch. tag=" + tag + " intent=" + intent, e);
         } catch (SecurityException e) {
             Toast.makeText(this, R.string.activity_not_found, Toast.LENGTH_SHORT).show();
             Log.e(TAG, "Launcher does not have the permission to launch " + intent +