summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
author TreeHugger Robot <treehugger-gerrit@google.com> 2018-01-19 01:24:40 +0000
committer Android (Google) Code Review <android-gerrit@google.com> 2018-01-19 01:24:40 +0000
commit07f35aa6165c7abd418faf3b419bc1a003f6d992 (patch)
tree8e18d0dd37c25747b72cfd89d876a32614d55379
parent22b111da8b41f5f5962d1a37725cb58db44577c5 (diff)
parentfabca09f0f5cf32eeebb4c8ae793f498aa182d58 (diff)
Merge changes from topic "shadow-in-app"
* changes: Remove DragDropController#prepareDrag() Create a drag shadow surface in app process,
-rw-r--r--core/java/android/view/IWindowSession.aidl32
-rw-r--r--core/java/android/view/SurfaceControl.aidl19
-rw-r--r--core/java/android/view/View.java70
-rw-r--r--services/core/java/com/android/server/wm/DisplayContent.java7
-rw-r--r--services/core/java/com/android/server/wm/DragDropController.java150
-rw-r--r--services/core/java/com/android/server/wm/Session.java19
-rw-r--r--services/tests/servicestests/src/com/android/server/wm/DragDropControllerTests.java42
7 files changed, 160 insertions, 179 deletions
diff --git a/core/java/android/view/IWindowSession.aidl b/core/java/android/view/IWindowSession.aidl
index 49f14442868b..17b6ddca6394 100644
--- a/core/java/android/view/IWindowSession.aidl
+++ b/core/java/android/view/IWindowSession.aidl
@@ -29,6 +29,7 @@ import android.view.IWindowId;
import android.view.MotionEvent;
import android.view.WindowManager;
import android.view.Surface;
+import android.view.SurfaceControl;
/**
* System private per-application interface to the window manager.
@@ -150,25 +151,32 @@ interface IWindowSession {
boolean performHapticFeedback(IWindow window, int effectId, boolean always);
/**
- * Allocate the drag's thumbnail surface. Also assigns a token that identifies
- * the drag to the OS and passes that as the return value. A return value of
- * null indicates failure.
- */
- IBinder prepareDrag(IWindow window, int flags,
- int thumbnailWidth, int thumbnailHeight, out Surface outSurface);
-
- /**
* Initiate the drag operation itself
- */
- boolean performDrag(IWindow window, IBinder dragToken, int touchSource,
+ *
+ * @param window Window which initiates drag operation.
+ * @param flags See {@code View#startDragAndDrop}
+ * @param surface Surface containing drag shadow image
+ * @param touchSource See {@code InputDevice#getSource()}
+ * @param touchX TODO (b/72072998): Fix the issue that the system server misuse the arguments as
+ * initial touch point while the framework passes drag shadow size.
+ * @param touchY TODO (b/72072998): Fix the issue that the system server misuse the arguments as
+ * initial touch point while the framework passes drag shadow size.
+ * @param thumbCenterX X coordinate for the position within the shadow image that should be
+ * underneath the touch point during the drag and drop operation.
+ * @param thumbCenterY Y coordinate for the position within the shadow image that should be
+ * underneath the touch point during the drag and drop operation.
+ * @param data Data transferred by drag and drop
+ * @return Token of drag operation which will be passed to cancelDragAndDrop.
+ */
+ IBinder performDrag(IWindow window, int flags, in SurfaceControl surface, int touchSource,
float touchX, float touchY, float thumbCenterX, float thumbCenterY, in ClipData data);
- /**
+ /**
* Report the result of a drop action targeted to the given window.
* consumed is 'true' when the drop was accepted by a valid recipient,
* 'false' otherwise.
*/
- void reportDropResult(IWindow window, boolean consumed);
+ void reportDropResult(IWindow window, boolean consumed);
/**
* Cancel the current drag operation.
diff --git a/core/java/android/view/SurfaceControl.aidl b/core/java/android/view/SurfaceControl.aidl
new file mode 100644
index 000000000000..744ead2be643
--- /dev/null
+++ b/core/java/android/view/SurfaceControl.aidl
@@ -0,0 +1,19 @@
+/*
+ * Copyright (C) 2017 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.view;
+
+parcelable SurfaceControl;
diff --git a/core/java/android/view/View.java b/core/java/android/view/View.java
index 3242ff1a0b90..05770c357526 100644
--- a/core/java/android/view/View.java
+++ b/core/java/android/view/View.java
@@ -23562,15 +23562,13 @@ public class View implements Drawable.Callback, KeyEvent.Callback,
data.prepareToLeaveProcess((flags & View.DRAG_FLAG_GLOBAL) != 0);
}
- boolean okay = false;
-
Point shadowSize = new Point();
Point shadowTouchPoint = new Point();
shadowBuilder.onProvideShadowMetrics(shadowSize, shadowTouchPoint);
- if ((shadowSize.x < 0) || (shadowSize.y < 0) ||
- (shadowTouchPoint.x < 0) || (shadowTouchPoint.y < 0)) {
- throw new IllegalStateException("Drag shadow dimensions must not be negative");
+ if ((shadowSize.x <= 0) || (shadowSize.y <= 0)
+ || (shadowTouchPoint.x < 0) || (shadowTouchPoint.y < 0)) {
+ throw new IllegalStateException("Drag shadow dimensions must be positive");
}
if (ViewDebug.DEBUG_DRAG) {
@@ -23581,40 +23579,50 @@ public class View implements Drawable.Callback, KeyEvent.Callback,
mAttachInfo.mDragSurface.release();
}
mAttachInfo.mDragSurface = new Surface();
+ mAttachInfo.mDragToken = null;
+
+ final ViewRootImpl root = mAttachInfo.mViewRootImpl;
+ final SurfaceSession session = new SurfaceSession(root.mSurface);
+ final SurfaceControl surface = new SurfaceControl.Builder(session)
+ .setName("drag surface")
+ .setSize(shadowSize.x, shadowSize.y)
+ .setFormat(PixelFormat.TRANSLUCENT)
+ .build();
try {
- mAttachInfo.mDragToken = mAttachInfo.mSession.prepareDrag(mAttachInfo.mWindow,
- flags, shadowSize.x, shadowSize.y, mAttachInfo.mDragSurface);
- if (ViewDebug.DEBUG_DRAG) Log.d(VIEW_LOG_TAG, "prepareDrag returned token="
- + mAttachInfo.mDragToken + " surface=" + mAttachInfo.mDragSurface);
- if (mAttachInfo.mDragToken != null) {
- Canvas canvas = mAttachInfo.mDragSurface.lockCanvas(null);
- try {
- canvas.drawColor(0, PorterDuff.Mode.CLEAR);
- shadowBuilder.onDrawShadow(canvas);
- } finally {
- mAttachInfo.mDragSurface.unlockCanvasAndPost(canvas);
- }
-
- final ViewRootImpl root = getViewRootImpl();
+ mAttachInfo.mDragSurface.copyFrom(surface);
+ final Canvas canvas = mAttachInfo.mDragSurface.lockCanvas(null);
+ try {
+ canvas.drawColor(0, PorterDuff.Mode.CLEAR);
+ shadowBuilder.onDrawShadow(canvas);
+ } finally {
+ mAttachInfo.mDragSurface.unlockCanvasAndPost(canvas);
+ }
- // Cache the local state object for delivery with DragEvents
- root.setLocalDragState(myLocalState);
+ // Cache the local state object for delivery with DragEvents
+ root.setLocalDragState(myLocalState);
- // repurpose 'shadowSize' for the last touch point
- root.getLastTouchPoint(shadowSize);
+ // repurpose 'shadowSize' for the last touch point
+ root.getLastTouchPoint(shadowSize);
- okay = mAttachInfo.mSession.performDrag(mAttachInfo.mWindow, mAttachInfo.mDragToken,
- root.getLastTouchSource(), shadowSize.x, shadowSize.y,
- shadowTouchPoint.x, shadowTouchPoint.y, data);
- if (ViewDebug.DEBUG_DRAG) Log.d(VIEW_LOG_TAG, "performDrag returned " + okay);
+ mAttachInfo.mDragToken = mAttachInfo.mSession.performDrag(
+ mAttachInfo.mWindow, flags, surface, root.getLastTouchSource(),
+ shadowSize.x, shadowSize.y, shadowTouchPoint.x, shadowTouchPoint.y, data);
+ if (ViewDebug.DEBUG_DRAG) {
+ Log.d(VIEW_LOG_TAG, "performDrag returned " + mAttachInfo.mDragToken);
}
+
+ return mAttachInfo.mDragToken != null;
} catch (Exception e) {
Log.e(VIEW_LOG_TAG, "Unable to initiate drag", e);
- mAttachInfo.mDragSurface.destroy();
- mAttachInfo.mDragSurface = null;
+ return false;
+ } finally {
+ if (mAttachInfo.mDragToken == null) {
+ mAttachInfo.mDragSurface.destroy();
+ mAttachInfo.mDragSurface = null;
+ root.setLocalDragState(null);
+ }
+ session.kill();
}
-
- return okay;
}
/**
diff --git a/services/core/java/com/android/server/wm/DisplayContent.java b/services/core/java/com/android/server/wm/DisplayContent.java
index 3997c56eec07..fba404ed6f0e 100644
--- a/services/core/java/com/android/server/wm/DisplayContent.java
+++ b/services/core/java/com/android/server/wm/DisplayContent.java
@@ -3697,6 +3697,13 @@ class DisplayContent extends WindowContainer<DisplayContent.DisplayChildWindowCo
.setParent(mOverlayLayer);
}
+ /**
+ * Reparents the given surface to mOverlayLayer.
+ */
+ void reparentToOverlay(Transaction transaction, SurfaceControl surface) {
+ transaction.reparent(surface, mOverlayLayer.getHandle());
+ }
+
void applyMagnificationSpec(MagnificationSpec spec) {
applyMagnificationSpec(getPendingTransaction(), spec);
getPendingTransaction().apply();
diff --git a/services/core/java/com/android/server/wm/DragDropController.java b/services/core/java/com/android/server/wm/DragDropController.java
index 0171b56ffc47..d55a64926504 100644
--- a/services/core/java/com/android/server/wm/DragDropController.java
+++ b/services/core/java/com/android/server/wm/DragDropController.java
@@ -18,12 +18,10 @@ package com.android.server.wm;
import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_DRAG;
import static com.android.server.wm.WindowManagerDebugConfig.SHOW_LIGHT_TRANSACTIONS;
-import static com.android.server.wm.WindowManagerDebugConfig.SHOW_TRANSACTIONS;
import static com.android.server.wm.WindowManagerDebugConfig.TAG_WM;
import android.annotation.NonNull;
import android.content.ClipData;
-import android.graphics.PixelFormat;
import android.os.Binder;
import android.os.Handler;
import android.os.IBinder;
@@ -32,8 +30,8 @@ import android.os.Message;
import android.util.Slog;
import android.view.Display;
import android.view.IWindow;
-import android.view.Surface;
import android.view.SurfaceControl;
+import android.view.SurfaceControl.Transaction;
import android.view.SurfaceSession;
import android.view.View;
@@ -50,10 +48,9 @@ class DragDropController {
private static final long DRAG_TIMEOUT_MS = 5000;
// Messages for Handler.
- private static final int MSG_DRAG_START_TIMEOUT = 0;
- static final int MSG_DRAG_END_TIMEOUT = 1;
- static final int MSG_TEAR_DOWN_DRAG_AND_DROP_INPUT = 2;
- static final int MSG_ANIMATION_END = 3;
+ static final int MSG_DRAG_END_TIMEOUT = 0;
+ static final int MSG_TEAR_DOWN_DRAG_AND_DROP_INPUT = 1;
+ static final int MSG_ANIMATION_END = 2;
/**
* Drag state per operation.
@@ -95,87 +92,35 @@ class DragDropController {
mDragState.sendDragStartedIfNeededLocked(window);
}
- IBinder prepareDrag(SurfaceSession session, int callerPid,
- int callerUid, IWindow window, int flags, int width, int height, Surface outSurface) {
+ IBinder performDrag(SurfaceSession session, int callerPid, int callerUid, IWindow window,
+ int flags, SurfaceControl surface, int touchSource, float touchX, float touchY,
+ float thumbCenterX, float thumbCenterY, ClipData data) {
if (DEBUG_DRAG) {
- Slog.d(TAG_WM, "prepare drag surface: w=" + width + " h=" + height
- + " flags=" + Integer.toHexString(flags) + " win=" + window
- + " asbinder=" + window.asBinder());
- }
-
- if (width <= 0 || height <= 0) {
- Slog.w(TAG_WM, "width and height of drag shadow must be positive");
- return null;
- }
-
- synchronized (mService.mWindowMap) {
- if (dragDropActiveLocked()) {
- Slog.w(TAG_WM, "Drag already in progress");
- return null;
- }
-
- // TODO(multi-display): support other displays
- final DisplayContent displayContent =
- mService.getDefaultDisplayContentLocked();
- final Display display = displayContent.getDisplay();
-
- final SurfaceControl surface = new SurfaceControl.Builder(session)
- .setName("drag surface")
- .setSize(width, height)
- .setFormat(PixelFormat.TRANSLUCENT)
- .build();
- surface.setLayerStack(display.getLayerStack());
- float alpha = 1;
- if ((flags & View.DRAG_FLAG_OPAQUE) == 0) {
- alpha = DRAG_SHADOW_ALPHA_TRANSPARENT;
- }
- surface.setAlpha(alpha);
-
- if (SHOW_TRANSACTIONS)
- Slog.i(TAG_WM, " DRAG " + surface + ": CREATE");
- outSurface.copyFrom(surface);
- final IBinder winBinder = window.asBinder();
- IBinder token = new Binder();
- mDragState = new DragState(mService, this, token, surface, flags, winBinder);
- mDragState.mPid = callerPid;
- mDragState.mUid = callerUid;
- mDragState.mOriginalAlpha = alpha;
- token = mDragState.mToken = new Binder();
-
- // 5 second timeout for this window to actually begin the drag
- sendTimeoutMessage(MSG_DRAG_START_TIMEOUT, winBinder);
- return token;
- }
- }
-
- boolean performDrag(IWindow window, IBinder dragToken,
- int touchSource, float touchX, float touchY, float thumbCenterX, float thumbCenterY,
- ClipData data) {
- if (DEBUG_DRAG) {
- Slog.d(TAG_WM, "perform drag: win=" + window + " data=" + data);
+ Slog.d(TAG_WM, "perform drag: win=" + window + " surface=" + surface + " flags=" +
+ Integer.toHexString(flags) + " data=" + data);
}
+ final IBinder dragToken = new Binder();
final boolean callbackResult = mCallback.get().prePerformDrag(window, dragToken,
touchSource, touchX, touchY, thumbCenterX, thumbCenterY, data);
try {
synchronized (mService.mWindowMap) {
- mHandler.removeMessages(MSG_DRAG_START_TIMEOUT, window.asBinder());
try {
if (!callbackResult) {
- return false;
+ Slog.w(TAG_WM, "IDragDropCallback rejects the performDrag request");
+ return null;
}
- Preconditions.checkState(
- mDragState != null, "performDrag() without prepareDrag()");
- Preconditions.checkState(
- mDragState.mToken == dragToken,
- "performDrag() does not match prepareDrag()");
+ if (dragDropActiveLocked()) {
+ Slog.w(TAG_WM, "Drag already in progress");
+ return null;
+ }
final WindowState callingWin = mService.windowForClientLocked(
null, window, false);
if (callingWin == null) {
Slog.w(TAG_WM, "Bad requesting window " + window);
- return false; // !!! TODO: throw here?
+ return null; // !!! TODO: throw here?
}
// !!! TODO: if input is not still focused on the initiating window, fail
@@ -188,18 +133,31 @@ class DragDropController {
// !!! FIXME: put all this heavy stuff onto the mHandler looper, as well as
// the actual drag event dispatch stuff in the dragstate
+ // !!! TODO(multi-display): support other displays
+
final DisplayContent displayContent = callingWin.getDisplayContent();
if (displayContent == null) {
Slog.w(TAG_WM, "display content is null");
- return false;
+ return null;
}
+ final float alpha = (flags & View.DRAG_FLAG_OPAQUE) == 0 ?
+ DRAG_SHADOW_ALPHA_TRANSPARENT : 1;
+ final IBinder winBinder = window.asBinder();
+ IBinder token = new Binder();
+ mDragState = new DragState(mService, this, token, surface, flags, winBinder);
+ surface = null;
+ mDragState.mPid = callerPid;
+ mDragState.mUid = callerUid;
+ mDragState.mOriginalAlpha = alpha;
+ mDragState.mToken = dragToken;
+
final Display display = displayContent.getDisplay();
mDragState.register(display);
if (!mService.mInputManager.transferTouchFocus(callingWin.mInputChannel,
mDragState.getInputChannel())) {
Slog.e(TAG_WM, "Unable to transfer touch focus");
- return false;
+ return null;
}
mDragState.mDisplayContent = displayContent;
@@ -213,28 +171,31 @@ class DragDropController {
// Make the surface visible at the proper location
final SurfaceControl surfaceControl = mDragState.mSurfaceControl;
if (SHOW_LIGHT_TRANSACTIONS) Slog.i(TAG_WM, ">>> OPEN TRANSACTION performDrag");
- mService.openSurfaceTransaction();
- try {
- surfaceControl.setPosition(touchX - thumbCenterX,
- touchY - thumbCenterY);
- surfaceControl.setLayer(mDragState.getDragLayerLocked());
- surfaceControl.setLayerStack(display.getLayerStack());
- surfaceControl.show();
- } finally {
- mService.closeSurfaceTransaction("performDrag");
- if (SHOW_LIGHT_TRANSACTIONS) {
- Slog.i(TAG_WM, "<<< CLOSE TRANSACTION performDrag");
- }
+
+ final SurfaceControl.Transaction transaction =
+ callingWin.getPendingTransaction();
+ transaction.setAlpha(surfaceControl, mDragState.mOriginalAlpha);
+ transaction.setPosition(
+ surfaceControl, touchX - thumbCenterX, touchY - thumbCenterY);
+ transaction.show(surfaceControl);
+ displayContent.reparentToOverlay(transaction, surfaceControl);
+ callingWin.scheduleAnimation();
+
+ if (SHOW_LIGHT_TRANSACTIONS) {
+ Slog.i(TAG_WM, "<<< CLOSE TRANSACTION performDrag");
}
mDragState.notifyLocationLocked(touchX, touchY);
} finally {
+ if (surface != null) {
+ surface.release();
+ }
if (mDragState != null && !mDragState.isInProgress()) {
mDragState.closeLocked();
}
}
}
- return true; // success!
+ return dragToken; // success!
} finally {
mCallback.get().postPerformDrag();
}
@@ -385,21 +346,6 @@ class DragDropController {
@Override
public void handleMessage(Message msg) {
switch (msg.what) {
- case MSG_DRAG_START_TIMEOUT: {
- IBinder win = (IBinder) msg.obj;
- if (DEBUG_DRAG) {
- Slog.w(TAG_WM, "Timeout starting drag by win " + win);
- }
-
- synchronized (mService.mWindowMap) {
- // !!! TODO: ANR the app that has failed to start the drag in time
- if (mDragState != null) {
- mDragState.closeLocked();
- }
- }
- break;
- }
-
case MSG_DRAG_END_TIMEOUT: {
final IBinder win = (IBinder) msg.obj;
if (DEBUG_DRAG) {
diff --git a/services/core/java/com/android/server/wm/Session.java b/services/core/java/com/android/server/wm/Session.java
index 334be336e199..04ae38ec33b1 100644
--- a/services/core/java/com/android/server/wm/Session.java
+++ b/services/core/java/com/android/server/wm/Session.java
@@ -51,6 +51,7 @@ import android.view.IWindowSession;
import android.view.IWindowSessionCallback;
import android.view.InputChannel;
import android.view.Surface;
+import android.view.SurfaceControl;
import android.view.SurfaceSession;
import android.view.WindowManager;
@@ -308,30 +309,22 @@ class Session extends IWindowSession.Stub implements IBinder.DeathRecipient {
}
/* Drag/drop */
+
@Override
- public IBinder prepareDrag(IWindow window, int flags, int width, int height,
- Surface outSurface) {
+ public IBinder performDrag(IWindow window, int flags, SurfaceControl surface, int touchSource,
+ float touchX, float touchY, float thumbCenterX, float thumbCenterY, ClipData data) {
final int callerPid = Binder.getCallingPid();
final int callerUid = Binder.getCallingUid();
final long ident = Binder.clearCallingIdentity();
try {
- return mDragDropController.prepareDrag(
- mSurfaceSession, callerPid, callerUid, window, flags, width, height,
- outSurface);
+ return mDragDropController.performDrag(mSurfaceSession, callerPid, callerUid, window,
+ flags, surface, touchSource, touchX, touchY, thumbCenterX, thumbCenterY, data);
} finally {
Binder.restoreCallingIdentity(ident);
}
}
@Override
- public boolean performDrag(IWindow window, IBinder dragToken,
- int touchSource, float touchX, float touchY, float thumbCenterX, float thumbCenterY,
- ClipData data) {
- return mDragDropController.performDrag(window, dragToken, touchSource,
- touchX, touchY, thumbCenterX, thumbCenterY, data);
- }
-
- @Override
public void reportDropResult(IWindow window, boolean consumed) {
final long ident = Binder.clearCallingIdentity();
try {
diff --git a/services/tests/servicestests/src/com/android/server/wm/DragDropControllerTests.java b/services/tests/servicestests/src/com/android/server/wm/DragDropControllerTests.java
index ac291632c877..57da6a3a60a6 100644
--- a/services/tests/servicestests/src/com/android/server/wm/DragDropControllerTests.java
+++ b/services/tests/servicestests/src/com/android/server/wm/DragDropControllerTests.java
@@ -20,7 +20,6 @@ import static android.app.WindowConfiguration.ACTIVITY_TYPE_STANDARD;
import static android.app.WindowConfiguration.WINDOWING_MODE_FULLSCREEN;
import static android.view.WindowManager.LayoutParams.TYPE_BASE_APPLICATION;
import static org.junit.Assert.assertNotNull;
-import static org.junit.Assert.assertNull;
import static org.junit.Assert.assertTrue;
import static org.mockito.Mockito.any;
import static org.mockito.Mockito.mock;
@@ -28,6 +27,7 @@ import static org.mockito.Mockito.spy;
import static org.mockito.Mockito.when;
import android.content.ClipData;
+import android.graphics.PixelFormat;
import android.os.IBinder;
import android.os.Looper;
import android.os.UserHandle;
@@ -36,7 +36,7 @@ import android.platform.test.annotations.Presubmit;
import android.support.test.filters.SmallTest;
import android.support.test.runner.AndroidJUnit4;
import android.view.InputChannel;
-import android.view.Surface;
+import android.view.SurfaceControl;
import android.view.SurfaceSession;
import android.view.View;
import com.android.internal.annotations.GuardedBy;
@@ -146,14 +146,6 @@ public class DragDropControllerTests extends WindowTestsBase {
}
@Test
- public void testPrepareDrag_ZeroSizeSurface() throws Exception {
- final Surface surface = new Surface();
- mToken = mTarget.prepareDrag(
- new SurfaceSession(), 0, 0, mWindow.mClient, 0, 0, 0, surface);
- assertNull(mToken);
- }
-
- @Test
public void testPerformDrag_NullDataWithGrantUri() throws Exception {
dragFlow(View.DRAG_FLAG_GLOBAL | View.DRAG_FLAG_GLOBAL_URI_READ, null, 0, 0);
}
@@ -169,16 +161,24 @@ public class DragDropControllerTests extends WindowTestsBase {
}
private void dragFlow(int flag, ClipData data, float dropX, float dropY) {
- final Surface surface = new Surface();
- mToken = mTarget.prepareDrag(
- new SurfaceSession(), 0, 0, mWindow.mClient, flag, 100, 100, surface);
- assertNotNull(mToken);
-
- assertTrue(sWm.mInputManager.transferTouchFocus(null, null));
- assertTrue(mTarget.performDrag(
- mWindow.mClient, mToken, 0, 0, 0, 0, 0, data));
-
- mTarget.handleMotionEvent(false, dropX, dropY);
- mToken = mWindow.mClient.asBinder();
+ final SurfaceSession appSession = new SurfaceSession();
+ try {
+ final SurfaceControl surface = new SurfaceControl.Builder(appSession)
+ .setName("drag surface")
+ .setSize(100, 100)
+ .setFormat(PixelFormat.TRANSLUCENT)
+ .build();
+
+ assertTrue(sWm.mInputManager.transferTouchFocus(null, null));
+ mToken = mTarget.performDrag(
+ new SurfaceSession(), 0, 0, mWindow.mClient, flag, surface, 0, 0, 0, 0, 0,
+ data);
+ assertNotNull(mToken);
+
+ mTarget.handleMotionEvent(false, dropX, dropY);
+ mToken = mWindow.mClient.asBinder();
+ } finally {
+ appSession.kill();
+ }
}
}