Merge "Change ActionBar animtion from/to ActionMode" into mnc-dev
diff --git a/core/java/com/android/internal/app/WindowDecorActionBar.java b/core/java/com/android/internal/app/WindowDecorActionBar.java
index 7ae7d0f..05cfd81 100644
--- a/core/java/com/android/internal/app/WindowDecorActionBar.java
+++ b/core/java/com/android/internal/app/WindowDecorActionBar.java
@@ -47,7 +47,6 @@
 import android.graphics.drawable.Drawable;
 import android.util.TypedValue;
 import android.view.ActionMode;
-import android.view.ActionMode.Callback;
 import android.view.ContextThemeWrapper;
 import android.view.LayoutInflater;
 import android.view.Menu;
@@ -106,6 +105,10 @@
 
     private static final int INVALID_POSITION = -1;
 
+    // The fade duration for toolbar and action bar when entering/exiting action mode.
+    private static final long FADE_OUT_DURATION_MS = 100;
+    private static final long FADE_IN_DURATION_MS = 200;
+
     private int mContextDisplayMode;
     private boolean mHasEmbeddedTabs;
 
@@ -866,8 +869,21 @@
             hideForActionMode();
         }
 
-        mDecorToolbar.animateToVisibility(toActionMode ? View.GONE : View.VISIBLE);
-        mContextView.animateToVisibility(toActionMode ? View.VISIBLE : View.GONE);
+        Animator fadeIn, fadeOut;
+        if (toActionMode) {
+            fadeOut = mDecorToolbar.setupAnimatorToVisibility(View.GONE,
+                    FADE_OUT_DURATION_MS);
+            fadeIn = mContextView.setupAnimatorToVisibility(View.VISIBLE,
+                    FADE_IN_DURATION_MS);
+        } else {
+            fadeIn = mDecorToolbar.setupAnimatorToVisibility(View.VISIBLE,
+                    FADE_IN_DURATION_MS);
+            fadeOut = mContextView.setupAnimatorToVisibility(View.GONE,
+                    FADE_OUT_DURATION_MS);
+        }
+        AnimatorSet set = new AnimatorSet();
+        set.playSequentially(fadeOut, fadeIn);
+        set.start();
         // mTabScrollView's visibility is not affected by action mode.
     }
 
diff --git a/core/java/com/android/internal/widget/AbsActionBarView.java b/core/java/com/android/internal/widget/AbsActionBarView.java
index 850ea23..35eeca7 100644
--- a/core/java/com/android/internal/widget/AbsActionBarView.java
+++ b/core/java/com/android/internal/widget/AbsActionBarView.java
@@ -136,10 +136,11 @@
         return getVisibility();
     }
 
-    public void animateToVisibility(int visibility) {
+    public Animator setupAnimatorToVisibility(int visibility, long duration) {
         if (mVisibilityAnim != null) {
             mVisibilityAnim.cancel();
         }
+
         if (visibility == VISIBLE) {
             if (getVisibility() != VISIBLE) {
                 setAlpha(0);
@@ -147,38 +148,43 @@
                     mMenuView.setAlpha(0);
                 }
             }
-            ObjectAnimator anim = ObjectAnimator.ofFloat(this, "alpha", 1);
-            anim.setDuration(FADE_DURATION);
+            ObjectAnimator anim = ObjectAnimator.ofFloat(this, View.ALPHA, 1);
+            anim.setDuration(duration);
             anim.setInterpolator(sAlphaInterpolator);
             if (mSplitView != null && mMenuView != null) {
                 AnimatorSet set = new AnimatorSet();
-                ObjectAnimator splitAnim = ObjectAnimator.ofFloat(mMenuView, "alpha", 1);
-                splitAnim.setDuration(FADE_DURATION);
+                ObjectAnimator splitAnim = ObjectAnimator.ofFloat(mMenuView, View.ALPHA, 1);
+                splitAnim.setDuration(duration);
                 set.addListener(mVisAnimListener.withFinalVisibility(visibility));
                 set.play(anim).with(splitAnim);
-                set.start();
+                return set;
             } else {
                 anim.addListener(mVisAnimListener.withFinalVisibility(visibility));
-                anim.start();
+                return anim;
             }
         } else {
-            ObjectAnimator anim = ObjectAnimator.ofFloat(this, "alpha", 0);
-            anim.setDuration(FADE_DURATION);
+            ObjectAnimator anim = ObjectAnimator.ofFloat(this, View.ALPHA, 0);
+            anim.setDuration(duration);
             anim.setInterpolator(sAlphaInterpolator);
             if (mSplitView != null && mMenuView != null) {
                 AnimatorSet set = new AnimatorSet();
-                ObjectAnimator splitAnim = ObjectAnimator.ofFloat(mMenuView, "alpha", 0);
-                splitAnim.setDuration(FADE_DURATION);
+                ObjectAnimator splitAnim = ObjectAnimator.ofFloat(mMenuView, View.ALPHA, 0);
+                splitAnim.setDuration(duration);
                 set.addListener(mVisAnimListener.withFinalVisibility(visibility));
                 set.play(anim).with(splitAnim);
-                set.start();
+                return set;
             } else {
                 anim.addListener(mVisAnimListener.withFinalVisibility(visibility));
-                anim.start();
+                return anim;
             }
         }
     }
 
+    public void animateToVisibility(int visibility) {
+        Animator anim = setupAnimatorToVisibility(visibility, FADE_DURATION);
+        anim.start();
+    }
+
     @Override
     public void setVisibility(int visibility) {
         if (visibility != getVisibility()) {
diff --git a/core/java/com/android/internal/widget/ActionBarContextView.java b/core/java/com/android/internal/widget/ActionBarContextView.java
index c5d3290..693b194 100644
--- a/core/java/com/android/internal/widget/ActionBarContextView.java
+++ b/core/java/com/android/internal/widget/ActionBarContextView.java
@@ -21,10 +21,6 @@
 import android.widget.ActionMenuView;
 import com.android.internal.view.menu.MenuBuilder;
 
-import android.animation.Animator;
-import android.animation.Animator.AnimatorListener;
-import android.animation.AnimatorSet;
-import android.animation.ObjectAnimator;
 import android.content.Context;
 import android.content.res.TypedArray;
 import android.graphics.drawable.Drawable;
@@ -35,14 +31,13 @@
 import android.view.View;
 import android.view.ViewGroup;
 import android.view.accessibility.AccessibilityEvent;
-import android.view.animation.DecelerateInterpolator;
 import android.widget.LinearLayout;
 import android.widget.TextView;
 
 /**
  * @hide
  */
-public class ActionBarContextView extends AbsActionBarView implements AnimatorListener {
+public class ActionBarContextView extends AbsActionBarView {
     private static final String TAG = "ActionBarContextView";
 
     private CharSequence mTitle;
@@ -59,14 +54,6 @@
     private boolean mTitleOptional;
     private int mCloseItemLayout;
 
-    private Animator mCurrentAnimation;
-    private boolean mAnimateInOnLayout;
-    private int mAnimationMode;
-
-    private static final int ANIMATE_IDLE = 0;
-    private static final int ANIMATE_IN = 1;
-    private static final int ANIMATE_OUT = 2;
-    
     public ActionBarContextView(Context context) {
         this(context, null);
     }
@@ -255,43 +242,23 @@
             mMenuView.setBackgroundDrawable(mSplitBackground);
             mSplitView.addView(mMenuView, layoutParams);
         }
-
-        mAnimateInOnLayout = true;
     }
 
     public void closeMode() {
-        if (mAnimationMode == ANIMATE_OUT) {
-            // Called again during close; just finish what we were doing.
-            return;
-        }
         if (mClose == null) {
             killMode();
             return;
         }
 
-        finishAnimation();
-        mAnimationMode = ANIMATE_OUT;
-        mCurrentAnimation = makeOutAnimation();
-        mCurrentAnimation.start();
-    }
-
-    private void finishAnimation() {
-        final Animator a = mCurrentAnimation;
-        if (a != null) {
-            mCurrentAnimation = null;
-            a.end();
-        }
     }
 
     public void killMode() {
-        finishAnimation();
         removeAllViews();
         if (mSplitView != null) {
             mSplitView.removeView(mMenuView);
         }
         mCustomView = null;
         mMenuView = null;
-        mAnimateInOnLayout = false;
     }
 
     @Override
@@ -343,7 +310,7 @@
             throw new IllegalStateException(getClass().getSimpleName() + " can only be used " +
                     "with android:layout_height=\"wrap_content\"");
         }
-        
+
         final int contentWidth = MeasureSpec.getSize(widthMeasureSpec);
 
         int maxHeight = mContentHeight > 0 ?
@@ -353,7 +320,7 @@
         int availableWidth = contentWidth - getPaddingLeft() - getPaddingRight();
         final int height = maxHeight - verticalPadding;
         final int childSpecHeight = MeasureSpec.makeMeasureSpec(height, MeasureSpec.AT_MOST);
-        
+
         if (mClose != null) {
             availableWidth = measureChildView(mClose, availableWidth, childSpecHeight, 0);
             MarginLayoutParams lp = (MarginLayoutParams) mClose.getLayoutParams();
@@ -411,66 +378,13 @@
         }
     }
 
-    private Animator makeInAnimation() {
-        mClose.setTranslationX(-mClose.getWidth() -
-                ((MarginLayoutParams) mClose.getLayoutParams()).leftMargin);
-        ObjectAnimator buttonAnimator = ObjectAnimator.ofFloat(mClose, "translationX", 0);
-        buttonAnimator.setDuration(200);
-        buttonAnimator.addListener(this);
-        buttonAnimator.setInterpolator(new DecelerateInterpolator());
-
-        AnimatorSet set = new AnimatorSet();
-        AnimatorSet.Builder b = set.play(buttonAnimator);
-
-        if (mMenuView != null) {
-            final int count = mMenuView.getChildCount();
-            if (count > 0) {
-                for (int i = count - 1, j = 0; i >= 0; i--, j++) {
-                    View child = mMenuView.getChildAt(i);
-                    child.setScaleY(0);
-                    ObjectAnimator a = ObjectAnimator.ofFloat(child, "scaleY", 0, 1);
-                    a.setDuration(300);
-                    b.with(a);
-                }
-            }
-        }
-
-        return set;
-    }
-
-    private Animator makeOutAnimation() {
-        ObjectAnimator buttonAnimator = ObjectAnimator.ofFloat(mClose, "translationX",
-                -mClose.getWidth() - ((MarginLayoutParams) mClose.getLayoutParams()).leftMargin);
-        buttonAnimator.setDuration(200);
-        buttonAnimator.addListener(this);
-        buttonAnimator.setInterpolator(new DecelerateInterpolator());
-
-        AnimatorSet set = new AnimatorSet();
-        AnimatorSet.Builder b = set.play(buttonAnimator);
-
-        if (mMenuView != null) {
-            final int count = mMenuView.getChildCount();
-            if (count > 0) {
-                for (int i = 0; i < 0; i++) {
-                    View child = mMenuView.getChildAt(i);
-                    child.setScaleY(0);
-                    ObjectAnimator a = ObjectAnimator.ofFloat(child, "scaleY", 0);
-                    a.setDuration(300);
-                    b.with(a);
-                }
-            }
-        }
-
-        return set;
-    }
-
     @Override
     protected void onLayout(boolean changed, int l, int t, int r, int b) {
         final boolean isLayoutRtl = isLayoutRtl();
         int x = isLayoutRtl ? r - l - getPaddingRight() : getPaddingLeft();
         final int y = getPaddingTop();
         final int contentHeight = b - t - getPaddingTop() - getPaddingBottom();
-        
+
         if (mClose != null && mClose.getVisibility() != GONE) {
             MarginLayoutParams lp = (MarginLayoutParams) mClose.getLayoutParams();
             final int startMargin = (isLayoutRtl ? lp.rightMargin : lp.leftMargin);
@@ -479,12 +393,6 @@
             x += positionChild(mClose, x, y, contentHeight, isLayoutRtl);
             x = next(x, endMargin, isLayoutRtl);
 
-            if (mAnimateInOnLayout) {
-                mAnimationMode = ANIMATE_IN;
-                mCurrentAnimation = makeInAnimation();
-                mCurrentAnimation.start();
-                mAnimateInOnLayout = false;
-            }
         }
 
         if (mTitleLayout != null && mCustomView == null && mTitleLayout.getVisibility() != GONE) {
@@ -503,26 +411,6 @@
     }
 
     @Override
-    public void onAnimationStart(Animator animation) {
-    }
-
-    @Override
-    public void onAnimationEnd(Animator animation) {
-        if (mAnimationMode == ANIMATE_OUT) {
-            killMode();
-        }
-        mAnimationMode = ANIMATE_IDLE;
-    }
-
-    @Override
-    public void onAnimationCancel(Animator animation) {
-    }
-
-    @Override
-    public void onAnimationRepeat(Animator animation) {
-    }
-
-    @Override
     public boolean shouldDelayChildPressedState() {
         return false;
     }
diff --git a/core/java/com/android/internal/widget/DecorToolbar.java b/core/java/com/android/internal/widget/DecorToolbar.java
index fb413b5..fe70d7b 100644
--- a/core/java/com/android/internal/widget/DecorToolbar.java
+++ b/core/java/com/android/internal/widget/DecorToolbar.java
@@ -17,6 +17,7 @@
 
 package com.android.internal.widget;
 
+import android.animation.Animator;
 import android.content.Context;
 import android.graphics.drawable.Drawable;
 import android.os.Parcelable;
@@ -87,6 +88,7 @@
     void setCustomView(View view);
     View getCustomView();
     void animateToVisibility(int visibility);
+    Animator setupAnimatorToVisibility(int visibility, long duration);
     void setNavigationIcon(Drawable icon);
     void setNavigationIcon(int resId);
     void setNavigationContentDescription(CharSequence description);
diff --git a/core/java/com/android/internal/widget/ToolbarWidgetWrapper.java b/core/java/com/android/internal/widget/ToolbarWidgetWrapper.java
index 54df87b..32aae72 100644
--- a/core/java/com/android/internal/widget/ToolbarWidgetWrapper.java
+++ b/core/java/com/android/internal/widget/ToolbarWidgetWrapper.java
@@ -19,6 +19,7 @@
 
 import android.animation.Animator;
 import android.animation.AnimatorListenerAdapter;
+import android.animation.ObjectAnimator;
 import android.app.ActionBar;
 import android.content.Context;
 import android.content.res.TypedArray;
@@ -59,6 +60,8 @@
 
     private static final int AFFECTS_LOGO_MASK =
             ActionBar.DISPLAY_SHOW_HOME | ActionBar.DISPLAY_USE_LOGO;
+    // Default fade duration for fading in/out tool bar.
+    private static final long DEFAULT_FADE_DURATION_MS = 200;
 
     private Toolbar mToolbar;
 
@@ -571,9 +574,19 @@
 
     @Override
     public void animateToVisibility(int visibility) {
+        Animator anim = setupAnimatorToVisibility(visibility, DEFAULT_FADE_DURATION_MS);
+        if (anim != null) {
+            anim.start();
+        }
+    }
+
+    @Override
+    public Animator setupAnimatorToVisibility(int visibility, long duration) {
+
         if (visibility == View.GONE) {
-            mToolbar.animate().alpha(0)
-                    .setListener(new AnimatorListenerAdapter() {
+            ObjectAnimator anim = ObjectAnimator.ofFloat(mToolbar, View.ALPHA, 1, 0);
+            anim.setDuration(duration);
+            anim.addListener(new AnimatorListenerAdapter() {
                         private boolean mCanceled = false;
                         @Override
                         public void onAnimationEnd(Animator animation) {
@@ -587,15 +600,19 @@
                             mCanceled = true;
                         }
                     });
+            return anim;
         } else if (visibility == View.VISIBLE) {
-            mToolbar.animate().alpha(1)
-                    .setListener(new AnimatorListenerAdapter() {
+            ObjectAnimator anim = ObjectAnimator.ofFloat(mToolbar, View.ALPHA, 0, 1);
+            anim.setDuration(duration);
+            anim.addListener(new AnimatorListenerAdapter() {
                         @Override
                         public void onAnimationStart(Animator animation) {
                             mToolbar.setVisibility(View.VISIBLE);
                         }
                     });
+            return anim;
         }
+        return null;
     }
 
     @Override