diff options
| author | 2023-08-22 17:21:21 +0000 | |
|---|---|---|
| committer | 2023-08-22 20:49:06 +0000 | |
| commit | 15118bd67c7e1301f3695714fa1a58f1e77bd717 (patch) | |
| tree | 2ff508f47a980939f2a3ea33956a70b816765314 | |
| parent | 9c9e0b77c165d48f1e5f62ceab0897c60e6dc587 (diff) | |
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
6 files changed, 50 insertions, 11 deletions
diff --git a/services/core/java/com/android/server/input/GestureMonitorSpyWindow.java b/services/core/java/com/android/server/input/GestureMonitorSpyWindow.java index d238dae634ad..2ede56dcecd9 100644 --- a/services/core/java/com/android/server/input/GestureMonitorSpyWindow.java +++ b/services/core/java/com/android/server/input/GestureMonitorSpyWindow.java @@ -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); diff --git a/services/core/java/com/android/server/input/InputManagerService.java b/services/core/java/com/android/server/input/InputManagerService.java index 5c80291f7f46..ff69719c9497 100644 --- a/services/core/java/com/android/server/input/InputManagerService.java +++ b/services/core/java/com/android/server/input/InputManagerService.java @@ -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. */ diff --git a/services/core/java/com/android/server/inputmethod/HandwritingEventReceiverSurface.java b/services/core/java/com/android/server/inputmethod/HandwritingEventReceiverSurface.java index 0c889c2765bb..7726f40fa2ae 100644 --- a/services/core/java/com/android/server/inputmethod/HandwritingEventReceiverSurface.java +++ b/services/core/java/com/android/server/inputmethod/HandwritingEventReceiverSurface.java @@ -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); diff --git a/services/core/java/com/android/server/wm/DisplayContent.java b/services/core/java/com/android/server/wm/DisplayContent.java index 4cb4fe292173..4a4039559de9 100644 --- a/services/core/java/com/android/server/wm/DisplayContent.java +++ b/services/core/java/com/android/server/wm/DisplayContent.java @@ -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; } diff --git a/services/core/java/com/android/server/wm/InputManagerCallback.java b/services/core/java/com/android/server/wm/InputManagerCallback.java index 73fdfe0d1181..8cf471394c63 100644 --- a/services/core/java/com/android/server/wm/InputManagerCallback.java +++ b/services/core/java/com/android/server/wm/InputManagerCallback.java @@ -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(); } } diff --git a/services/core/java/com/android/server/wm/WindowManagerService.java b/services/core/java/com/android/server/wm/WindowManagerService.java index 3a19a3b1e56a..b20be551c114 100644 --- a/services/core/java/com/android/server/wm/WindowManagerService.java +++ b/services/core/java/com/android/server/wm/WindowManagerService.java @@ -8311,12 +8311,18 @@ public class WindowManagerService extends IWindowManager.Stub + displayId + " - DisplayContent not found."); return null; } - //TODO (b/210039666): Use a method like add/removeDisplayOverlay if available. + 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; + } + // TODO(b/210039666): Use a method like add/removeDisplayOverlay if available. return makeSurfaceBuilder(dc.getSession()) .setContainerLayer() .setName("IME Handwriting Surface") .setCallsite("getHandwritingSurfaceForDisplay") - .setParent(dc.getSurfaceControl()) + .setParent(inputOverlay) .build(); } } |