Merge "Contacts app no longer gets to be in acore."
diff --git a/res/drawable-hdpi/dial_background_texture.png b/res/drawable-hdpi/dial_background_texture.png
index 5b299fd..7ed0984 100644
--- a/res/drawable-hdpi/dial_background_texture.png
+++ b/res/drawable-hdpi/dial_background_texture.png
Binary files differ
diff --git a/res/drawable-hdpi/dial_num_0_wht.png b/res/drawable-hdpi/dial_num_0_wht.png
index a0720f3..9d7fc62 100644
--- a/res/drawable-hdpi/dial_num_0_wht.png
+++ b/res/drawable-hdpi/dial_num_0_wht.png
Binary files differ
diff --git a/res/drawable-hdpi/dial_num_1_wht.png b/res/drawable-hdpi/dial_num_1_wht.png
index 0c79720..e941c52 100644
--- a/res/drawable-hdpi/dial_num_1_wht.png
+++ b/res/drawable-hdpi/dial_num_1_wht.png
Binary files differ
diff --git a/res/drawable-hdpi/dial_num_2_wht.png b/res/drawable-hdpi/dial_num_2_wht.png
index ab90531..fc5540b 100644
--- a/res/drawable-hdpi/dial_num_2_wht.png
+++ b/res/drawable-hdpi/dial_num_2_wht.png
Binary files differ
diff --git a/res/drawable-hdpi/dial_num_3_wht.png b/res/drawable-hdpi/dial_num_3_wht.png
index 956cba9..45637b9 100644
--- a/res/drawable-hdpi/dial_num_3_wht.png
+++ b/res/drawable-hdpi/dial_num_3_wht.png
Binary files differ
diff --git a/res/drawable-hdpi/dial_num_4_wht.png b/res/drawable-hdpi/dial_num_4_wht.png
index 34e157c..af8c8aa 100644
--- a/res/drawable-hdpi/dial_num_4_wht.png
+++ b/res/drawable-hdpi/dial_num_4_wht.png
Binary files differ
diff --git a/res/drawable-hdpi/dial_num_5_wht.png b/res/drawable-hdpi/dial_num_5_wht.png
index 4a3560a..20ab0b1 100644
--- a/res/drawable-hdpi/dial_num_5_wht.png
+++ b/res/drawable-hdpi/dial_num_5_wht.png
Binary files differ
diff --git a/res/drawable-hdpi/dial_num_6_wht.png b/res/drawable-hdpi/dial_num_6_wht.png
index a60420b..8811b4b 100644
--- a/res/drawable-hdpi/dial_num_6_wht.png
+++ b/res/drawable-hdpi/dial_num_6_wht.png
Binary files differ
diff --git a/res/drawable-hdpi/dial_num_7_wht.png b/res/drawable-hdpi/dial_num_7_wht.png
index 95e4cff..ed6d749 100644
--- a/res/drawable-hdpi/dial_num_7_wht.png
+++ b/res/drawable-hdpi/dial_num_7_wht.png
Binary files differ
diff --git a/res/drawable-hdpi/dial_num_8_wht.png b/res/drawable-hdpi/dial_num_8_wht.png
index 4b17084..6844aeb 100644
--- a/res/drawable-hdpi/dial_num_8_wht.png
+++ b/res/drawable-hdpi/dial_num_8_wht.png
Binary files differ
diff --git a/res/drawable-hdpi/dial_num_9_wht.png b/res/drawable-hdpi/dial_num_9_wht.png
index f772901..df294be 100644
--- a/res/drawable-hdpi/dial_num_9_wht.png
+++ b/res/drawable-hdpi/dial_num_9_wht.png
Binary files differ
diff --git a/res/drawable-hdpi/dial_num_pound_wht.png b/res/drawable-hdpi/dial_num_pound_wht.png
index 1d7f55a..46316e5 100644
--- a/res/drawable-hdpi/dial_num_pound_wht.png
+++ b/res/drawable-hdpi/dial_num_pound_wht.png
Binary files differ
diff --git a/res/drawable-hdpi/dial_num_star_wht.png b/res/drawable-hdpi/dial_num_star_wht.png
index 2add63b..c36e31c 100644
--- a/res/drawable-hdpi/dial_num_star_wht.png
+++ b/res/drawable-hdpi/dial_num_star_wht.png
Binary files differ
diff --git a/res/drawable-hdpi/ic_dial_action_delete.png b/res/drawable-hdpi/ic_dial_action_delete.png
index f93a308..0bf8563 100644
--- a/res/drawable-hdpi/ic_dial_action_delete.png
+++ b/res/drawable-hdpi/ic_dial_action_delete.png
Binary files differ
diff --git a/res/drawable-hdpi/ic_text_holo_dark.png b/res/drawable-hdpi/ic_text_holo_dark.png
index 1816201..6d21e42 100644
--- a/res/drawable-hdpi/ic_text_holo_dark.png
+++ b/res/drawable-hdpi/ic_text_holo_dark.png
Binary files differ
diff --git a/res/drawable-hdpi/list_activated_holo.9.png b/res/drawable-hdpi/list_activated_holo.9.png
index 36ccb79..7b89319 100644
--- a/res/drawable-hdpi/list_activated_holo.9.png
+++ b/res/drawable-hdpi/list_activated_holo.9.png
Binary files differ
diff --git a/res/drawable-hdpi/list_focused_holo.9.png b/res/drawable-hdpi/list_focused_holo.9.png
index 54c5c2d..e962ce8 100644
--- a/res/drawable-hdpi/list_focused_holo.9.png
+++ b/res/drawable-hdpi/list_focused_holo.9.png
Binary files differ
diff --git a/res/drawable-hdpi/list_pressed_holo.9.png b/res/drawable-hdpi/list_pressed_holo.9.png
index 423fa4b..dd183c0 100644
--- a/res/drawable-hdpi/list_pressed_holo.9.png
+++ b/res/drawable-hdpi/list_pressed_holo.9.png
Binary files differ
diff --git a/res/drawable-mdpi/dial_background_texture.png b/res/drawable-mdpi/dial_background_texture.png
index 881f3a0..f0ba700 100644
--- a/res/drawable-mdpi/dial_background_texture.png
+++ b/res/drawable-mdpi/dial_background_texture.png
Binary files differ
diff --git a/res/drawable-mdpi/dial_num_0_wht.png b/res/drawable-mdpi/dial_num_0_wht.png
index 5391fb3..96a0dcd 100644
--- a/res/drawable-mdpi/dial_num_0_wht.png
+++ b/res/drawable-mdpi/dial_num_0_wht.png
Binary files differ
diff --git a/res/drawable-mdpi/dial_num_1_wht.png b/res/drawable-mdpi/dial_num_1_wht.png
index ff8f125..56dbca3 100644
--- a/res/drawable-mdpi/dial_num_1_wht.png
+++ b/res/drawable-mdpi/dial_num_1_wht.png
Binary files differ
diff --git a/res/drawable-mdpi/dial_num_2_wht.png b/res/drawable-mdpi/dial_num_2_wht.png
index 041bafb..4c0991c 100644
--- a/res/drawable-mdpi/dial_num_2_wht.png
+++ b/res/drawable-mdpi/dial_num_2_wht.png
Binary files differ
diff --git a/res/drawable-mdpi/dial_num_3_wht.png b/res/drawable-mdpi/dial_num_3_wht.png
index b91b4f5..81bf770 100644
--- a/res/drawable-mdpi/dial_num_3_wht.png
+++ b/res/drawable-mdpi/dial_num_3_wht.png
Binary files differ
diff --git a/res/drawable-mdpi/dial_num_4_wht.png b/res/drawable-mdpi/dial_num_4_wht.png
index 912b4cb..5f07476 100644
--- a/res/drawable-mdpi/dial_num_4_wht.png
+++ b/res/drawable-mdpi/dial_num_4_wht.png
Binary files differ
diff --git a/res/drawable-mdpi/dial_num_5_wht.png b/res/drawable-mdpi/dial_num_5_wht.png
index efd385f..5cf9c7a 100644
--- a/res/drawable-mdpi/dial_num_5_wht.png
+++ b/res/drawable-mdpi/dial_num_5_wht.png
Binary files differ
diff --git a/res/drawable-mdpi/dial_num_6_wht.png b/res/drawable-mdpi/dial_num_6_wht.png
index c0f47c5..ceffb29 100644
--- a/res/drawable-mdpi/dial_num_6_wht.png
+++ b/res/drawable-mdpi/dial_num_6_wht.png
Binary files differ
diff --git a/res/drawable-mdpi/dial_num_7_wht.png b/res/drawable-mdpi/dial_num_7_wht.png
index 5644f2b..022ef9c 100644
--- a/res/drawable-mdpi/dial_num_7_wht.png
+++ b/res/drawable-mdpi/dial_num_7_wht.png
Binary files differ
diff --git a/res/drawable-mdpi/dial_num_8_wht.png b/res/drawable-mdpi/dial_num_8_wht.png
index d0c517d..c470e68 100644
--- a/res/drawable-mdpi/dial_num_8_wht.png
+++ b/res/drawable-mdpi/dial_num_8_wht.png
Binary files differ
diff --git a/res/drawable-mdpi/dial_num_9_wht.png b/res/drawable-mdpi/dial_num_9_wht.png
index fb443ec..27d94ef 100644
--- a/res/drawable-mdpi/dial_num_9_wht.png
+++ b/res/drawable-mdpi/dial_num_9_wht.png
Binary files differ
diff --git a/res/drawable-mdpi/dial_num_pound_wht.png b/res/drawable-mdpi/dial_num_pound_wht.png
index 11751ec..68908c3 100644
--- a/res/drawable-mdpi/dial_num_pound_wht.png
+++ b/res/drawable-mdpi/dial_num_pound_wht.png
Binary files differ
diff --git a/res/drawable-mdpi/dial_num_star_wht.png b/res/drawable-mdpi/dial_num_star_wht.png
index 61b24c1..cb8aa28 100644
--- a/res/drawable-mdpi/dial_num_star_wht.png
+++ b/res/drawable-mdpi/dial_num_star_wht.png
Binary files differ
diff --git a/res/drawable-mdpi/ic_dial_action_delete.png b/res/drawable-mdpi/ic_dial_action_delete.png
index 32b0022..98341e9 100644
--- a/res/drawable-mdpi/ic_dial_action_delete.png
+++ b/res/drawable-mdpi/ic_dial_action_delete.png
Binary files differ
diff --git a/res/drawable-mdpi/ic_text_holo_dark.png b/res/drawable-mdpi/ic_text_holo_dark.png
index bbaa84f..80b95ee 100644
--- a/res/drawable-mdpi/ic_text_holo_dark.png
+++ b/res/drawable-mdpi/ic_text_holo_dark.png
Binary files differ
diff --git a/res/drawable-mdpi/list_activated_holo.9.png b/res/drawable-mdpi/list_activated_holo.9.png
index f7cd24e..4d98919 100644
--- a/res/drawable-mdpi/list_activated_holo.9.png
+++ b/res/drawable-mdpi/list_activated_holo.9.png
Binary files differ
diff --git a/res/drawable-mdpi/list_focused_holo.9.png b/res/drawable-mdpi/list_focused_holo.9.png
index 32cb628..6e041f3 100644
--- a/res/drawable-mdpi/list_focused_holo.9.png
+++ b/res/drawable-mdpi/list_focused_holo.9.png
Binary files differ
diff --git a/res/drawable-mdpi/list_pressed_holo.9.png b/res/drawable-mdpi/list_pressed_holo.9.png
index 7ea8666..9358dd8 100644
--- a/res/drawable-mdpi/list_pressed_holo.9.png
+++ b/res/drawable-mdpi/list_pressed_holo.9.png
Binary files differ
diff --git a/res/drawable-xhdpi/bg_status_contact_widget.9.png b/res/drawable-xhdpi/bg_status_contact_widget.9.png
index db34bf4..ced5296 100644
--- a/res/drawable-xhdpi/bg_status_contact_widget.9.png
+++ b/res/drawable-xhdpi/bg_status_contact_widget.9.png
Binary files differ
diff --git a/res/drawable-xhdpi/contacts_widget_preview.png b/res/drawable-xhdpi/contacts_widget_preview.png
index 65ac914..1f42ca0 100644
--- a/res/drawable-xhdpi/contacts_widget_preview.png
+++ b/res/drawable-xhdpi/contacts_widget_preview.png
Binary files differ
diff --git a/res/drawable-xhdpi/dial_background_texture.png b/res/drawable-xhdpi/dial_background_texture.png
index 4c8617a..3d6e8c7 100644
--- a/res/drawable-xhdpi/dial_background_texture.png
+++ b/res/drawable-xhdpi/dial_background_texture.png
Binary files differ
diff --git a/res/drawable-xhdpi/dial_num_0_wht.png b/res/drawable-xhdpi/dial_num_0_wht.png
index 99aca70..f6f96cc 100644
--- a/res/drawable-xhdpi/dial_num_0_wht.png
+++ b/res/drawable-xhdpi/dial_num_0_wht.png
Binary files differ
diff --git a/res/drawable-xhdpi/dial_num_1_wht.png b/res/drawable-xhdpi/dial_num_1_wht.png
index 5a54bfd..8333aba 100644
--- a/res/drawable-xhdpi/dial_num_1_wht.png
+++ b/res/drawable-xhdpi/dial_num_1_wht.png
Binary files differ
diff --git a/res/drawable-xhdpi/dial_num_2_wht.png b/res/drawable-xhdpi/dial_num_2_wht.png
index 3407d79..02f8fdf 100644
--- a/res/drawable-xhdpi/dial_num_2_wht.png
+++ b/res/drawable-xhdpi/dial_num_2_wht.png
Binary files differ
diff --git a/res/drawable-xhdpi/dial_num_3_wht.png b/res/drawable-xhdpi/dial_num_3_wht.png
index dd16bbb..44383b5 100644
--- a/res/drawable-xhdpi/dial_num_3_wht.png
+++ b/res/drawable-xhdpi/dial_num_3_wht.png
Binary files differ
diff --git a/res/drawable-xhdpi/dial_num_4_wht.png b/res/drawable-xhdpi/dial_num_4_wht.png
index 98f8773..f90cb73 100644
--- a/res/drawable-xhdpi/dial_num_4_wht.png
+++ b/res/drawable-xhdpi/dial_num_4_wht.png
Binary files differ
diff --git a/res/drawable-xhdpi/dial_num_5_wht.png b/res/drawable-xhdpi/dial_num_5_wht.png
index 12a92bf..c41c615 100644
--- a/res/drawable-xhdpi/dial_num_5_wht.png
+++ b/res/drawable-xhdpi/dial_num_5_wht.png
Binary files differ
diff --git a/res/drawable-xhdpi/dial_num_6_wht.png b/res/drawable-xhdpi/dial_num_6_wht.png
index 39c3eda..4c7a235 100644
--- a/res/drawable-xhdpi/dial_num_6_wht.png
+++ b/res/drawable-xhdpi/dial_num_6_wht.png
Binary files differ
diff --git a/res/drawable-xhdpi/dial_num_7_wht.png b/res/drawable-xhdpi/dial_num_7_wht.png
index 5e3a0b0..fabca99 100644
--- a/res/drawable-xhdpi/dial_num_7_wht.png
+++ b/res/drawable-xhdpi/dial_num_7_wht.png
Binary files differ
diff --git a/res/drawable-xhdpi/dial_num_8_wht.png b/res/drawable-xhdpi/dial_num_8_wht.png
index d68142d..7bd70b0 100644
--- a/res/drawable-xhdpi/dial_num_8_wht.png
+++ b/res/drawable-xhdpi/dial_num_8_wht.png
Binary files differ
diff --git a/res/drawable-xhdpi/dial_num_9_wht.png b/res/drawable-xhdpi/dial_num_9_wht.png
index b34bc1d..207276c 100644
--- a/res/drawable-xhdpi/dial_num_9_wht.png
+++ b/res/drawable-xhdpi/dial_num_9_wht.png
Binary files differ
diff --git a/res/drawable-xhdpi/dial_num_pound_wht.png b/res/drawable-xhdpi/dial_num_pound_wht.png
index a4ead0a..b2cac17 100644
--- a/res/drawable-xhdpi/dial_num_pound_wht.png
+++ b/res/drawable-xhdpi/dial_num_pound_wht.png
Binary files differ
diff --git a/res/drawable-xhdpi/dial_num_star_wht.png b/res/drawable-xhdpi/dial_num_star_wht.png
index ba0a787..2862c45 100644
--- a/res/drawable-xhdpi/dial_num_star_wht.png
+++ b/res/drawable-xhdpi/dial_num_star_wht.png
Binary files differ
diff --git a/res/drawable-xhdpi/frame_thumbnail_contact_widget_focused_holo.png b/res/drawable-xhdpi/frame_thumbnail_contact_widget_focused_holo.png
index a05ca8a..157ef56 100644
--- a/res/drawable-xhdpi/frame_thumbnail_contact_widget_focused_holo.png
+++ b/res/drawable-xhdpi/frame_thumbnail_contact_widget_focused_holo.png
Binary files differ
diff --git a/res/drawable-xhdpi/frame_thumbnail_contact_widget_holo.png b/res/drawable-xhdpi/frame_thumbnail_contact_widget_holo.png
index bf2e4a8..7719710 100644
--- a/res/drawable-xhdpi/frame_thumbnail_contact_widget_holo.png
+++ b/res/drawable-xhdpi/frame_thumbnail_contact_widget_holo.png
Binary files differ
diff --git a/res/drawable-xhdpi/frame_thumbnail_contact_widget_pressed_holo.png b/res/drawable-xhdpi/frame_thumbnail_contact_widget_pressed_holo.png
index 6541c62..8c5008b 100644
--- a/res/drawable-xhdpi/frame_thumbnail_contact_widget_pressed_holo.png
+++ b/res/drawable-xhdpi/frame_thumbnail_contact_widget_pressed_holo.png
Binary files differ
diff --git a/res/drawable-xhdpi/ic_dial_action_delete.png b/res/drawable-xhdpi/ic_dial_action_delete.png
index 9c0b4f0..989e8b1 100644
--- a/res/drawable-xhdpi/ic_dial_action_delete.png
+++ b/res/drawable-xhdpi/ic_dial_action_delete.png
Binary files differ
diff --git a/res/drawable-xhdpi/ic_text_holo_dark.png b/res/drawable-xhdpi/ic_text_holo_dark.png
index 8c697d9..e80a042 100644
--- a/res/drawable-xhdpi/ic_text_holo_dark.png
+++ b/res/drawable-xhdpi/ic_text_holo_dark.png
Binary files differ
diff --git a/res/drawable-xhdpi/list_activated_holo.9.png b/res/drawable-xhdpi/list_activated_holo.9.png
index bb9a7f9..4e13add 100644
--- a/res/drawable-xhdpi/list_activated_holo.9.png
+++ b/res/drawable-xhdpi/list_activated_holo.9.png
Binary files differ
diff --git a/res/drawable-xhdpi/list_focused_holo.9.png b/res/drawable-xhdpi/list_focused_holo.9.png
index 6051708..9c90c2b 100644
--- a/res/drawable-xhdpi/list_focused_holo.9.png
+++ b/res/drawable-xhdpi/list_focused_holo.9.png
Binary files differ
diff --git a/res/drawable-xhdpi/list_pressed_holo.9.png b/res/drawable-xhdpi/list_pressed_holo.9.png
index f4b4c38..d0fc7e0 100644
--- a/res/drawable-xhdpi/list_pressed_holo.9.png
+++ b/res/drawable-xhdpi/list_pressed_holo.9.png
Binary files differ
diff --git a/src/com/android/contacts/activities/ContactDetailActivity.java b/src/com/android/contacts/activities/ContactDetailActivity.java
index 53c7f5e..3cd07ca 100644
--- a/src/com/android/contacts/activities/ContactDetailActivity.java
+++ b/src/com/android/contacts/activities/ContactDetailActivity.java
@@ -28,6 +28,7 @@
 import com.android.contacts.detail.ContactDetailViewPagerAdapter;
 import com.android.contacts.detail.ContactLoaderFragment;
 import com.android.contacts.detail.ContactLoaderFragment.ContactLoaderFragmentListener;
+import com.android.contacts.detail.TabCarouselScrollManager;
 import com.android.contacts.interactions.ContactDeletionInteraction;
 import com.android.contacts.model.AccountWithDataSet;
 import com.android.contacts.util.PhoneCapabilityTester;
@@ -55,8 +56,6 @@
 import android.view.View;
 import android.view.View.OnClickListener;
 import android.view.ViewGroup;
-import android.widget.AbsListView;
-import android.widget.AbsListView.OnScrollListener;
 import android.widget.CheckBox;
 import android.widget.Toast;
 
@@ -153,8 +152,7 @@
         }
 
         mDetailFragment.setListener(mFragmentListener);
-        mDetailFragment.setVerticalScrollListener(mVerticalScrollListener);
-        mUpdatesFragment.setVerticalScrollListener(mVerticalScrollListener);
+        TabCarouselScrollManager.bind(mTabCarousel, mDetailFragment, mUpdatesFragment);
         mDetailFragment.setData(mLookupUri, mContactData);
         mUpdatesFragment.setData(mLookupUri, mContactData);
 
@@ -435,6 +433,7 @@
             mRootView.addView(mContentView);
             mDetailFragment = (ContactDetailFragment) getFragmentManager().findFragmentById(
                     R.id.contact_detail_fragment);
+            mDetailFragment.setListener(mFragmentListener);
         }
         // Reset contact data
         if (mDetailFragment != null) {
@@ -555,34 +554,6 @@
         }
     };
 
-    private OnScrollListener mVerticalScrollListener = new OnScrollListener() {
-
-        @Override
-        public void onScroll(
-                AbsListView view, int firstVisibleItem, int visibleItemCount, int totalItemCount) {
-            if (mTabCarousel == null) {
-                return;
-            }
-            // If the FIRST item is not visible on the screen, then the carousel must be pinned
-            // at the top of the screen.
-            if (firstVisibleItem != 0) {
-                mTabCarousel.setY(-mTabCarousel.getAllowedVerticalScrollLength());
-                return;
-            }
-            View topView = view.getChildAt(firstVisibleItem);
-            if (topView == null) {
-                return;
-            }
-            int amtToScroll = Math.max((int) view.getChildAt(firstVisibleItem).getY(),
-                    - mTabCarousel.getAllowedVerticalScrollLength());
-            mTabCarousel.setY(amtToScroll);
-        }
-
-        @Override
-        public void onScrollStateChanged(AbsListView view, int scrollState) {}
-
-    };
-
     /**
      * This interface should be implemented by {@link Fragment}s within this
      * activity so that the activity can determine whether the currently
diff --git a/src/com/android/contacts/detail/ContactDetailLayoutController.java b/src/com/android/contacts/detail/ContactDetailLayoutController.java
index 7abe76e..f3cc016 100644
--- a/src/com/android/contacts/detail/ContactDetailLayoutController.java
+++ b/src/com/android/contacts/detail/ContactDetailLayoutController.java
@@ -29,8 +29,6 @@
 import android.view.LayoutInflater;
 import android.view.View;
 import android.view.ViewGroup;
-import android.widget.AbsListView;
-import android.widget.AbsListView.OnScrollListener;
 
 /**
  * Determines the layout of the contact card.
@@ -115,8 +113,6 @@
         }
 
         mDetailFragment.setListener(mContactDetailFragmentListener);
-        mDetailFragment.setVerticalScrollListener(mVerticalScrollListener);
-        mUpdatesFragment.setVerticalScrollListener(mVerticalScrollListener);
 
         switch (mLayoutMode) {
             case VIEW_PAGER_AND_CAROUSEL: {
@@ -151,6 +147,7 @@
                 }
                 transaction.commit();
                 mFragmentManager.executePendingTransactions();
+                TabCarouselScrollManager.bind(mTabCarousel, mDetailFragment, mUpdatesFragment);
                 break;
             }
             case TWO_COLUMN: {
@@ -306,32 +303,4 @@
             mViewPager.setCurrentItem(position);
         }
     };
-
-    private OnScrollListener mVerticalScrollListener = new OnScrollListener() {
-
-        @Override
-        public void onScroll(
-                AbsListView view, int firstVisibleItem, int visibleItemCount, int totalItemCount) {
-            if (mTabCarousel == null) {
-                return;
-            }
-            // If the FIRST item is not visible on the screen, then the carousel must be pinned
-            // at the top of the screen.
-            if (firstVisibleItem != 0) {
-                mTabCarousel.setY(-mTabCarousel.getAllowedVerticalScrollLength());
-                return;
-            }
-            View topView = view.getChildAt(firstVisibleItem);
-            if (topView == null) {
-                return;
-            }
-            int amtToScroll = Math.max((int) view.getChildAt(firstVisibleItem).getY(),
-                    -mTabCarousel.getAllowedVerticalScrollLength());
-            mTabCarousel.setY(amtToScroll);
-        }
-
-        @Override
-        public void onScrollStateChanged(AbsListView view, int scrollState) {}
-
-    };
 }
diff --git a/src/com/android/contacts/detail/TabCarouselScrollManager.java b/src/com/android/contacts/detail/TabCarouselScrollManager.java
new file mode 100644
index 0000000..2415b50
--- /dev/null
+++ b/src/com/android/contacts/detail/TabCarouselScrollManager.java
@@ -0,0 +1,74 @@
+/*
+ * Copyright (C) 2011 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.contacts.detail;
+
+import android.view.View;
+import android.widget.AbsListView;
+import android.widget.AbsListView.OnScrollListener;
+
+/**
+ * Takes care of managing scrolling for the side-by-side views using the tab carousel.
+ */
+public class TabCarouselScrollManager {
+    private final ContactDetailTabCarousel mTabCarousel;
+    private final ContactDetailFragment mAboutFragment;
+    private final ContactDetailUpdatesFragment mUpdatesFragment;
+    private final OnScrollListener mVerticalScrollListener = new OnScrollListener() {
+        @Override
+        public void onScroll(AbsListView view, int firstVisibleItem, int visibleItemCount,
+                int totalItemCount) {
+            if (mTabCarousel == null) {
+                return;
+            }
+            // If the FIRST item is not visible on the screen, then the carousel must be pinned
+            // at the top of the screen.
+            if (firstVisibleItem != 0) {
+                mTabCarousel.setY(-mTabCarousel.getAllowedVerticalScrollLength());
+                return;
+            }
+            View topView = view.getChildAt(firstVisibleItem);
+            if (topView == null) {
+                return;
+            }
+            int amtToScroll = Math.max((int) view.getChildAt(firstVisibleItem).getY(),
+                    -mTabCarousel.getAllowedVerticalScrollLength());
+            mTabCarousel.setY(amtToScroll);
+        }
+
+        @Override
+        public void onScrollStateChanged(AbsListView view, int scrollState) {}
+    };
+
+    private TabCarouselScrollManager(ContactDetailTabCarousel tabCarousel,
+            ContactDetailFragment aboutFragment, ContactDetailUpdatesFragment updatesFragment) {
+        mTabCarousel = tabCarousel;
+        mAboutFragment = aboutFragment;
+        mUpdatesFragment = updatesFragment;
+    }
+
+    public void bind() {
+        mAboutFragment.setVerticalScrollListener(mVerticalScrollListener);
+        mUpdatesFragment.setVerticalScrollListener(mVerticalScrollListener);
+    }
+
+    public static void bind(ContactDetailTabCarousel tabCarousel,
+            ContactDetailFragment aboutFragment, ContactDetailUpdatesFragment updatesFragment) {
+        TabCarouselScrollManager scrollManager =
+                new TabCarouselScrollManager(tabCarousel, aboutFragment, updatesFragment);
+        scrollManager.bind();
+    }
+}