Support monitor input per display (2/2)
To support system gesture per display,
monitor Input should be separated by display.
So each DisplayContent would contain its own
PointerEventDispatcher to detect system gesture.
Bug: b/115602714
Test: atest DisplayContentTests ActivityManagerMultiDisplayTests
Test: atest inputflinger_tests
Change-Id: I7889128af82f0d61dbdc89a84d6ccf0b337e38b4
diff --git a/services/core/java/com/android/server/wm/DisplayContent.java b/services/core/java/com/android/server/wm/DisplayContent.java
index d8fd198..ca23360 100644
--- a/services/core/java/com/android/server/wm/DisplayContent.java
+++ b/services/core/java/com/android/server/wm/DisplayContent.java
@@ -145,12 +145,14 @@
import android.view.DisplayCutout;
import android.view.DisplayInfo;
import android.view.Gravity;
+import android.view.InputChannel;
import android.view.InputDevice;
import android.view.MagnificationSpec;
import android.view.Surface;
import android.view.SurfaceControl;
import android.view.SurfaceControl.Transaction;
import android.view.SurfaceSession;
+import android.view.WindowManagerPolicyConstants.PointerEventListener;
import com.android.internal.annotations.VisibleForTesting;
import com.android.internal.util.ToBooleanFunction;
@@ -454,6 +456,8 @@
*/
WindowState mInputMethodWindow;
+ private final PointerEventDispatcher mPointerEventDispatcher;
+
private final Consumer<WindowState> mUpdateWindowsForAnimator = w -> {
WindowStateAnimator winAnimator = w.mWinAnimator;
final AppWindowToken atoken = w.mAppToken;
@@ -833,6 +837,15 @@
mDisplayReady = true;
mInputMonitor = new InputMonitor(service, mDisplayId);
+
+ if (mService.mInputManager != null) {
+ final InputChannel inputChannel = mService.mInputManager.monitorInput("Display "
+ + mDisplayId, mDisplayId);
+ mPointerEventDispatcher = inputChannel != null
+ ? new PointerEventDispatcher(inputChannel) : null;
+ } else {
+ mPointerEventDispatcher = null;
+ }
}
boolean isReady() {
@@ -1286,6 +1299,19 @@
mDisplayFrames.onDisplayInfoUpdated(mDisplayInfo,
calculateDisplayCutoutForRotation(mDisplayInfo.rotation));
+
+ // Tap Listeners are supported for:
+ // 1. All physical displays (multi-display).
+ // 2. VirtualDisplays on VR, AA (and everything else).
+ if (mPointerEventDispatcher != null && mTapDetector == null) {
+ if (DEBUG_DISPLAY) {
+ Slog.d(TAG,
+ "Registering PointerEventListener for DisplayId: " + mDisplayId);
+ }
+ mTapDetector = new TaskTapPointerEventListener(mService, this);
+ registerPointerEventListener(mTapDetector);
+ registerPointerEventListener(mService.mMousePositionTracker);
+ }
}
/**
@@ -2186,13 +2212,10 @@
try {
super.removeImmediately();
if (DEBUG_DISPLAY) Slog.v(TAG_WM, "Removing display=" + this);
- if (mService.canDispatchPointerEvents()) {
- if (mTapDetector != null) {
- mService.unregisterPointerEventListener(mTapDetector);
- }
- if (mDisplayId == DEFAULT_DISPLAY && mService.mMousePositionTracker != null) {
- mService.unregisterPointerEventListener(mService.mMousePositionTracker);
- }
+ if (mPointerEventDispatcher != null && mTapDetector != null) {
+ unregisterPointerEventListener(mTapDetector);
+ unregisterPointerEventListener(mService.mMousePositionTracker);
+ mTapDetector = null;
}
mService.mAnimator.removeDisplayLocked(mDisplayId);
mWindowingLayer.release();
@@ -4409,4 +4432,16 @@
boolean getLastHasContent() {
return mLastHasContent;
}
+
+ void registerPointerEventListener(@NonNull PointerEventListener listener) {
+ if (mPointerEventDispatcher != null) {
+ mPointerEventDispatcher.registerInputEventListener(listener);
+ }
+ }
+
+ void unregisterPointerEventListener(@NonNull PointerEventListener listener) {
+ if (mPointerEventDispatcher != null) {
+ mPointerEventDispatcher.unregisterInputEventListener(listener);
+ }
+ }
}
diff --git a/services/core/java/com/android/server/wm/RootWindowContainer.java b/services/core/java/com/android/server/wm/RootWindowContainer.java
index 3fef87d..c8977be 100644
--- a/services/core/java/com/android/server/wm/RootWindowContainer.java
+++ b/services/core/java/com/android/server/wm/RootWindowContainer.java
@@ -228,21 +228,6 @@
mService.mDisplayManagerInternal.setDisplayInfoOverrideFromWindowManager(
displayId, dc.getDisplayInfo());
dc.configureDisplayPolicy();
-
- // Tap Listeners are supported for:
- // 1. All physical displays (multi-display).
- // 2. VirtualDisplays on VR, AA (and everything else).
- if (mService.canDispatchPointerEvents()) {
- if (DEBUG_DISPLAY) {
- Slog.d(TAG,
- "Registering PointerEventListener for DisplayId: " + displayId);
- }
- dc.mTapDetector = new TaskTapPointerEventListener(mService, dc);
- mService.registerPointerEventListener(dc.mTapDetector);
- if (displayId == DEFAULT_DISPLAY) {
- mService.registerPointerEventListener(mService.mMousePositionTracker);
- }
- }
}
return dc;
diff --git a/services/core/java/com/android/server/wm/WindowManagerService.java b/services/core/java/com/android/server/wm/WindowManagerService.java
index 8b1b327..75b1bbe 100644
--- a/services/core/java/com/android/server/wm/WindowManagerService.java
+++ b/services/core/java/com/android/server/wm/WindowManagerService.java
@@ -753,8 +753,6 @@
final ArrayMap<AnimationAdapter, SurfaceAnimator> mAnimationTransferMap = new ArrayMap<>();
final BoundsAnimationController mBoundsAnimationController;
- private final PointerEventDispatcher mPointerEventDispatcher;
-
private WindowContentFrameStats mTempWindowRenderStats;
private final LatencyTracker mLatencyTracker;
@@ -945,14 +943,6 @@
LocalServices.addService(WindowManagerPolicy.class, mPolicy);
- if(mInputManager != null) {
- final InputChannel inputChannel = mInputManager.monitorInput(TAG_WM);
- mPointerEventDispatcher = inputChannel != null
- ? new PointerEventDispatcher(inputChannel) : null;
- } else {
- mPointerEventDispatcher = null;
- }
-
mDisplayManager = (DisplayManager)context.getSystemService(Context.DISPLAY_SERVICE);
mKeyguardDisableHandler = new KeyguardDisableHandler(mContext, mPolicy);
@@ -3126,18 +3116,23 @@
}
@Override
- public void registerPointerEventListener(PointerEventListener listener) {
- mPointerEventDispatcher.registerInputEventListener(listener);
+ public void registerPointerEventListener(PointerEventListener listener, int displayId) {
+ synchronized (mWindowMap) {
+ final DisplayContent displayContent = mRoot.getDisplayContent(displayId);
+ if (displayContent != null) {
+ displayContent.registerPointerEventListener(listener);
+ }
+ }
}
@Override
- public void unregisterPointerEventListener(PointerEventListener listener) {
- mPointerEventDispatcher.unregisterInputEventListener(listener);
- }
-
- /** Check if the service is set to dispatch pointer events. */
- boolean canDispatchPointerEvents() {
- return mPointerEventDispatcher != null;
+ public void unregisterPointerEventListener(PointerEventListener listener, int displayId) {
+ synchronized (mWindowMap) {
+ final DisplayContent displayContent = mRoot.getDisplayContent(displayId);
+ if (displayContent != null) {
+ displayContent.unregisterPointerEventListener(listener);
+ }
+ }
}
// Called by window manager policy. Not exposed externally.