Merge changes I3afc0622,I25723107
* changes: Make DragDropController#mDragState private Sort out various cleanup methods of DragState
This commit is contained in:
committed by
Android (Google) Code Review
commit
5647b92d23
@@ -35,6 +35,7 @@ import android.view.Surface;
|
||||
import android.view.SurfaceControl;
|
||||
import android.view.SurfaceSession;
|
||||
import android.view.View;
|
||||
import com.android.server.input.InputWindowHandle;
|
||||
|
||||
/**
|
||||
* Managing drag and drop operations initiated by View#startDragAndDrop.
|
||||
@@ -49,7 +50,12 @@ class DragDropController {
|
||||
static final int MSG_TEAR_DOWN_DRAG_AND_DROP_INPUT = 2;
|
||||
static final int MSG_ANIMATION_END = 3;
|
||||
|
||||
DragState mDragState;
|
||||
/**
|
||||
* Drag state per operation.
|
||||
* The variable is cleared by {@code #onDragStateClosedLocked} which is invoked by DragState
|
||||
* itself, thus the variable can be null after calling DragState's methods.
|
||||
*/
|
||||
private DragState mDragState;
|
||||
|
||||
private WindowManagerService mService;
|
||||
private final Handler mHandler;
|
||||
@@ -58,11 +64,19 @@ class DragDropController {
|
||||
return mDragState != null;
|
||||
}
|
||||
|
||||
InputWindowHandle getInputWindowHandleLocked() {
|
||||
return mDragState.getInputWindowHandle();
|
||||
}
|
||||
|
||||
DragDropController(WindowManagerService service, Looper looper) {
|
||||
mService = service;
|
||||
mHandler = new DragHandler(service, looper);
|
||||
}
|
||||
|
||||
void sendDragStartedIfNeededLocked(WindowState window) {
|
||||
mDragState.sendDragStartedIfNeededLocked(window);
|
||||
}
|
||||
|
||||
IBinder prepareDrag(SurfaceSession session, int callerPid,
|
||||
int callerUid, IWindow window, int flags, int width, int height, Surface outSurface) {
|
||||
if (DEBUG_DRAG) {
|
||||
@@ -158,9 +172,7 @@ class DragDropController {
|
||||
if (!mService.mInputManager.transferTouchFocus(callingWin.mInputChannel,
|
||||
mDragState.getInputChannel())) {
|
||||
Slog.e(TAG_WM, "Unable to transfer touch focus");
|
||||
mDragState.unregister();
|
||||
mDragState.reset();
|
||||
mDragState = null;
|
||||
mDragState.closeLocked();
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -254,6 +266,30 @@ class DragDropController {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Handles motion events.
|
||||
* @param keepHandling Whether if the drag operation is continuing or this is the last motion
|
||||
* event.
|
||||
* @param newX X coordinate value in dp in the screen coordinate
|
||||
* @param newY Y coordinate value in dp in the screen coordinate
|
||||
*/
|
||||
void handleMotionEvent(boolean keepHandling, float newX, float newY) {
|
||||
synchronized (mService.mWindowMap) {
|
||||
if (!dragDropActiveLocked()) {
|
||||
// The drag has ended but the clean-up message has not been processed by
|
||||
// window manager. Drop events that occur after this until window manager
|
||||
// has a chance to clean-up the input handle.
|
||||
return;
|
||||
}
|
||||
|
||||
if (keepHandling) {
|
||||
mDragState.notifyMoveLocked(newX, newY);
|
||||
} else {
|
||||
mDragState.notifyDropLocked(newX, newY);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void dragRecipientEntered(IWindow window) {
|
||||
if (DEBUG_DRAG) {
|
||||
Slog.d(TAG_WM, "Drag into new candidate view @ " + window.asBinder());
|
||||
@@ -282,6 +318,17 @@ class DragDropController {
|
||||
mHandler.sendMessageDelayed(msg, DRAG_TIMEOUT_MS);
|
||||
}
|
||||
|
||||
/**
|
||||
* Notifies the current drag state is closed.
|
||||
*/
|
||||
void onDragStateClosedLocked(DragState dragState) {
|
||||
if (mDragState != dragState) {
|
||||
Slog.wtf(TAG_WM, "Unknown drag state is closed");
|
||||
return;
|
||||
}
|
||||
mDragState = null;
|
||||
}
|
||||
|
||||
private class DragHandler extends Handler {
|
||||
/**
|
||||
* Lock for window manager.
|
||||
@@ -304,9 +351,7 @@ class DragDropController {
|
||||
synchronized (mService.mWindowMap) {
|
||||
// !!! TODO: ANR the app that has failed to start the drag in time
|
||||
if (mDragState != null) {
|
||||
mDragState.unregister();
|
||||
mDragState.reset();
|
||||
mDragState = null;
|
||||
mDragState.closeLocked();
|
||||
}
|
||||
}
|
||||
break;
|
||||
@@ -346,7 +391,7 @@ class DragDropController {
|
||||
"plyaing animation");
|
||||
return;
|
||||
}
|
||||
mDragState.onAnimationEndLocked();
|
||||
mDragState.closeLocked();
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
@@ -37,7 +37,6 @@ import android.view.MotionEvent;
|
||||
* Input receiver for drag and drop
|
||||
*/
|
||||
class DragInputEventReceiver extends InputEventReceiver {
|
||||
private final WindowManagerService mService;
|
||||
private final DragDropController mDragDropController;
|
||||
|
||||
// Set, if stylus button was down at the start of the drag.
|
||||
@@ -48,100 +47,63 @@ class DragInputEventReceiver extends InputEventReceiver {
|
||||
// are still being dispatched.
|
||||
private boolean mMuteInput = false;
|
||||
|
||||
public DragInputEventReceiver(InputChannel inputChannel, Looper looper,
|
||||
DragDropController controller, WindowManagerService service) {
|
||||
DragInputEventReceiver(InputChannel inputChannel, Looper looper,
|
||||
DragDropController controller) {
|
||||
super(inputChannel, looper);
|
||||
mDragDropController = controller;
|
||||
mService = service;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onInputEvent(InputEvent event, int displayId) {
|
||||
boolean handled = false;
|
||||
try {
|
||||
synchronized (mService.mWindowMap) {
|
||||
if (!mDragDropController.dragDropActiveLocked()) {
|
||||
// The drag has ended but the clean-up message has not been processed by
|
||||
// window manager. Drop events that occur after this until window manager
|
||||
// has a chance to clean-up the input handle.
|
||||
handled = true;
|
||||
return;
|
||||
}
|
||||
if (!(event instanceof MotionEvent)
|
||||
|| (event.getSource() & SOURCE_CLASS_POINTER) == 0
|
||||
|| mMuteInput) {
|
||||
return;
|
||||
}
|
||||
final MotionEvent motionEvent = (MotionEvent) event;
|
||||
boolean endDrag = false;
|
||||
final float newX = motionEvent.getRawX();
|
||||
final float newY = motionEvent.getRawY();
|
||||
final boolean isStylusButtonDown =
|
||||
(motionEvent.getButtonState() & BUTTON_STYLUS_PRIMARY) != 0;
|
||||
|
||||
if (mIsStartEvent) {
|
||||
if (isStylusButtonDown) {
|
||||
// First event and the button was down, check for the button being
|
||||
// lifted in the future, if that happens we'll drop the item.
|
||||
mStylusButtonDownAtStart = true;
|
||||
}
|
||||
mIsStartEvent = false;
|
||||
}
|
||||
|
||||
switch (motionEvent.getAction()) {
|
||||
case ACTION_DOWN: {
|
||||
if (DEBUG_DRAG) Slog.w(TAG_WM, "Unexpected ACTION_DOWN in drag layer");
|
||||
}
|
||||
break;
|
||||
|
||||
case ACTION_MOVE: {
|
||||
if (mStylusButtonDownAtStart && !isStylusButtonDown) {
|
||||
if (DEBUG_DRAG) {
|
||||
Slog.d(TAG_WM, "Button no longer pressed; dropping at "
|
||||
+ newX + "," + newY);
|
||||
}
|
||||
mMuteInput = true;
|
||||
endDrag = mDragDropController.mDragState
|
||||
.notifyDropLocked(newX, newY);
|
||||
} else {
|
||||
// move the surface and tell the involved window(s) where we are
|
||||
mDragDropController.mDragState.notifyMoveLocked(newX, newY);
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
case ACTION_UP: {
|
||||
if (DEBUG_DRAG) {
|
||||
Slog.d(TAG_WM, "Got UP on move channel; dropping at "
|
||||
+ newX + "," + newY);
|
||||
}
|
||||
mMuteInput = true;
|
||||
endDrag = mDragDropController.mDragState
|
||||
.notifyDropLocked(newX, newY);
|
||||
}
|
||||
break;
|
||||
|
||||
case ACTION_CANCEL: {
|
||||
if (DEBUG_DRAG) Slog.d(TAG_WM, "Drag cancelled!");
|
||||
mMuteInput = true;
|
||||
endDrag = true;
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
if (endDrag) {
|
||||
if (DEBUG_DRAG)
|
||||
Slog.d(TAG_WM, "Drag ended; tearing down state");
|
||||
// tell all the windows that the drag has ended
|
||||
// endDragLocked will post back to looper to dispose the receiver
|
||||
// since we still need the receiver for the last finishInputEvent.
|
||||
mDragDropController.mDragState.endDragLocked();
|
||||
mStylusButtonDownAtStart = false;
|
||||
mIsStartEvent = true;
|
||||
}
|
||||
|
||||
handled = true;
|
||||
if (!(event instanceof MotionEvent)
|
||||
|| (event.getSource() & SOURCE_CLASS_POINTER) == 0
|
||||
|| mMuteInput) {
|
||||
return;
|
||||
}
|
||||
final MotionEvent motionEvent = (MotionEvent) event;
|
||||
final float newX = motionEvent.getRawX();
|
||||
final float newY = motionEvent.getRawY();
|
||||
final boolean isStylusButtonDown =
|
||||
(motionEvent.getButtonState() & BUTTON_STYLUS_PRIMARY) != 0;
|
||||
|
||||
if (mIsStartEvent) {
|
||||
// First event and the button was down, check for the button being
|
||||
// lifted in the future, if that happens we'll drop the item.
|
||||
mStylusButtonDownAtStart = isStylusButtonDown;
|
||||
mIsStartEvent = false;
|
||||
}
|
||||
|
||||
switch (motionEvent.getAction()) {
|
||||
case ACTION_DOWN:
|
||||
if (DEBUG_DRAG) Slog.w(TAG_WM, "Unexpected ACTION_DOWN in drag layer");
|
||||
return;
|
||||
case ACTION_MOVE:
|
||||
if (mStylusButtonDownAtStart && !isStylusButtonDown) {
|
||||
if (DEBUG_DRAG) {
|
||||
Slog.d(TAG_WM, "Button no longer pressed; dropping at " + newX + ","
|
||||
+ newY);
|
||||
}
|
||||
mMuteInput = true;
|
||||
}
|
||||
break;
|
||||
case ACTION_UP:
|
||||
if (DEBUG_DRAG) {
|
||||
Slog.d(TAG_WM, "Got UP on move channel; dropping at " + newX + "," + newY);
|
||||
}
|
||||
mMuteInput = true;
|
||||
break;
|
||||
case ACTION_CANCEL:
|
||||
if (DEBUG_DRAG) Slog.d(TAG_WM, "Drag cancelled!");
|
||||
mMuteInput = true;
|
||||
break;
|
||||
default:
|
||||
return;
|
||||
}
|
||||
|
||||
mDragDropController.handleMotionEvent(!mMuteInput /* keepHandling */, newX, newY);
|
||||
handled = true;
|
||||
} catch (Exception e) {
|
||||
Slog.e(TAG_WM, "Exception caught by drag handleMotion", e);
|
||||
} finally {
|
||||
|
||||
@@ -105,6 +105,11 @@ class DragState {
|
||||
WindowState mTargetWindow;
|
||||
ArrayList<WindowState> mNotifiedWindows;
|
||||
boolean mDragInProgress;
|
||||
/**
|
||||
* Whether if animation is completed. Needs to be volatile to update from the animation thread
|
||||
* without having a WM lock.
|
||||
*/
|
||||
volatile boolean mAnimationCompleted = false;
|
||||
DisplayContent mDisplayContent;
|
||||
|
||||
@Nullable private ValueAnimator mAnimator;
|
||||
@@ -122,21 +127,79 @@ class DragState {
|
||||
mNotifiedWindows = new ArrayList<WindowState>();
|
||||
}
|
||||
|
||||
void reset() {
|
||||
if (mAnimator != null) {
|
||||
/**
|
||||
* After calling this, DragDropController#onDragStateClosedLocked is invoked, which causes
|
||||
* DragDropController#mDragState becomes null.
|
||||
*/
|
||||
void closeLocked() {
|
||||
// Unregister the input interceptor.
|
||||
if (mInputInterceptor != null) {
|
||||
if (DEBUG_DRAG)
|
||||
Slog.d(TAG_WM, "unregistering drag input channel");
|
||||
|
||||
// Input channel should be disposed on the thread where the input is being handled.
|
||||
mDragDropController.sendHandlerMessage(
|
||||
MSG_TEAR_DOWN_DRAG_AND_DROP_INPUT, mInputInterceptor);
|
||||
mInputInterceptor = null;
|
||||
mService.mInputMonitor.updateInputWindowsLw(true /*force*/);
|
||||
}
|
||||
|
||||
// Send drag end broadcast if drag start has been sent.
|
||||
if (mDragInProgress) {
|
||||
final int myPid = Process.myPid();
|
||||
|
||||
if (DEBUG_DRAG) {
|
||||
Slog.d(TAG_WM, "broadcasting DRAG_ENDED");
|
||||
}
|
||||
for (WindowState ws : mNotifiedWindows) {
|
||||
float x = 0;
|
||||
float y = 0;
|
||||
if (!mDragResult && (ws.mSession.mPid == mPid)) {
|
||||
// Report unconsumed drop location back to the app that started the drag.
|
||||
x = mCurrentX;
|
||||
y = mCurrentY;
|
||||
}
|
||||
DragEvent evt = DragEvent.obtain(DragEvent.ACTION_DRAG_ENDED,
|
||||
x, y, null, null, null, null, mDragResult);
|
||||
try {
|
||||
ws.mClient.dispatchDragEvent(evt);
|
||||
} catch (RemoteException e) {
|
||||
Slog.w(TAG_WM, "Unable to drag-end window " + ws);
|
||||
}
|
||||
// if the current window is in the same process,
|
||||
// the dispatch has already recycled the event
|
||||
if (myPid != ws.mSession.mPid) {
|
||||
evt.recycle();
|
||||
}
|
||||
}
|
||||
mNotifiedWindows.clear();
|
||||
mDragInProgress = false;
|
||||
}
|
||||
|
||||
// Take the cursor back if it has been changed.
|
||||
if (isFromSource(InputDevice.SOURCE_MOUSE)) {
|
||||
mService.restorePointerIconLocked(mDisplayContent, mCurrentX, mCurrentY);
|
||||
mTouchSource = 0;
|
||||
}
|
||||
|
||||
// Clear the internal variables.
|
||||
if (mSurfaceControl != null) {
|
||||
mSurfaceControl.destroy();
|
||||
mSurfaceControl = null;
|
||||
}
|
||||
if (mAnimator != null && !mAnimationCompleted) {
|
||||
Slog.wtf(TAG_WM,
|
||||
"Unexpectedly destroying mSurfaceControl while animation is running");
|
||||
}
|
||||
if (mSurfaceControl != null) {
|
||||
mSurfaceControl.destroy();
|
||||
}
|
||||
mSurfaceControl = null;
|
||||
mFlags = 0;
|
||||
mLocalWin = null;
|
||||
mToken = null;
|
||||
mData = null;
|
||||
mThumbOffsetX = mThumbOffsetY = 0;
|
||||
mNotifiedWindows = null;
|
||||
|
||||
// Notifies the controller that the drag state is closed.
|
||||
mDragDropController.onDragStateClosedLocked(this);
|
||||
}
|
||||
|
||||
class InputInterceptor {
|
||||
@@ -151,7 +214,7 @@ class DragState {
|
||||
mClientChannel = channels[1];
|
||||
mService.mInputManager.registerInputChannel(mServerChannel, null);
|
||||
mInputEventReceiver = new DragInputEventReceiver(mClientChannel,
|
||||
mService.mH.getLooper(), mDragDropController, mService);
|
||||
mService.mH.getLooper(), mDragDropController);
|
||||
|
||||
mDragApplicationHandle = new InputApplicationHandle(null);
|
||||
mDragApplicationHandle.name = "drag";
|
||||
@@ -235,19 +298,6 @@ class DragState {
|
||||
}
|
||||
}
|
||||
|
||||
void unregister() {
|
||||
if (DEBUG_DRAG) Slog.d(TAG_WM, "unregistering drag input channel");
|
||||
if (mInputInterceptor == null) {
|
||||
Slog.e(TAG_WM, "Unregister of nonexistent drag input channel");
|
||||
} else {
|
||||
// Input channel should be disposed on the thread where the input is being handled.
|
||||
mDragDropController.sendHandlerMessage(
|
||||
MSG_TEAR_DOWN_DRAG_AND_DROP_INPUT, mInputInterceptor);
|
||||
mInputInterceptor = null;
|
||||
mService.mInputMonitor.updateInputWindowsLw(true /*force*/);
|
||||
}
|
||||
}
|
||||
|
||||
int getDragLayerLocked() {
|
||||
return mService.mPolicy.getWindowLayerFromTypeLw(WindowManager.LayoutParams.TYPE_DRAG)
|
||||
* WindowManagerService.TYPE_LAYER_MULTIPLIER
|
||||
@@ -366,46 +416,15 @@ class DragState {
|
||||
return false;
|
||||
}
|
||||
|
||||
private void broadcastDragEndedLocked() {
|
||||
final int myPid = Process.myPid();
|
||||
|
||||
if (DEBUG_DRAG) {
|
||||
Slog.d(TAG_WM, "broadcasting DRAG_ENDED");
|
||||
}
|
||||
for (WindowState ws : mNotifiedWindows) {
|
||||
float x = 0;
|
||||
float y = 0;
|
||||
if (!mDragResult && (ws.mSession.mPid == mPid)) {
|
||||
// Report unconsumed drop location back to the app that started the drag.
|
||||
x = mCurrentX;
|
||||
y = mCurrentY;
|
||||
}
|
||||
DragEvent evt = DragEvent.obtain(DragEvent.ACTION_DRAG_ENDED,
|
||||
x, y, null, null, null, null, mDragResult);
|
||||
try {
|
||||
ws.mClient.dispatchDragEvent(evt);
|
||||
} catch (RemoteException e) {
|
||||
Slog.w(TAG_WM, "Unable to drag-end window " + ws);
|
||||
}
|
||||
// if the current window is in the same process,
|
||||
// the dispatch has already recycled the event
|
||||
if (myPid != ws.mSession.mPid) {
|
||||
evt.recycle();
|
||||
}
|
||||
}
|
||||
mNotifiedWindows.clear();
|
||||
mDragInProgress = false;
|
||||
}
|
||||
|
||||
void endDragLocked() {
|
||||
if (mAnimator != null) {
|
||||
return;
|
||||
}
|
||||
if (!mDragResult) {
|
||||
mAnimator = createReturnAnimationLocked();
|
||||
return; // Will call cleanUpDragLw when the animation is done.
|
||||
return; // Will call closeLocked() when the animation is done.
|
||||
}
|
||||
cleanUpDragLocked();
|
||||
closeLocked();
|
||||
}
|
||||
|
||||
void cancelDragLocked() {
|
||||
@@ -414,33 +433,15 @@ class DragState {
|
||||
}
|
||||
if (!mDragInProgress) {
|
||||
// This can happen if an app invokes Session#cancelDragAndDrop before
|
||||
// Session#performDrag. Reset the drag state:
|
||||
// 1. without sending the end broadcast because the start broadcast has not been sent,
|
||||
// and
|
||||
// 2. without playing the cancel animation because H.DRAG_START_TIMEOUT may be sent to
|
||||
// WindowManagerService, which will cause DragState#reset() while playing the
|
||||
// cancel animation.
|
||||
reset();
|
||||
mDragDropController.mDragState = null;
|
||||
// Session#performDrag. Reset the drag state without playing the cancel animation
|
||||
// because H.DRAG_START_TIMEOUT may be sent to WindowManagerService, which will cause
|
||||
// DragState#reset() while playing the cancel animation.
|
||||
closeLocked();
|
||||
return;
|
||||
}
|
||||
mAnimator = createCancelAnimationLocked();
|
||||
}
|
||||
|
||||
private void cleanUpDragLocked() {
|
||||
broadcastDragEndedLocked();
|
||||
if (isFromSource(InputDevice.SOURCE_MOUSE)) {
|
||||
mService.restorePointerIconLocked(mDisplayContent, mCurrentX, mCurrentY);
|
||||
}
|
||||
|
||||
// stop intercepting input
|
||||
unregister();
|
||||
|
||||
// free our resources and drop all the object references
|
||||
reset();
|
||||
mDragDropController.mDragState = null;
|
||||
}
|
||||
|
||||
void notifyMoveLocked(float x, float y) {
|
||||
if (mAnimator != null) {
|
||||
return;
|
||||
@@ -507,34 +508,33 @@ class DragState {
|
||||
mTargetWindow = touchedWin;
|
||||
}
|
||||
|
||||
// Find the drop target and tell it about the data. Returns 'true' if we can immediately
|
||||
// dispatch the global drag-ended message, 'false' if we need to wait for a
|
||||
// result from the recipient.
|
||||
boolean notifyDropLocked(float x, float y) {
|
||||
/**
|
||||
* Finds the drop target and tells it about the data. If the drop event is not sent to the
|
||||
* target, invokes {@code endDragLocked} immediately.
|
||||
*/
|
||||
void notifyDropLocked(float x, float y) {
|
||||
if (mAnimator != null) {
|
||||
return false;
|
||||
return;
|
||||
}
|
||||
mCurrentX = x;
|
||||
mCurrentY = y;
|
||||
|
||||
WindowState touchedWin = mDisplayContent.getTouchableWinAtPointLocked(x, y);
|
||||
final WindowState touchedWin = mDisplayContent.getTouchableWinAtPointLocked(x, y);
|
||||
|
||||
if (!isWindowNotified(touchedWin)) {
|
||||
// "drop" outside a valid window -- no recipient to apply a
|
||||
// timeout to, and we can send the drag-ended message immediately.
|
||||
mDragResult = false;
|
||||
return true;
|
||||
endDragLocked();
|
||||
return;
|
||||
}
|
||||
|
||||
if (DEBUG_DRAG) {
|
||||
Slog.d(TAG_WM, "sending DROP to " + touchedWin);
|
||||
}
|
||||
if (DEBUG_DRAG) Slog.d(TAG_WM, "sending DROP to " + touchedWin);
|
||||
|
||||
final int targetUserId = UserHandle.getUserId(touchedWin.getOwningUid());
|
||||
|
||||
DragAndDropPermissionsHandler dragAndDropPermissions = null;
|
||||
if ((mFlags & View.DRAG_FLAG_GLOBAL) != 0 &&
|
||||
(mFlags & DRAG_FLAGS_URI_ACCESS) != 0) {
|
||||
final DragAndDropPermissionsHandler dragAndDropPermissions;
|
||||
if ((mFlags & View.DRAG_FLAG_GLOBAL) != 0 && (mFlags & DRAG_FLAGS_URI_ACCESS) != 0) {
|
||||
dragAndDropPermissions = new DragAndDropPermissionsHandler(
|
||||
mData,
|
||||
mUid,
|
||||
@@ -542,13 +542,15 @@ class DragState {
|
||||
mFlags & DRAG_FLAGS_URI_PERMISSIONS,
|
||||
mSourceUserId,
|
||||
targetUserId);
|
||||
} else {
|
||||
dragAndDropPermissions = null;
|
||||
}
|
||||
if (mSourceUserId != targetUserId){
|
||||
mData.fixUris(mSourceUserId);
|
||||
}
|
||||
final int myPid = Process.myPid();
|
||||
final IBinder token = touchedWin.mClient.asBinder();
|
||||
DragEvent evt = obtainDragEvent(touchedWin, DragEvent.ACTION_DROP, x, y,
|
||||
final DragEvent evt = obtainDragEvent(touchedWin, DragEvent.ACTION_DROP, x, y,
|
||||
null, null, mData, dragAndDropPermissions, false);
|
||||
try {
|
||||
touchedWin.mClient.dispatchDragEvent(evt);
|
||||
@@ -557,23 +559,13 @@ class DragState {
|
||||
mDragDropController.sendTimeoutMessage(MSG_DRAG_END_TIMEOUT, token);
|
||||
} catch (RemoteException e) {
|
||||
Slog.w(TAG_WM, "can't send drop notification to win " + touchedWin);
|
||||
return true;
|
||||
endDragLocked();
|
||||
} finally {
|
||||
if (myPid != touchedWin.mSession.mPid) {
|
||||
evt.recycle();
|
||||
}
|
||||
}
|
||||
mToken = token;
|
||||
return false;
|
||||
}
|
||||
|
||||
void onAnimationEndLocked() {
|
||||
if (mAnimator == null) {
|
||||
Slog.wtf(TAG_WM, "Unexpected null mAnimator");
|
||||
return;
|
||||
}
|
||||
mAnimator = null;
|
||||
cleanUpDragLocked();
|
||||
}
|
||||
|
||||
private static DragEvent obtainDragEvent(WindowState win, int action,
|
||||
@@ -677,6 +669,7 @@ class DragState {
|
||||
|
||||
@Override
|
||||
public void onAnimationEnd(Animator animator) {
|
||||
mAnimationCompleted = true;
|
||||
// Updating mDragState requires the WM lock so continues it on the out of
|
||||
// AnimationThread.
|
||||
mDragDropController.sendHandlerMessage(MSG_ANIMATION_END, null);
|
||||
|
||||
@@ -381,7 +381,7 @@ final class InputMonitor implements InputManagerService.WindowManagerCallbacks {
|
||||
Log.d(TAG_WM, "Inserting drag window");
|
||||
}
|
||||
final InputWindowHandle dragWindowHandle =
|
||||
mService.mDragDropController.mDragState.getInputWindowHandle();
|
||||
mService.mDragDropController.getInputWindowHandleLocked();
|
||||
if (dragWindowHandle != null) {
|
||||
addInputWindowHandle(dragWindowHandle);
|
||||
} else {
|
||||
@@ -698,7 +698,7 @@ final class InputMonitor implements InputManagerService.WindowManagerCallbacks {
|
||||
// If there's a drag in progress and 'child' is a potential drop target,
|
||||
// make sure it's been told about the drag
|
||||
if (inDrag && isVisible && w.getDisplayContent().isDefaultDisplay) {
|
||||
mService.mDragDropController.mDragState.sendDragStartedIfNeededLocked(w);
|
||||
mService.mDragDropController.sendDragStartedIfNeededLocked(w);
|
||||
}
|
||||
|
||||
addInputWindowHandle(
|
||||
|
||||
@@ -7087,7 +7087,7 @@ public class WindowManagerService extends IWindowManager.Stub
|
||||
}
|
||||
|
||||
synchronized (mWindowMap) {
|
||||
if (mDragDropController.mDragState != null) {
|
||||
if (mDragDropController.dragDropActiveLocked()) {
|
||||
// Drag cursor overrides the app cursor.
|
||||
return;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user