Fix WM input limitations on secondary displays (3/4)

One DisplayContent contains one InputMonitor now.
- Change setInputWindow of InputManagerService updated by displayId,
  so Window Handles in InputDispather can be updated by each DisplayContent.
- Only exist one focus in current state, reset it if in removed DisplayContent,
  will be updated by default display or focused display.
- Add displayId parameter for createInputConsumer and destroyInputConsumer,
  so InputConsumer from PIP, RecentApp and Wallpaper can be supported in multi-display.

Bug: 111363643
Test: atest WindowManagerSmokeTest ActivityManagerMultiDisplayTests
Test: atest com.android.server.wm.DisplayContentTests
Test: atest libinput_tests inputflinger_tests
Change-Id: I999c355be1789af5759f00206475d004e10116e3
diff --git a/services/core/java/com/android/server/wm/DisplayContent.java b/services/core/java/com/android/server/wm/DisplayContent.java
index ba46737..82c1808 100644
--- a/services/core/java/com/android/server/wm/DisplayContent.java
+++ b/services/core/java/com/android/server/wm/DisplayContent.java
@@ -814,9 +814,7 @@
         // {@link DisplayContent} ready for use.
         mDisplayReady = true;
 
-        // TODO(b/112081256): Use independent InputMonitor.
-        mInputMonitor = isDefaultDisplay ? new InputMonitor(service, mDisplayId)
-                : mService.getDefaultDisplayContentLocked().mInputMonitor;
+        mInputMonitor = new InputMonitor(service, mDisplayId);
     }
 
     boolean isReady() {
@@ -2180,6 +2178,7 @@
             mRemovingDisplay = false;
         }
 
+        mInputMonitor.onRemoved();
         mService.onDisplayRemoved(mDisplayId);
     }
 
diff --git a/services/core/java/com/android/server/wm/InputConsumerImpl.java b/services/core/java/com/android/server/wm/InputConsumerImpl.java
index 6a08f4d..585a4f5 100644
--- a/services/core/java/com/android/server/wm/InputConsumerImpl.java
+++ b/services/core/java/com/android/server/wm/InputConsumerImpl.java
@@ -20,9 +20,9 @@
 import android.os.Process;
 import android.os.RemoteException;
 import android.os.UserHandle;
-import android.view.Display;
 import android.view.InputChannel;
 import android.view.WindowManager;
+
 import com.android.server.input.InputApplicationHandle;
 import com.android.server.input.InputWindowHandle;
 
diff --git a/services/core/java/com/android/server/wm/InputMonitor.java b/services/core/java/com/android/server/wm/InputMonitor.java
index c4beb55..3309798 100644
--- a/services/core/java/com/android/server/wm/InputMonitor.java
+++ b/services/core/java/com/android/server/wm/InputMonitor.java
@@ -367,6 +367,13 @@
         }
     }
 
+    void onRemoved() {
+        // If DisplayContent removed, we need find a way to remove window handles of this display
+        // from InputDispatcher, so pass an empty InputWindowHandles to remove them.
+        mService.mInputManager.setInputWindows(mInputWindowHandles, mFocusedInputWindowHandle,
+                mDisplayId);
+    }
+
     private final class UpdateInputForAllWindowsConsumer implements Consumer<WindowState> {
         InputConsumerImpl navInputConsumer;
         InputConsumerImpl pipInputConsumer;
@@ -399,8 +406,7 @@
             this.inDrag = inDrag;
             wallpaperController = mService.mRoot.mWallpaperController;
 
-            // TODO(b/112081256): Use independent InputMonitor for each display.
-            mService.mRoot/*.getDisplayContent(mDisplayId)*/.forAllWindows(this,
+            mService.mRoot.getDisplayContent(mDisplayId).forAllWindows(this,
                     true /* traverseTopToBottom */);
             if (mAddWallpaperInputConsumerHandle) {
                 // No visible wallpaper found, add the wallpaper input consumer at the end.
@@ -408,8 +414,8 @@
             }
 
             // Send windows to native code.
-            // TODO: Update Input windows and focus by display?
-            mService.mInputManager.setInputWindows(mInputWindowHandles, mFocusedInputWindowHandle);
+            mService.mInputManager.setInputWindows(mInputWindowHandles, mFocusedInputWindowHandle,
+                    mDisplayId);
 
             clearInputWindowHandlesLw();
 
@@ -429,7 +435,8 @@
             final int flags = w.mAttrs.flags;
             final int privateFlags = w.mAttrs.privateFlags;
             final int type = w.mAttrs.type;
-            final boolean hasFocus = w == mInputFocus;
+            // TODO(b/111361570): multi-display focus, one focus window per display.
+            final boolean hasFocus = w.isFocused();
             final boolean isVisible = w.isVisibleLw();
 
             if (mAddRecentsAnimationInputConsumerHandle) {
diff --git a/services/core/java/com/android/server/wm/WindowManagerService.java b/services/core/java/com/android/server/wm/WindowManagerService.java
index da77edf..50fe7e3 100644
--- a/services/core/java/com/android/server/wm/WindowManagerService.java
+++ b/services/core/java/com/android/server/wm/WindowManagerService.java
@@ -6036,11 +6036,10 @@
     }
 
     @Override
-    public void createInputConsumer(IBinder token, String name, InputChannel inputChannel) {
+    public void createInputConsumer(IBinder token, String name, int displayId,
+            InputChannel inputChannel) {
         synchronized (mWindowMap) {
-            // TODO(b/112049699): Fix this for multiple displays. There is only one inputChannel
-            // here to accept the return value.
-            DisplayContent display = mRoot.getDisplayContent(Display.DEFAULT_DISPLAY);
+            DisplayContent display = mRoot.getDisplayContent(displayId);
             if (display != null) {
                 display.getInputMonitor().createInputConsumer(token, name, inputChannel,
                         Binder.getCallingPid(), Binder.getCallingUserHandle());
@@ -6049,11 +6048,9 @@
     }
 
     @Override
-    public boolean destroyInputConsumer(String name) {
+    public boolean destroyInputConsumer(String name, int displayId) {
         synchronized (mWindowMap) {
-            // TODO(b/112049699): Fix this for multiple displays. For consistency with
-            // createInputConsumer above.
-            DisplayContent display = mRoot.getDisplayContent(Display.DEFAULT_DISPLAY);
+            DisplayContent display = mRoot.getDisplayContent(displayId);
             if (display != null) {
                 return display.getInputMonitor().destroyInputConsumer(name);
             }