Lock out ResolverDrawerLayout dismissals during animations

Due to views being offset during the ChooserActivity animating in
direct share targets, it was possible to touch down on the sheet
attempting to tap, but have it be interpreted as a fling downward as
the relative touch position within the parent was moving. Lock the
dismiss gesture during animations to prevent this.

Bug: 36032762
Test: manual
Change-Id: I18b6f03148cbf402efc23e873262927e412ea7b7
diff --git a/core/java/com/android/internal/app/ChooserActivity.java b/core/java/com/android/internal/app/ChooserActivity.java
index df65659..ece4981 100644
--- a/core/java/com/android/internal/app/ChooserActivity.java
+++ b/core/java/com/android/internal/app/ChooserActivity.java
@@ -16,6 +16,8 @@
 
 package com.android.internal.app;
 
+import android.animation.Animator;
+import android.animation.AnimatorListenerAdapter;
 import android.animation.ObjectAnimator;
 import android.annotation.NonNull;
 import android.app.Activity;
@@ -1136,8 +1138,10 @@
          * Set to true to reveal all service targets at once.
          */
         public void setShowServiceTargets(boolean show) {
-            mShowServiceTargets = show;
-            notifyDataSetChanged();
+            if (show != mShowServiceTargets) {
+                mShowServiceTargets = show;
+                notifyDataSetChanged();
+            }
         }
 
         private void insertServiceTarget(ChooserTargetInfo chooserTargetInfo) {
@@ -1201,7 +1205,18 @@
                 return;
             }
 
-            mAnimator = ObjectAnimator.ofFloat(this, PROPERTY, from, to).setDuration(DURATION);
+            mAnimator = ObjectAnimator.ofFloat(this, PROPERTY, from, to)
+                .setDuration(DURATION);
+            mAnimator.addListener(new AnimatorListenerAdapter() {
+                @Override
+                public void onAnimationStart(Animator animation) {
+                    mAdapter.onAnimationStart();
+                }
+                @Override
+                public void onAnimationEnd(Animator animation) {
+                    mAdapter.onAnimationEnd();
+                }
+            });
         }
 
         public RowScale setInterpolator(Interpolator interpolator) {
@@ -1234,6 +1249,7 @@
         private final int mColumnCount = 4;
         private RowScale[] mServiceTargetScale;
         private final Interpolator mInterpolator;
+        private int mAnimationCount = 0;
 
         public ChooserRowAdapter(ChooserListAdapter wrappedAdapter) {
             mChooserListAdapter = wrappedAdapter;
@@ -1302,6 +1318,21 @@
             return 1.f;
         }
 
+        public void onAnimationStart() {
+            final boolean lock = mAnimationCount == 0;
+            mAnimationCount++;
+            if (lock) {
+                mResolverDrawerLayout.setDismissLocked(true);
+            }
+        }
+
+        public void onAnimationEnd() {
+            mAnimationCount--;
+            if (mAnimationCount == 0) {
+                mResolverDrawerLayout.setDismissLocked(false);
+            }
+        }
+
         @Override
         public int getCount() {
             return (int) (
diff --git a/core/java/com/android/internal/widget/ResolverDrawerLayout.java b/core/java/com/android/internal/widget/ResolverDrawerLayout.java
index e224b17..17c7ebd 100644
--- a/core/java/com/android/internal/widget/ResolverDrawerLayout.java
+++ b/core/java/com/android/internal/widget/ResolverDrawerLayout.java
@@ -96,6 +96,8 @@
     private OnDismissedListener mOnDismissedListener;
     private RunOnDismissedListener mRunOnDismissedListener;
 
+    private boolean mDismissLocked;
+
     private float mInitialTouchX;
     private float mInitialTouchY;
     private float mLastTouchY;
@@ -187,6 +189,10 @@
         invalidate();
     }
 
+    public void setDismissLocked(boolean locked) {
+        mDismissLocked = locked;
+    }
+
     private boolean isMoving() {
         return mIsDragging || !mScroller.isFinished();
     }
@@ -229,6 +235,10 @@
         mOnDismissedListener = listener;
     }
 
+    private boolean isDismissable() {
+        return mOnDismissedListener != null && !mDismissLocked;
+    }
+
     @Override
     public boolean onInterceptTouchEvent(MotionEvent ev) {
         final int action = ev.getActionMasked();
@@ -296,7 +306,7 @@
                 mInitialTouchY = mLastTouchY = y;
                 mActivePointerId = ev.getPointerId(0);
                 final boolean hitView = findChildUnder(mInitialTouchX, mInitialTouchY) != null;
-                handled = mOnDismissedListener != null || mCollapsibleHeight > 0;
+                handled = isDismissable() || mCollapsibleHeight > 0;
                 mIsDragging = hitView && handled;
                 abortAnimation();
             }
@@ -348,7 +358,7 @@
                 mIsDragging = false;
                 if (!wasDragging && findChildUnder(mInitialTouchX, mInitialTouchY) == null &&
                         findChildUnder(ev.getX(), ev.getY()) == null) {
-                    if (mOnDismissedListener != null) {
+                    if (isDismissable()) {
                         dispatchOnDismissed();
                         resetTouch();
                         return true;
@@ -362,7 +372,7 @@
                 mVelocityTracker.computeCurrentVelocity(1000);
                 final float yvel = mVelocityTracker.getYVelocity(mActivePointerId);
                 if (Math.abs(yvel) > mMinFlingVelocity) {
-                    if (mOnDismissedListener != null
+                    if (isDismissable()
                             && yvel > 0 && mCollapseOffset > mCollapsibleHeight) {
                         smoothScrollTo(mCollapsibleHeight + mUncollapsibleHeight, yvel);
                         mDismissOnScrollerFinished = true;
@@ -656,7 +666,7 @@
     @Override
     public boolean onNestedFling(View target, float velocityX, float velocityY, boolean consumed) {
         if (!consumed && Math.abs(velocityY) > mMinFlingVelocity) {
-            if (mOnDismissedListener != null
+            if (isDismissable()
                     && velocityY < 0 && mCollapseOffset > mCollapsibleHeight) {
                 smoothScrollTo(mCollapsibleHeight + mUncollapsibleHeight, velocityY);
                 mDismissOnScrollerFinished = true;