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

Commit b37e35e4 authored by Arthur Hung's avatar Arthur Hung
Browse files

Fix WM input limitations on secondary displays (2/N)

One DisplayContent contains one InputMonitor now.
- Change setInputWindow of InputManagerService to carry displayId,
  so InputWindowHandle can be updated by each DisplayContent.
- Only one focus in current, so reference the WMS current focus,
  need changed in focus of multi-display patch.
- Change InputConsumerController can just create in default display,
  need consider more behaviors about adding to another display.

Bug: 111363643
Test: atest WindowManagerSmokeTest ActivityManagerMultiDisplayTests
Test: atest libinput_tests inputflinger_tests
Change-Id: I336945abdd36a543207e15650264280b04253eef
parent 5293635e
Loading
Loading
Loading
Loading
+4 −3
Original line number Diff line number Diff line
@@ -212,7 +212,8 @@ public class InputManagerService extends IInputManager.Stub
            int injectorPid, int injectorUid, int syncMode, int timeoutMillis,
            int policyFlags);
    private static native void nativeToggleCapsLock(long ptr, int deviceId);
    private static native void nativeSetInputWindows(long ptr, InputWindowHandle[] windowHandles);
    private static native void nativeSetInputWindows(long ptr, InputWindowHandle[] windowHandles,
            int displayId);
    private static native void nativeSetInputDispatchMode(long ptr, boolean enabled, boolean frozen);
    private static native void nativeSetSystemUiVisibility(long ptr, int visibility);
    private static native void nativeSetFocusedApplication(long ptr,
@@ -1467,7 +1468,7 @@ public class InputManagerService extends IInputManager.Stub
    }

    public void setInputWindows(InputWindowHandle[] windowHandles,
            InputWindowHandle focusedWindowHandle) {
            InputWindowHandle focusedWindowHandle, int displayId) {
        final IWindow newFocusedWindow =
            focusedWindowHandle != null ? focusedWindowHandle.clientWindow : null;
        if (mFocusedWindow != newFocusedWindow) {
@@ -1476,7 +1477,7 @@ public class InputManagerService extends IInputManager.Stub
                setPointerCapture(false);
            }
        }
        nativeSetInputWindows(mPtr, windowHandles);
        nativeSetInputWindows(mPtr, windowHandles, displayId);
    }

    public void setFocusedApplication(InputApplicationHandle application) {
+2 −3
Original line number Diff line number Diff line
@@ -814,9 +814,7 @@ class DisplayContent extends WindowContainer<DisplayContent.DisplayChildWindowCo
        // {@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() {
@@ -2134,6 +2132,7 @@ class DisplayContent extends WindowContainer<DisplayContent.DisplayChildWindowCo
            mRemovingDisplay = false;
        }

        mInputMonitor.onRemoved();
        mService.onDisplayRemoved(mDisplayId);
    }

+0 −1
Original line number Diff line number Diff line
@@ -20,7 +20,6 @@ import android.os.IBinder;
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;
+12 −5
Original line number Diff line number Diff line
@@ -367,6 +367,13 @@ final class InputMonitor {
        }
    }

    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 @@ final class InputMonitor {
            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 @@ final class InputMonitor {
            }

            // 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 class InputMonitor {
            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 for all display in current.
            final boolean hasFocus = w == mService.mCurrentFocus;//mInputFocus;
            final boolean isVisible = w.isVisibleLw();

            if (mAddRecentsAnimationInputConsumerHandle) {
+9 −14
Original line number Diff line number Diff line
@@ -6070,26 +6070,21 @@ public class WindowManagerService extends IWindowManager.Stub
    @Override
    public void createInputConsumer(IBinder token, String name, 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);
            if (display != null) {
                display.getInputMonitor().createInputConsumer(token, name, inputChannel,
            // TODO(b/112049699): multi-display inputConsumer, just support default in current.
            // Need consider about the behavior from controller.
            DisplayContent displayContent = getDefaultDisplayContentLocked();
            displayContent.getInputMonitor().createInputConsumer(token, name, inputChannel,
                    Binder.getCallingPid(), Binder.getCallingUserHandle());
        }
    }
    }

    @Override
    public boolean destroyInputConsumer(String name) {
        synchronized (mWindowMap) {
            // TODO(b/112049699): Fix this for multiple displays. For consistency with
            // createInputConsumer above.
            DisplayContent display = mRoot.getDisplayContent(Display.DEFAULT_DISPLAY);
            if (display != null) {
                return display.getInputMonitor().destroyInputConsumer(name);
            }
            return false;
            // TODO(b/112049699): multi-display inputConsumer, just support default in current.
            // Need consider about the behavior from controller.
            DisplayContent displayContent = getDefaultDisplayContentLocked();
            return displayContent.getInputMonitor().destroyInputConsumer(name);
        }
    }

Loading