Merge "Reintroduce cross-fade on tablet when going from one contact to the next"
diff --git a/res/layout-sw580dp/contact_detail_container.xml b/res/layout-sw580dp/contact_detail_container.xml
index cdb789f..6ddc98d 100644
--- a/res/layout-sw580dp/contact_detail_container.xml
+++ b/res/layout-sw580dp/contact_detail_container.xml
@@ -17,7 +17,9 @@
 <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
     android:layout_width="match_parent"
     android:layout_height="match_parent"
-    android:orientation="vertical">
+    android:paddingLeft="16dip"
+    android:paddingTop="16dip"
+    android:paddingRight="16dip">
 
     <android.support.v4.view.ViewPager
         android:id="@+id/pager"
diff --git a/res/layout-sw580dp/people_activity.xml b/res/layout-sw580dp/people_activity.xml
index 9cf695d..80ede2d 100644
--- a/res/layout-sw580dp/people_activity.xml
+++ b/res/layout-sw580dp/people_activity.xml
@@ -72,10 +72,7 @@
                 android:id="@+id/contact_detail_container"
                 layout="@layout/contact_detail_container"
                 android:layout_width="match_parent"
-                android:layout_height="match_parent"
-                android:layout_marginTop="16dip"
-                android:layout_marginLeft="16dip"
-                android:layout_marginRight="16dip"/>
+                android:layout_height="match_parent" />
 
             <!-- This invisible worker fragment loads the contact's details -->
             <fragment
@@ -94,54 +91,41 @@
                 android:visibility="gone" />
         </view>
 
-        <view
-            class="com.android.contacts.widget.TransitionAnimationView"
+        <LinearLayout
             android:id="@+id/favorites_view"
             android:layout_width="match_parent"
             android:layout_height="match_parent"
-            ex:clipMarginLeft="0dip"
-            ex:clipMarginTop="3dip"
-            ex:clipMarginRight="3dip"
-            ex:clipMarginBottom="9dip"
-            ex:enterAnimation="@android:animator/fade_in"
-            ex:exitAnimation="@android:animator/fade_out"
-            ex:animationDuration="200">
+            android:background="@drawable/list_background_holo"
+            android:baselineAligned="false">
 
-            <LinearLayout
-                android:layout_width="match_parent"
+            <!-- Starred -->
+            <FrameLayout
+                android:layout_width="0dip"
                 android:layout_height="match_parent"
-                android:background="@drawable/list_background_holo"
-                android:baselineAligned="false">
+                android:layout_weight="10"
+                android:background="@drawable/panel_favorites_holo_light">
 
-                <!-- Starred -->
-                <FrameLayout
-                    android:layout_width="0dip"
-                    android:layout_height="match_parent"
-                    android:layout_weight="10"
-                    android:background="@drawable/panel_favorites_holo_light">
-
-                    <fragment
-                        android:id="@+id/favorites_fragment"
-                        class="com.android.contacts.list.ContactTileListFragment"
-                        android:layout_height="match_parent"
-                        android:layout_width="match_parent"
-                        android:layout_marginRight="16dip"
-                        android:layout_marginLeft="16dip"/>
-
-                </FrameLayout>
-
-                <!-- Most Frequent -->
                 <fragment
-                    android:id="@+id/frequent_fragment"
-                    class="com.android.contacts.list.ContactTileFrequentFragment"
-                    android:layout_width="0dip"
+                    android:id="@+id/favorites_fragment"
+                    class="com.android.contacts.list.ContactTileListFragment"
                     android:layout_height="match_parent"
-                    android:layout_weight="8"
-                    android:layout_marginTop="16dip"
-                    android:layout_marginRight="16dip"/>
+                    android:layout_width="match_parent"
+                    android:layout_marginRight="16dip"
+                    android:layout_marginLeft="16dip"/>
 
-            </LinearLayout>
-        </view>
+            </FrameLayout>
+
+            <!-- Most Frequent -->
+            <fragment
+                android:id="@+id/frequent_fragment"
+                class="com.android.contacts.list.ContactTileFrequentFragment"
+                android:layout_width="0dip"
+                android:layout_height="match_parent"
+                android:layout_weight="8"
+                android:layout_marginTop="16dip"
+                android:layout_marginRight="16dip"/>
+
+        </LinearLayout>
 
     </LinearLayout>
 
diff --git a/res/layout-sw680dp-w1000dp/people_activity.xml b/res/layout-sw680dp-w1000dp/people_activity.xml
index e34ec21..f45324e 100644
--- a/res/layout-sw680dp-w1000dp/people_activity.xml
+++ b/res/layout-sw680dp-w1000dp/people_activity.xml
@@ -97,54 +97,41 @@
                 android:visibility="gone" />
         </view>
 
-        <view
-            class="com.android.contacts.widget.TransitionAnimationView"
+        <LinearLayout
             android:id="@+id/favorites_view"
             android:layout_width="match_parent"
             android:layout_height="match_parent"
-            ex:clipMarginLeft="0dip"
-            ex:clipMarginTop="3dip"
-            ex:clipMarginRight="3dip"
-            ex:clipMarginBottom="9dip"
-            ex:enterAnimation="@android:animator/fade_in"
-            ex:exitAnimation="@android:animator/fade_out"
-            ex:animationDuration="200">
+            android:background="@drawable/list_background_holo"
+            android:baselineAligned="false">
 
-            <LinearLayout
-                android:layout_width="match_parent"
+            <!-- Starred -->
+            <FrameLayout
+                android:layout_width="0dip"
                 android:layout_height="match_parent"
-                android:background="@drawable/list_background_holo"
-                android:baselineAligned="false">
+                android:layout_weight="7"
+                android:background="@drawable/panel_favorites_holo_light">
 
-                <!-- Starred -->
-                <FrameLayout
-                    android:layout_width="0dip"
-                    android:layout_height="match_parent"
-                    android:layout_weight="7"
-                    android:background="@drawable/panel_favorites_holo_light">
-
-                    <fragment
-                        android:id="@+id/favorites_fragment"
-                        class="com.android.contacts.list.ContactTileListFragment"
-                        android:layout_height="match_parent"
-                        android:layout_width="match_parent"
-                        android:layout_marginRight="32dip"
-                        android:layout_marginLeft="32dip"/>
-
-                </FrameLayout>
-
-                <!-- Most Frequent -->
                 <fragment
-                    android:id="@+id/frequent_fragment"
-                    class="com.android.contacts.list.ContactTileFrequentFragment"
-                    android:layout_width="0dip"
+                    android:id="@+id/favorites_fragment"
+                    class="com.android.contacts.list.ContactTileListFragment"
                     android:layout_height="match_parent"
-                    android:layout_weight="3"
-                    android:layout_marginTop="32dip"
-                    android:layout_marginRight="16dip"/>
+                    android:layout_width="match_parent"
+                    android:layout_marginRight="32dip"
+                    android:layout_marginLeft="32dip"/>
 
-            </LinearLayout>
-        </view>
+            </FrameLayout>
+
+            <!-- Most Frequent -->
+            <fragment
+                android:id="@+id/frequent_fragment"
+                class="com.android.contacts.list.ContactTileFrequentFragment"
+                android:layout_width="0dip"
+                android:layout_height="match_parent"
+                android:layout_weight="3"
+                android:layout_marginTop="32dip"
+                android:layout_marginRight="16dip"/>
+
+        </LinearLayout>
 
     </com.android.contacts.widget.InterpolatingLayout>
 
diff --git a/res/layout-w470dp/contact_detail_container.xml b/res/layout-w470dp/contact_detail_container.xml
index a8ee0a5..fc401b7 100644
--- a/res/layout-w470dp/contact_detail_container.xml
+++ b/res/layout-w470dp/contact_detail_container.xml
@@ -16,8 +16,7 @@
 
 <FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
     android:layout_width="match_parent"
-    android:layout_height="match_parent"
-    android:orientation="vertical">
+    android:layout_height="match_parent">
 
     <com.android.contacts.detail.ContactDetailFragmentCarousel
         android:id="@+id/fragment_carousel"
diff --git a/res/layout/contact_detail_container.xml b/res/layout/contact_detail_container.xml
index ff2eab1..a59ada4 100644
--- a/res/layout/contact_detail_container.xml
+++ b/res/layout/contact_detail_container.xml
@@ -25,8 +25,7 @@
 
 <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
     android:layout_width="match_parent"
-    android:layout_height="match_parent"
-    android:orientation="vertical">
+    android:layout_height="match_parent">
 
     <android.support.v4.view.ViewPager
         android:id="@+id/pager"
diff --git a/src/com/android/contacts/activities/ContactDetailActivity.java b/src/com/android/contacts/activities/ContactDetailActivity.java
index dd3b03b..ea9e116 100644
--- a/src/com/android/contacts/activities/ContactDetailActivity.java
+++ b/src/com/android/contacts/activities/ContactDetailActivity.java
@@ -100,7 +100,7 @@
         setContentView(R.layout.contact_detail_activity);
 
         mContactDetailLayoutController = new ContactDetailLayoutController(this, savedState,
-                getFragmentManager(), findViewById(R.id.contact_detail_container),
+                getFragmentManager(), null, findViewById(R.id.contact_detail_container),
                 mContactDetailFragmentListener);
 
         // We want the UP affordance but no app icon.
diff --git a/src/com/android/contacts/activities/PeopleActivity.java b/src/com/android/contacts/activities/PeopleActivity.java
index de08c4c..e41adad 100644
--- a/src/com/android/contacts/activities/PeopleActivity.java
+++ b/src/com/android/contacts/activities/PeopleActivity.java
@@ -60,6 +60,7 @@
 import com.android.contacts.util.Constants;
 import com.android.contacts.util.DialogManager;
 import com.android.contacts.util.PhoneCapabilityTester;
+import com.android.contacts.widget.TransitionAnimationView;
 
 import android.app.Fragment;
 import android.app.FragmentManager;
@@ -129,7 +130,6 @@
     private ActionBarAdapter mActionBarAdapter;
 
     private ContactDetailFragment mContactDetailFragment;
-    private ContactDetailUpdatesFragment mContactDetailUpdatesFragment;
 
     private ContactLoaderFragment mContactDetailLoaderFragment;
     private final ContactDetailLoaderFragmentListener mContactDetailLoaderFragmentListener =
@@ -160,7 +160,7 @@
 
     private View mFavoritesView;
     private View mBrowserView;
-    private View mDetailsView;
+    private TransitionAnimationView mDetailsView;
 
     private View mAddGroupImageView;
 
@@ -240,8 +240,6 @@
     public void onAttachFragment(Fragment fragment) {
         if (fragment instanceof ContactDetailFragment) {
             mContactDetailFragment = (ContactDetailFragment) fragment;
-        } else if (fragment instanceof ContactDetailUpdatesFragment) {
-            mContactDetailUpdatesFragment = (ContactDetailUpdatesFragment) fragment;
         } else if (fragment instanceof ContactsUnavailableFragment) {
             mContactsUnavailableFragment = (ContactsUnavailableFragment)fragment;
             mContactsUnavailableFragment.setProviderStatusLoader(mProviderStatusLoader);
@@ -418,7 +416,7 @@
 
             // Configure contact details
             mContactDetailLayoutController = new ContactDetailLayoutController(this, savedState,
-                    getFragmentManager(), findViewById(R.id.contact_detail_container),
+                    getFragmentManager(), mDetailsView, findViewById(R.id.contact_detail_container),
                     new ContactDetailFragmentListener());
         }
         transaction.commitAllowingStateLoss();
diff --git a/src/com/android/contacts/detail/ContactDetailFragment.java b/src/com/android/contacts/detail/ContactDetailFragment.java
index b0050c0..d8e5a1d 100644
--- a/src/com/android/contacts/detail/ContactDetailFragment.java
+++ b/src/com/android/contacts/detail/ContactDetailFragment.java
@@ -104,7 +104,6 @@
 import android.widget.AdapterView.OnItemClickListener;
 import android.widget.BaseAdapter;
 import android.widget.Button;
-import android.widget.CheckBox;
 import android.widget.ImageView;
 import android.widget.ListAdapter;
 import android.widget.ListPopupWindow;
@@ -222,8 +221,6 @@
     private ArrayList<ViewEntry> mAllEntries = new ArrayList<ViewEntry>();
     private LayoutInflater mInflater;
 
-    private boolean mTransitionAnimationRequested;
-
     private boolean mIsUniqueNumber;
     private boolean mIsUniqueEmail;
 
@@ -418,11 +415,6 @@
             getActivity().invalidateOptionsMenu();
         }
 
-        if (mTransitionAnimationRequested) {
-            TransitionAnimationView.startAnimation(mView, mContactData == null);
-            mTransitionAnimationRequested = false;
-        }
-
         if (mContactData == null) {
             mView.setVisibility(View.INVISIBLE);
             mAllEntries.clear();
diff --git a/src/com/android/contacts/detail/ContactDetailLayoutController.java b/src/com/android/contacts/detail/ContactDetailLayoutController.java
index cd479ca..b79ccc0 100644
--- a/src/com/android/contacts/detail/ContactDetailLayoutController.java
+++ b/src/com/android/contacts/detail/ContactDetailLayoutController.java
@@ -20,7 +20,9 @@
 import com.android.contacts.NfcHandler;
 import com.android.contacts.R;
 import com.android.contacts.activities.ContactDetailActivity.FragmentKeyListener;
+import com.android.contacts.util.PhoneCapabilityTester;
 import com.android.contacts.util.UriUtils;
+import com.android.contacts.widget.TransitionAnimationView;
 
 import android.animation.Animator;
 import android.animation.Animator.AnimatorListener;
@@ -35,6 +37,7 @@
 import android.support.v4.view.ViewPager.OnPageChangeListener;
 import android.view.LayoutInflater;
 import android.view.View;
+import android.view.ViewPropertyAnimator;
 import android.view.animation.AnimationUtils;
 import android.widget.AbsListView;
 import android.widget.AbsListView.OnScrollListener;
@@ -51,6 +54,8 @@
     private static final int TAB_INDEX_DETAIL = 0;
     private static final int TAB_INDEX_UPDATES = 1;
 
+    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
@@ -65,7 +70,8 @@
     private final LayoutInflater mLayoutInflater;
     private final FragmentManager mFragmentManager;
 
-    private View mViewContainer;
+    private final View mViewContainer;
+    private final TransitionAnimationView mTransitionAnimationView;
     private ContactDetailFragment mDetailFragment;
     private ContactDetailUpdatesFragment mUpdatesFragment;
 
@@ -79,7 +85,7 @@
     private final ContactDetailTabCarousel mTabCarousel;
     private final ContactDetailFragmentCarousel mFragmentCarousel;
 
-    private ContactDetailFragment.Listener mContactDetailFragmentListener;
+    private final ContactDetailFragment.Listener mContactDetailFragmentListener;
 
     private ContactLoader.Result mContactData;
     private Uri mContactUri;
@@ -91,8 +97,8 @@
     private LayoutMode mLayoutMode;
 
     public ContactDetailLayoutController(Activity activity, Bundle savedState,
-            FragmentManager fragmentManager, View viewContainer, ContactDetailFragment.Listener
-            contactDetailFragmentListener) {
+            FragmentManager fragmentManager, TransitionAnimationView animationView,
+            View viewContainer, ContactDetailFragment.Listener contactDetailFragmentListener) {
 
         if (fragmentManager == null) {
             throw new IllegalStateException("Cannot initialize a ContactDetailLayoutController "
@@ -105,8 +111,11 @@
         mFragmentManager = fragmentManager;
         mContactDetailFragmentListener = contactDetailFragmentListener;
 
+        mTransitionAnimationView = animationView;
+
         // Retrieve views in case this is view pager and carousel mode
         mViewContainer = viewContainer;
+
         mViewPager = (ViewPager) viewContainer.findViewById(R.id.pager);
         mTabCarousel = (ContactDetailTabCarousel) viewContainer.findViewById(R.id.tab_carousel);
 
@@ -239,17 +248,36 @@
     }
 
     public void setContactData(ContactLoader.Result data) {
-        final Boolean contactHadUpdates;
+        final boolean contactWasLoaded;
+        final boolean contactHadUpdates;
         if (mContactData == null) {
-            contactHadUpdates = null;
+            contactHadUpdates = false;
+            contactWasLoaded = false;
         } else {
             contactHadUpdates = mContactHasUpdates;
+            contactWasLoaded = true;
         }
         mContactData = data;
         mContactHasUpdates = !data.getStreamItems().isEmpty();
+
+        if (PhoneCapabilityTester.isUsingTwoPanes(mActivity)) {
+            // Tablet: If we already showed data before, we want to cross-fade from screen to screen
+            if (contactWasLoaded && mTransitionAnimationView != null) {
+                mTransitionAnimationView.startTransition(mViewContainer, mContactData == null);
+            }
+        } else {
+            // Small screen: We are on our own screen. Fade the data in, but only the first time
+            if (!contactWasLoaded) {
+                mViewContainer.setAlpha(0.0f);
+                final ViewPropertyAnimator animator = mViewContainer.animate();
+                animator.alpha(1.0f);
+                animator.setDuration(SINGLE_PANE_FADE_IN_DURATION);
+            }
+        }
+
         if (mContactHasUpdates) {
             showContactWithUpdates(
-                    contactHadUpdates != null && contactHadUpdates.booleanValue() == false);
+                    contactWasLoaded && contactHadUpdates == false);
         } else {
             showContactWithoutUpdates();
         }
diff --git a/src/com/android/contacts/detail/ContactLoaderFragment.java b/src/com/android/contacts/detail/ContactLoaderFragment.java
index ddccfe6..fd1f458 100644
--- a/src/com/android/contacts/detail/ContactLoaderFragment.java
+++ b/src/com/android/contacts/detail/ContactLoaderFragment.java
@@ -33,7 +33,6 @@
 import android.content.Loader;
 import android.media.RingtoneManager;
 import android.net.Uri;
-import android.os.AsyncTask;
 import android.os.Bundle;
 import android.provider.ContactsContract;
 import android.provider.ContactsContract.Contacts;
diff --git a/src/com/android/contacts/widget/TransitionAnimationView.java b/src/com/android/contacts/widget/TransitionAnimationView.java
index e2f8a87..c70ca25 100644
--- a/src/com/android/contacts/widget/TransitionAnimationView.java
+++ b/src/com/android/contacts/widget/TransitionAnimationView.java
@@ -25,12 +25,10 @@
 import android.graphics.Bitmap;
 import android.graphics.Canvas;
 import android.graphics.Color;
-import android.graphics.Paint;
 import android.graphics.Rect;
 import android.graphics.drawable.BitmapDrawable;
 import android.util.AttributeSet;
 import android.view.View;
-import android.view.ViewParent;
 import android.widget.FrameLayout;
 
 /**
@@ -99,7 +97,7 @@
         if (mExitAnimation == null) {
             throw new IllegalArgumentException("Invalid exit animation: " + mExitAnimationId);
         }
-
+        mExitAnimation.setDuration(mAnimationDuration);
     }
 
     @Override
@@ -136,23 +134,7 @@
         }
     }
 
-    public static void startAnimation(View view, boolean closing) {
-        TransitionAnimationView container = null;
-        ViewParent parent = view.getParent();
-        while (parent instanceof View) {
-            if (parent instanceof TransitionAnimationView) {
-                container = (TransitionAnimationView) parent;
-                break;
-            }
-            parent = parent.getParent();
-        }
-
-        if (container != null) {
-            container.start(view, closing);
-        }
-    }
-
-    private void start(View view, boolean closing) {
+    public void startTransition(View view, boolean closing) {
         if (mEnterAnimation.isRunning()) {
             mEnterAnimation.end();
         }
@@ -172,11 +154,8 @@
                 return;
             }
 
+            mPreviousStateBitmap.eraseColor(Color.TRANSPARENT);
             Canvas canvas = new Canvas(mPreviousStateBitmap);
-            Paint paint = new Paint();
-            paint.setColor(Color.TRANSPARENT);
-            canvas.drawRect(0, 0, mPreviousStateBitmap.getWidth(), mPreviousStateBitmap.getHeight(),
-                    paint);
             canvas.clipRect(mClipRect);
             view.draw(canvas);
             canvas.setBitmap(null);