Bullet-proofing the drag window initial animation.
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
diff --git a/src/com/android/launcher3/DragDriver.java b/src/com/android/launcher3/DragDriver.java
index 000033c..12545fb 100644
--- a/src/com/android/launcher3/DragDriver.java
+++ b/src/com/android/launcher3/DragDriver.java
@@ -46,11 +46,42 @@
*/
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 @@
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 @@
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 @@
@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 @@
new AnotherWindowDropTarget(mDragView.getContext()) : null;
mEventListener.onDriverDragEnd(mLastX, mLastY, dropTargetOverride);
- mDragging = false;
+ mIsFrameworkDragActive = false;
return true;
default:
@@ -210,41 +241,5 @@
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 8957735..226e5ce 100644
--- a/src/com/android/launcher3/DragView.java
+++ b/src/com/android/launcher3/DragView.java
@@ -56,6 +56,7 @@
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 @@
mAnim.addListener(new AnimatorListenerAdapter() {
@Override
public void onAnimationEnd(Animator animation) {
- mDragController.onDragViewAnimationEnd();
+ if (!mAnimationCancelled) {
+ mDragController.onDragViewAnimationEnd();
+ }
}
});
@@ -332,6 +335,7 @@
}
public void cancelAnimation() {
+ mAnimationCancelled = true;
if (mAnim != null && mAnim.isRunning()) {
mAnim.cancel();
}