Merge "Fix FloatingToolbar flicker in reaction to text cursor blink." into mnc-dev
diff --git a/core/java/com/android/internal/view/FloatingActionMode.java b/core/java/com/android/internal/view/FloatingActionMode.java
index 863506b..c869722 100644
--- a/core/java/com/android/internal/view/FloatingActionMode.java
+++ b/core/java/com/android/internal/view/FloatingActionMode.java
@@ -30,6 +30,8 @@
 import com.android.internal.view.menu.MenuBuilder;
 import com.android.internal.widget.FloatingToolbar;
 
+import java.util.Arrays;
+
 public class FloatingActionMode extends ActionMode {
 
     private static final int MAX_HIDE_DURATION = 3000;
@@ -42,7 +44,9 @@
     private final Rect mContentRectOnWindow;
     private final Rect mPreviousContentRectOnWindow;
     private final int[] mViewPosition;
+    private final int[] mPreviousViewPosition;
     private final Rect mViewRect;
+    private final Rect mPreviousViewRect;
     private final Rect mScreenRect;
     private final View mOriginatingView;
     private final int mBottomAllowance;
@@ -75,7 +79,9 @@
         mContentRectOnWindow = new Rect();
         mPreviousContentRectOnWindow = new Rect();
         mViewPosition = new int[2];
+        mPreviousViewPosition = new int[2];
         mViewRect = new Rect();
+        mPreviousViewRect = new Rect();
         mScreenRect = new Rect();
         mOriginatingView = Preconditions.checkNotNull(originatingView);
         mOriginatingView.getLocationInWindow(mViewPosition);
@@ -129,9 +135,17 @@
 
     public void updateViewLocationInWindow() {
         checkToolbarInitialized();
+
         mOriginatingView.getLocationInWindow(mViewPosition);
         mOriginatingView.getGlobalVisibleRect(mViewRect);
-        repositionToolbar();
+
+        if (!Arrays.equals(mViewPosition, mPreviousViewPosition)
+                || !mViewRect.equals(mPreviousViewRect)) {
+            repositionToolbar();
+            mPreviousViewPosition[0] = mViewPosition[0];
+            mPreviousViewPosition[1] = mViewPosition[1];
+            mPreviousViewRect.set(mViewRect);
+        }
     }
 
     private void repositionToolbar() {
diff --git a/core/java/com/android/internal/widget/FloatingToolbar.java b/core/java/com/android/internal/widget/FloatingToolbar.java
index 32a145c..163b8ce 100644
--- a/core/java/com/android/internal/widget/FloatingToolbar.java
+++ b/core/java/com/android/internal/widget/FloatingToolbar.java
@@ -85,6 +85,7 @@
     private final FloatingToolbarPopup mPopup;
 
     private final Rect mContentRect = new Rect();
+    private final Rect mPreviousContentRect = new Rect();
 
     private Menu mMenu;
     private List<Object> mShowingMenuItems = new ArrayList<Object>();
@@ -178,11 +179,13 @@
             mPopup.layoutMenuItems(menuItems, mMenuItemClickListener, mSuggestedWidth);
             mShowingMenuItems = getShowingMenuItemsReferences(menuItems);
         }
-        mPopup.updateCoordinates(mContentRect);
         if (!mPopup.isShowing()) {
             mPopup.show(mContentRect);
+        } else if (!mPreviousContentRect.equals(mContentRect)) {
+            mPopup.updateCoordinates(mContentRect);
         }
         mWidthChanged = false;
+        mPreviousContentRect.set(mContentRect);
         return this;
     }
 
@@ -318,24 +321,8 @@
                 };
         private final AnimatorSet mDismissAnimation;
         private final AnimatorSet mHideAnimation;
-        private final AnimationSet mOpenOverflowAnimation = new AnimationSet(true) {
-            @Override
-            public void cancel() {
-                if (hasStarted() && !hasEnded()) {
-                    super.cancel();
-                    setOverflowPanelAsContent();
-                }
-            }
-        };
-        private final AnimationSet mCloseOverflowAnimation = new AnimationSet(true) {
-            @Override
-            public void cancel() {
-                if (hasStarted() && !hasEnded()) {
-                    super.cancel();
-                    setMainPanelAsContent();
-                }
-            }
-        };
+        private final AnimationSet mOpenOverflowAnimation = new AnimationSet(true);
+        private final AnimationSet mCloseOverflowAnimation = new AnimationSet(true);
 
         private final Runnable mOpenOverflow = new Runnable() {
             @Override
@@ -657,8 +644,24 @@
         }
 
         private void cancelOverflowAnimations() {
-            mOpenOverflowAnimation.cancel();
-            mCloseOverflowAnimation.cancel();
+            if (mOpenOverflowAnimation.hasStarted()
+                    && !mOpenOverflowAnimation.hasEnded()) {
+                // Remove the animation listener, stop the animation,
+                // then trigger the lister explicitly so it is not posted
+                // to the message queue.
+                mOpenOverflowAnimation.setAnimationListener(null);
+                mContentContainer.clearAnimation();
+                mOnOverflowOpened.onAnimationEnd(null);
+            }
+            if (mCloseOverflowAnimation.hasStarted()
+                    && !mCloseOverflowAnimation.hasEnded()) {
+                // Remove the animation listener, stop the animation,
+                // then trigger the lister explicitly so it is not posted
+                // to the message queue.
+                mCloseOverflowAnimation.setAnimationListener(null);
+                mContentContainer.clearAnimation();
+                mOnOverflowClosed.onAnimationEnd(null);
+            }
         }
 
         /**