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

Commit f15015b6 authored by Garfield Tan's avatar Garfield Tan Committed by Android (Google) Code Review
Browse files

Merge "Use spy windows to resize tasks" into udc-qpr-dev

parents 22572023 a9b24fb2
Loading
Loading
Loading
Loading
+3 −1
Original line number Diff line number Diff line
@@ -145,7 +145,9 @@ public class CaptionWindowDecoration extends WindowDecoration<WindowDecorLinearL
                    mDisplay.getDisplayId(),
                    0 /* taskCornerRadius */,
                    mDecorationContainerSurface,
                    mDragPositioningCallback);
                    mDragPositioningCallback,
                    mSurfaceControlBuilderSupplier,
                    mSurfaceControlTransactionSupplier);
        }

        final int touchSlop = ViewConfiguration.get(mResult.mRootView.getContext())
+3 −1
Original line number Diff line number Diff line
@@ -234,7 +234,9 @@ public class DesktopModeWindowDecoration extends WindowDecoration<WindowDecorLin
                    mDisplay.getDisplayId(),
                    mRelayoutParams.mCornerRadius,
                    mDecorationContainerSurface,
                    mDragPositioningCallback);
                    mDragPositioningCallback,
                    mSurfaceControlBuilderSupplier,
                    mSurfaceControlTransactionSupplier);
        }

        final int touchSlop = ViewConfiguration.get(mResult.mRootView.getContext())
+3 −1
Original line number Diff line number Diff line
@@ -22,7 +22,9 @@ import android.annotation.IntDef;
 * Callback called when receiving drag-resize or drag-move related input events.
 */
public interface DragPositioningCallback {
    @IntDef({CTRL_TYPE_UNDEFINED, CTRL_TYPE_LEFT, CTRL_TYPE_RIGHT, CTRL_TYPE_TOP, CTRL_TYPE_BOTTOM})
    @IntDef(flag = true, value = {
            CTRL_TYPE_UNDEFINED, CTRL_TYPE_LEFT, CTRL_TYPE_RIGHT, CTRL_TYPE_TOP, CTRL_TYPE_BOTTOM
    })
    @interface CtrlType {}

    int CTRL_TYPE_UNDEFINED = 0;
+87 −5
Original line number Diff line number Diff line
@@ -18,8 +18,11 @@ package com.android.wm.shell.windowdecor;

import static android.view.InputDevice.SOURCE_TOUCHSCREEN;
import static android.view.WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE;
import static android.view.WindowManager.LayoutParams.INPUT_FEATURE_NO_INPUT_CHANNEL;
import static android.view.WindowManager.LayoutParams.INPUT_FEATURE_SPY;
import static android.view.WindowManager.LayoutParams.PRIVATE_FLAG_TRUSTED_OVERLAY;
import static android.view.WindowManager.LayoutParams.TYPE_APPLICATION;
import static android.view.WindowManager.LayoutParams.TYPE_INPUT_CONSUMER;

import static com.android.wm.shell.windowdecor.DragPositioningCallback.CTRL_TYPE_BOTTOM;
import static com.android.wm.shell.windowdecor.DragPositioningCallback.CTRL_TYPE_LEFT;
@@ -48,6 +51,8 @@ import android.view.WindowManagerGlobal;

import com.android.internal.view.BaseIWindow;

import java.util.function.Supplier;

/**
 * An input event listener registered to InputDispatcher to receive input events on task edges and
 * and corners. Converts them to drag resize requests.
@@ -60,6 +65,7 @@ class DragResizeInputListener implements AutoCloseable {
    private final Handler mHandler;
    private final Choreographer mChoreographer;
    private final InputManager mInputManager;
    private final Supplier<SurfaceControl.Transaction> mSurfaceControlTransactionSupplier;

    private final int mDisplayId;
    private final BaseIWindow mFakeWindow;
@@ -69,6 +75,10 @@ class DragResizeInputListener implements AutoCloseable {
    private final TaskResizeInputEventReceiver mInputEventReceiver;
    private final DragPositioningCallback mCallback;

    private final SurfaceControl mInputSinkSurface;
    private final BaseIWindow mFakeSinkWindow;
    private final InputChannel mSinkInputChannel;

    private int mTaskWidth;
    private int mTaskHeight;
    private int mResizeHandleThickness;
@@ -90,15 +100,18 @@ class DragResizeInputListener implements AutoCloseable {
            int displayId,
            int taskCornerRadius,
            SurfaceControl decorationSurface,
            DragPositioningCallback callback) {
            DragPositioningCallback callback,
            Supplier<SurfaceControl.Builder> surfaceControlBuilderSupplier,
            Supplier<SurfaceControl.Transaction> surfaceControlTransactionSupplier) {
        mInputManager = context.getSystemService(InputManager.class);
        mHandler = handler;
        mChoreographer = choreographer;
        mSurfaceControlTransactionSupplier = surfaceControlTransactionSupplier;
        mDisplayId = displayId;
        mTaskCornerRadius = taskCornerRadius;
        mDecorationSurface = decorationSurface;
        // Use a fake window as the backing surface is a container layer and we don't want to create
        // a buffer layer for it so we can't use ViewRootImpl.
        // Use a fake window as the backing surface is a container layer, and we don't want to
        // create a buffer layer for it, so we can't use ViewRootImpl.
        mFakeWindow = new BaseIWindow();
        mFakeWindow.setSession(mWindowSession);
        mFocusGrantToken = new Binder();
@@ -111,7 +124,7 @@ class DragResizeInputListener implements AutoCloseable {
                    null /* hostInputToken */,
                    FLAG_NOT_FOCUSABLE,
                    PRIVATE_FLAG_TRUSTED_OVERLAY,
                    0 /* inputFeatures */,
                    INPUT_FEATURE_SPY,
                    TYPE_APPLICATION,
                    null /* windowToken */,
                    mFocusGrantToken,
@@ -126,6 +139,35 @@ class DragResizeInputListener implements AutoCloseable {
        mCallback = callback;
        mDragDetector = new DragDetector(mInputEventReceiver);
        mDragDetector.setTouchSlop(ViewConfiguration.get(context).getScaledTouchSlop());

        mInputSinkSurface = surfaceControlBuilderSupplier.get()
                .setName("TaskInputSink of " + decorationSurface)
                .setContainerLayer()
                .setParent(mDecorationSurface)
                .build();
        mSurfaceControlTransactionSupplier.get()
                .setLayer(mInputSinkSurface, WindowDecoration.INPUT_SINK_Z_ORDER)
                .show(mInputSinkSurface)
                .apply();
        mFakeSinkWindow = new BaseIWindow();
        mSinkInputChannel = new InputChannel();
        try {
            mWindowSession.grantInputChannel(
                    mDisplayId,
                    mInputSinkSurface,
                    mFakeSinkWindow,
                    null /* hostInputToken */,
                    FLAG_NOT_FOCUSABLE,
                    0 /* privateFlags */,
                    INPUT_FEATURE_NO_INPUT_CHANNEL,
                    TYPE_INPUT_CONSUMER,
                    null /* windowToken */,
                    mFocusGrantToken,
                    "TaskInputSink of " + decorationSurface,
                    mSinkInputChannel);
        } catch (RemoteException e) {
            e.rethrowFromSystemServer();
        }
    }

    /**
@@ -219,7 +261,35 @@ class DragResizeInputListener implements AutoCloseable {
                    mDecorationSurface,
                    FLAG_NOT_FOCUSABLE,
                    PRIVATE_FLAG_TRUSTED_OVERLAY,
                    0 /* inputFeatures */,
                    INPUT_FEATURE_SPY,
                    touchRegion);
        } catch (RemoteException e) {
            e.rethrowFromSystemServer();
        }

        mSurfaceControlTransactionSupplier.get()
                .setWindowCrop(mInputSinkSurface, mTaskWidth, mTaskHeight)
                .apply();
        // The touch region of the TaskInputSink should be the touch region of this
        // DragResizeInputHandler minus the task bounds. Pilfering events isn't enough to prevent
        // input windows from handling down events, which will bring tasks in the back to front.
        //
        // Note not the entire touch region responds to both mouse and touchscreen events.
        // Therefore, in the region that only responds to one of them, it would be a no-op to
        // perform a gesture in the other type of events. We currently only have a mouse-only region
        // out of the task bounds, and due to the roughness of touchscreen events, it's not a severe
        // issue. However, were there touchscreen-only a region out of the task bounds, mouse
        // gestures will become no-op in that region, even though the mouse gestures may appear to
        // be performed on the input window behind the resize handle.
        touchRegion.op(0, 0, mTaskWidth, mTaskHeight, Region.Op.DIFFERENCE);
        try {
            mWindowSession.updateInputChannel(
                    mSinkInputChannel.getToken(),
                    mDisplayId,
                    mInputSinkSurface,
                    FLAG_NOT_FOCUSABLE,
                    0 /* privateFlags */,
                    INPUT_FEATURE_NO_INPUT_CHANNEL,
                    touchRegion);
        } catch (RemoteException e) {
            e.rethrowFromSystemServer();
@@ -248,6 +318,16 @@ class DragResizeInputListener implements AutoCloseable {
        } catch (RemoteException e) {
            e.rethrowFromSystemServer();
        }

        mSinkInputChannel.dispose();
        try {
            mWindowSession.remove(mFakeSinkWindow);
        } catch (RemoteException e) {
            e.rethrowFromSystemServer();
        }
        mSurfaceControlTransactionSupplier.get()
                .remove(mInputSinkSurface)
                .apply();
    }

    private class TaskResizeInputEventReceiver extends InputEventReceiver
@@ -316,6 +396,8 @@ class DragResizeInputListener implements AutoCloseable {
                        mShouldHandleEvents = isInResizeHandleBounds(x, y);
                    }
                    if (mShouldHandleEvents) {
                        mInputManager.pilferPointers(mInputChannel.getToken());

                        mDragPointerId = e.getPointerId(0);
                        float rawX = e.getRawX(0);
                        float rawY = e.getRawY(0);
+19 −4
Original line number Diff line number Diff line
@@ -63,6 +63,24 @@ import java.util.function.Supplier;
public abstract class WindowDecoration<T extends View & TaskFocusStateConsumer>
        implements AutoCloseable {

    /**
     * The Z-order of {@link #mCaptionContainerSurface}.
     * <p>
     * We use {@link #mDecorationContainerSurface} to define input window for task resizing; by
     * layering it in front of {@link #mCaptionContainerSurface}, we can allow it to handle input
     * prior to caption view itself, treating corner inputs as resize events rather than
     * repositioning.
     */
    static final int CAPTION_LAYER_Z_ORDER = -1;
    /**
     * The Z-order of the task input sink in {@link DragPositioningCallback}.
     * <p>
     * This task input sink is used to prevent undesired dispatching of motion events out of task
     * bounds; by layering it behind {@link #mCaptionContainerSurface}, we allow captions to handle
     * input events first.
     */
    static final int INPUT_SINK_Z_ORDER = -2;

    /**
     * System-wide context. Only used to create context with overridden configurations.
     */
@@ -238,11 +256,8 @@ public abstract class WindowDecoration<T extends View & TaskFocusStateConsumer>
        final int captionHeight = loadDimensionPixelSize(resources, params.mCaptionHeightId);
        final int captionWidth = taskBounds.width();

        // We use mDecorationContainerSurface to define input window for task resizing; by layering
        // it in front of mCaptionContainerSurface, we can allow it to handle input prior to
        // caption view itself, treating corner inputs as resize events rather than repositioning.
        startT.setWindowCrop(mCaptionContainerSurface, captionWidth, captionHeight)
                .setLayer(mCaptionContainerSurface, -1)
                .setLayer(mCaptionContainerSurface, CAPTION_LAYER_Z_ORDER)
                .show(mCaptionContainerSurface);

        if (ViewRootImpl.CAPTION_ON_SHELL) {