summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
author Prabir Pradhan <prabirmsp@google.com> 2023-08-22 17:21:21 +0000
committer Prabir Pradhan <prabirmsp@google.com> 2023-08-22 20:49:06 +0000
commit15118bd67c7e1301f3695714fa1a58f1e77bd717 (patch)
tree2ff508f47a980939f2a3ea33956a70b816765314
parent9c9e0b77c165d48f1e5f62ceab0897c60e6dc587 (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
-rw-r--r--services/core/java/com/android/server/input/GestureMonitorSpyWindow.java2
-rw-r--r--services/core/java/com/android/server/input/InputManagerService.java11
-rw-r--r--services/core/java/com/android/server/inputmethod/HandwritingEventReceiverSurface.java9
-rw-r--r--services/core/java/com/android/server/wm/DisplayContent.java21
-rw-r--r--services/core/java/com/android/server/wm/InputManagerCallback.java8
-rw-r--r--services/core/java/com/android/server/wm/WindowManagerService.java10
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();
}
}