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

Commit 15118bd6 authored by Prabir Pradhan's avatar Prabir Pradhan
Browse files

Move input surfaces into its own overlay in DisplayContent

Input surfaces, such as gesture monitors and handwriting windows, were
created and placed directly inside the DisplayContent's SurfaceControl.

In some cases, like when the display is recreated, the DisplayContent's
SurfaceControl changes, so the surfaces should be reparented to the new
SurfaceControl when that happens.

To do that, we create a new overlay layer in DisplayContent for input
surfaces, and place that between the display overlay and the a11y
overlay. That way, we can ensure that the input overlays are always
parented to the correct display in the hierarchy, even when the display
is recreated.

Bug: 295386214
Test: manual
Change-Id: Ia1e31e68dca20610b7cb704869ceb71bb49e753b
parent 9c9e0b77
Loading
Loading
Loading
Loading
+1 −1
Original line number Diff line number Diff line
@@ -67,7 +67,7 @@ class GestureMonitorSpyWindow {

        final SurfaceControl.Transaction t = new SurfaceControl.Transaction();
        t.setInputWindowInfo(mInputSurface, mWindowHandle);
        t.setLayer(mInputSurface, Integer.MAX_VALUE);
        t.setLayer(mInputSurface, InputManagerService.INPUT_OVERLAY_LAYER_GESTURE_MONITOR);
        t.setPosition(mInputSurface, 0, 0);
        t.setCrop(mInputSurface, null /* crop to parent surface */);
        t.show(mInputSurface);
+11 −0
Original line number Diff line number Diff line
@@ -381,6 +381,17 @@ public class InputManagerService extends IInputManager.Stub
    public static final int SW_CAMERA_LENS_COVER_BIT = 1 << SW_CAMERA_LENS_COVER;
    public static final int SW_MUTE_DEVICE_BIT = 1 << SW_MUTE_DEVICE;

    // The following are layer numbers used for z-ordering the input overlay layers on the display.
    // This is used for ordering layers inside {@code DisplayContent#getInputOverlayLayer()}.
    //
    // The layer where gesture monitors are added.
    public static final int INPUT_OVERLAY_LAYER_GESTURE_MONITOR = 1;
    // Place the handwriting layer above gesture monitors so that styluses cannot trigger
    // system gestures (e.g. navigation bar, edge-back, etc) while there is an active
    // handwriting session.
    public static final int INPUT_OVERLAY_LAYER_HANDWRITING_SURFACE = 2;


    private final String mVelocityTrackerStrategy;

    /** Whether to use the dev/input/event or uevent subsystem for the audio jack. */
+3 −6
Original line number Diff line number Diff line
@@ -27,16 +27,13 @@ import android.view.InputWindowHandle;
import android.view.SurfaceControl;
import android.view.WindowManager;

import com.android.server.input.InputManagerService;

final class HandwritingEventReceiverSurface {

    public static final String TAG = HandwritingEventReceiverSurface.class.getSimpleName();
    static final boolean DEBUG = HandwritingModeController.DEBUG;

    // Place the layer at the highest layer so stylus cannot trigger gesture monitors
    // (e.g. navigation bar, edge-back, etc) while handwriting is ongoing.
    // TODO(b/217538817): Specify the ordering in WM by usage.
    private static final int HANDWRITING_SURFACE_LAYER = Integer.MAX_VALUE;

    private final InputWindowHandle mWindowHandle;
    private final InputChannel mClientChannel;
    private final SurfaceControl mInputSurface;
@@ -68,7 +65,7 @@ final class HandwritingEventReceiverSurface {

        final SurfaceControl.Transaction t = new SurfaceControl.Transaction();
        t.setInputWindowInfo(mInputSurface, mWindowHandle);
        t.setLayer(mInputSurface, HANDWRITING_SURFACE_LAYER);
        t.setLayer(mInputSurface, InputManagerService.INPUT_OVERLAY_LAYER_HANDWRITING_SURFACE);
        t.setPosition(mInputSurface, 0, 0);
        t.setCrop(mInputSurface, null /* crop to parent surface */);
        t.show(mInputSurface);
+20 −1
Original line number Diff line number Diff line
@@ -328,6 +328,12 @@ class DisplayContent extends RootDisplayArea implements WindowManagerPolicy.Disp
     */
    private SurfaceControl mOverlayLayer;

    /**
     * A SurfaceControl that contains input overlays used for cases where we need to receive input
     * over the entire display.
     */
    private SurfaceControl mInputOverlayLayer;

    /** A surfaceControl specifically for accessibility overlays. */
    private SurfaceControl mA11yOverlayLayer;

@@ -1329,6 +1335,12 @@ class DisplayContent extends RootDisplayArea implements WindowManagerPolicy.Disp
            transaction.reparent(mOverlayLayer, mSurfaceControl);
        }

        if (mInputOverlayLayer == null) {
            mInputOverlayLayer = b.setName("Input Overlays").setParent(mSurfaceControl).build();
        } else {
            transaction.reparent(mInputOverlayLayer, mSurfaceControl);
        }

        if (mA11yOverlayLayer == null) {
            mA11yOverlayLayer =
                    b.setName("Accessibility Overlays").setParent(mSurfaceControl).build();
@@ -1342,7 +1354,9 @@ class DisplayContent extends RootDisplayArea implements WindowManagerPolicy.Disp
                .show(mSurfaceControl)
                .setLayer(mOverlayLayer, Integer.MAX_VALUE)
                .show(mOverlayLayer)
                .setLayer(mA11yOverlayLayer, Integer.MAX_VALUE - 1)
                .setLayer(mInputOverlayLayer, Integer.MAX_VALUE - 1)
                .show(mInputOverlayLayer)
                .setLayer(mA11yOverlayLayer, Integer.MAX_VALUE - 2)
                .show(mA11yOverlayLayer);
    }

@@ -3353,6 +3367,7 @@ class DisplayContent extends RootDisplayArea implements WindowManagerPolicy.Disp
            // -> this DisplayContent.
            setRemoteInsetsController(null);
            mOverlayLayer.release();
            mInputOverlayLayer.release();
            mA11yOverlayLayer.release();
            mWindowingLayer.release();
            mInputMonitor.onDisplayRemoved();
@@ -5703,6 +5718,10 @@ class DisplayContent extends RootDisplayArea implements WindowManagerPolicy.Disp
        return mOverlayLayer;
    }

    SurfaceControl getInputOverlayLayer() {
        return mInputOverlayLayer;
    }

    SurfaceControl getA11yOverlayLayer() {
        return mA11yOverlayLayer;
    }
+7 −1
Original line number Diff line number Diff line
@@ -275,11 +275,17 @@ final class InputManagerCallback implements InputManagerService.WindowManagerCal
                        + " - DisplayContent not found.");
                return null;
            }
            final SurfaceControl inputOverlay = dc.getInputOverlayLayer();
            if (inputOverlay == null) {
                Slog.e(TAG, "Failed to create a gesture monitor on display: " + displayId
                        + " - Input overlay layer is not initialized.");
                return null;
            }
            return mService.makeSurfaceBuilder(dc.getSession())
                    .setContainerLayer()
                    .setName(name)
                    .setCallsite("createSurfaceForGestureMonitor")
                    .setParent(dc.getSurfaceControl())
                    .setParent(inputOverlay)
                    .build();
        }
    }
Loading