Move mDragState from WindowManagerService to DragDropController
Bug: 65564090
Test: android.server.wm.CrossAppDragAndDropTests, manually check the drag
and drop behavior on test app.
Change-Id: I2445ccff6e2cfd673c47f591ac88f3f60a7a6ddc
diff --git a/services/core/java/com/android/server/wm/DragDropController.java b/services/core/java/com/android/server/wm/DragDropController.java
index cd20421..a3c6167 100644
--- a/services/core/java/com/android/server/wm/DragDropController.java
+++ b/services/core/java/com/android/server/wm/DragDropController.java
@@ -16,8 +16,6 @@
package com.android.server.wm;
-import static android.graphics.PixelFormat.TRANSLUCENT;
-import static android.view.SurfaceControl.HIDDEN;
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;
@@ -26,14 +24,12 @@
import android.content.ClipData;
import android.graphics.PixelFormat;
import android.os.Binder;
-import android.os.Handler;
import android.os.IBinder;
import android.os.Message;
import android.util.Slog;
import android.view.Display;
import android.view.IWindow;
import android.view.Surface;
-import android.view.Surface.OutOfResourcesException;
import android.view.SurfaceControl;
import android.view.SurfaceSession;
import android.view.View;
@@ -45,6 +41,11 @@
class DragDropController {
private static final float DRAG_SHADOW_ALPHA_TRANSPARENT = .7071f;
private static final long DRAG_TIMEOUT_MS = 5000;
+ DragState mDragState;
+
+ boolean dragDropActiveLocked() {
+ return mDragState != null;
+ }
IBinder prepareDrag(WindowManagerService service, SurfaceSession session, int callerPid,
int callerUid, IWindow window, int flags, int width, int height, Surface outSurface) {
@@ -57,52 +58,42 @@
IBinder token = null;
synchronized (service.mWindowMap) {
- try {
- if (service.mDragState == null) {
- // TODO(multi-display): support other displays
- final DisplayContent displayContent =
- service.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();
- token = new Binder();
- service.mDragState =
- new DragState(service, token, surface, flags, winBinder);
- service.mDragState.mPid = callerPid;
- service.mDragState.mUid = callerUid;
- service.mDragState.mOriginalAlpha = alpha;
- token = service.mDragState.mToken = new Binder();
-
- // 5 second timeout for this window to actually begin the drag
- service.mH.removeMessages(H.DRAG_START_TIMEOUT, winBinder);
- Message msg = service.mH.obtainMessage(H.DRAG_START_TIMEOUT, winBinder);
- service.mH.sendMessageDelayed(msg, DRAG_TIMEOUT_MS);
- } else {
- Slog.w(TAG_WM, "Drag already in progress");
- }
- } catch (OutOfResourcesException e) {
- Slog.e(TAG_WM, "Can't allocate drag surface w=" + width + " h=" + height,
- e);
- if (service.mDragState != null) {
- service.mDragState.reset();
- service.mDragState = null;
- }
+ if (dragDropActiveLocked()) {
+ Slog.w(TAG_WM, "Drag already in progress");
+ return null;
}
+
+ // TODO(multi-display): support other displays
+ final DisplayContent displayContent =
+ service.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();
+ token = new Binder();
+ mDragState = new DragState(service, 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
+ service.mH.removeMessages(H.DRAG_START_TIMEOUT, winBinder);
+ Message msg = service.mH.obtainMessage(H.DRAG_START_TIMEOUT, winBinder);
+ service.mH.sendMessageDelayed(msg, DRAG_TIMEOUT_MS);
}
return token;
@@ -116,12 +107,12 @@
}
synchronized (service.mWindowMap) {
- if (service.mDragState == null) {
+ if (mDragState == null) {
Slog.w(TAG_WM, "No drag prepared");
throw new IllegalStateException("performDrag() without prepareDrag()");
}
- if (dragToken != service.mDragState.mToken) {
+ if (dragToken != mDragState.mToken) {
Slog.w(TAG_WM, "Performing mismatched drag");
throw new IllegalStateException("performDrag() does not match prepareDrag()");
}
@@ -149,34 +140,34 @@
return false;
}
Display display = displayContent.getDisplay();
- service.mDragState.register(display);
+ mDragState.register(display);
if (!service.mInputManager.transferTouchFocus(callingWin.mInputChannel,
- service.mDragState.getInputChannel())) {
+ mDragState.getInputChannel())) {
Slog.e(TAG_WM, "Unable to transfer touch focus");
- service.mDragState.unregister();
- service.mDragState.reset();
- service.mDragState = null;
+ mDragState.unregister();
+ mDragState.reset();
+ mDragState = null;
return false;
}
- service.mDragState.mDisplayContent = displayContent;
- service.mDragState.mData = data;
- service.mDragState.broadcastDragStartedLw(touchX, touchY);
- service.mDragState.overridePointerIconLw(touchSource);
+ mDragState.mDisplayContent = displayContent;
+ mDragState.mData = data;
+ mDragState.broadcastDragStartedLw(touchX, touchY);
+ mDragState.overridePointerIconLw(touchSource);
// remember the thumb offsets for later
- service.mDragState.mThumbOffsetX = thumbCenterX;
- service.mDragState.mThumbOffsetY = thumbCenterY;
+ mDragState.mThumbOffsetX = thumbCenterX;
+ mDragState.mThumbOffsetY = thumbCenterY;
// Make the surface visible at the proper location
- final SurfaceControl surfaceControl = service.mDragState.mSurfaceControl;
+ final SurfaceControl surfaceControl = mDragState.mSurfaceControl;
if (SHOW_LIGHT_TRANSACTIONS) Slog.i(
TAG_WM, ">>> OPEN TRANSACTION performDrag");
service.openSurfaceTransaction();
try {
surfaceControl.setPosition(touchX - thumbCenterX,
touchY - thumbCenterY);
- surfaceControl.setLayer(service.mDragState.getDragLayerLw());
+ surfaceControl.setLayer(mDragState.getDragLayerLw());
surfaceControl.setLayerStack(display.getLayerStack());
surfaceControl.show();
} finally {
@@ -185,7 +176,7 @@
TAG_WM, "<<< CLOSE TRANSACTION performDrag");
}
- service.mDragState.notifyLocationLw(touchX, touchY);
+ mDragState.notifyLocationLw(touchX, touchY);
}
return true; // success!
@@ -198,14 +189,14 @@
}
synchronized (service.mWindowMap) {
- if (service.mDragState == null) {
+ if (mDragState == null) {
// Most likely the drop recipient ANRed and we ended the drag
// out from under it. Log the issue and move on.
Slog.w(TAG_WM, "Drop result given but no drag in progress");
return;
}
- if (service.mDragState.mToken != token) {
+ if (mDragState.mToken != token) {
// We're in a drag, but the wrong window has responded.
Slog.w(TAG_WM, "Invalid drop-result claim by " + window);
throw new IllegalStateException("reportDropResult() by non-recipient");
@@ -221,8 +212,8 @@
return; // !!! TODO: throw here?
}
- service.mDragState.mDragResult = consumed;
- service.mDragState.endDragLw();
+ mDragState.mDragResult = consumed;
+ mDragState.endDragLw();
}
}
@@ -232,20 +223,20 @@
}
synchronized (service.mWindowMap) {
- if (service.mDragState == null) {
+ if (mDragState == null) {
Slog.w(TAG_WM, "cancelDragAndDrop() without prepareDrag()");
throw new IllegalStateException("cancelDragAndDrop() without prepareDrag()");
}
- if (service.mDragState.mToken != dragToken) {
+ if (mDragState.mToken != dragToken) {
Slog.w(TAG_WM,
"cancelDragAndDrop() does not match prepareDrag()");
throw new IllegalStateException(
"cancelDragAndDrop() does not match prepareDrag()");
}
- service.mDragState.mDragResult = false;
- service.mDragState.cancelDragLw();
+ mDragState.mDragResult = false;
+ mDragState.cancelDragLw();
}
}
@@ -270,10 +261,10 @@
}
synchronized (service.mWindowMap) {
// !!! TODO: ANR the app that has failed to start the drag in time
- if (service.mDragState != null) {
- service.mDragState.unregister();
- service.mDragState.reset();
- service.mDragState = null;
+ if (mDragState != null) {
+ mDragState.unregister();
+ mDragState.reset();
+ mDragState = null;
}
}
break;
@@ -286,9 +277,9 @@
}
synchronized (service.mWindowMap) {
// !!! TODO: ANR the drag-receiving app
- if (service.mDragState != null) {
- service.mDragState.mDragResult = false;
- service.mDragState.endDragLw();
+ if (mDragState != null) {
+ mDragState.mDragResult = false;
+ mDragState.endDragLw();
}
}
break;