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

Commit 40089ca9 authored by Vladislav Kaznacheev's avatar Vladislav Kaznacheev Committed by Android (Google) Code Review
Browse files

Merge "Move more drag-related code to DragState" into nyc-dev

parents 7fbec419 5d6bdebf
Loading
Loading
Loading
Loading
+38 −0
Original line number Diff line number Diff line
@@ -19,6 +19,9 @@ package com.android.server.wm;
import static android.app.ActivityManager.StackId.DOCKED_STACK_ID;
import static android.app.ActivityManager.StackId.HOME_STACK_ID;
import static android.app.ActivityManager.StackId.PINNED_STACK_ID;
import static android.view.WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE;
import static android.view.WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE;
import static android.view.WindowManager.LayoutParams.FLAG_NOT_TOUCH_MODAL;
import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_VISIBILITY;
import static com.android.server.wm.WindowManagerDebugConfig.TAG_WM;
import static com.android.server.wm.WindowState.RESIZE_HANDLE_WIDTH_IN_DP;
@@ -607,4 +610,39 @@ class DisplayContent {
        final TaskStack stack = mService.mStackIdToStack.get(DOCKED_STACK_ID);
        return (stack != null && stack.isVisibleLocked()) ? stack : null;
    }

    /**
     * Find the visible, touch-deliverable window under the given point
     */
    WindowState getTouchableWinAtPointLocked(float xf, float yf) {
        WindowState touchedWin = null;
        final int x = (int) xf;
        final int y = (int) yf;

        for (int i = mWindows.size() - 1; i >= 0; i--) {
            WindowState window = mWindows.get(i);
            final int flags = window.mAttrs.flags;
            if (!window.isVisibleLw()) {
                continue;
            }
            if ((flags & FLAG_NOT_TOUCHABLE) != 0) {
                continue;
            }

            window.getVisibleBounds(mTmpRect);
            if (!mTmpRect.contains(x, y)) {
                continue;
            }

            window.getTouchableRegion(mTmpRegion);

            final int touchFlags = flags & (FLAG_NOT_FOCUSABLE | FLAG_NOT_TOUCH_MODAL);
            if (mTmpRegion.contains(x, y) || touchFlags == 0) {
                touchedWin = window;
                break;
            }
        }

        return touchedWin;
    }
}
+37 −21
Original line number Diff line number Diff line
@@ -27,8 +27,6 @@ import android.content.ClipDescription;
import android.content.Context;
import android.graphics.Matrix;
import android.graphics.Point;
import android.graphics.Rect;
import android.graphics.Region;
import android.hardware.input.InputManager;
import android.os.IBinder;
import android.os.Message;
@@ -71,6 +69,13 @@ import java.util.ArrayList;
class DragState {
    private static final long ANIMATION_DURATION_MS = 500;

    private static final int DRAG_FLAGS_URI_ACCESS = View.DRAG_FLAG_GLOBAL_URI_READ |
            View.DRAG_FLAG_GLOBAL_URI_WRITE;

    private static final int DRAG_FLAGS_URI_PERMISSIONS = DRAG_FLAGS_URI_ACCESS |
            View.DRAG_FLAG_GLOBAL_PERSISTABLE_URI_PERMISSION |
            View.DRAG_FLAG_GLOBAL_PREFIX_URI_PERMISSION;

    final WindowManagerService mService;
    IBinder mToken;
    SurfaceControl mSurfaceControl;
@@ -95,10 +100,7 @@ class DragState {
    WindowState mTargetWindow;
    ArrayList<WindowState> mNotifiedWindows;
    boolean mDragInProgress;
    Display mDisplay;

    private final Region mTmpRegion = new Region();
    private final Rect mTmpRect = new Rect();
    DisplayContent mDisplayContent;

    private Animation mAnimation;
    final Transformation mTransformation = new Transformation();
@@ -131,11 +133,12 @@ class DragState {
     * @param display The Display that the window being dragged is on.
     */
    void register(Display display) {
        mDisplay = display;
        if (DEBUG_DRAG) Slog.d(TAG_WM, "registering drag input channel");
        if (mClientChannel != null) {
            Slog.e(TAG_WM, "Duplicate register of drag input channel");
        } else {
            mDisplayContent = mService.getDisplayContentLocked(display.getDisplayId());

            InputChannel[] channels = InputChannel.openInputChannelPair("drag");
            mServerChannel = channels[0];
            mClientChannel = channels[1];
@@ -149,7 +152,7 @@ class DragState {
                    WindowManagerService.DEFAULT_INPUT_DISPATCHING_TIMEOUT_NANOS;

            mDragWindowHandle = new InputWindowHandle(mDragApplicationHandle, null,
                    mDisplay.getDisplayId());
                    display.getDisplayId());
            mDragWindowHandle.name = "drag";
            mDragWindowHandle.inputChannel = mServerChannel;
            mDragWindowHandle.layer = getDragLayerLw();
@@ -174,7 +177,7 @@ class DragState {
            mDragWindowHandle.frameLeft = 0;
            mDragWindowHandle.frameTop = 0;
            Point p = new Point();
            mDisplay.getRealSize(p);
            display.getRealSize(p);
            mDragWindowHandle.frameRight = p.x;
            mDragWindowHandle.frameBottom = p.y;

@@ -244,14 +247,12 @@ class DragState {
            Slog.d(TAG_WM, "broadcasting DRAG_STARTED at (" + touchX + ", " + touchY + ")");
        }

        final WindowList windows = mService.getWindowListLocked(mDisplay);
        if (windows != null) {
        final WindowList windows = mDisplayContent.getWindowList();
        final int N = windows.size();
        for (int i = 0; i < N; i++) {
            sendDragStartedLw(windows.get(i), touchX, touchY, mDataDescription);
        }
    }
    }

    /* helper - send a ACTION_DRAG_STARTED event, if the
     * designated window is potentially a drop recipient.  There are race situations
@@ -379,7 +380,7 @@ class DragState {
    private void cleanUpDragLw() {
        broadcastDragEndedLw();
        if (isFromSource(InputDevice.SOURCE_MOUSE)) {
            mService.restorePointerIconLocked(mDisplay, mCurrentX, mCurrentY);
            mService.restorePointerIconLocked(mDisplayContent, mCurrentX, mCurrentY);
        }

        // stop intercepting input
@@ -418,7 +419,7 @@ class DragState {

    void notifyLocationLw(float x, float y) {
        // Tell the affected window
        WindowState touchedWin = mService.getTouchableWinAtPointLocked(mDisplay, x, y);
        WindowState touchedWin = mDisplayContent.getTouchableWinAtPointLocked(x, y);
        if (touchedWin == null) {
            if (DEBUG_DRAG) Slog.d(TAG_WM, "No touched win at x=" + x + " y=" + y);
            return;
@@ -463,17 +464,18 @@ class DragState {
        mTargetWindow = touchedWin;
    }

    // Tell the drop target about the data.  Returns 'true' if we can immediately
    // 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 notifyDropLw(WindowState touchedWin, IDropPermissions dropPermissions,
            float x, float y) {
    boolean notifyDropLw(float x, float y) {
        if (mAnimation != null) {
            return false;
        }
        mCurrentX = x;
        mCurrentY = y;

        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.
@@ -484,7 +486,21 @@ class DragState {
        if (DEBUG_DRAG) {
            Slog.d(TAG_WM, "sending DROP to " + touchedWin);
        }
        if (mSourceUserId != UserHandle.getUserId(touchedWin.getOwningUid())){

        final int targetUserId = UserHandle.getUserId(touchedWin.getOwningUid());

        DropPermissionsHandler dropPermissions = null;
        if ((mFlags & View.DRAG_FLAG_GLOBAL) != 0 &&
                (mFlags & DRAG_FLAGS_URI_ACCESS) != 0) {
            dropPermissions = new DropPermissionsHandler(
                    mData,
                    mUid,
                    touchedWin.getOwningPackage(),
                    mFlags & DRAG_FLAGS_URI_PERMISSIONS,
                    mSourceUserId,
                    targetUserId);
        }
        if (mSourceUserId != targetUserId){
            mData.fixUris(mSourceUserId);
        }
        final int myPid = Process.myPid();
+7 −74
Original line number Diff line number Diff line
@@ -664,13 +664,6 @@ public class WindowManagerService extends IWindowManager.Stub

    private WindowContentFrameStats mTempWindowRenderStats;

    private static final int DRAG_FLAGS_URI_ACCESS = View.DRAG_FLAG_GLOBAL_URI_READ |
            View.DRAG_FLAG_GLOBAL_URI_WRITE;

    private static final int DRAG_FLAGS_URI_PERMISSIONS = DRAG_FLAGS_URI_ACCESS |
            View.DRAG_FLAG_GLOBAL_PERSISTABLE_URI_PERMISSION |
            View.DRAG_FLAG_GLOBAL_PREFIX_URI_PERMISSION;

    final class DragInputEventReceiver extends InputEventReceiver {
        // Set, if stylus button was down at the start of the drag.
        private boolean mStylusButtonDownAtStart;
@@ -716,7 +709,7 @@ public class WindowManagerService extends IWindowManager.Stub
                            if (DEBUG_DRAG) Slog.d(TAG_WM, "Button no longer pressed; dropping at "
                                    + newX + "," + newY);
                            synchronized (mWindowMap) {
                                endDrag = completeDropLw(newX, newY);
                                endDrag = mDragState.notifyDropLw(newX, newY);
                            }
                        } else {
                            synchronized (mWindowMap) {
@@ -730,7 +723,7 @@ public class WindowManagerService extends IWindowManager.Stub
                        if (DEBUG_DRAG) Slog.d(TAG_WM, "Got UP on move channel; dropping at "
                                + newX + "," + newY);
                        synchronized (mWindowMap) {
                            endDrag = completeDropLw(newX, newY);
                            endDrag = mDragState.notifyDropLw(newX, newY);
                        }
                    } break;

@@ -760,25 +753,6 @@ public class WindowManagerService extends IWindowManager.Stub
        }
    }

    private boolean completeDropLw(float x, float y) {
        WindowState dropTargetWin = getTouchableWinAtPointLocked(mDragState.mDisplay, x, y);

        DropPermissionsHandler dropPermissions = null;
        if (dropTargetWin != null &&
                (mDragState.mFlags & View.DRAG_FLAG_GLOBAL) != 0 &&
                (mDragState.mFlags & DRAG_FLAGS_URI_ACCESS) != 0) {
            dropPermissions = new DropPermissionsHandler(
                    mDragState.mData,
                    mDragState.mUid,
                    dropTargetWin.getOwningPackage(),
                    mDragState.mFlags & DRAG_FLAGS_URI_PERMISSIONS,
                    mDragState.mSourceUserId,
                    UserHandle.getUserId(dropTargetWin.getOwningUid()));
        }

        return mDragState.notifyDropLw(dropTargetWin, dropPermissions, x, y);
    }

    /**
     * Whether the UI is currently running in touch mode (not showing
     * navigational focus because the user is directly pressing the screen).
@@ -10467,48 +10441,6 @@ public class WindowManagerService extends IWindowManager.Stub
        }
    }

    /**
     * Find the visible, touch-deliverable window under the given point
     */
    WindowState getTouchableWinAtPointLocked(Display display, float xf, float yf) {
        WindowState touchedWin = null;
        final int x = (int) xf;
        final int y = (int) yf;

        final WindowList windows = getWindowListLocked(display);
        if (windows == null) {
            return null;
        }
        final int N = windows.size();
        for (int i = N - 1; i >= 0; i--) {
            WindowState child = windows.get(i);
            final int flags = child.mAttrs.flags;
            if (!child.isVisibleLw()) {
                continue;
            }
            if ((flags & WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE) != 0) {
                continue;
            }

            child.getVisibleBounds(mTmpRect);
            if (!mTmpRect.contains(x, y)) {
                continue;
            }

            child.getTouchableRegion(mTmpRegion);

            final int touchFlags = flags &
                    (WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE
                            | WindowManager.LayoutParams.FLAG_NOT_TOUCH_MODAL);
            if (mTmpRegion.contains(x, y) || touchFlags == 0) {
                touchedWin = child;
                break;
            }
        }

        return touchedWin;
    }

    private MousePositionTracker mMousePositionTracker = new MousePositionTracker();

    private static class MousePositionTracker implements PointerEventListener {
@@ -10561,8 +10493,8 @@ public class WindowManagerService extends IWindowManager.Stub
            if (displayContent == null) {
                return;
            }
            Display display = displayContent.getDisplay();
            WindowState windowUnderPointer = getTouchableWinAtPointLocked(display, mouseX, mouseY);
            WindowState windowUnderPointer =
                    displayContent.getTouchableWinAtPointLocked(mouseX, mouseY);
            if (windowUnderPointer != callingWin) {
                return;
            }
@@ -10576,11 +10508,12 @@ public class WindowManagerService extends IWindowManager.Stub
        }
    }

    void restorePointerIconLocked(Display display, float latestX, float latestY) {
    void restorePointerIconLocked(DisplayContent displayContent, float latestX, float latestY) {
        // Mouse position tracker has not been getting updates while dragging, update it now.
        mMousePositionTracker.updatePosition(latestX, latestY);

        WindowState windowUnderPointer = getTouchableWinAtPointLocked(display, latestX, latestY);
        WindowState windowUnderPointer =
                displayContent.getTouchableWinAtPointLocked(latestX, latestY);
        if (windowUnderPointer != null) {
            try {
                windowUnderPointer.mClient.updatePointerIcon(