Fix action mode animation on recreations - framework edition

Currently if an action mode is started in onCreate()
it will fade in. This isn't ideal though, especially
since Activities are recreated routinely with
multi-window and resizable Activities. In that instance
we fade it in on every recreate.

This CL fixes this in both the decor and toolbar action
modes to only fade in if the decor has been laid out.

BUG: 29036694

Change-Id: Iae985efcced170a0a4229124c1c132355c2aa71e
diff --git a/core/java/com/android/internal/app/WindowDecorActionBar.java b/core/java/com/android/internal/app/WindowDecorActionBar.java
index a09dbe5..1376d0a 100644
--- a/core/java/com/android/internal/app/WindowDecorActionBar.java
+++ b/core/java/com/android/internal/app/WindowDecorActionBar.java
@@ -873,24 +873,40 @@
             hideForActionMode();
         }
 
-        Animator fadeIn, fadeOut;
-        if (toActionMode) {
-            fadeOut = mDecorToolbar.setupAnimatorToVisibility(View.GONE,
-                    FADE_OUT_DURATION_MS);
-            fadeIn = mContextView.setupAnimatorToVisibility(View.VISIBLE,
-                    FADE_IN_DURATION_MS);
+        if (shouldAnimateContextView()) {
+            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();
         } else {
-            fadeIn = mDecorToolbar.setupAnimatorToVisibility(View.VISIBLE,
-                    FADE_IN_DURATION_MS);
-            fadeOut = mContextView.setupAnimatorToVisibility(View.GONE,
-                    FADE_OUT_DURATION_MS);
+            if (toActionMode) {
+                mDecorToolbar.setVisibility(View.GONE);
+                mContextView.setVisibility(View.VISIBLE);
+            } else {
+                mDecorToolbar.setVisibility(View.VISIBLE);
+                mContextView.setVisibility(View.GONE);
+            }
         }
-        AnimatorSet set = new AnimatorSet();
-        set.playSequentially(fadeOut, fadeIn);
-        set.start();
         // mTabScrollView's visibility is not affected by action mode.
     }
 
+    private boolean shouldAnimateContextView() {
+        // We only to animate the action mode in if the container view has already been laid out.
+        // If it hasn't been laid out, it hasn't been drawn to screen yet.
+        return mContainerView.isLaidOut();
+    }
+
     public Context getThemedContext() {
         if (mThemedContext == null) {
             TypedValue outValue = new TypedValue();
diff --git a/core/java/com/android/internal/policy/DecorView.java b/core/java/com/android/internal/policy/DecorView.java
index a065219..7e38d9b 100644
--- a/core/java/com/android/internal/policy/DecorView.java
+++ b/core/java/com/android/internal/policy/DecorView.java
@@ -32,6 +32,7 @@
 import java.util.List;
 
 import android.animation.Animator;
+import android.animation.AnimatorListenerAdapter;
 import android.animation.ObjectAnimator;
 import android.app.ActivityManager;
 import android.content.Context;
@@ -1588,31 +1589,27 @@
                                 mPrimaryActionModeView.getApplicationWindowToken(),
                                 Gravity.TOP | Gravity.FILL_HORIZONTAL, 0, 0);
                         endOnGoingFadeAnimation();
-                        mFadeAnim = ObjectAnimator.ofFloat(mPrimaryActionModeView, View.ALPHA,
-                                0f, 1f);
-                        mFadeAnim.addListener(new Animator.AnimatorListener() {
-                            @Override
-                            public void onAnimationStart(Animator animation) {
-                                mPrimaryActionModeView.setVisibility(VISIBLE);
-                            }
 
-                            @Override
-                            public void onAnimationEnd(Animator animation) {
-                                mPrimaryActionModeView.setAlpha(1f);
-                                mFadeAnim = null;
-                            }
+                        if (shouldAnimatePrimaryActionModeView()) {
+                            mFadeAnim = ObjectAnimator.ofFloat(mPrimaryActionModeView, View.ALPHA,
+                                    0f, 1f);
+                            mFadeAnim.addListener(new AnimatorListenerAdapter() {
+                                @Override
+                                public void onAnimationStart(Animator animation) {
+                                    mPrimaryActionModeView.setVisibility(VISIBLE);
+                                }
 
-                            @Override
-                            public void onAnimationCancel(Animator animation) {
-
-                            }
-
-                            @Override
-                            public void onAnimationRepeat(Animator animation) {
-
-                            }
-                        });
-                        mFadeAnim.start();
+                                @Override
+                                public void onAnimationEnd(Animator animation) {
+                                    mPrimaryActionModeView.setAlpha(1f);
+                                    mFadeAnim = null;
+                                }
+                            });
+                            mFadeAnim.start();
+                        } else {
+                            mPrimaryActionModeView.setAlpha(1f);
+                            mPrimaryActionModeView.setVisibility(VISIBLE);
+                        }
                     }
                 };
             } else {
@@ -1646,35 +1643,36 @@
         if (mPrimaryActionModePopup != null) {
             post(mShowPrimaryActionModePopup);
         } else {
-            mFadeAnim = ObjectAnimator.ofFloat(mPrimaryActionModeView, View.ALPHA, 0f, 1f);
-            mFadeAnim.addListener(new Animator.AnimatorListener() {
-                @Override
-                public void onAnimationStart(Animator animation) {
-                    mPrimaryActionModeView.setVisibility(View.VISIBLE);
-                }
+            if (shouldAnimatePrimaryActionModeView()) {
+                mFadeAnim = ObjectAnimator.ofFloat(mPrimaryActionModeView, View.ALPHA, 0f, 1f);
+                mFadeAnim.addListener(new AnimatorListenerAdapter() {
+                    @Override
+                    public void onAnimationStart(Animator animation) {
+                        mPrimaryActionModeView.setVisibility(View.VISIBLE);
+                    }
 
-                @Override
-                public void onAnimationEnd(Animator animation) {
-                    mPrimaryActionModeView.setAlpha(1f);
-                    mFadeAnim = null;
-                }
-
-                @Override
-                public void onAnimationCancel(Animator animation) {
-
-                }
-
-                @Override
-                public void onAnimationRepeat(Animator animation) {
-
-                }
-            });
-            mFadeAnim.start();
+                    @Override
+                    public void onAnimationEnd(Animator animation) {
+                        mPrimaryActionModeView.setAlpha(1f);
+                        mFadeAnim = null;
+                    }
+                });
+                mFadeAnim.start();
+            } else {
+                mPrimaryActionModeView.setAlpha(1f);
+                mPrimaryActionModeView.setVisibility(View.VISIBLE);
+            }
         }
         mPrimaryActionModeView.sendAccessibilityEvent(
                 AccessibilityEvent.TYPE_WINDOW_STATE_CHANGED);
     }
 
+    boolean shouldAnimatePrimaryActionModeView() {
+        // We only to animate the action mode in if the decor has already been laid out.
+        // If it hasn't been laid out, it hasn't been drawn to screen yet.
+        return isLaidOut();
+    }
+
     private ActionMode createFloatingActionMode(
             View originatingView, ActionMode.Callback2 callback) {
         if (mFloatingActionMode != null) {