summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--services/core/java/com/android/server/wm/DragDropController.java306
-rw-r--r--services/core/java/com/android/server/wm/Session.java196
-rw-r--r--services/core/java/com/android/server/wm/WindowManagerService.java114
3 files changed, 350 insertions, 266 deletions
diff --git a/services/core/java/com/android/server/wm/DragDropController.java b/services/core/java/com/android/server/wm/DragDropController.java
new file mode 100644
index 000000000000..36871b1d8c5b
--- /dev/null
+++ b/services/core/java/com/android/server/wm/DragDropController.java
@@ -0,0 +1,306 @@
+/*
+ * 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 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;
+import static com.android.server.wm.WindowManagerDebugConfig.TAG_WM;
+
+import android.content.ClipData;
+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;
+import com.android.server.wm.WindowManagerService.H;
+
+/**
+ * Managing drag and drop operations initiated by View#startDragAndDrop.
+ */
+class DragDropController {
+ private static final float DRAG_SHADOW_ALPHA_TRANSPARENT = .7071f;
+ private static final long DRAG_TIMEOUT_MS = 5000;
+
+ IBinder prepareDrag(WindowManagerService service, SurfaceSession session, int callerPid,
+ int callerUid, IWindow window, int flags, int width, int height, Surface outSurface) {
+ if (DEBUG_DRAG) {
+ Slog.d(TAG_WM, "prepare drag surface: w=" + width + " h=" + height
+ + " flags=" + Integer.toHexString(flags) + " win=" + window
+ + " asbinder=" + window.asBinder());
+ }
+
+ 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();
+
+ SurfaceControl surface = new SurfaceControl(session, "drag surface",
+ width, height, TRANSLUCENT, HIDDEN);
+ 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;
+ }
+ }
+ }
+
+ return token;
+ }
+
+ boolean performDrag(WindowManagerService service, 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);
+ }
+
+ synchronized (service.mWindowMap) {
+ if (service.mDragState == null) {
+ Slog.w(TAG_WM, "No drag prepared");
+ throw new IllegalStateException("performDrag() without prepareDrag()");
+ }
+
+ if (dragToken != service.mDragState.mToken) {
+ Slog.w(TAG_WM, "Performing mismatched drag");
+ throw new IllegalStateException("performDrag() does not match prepareDrag()");
+ }
+
+ final WindowState callingWin = service.windowForClientLocked(null, window, false);
+ if (callingWin == null) {
+ Slog.w(TAG_WM, "Bad requesting window " + window);
+ return false; // !!! TODO: throw here?
+ }
+
+ // !!! TODO: if input is not still focused on the initiating window, fail
+ // the drag initiation (e.g. an alarm window popped up just as the application
+ // called performDrag()
+
+ service.mH.removeMessages(H.DRAG_START_TIMEOUT, window.asBinder());
+
+ // !!! TODO: extract the current touch (x, y) in screen coordinates. That
+ // will let us eliminate the (touchX,touchY) parameters from the API.
+
+ // !!! FIXME: put all this heavy stuff onto the mH looper, as well as
+ // the actual drag event dispatch stuff in the dragstate
+
+ final DisplayContent displayContent = callingWin.getDisplayContent();
+ if (displayContent == null) {
+ return false;
+ }
+ Display display = displayContent.getDisplay();
+ service.mDragState.register(display);
+ if (!service.mInputManager.transferTouchFocus(callingWin.mInputChannel,
+ service.mDragState.getInputChannel())) {
+ Slog.e(TAG_WM, "Unable to transfer touch focus");
+ service.mDragState.unregister();
+ service.mDragState.reset();
+ service.mDragState = null;
+ return false;
+ }
+
+ service.mDragState.mDisplayContent = displayContent;
+ service.mDragState.mData = data;
+ service.mDragState.broadcastDragStartedLw(touchX, touchY);
+ service.mDragState.overridePointerIconLw(touchSource);
+
+ // remember the thumb offsets for later
+ service.mDragState.mThumbOffsetX = thumbCenterX;
+ service.mDragState.mThumbOffsetY = thumbCenterY;
+
+ // Make the surface visible at the proper location
+ final SurfaceControl surfaceControl = service.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.setLayerStack(display.getLayerStack());
+ surfaceControl.show();
+ } finally {
+ service.closeSurfaceTransaction();
+ if (SHOW_LIGHT_TRANSACTIONS) Slog.i(
+ TAG_WM, "<<< CLOSE TRANSACTION performDrag");
+ }
+
+ service.mDragState.notifyLocationLw(touchX, touchY);
+ }
+
+ return true; // success!
+ }
+
+ void reportDropResult(WindowManagerService service, IWindow window, boolean consumed) {
+ IBinder token = window.asBinder();
+ if (DEBUG_DRAG) {
+ Slog.d(TAG_WM, "Drop result=" + consumed + " reported by " + token);
+ }
+
+ synchronized (service.mWindowMap) {
+ if (service.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) {
+ // 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");
+ }
+
+ // The right window has responded, even if it's no longer around,
+ // so be sure to halt the timeout even if the later WindowState
+ // lookup fails.
+ service.mH.removeMessages(H.DRAG_END_TIMEOUT, window.asBinder());
+ WindowState callingWin = service.windowForClientLocked(null, window, false);
+ if (callingWin == null) {
+ Slog.w(TAG_WM, "Bad result-reporting window " + window);
+ return; // !!! TODO: throw here?
+ }
+
+ service.mDragState.mDragResult = consumed;
+ service.mDragState.endDragLw();
+ }
+ }
+
+ void cancelDragAndDrop(WindowManagerService service, IBinder dragToken) {
+ if (DEBUG_DRAG) {
+ Slog.d(TAG_WM, "cancelDragAndDrop");
+ }
+
+ synchronized (service.mWindowMap) {
+ if (service.mDragState == null) {
+ Slog.w(TAG_WM, "cancelDragAndDrop() without prepareDrag()");
+ throw new IllegalStateException("cancelDragAndDrop() without prepareDrag()");
+ }
+
+ if (service.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();
+ }
+ }
+
+ void dragRecipientEntered(IWindow window) {
+ if (DEBUG_DRAG) {
+ Slog.d(TAG_WM, "Drag into new candidate view @ " + window.asBinder());
+ }
+ }
+
+ void dragRecipientExited(IWindow window) {
+ if (DEBUG_DRAG) {
+ Slog.d(TAG_WM, "Drag from old candidate view @ " + window.asBinder());
+ }
+ }
+
+ void handleMessage(WindowManagerService service, Message msg) {
+ switch (msg.what) {
+ case H.DRAG_START_TIMEOUT: {
+ IBinder win = (IBinder) msg.obj;
+ if (DEBUG_DRAG) {
+ Slog.w(TAG_WM, "Timeout starting drag by win " + win);
+ }
+ 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;
+ }
+ }
+ break;
+ }
+
+ case H.DRAG_END_TIMEOUT: {
+ IBinder win = (IBinder) msg.obj;
+ if (DEBUG_DRAG) {
+ Slog.w(TAG_WM, "Timeout ending drag to win " + win);
+ }
+ synchronized (service.mWindowMap) {
+ // !!! TODO: ANR the drag-receiving app
+ if (service.mDragState != null) {
+ service.mDragState.mDragResult = false;
+ service.mDragState.endDragLw();
+ }
+ }
+ break;
+ }
+
+ case H.TEAR_DOWN_DRAG_AND_DROP_INPUT: {
+ if (DEBUG_DRAG)
+ Slog.d(TAG_WM, "Drag ending; tearing down input channel");
+ DragState.InputInterceptor interceptor = (DragState.InputInterceptor) msg.obj;
+ if (interceptor != null) {
+ synchronized (service.mWindowMap) {
+ interceptor.tearDown();
+ }
+ }
+ break;
+ }
+ }
+ }
+}
diff --git a/services/core/java/com/android/server/wm/Session.java b/services/core/java/com/android/server/wm/Session.java
index 2bb023557647..717c5774f9f3 100644
--- a/services/core/java/com/android/server/wm/Session.java
+++ b/services/core/java/com/android/server/wm/Session.java
@@ -81,6 +81,7 @@ class Session extends IWindowSession.Stub implements IBinder.DeathRecipient {
private final Set<WindowSurfaceController> mAppOverlaySurfaces = new HashSet<>();
// Set of visible alert window surfaces connected to this session.
private final Set<WindowSurfaceController> mAlertWindowSurfaces = new HashSet<>();
+ private final DragDropController mDragDropController;
final boolean mCanAddInternalSystemWindow;
final boolean mCanHideNonSystemOverlayWindows;
final boolean mCanAcquireSleepToken;
@@ -106,6 +107,7 @@ class Session extends IWindowSession.Stub implements IBinder.DeathRecipient {
mCanAcquireSleepToken = service.mContext.checkCallingOrSelfPermission(DEVICE_POWER)
== PERMISSION_GRANTED;
mShowingAlertWindowNotificationAllowed = mService.mShowAlertWindowNotifications;
+ mDragDropController = mService.mDragDropController;
StringBuilder sb = new StringBuilder();
sb.append("Session{");
sb.append(Integer.toHexString(System.identityHashCode(this)));
@@ -304,190 +306,68 @@ class Session extends IWindowSession.Stub implements IBinder.DeathRecipient {
/* Drag/drop */
@Override
- public IBinder prepareDrag(IWindow window, int flags,
- int width, int height, Surface outSurface) {
- return mService.prepareDragSurface(window, mSurfaceSession, flags,
- width, height, outSurface);
+ public IBinder prepareDrag(IWindow window, int flags, int width, int height,
+ Surface outSurface) {
+ final int callerPid = Binder.getCallingPid();
+ final int callerUid = Binder.getCallingUid();
+ final long ident = Binder.clearCallingIdentity();
+ try {
+ return mDragDropController.prepareDrag(
+ mService, mSurfaceSession, callerPid, callerUid, window, flags, width, height,
+ outSurface);
+ } finally {
+ Binder.restoreCallingIdentity(ident);
+ }
}
@Override
public 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);
- }
-
- synchronized (mService.mWindowMap) {
- if (mService.mDragState == null) {
- Slog.w(TAG_WM, "No drag prepared");
- throw new IllegalStateException("performDrag() without prepareDrag()");
- }
-
- if (dragToken != mService.mDragState.mToken) {
- Slog.w(TAG_WM, "Performing mismatched drag");
- throw new IllegalStateException("performDrag() does not match prepareDrag()");
- }
-
- WindowState callingWin = mService.windowForClientLocked(null, window, false);
- if (callingWin == null) {
- Slog.w(TAG_WM, "Bad requesting window " + window);
- return false; // !!! TODO: throw here?
- }
-
- // !!! TODO: if input is not still focused on the initiating window, fail
- // the drag initiation (e.g. an alarm window popped up just as the application
- // called performDrag()
-
- mService.mH.removeMessages(H.DRAG_START_TIMEOUT, window.asBinder());
-
- // !!! TODO: extract the current touch (x, y) in screen coordinates. That
- // will let us eliminate the (touchX,touchY) parameters from the API.
-
- // !!! FIXME: put all this heavy stuff onto the mH looper, as well as
- // the actual drag event dispatch stuff in the dragstate
-
- final DisplayContent displayContent = callingWin.getDisplayContent();
- if (displayContent == null) {
- return false;
- }
- Display display = displayContent.getDisplay();
- mService.mDragState.register(display);
- if (!mService.mInputManager.transferTouchFocus(callingWin.mInputChannel,
- mService.mDragState.getInputChannel())) {
- Slog.e(TAG_WM, "Unable to transfer touch focus");
- mService.mDragState.unregister();
- mService.mDragState.reset();
- mService.mDragState = null;
- return false;
- }
-
- mService.mDragState.mDisplayContent = displayContent;
- mService.mDragState.mData = data;
- mService.mDragState.broadcastDragStartedLw(touchX, touchY);
- mService.mDragState.overridePointerIconLw(touchSource);
-
- // remember the thumb offsets for later
- mService.mDragState.mThumbOffsetX = thumbCenterX;
- mService.mDragState.mThumbOffsetY = thumbCenterY;
-
- // Make the surface visible at the proper location
- final SurfaceControl surfaceControl = mService.mDragState.mSurfaceControl;
- if (SHOW_LIGHT_TRANSACTIONS) Slog.i(
- TAG_WM, ">>> OPEN TRANSACTION performDrag");
- mService.openSurfaceTransaction();
- try {
- surfaceControl.setPosition(touchX - thumbCenterX,
- touchY - thumbCenterY);
- surfaceControl.setLayer(mService.mDragState.getDragLayerLw());
- surfaceControl.setLayerStack(display.getLayerStack());
- surfaceControl.show();
- } finally {
- mService.closeSurfaceTransaction();
- if (SHOW_LIGHT_TRANSACTIONS) Slog.i(
- TAG_WM, "<<< CLOSE TRANSACTION performDrag");
- }
-
- mService.mDragState.notifyLocationLw(touchX, touchY);
- }
-
- return true; // success!
+ return mDragDropController.performDrag(mService, window, dragToken, touchSource,
+ touchX, touchY, thumbCenterX, thumbCenterY, data);
}
@Override
- public boolean startMovingTask(IWindow window, float startX, float startY) {
- if (DEBUG_TASK_POSITIONING) Slog.d(
- TAG_WM, "startMovingTask: {" + startX + "," + startY + "}");
-
- long ident = Binder.clearCallingIdentity();
+ public void reportDropResult(IWindow window, boolean consumed) {
+ final long ident = Binder.clearCallingIdentity();
try {
- return mService.startMovingTask(window, startX, startY);
+ mDragDropController.reportDropResult(mService, window, consumed);
} finally {
Binder.restoreCallingIdentity(ident);
}
}
@Override
- public void reportDropResult(IWindow window, boolean consumed) {
- IBinder token = window.asBinder();
- if (DEBUG_DRAG) {
- Slog.d(TAG_WM, "Drop result=" + consumed + " reported by " + token);
- }
-
- synchronized (mService.mWindowMap) {
- long ident = Binder.clearCallingIdentity();
- try {
- if (mService.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 (mService.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");
- }
-
- // The right window has responded, even if it's no longer around,
- // so be sure to halt the timeout even if the later WindowState
- // lookup fails.
- mService.mH.removeMessages(H.DRAG_END_TIMEOUT, window.asBinder());
- WindowState callingWin = mService.windowForClientLocked(null, window, false);
- if (callingWin == null) {
- Slog.w(TAG_WM, "Bad result-reporting window " + window);
- return; // !!! TODO: throw here?
- }
-
- mService.mDragState.mDragResult = consumed;
- mService.mDragState.endDragLw();
- } finally {
- Binder.restoreCallingIdentity(ident);
- }
- }
- }
-
- @Override
public void cancelDragAndDrop(IBinder dragToken) {
- if (DEBUG_DRAG) {
- Slog.d(TAG_WM, "cancelDragAndDrop");
- }
-
- synchronized (mService.mWindowMap) {
- long ident = Binder.clearCallingIdentity();
- try {
- if (mService.mDragState == null) {
- Slog.w(TAG_WM, "cancelDragAndDrop() without prepareDrag()");
- throw new IllegalStateException("cancelDragAndDrop() without prepareDrag()");
- }
-
- if (mService.mDragState.mToken != dragToken) {
- Slog.w(TAG_WM,
- "cancelDragAndDrop() does not match prepareDrag()");
- throw new IllegalStateException(
- "cancelDragAndDrop() does not match prepareDrag()");
- }
-
- mService.mDragState.mDragResult = false;
- mService.mDragState.cancelDragLw();
- } finally {
- Binder.restoreCallingIdentity(ident);
- }
+ final long ident = Binder.clearCallingIdentity();
+ try {
+ mDragDropController.cancelDragAndDrop(mService, dragToken);
+ } finally {
+ Binder.restoreCallingIdentity(ident);
}
}
@Override
public void dragRecipientEntered(IWindow window) {
- if (DEBUG_DRAG) {
- Slog.d(TAG_WM, "Drag into new candidate view @ " + window.asBinder());
- }
+ mDragDropController.dragRecipientEntered(window);
}
@Override
public void dragRecipientExited(IWindow window) {
- if (DEBUG_DRAG) {
- Slog.d(TAG_WM, "Drag from old candidate view @ " + window.asBinder());
+ mDragDropController.dragRecipientExited(window);
+ }
+
+ @Override
+ public boolean startMovingTask(IWindow window, float startX, float startY) {
+ if (DEBUG_TASK_POSITIONING) Slog.d(
+ TAG_WM, "startMovingTask: {" + startX + "," + startY + "}");
+
+ long ident = Binder.clearCallingIdentity();
+ try {
+ return mService.startMovingTask(window, startX, startY);
+ } finally {
+ Binder.restoreCallingIdentity(ident);
}
}
diff --git a/services/core/java/com/android/server/wm/WindowManagerService.java b/services/core/java/com/android/server/wm/WindowManagerService.java
index f0da4742efa0..3d60475684e5 100644
--- a/services/core/java/com/android/server/wm/WindowManagerService.java
+++ b/services/core/java/com/android/server/wm/WindowManagerService.java
@@ -357,8 +357,6 @@ public class WindowManagerService extends IWindowManager.Stub
// trying to apply a new one.
private static final boolean ALWAYS_KEEP_CURRENT = true;
- private static final float DRAG_SHADOW_ALPHA_TRANSPARENT = .7071f;
-
// Enums for animation scale update types.
@Retention(RetentionPolicy.SOURCE)
@IntDef({WINDOW_ANIMATION_SCALE, TRANSITION_ANIMATION_SCALE, ANIMATION_DURATION_SCALE})
@@ -752,6 +750,7 @@ public class WindowManagerService extends IWindowManager.Stub
boolean mAllowTheaterModeWakeFromLayout;
TaskPositioner mTaskPositioner;
+ final DragDropController mDragDropController = new DragDropController();
DragState mDragState = null;
// For frozen screen animations.
@@ -4637,73 +4636,6 @@ public class WindowManagerService extends IWindowManager.Stub
}
// -------------------------------------------------------------
- // Drag and drop
- // -------------------------------------------------------------
-
- IBinder prepareDragSurface(IWindow window, SurfaceSession session,
- int flags, int width, int height, Surface outSurface) {
- if (DEBUG_DRAG) {
- Slog.d(TAG_WM, "prepare drag surface: w=" + width + " h=" + height
- + " flags=" + Integer.toHexString(flags) + " win=" + window
- + " asbinder=" + window.asBinder());
- }
-
- final int callerPid = Binder.getCallingPid();
- final int callerUid = Binder.getCallingUid();
- final long origId = Binder.clearCallingIdentity();
- IBinder token = null;
-
- try {
- synchronized (mWindowMap) {
- try {
- if (mDragState == null) {
- // TODO(multi-display): support other displays
- final DisplayContent displayContent = getDefaultDisplayContentLocked();
- final Display display = displayContent.getDisplay();
-
- SurfaceControl surface = new SurfaceControl(session, "drag surface",
- width, height, PixelFormat.TRANSLUCENT, SurfaceControl.HIDDEN);
- 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(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
- mH.removeMessages(H.DRAG_START_TIMEOUT, winBinder);
- Message msg = mH.obtainMessage(H.DRAG_START_TIMEOUT, winBinder);
- mH.sendMessageDelayed(msg, 5000);
- } 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 (mDragState != null) {
- mDragState.reset();
- mDragState = null;
- }
- }
- }
- } finally {
- Binder.restoreCallingIdentity(origId);
- }
-
- return token;
- }
-
- // -------------------------------------------------------------
// Input Events and Focus Management
// -------------------------------------------------------------
@@ -4866,6 +4798,7 @@ public class WindowManagerService extends IWindowManager.Stub
public static final int REPORT_WINDOWS_CHANGE = 19;
public static final int DRAG_START_TIMEOUT = 20;
public static final int DRAG_END_TIMEOUT = 21;
+
public static final int REPORT_HARD_KEYBOARD_STATUS_CHANGE = 22;
public static final int BOOT_TIMEOUT = 23;
public static final int WAITING_FOR_DRAWN_TIMEOUT = 24;
@@ -5120,47 +5053,12 @@ public class WindowManagerService extends IWindowManager.Stub
break;
}
- case DRAG_START_TIMEOUT: {
- IBinder win = (IBinder)msg.obj;
- if (DEBUG_DRAG) {
- Slog.w(TAG_WM, "Timeout starting drag by win " + win);
- }
- synchronized (mWindowMap) {
- // !!! TODO: ANR the app that has failed to start the drag in time
- if (mDragState != null) {
- mDragState.unregister();
- mDragState.reset();
- mDragState = null;
- }
- }
- break;
- }
-
- case DRAG_END_TIMEOUT: {
- IBinder win = (IBinder)msg.obj;
- if (DEBUG_DRAG) {
- Slog.w(TAG_WM, "Timeout ending drag to win " + win);
- }
- synchronized (mWindowMap) {
- // !!! TODO: ANR the drag-receiving app
- if (mDragState != null) {
- mDragState.mDragResult = false;
- mDragState.endDragLw();
- }
- }
- break;
- }
-
+ case DRAG_START_TIMEOUT:
+ case DRAG_END_TIMEOUT:
case TEAR_DOWN_DRAG_AND_DROP_INPUT: {
- if (DEBUG_DRAG) Slog.d(TAG_WM, "Drag ending; tearing down input channel");
- DragState.InputInterceptor interceptor = (DragState.InputInterceptor) msg.obj;
- if (interceptor != null) {
- synchronized (mWindowMap) {
- interceptor.tearDown();
- }
- }
+ mDragDropController.handleMessage(WindowManagerService.this, msg);
+ break;
}
- break;
case REPORT_HARD_KEYBOARD_STATUS_CHANGE: {
notifyHardKeyboardStatusChange();