Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 663e9a77 authored by Daichi Hirono's avatar Daichi Hirono
Browse files

Close mDragState immediately when error

Previously if we encounter an error at performDrag, it sometimes just
returns and lets MSG_DRAG_START_TIMEOUT clean up the drag state.

It means users cannot start another drag and drop operation before
timeout.

The CL fix the error handling so that it immediately cleans the drag
state on errors.

Bug: 69141835
Test: android.server.wm.CrossAppDragAndDropTests, manually check the
      drag and drop behavior on test app.
Change-Id: Ibc5784a842eed77e2fa082d8f38d69acc9954e3e
parent bb28efb6
Loading
Loading
Loading
Loading
+65 −61
Original line number Original line Diff line number Diff line
@@ -150,23 +150,24 @@ class DragDropController {
            Slog.d(TAG_WM, "perform drag: win=" + window + " data=" + data);
            Slog.d(TAG_WM, "perform drag: win=" + window + " data=" + data);
        }
        }


        if (!mCallback.get().prePerformDrag(window, dragToken, touchSource, touchX, touchY, thumbCenterX,
        final boolean callbackResult = mCallback.get().prePerformDrag(window, dragToken,
                thumbCenterY, data)) {
                touchSource, touchX, touchY, thumbCenterX, thumbCenterY, data);
            return false;
        }
        try {
        try {
            synchronized (mService.mWindowMap) {
            synchronized (mService.mWindowMap) {
                if (mDragState == null) {
                mHandler.removeMessages(MSG_DRAG_START_TIMEOUT, window.asBinder());
                    Slog.w(TAG_WM, "No drag prepared");
                try {
                    throw new IllegalStateException("performDrag() without prepareDrag()");
                    if (!callbackResult) {
                        return false;
                    }
                    }


                if (dragToken != mDragState.mToken) {
                    Preconditions.checkState(
                    Slog.w(TAG_WM, "Performing mismatched drag");
                            mDragState != null, "performDrag() without prepareDrag()");
                    throw new IllegalStateException("performDrag() does not match prepareDrag()");
                    Preconditions.checkState(
                }
                            mDragState.mToken == dragToken,
                            "performDrag() does not match prepareDrag()");


                final WindowState callingWin = mService.windowForClientLocked(null, window, false);
                    final WindowState callingWin = mService.windowForClientLocked(
                            null, window, false);
                    if (callingWin == null) {
                    if (callingWin == null) {
                        Slog.w(TAG_WM, "Bad requesting window " + window);
                        Slog.w(TAG_WM, "Bad requesting window " + window);
                        return false;  // !!! TODO: throw here?
                        return false;  // !!! TODO: throw here?
@@ -176,8 +177,6 @@ class DragDropController {
                    // the drag initiation (e.g. an alarm window popped up just as the application
                    // the drag initiation (e.g. an alarm window popped up just as the application
                    // called performDrag()
                    // called performDrag()


                mHandler.removeMessages(MSG_DRAG_START_TIMEOUT, window.asBinder());

                    // !!! TODO: extract the current touch (x, y) in screen coordinates.  That
                    // !!! TODO: extract the current touch (x, y) in screen coordinates.  That
                    // will let us eliminate the (touchX,touchY) parameters from the API.
                    // will let us eliminate the (touchX,touchY) parameters from the API.


@@ -186,14 +185,15 @@ class DragDropController {


                    final DisplayContent displayContent = callingWin.getDisplayContent();
                    final DisplayContent displayContent = callingWin.getDisplayContent();
                    if (displayContent == null) {
                    if (displayContent == null) {
                        Slog.w(TAG_WM, "display content is null");
                        return false;
                        return false;
                    }
                    }
                Display display = displayContent.getDisplay();

                    final Display display = displayContent.getDisplay();
                    mDragState.register(display);
                    mDragState.register(display);
                    if (!mService.mInputManager.transferTouchFocus(callingWin.mInputChannel,
                    if (!mService.mInputManager.transferTouchFocus(callingWin.mInputChannel,
                            mDragState.getInputChannel())) {
                            mDragState.getInputChannel())) {
                        Slog.e(TAG_WM, "Unable to transfer touch focus");
                        Slog.e(TAG_WM, "Unable to transfer touch focus");
                    mDragState.closeLocked();
                        return false;
                        return false;
                    }
                    }


@@ -201,7 +201,6 @@ class DragDropController {
                    mDragState.mData = data;
                    mDragState.mData = data;
                    mDragState.broadcastDragStartedLocked(touchX, touchY);
                    mDragState.broadcastDragStartedLocked(touchX, touchY);
                    mDragState.overridePointerIconLocked(touchSource);
                    mDragState.overridePointerIconLocked(touchSource);

                    // remember the thumb offsets for later
                    // remember the thumb offsets for later
                    mDragState.mThumbOffsetX = thumbCenterX;
                    mDragState.mThumbOffsetX = thumbCenterX;
                    mDragState.mThumbOffsetY = thumbCenterY;
                    mDragState.mThumbOffsetY = thumbCenterY;
@@ -224,6 +223,11 @@ class DragDropController {
                    }
                    }


                    mDragState.notifyLocationLocked(touchX, touchY);
                    mDragState.notifyLocationLocked(touchX, touchY);
                } finally {
                    if (mDragState != null && !mDragState.isInProgress()) {
                        mDragState.closeLocked();
                    }
                }
            }
            }
            return true;    // success!
            return true;    // success!
        } finally {
        } finally {
+8 −0
Original line number Original line Diff line number Diff line
@@ -568,6 +568,14 @@ class DragState {
        mToken = token;
        mToken = token;
    }
    }


    /**
     * Returns true if it has sent DRAG_STARTED broadcast out but has not been sent DRAG_END
     * broadcast.
     */
    boolean isInProgress() {
        return mDragInProgress;
    }

    private static DragEvent obtainDragEvent(WindowState win, int action,
    private static DragEvent obtainDragEvent(WindowState win, int action,
            float x, float y, Object localState,
            float x, float y, Object localState,
            ClipDescription description, ClipData data,
            ClipDescription description, ClipData data,