From 456e87e1943ee4e779929f77a9cf11de7af3ec6a Mon Sep 17 00:00:00 2001 From: Vadim Tryshev Date: Thu, 13 Aug 2015 17:35:21 -0700 Subject: [PATCH] Bullet-proofing the drag window initial animation. MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit It’s unlikely, but still possible that something interesting will happen during the 150 ms that DragWindows takes to slightly increase in size before it gets hidden and replaced by the framework DND drag shadow. This fix covers 2 possible events that can happen during that time: 1. The drag gets cancelled (for example because of an app uninstall). Here, we eliminate a crash. 2. The user starts dragging the shadow. Before, this would start scrolling the home page. Now, SystemDragDriver starts processing touch events exactly as the InternalDragDriver would, until the growing finishes. Afterwards, it switches to framework dragging. Bug: 22609426 Change-Id: I73cc09fea45fcdcc6b75b13be1347da3e7c95509 --- src/com/android/launcher3/DragDriver.java | 85 +++++++++++------------ src/com/android/launcher3/DragView.java | 6 +- 2 files changed, 45 insertions(+), 46 deletions(-) diff --git a/src/com/android/launcher3/DragDriver.java b/src/com/android/launcher3/DragDriver.java index 000033c2ec..12545fbfe1 100644 --- a/src/com/android/launcher3/DragDriver.java +++ b/src/com/android/launcher3/DragDriver.java @@ -46,11 +46,42 @@ public abstract class DragDriver { */ public abstract void onDragViewAnimationEnd(); - public abstract boolean onTouchEvent(MotionEvent ev); + public boolean onTouchEvent(MotionEvent ev) { + final int action = ev.getAction(); + + switch (action) { + case MotionEvent.ACTION_MOVE: + mEventListener.onDriverDragMove(ev.getX(), ev.getY()); + break; + case MotionEvent.ACTION_UP: + mEventListener.onDriverDragMove(ev.getX(), ev.getY()); + mEventListener.onDriverDragEnd(ev.getX(), ev.getY(), null); + break; + case MotionEvent.ACTION_CANCEL: + mEventListener.onDriverDragCancel(); + break; + } + + return true; + } public abstract boolean onDragEvent (DragEvent event); - public abstract boolean onInterceptTouchEvent(MotionEvent ev); + + public boolean onInterceptTouchEvent(MotionEvent ev) { + final int action = ev.getAction(); + + switch (action) { + case MotionEvent.ACTION_UP: + mEventListener.onDriverDragEnd(ev.getX(), ev.getY(), null); + break; + case MotionEvent.ACTION_CANCEL: + mEventListener.onDriverDragCancel(); + break; + } + + return true; + } public static DragDriver create( DragController dragController, ItemInfo dragInfo, DragView dragView) { @@ -71,7 +102,7 @@ class SystemDragDriver extends DragDriver { private final Intent mDragIntent; private final DragView mDragView; - boolean mDragging = false; + boolean mIsFrameworkDragActive = false; boolean mReceivedDropEvent = false; float mLastX = 0; float mLastY = 0; @@ -116,10 +147,10 @@ class SystemDragDriver extends DragDriver { final int flagOpaque = 1 << 9; final int flags = (mDragIntent != null ? flagGlobal : 0) | flagOpaque; - mDragging = true; + mIsFrameworkDragActive = true; if (!mDragView.startDrag(dragData, shadowBuilder, null, flags)) { - mDragging = false; + mIsFrameworkDragActive = false; mEventListener.onDriverDragCancel(); return; } @@ -131,17 +162,17 @@ class SystemDragDriver extends DragDriver { @Override public boolean onTouchEvent(MotionEvent ev) { - return false; + return !mIsFrameworkDragActive && super.onTouchEvent(ev); } @Override public boolean onInterceptTouchEvent(MotionEvent ev) { - return false; + return !mIsFrameworkDragActive && super.onInterceptTouchEvent(ev); } @Override public boolean onDragEvent (DragEvent event) { - if (!mDragging) { + if (!mIsFrameworkDragActive) { // We are interested only in drag events started by this driver. return false; } @@ -189,7 +220,7 @@ class SystemDragDriver extends DragDriver { new AnotherWindowDropTarget(mDragView.getContext()) : null; mEventListener.onDriverDragEnd(mLastX, mLastY, dropTargetOverride); - mDragging = false; + mIsFrameworkDragActive = false; return true; default: @@ -209,42 +240,6 @@ class InternalDragDriver extends DragDriver { @Override public void onDragViewAnimationEnd() {} - @Override - public boolean onTouchEvent(MotionEvent ev) { - final int action = ev.getAction(); - - switch (action) { - case MotionEvent.ACTION_MOVE: - mEventListener.onDriverDragMove(ev.getX(), ev.getY()); - break; - case MotionEvent.ACTION_UP: - mEventListener.onDriverDragMove(ev.getX(), ev.getY()); - mEventListener.onDriverDragEnd(ev.getX(), ev.getY(), null); - break; - case MotionEvent.ACTION_CANCEL: - mEventListener.onDriverDragCancel(); - break; - } - - return true; - } - - @Override - public boolean onInterceptTouchEvent(MotionEvent ev) { - final int action = ev.getAction(); - - switch (action) { - case MotionEvent.ACTION_UP: - mEventListener.onDriverDragEnd(ev.getX(), ev.getY(), null); - break; - case MotionEvent.ACTION_CANCEL: - mEventListener.onDriverDragCancel(); - break; - } - - return true; - } - @Override public boolean onDragEvent (DragEvent event) { return false; } }; diff --git a/src/com/android/launcher3/DragView.java b/src/com/android/launcher3/DragView.java index 89577353bd..226e5cef4f 100644 --- a/src/com/android/launcher3/DragView.java +++ b/src/com/android/launcher3/DragView.java @@ -56,6 +56,7 @@ public class DragView extends View { private final DragController mDragController; private boolean mHasDrawn = false; @Thunk float mCrossFadeProgress = 0f; + private boolean mAnimationCancelled = false; ValueAnimator mAnim; private float mInitialScale = 1f; @@ -116,7 +117,9 @@ public class DragView extends View { mAnim.addListener(new AnimatorListenerAdapter() { @Override public void onAnimationEnd(Animator animation) { - mDragController.onDragViewAnimationEnd(); + if (!mAnimationCancelled) { + mDragController.onDragViewAnimationEnd(); + } } }); @@ -332,6 +335,7 @@ public class DragView extends View { } public void cancelAnimation() { + mAnimationCancelled = true; if (mAnim != null && mAnim.isRunning()) { mAnim.cancel(); }