Merge "Change contact detail on 7" to fragment carousel" into jb-dev
diff --git a/res/layout-sw580dp-w940dp/contact_detail_container.xml b/res/layout-sw580dp-w940dp/contact_detail_container.xml
new file mode 100644
index 0000000..e653d9d
--- /dev/null
+++ b/res/layout-sw580dp-w940dp/contact_detail_container.xml
@@ -0,0 +1,27 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2012 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.
+-->
+
+<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
+    android:layout_width="match_parent"
+    android:layout_height="match_parent">
+
+    <com.android.contacts.detail.ContactDetailFragmentCarousel
+        android:id="@+id/fragment_carousel"
+        android:layout_width="match_parent"
+        android:layout_height="match_parent"
+        android:layout_marginLeft="16dip"/>
+
+</FrameLayout>
diff --git a/res/layout-sw580dp-w940dp/contact_detail_fragment.xml b/res/layout-sw580dp-w940dp/contact_detail_fragment.xml
new file mode 100644
index 0000000..cf89727
--- /dev/null
+++ b/res/layout-sw580dp-w940dp/contact_detail_fragment.xml
@@ -0,0 +1,67 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2012 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:id="@+id/contact_detail"
+    android:orientation="vertical"
+    android:layout_width="match_parent"
+    android:layout_height="match_parent"
+    android:background="@color/background_primary"
+    android:paddingRight="16dip">
+
+    <!-- Placeholder for empty list -->
+    <include
+        android:id="@android:id/empty"
+        layout="@layout/contact_detail_empty"
+        android:visibility="gone" />
+
+    <!-- Real list -->
+    <LinearLayout
+        android:orientation="horizontal"
+        android:layout_weight="1"
+        android:layout_width="match_parent"
+        android:layout_height="0dip"
+        android:baselineAligned="false">
+
+        <include android:id="@+id/static_photo_container"
+            layout="@layout/photo_selector_view"
+            android:layout_width="@dimen/detail_contact_photo_size"
+            android:layout_height="@dimen/detail_contact_photo_size"
+            android:layout_marginTop="@dimen/detail_contact_photo_margin"
+            android:layout_marginRight="@dimen/detail_contact_photo_margin" />
+
+        <ListView android:id="@android:id/list"
+            android:layout_width="0dip"
+            android:layout_height="match_parent"
+            android:paddingTop="16dip"
+            android:clipToPadding="false"
+            android:fadingEdge="none"
+            android:layout_weight="1"
+            android:divider="@null"/>
+
+    </LinearLayout>
+
+    <!-- "QuickFix"- button (Copy to local contact, add to group) -->
+    <Button
+        android:id="@+id/contact_quick_fix"
+        android:layout_width="wrap_content"
+        android:layout_height="wrap_content"
+        android:visibility="gone"
+        android:layout_gravity="center"
+        android:layout_marginTop="10dip"
+        android:layout_marginBottom="10dip" />
+</LinearLayout>
diff --git a/res/layout-sw580dp-w940dp/contact_detail_updates_fragment.xml b/res/layout-sw580dp-w940dp/contact_detail_updates_fragment.xml
new file mode 100644
index 0000000..3bcce3f
--- /dev/null
+++ b/res/layout-sw580dp-w940dp/contact_detail_updates_fragment.xml
@@ -0,0 +1,27 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2012 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.
+-->
+
+<ListView xmlns:android="http://schemas.android.com/apk/res/android"
+    android:id="@android:id/list"
+    android:layout_width="match_parent"
+    android:layout_height="match_parent"
+    android:background="@color/background_social_updates"
+    android:fadingEdge="none"
+    android:divider="@null"
+    android:paddingTop="@dimen/contact_detail_list_top_padding"
+    android:paddingLeft="16dip"
+    android:paddingRight="16dip"
+    android:clipToPadding="false"/>
diff --git a/res/layout-sw580dp-w940dp/detail_header_contact_with_updates.xml b/res/layout-sw580dp-w940dp/detail_header_contact_with_updates.xml
new file mode 100644
index 0000000..32eecc9
--- /dev/null
+++ b/res/layout-sw580dp-w940dp/detail_header_contact_with_updates.xml
@@ -0,0 +1,63 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2012 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.
+-->
+
+<!--
+  This is a header entry in the contact details list for when the contact has social updates. The
+  entry shows the contact's basic info and maintains vertical padding to ensure that the first
+  contact detail is visible (and below the tab carousel). The photo is not displayed here
+  because it will be shown in the tab carousel.
+-->
+<LinearLayout
+    xmlns:android="http://schemas.android.com/apk/res/android"
+    android:layout_width="match_parent"
+    android:layout_height="wrap_content"
+    android:paddingBottom="8dip"
+    android:orientation="horizontal">
+
+    <include layout="@layout/photo_selector_view"
+        android:layout_width="@dimen/detail_contact_photo_size"
+        android:layout_height="@dimen/detail_contact_photo_size" />
+
+    <LinearLayout
+        android:layout_width="0dip"
+        android:layout_height="match_parent"
+        android:layout_weight="1"
+        android:orientation="vertical"
+        android:paddingLeft="16dip"
+        android:paddingRight="4dip">
+
+        <TextView
+            android:id="@+id/name"
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content"
+            android:gravity="center_vertical"
+            android:textAppearance="?android:attr/textAppearanceLarge"
+            android:textSize="@dimen/detail_header_name_text_size" />
+
+        <TextView
+            android:id="@+id/company"
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content"
+            android:gravity="center_vertical"
+            android:textAppearance="?android:attr/textAppearanceMedium"
+            android:textColor="?android:attr/textColorSecondary" />
+
+    </LinearLayout>
+
+    <include
+        layout="@layout/favorites_star" />
+
+</LinearLayout>
diff --git a/res/layout-sw580dp-w940dp/detail_header_contact_without_updates.xml b/res/layout-sw580dp-w940dp/detail_header_contact_without_updates.xml
new file mode 100644
index 0000000..57a2820
--- /dev/null
+++ b/res/layout-sw580dp-w940dp/detail_header_contact_without_updates.xml
@@ -0,0 +1,56 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2012 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.
+-->
+
+<!--
+  This is a header entry in the contact details list for when the contact does not have social
+  updates, which means that the contact's basic info will scroll with the list of details. The
+  photo is not included because it will be displayed in a static place elsewhere.
+-->
+<LinearLayout
+    xmlns:android="http://schemas.android.com/apk/res/android"
+    android:layout_width="match_parent"
+    android:layout_height="wrap_content"
+    android:paddingLeft="8dip"
+    android:paddingBottom="16dip"
+    android:orientation="vertical">
+
+    <LinearLayout
+        android:layout_width="match_parent"
+        android:layout_height="wrap_content"
+        android:paddingRight="16dip">
+
+        <TextView
+            android:id="@+id/name"
+            android:layout_width="0dip"
+            android:layout_weight="1"
+            android:layout_height="wrap_content"
+            android:textAppearance="?android:attr/textAppearanceLarge"
+            android:textSize="@dimen/detail_header_name_text_size"
+            android:paddingRight="16dip" />
+
+        <include
+            layout="@layout/favorites_star" />
+
+    </LinearLayout>
+
+    <TextView
+        android:id="@+id/company"
+        android:layout_width="match_parent"
+        android:layout_height="wrap_content"
+        android:textAppearance="?android:attr/textAppearanceMedium"
+        android:textColor="?android:attr/textColorSecondary" />
+
+</LinearLayout>
diff --git a/res/layout-sw580dp-w940dp/people_activity.xml b/res/layout-sw580dp-w940dp/people_activity.xml
index 44e740e..3a86842 100644
--- a/res/layout-sw580dp-w940dp/people_activity.xml
+++ b/res/layout-sw580dp-w940dp/people_activity.xml
@@ -67,10 +67,7 @@
                 android:id="@+id/contact_detail_container"
                 layout="@layout/contact_detail_container"
                 android:layout_width="match_parent"
-                android:layout_height="match_parent"
-                android:layout_marginLeft="16dip"
-                android:layout_marginTop="16dip"
-                android:layout_marginRight="16dip" />
+                android:layout_height="match_parent"/>
 
             <!-- This invisible worker fragment loads the contact's details -->
             <fragment
diff --git a/res/layout-sw580dp-w940dp/updates_header_contact.xml b/res/layout-sw580dp-w940dp/updates_header_contact.xml
new file mode 100644
index 0000000..1ffdcaa
--- /dev/null
+++ b/res/layout-sw580dp-w940dp/updates_header_contact.xml
@@ -0,0 +1,38 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2012 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.
+-->
+
+<!--
+  This is a header entry in the contact updates list.
+-->
+<FrameLayout
+    xmlns:android="http://schemas.android.com/apk/res/android"
+    android:layout_width="match_parent"
+    android:layout_height="wrap_content"
+    android:focusable="false">
+
+    <TextView
+        style="?android:attr/listSeparatorTextViewStyle"
+        android:layout_height="32dip"
+        android:paddingLeft="8dip"
+        android:paddingRight="8dip"
+        android:background="@drawable/list_section_divider_holo_custom"
+        android:text="@string/recent_updates"
+        android:textColor="@color/people_app_theme_color"
+        android:textAllCaps="true"
+        android:singleLine="true"
+        android:ellipsize="end" />
+
+</FrameLayout>
diff --git a/res/layout-sw680dp/contact_detail_container.xml b/res/layout-sw680dp/contact_detail_container.xml
new file mode 100644
index 0000000..dfbd0d0
--- /dev/null
+++ b/res/layout-sw680dp/contact_detail_container.xml
@@ -0,0 +1,37 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2012 The Android Open Source Project
+
+     Licensed under the Apache License, Version 2.0 (the "License");
+     you may not use this file except in compliance with the License.
+     You may obtain a copy of the License at
+
+          http://www.apache.org/licenses/LICENSE-2.0
+
+     Unless required by applicable law or agreed to in writing, software
+     distributed under the License is distributed on an "AS IS" BASIS,
+     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+     See the License for the specific language governing permissions and
+     limitations under the License.
+-->
+
+<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
+    android:layout_width="match_parent"
+    android:layout_height="match_parent">
+
+    <android.support.v4.view.ViewPager
+        android:id="@+id/pager"
+        android:layout_alignParentTop="true"
+        android:layout_alignParentLeft="true"
+        android:layout_width="match_parent"
+        android:layout_height="match_parent" />
+
+    <include
+        android:id="@+id/tab_carousel"
+        layout="@layout/contact_detail_tab_carousel"
+        android:layout_alignParentTop="true"
+        android:layout_alignParentLeft="true"
+        android:layout_width="match_parent"
+        android:layout_height="wrap_content"
+        android:visibility="gone"/>
+
+</RelativeLayout>
diff --git a/res/layout-sw680dp/contact_detail_fragment.xml b/res/layout-sw680dp/contact_detail_fragment.xml
new file mode 100644
index 0000000..3e4d255
--- /dev/null
+++ b/res/layout-sw680dp/contact_detail_fragment.xml
@@ -0,0 +1,49 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2012 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:id="@+id/contact_detail"
+    android:orientation="vertical"
+    android:layout_width="match_parent"
+    android:layout_height="match_parent">
+
+    <!-- Placeholder for empty list -->
+    <include
+        android:id="@android:id/empty"
+        layout="@layout/contact_detail_empty"
+        android:visibility="gone" />
+
+    <!-- Real list -->
+    <ListView android:id="@android:id/list"
+        android:layout_weight="1"
+        android:layout_width="match_parent"
+        android:layout_height="0dip"
+        android:fadingEdge="none"
+        android:cacheColorHint="#00000000"
+        android:divider="@null"
+    />
+
+    <!-- "QuickFix"- button (Copy to local contact, add to group) -->
+    <Button
+        android:id="@+id/contact_quick_fix"
+        android:layout_width="wrap_content"
+        android:layout_height="wrap_content"
+        android:visibility="gone"
+        android:layout_gravity="center"
+        android:layout_marginTop="10dip"
+        android:layout_marginBottom="10dip" />
+</LinearLayout>
diff --git a/res/layout-sw680dp/contact_detail_updates_fragment.xml b/res/layout-sw680dp/contact_detail_updates_fragment.xml
new file mode 100644
index 0000000..03a2e41
--- /dev/null
+++ b/res/layout-sw680dp/contact_detail_updates_fragment.xml
@@ -0,0 +1,29 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2012 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.
+-->
+
+<FrameLayout
+    xmlns:android="http://schemas.android.com/apk/res/android"
+    android:id="@+id/contact_detail_updates_fragment"
+    android:layout_width="match_parent"
+    android:layout_height="match_parent">
+
+    <ListView android:id="@android:id/list"
+        android:layout_width="match_parent"
+        android:layout_height="match_parent"
+        android:fadingEdge="none"
+        android:divider="@null"/>
+
+</FrameLayout>
diff --git a/res/layout-w470dp/contact_detail_fragment.xml b/res/layout-w470dp/contact_detail_fragment.xml
index b5c4c94..86692d8 100644
--- a/res/layout-w470dp/contact_detail_fragment.xml
+++ b/res/layout-w470dp/contact_detail_fragment.xml
@@ -36,12 +36,13 @@
         android:layout_width="match_parent"
         android:layout_above="@id/contact_quick_fix"
         android:layout_height="match_parent"
-        android:baselineAligned="false" >
+        android:baselineAligned="false"
+        android:background="@android:color/white">
 
         <include android:id="@+id/static_photo_container"
             layout="@layout/photo_selector_view"
-            android:layout_width="128dip"
-            android:layout_height="128dip"
+            android:layout_width="@dimen/detail_contact_photo_size"
+            android:layout_height="@dimen/detail_contact_photo_size"
             android:layout_marginLeft="@dimen/detail_contact_photo_margin"
             android:layout_marginTop="@dimen/detail_contact_photo_margin" />
 
diff --git a/res/layout-w470dp/contact_detail_updates_fragment.xml b/res/layout-w470dp/contact_detail_updates_fragment.xml
index 338a986..801f2bb 100644
--- a/res/layout-w470dp/contact_detail_updates_fragment.xml
+++ b/res/layout-w470dp/contact_detail_updates_fragment.xml
@@ -17,12 +17,14 @@
 <FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
     android:id="@+id/contact_detail_updates_fragment"
     android:layout_width="match_parent"
-    android:layout_height="match_parent">
+    android:layout_height="match_parent"
+    android:background="@color/background_social_updates">
 
     <ListView android:id="@android:id/list"
         android:layout_width="match_parent"
         android:layout_height="wrap_content"
         android:fadingEdge="none"
-        android:divider="@null"/>
+        android:divider="@null"
+        android:background="@android:color/transparent"/>
 
 </FrameLayout>
diff --git a/res/values-sw580dp-w940dp/dimens.xml b/res/values-sw580dp-w940dp/dimens.xml
index 4053a98..99f749c 100644
--- a/res/values-sw580dp-w940dp/dimens.xml
+++ b/res/values-sw580dp-w940dp/dimens.xml
@@ -17,4 +17,6 @@
     <dimen name="group_editor_side_padding">64dip</dimen>
     <dimen name="quick_contact_photo_container_height">180dip</dimen>
     <dimen name="list_visible_scrollbar_padding">32dip</dimen>
+    <dimen name="detail_contact_photo_size">192dip</dimen>
+    <dimen name="detail_contact_photo_margin">16dip</dimen>
 </resources>
diff --git a/res/values-sw680dp-w1000dp/dimens.xml b/res/values-sw680dp-w1000dp/dimens.xml
index 661401a..6a2d1cc 100644
--- a/res/values-sw680dp-w1000dp/dimens.xml
+++ b/res/values-sw680dp-w1000dp/dimens.xml
@@ -16,8 +16,8 @@
 <resources>
     <dimen name="group_detail_border_padding">32dip</dimen>
     <dimen name="group_editor_side_padding">64dip</dimen>
-    <dimen name="detail_contact_photo_margin">16dip</dimen>
     <dimen name="contact_detail_list_top_padding">32dip</dimen>
     <dimen name="contact_tile_list_padding_top">32dip</dimen>
     <dimen name="list_visible_scrollbar_padding">48dip</dimen>
+    <dimen name="detail_contact_photo_size">256dip</dimen>
 </resources>
diff --git a/res/values/dimens.xml b/res/values/dimens.xml
index cbfccd5..c53e03f 100644
--- a/res/values/dimens.xml
+++ b/res/values/dimens.xml
@@ -80,7 +80,7 @@
     <dimen name="detail_contact_photo_margin">8dip</dimen>
 
     <!-- Width and height of the contact photo on the contact detail page -->
-    <dimen name="detail_contact_photo_size">256dip</dimen>
+    <dimen name="detail_contact_photo_size">128dip</dimen>
 
     <!-- Left and right padding for a contact detail item -->
     <dimen name="detail_item_icon_margin">8dip</dimen>
diff --git a/src/com/android/contacts/detail/ContactDetailFragment.java b/src/com/android/contacts/detail/ContactDetailFragment.java
index c3ccfa2..29aa51a 100644
--- a/src/com/android/contacts/detail/ContactDetailFragment.java
+++ b/src/com/android/contacts/detail/ContactDetailFragment.java
@@ -50,8 +50,6 @@
 import android.app.Activity;
 import android.app.Fragment;
 import android.app.SearchManager;
-import android.content.ClipData;
-import android.content.ClipboardManager;
 import android.content.ContentUris;
 import android.content.ContentValues;
 import android.content.Context;
@@ -85,7 +83,6 @@
 import android.provider.ContactsContract.Data;
 import android.provider.ContactsContract.Directory;
 import android.provider.ContactsContract.DisplayNameSources;
-import android.provider.ContactsContract.PhoneLookup;
 import android.provider.ContactsContract.RawContacts;
 import android.provider.ContactsContract.StatusUpdates;
 import android.telephony.PhoneNumberUtils;
@@ -93,11 +90,15 @@
 import android.util.Log;
 import android.view.ContextMenu;
 import android.view.ContextMenu.ContextMenuInfo;
+import android.view.DragEvent;
 import android.view.KeyEvent;
 import android.view.LayoutInflater;
 import android.view.MenuItem;
+import android.view.MotionEvent;
 import android.view.View;
 import android.view.View.OnClickListener;
+import android.view.View.OnDragListener;
+import android.view.View.OnTouchListener;
 import android.view.ViewGroup;
 import android.widget.AbsListView.OnScrollListener;
 import android.widget.AdapterView;
@@ -110,7 +111,6 @@
 import android.widget.ListPopupWindow;
 import android.widget.ListView;
 import android.widget.TextView;
-import android.widget.Toast;
 
 import java.util.ArrayList;
 import java.util.Collections;
@@ -213,6 +213,36 @@
 
     private ListPopupWindow mPopup;
 
+    /**
+     * This is to forward touch events to the list view to enable users to scroll the list view
+     * from the blank area underneath the static photo when the layout with static photo is used.
+     */
+    private OnTouchListener mForwardTouchToListView = new OnTouchListener() {
+        @Override
+        public boolean onTouch(View v, MotionEvent event) {
+            if (mListView != null) {
+                mListView.dispatchTouchEvent(event);
+                return true;
+            }
+            return false;
+        }
+    };
+
+    /**
+     * This is to forward drag events to the list view to enable users to scroll the list view
+     * from the blank area underneath the static photo when the layout with static photo is used.
+     */
+    private OnDragListener mForwardDragToListView = new OnDragListener() {
+        @Override
+        public boolean onDrag(View v, DragEvent event) {
+            if (mListView != null) {
+                mListView.dispatchDragEvent(event);
+                return true;
+            }
+            return false;
+        }
+    };
+
     public ContactDetailFragment() {
         // Explicit constructor for inflation
     }
@@ -257,6 +287,10 @@
     @Override
     public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedState) {
         mView = inflater.inflate(R.layout.contact_detail_fragment, container, false);
+        // Set the touch and drag listener to forward the event to the mListView so that
+        // vertical scrolling can happen from outside of the list view.
+        mView.setOnTouchListener(mForwardTouchToListView);
+        mView.setOnDragListener(mForwardDragToListView);
 
         mInflater = inflater;
 
diff --git a/src/com/android/contacts/detail/ContactDetailFragmentCarousel.java b/src/com/android/contacts/detail/ContactDetailFragmentCarousel.java
index 7153b8d..7af9b28 100644
--- a/src/com/android/contacts/detail/ContactDetailFragmentCarousel.java
+++ b/src/com/android/contacts/detail/ContactDetailFragmentCarousel.java
@@ -31,8 +31,7 @@
 /**
  * This is a horizontally scrolling carousel with 2 fragments: one to see info about the contact and
  * one to see updates from the contact. Depending on the scroll position and user selection of which
- * fragment to currently view, the alpha values and touch interceptors over each fragment are
- * configured accordingly.
+ * fragment to currently view, the touch interceptors over each fragment are configured accordingly.
  */
 public class ContactDetailFragmentCarousel extends HorizontalScrollView implements OnTouchListener {
 
@@ -62,12 +61,6 @@
     private int mMinFragmentWidth = Integer.MIN_VALUE;
 
     /**
-     * Maximum alpha value of the overlay on the fragment that is not currently selected
-     * (if there are 1+ fragments in the carousel).
-     */
-    private static final float MAX_ALPHA = 0.5f;
-
-    /**
      * Fragment width (if there are 1+ fragments in the carousel) as defined as a fraction of the
      * screen width.
      */
@@ -147,11 +140,6 @@
     public void setCurrentPage(int pageIndex) {
         mCurrentPage = pageIndex;
 
-        if (mAboutFragment != null && mUpdatesFragment != null) {
-            mAboutFragment.setAlphaLayerValue(mCurrentPage == ABOUT_PAGE ? 0 : MAX_ALPHA);
-            mUpdatesFragment.setAlphaLayerValue(mCurrentPage == UPDATES_PAGE ? 0 : MAX_ALPHA);
-        }
-
         updateTouchInterceptors();
     }
 
@@ -215,12 +203,6 @@
         }
     }
 
-    private void updateAlphaLayers() {
-        float alpha = mLastScrollPosition * MAX_ALPHA / mAllowedHorizontalScrollLength;
-        mAboutFragment.setAlphaLayerValue(alpha);
-        mUpdatesFragment.setAlphaLayerValue(MAX_ALPHA - alpha);
-    }
-
     @Override
     protected void onScrollChanged(int l, int t, int oldl, int oldt) {
         super.onScrollChanged(l, t, oldl, oldt);
@@ -228,7 +210,6 @@
             return;
         }
         mLastScrollPosition = l;
-        updateAlphaLayers();
     }
 
     private void snapToEdge() {
diff --git a/src/com/android/contacts/detail/ContactDetailLayoutController.java b/src/com/android/contacts/detail/ContactDetailLayoutController.java
index 12facef..a99f35f 100644
--- a/src/com/android/contacts/detail/ContactDetailLayoutController.java
+++ b/src/com/android/contacts/detail/ContactDetailLayoutController.java
@@ -44,8 +44,6 @@
 import android.widget.AbsListView;
 import android.widget.AbsListView.OnScrollListener;
 
-import android.util.Log;
-
 /**
  * Determines the layout of the contact card.
  */
@@ -61,13 +59,27 @@
     private final int SINGLE_PANE_FADE_IN_DURATION = 275;
 
     /**
-     * There are 3 possible layouts for the contact detail screen:
-     * 1. TWO_COLUMN - Tall and wide screen so the 2 pages can be shown side-by-side
-     * 2. VIEW_PAGER_AND_TAB_CAROUSEL - Tall and narrow screen to allow swipe between the 2 pages
-     * 3. FRAGMENT_CAROUSEL- Short and wide screen to allow half of the other page to show at a time
+     * There are 4 possible layouts for the contact detail screen: TWO_COLUMN,
+     * VIEW_PAGER_AND_TAB_CAROUSEL, FRAGMENT_CAROUSEL, and TWO_COLUMN_FRAGMENT_CAROUSEL.
      */
-    private enum LayoutMode {
-        TWO_COLUMN, VIEW_PAGER_AND_TAB_CAROUSEL, FRAGMENT_CAROUSEL,
+    private interface LayoutMode {
+        /**
+         * Tall and wide screen with details and updates shown side-by-side.
+         */
+        static final int TWO_COLUMN = 0;
+        /**
+         * Tall and narrow screen to allow swipe between the details and updates.
+         */
+        static final int VIEW_PAGER_AND_TAB_CAROUSEL = 1;
+        /**
+         * Short and wide screen to allow part of the other page to show.
+         */
+        static final int FRAGMENT_CAROUSEL = 2;
+        /**
+         * Same as FRAGMENT_CAROUSEL (allowing part of the other page to show) except the details
+         * layout is similar to the details layout in TWO_COLUMN mode.
+         */
+        static final int TWO_COLUMN_FRAGMENT_CAROUSEL = 3;
     }
 
     private final Activity mActivity;
@@ -98,7 +110,7 @@
 
     private boolean mContactHasUpdates;
 
-    private LayoutMode mLayoutMode;
+    private int mLayoutMode;
 
     public ContactDetailLayoutController(Activity activity, Bundle savedState,
             FragmentManager fragmentManager, TransitionAnimationView animationView,
@@ -135,7 +147,11 @@
         if (mViewPager != null) {
             mLayoutMode = LayoutMode.VIEW_PAGER_AND_TAB_CAROUSEL;
         } else if (mFragmentCarousel != null) {
-            mLayoutMode = LayoutMode.FRAGMENT_CAROUSEL;
+            if (PhoneCapabilityTester.isUsingTwoPanes(mActivity)) {
+                mLayoutMode = LayoutMode.TWO_COLUMN_FRAGMENT_CAROUSEL;
+            } else {
+                mLayoutMode = LayoutMode.FRAGMENT_CAROUSEL;
+            }
         } else {
             mLayoutMode = LayoutMode.TWO_COLUMN;
         }
@@ -171,7 +187,7 @@
         }
 
         switch (mLayoutMode) {
-            case VIEW_PAGER_AND_TAB_CAROUSEL: {
+            case LayoutMode.VIEW_PAGER_AND_TAB_CAROUSEL: {
                 // Inflate 2 view containers to pass in as children to the {@link ViewPager},
                 // which will in turn be the parents to the mDetailFragment and mUpdatesFragment
                 // since the fragments must have the same parent view IDs in both landscape and
@@ -209,7 +225,7 @@
                 mViewPager.setCurrentItem(currentPageIndex);
                 break;
             }
-            case TWO_COLUMN: {
+            case LayoutMode.TWO_COLUMN: {
                 if (!fragmentsAddedToFragmentManager) {
                     FragmentTransaction transaction = mFragmentManager.beginTransaction();
                     transaction.add(R.id.about_fragment_container, mDetailFragment,
@@ -221,7 +237,8 @@
                 }
                 break;
             }
-            case FRAGMENT_CAROUSEL: {
+            case LayoutMode.FRAGMENT_CAROUSEL:
+            case LayoutMode.TWO_COLUMN_FRAGMENT_CAROUSEL: {
                 // Add the fragments to the fragment containers in the carousel using a
                 // {@link FragmentTransaction} if they haven't already been added to the
                 // {@link FragmentManager}.
@@ -297,19 +314,27 @@
 
     public void showEmptyState() {
         switch (mLayoutMode) {
-            case FRAGMENT_CAROUSEL: {
+            case LayoutMode.FRAGMENT_CAROUSEL: {
                 mFragmentCarousel.setCurrentPage(0);
                 mFragmentCarousel.enableSwipe(false);
                 mDetailFragment.showEmptyState();
                 break;
             }
-            case TWO_COLUMN: {
+            case LayoutMode.TWO_COLUMN: {
                 mDetailFragment.setShowStaticPhoto(false);
                 mUpdatesFragmentView.setVisibility(View.GONE);
                 mDetailFragment.showEmptyState();
                 break;
             }
-            case VIEW_PAGER_AND_TAB_CAROUSEL: {
+            case LayoutMode.TWO_COLUMN_FRAGMENT_CAROUSEL: {
+                mFragmentCarousel.setCurrentPage(0);
+                mFragmentCarousel.enableSwipe(false);
+                mDetailFragment.setShowStaticPhoto(false);
+                mUpdatesFragmentView.setVisibility(View.GONE);
+                mDetailFragment.showEmptyState();
+                break;
+            }
+            case LayoutMode.VIEW_PAGER_AND_TAB_CAROUSEL: {
                 mDetailFragment.setShowStaticPhoto(false);
                 mDetailFragment.showEmptyState();
                 mTabCarousel.loadData(null);
@@ -337,7 +362,7 @@
         boolean isDifferentContact = !UriUtils.areEqual(previousContactUri, mContactUri);
 
         switch (mLayoutMode) {
-            case TWO_COLUMN: {
+            case LayoutMode.TWO_COLUMN: {
                 if (!isDifferentContact && animateStateChange) {
                     // This is screen is very hard to animate properly, because there is such a hard
                     // cut from the regular version. A proper animation would have to reflow text
@@ -352,7 +377,7 @@
                 mUpdatesFragmentView.setVisibility(View.VISIBLE);
                 break;
             }
-            case VIEW_PAGER_AND_TAB_CAROUSEL: {
+            case LayoutMode.VIEW_PAGER_AND_TAB_CAROUSEL: {
                 // Update and show the tab carousel (also restore its last saved position)
                 mTabCarousel.loadData(mContactData);
                 mTabCarousel.restoreYCoordinate();
@@ -370,7 +395,7 @@
                 }
                 break;
             }
-            case FRAGMENT_CAROUSEL: {
+            case LayoutMode.FRAGMENT_CAROUSEL: {
                 // Allow swiping between all fragments
                 mFragmentCarousel.enableSwipe(true);
                 if (!isDifferentContact && animateStateChange) {
@@ -378,6 +403,15 @@
                 }
                 break;
             }
+            case LayoutMode.TWO_COLUMN_FRAGMENT_CAROUSEL: {
+                // Allow swiping between all fragments
+                mFragmentCarousel.enableSwipe(true);
+                if (!isDifferentContact && animateStateChange) {
+                    mFragmentCarousel.animateAppear();
+                }
+                mDetailFragment.setShowStaticPhoto(false);
+                break;
+            }
             default:
                 throw new IllegalStateException("Invalid LayoutMode " + mLayoutMode);
         }
@@ -404,13 +438,13 @@
         boolean isDifferentContact = !UriUtils.areEqual(previousContactUri, mContactUri);
 
         switch (mLayoutMode) {
-            case TWO_COLUMN:
+            case LayoutMode.TWO_COLUMN:
                 // Show the static photo which is next to the list of scrolling contact details
                 mDetailFragment.setShowStaticPhoto(true);
                 // Hide the updates fragment
                 mUpdatesFragmentView.setVisibility(View.GONE);
                 break;
-            case VIEW_PAGER_AND_TAB_CAROUSEL:
+            case LayoutMode.VIEW_PAGER_AND_TAB_CAROUSEL:
                 // Hide the tab carousel
                 mTabCarousel.setVisibility(View.GONE);
                 // Update ViewPager to disable swipe so that it only shows the detail fragment
@@ -418,12 +452,16 @@
                 mViewPagerAdapter.enableSwipe(false);
                 mViewPager.setCurrentItem(0, false /* smooth transition */);
                 break;
-            case FRAGMENT_CAROUSEL: {
+            case LayoutMode.FRAGMENT_CAROUSEL:
                 // Disable swipe so only the detail fragment shows
                 mFragmentCarousel.setCurrentPage(0);
                 mFragmentCarousel.enableSwipe(false);
                 break;
-            }
+            case LayoutMode.TWO_COLUMN_FRAGMENT_CAROUSEL:
+                mFragmentCarousel.setCurrentPage(0);
+                mFragmentCarousel.enableSwipe(false);
+                mDetailFragment.setShowStaticPhoto(true);
+                break;
             default:
                 throw new IllegalStateException("Invalid LayoutMode " + mLayoutMode);
         }