Merge "Implementing group renaming and deletion"
diff --git a/res/anim/quickcontact.xml b/res/anim/quickcontact.xml
deleted file mode 100644
index 5dd5a16..0000000
--- a/res/anim/quickcontact.xml
+++ /dev/null
@@ -1,7 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-
-<translate
-    xmlns:android="http://schemas.android.com/apk/res/android"
-    android:fromXDelta="100%p"
-    android:toXDelta="0"
-    android:duration="325" />
diff --git a/res/drawable-hdpi/quickactions_arrowdown_left_holo_light.9.png b/res/drawable-hdpi/quickactions_arrowdown_left_holo_light.9.png
new file mode 100644
index 0000000..b09016b
--- /dev/null
+++ b/res/drawable-hdpi/quickactions_arrowdown_left_holo_light.9.png
Binary files differ
diff --git a/res/drawable-hdpi/quickactions_arrowdown_middle_holo_light.9.png b/res/drawable-hdpi/quickactions_arrowdown_middle_holo_light.9.png
new file mode 100644
index 0000000..670d89f
--- /dev/null
+++ b/res/drawable-hdpi/quickactions_arrowdown_middle_holo_light.9.png
Binary files differ
diff --git a/res/drawable-hdpi/quickactions_arrowdown_right_holo_light.9.png b/res/drawable-hdpi/quickactions_arrowdown_right_holo_light.9.png
new file mode 100644
index 0000000..81f4859
--- /dev/null
+++ b/res/drawable-hdpi/quickactions_arrowdown_right_holo_light.9.png
Binary files differ
diff --git a/res/drawable-hdpi/quickactions_arrowup_left_holo_light.9.png b/res/drawable-hdpi/quickactions_arrowup_left_holo_light.9.png
new file mode 100644
index 0000000..99ad9e2
--- /dev/null
+++ b/res/drawable-hdpi/quickactions_arrowup_left_holo_light.9.png
Binary files differ
diff --git a/res/drawable-hdpi/quickactions_arrowup_middle_holo_light.9.png b/res/drawable-hdpi/quickactions_arrowup_middle_holo_light.9.png
new file mode 100644
index 0000000..500d820
--- /dev/null
+++ b/res/drawable-hdpi/quickactions_arrowup_middle_holo_light.9.png
Binary files differ
diff --git a/res/drawable-hdpi/quickactions_arrowup_right_holo_light.9.png b/res/drawable-hdpi/quickactions_arrowup_right_holo_light.9.png
new file mode 100644
index 0000000..d99058b
--- /dev/null
+++ b/res/drawable-hdpi/quickactions_arrowup_right_holo_light.9.png
Binary files differ
diff --git a/res/drawable-hdpi/quickcontact_arrow_down.png b/res/drawable-hdpi/quickcontact_arrow_down.png
deleted file mode 100644
index 7eba756..0000000
--- a/res/drawable-hdpi/quickcontact_arrow_down.png
+++ /dev/null
Binary files differ
diff --git a/res/drawable-hdpi/quickcontact_arrow_up.png b/res/drawable-hdpi/quickcontact_arrow_up.png
deleted file mode 100644
index 6daf90a..0000000
--- a/res/drawable-hdpi/quickcontact_arrow_up.png
+++ /dev/null
Binary files differ
diff --git a/res/drawable-hdpi/quickcontact_bottom_frame.9.png b/res/drawable-hdpi/quickcontact_bottom_frame.9.png
deleted file mode 100644
index 9fac225..0000000
--- a/res/drawable-hdpi/quickcontact_bottom_frame.9.png
+++ /dev/null
Binary files differ
diff --git a/res/drawable-hdpi/quickcontact_disambig_bottom_bg.9.png b/res/drawable-hdpi/quickcontact_disambig_bottom_bg.9.png
deleted file mode 100644
index 4702f16..0000000
--- a/res/drawable-hdpi/quickcontact_disambig_bottom_bg.9.png
+++ /dev/null
Binary files differ
diff --git a/res/drawable-hdpi/quickcontact_disambig_checkbox_off.png b/res/drawable-hdpi/quickcontact_disambig_checkbox_off.png
deleted file mode 100644
index f87572c..0000000
--- a/res/drawable-hdpi/quickcontact_disambig_checkbox_off.png
+++ /dev/null
Binary files differ
diff --git a/res/drawable-hdpi/quickcontact_disambig_checkbox_on.png b/res/drawable-hdpi/quickcontact_disambig_checkbox_on.png
deleted file mode 100644
index 3ea5360..0000000
--- a/res/drawable-hdpi/quickcontact_disambig_checkbox_on.png
+++ /dev/null
Binary files differ
diff --git a/res/drawable-hdpi/quickcontact_disambig_divider.9.png b/res/drawable-hdpi/quickcontact_disambig_divider.9.png
deleted file mode 100644
index 8c35e8c..0000000
--- a/res/drawable-hdpi/quickcontact_disambig_divider.9.png
+++ /dev/null
Binary files differ
diff --git a/res/drawable-hdpi/quickcontact_drop_shadow.9.png b/res/drawable-hdpi/quickcontact_drop_shadow.9.png
deleted file mode 100644
index 0dcf076..0000000
--- a/res/drawable-hdpi/quickcontact_drop_shadow.9.png
+++ /dev/null
Binary files differ
diff --git a/res/drawable-hdpi/quickcontact_photo_frame.9.png b/res/drawable-hdpi/quickcontact_photo_frame.9.png
deleted file mode 100644
index 990c75d..0000000
--- a/res/drawable-hdpi/quickcontact_photo_frame.9.png
+++ /dev/null
Binary files differ
diff --git a/res/drawable-hdpi/quickcontact_slider_background.png b/res/drawable-hdpi/quickcontact_slider_background.png
deleted file mode 100644
index c9c09ee..0000000
--- a/res/drawable-hdpi/quickcontact_slider_background.png
+++ /dev/null
Binary files differ
diff --git a/res/drawable-hdpi/quickcontact_slider_btn_normal.9.png b/res/drawable-hdpi/quickcontact_slider_btn_normal.9.png
deleted file mode 100644
index 9d3d7ad..0000000
--- a/res/drawable-hdpi/quickcontact_slider_btn_normal.9.png
+++ /dev/null
Binary files differ
diff --git a/res/drawable-hdpi/quickcontact_slider_grip_left.png b/res/drawable-hdpi/quickcontact_slider_grip_left.png
deleted file mode 100644
index 97f12aa..0000000
--- a/res/drawable-hdpi/quickcontact_slider_grip_left.png
+++ /dev/null
Binary files differ
diff --git a/res/drawable-hdpi/quickcontact_slider_grip_right.png b/res/drawable-hdpi/quickcontact_slider_grip_right.png
deleted file mode 100644
index e410059..0000000
--- a/res/drawable-hdpi/quickcontact_slider_grip_right.png
+++ /dev/null
Binary files differ
diff --git a/res/drawable-hdpi/quickcontact_top_frame.9.png b/res/drawable-hdpi/quickcontact_top_frame.9.png
deleted file mode 100644
index 4556bb2..0000000
--- a/res/drawable-hdpi/quickcontact_top_frame.9.png
+++ /dev/null
Binary files differ
diff --git a/res/drawable-mdpi/quickactions_arrowdown_left_holo_light.9.png b/res/drawable-mdpi/quickactions_arrowdown_left_holo_light.9.png
new file mode 100644
index 0000000..bd43850
--- /dev/null
+++ b/res/drawable-mdpi/quickactions_arrowdown_left_holo_light.9.png
Binary files differ
diff --git a/res/drawable-mdpi/quickactions_arrowdown_middle_holo_light.9.png b/res/drawable-mdpi/quickactions_arrowdown_middle_holo_light.9.png
new file mode 100644
index 0000000..c284dbb
--- /dev/null
+++ b/res/drawable-mdpi/quickactions_arrowdown_middle_holo_light.9.png
Binary files differ
diff --git a/res/drawable-mdpi/quickactions_arrowdown_right_holo_light.9.png b/res/drawable-mdpi/quickactions_arrowdown_right_holo_light.9.png
new file mode 100644
index 0000000..c057f71
--- /dev/null
+++ b/res/drawable-mdpi/quickactions_arrowdown_right_holo_light.9.png
Binary files differ
diff --git a/res/drawable-mdpi/quickactions_arrowup_left_holo_light.9.png b/res/drawable-mdpi/quickactions_arrowup_left_holo_light.9.png
new file mode 100644
index 0000000..85d092f
--- /dev/null
+++ b/res/drawable-mdpi/quickactions_arrowup_left_holo_light.9.png
Binary files differ
diff --git a/res/drawable-mdpi/quickactions_arrowup_middle_holo_light.9.png b/res/drawable-mdpi/quickactions_arrowup_middle_holo_light.9.png
new file mode 100644
index 0000000..828b718
--- /dev/null
+++ b/res/drawable-mdpi/quickactions_arrowup_middle_holo_light.9.png
Binary files differ
diff --git a/res/drawable-mdpi/quickactions_arrowup_right_holo_light.9.png b/res/drawable-mdpi/quickactions_arrowup_right_holo_light.9.png
new file mode 100644
index 0000000..e4994b4
--- /dev/null
+++ b/res/drawable-mdpi/quickactions_arrowup_right_holo_light.9.png
Binary files differ
diff --git a/res/drawable-mdpi/quickcontact_arrow_down.png b/res/drawable-mdpi/quickcontact_arrow_down.png
deleted file mode 100644
index 3ba6c8c..0000000
--- a/res/drawable-mdpi/quickcontact_arrow_down.png
+++ /dev/null
Binary files differ
diff --git a/res/drawable-mdpi/quickcontact_arrow_up.png b/res/drawable-mdpi/quickcontact_arrow_up.png
deleted file mode 100644
index 1a6fa2e..0000000
--- a/res/drawable-mdpi/quickcontact_arrow_up.png
+++ /dev/null
Binary files differ
diff --git a/res/drawable-mdpi/quickcontact_bottom_frame.9.png b/res/drawable-mdpi/quickcontact_bottom_frame.9.png
deleted file mode 100644
index 6f84306..0000000
--- a/res/drawable-mdpi/quickcontact_bottom_frame.9.png
+++ /dev/null
Binary files differ
diff --git a/res/drawable-mdpi/quickcontact_disambig_bottom_bg.9.png b/res/drawable-mdpi/quickcontact_disambig_bottom_bg.9.png
deleted file mode 100644
index bbc2075..0000000
--- a/res/drawable-mdpi/quickcontact_disambig_bottom_bg.9.png
+++ /dev/null
Binary files differ
diff --git a/res/drawable-mdpi/quickcontact_disambig_checkbox_off.png b/res/drawable-mdpi/quickcontact_disambig_checkbox_off.png
deleted file mode 100644
index 7e51863..0000000
--- a/res/drawable-mdpi/quickcontact_disambig_checkbox_off.png
+++ /dev/null
Binary files differ
diff --git a/res/drawable-mdpi/quickcontact_disambig_checkbox_on.png b/res/drawable-mdpi/quickcontact_disambig_checkbox_on.png
deleted file mode 100644
index 93c06aa..0000000
--- a/res/drawable-mdpi/quickcontact_disambig_checkbox_on.png
+++ /dev/null
Binary files differ
diff --git a/res/drawable-mdpi/quickcontact_disambig_divider.9.png b/res/drawable-mdpi/quickcontact_disambig_divider.9.png
deleted file mode 100644
index 8c35e8c..0000000
--- a/res/drawable-mdpi/quickcontact_disambig_divider.9.png
+++ /dev/null
Binary files differ
diff --git a/res/drawable-mdpi/quickcontact_drop_shadow.9.png b/res/drawable-mdpi/quickcontact_drop_shadow.9.png
deleted file mode 100644
index 2d20076..0000000
--- a/res/drawable-mdpi/quickcontact_drop_shadow.9.png
+++ /dev/null
Binary files differ
diff --git a/res/drawable-mdpi/quickcontact_photo_frame.9.png b/res/drawable-mdpi/quickcontact_photo_frame.9.png
deleted file mode 100644
index a509c30..0000000
--- a/res/drawable-mdpi/quickcontact_photo_frame.9.png
+++ /dev/null
Binary files differ
diff --git a/res/drawable-mdpi/quickcontact_slider_background.png b/res/drawable-mdpi/quickcontact_slider_background.png
deleted file mode 100644
index b6a9f91..0000000
--- a/res/drawable-mdpi/quickcontact_slider_background.png
+++ /dev/null
Binary files differ
diff --git a/res/drawable-mdpi/quickcontact_slider_btn_normal.9.png b/res/drawable-mdpi/quickcontact_slider_btn_normal.9.png
deleted file mode 100644
index cf4f1e4..0000000
--- a/res/drawable-mdpi/quickcontact_slider_btn_normal.9.png
+++ /dev/null
Binary files differ
diff --git a/res/drawable-mdpi/quickcontact_slider_grip_left.png b/res/drawable-mdpi/quickcontact_slider_grip_left.png
deleted file mode 100644
index 337b2fc..0000000
--- a/res/drawable-mdpi/quickcontact_slider_grip_left.png
+++ /dev/null
Binary files differ
diff --git a/res/drawable-mdpi/quickcontact_slider_grip_right.png b/res/drawable-mdpi/quickcontact_slider_grip_right.png
deleted file mode 100644
index 1e222c3..0000000
--- a/res/drawable-mdpi/quickcontact_slider_grip_right.png
+++ /dev/null
Binary files differ
diff --git a/res/drawable-mdpi/quickcontact_top_frame.9.png b/res/drawable-mdpi/quickcontact_top_frame.9.png
deleted file mode 100644
index 6d43305..0000000
--- a/res/drawable-mdpi/quickcontact_top_frame.9.png
+++ /dev/null
Binary files differ
diff --git a/res/drawable/quickcontact_disambig_checkbox.xml b/res/drawable/quickcontact_disambig_checkbox.xml
deleted file mode 100644
index 4add69c..0000000
--- a/res/drawable/quickcontact_disambig_checkbox.xml
+++ /dev/null
@@ -1,25 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!-- Copyright (C) 2009 The Android Open Source Project
-
-     Licensed under the Apache License, Version 2.0 (the "License");
-     you may not use this file except in compliance with the License.
-     You may obtain a copy of the License at
-
-          http://www.apache.org/licenses/LICENSE-2.0
-
-     Unless required by applicable law or agreed to in writing, software
-     distributed under the License is distributed on an "AS IS" BASIS,
-     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-     See the License for the specific language governing permissions and
-     limitations under the License.
--->
-
-<selector xmlns:android="http://schemas.android.com/apk/res/android"
-    android:dither="true">
-
-    <item android:state_checked="true"
-        android:drawable="@drawable/quickcontact_disambig_checkbox_on" />
-    <item
-        android:drawable="@drawable/quickcontact_disambig_checkbox_off" />
-
-</selector>
diff --git a/res/drawable/quickcontact_slider_btn.xml b/res/drawable/quickcontact_slider_btn.xml
index a1be8f4..f6164df 100644
--- a/res/drawable/quickcontact_slider_btn.xml
+++ b/res/drawable/quickcontact_slider_btn.xml
@@ -16,16 +16,15 @@
 
 <selector xmlns:android="http://schemas.android.com/apk/res/android"
     android:dither="true">
-
+    <!-- TODO: We should be using framework resources here once they are finished -->
     <item android:state_checked="true"
         android:drawable="@drawable/quickcontact_slider_btn_on" />
     <item android:state_window_focused="false"
-        android:drawable="@drawable/quickcontact_slider_btn_normal" />
+        android:drawable="@android:color/transparent" />
     <item android:state_pressed="true"
         android:drawable="@drawable/quickcontact_slider_btn_pressed" />
     <item android:state_focused="true"
         android:drawable="@drawable/quickcontact_slider_btn_selected" />
     <item
-        android:drawable="@drawable/quickcontact_slider_btn_normal" />
-
+        android:drawable="@android:color/transparent" />
 </selector>
diff --git a/res/layout-finger/quickcontact_item_nodata.xml b/res/layout-finger/quickcontact_item_nodata.xml
index 5215e30..5f951e2 100644
--- a/res/layout-finger/quickcontact_item_nodata.xml
+++ b/res/layout-finger/quickcontact_item_nodata.xml
@@ -24,6 +24,5 @@
     android:focusable="false"
     android:clickable="false"
     android:gravity="center_vertical"
-    android:background="@drawable/quickcontact_slider_btn_normal"
     android:textColor="@android:color/black"
     android:text="@string/quickcontact_no_data" />
diff --git a/res/layout/quickcontact.xml b/res/layout/quickcontact.xml
index 34bbc9a..94b09df 100644
--- a/res/layout/quickcontact.xml
+++ b/res/layout/quickcontact.xml
@@ -1,4 +1,3 @@
-<?xml version="1.0" encoding="utf-8"?>
 <!-- Copyright (C) 2009 The Android Open Source Project
 
      Licensed under the Apache License, Version 2.0 (the "License");
@@ -16,13 +15,11 @@
 
 <view
     xmlns:android="http://schemas.android.com/apk/res/android"
-    class="com.android.contacts.quickcontact.QuickContactWindow$RootLayout"
+    class="com.android.contacts.quickcontact.QuickContactRootLayout"
     android:id="@+id/root"
     android:layout_width="match_parent"
     android:layout_height="wrap_content"
-    android:paddingLeft="@dimen/quickcontact_shadow_horiz"
-    android:paddingRight="@dimen/quickcontact_shadow_horiz"
-    android:background="@drawable/quickcontact_drop_shadow">
+    android:orientation="vertical">
 
     <FrameLayout
         android:id="@+id/header"
@@ -57,46 +54,24 @@
         android:id="@+id/scroll"
         android:layout_width="match_parent"
         android:layout_height="wrap_content"
-        android:layout_below="@id/header"
+        android:layout_marginTop="5dip"
+        android:layout_marginLeft="15dip"
+        android:layout_marginRight="15dip"
+        android:layout_marginBottom="10dip"
         android:fadingEdgeLength="0dip"
-        android:background="@drawable/quickcontact_slider_background"
         android:scrollbars="none">
 
         <LinearLayout
             android:id="@+id/quickcontact"
             android:layout_width="wrap_content"
             android:layout_height="wrap_content"
-            android:paddingTop="4dip"
-            android:paddingBottom="4dip"
-            android:orientation="horizontal">
-
-            <ImageView
-                android:layout_width="wrap_content"
-                android:layout_height="wrap_content"
-                android:src="@drawable/quickcontact_slider_grip_left" />
-
-            <ImageView
-                android:layout_width="wrap_content"
-                android:layout_height="wrap_content"
-                android:src="@drawable/quickcontact_slider_grip_right" />
-
-        </LinearLayout>
-
+            android:orientation="horizontal" />
     </HorizontalScrollView>
 
-    <FrameLayout
-        android:id="@+id/footer"
-        android:layout_width="match_parent"
-        android:layout_height="wrap_content"
-        android:layout_below="@id/scroll"
-        android:background="@drawable/quickcontact_bottom_frame" />
-
     <LinearLayout
         android:id="@+id/footer_disambig"
         android:layout_width="match_parent"
         android:layout_height="wrap_content"
-        android:layout_below="@id/scroll"
-        android:background="@drawable/quickcontact_disambig_bottom_bg"
         android:orientation="vertical"
         android:visibility="gone">
 
@@ -105,8 +80,8 @@
             android:layout_width="match_parent"
             android:layout_height="0dip"
             android:layout_weight="1"
-            android:background="@color/quickcontact_disambig"
-            android:divider="@drawable/quickcontact_disambig_divider"
+            android:layout_marginLeft="5dip"
+            android:layout_marginRight="5dip"
             android:cacheColorHint="@null" />
 
         <CheckBox
@@ -119,32 +94,7 @@
             android:textColor="#f000"
             android:textStyle="bold"
             android:text="@string/quickcontact_remember_choice"
-            android:textAppearance="?android:attr/textAppearanceSmallInverse"
-            android:button="@drawable/quickcontact_disambig_checkbox" />
+            android:textAppearance="?android:attr/textAppearanceSmallInverse" />
 
     </LinearLayout>
-
-    <ImageView
-        android:id="@+id/arrow_up"
-        android:layout_width="wrap_content"
-        android:layout_height="wrap_content"
-        android:src="@drawable/quickcontact_arrow_up" />
-
-    <ImageView
-        android:id="@+id/arrow_down"
-        android:layout_width="wrap_content"
-        android:layout_height="wrap_content"
-        android:layout_marginTop="-1dip"
-        android:layout_below="@id/footer"
-        android:src="@drawable/quickcontact_arrow_down" />
-
-    <ImageView
-        android:id="@+id/arrow_down_stub"
-        android:layout_width="wrap_content"
-        android:layout_height="wrap_content"
-        android:layout_marginTop="-1dip"
-        android:layout_below="@id/footer_disambig"
-        android:visibility="invisible"
-        android:src="@drawable/quickcontact_arrow_down" />
-
 </view>
diff --git a/res/layout/quickcontact_header_large.xml b/res/layout/quickcontact_header_large.xml
index d9d4875..18acbe1 100644
--- a/res/layout/quickcontact_header_large.xml
+++ b/res/layout/quickcontact_header_large.xml
@@ -20,16 +20,14 @@
     android:layout_width="match_parent"
     android:layout_height="wrap_content"
     android:minHeight="87dip"
-    android:background="@drawable/quickcontact_top_frame"
     android:gravity="center_vertical"
     android:orientation="horizontal">
 
     <ImageView
         android:id="@+id/photo"
-        android:layout_width="54dip"
-        android:layout_height="57dip"
-        android:layout_marginLeft="15dip"
-        android:background="@drawable/quickcontact_photo_frame" />
+        android:layout_width="64dip"
+        android:layout_height="64dip"
+        android:layout_marginLeft="15dip" />
 
     <LinearLayout
         android:layout_width="0dip"
diff --git a/res/layout/quickcontact_header_med.xml b/res/layout/quickcontact_header_med.xml
index bed886d..77cb1a5 100644
--- a/res/layout/quickcontact_header_med.xml
+++ b/res/layout/quickcontact_header_med.xml
@@ -20,7 +20,6 @@
     android:layout_width="match_parent"
     android:layout_height="wrap_content"
     android:minHeight="51dip"
-    android:background="@drawable/quickcontact_top_frame"
     android:gravity="center_vertical"
     android:orientation="horizontal">
 
diff --git a/res/layout/quickcontact_header_small.xml b/res/layout/quickcontact_header_small.xml
index 9dfe0a1..f3a46d5 100644
--- a/res/layout/quickcontact_header_small.xml
+++ b/res/layout/quickcontact_header_small.xml
@@ -19,5 +19,4 @@
     android:id="@+id/header_small"
     android:layout_width="match_parent"
     android:layout_height="wrap_content"
-    android:background="@drawable/quickcontact_top_frame"
     android:orientation="horizontal" />
diff --git a/res/layout/quickcontact_resolve_item.xml b/res/layout/quickcontact_resolve_item.xml
index db683a0..55de80e 100755
--- a/res/layout/quickcontact_resolve_item.xml
+++ b/res/layout/quickcontact_resolve_item.xml
@@ -18,8 +18,8 @@
     android:layout_width="match_parent"
     android:layout_height="wrap_content"
     android:orientation="vertical"
-    android:paddingLeft="30dip"
-    android:paddingRight="30dip"
+    android:paddingLeft="25dip"
+    android:paddingRight="25dip"
     android:minHeight="?android:attr/listPreferredItemHeight"
     android:gravity="center_vertical">
 
diff --git a/res/values-xlarge/dimens.xml b/res/values-xlarge/dimens.xml
index b3925c0..12871f6 100644
--- a/res/values-xlarge/dimens.xml
+++ b/res/values-xlarge/dimens.xml
@@ -14,10 +14,6 @@
      limitations under the License.
 -->
 <resources>
-    <!-- Size of the text in the aizy visual scroll control -->
-    
-
     <dimen name="edit_photo_size">96dip</dimen>
-
     <dimen name="aggregation_suggestion_icon_size">64dip</dimen>
 </resources>
diff --git a/res/values/dimens.xml b/res/values/dimens.xml
index 29241ae..0916989 100644
--- a/res/values/dimens.xml
+++ b/res/values/dimens.xml
@@ -14,18 +14,14 @@
      limitations under the License.
 -->
 <resources>
-    <dimen name="quickcontact_shadow_horiz">30dip</dimen>
-    <dimen name="quickcontact_shadow_vert">37dip</dimen>
-    <dimen name="quickcontact_shadow_touch">20dip</dimen>
-
     <dimen name="edit_photo_size">76dip</dimen>
 
     <!-- The height of the ScrollingTabWidget -->
     <dimen name="tab_height">40dip</dimen>
     <dimen name="account_name_height">25dip</dimen>
 
-    <dimen name="contact_shortcut_frame_width">50dip</dimen>    
-    <dimen name="contact_shortcut_frame_height">56dip</dimen>    
+    <dimen name="contact_shortcut_frame_width">50dip</dimen>
+    <dimen name="contact_shortcut_frame_height">56dip</dimen>
 
     <dimen name="aggregation_suggestion_icon_size">40dip</dimen>
 
@@ -36,6 +32,11 @@
     <dimen name="aizy_preview_width">80dip</dimen>
     <dimen name="aizy_preview_height">80dip</dimen>
 
+    <!-- Width of the quick contact popup. This size is chosen so that the last icon is clipped
+    to indicate horizontal scrollability. Also, this size is the same as the widget to make them
+    aligned -->
+    <dimen name="quick_contact_width">352dip</dimen>
+
     <!-- Padding of the rounded plus/minus/expand/collapse buttons in the editor  -->
     <dimen name="editor_round_button_padding_left">10dip</dimen>
     <dimen name="editor_round_button_padding_right">10dip</dimen>
diff --git a/res/values/styles.xml b/res/values/styles.xml
index 914ebcc..c19ee5b 100644
--- a/res/values/styles.xml
+++ b/res/values/styles.xml
@@ -50,7 +50,8 @@
         <item name="android:windowAnimationStyle">@style/DummyAnimation</item>
     </style>
 
-    <style name="QuickContact">
+    <style name="QuickContact" parent="@android:Theme.Light.Holo">
+        <item name="android:windowNoTitle">true</item>
         <item name="android:windowFrame">@null</item>
         <item name="android:windowBackground">@android:color/transparent</item>
         <item name="android:windowIsFloating">true</item>
diff --git a/src/com/android/contacts/quickcontact/QuickContactActivity.java b/src/com/android/contacts/quickcontact/QuickContactActivity.java
index 97df680..7e5e1a0 100644
--- a/src/com/android/contacts/quickcontact/QuickContactActivity.java
+++ b/src/com/android/contacts/quickcontact/QuickContactActivity.java
@@ -103,6 +103,7 @@
     }
 
     /** {@inheritDoc} */
+    @Override
     public void onDismiss(QuickContactWindow dialog) {
         if (LOGV) Log.d(TAG, "onDismiss");
 
diff --git a/src/com/android/contacts/quickcontact/QuickContactBackgroundDrawable.java b/src/com/android/contacts/quickcontact/QuickContactBackgroundDrawable.java
new file mode 100644
index 0000000..ef970d5
--- /dev/null
+++ b/src/com/android/contacts/quickcontact/QuickContactBackgroundDrawable.java
@@ -0,0 +1,109 @@
+package com.android.contacts.quickcontact;
+
+import com.android.contacts.R;
+
+import android.content.res.Resources;
+import android.graphics.Canvas;
+import android.graphics.ColorFilter;
+import android.graphics.PixelFormat;
+import android.graphics.Rect;
+import android.graphics.drawable.Drawable;
+
+/**
+ * Drawable that draws three pictures for the QuickContact-Background. ColorFilter is ignored
+ */
+public class QuickContactBackgroundDrawable extends Drawable {
+    private Drawable mLeftDrawable;
+    private Drawable mMiddleDrawable;
+    private Drawable mRightDrawable;
+    private int mRequestedX = Integer.MIN_VALUE;
+    private boolean mBoundsSet = false;
+    private int mAlpha = -1;
+    private int mBottomOverride = Integer.MIN_VALUE;
+
+    @Override
+    public void setAlpha(int alpha) {
+        mAlpha = alpha;
+        setChildAlpha();
+    }
+
+    /**
+     * Overrides the bottom bounds. This is used for the animation when the QuickContact
+     * expands/collapses options
+     */
+    public void setBottomOverride(int value) {
+        mBottomOverride = value;
+        setChildBounds();
+        invalidateSelf();
+    }
+
+    public void clearBottomOverride() {
+        mBottomOverride = Integer.MIN_VALUE;
+        invalidateSelf();
+        setChildBounds();
+    }
+
+    public float getBottomOverride() {
+        return mBottomOverride;
+    }
+
+    @Override
+    public void setColorFilter(ColorFilter cf) {
+    }
+
+    @Override
+    public int getOpacity() {
+        return PixelFormat.TRANSLUCENT;
+    }
+
+    public void configure(Resources resources, boolean arrowUp, int requestedX) {
+        mLeftDrawable = resources.getDrawable(arrowUp
+                ? R.drawable.quickactions_arrowup_left_holo_light
+                : R.drawable.quickactions_arrowdown_left_holo_light);
+        mMiddleDrawable = resources.getDrawable(arrowUp
+                ? R.drawable.quickactions_arrowup_middle_holo_light
+                : R.drawable.quickactions_arrowdown_middle_holo_light);
+        mRightDrawable = resources.getDrawable(arrowUp
+                ? R.drawable.quickactions_arrowup_right_holo_light
+                : R.drawable.quickactions_arrowdown_right_holo_light);
+
+        mRequestedX = requestedX;
+
+        setChildAlpha();
+        setChildBounds();
+    }
+
+    @Override
+    protected void onBoundsChange(Rect bounds) {
+        mBoundsSet = true;
+        setChildBounds();
+    }
+
+    private void setChildAlpha() {
+        if (mAlpha == -1) return;
+
+        if (mLeftDrawable != null) mLeftDrawable.setAlpha(mAlpha);
+        if (mMiddleDrawable != null) mMiddleDrawable.setAlpha(mAlpha);
+        if (mRightDrawable != null) mRightDrawable.setAlpha(mAlpha);
+    }
+
+    private void setChildBounds() {
+        if (mRequestedX == Integer.MIN_VALUE) return;
+        if (!mBoundsSet) return;
+
+        final Rect bounds = getBounds();
+        final int middleLeft = mRequestedX - mMiddleDrawable.getIntrinsicWidth() / 2;
+        final int middleRight = mRequestedX + mMiddleDrawable.getIntrinsicWidth() / 2;
+        final int bottom = mBottomOverride == Integer.MIN_VALUE ? bounds.bottom : mBottomOverride;
+        mLeftDrawable.setBounds(bounds.left, bounds.top, middleLeft, bottom);
+        mMiddleDrawable.setBounds(middleLeft, bounds.top, middleRight, bottom);
+        mRightDrawable.setBounds(middleRight, bounds.top, bounds.right, bottom);
+    }
+
+    @Override
+    public void draw(Canvas canvas) {
+        mLeftDrawable.draw(canvas);
+        mMiddleDrawable.draw(canvas);
+        mRightDrawable.draw(canvas);
+    }
+}
diff --git a/src/com/android/contacts/quickcontact/QuickContactRootLayout.java b/src/com/android/contacts/quickcontact/QuickContactRootLayout.java
new file mode 100644
index 0000000..007783a
--- /dev/null
+++ b/src/com/android/contacts/quickcontact/QuickContactRootLayout.java
@@ -0,0 +1,54 @@
+/*
+ * Copyright (C) 2010 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.contacts.quickcontact;
+
+import android.content.Context;
+import android.util.AttributeSet;
+import android.view.KeyEvent;
+import android.widget.LinearLayout;
+
+/**
+ * Custom layout for Quick Contact. It intercepts the BACK key and
+ * close QC even when the soft keyboard is open.
+ */
+public class QuickContactRootLayout extends LinearLayout {
+    private Listener mListener;
+
+    public QuickContactRootLayout(Context context, AttributeSet attrs) {
+        super(context, attrs);
+    }
+
+    public void setListener(Listener value) {
+        mListener = value;
+    }
+
+    /**
+     * Intercepts the BACK key event and dismisses QuickContact window.
+     */
+    @Override
+    public boolean dispatchKeyEventPreIme(KeyEvent event) {
+        if (event.getKeyCode() == KeyEvent.KEYCODE_BACK) {
+            if (mListener != null) mListener.onBackPressed();
+            return true;
+        }
+        return super.dispatchKeyEventPreIme(event);
+    }
+
+    public interface Listener {
+        void onBackPressed();
+    }
+}
diff --git a/src/com/android/contacts/quickcontact/QuickContactWindow.java b/src/com/android/contacts/quickcontact/QuickContactWindow.java
index d7a03c4..e773759 100644
--- a/src/com/android/contacts/quickcontact/QuickContactWindow.java
+++ b/src/com/android/contacts/quickcontact/QuickContactWindow.java
@@ -30,6 +30,9 @@
 import com.android.internal.policy.PolicyManager;
 import com.google.android.collect.Sets;
 
+import android.animation.Animator;
+import android.animation.AnimatorListenerAdapter;
+import android.animation.ObjectAnimator;
 import android.content.ActivityNotFoundException;
 import android.content.ContentUris;
 import android.content.ContentValues;
@@ -39,13 +42,13 @@
 import android.content.pm.ApplicationInfo;
 import android.content.pm.PackageManager;
 import android.content.pm.ResolveInfo;
-import android.content.res.Resources;
 import android.database.Cursor;
 import android.graphics.Bitmap;
 import android.graphics.BitmapFactory;
 import android.graphics.Rect;
 import android.graphics.drawable.Drawable;
 import android.net.Uri;
+import android.os.Handler;
 import android.provider.ContactsContract.CommonDataKinds.Email;
 import android.provider.ContactsContract.CommonDataKinds.Im;
 import android.provider.ContactsContract.CommonDataKinds.Phone;
@@ -58,7 +61,6 @@
 import android.provider.ContactsContract.QuickContact;
 import android.provider.ContactsContract.RawContacts;
 import android.text.TextUtils;
-import android.util.AttributeSet;
 import android.util.Log;
 import android.view.ActionMode;
 import android.view.ContextThemeWrapper;
@@ -75,9 +77,6 @@
 import android.view.Window;
 import android.view.WindowManager;
 import android.view.accessibility.AccessibilityEvent;
-import android.view.animation.Animation;
-import android.view.animation.AnimationUtils;
-import android.view.animation.Interpolator;
 import android.widget.AbsListView;
 import android.widget.AdapterView;
 import android.widget.BaseAdapter;
@@ -85,8 +84,8 @@
 import android.widget.CompoundButton;
 import android.widget.HorizontalScrollView;
 import android.widget.ImageView;
+import android.widget.LinearLayout;
 import android.widget.ListView;
-import android.widget.RelativeLayout;
 import android.widget.TextView;
 import android.widget.Toast;
 
@@ -105,7 +104,7 @@
 public class QuickContactWindow implements Window.Callback,
         NotifyingAsyncQueryHandler.AsyncQueryListener, View.OnClickListener,
         AbsListView.OnItemClickListener, CompoundButton.OnCheckedChangeListener, KeyEvent.Callback,
-        OnGlobalLayoutListener {
+        OnGlobalLayoutListener, QuickContactRootLayout.Listener {
     private static final String TAG = "QuickContactWindow";
 
     /**
@@ -116,30 +115,10 @@
         public void onDismiss(QuickContactWindow dialog);
     }
 
-    /**
-     * Custom layout the sole purpose of which is to intercept the BACK key and
-     * close QC even when the soft keyboard is open.
-     */
-    public static class RootLayout extends RelativeLayout {
-
-        QuickContactWindow mQuickContactWindow;
-
-        public RootLayout(Context context, AttributeSet attrs) {
-            super(context, attrs);
-        }
-
-        /**
-         * Intercepts the BACK key event and dismisses QuickContact window.
-         */
-        @Override
-        public boolean dispatchKeyEventPreIme(KeyEvent event) {
-            if (event.getKeyCode() == KeyEvent.KEYCODE_BACK) {
-                mQuickContactWindow.onBackPressed();
-                return true;
-            }
-            return super.dispatchKeyEventPreIme(event);
-        }
-    }
+    private final static int ANIMATION_FADE_IN_TIME = 100;
+    private final static int ANIMATION_FADE_OUT_TIME = 100;
+    private final static int ANIMATION_EXPAND_TIME = 100;
+    private final static int ANIMATION_COLLAPSE_TIME = 100;
 
     private final Context mContext;
     private final LayoutInflater mInflater;
@@ -159,29 +138,21 @@
     private Uri mLookupUri;
     private Rect mAnchor;
 
-    private int mShadowHoriz;
-    private int mShadowVert;
-    private int mShadowTouch;
-
     private int mScreenWidth;
-    private int mScreenHeight;
+    private int mUseableScreenHeight;
     private int mRequestedY;
 
     private boolean mHasValidSocial = false;
     private boolean mMakePrimary = false;
 
-    private ImageView mArrowUp;
-    private ImageView mArrowDown;
-
     private int mMode;
-    private RootLayout mRootView;
+    private QuickContactRootLayout mRootView;
+    private QuickContactBackgroundDrawable mBackground;
     private View mHeader;
     private HorizontalScrollView mTrackScroll;
     private ViewGroup mTrack;
-    private Animation mTrackAnim;
 
-    private View mFooter;
-    private View mFooterDisambig;
+    private LinearLayout mFooterDisambig;
     private ListView mResolveList;
     private CheckableImageView mLastAction;
     private CheckBox mSetPrimaryCheckBox;
@@ -268,47 +239,32 @@
 
         mWindow.setContentView(R.layout.quickcontact);
 
-        mRootView = (RootLayout)mWindow.findViewById(R.id.root);
-        mRootView.mQuickContactWindow = this;
+        mRootView = (QuickContactRootLayout)mWindow.findViewById(R.id.root);
+        mRootView.setListener(this);
         mRootView.setFocusable(true);
         mRootView.setFocusableInTouchMode(true);
-        mRootView.setDescendantFocusability(RootLayout.FOCUS_AFTER_DESCENDANTS);
+        mRootView.setDescendantFocusability(ViewGroup.FOCUS_AFTER_DESCENDANTS);
 
-        mArrowUp = (ImageView)mWindow.findViewById(R.id.arrow_up);
-        mArrowDown = (ImageView)mWindow.findViewById(R.id.arrow_down);
+        mBackground = new QuickContactBackgroundDrawable();
+        mRootView.setBackgroundDrawable(mBackground);
 
         mResolveCache = new ResolveCache(mContext);
 
-        final Resources res = mContext.getResources();
-        mShadowHoriz = res.getDimensionPixelSize(R.dimen.quickcontact_shadow_horiz);
-        mShadowVert = res.getDimensionPixelSize(R.dimen.quickcontact_shadow_vert);
-        mShadowTouch = res.getDimensionPixelSize(R.dimen.quickcontact_shadow_touch);
-
         mScreenWidth = mWindowManager.getDefaultDisplay().getWidth();
-        mScreenHeight = mWindowManager.getDefaultDisplay().getHeight();
+        // Status bar height
+        int screenMarginBottom = context.getResources().getDimensionPixelSize(
+                com.android.internal.R.dimen.screen_margin_bottom);
+        mUseableScreenHeight = mWindowManager.getDefaultDisplay().getHeight() - screenMarginBottom;
 
-        mTrack = (ViewGroup)mWindow.findViewById(R.id.quickcontact);
-        mTrackScroll = (HorizontalScrollView)mWindow.findViewById(R.id.scroll);
+        mTrack = (ViewGroup) mWindow.findViewById(R.id.quickcontact);
+        mTrackScroll = (HorizontalScrollView) mWindow.findViewById(R.id.scroll);
 
-        mFooter = mWindow.findViewById(R.id.footer);
-        mFooterDisambig = mWindow.findViewById(R.id.footer_disambig);
-        mResolveList = (ListView)mWindow.findViewById(android.R.id.list);
-        mSetPrimaryCheckBox = (CheckBox)mWindow.findViewById(android.R.id.checkbox);
+        mFooterDisambig = (LinearLayout) mWindow.findViewById(R.id.footer_disambig);
+        mResolveList = (ListView) mWindow.findViewById(android.R.id.list);
+        mSetPrimaryCheckBox = (CheckBox) mWindow.findViewById(android.R.id.checkbox);
 
         mSetPrimaryCheckBox.setOnCheckedChangeListener(this);
 
-        // Prepare track entrance animation
-        mTrackAnim = AnimationUtils.loadAnimation(mContext, R.anim.quickcontact);
-        mTrackAnim.setInterpolator(new Interpolator() {
-            @Override
-            public float getInterpolation(float t) {
-                // Pushes past the target area, then snaps back into place.
-                // Equation for graphing: 1.2-((x*1.6)-1.1)^2
-                final float inner = (t * 1.55f) - 1.1f;
-                return 1.2f - inner * inner;
-            }
-        });
-
         mHandler = new NotifyingAsyncQueryHandler(mContext, this);
     }
 
@@ -437,19 +393,10 @@
     }
 
     /**
-     * Show the correct call-out arrow based on a {@link R.id} reference.
+     * Creates and configures the background resource
      */
-    private void showArrow(int whichArrow, int requestedX) {
-        final View showArrow = (whichArrow == R.id.arrow_up) ? mArrowUp : mArrowDown;
-        final View hideArrow = (whichArrow == R.id.arrow_up) ? mArrowDown : mArrowUp;
-
-        final int arrowWidth = mArrowUp.getMeasuredWidth();
-
-        showArrow.setVisibility(View.VISIBLE);
-        ViewGroup.MarginLayoutParams param = (ViewGroup.MarginLayoutParams)showArrow.getLayoutParams();
-        param.leftMargin = requestedX - arrowWidth / 2;
-
-        hideArrow.setVisibility(View.INVISIBLE);
+    private void configureBackground(boolean arrowUp, int requestedX) {
+        mBackground.configure(mContext.getResources(), arrowUp, requestedX);
     }
 
     /**
@@ -459,45 +406,55 @@
     private void showInternal() {
         mDecor = mWindow.getDecorView();
         mDecor.getViewTreeObserver().addOnGlobalLayoutListener(this);
-        WindowManager.LayoutParams l = mWindow.getAttributes();
+        WindowManager.LayoutParams layoutParams = mWindow.getAttributes();
 
-        l.width = mScreenWidth + mShadowHoriz + mShadowHoriz;
-        l.height = WindowManager.LayoutParams.WRAP_CONTENT;
+        layoutParams.width = mContext.getResources().getDimensionPixelSize(
+                R.dimen.quick_contact_width);
+        layoutParams.height = WindowManager.LayoutParams.WRAP_CONTENT;
 
-        // Force layout measuring pass so we have baseline numbers
-        mDecor.measure(l.width, l.height);
-        final int blockHeight = mDecor.getMeasuredHeight();
-
-        l.gravity = Gravity.TOP | Gravity.LEFT;
-        l.x = -mShadowHoriz;
-
-        if (mAnchor.top > blockHeight) {
-            // Show downwards callout when enough room, aligning bottom block
-            // edge with top of anchor area, and adjusting to inset arrow.
-            showArrow(R.id.arrow_down, mAnchor.centerX());
-            l.y = mAnchor.top - blockHeight + mShadowVert;
-            l.windowAnimations = R.style.QuickContactAboveAnimation;
-
+        // Try to left align with the anchor control
+        if (mAnchor.left + layoutParams.width <= mScreenWidth) {
+            layoutParams.x = mAnchor.left;
         } else {
-            // Otherwise show upwards callout, aligning block top with bottom of
-            // anchor area, and adjusting to inset arrow.
-            showArrow(R.id.arrow_up, mAnchor.centerX());
-            l.y = mAnchor.bottom - mShadowVert;
-            l.windowAnimations = R.style.QuickContactBelowAnimation;
-
+            // Not enough space. Try to right align to the anchor
+            if (mAnchor.right - layoutParams.width >= 0) {
+                layoutParams.x = mAnchor.right - layoutParams.width;
+            } else {
+                // Also not enough space. Use the whole screen width available
+                layoutParams.x = 0;
+                layoutParams.width = mScreenWidth;
+            }
         }
 
-        l.flags = WindowManager.LayoutParams.FLAG_LAYOUT_IN_SCREEN
+        // Force layout measuring pass so we have baseline numbers
+        mDecor.measure(layoutParams.width, layoutParams.height);
+        final int blockHeight = mDecor.getMeasuredHeight();
+
+        layoutParams.gravity = Gravity.TOP | Gravity.LEFT;
+
+        if (mUseableScreenHeight - mAnchor.bottom > blockHeight) {
+            // Show downwards callout when enough room, aligning block top with bottom of
+            // anchor area, and adjusting to inset arrow.
+            configureBackground(true, mAnchor.centerX() - layoutParams.x);
+            layoutParams.y = mAnchor.bottom;
+            layoutParams.windowAnimations = R.style.QuickContactBelowAnimation;
+        } else {
+            // Show upwards callout, aligning bottom block
+            // edge with top of anchor area, and adjusting to inset arrow.
+            configureBackground(false, mAnchor.centerX() - layoutParams.x);
+            layoutParams.y = mAnchor.top - blockHeight;
+            layoutParams.windowAnimations = R.style.QuickContactAboveAnimation;
+        }
+
+        layoutParams.flags = WindowManager.LayoutParams.FLAG_LAYOUT_IN_SCREEN
                 | WindowManager.LayoutParams.FLAG_LAYOUT_NO_LIMITS;
 
-        mRequestedY = l.y;
-        mWindowManager.addView(mDecor, l);
+        mRequestedY = layoutParams.y;
+        mWindowManager.addView(mDecor, layoutParams);
         mShowing = true;
         mQuerying = false;
         mDismissed = false;
 
-        mTrack.startAnimation(mTrackAnim);
-
         if (TRACE_LAUNCH) {
             android.os.Debug.stopMethodTracing();
             Log.d(TAG, "Window recycled " + mWindowRecycled + " times, chiclets "
@@ -524,9 +481,9 @@
         final int blockHeight = mDecor.getHeight();
 
         l.y = mRequestedY;
-        if (mRequestedY + blockHeight > mScreenHeight) {
+        if (mRequestedY + blockHeight > mUseableScreenHeight) {
             // Shift up from bottom when overflowing
-            l.y = mScreenHeight - blockHeight;
+            l.y = mUseableScreenHeight - blockHeight;
         }
 
         if (originalY != l.y) {
@@ -573,6 +530,9 @@
      * Reset track to initial state, recycling any chiclets.
      */
     private void resetTrack() {
+        // Clear background height-animation override
+        mBackground.clearBottomOverride();
+
         // Release reference to last chiclet
         mLastAction = null;
 
@@ -581,19 +541,19 @@
         mActions.clear();
 
         // Recycle any chiclets in use
-        while (mTrack.getChildCount() > 2) {
-            this.releaseView(mTrack.getChildAt(1));
-            mTrack.removeViewAt(1);
+        for (int i = mTrack.getChildCount() - 1; i >= 0; i--) {
+            releaseView(mTrack.getChildAt(i));
+            mTrack.removeViewAt(i);
         }
 
         mTrackScroll.fullScroll(View.FOCUS_LEFT);
-        mWasDownArrow = false;
 
         // Clear any primary requests
         mMakePrimary = false;
         mSetPrimaryCheckBox.setChecked(false);
 
-        setResolveVisible(false, null);
+        setNewActionViewChecked(null);
+        mFooterDisambig.setVisibility(View.GONE);
     }
 
     /**
@@ -1008,7 +968,7 @@
          */
         private static class Entry {
             public ResolveInfo bestResolve;
-            public SoftReference<Drawable> icon;
+            public Drawable icon;
         }
 
         private HashMap<String, Entry> mCache = new HashMap<String, Entry>();
@@ -1045,7 +1005,7 @@
                     final Drawable icon = bestResolve.loadIcon(mPackageManager);
 
                     entry.bestResolve = bestResolve;
-                    entry.icon = new SoftReference<Drawable>(icon);
+                    entry.icon = icon;
                 }
             }
 
@@ -1122,8 +1082,7 @@
          * {@link PackageManager} query.
          */
         public Drawable getIcon(Action action) {
-            final SoftReference<Drawable> iconRef = getEntry(action).icon;
-            return (iconRef == null) ? null : iconRef.get();
+            return getEntry(action).icon;
         }
 
         public void clear() {
@@ -1397,38 +1356,65 @@
     }
 
     /**
-     * Flag indicating if {@link #mArrowDown} was visible during the last call
-     * to {@link #setResolveVisible(boolean, CheckableImageView)}. Used to
-     * decide during a later call if the arrow should be restored.
+     * Helper for showing and hiding {@link #mFooterDisambig}
      */
-    private boolean mWasDownArrow = false;
-
-    /**
-     * Helper for showing and hiding {@link #mFooterDisambig}, which will
-     * correctly manage {@link #mArrowDown} as needed.
-     */
-    private void setResolveVisible(boolean visible, CheckableImageView actionView) {
-        // Show or hide the resolve list if needed
-        boolean visibleNow = mFooterDisambig.getVisibility() == View.VISIBLE;
-
+    private void setNewActionViewChecked(CheckableImageView actionView) {
         if (mLastAction != null) mLastAction.setChecked(false);
         if (actionView != null) actionView.setChecked(true);
         mLastAction = actionView;
+    }
 
-        // Bail early if already in desired state
-        if (visible == visibleNow) return;
+    /**
+     * Animates collpasing of the disambig area. When done, it expands again to the new size
+     */
+    private void animateCollapse(final Runnable whenDone) {
+        final int oldBottom = mBackground.getBounds().bottom;
+        mBackground.setBottomOverride(oldBottom);
 
-        mFooter.setVisibility(visible ? View.GONE : View.VISIBLE);
-        mFooterDisambig.setVisibility(visible ? View.VISIBLE : View.GONE);
+        final ObjectAnimator fadeOutAnimator = ObjectAnimator.ofFloat(mFooterDisambig, "alpha",
+                1.0f, 0.0f);
+        fadeOutAnimator.setDuration(ANIMATION_FADE_OUT_TIME);
+        fadeOutAnimator.start();
 
-        if (visible) {
-            // If showing list, then hide and save state of down arrow
-            mWasDownArrow = mWasDownArrow || (mArrowDown.getVisibility() == View.VISIBLE);
-            mArrowDown.setVisibility(View.INVISIBLE);
-        } else {
-            // If hiding list, restore any down arrow state
-            mArrowDown.setVisibility(mWasDownArrow ? View.VISIBLE : View.INVISIBLE);
-        }
+        final ObjectAnimator collapseAnimator = ObjectAnimator.ofInt(mBackground,
+                "bottomOverride", oldBottom, oldBottom - mFooterDisambig.getHeight());
+        collapseAnimator.setDuration(ANIMATION_COLLAPSE_TIME);
+        collapseAnimator.setStartDelay(ANIMATION_FADE_OUT_TIME);
+        collapseAnimator.start();
+
+        collapseAnimator.addListener(new AnimatorListenerAdapter() {
+            @Override
+            public void onAnimationEnd(Animator animation) {
+                mFooterDisambig.setVisibility(View.GONE);
+                new Handler().post(whenDone);
+            }
+        });
+    }
+
+    /**
+     * Animates expansion of the disambig area.
+     */
+    private void animateExpand() {
+        mFooterDisambig.setVisibility(View.VISIBLE);
+        final int oldBottom = mBackground.getBounds().bottom;
+        mBackground.setBottomOverride(oldBottom);
+        mFooterDisambig.setAlpha(0.0f);
+        new Handler().post(new Runnable() {
+            @Override
+            public void run() {
+                final int newBottom = mBackground.getBounds().bottom;
+                final ObjectAnimator expandAnimator = ObjectAnimator.ofInt(mBackground,
+                        "bottomOverride", oldBottom, newBottom);
+                expandAnimator.setDuration(ANIMATION_EXPAND_TIME);
+                expandAnimator.start();
+
+                final ObjectAnimator fadeInAnimator = ObjectAnimator.ofFloat(mFooterDisambig,
+                        "alpha", 0.0f, 1.0f);
+                fadeInAnimator.setDuration(ANIMATION_FADE_IN_TIME);
+                fadeInAnimator.setStartDelay(ANIMATION_EXPAND_TIME);
+                fadeInAnimator.start();
+            }
+        });
     }
 
     /** {@inheritDoc} */
@@ -1438,75 +1424,106 @@
         final CheckableImageView actionView = isActionView ? (CheckableImageView)view : null;
         final Object tag = view.getTag();
         if (tag instanceof Action) {
-            // Incoming tag is concrete intent, so try launching
-            final Action action = (Action)tag;
-            final boolean makePrimary = mMakePrimary;
+            final Runnable startAppRunnable = new Runnable() {
+                @Override
+                public void run() {
+                    // Incoming tag is concrete intent, so try launching
+                    final Action action = (Action)tag;
+                    try {
+                        mContext.startActivity(action.getIntent());
+                    } catch (ActivityNotFoundException e) {
+                        Toast.makeText(mContext, R.string.quickcontact_missing_app,
+                                Toast.LENGTH_SHORT).show();
+                    }
 
-            try {
-                mContext.startActivity(action.getIntent());
-            } catch (ActivityNotFoundException e) {
-                Toast.makeText(mContext, R.string.quickcontact_missing_app, Toast.LENGTH_SHORT)
-                        .show();
-            }
+                    // Hide the resolution list, if present
+                    setNewActionViewChecked(null);
+                    dismiss();
+                    mFooterDisambig.setVisibility(View.GONE);
 
-            // Hide the resolution list, if present
-            setResolveVisible(false, null);
-            this.dismiss();
-
-            if (makePrimary) {
-                ContentValues values = new ContentValues(1);
-                values.put(Data.IS_SUPER_PRIMARY, 1);
-                final Uri dataUri = action.getDataUri();
-                if (dataUri != null) {
-                    mContext.getContentResolver().update(dataUri, values, null, null);
+                    if (mMakePrimary) {
+                        ContentValues values = new ContentValues(1);
+                        values.put(Data.IS_SUPER_PRIMARY, 1);
+                        final Uri dataUri = action.getDataUri();
+                        if (dataUri != null) {
+                            mContext.getContentResolver().update(dataUri, values, null, null);
+                        }
+                    }
                 }
+            };
+            if (isActionView && mFooterDisambig.getVisibility() == View.VISIBLE) {
+                // If the expansion list is currently opened, animate its collapse and then
+                // execute the target app
+                animateCollapse(startAppRunnable);
+            } else {
+                // Defer the action to make the window properly repaint
+                new Handler().post(startAppRunnable);
             }
         } else if (tag instanceof ActionList) {
-            // Incoming tag is a MIME-type, so show resolution list
-            final ActionList children = (ActionList)tag;
+            // Don't do anything if already open
+            if (actionView != mLastAction) {
+                final Runnable configureListRunnable = new Runnable() {
+                    @Override
+                    public void run() {
+                        // Show resolution list and set adapter
+                        setNewActionViewChecked(actionView);
 
-            // Show resolution list and set adapter
-            setResolveVisible(true, actionView);
+                        // Incoming tag is a MIME-type, so show resolution list
+                        final ActionList children = (ActionList)tag;
 
-            mResolveList.setOnItemClickListener(this);
-            mResolveList.setAdapter(new BaseAdapter() {
-                @Override
-                public int getCount() {
-                    return children.size();
+                        mResolveList.setOnItemClickListener(QuickContactWindow.this);
+                        mResolveList.setAdapter(new BaseAdapter() {
+                            @Override
+                            public int getCount() {
+                                return children.size();
+                            }
+
+                            @Override
+                            public Object getItem(int position) {
+                                return children.get(position);
+                            }
+
+                            @Override
+                            public long getItemId(int position) {
+                                return position;
+                            }
+
+                            @Override
+                            public View getView(int position, View convertView, ViewGroup parent) {
+                                final View result = convertView != null ? convertView :
+                                        mInflater.inflate(R.layout.quickcontact_resolve_item,
+                                        parent, false);
+                                // Set action title based on summary value
+                                final Action action = (Action)getItem(position);
+
+                                TextView text1 = (TextView)result.findViewById(android.R.id.text1);
+                                TextView text2 = (TextView)result.findViewById(android.R.id.text2);
+
+                                text1.setText(action.getHeader());
+                                text2.setText(action.getBody());
+
+                                result.setTag(action);
+                                return result;
+                            }
+                        });
+
+                        animateExpand();
+                        // Make sure we resize to make room for ListView
+                        if (mDecor != null) {
+                            mDecor.forceLayout();
+                            mDecor.invalidate();
+                        }
+                    }
+                };
+                if (mFooterDisambig.getVisibility() == View.VISIBLE) {
+                    // If the expansion list is currently opened, animate its collapse and then
+                    // execute the target app
+                    animateCollapse(configureListRunnable);
+                } else {
+                    // Defer the action to make the window properly repaint
+                    configureListRunnable.run();
                 }
-
-                @Override
-                public Object getItem(int position) {
-                    return children.get(position);
-                }
-
-                @Override
-                public long getItemId(int position) {
-                    return position;
-                }
-
-                @Override
-                public View getView(int position, View convertView, ViewGroup parent) {
-                    final View result = convertView != null ? convertView : mInflater.inflate(
-                            R.layout.quickcontact_resolve_item, parent, false);
-                    // Set action title based on summary value
-                    final Action action = (Action)getItem(position);
-
-                    TextView text1 = (TextView)result.findViewById(android.R.id.text1);
-                    TextView text2 = (TextView)result.findViewById(android.R.id.text2);
-
-                    text1.setText(action.getHeader());
-                    text2.setText(action.getBody());
-
-                    result.setTag(action);
-                    return result;
-                }
-            });
-
-            // Make sure we resize to make room for ListView
-            mDecor.forceLayout();
-            mDecor.invalidate();
-
+            }
         }
     }
 
@@ -1515,16 +1532,9 @@
         mMakePrimary = isChecked;
     }
 
-    private void onBackPressed() {
-        // Back key will first dismiss any expanded resolve list, otherwise
-        // it will close the entire dialog.
-        if (mFooterDisambig.getVisibility() == View.VISIBLE) {
-            setResolveVisible(false, null);
-            mDecor.forceLayout();
-            mDecor.invalidate();
-        } else {
-            dismiss();
-        }
+    @Override
+    public void onBackPressed() {
+        dismiss();
     }
 
     /** {@inheritDoc} */
@@ -1587,8 +1597,6 @@
         if (event.getAction() == MotionEvent.ACTION_DOWN && mDecor != null) {
             // Only try detecting outside events on down-press
             mDecor.getHitRect(mRect);
-            mRect.top = mRect.top + mShadowTouch;
-            mRect.bottom = mRect.bottom - mShadowTouch;
             final int x = (int)event.getX();
             final int y = (int)event.getY();
             if (!mRect.contains(x, y)) {
diff --git a/tests/AndroidManifest.xml b/tests/AndroidManifest.xml
index c41ff55..e714c25 100644
--- a/tests/AndroidManifest.xml
+++ b/tests/AndroidManifest.xml
@@ -53,6 +53,15 @@
             </intent-filter>
         </activity>
 
+        <activity android:name=".quickcontact.QuickContactTestsActivity"
+            android:label="@string/quickContactTests"
+            >
+            <intent-filter>
+                <action android:name="android.intent.action.MAIN" />
+                <category android:name="android.intent.category.DEFAULT" />
+                <category android:name="android.intent.category.LAUNCHER" />
+            </intent-filter>
+        </activity>
     </application>
 
     <instrumentation android:name="android.test.InstrumentationTestRunner"
diff --git a/tests/res/drawable/ic_contact_picture.png b/tests/res/drawable/ic_contact_picture.png
new file mode 100644
index 0000000..3a338e8
--- /dev/null
+++ b/tests/res/drawable/ic_contact_picture.png
Binary files differ
diff --git a/tests/res/layout/quick_contact_tests.xml b/tests/res/layout/quick_contact_tests.xml
new file mode 100644
index 0000000..7687713
--- /dev/null
+++ b/tests/res/layout/quick_contact_tests.xml
@@ -0,0 +1,89 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2010 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.
+-->
+
+<LinearLayout
+    xmlns:android="http://schemas.android.com/apk/res/android"
+    android:layout_width="match_parent"
+    android:layout_height="match_parent"
+    android:orientation="vertical">
+    <LinearLayout
+        android:layout_width="match_parent"
+        android:layout_height="wrap_content"
+        android:orientation="horizontal"
+        android:layout_marginTop="16dip">
+        <QuickContactBadge
+            android:id="@+id/small_badge1"
+            android:layout_width="wrap_content"
+            android:layout_height="wrap_content"
+            android:layout_marginLeft="32dip" />
+        <QuickContactBadge
+            android:id="@+id/medium_badge1"
+            android:layout_width="wrap_content"
+            android:layout_height="wrap_content"
+            android:layout_marginLeft="64dip" />
+        <QuickContactBadge
+            android:id="@+id/large_badge1"
+            android:layout_width="wrap_content"
+            android:layout_height="wrap_content"
+            android:layout_marginLeft="64dip" />
+    </LinearLayout>
+    <View
+        android:layout_width="match_parent"
+        android:layout_height="0px"
+        android:layout_weight="1" />
+    <LinearLayout
+        android:layout_width="match_parent"
+        android:layout_height="wrap_content"
+        android:orientation="horizontal">
+        <Button
+            android:id="@+id/pick_contact"
+            android:layout_width="wrap_content"
+            android:layout_height="wrap_content"
+            android:padding="32dip"
+            android:text="@string/pickContact" />
+        <TextView
+            android:id="@+id/uri"
+            android:layout_width="wrap_content"
+            android:layout_height="wrap_content"
+            android:padding="32dip" />
+    </LinearLayout>
+    <View
+        android:layout_width="match_parent"
+        android:layout_height="0px"
+        android:layout_weight="1" />
+    <LinearLayout
+        android:layout_width="match_parent"
+        android:layout_height="wrap_content"
+        android:orientation="horizontal"
+        android:layout_marginBottom="16dip">
+        <QuickContactBadge
+            android:id="@+id/small_badge2"
+            android:layout_width="wrap_content"
+            android:layout_height="wrap_content"
+            android:layout_marginLeft="32dip" />
+        <QuickContactBadge
+            android:id="@+id/medium_badge2"
+            android:layout_width="wrap_content"
+            android:layout_height="wrap_content"
+            android:layout_marginLeft="64dip" />
+        <QuickContactBadge
+            android:id="@+id/large_badge2"
+            android:layout_width="wrap_content"
+            android:layout_height="wrap_content"
+            android:layout_marginLeft="64dip" />
+    </LinearLayout>
+</LinearLayout>
+
diff --git a/tests/res/values/donottranslate_strings.xml b/tests/res/values/donottranslate_strings.xml
index 6891c2f..660bae2 100644
--- a/tests/res/values/donottranslate_strings.xml
+++ b/tests/res/values/donottranslate_strings.xml
@@ -94,6 +94,8 @@
     </string-array>
 
     <string name="pinnedHeaderList">Pinned Headers</string>
+    <string name="quickContactTests">Quick Contact modes</string>
+    <string name="pickContact">Pick contact</string>
 
     <string-array name="pinnedHeaderUseCases">
         <item>One short section - no headers</item>
diff --git a/tests/src/com/android/contacts/tests/quickcontact/QuickContactTestsActivity.java b/tests/src/com/android/contacts/tests/quickcontact/QuickContactTestsActivity.java
new file mode 100644
index 0000000..c865680
--- /dev/null
+++ b/tests/src/com/android/contacts/tests/quickcontact/QuickContactTestsActivity.java
@@ -0,0 +1,131 @@
+/*
+ * Copyright (C) 2010 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.contacts.tests.quickcontact;
+
+import com.android.contacts.tests.R;
+
+import android.app.Activity;
+import android.content.Intent;
+import android.content.SharedPreferences;
+import android.content.SharedPreferences.Editor;
+import android.net.Uri;
+import android.os.Bundle;
+import android.provider.ContactsContract.Contacts;
+import android.provider.ContactsContract.QuickContact;
+import android.view.View;
+import android.view.View.OnClickListener;
+import android.view.Window;
+import android.widget.Button;
+import android.widget.QuickContactBadge;
+import android.widget.TextView;
+
+public class QuickContactTestsActivity extends Activity {
+    private static final int REQUEST_CODE_PICK = 1;
+    private static final String PREF_NAME = "quick_contact_prefs";
+    private static final String PREF_SETTING_URI = "uri";
+
+    private Button mPickContact;
+    private TextView mUriTextView;
+    private QuickContactBadge mSmallBadge1;
+    private QuickContactBadge mSmallBadge2;
+    private QuickContactBadge mMediumBadge1;
+    private QuickContactBadge mMediumBadge2;
+    private QuickContactBadge mLargeBadge1;
+    private QuickContactBadge mLargeBadge2;
+
+    private Uri mContactUri;
+
+    @Override
+    protected void onCreate(Bundle savedInstanceState) {
+        super.onCreate(savedInstanceState);
+
+        getWindow().requestFeature(Window.FEATURE_NO_TITLE);
+        setContentView(R.layout.quick_contact_tests);
+
+        mPickContact = (Button) findViewById(R.id.pick_contact);
+        mUriTextView = (TextView) findViewById(R.id.uri);
+        mSmallBadge1 = (QuickContactBadge) findViewById(R.id.small_badge1);
+        mSmallBadge2 = (QuickContactBadge) findViewById(R.id.small_badge2);
+        mMediumBadge1 = (QuickContactBadge) findViewById(R.id.medium_badge1);
+        mMediumBadge2 = (QuickContactBadge) findViewById(R.id.medium_badge2);
+        mLargeBadge1 = (QuickContactBadge) findViewById(R.id.large_badge1);
+        mLargeBadge2 = (QuickContactBadge) findViewById(R.id.large_badge2);
+
+        mSmallBadge1.setMode(QuickContact.MODE_SMALL);
+        mSmallBadge2.setMode(QuickContact.MODE_SMALL);
+        mMediumBadge1.setMode(QuickContact.MODE_MEDIUM);
+        mMediumBadge2.setMode(QuickContact.MODE_MEDIUM);
+        mLargeBadge1.setMode(QuickContact.MODE_LARGE);
+        mLargeBadge2.setMode(QuickContact.MODE_LARGE);
+
+        mSmallBadge1.setImageResource(R.drawable.ic_contact_picture);
+        mSmallBadge2.setImageResource(R.drawable.ic_contact_picture);
+        mMediumBadge1.setImageResource(R.drawable.ic_contact_picture);
+        mMediumBadge2.setImageResource(R.drawable.ic_contact_picture);
+        mLargeBadge1.setImageResource(R.drawable.ic_contact_picture);
+        mLargeBadge2.setImageResource(R.drawable.ic_contact_picture);
+
+        mPickContact.setOnClickListener(new OnClickListener() {
+            @Override
+            public void onClick(View v) {
+                final Intent intent = new Intent(Intent.ACTION_PICK, Contacts.CONTENT_URI);
+                startActivityForResult(intent , REQUEST_CODE_PICK);
+            }
+        });
+
+        // Load Uri if known
+        final SharedPreferences sharedPreferences = getSharedPreferences(PREF_NAME, MODE_PRIVATE);
+        final String uriString = sharedPreferences.getString(PREF_SETTING_URI, null);
+        if (uriString != null) {
+            mContactUri = Uri.parse(uriString);
+            assignUri();
+        }
+    }
+
+    @Override
+    protected void onActivityResult(int requestCode, int resultCode, Intent data) {
+        super.onActivityResult(requestCode, resultCode, data);
+        if (resultCode == Activity.RESULT_CANCELED) return;
+        switch (requestCode) {
+            case REQUEST_CODE_PICK: {
+                mContactUri = data.getData();
+                assignUri();
+                break;
+            }
+        }
+    }
+
+    @Override
+    protected void onDestroy() {
+        super.onDestroy();
+
+        final SharedPreferences sharedPreferences = getSharedPreferences(PREF_NAME, MODE_PRIVATE);
+        final Editor editor = sharedPreferences.edit();
+        editor.putString(PREF_SETTING_URI, mContactUri == null ? null : mContactUri.toString());
+        editor.apply();
+    }
+
+    private void assignUri() {
+        mUriTextView.setText(mContactUri.toString());
+        mSmallBadge1.assignContactUri(mContactUri);
+        mSmallBadge2.assignContactUri(mContactUri);
+        mMediumBadge1.assignContactUri(mContactUri);
+        mMediumBadge2.assignContactUri(mContactUri);
+        mLargeBadge1.assignContactUri(mContactUri);
+        mLargeBadge2.assignContactUri(mContactUri);
+    }
+}