summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
author Vladislav Kaznacheev <kaznacheev@google.com> 2015-11-18 19:13:13 +0000
committer Android (Google) Code Review <android-gerrit@google.com> 2015-11-18 19:13:13 +0000
commitf91e74d9a945f59cdb714a80a2a87953d72dbd99 (patch)
treef022fc9e6fda3a5f788bc925c05897df004f476b
parent32bb7bc314e9ce1ad2f870818aafff83ddec3704 (diff)
parent93cf731b26e2ab4db49bd80f60675b03e40512f3 (diff)
Merge "Implement View.cancelDrag"
-rw-r--r--api/current.txt1
-rw-r--r--api/system-current.txt1
-rw-r--r--core/java/android/view/IWindowSession.aidl5
-rw-r--r--core/java/android/view/View.java31
-rw-r--r--core/java/android/view/ViewRootImpl.java4
-rw-r--r--services/core/java/com/android/server/wm/Session.java26
6 files changed, 61 insertions, 7 deletions
diff --git a/api/current.txt b/api/current.txt
index 620864060898..1a7139c08cd8 100644
--- a/api/current.txt
+++ b/api/current.txt
@@ -36238,6 +36238,7 @@ package android.view {
method public boolean canResolveTextDirection();
method public boolean canScrollHorizontally(int);
method public boolean canScrollVertically(int);
+ method public final void cancelDrag();
method public void cancelLongPress();
method public final void cancelPendingInputEvents();
method public boolean checkInputConnectionProxy(android.view.View);
diff --git a/api/system-current.txt b/api/system-current.txt
index fc11f34314b5..f27844101473 100644
--- a/api/system-current.txt
+++ b/api/system-current.txt
@@ -38559,6 +38559,7 @@ package android.view {
method public boolean canResolveTextDirection();
method public boolean canScrollHorizontally(int);
method public boolean canScrollVertically(int);
+ method public final void cancelDrag();
method public void cancelLongPress();
method public final void cancelPendingInputEvents();
method public boolean checkInputConnectionProxy(android.view.View);
diff --git a/core/java/android/view/IWindowSession.aidl b/core/java/android/view/IWindowSession.aidl
index 3fc70cc3b4d9..f81b5d01671a 100644
--- a/core/java/android/view/IWindowSession.aidl
+++ b/core/java/android/view/IWindowSession.aidl
@@ -186,6 +186,11 @@ interface IWindowSession {
void reportDropResult(IWindow window, boolean consumed);
/**
+ * Cancel a drag operation.
+ */
+ void cancelDrag(IBinder dragToken);
+
+ /**
* Tell the OS that we've just dragged into a View that is willing to accept the drop
*/
void dragRecipientEntered(IWindow window);
diff --git a/core/java/android/view/View.java b/core/java/android/view/View.java
index de4d43990ea0..30408c6d4d46 100644
--- a/core/java/android/view/View.java
+++ b/core/java/android/view/View.java
@@ -19905,11 +19905,11 @@ public class View implements Drawable.Callback, KeyEvent.Callback,
}
Surface surface = new Surface();
try {
- IBinder token = mAttachInfo.mSession.prepareDrag(mAttachInfo.mWindow,
+ mAttachInfo.mDragToken = mAttachInfo.mSession.prepareDrag(mAttachInfo.mWindow,
flags, shadowSize.x, shadowSize.y, surface);
- if (ViewDebug.DEBUG_DRAG) Log.d(VIEW_LOG_TAG, "prepareDrag returned token=" + token
- + " surface=" + surface);
- if (token != null) {
+ if (ViewDebug.DEBUG_DRAG) Log.d(VIEW_LOG_TAG, "prepareDrag returned token="
+ + mAttachInfo.mDragToken + " surface=" + surface);
+ if (mAttachInfo.mDragToken != null) {
Canvas canvas = surface.lockCanvas(null);
try {
canvas.drawColor(0, PorterDuff.Mode.CLEAR);
@@ -19926,7 +19926,7 @@ public class View implements Drawable.Callback, KeyEvent.Callback,
// repurpose 'shadowSize' for the last touch point
root.getLastTouchPoint(shadowSize);
- okay = mAttachInfo.mSession.performDrag(mAttachInfo.mWindow, token,
+ okay = mAttachInfo.mSession.performDrag(mAttachInfo.mWindow, mAttachInfo.mDragToken,
shadowSize.x, shadowSize.y,
shadowTouchPoint.x, shadowTouchPoint.y, data);
if (ViewDebug.DEBUG_DRAG) Log.d(VIEW_LOG_TAG, "performDrag returned " + okay);
@@ -19943,6 +19943,22 @@ public class View implements Drawable.Callback, KeyEvent.Callback,
return okay;
}
+ public final void cancelDrag() {
+ if (ViewDebug.DEBUG_DRAG) {
+ Log.d(VIEW_LOG_TAG, "cancelDrag");
+ }
+ if (mAttachInfo.mDragToken != null) {
+ try {
+ mAttachInfo.mSession.cancelDrag(mAttachInfo.mDragToken);
+ } catch (Exception e) {
+ Log.e(VIEW_LOG_TAG, "Unable to cancel drag", e);
+ }
+ mAttachInfo.mDragToken = null;
+ } else {
+ Log.e(VIEW_LOG_TAG, "No active drag to cancel");
+ }
+ }
+
/**
* Starts a move from {startX, startY}, the amount of the movement will be the offset
* between {startX, startY} and the new cursor positon.
@@ -22221,6 +22237,11 @@ public class View implements Drawable.Callback, KeyEvent.Callback,
View mViewRequestingLayout;
/**
+ * Used to track the identity of the current drag operation.
+ */
+ IBinder mDragToken;
+
+ /**
* Creates a new set of attachment information with the specified
* events handler and thread.
*
diff --git a/core/java/android/view/ViewRootImpl.java b/core/java/android/view/ViewRootImpl.java
index cd9dd97468b3..f1d9f1ab1b45 100644
--- a/core/java/android/view/ViewRootImpl.java
+++ b/core/java/android/view/ViewRootImpl.java
@@ -5307,10 +5307,10 @@ public final class ViewRootImpl implements ViewParent,
}
}
- // When the drag operation ends, release any local state object
- // that may have been in use
+ // When the drag operation ends, reset drag-related state
if (what == DragEvent.ACTION_DRAG_ENDED) {
setLocalDragState(null);
+ mAttachInfo.mDragToken = null;
}
}
}
diff --git a/services/core/java/com/android/server/wm/Session.java b/services/core/java/com/android/server/wm/Session.java
index 1caeca09238d..b85a6923d7f3 100644
--- a/services/core/java/com/android/server/wm/Session.java
+++ b/services/core/java/com/android/server/wm/Session.java
@@ -401,6 +401,32 @@ final class Session extends IWindowSession.Stub
}
}
+ public void cancelDrag(IBinder dragToken) {
+ if (WindowManagerService.DEBUG_DRAG) {
+ Slog.d(WindowManagerService.TAG, "cancel drag");
+ }
+
+ synchronized (mService.mWindowMap) {
+ long ident = Binder.clearCallingIdentity();
+ try {
+ if (mService.mDragState == null) {
+ Slog.w(WindowManagerService.TAG, "cancelDrag() without prepareDrag()");
+ throw new IllegalStateException("cancelDrag() without prepareDrag()");
+ }
+
+ if (mService.mDragState.mToken != dragToken) {
+ Slog.w(WindowManagerService.TAG, "cancelDrag() does not match prepareDrag()");
+ throw new IllegalStateException("cancelDrag() does not match prepareDrag()");
+ }
+
+ mService.mDragState.mDragResult = false;
+ mService.mDragState.endDragLw();
+ } finally {
+ Binder.restoreCallingIdentity(ident);
+ }
+ }
+ }
+
public void dragRecipientEntered(IWindow window) {
if (WindowManagerService.DEBUG_DRAG) {
Slog.d(WindowManagerService.TAG, "Drag into new candidate view @ " + window.asBinder());