From 6013a558262d149023b32ab175c9b885b6c5b81d Mon Sep 17 00:00:00 2001 From: Vladislav Kaznacheev Date: Tue, 29 Mar 2016 15:43:28 -0700 Subject: [PATCH] Add wallpaper input consumer to WindowManagerService This is an input consumer similar to the one used when hiding the navbar, but placed above wallpapers. It might be useful for processing touch events over "desktop" in freeform MW mode. Bug:26688904 Change-Id: I9d6d28a624f750ad48fc39f9b149dd1f989cceba --- core/java/android/view/IWindowManager.aidl | 10 ++++ .../android/server/wm/InputConsumerImpl.java | 44 ++++++--------- .../com/android/server/wm/InputMonitor.java | 15 ++++++ .../server/wm/WindowManagerService.java | 53 +++++++++++++++++-- .../server/wm/WindowSurfacePlacer.java | 4 ++ 5 files changed, 95 insertions(+), 31 deletions(-) diff --git a/core/java/android/view/IWindowManager.aidl b/core/java/android/view/IWindowManager.aidl index 7af4a1fea441d..5bcf1027f3848 100644 --- a/core/java/android/view/IWindowManager.aidl +++ b/core/java/android/view/IWindowManager.aidl @@ -400,4 +400,14 @@ interface IWindowManager * @hide */ void registerShortcutKey(in long shortcutCode, IShortcutService keySubscriber); + + /** + * Create the input consumer for wallpaper events. + */ + void createWallpaperInputConsumer(out InputChannel inputChannel); + + /** + * Remove the input consumer for wallpaper events. + */ + void removeWallpaperInputConsumer(); } diff --git a/services/core/java/com/android/server/wm/InputConsumerImpl.java b/services/core/java/com/android/server/wm/InputConsumerImpl.java index 0581a165a3743..24783bccf3d5b 100644 --- a/services/core/java/com/android/server/wm/InputConsumerImpl.java +++ b/services/core/java/com/android/server/wm/InputConsumerImpl.java @@ -16,38 +16,33 @@ package com.android.server.wm; -import android.os.Looper; import android.os.Process; import android.view.Display; import android.view.InputChannel; -import android.view.InputEventReceiver; import android.view.WindowManager; -import android.view.WindowManagerPolicy; - import com.android.server.input.InputApplicationHandle; import com.android.server.input.InputWindowHandle; -public final class InputConsumerImpl implements WindowManagerPolicy.InputConsumer { +class InputConsumerImpl { final WindowManagerService mService; final InputChannel mServerChannel, mClientChannel; final InputApplicationHandle mApplicationHandle; final InputWindowHandle mWindowHandle; - final InputEventReceiver mInputEventReceiver; - final int mWindowLayer; - public InputConsumerImpl(WindowManagerService service, Looper looper, - InputEventReceiver.Factory inputEventReceiverFactory) { - String name = "input consumer"; + InputConsumerImpl(WindowManagerService service, String name, InputChannel inputChannel) { mService = service; InputChannel[] channels = InputChannel.openInputChannelPair(name); mServerChannel = channels[0]; - mClientChannel = channels[1]; + if (inputChannel != null) { + channels[1].transferTo(inputChannel); + channels[1].dispose(); + mClientChannel = inputChannel; + } else { + mClientChannel = channels[1]; + } mService.mInputManager.registerInputChannel(mServerChannel, null); - mInputEventReceiver = inputEventReceiverFactory.createInputEventReceiver( - mClientChannel, looper); - mApplicationHandle = new InputApplicationHandle(null); mApplicationHandle.name = name; mApplicationHandle.dispatchingTimeoutNanos = @@ -57,8 +52,7 @@ public final class InputConsumerImpl implements WindowManagerPolicy.InputConsume mWindowHandle.name = name; mWindowHandle.inputChannel = mServerChannel; mWindowHandle.layoutParamsType = WindowManager.LayoutParams.TYPE_INPUT_CONSUMER; - mWindowLayer = getLayerLw(mWindowHandle.layoutParamsType); - mWindowHandle.layer = mWindowLayer; + mWindowHandle.layer = getLayerLw(mWindowHandle.layoutParamsType); mWindowHandle.layoutParamsFlags = 0; mWindowHandle.dispatchingTimeoutNanos = WindowManagerService.DEFAULT_INPUT_DISPATCHING_TIMEOUT_NANOS; @@ -81,21 +75,15 @@ public final class InputConsumerImpl implements WindowManagerPolicy.InputConsume mWindowHandle.frameBottom = dh; } - @Override - public void dismiss() { - synchronized (mService.mWindowMap) { - if (mService.removeInputConsumer()) { - mInputEventReceiver.dispose(); - mService.mInputManager.unregisterInputChannel(mServerChannel); - mClientChannel.dispose(); - mServerChannel.dispose(); - } - } - } - private int getLayerLw(int windowType) { return mService.mPolicy.windowTypeToLayerLw(windowType) * WindowManagerService.TYPE_LAYER_MULTIPLIER + WindowManagerService.TYPE_LAYER_OFFSET; } + + void disposeChannelsLw() { + mService.mInputManager.unregisterInputChannel(mServerChannel); + mClientChannel.dispose(); + mServerChannel.dispose(); + } } diff --git a/services/core/java/com/android/server/wm/InputMonitor.java b/services/core/java/com/android/server/wm/InputMonitor.java index b70218059b74b..eea0e73c1b0ba 100644 --- a/services/core/java/com/android/server/wm/InputMonitor.java +++ b/services/core/java/com/android/server/wm/InputMonitor.java @@ -282,6 +282,8 @@ final class InputMonitor implements InputManagerService.WindowManagerCallbacks { boolean addInputConsumerHandle = mService.mInputConsumer != null; + boolean addWallpaperInputConsumerHandle = mService.mWallpaperInputConsumer != null; + // Add all windows on the default display. final int numDisplays = mService.mDisplayContents.size(); final WallpaperController wallpaperController = mService.mWallpaperControllerLocked; @@ -302,6 +304,14 @@ final class InputMonitor implements InputManagerService.WindowManagerCallbacks { addInputConsumerHandle = false; } + if (addWallpaperInputConsumerHandle) { + if (child.mAttrs.type == WindowManager.LayoutParams.TYPE_WALLPAPER) { + // Add the wallpaper input consumer above the first wallpaper window. + addInputWindowHandleLw(mService.mWallpaperInputConsumer.mWindowHandle); + addWallpaperInputConsumerHandle = false; + } + } + final int flags = child.mAttrs.flags; final int privateFlags = child.mAttrs.privateFlags; final int type = child.mAttrs.type; @@ -329,6 +339,11 @@ final class InputMonitor implements InputManagerService.WindowManagerCallbacks { } } + if (addWallpaperInputConsumerHandle) { + // No wallpaper found, add the wallpaper input consumer at the end. + addInputWindowHandleLw(mService.mWallpaperInputConsumer.mWindowHandle); + } + // Send windows to native code. mService.mInputManager.setInputWindows(mInputWindowHandles); diff --git a/services/core/java/com/android/server/wm/WindowManagerService.java b/services/core/java/com/android/server/wm/WindowManagerService.java index 97c4c42dfd5d3..dcb4a63a560ae 100644 --- a/services/core/java/com/android/server/wm/WindowManagerService.java +++ b/services/core/java/com/android/server/wm/WindowManagerService.java @@ -406,6 +406,11 @@ public class WindowManagerService extends IWindowManager.Stub */ InputConsumerImpl mInputConsumer; + /** + * The input consumer added to the window manager before all wallpaper windows. + */ + InputConsumerImpl mWallpaperInputConsumer; + /** * Windows that are being resized. Used so we can tell the client about * the resize after closing the transaction in which we resized the @@ -9624,13 +9629,37 @@ public class WindowManagerService extends IWindowManager.Stub } } + private static final class HideNavInputConsumer extends InputConsumerImpl + implements WindowManagerPolicy.InputConsumer { + private final InputEventReceiver mInputEventReceiver; + + HideNavInputConsumer(WindowManagerService service, Looper looper, + InputEventReceiver.Factory inputEventReceiverFactory) { + super(service, "input consumer", null); + mInputEventReceiver = inputEventReceiverFactory.createInputEventReceiver( + mClientChannel, looper); + } + + @Override + public void dismiss() { + if (mService.removeInputConsumer()) { + synchronized (mService.mWindowMap) { + mInputEventReceiver.dispose(); + disposeChannelsLw(); + } + } + } + } + @Override - public InputConsumerImpl addInputConsumer(Looper looper, + public WindowManagerPolicy.InputConsumer addInputConsumer(Looper looper, InputEventReceiver.Factory inputEventReceiverFactory) { synchronized (mWindowMap) { - mInputConsumer = new InputConsumerImpl(this, looper, inputEventReceiverFactory); + HideNavInputConsumer inputConsumerImpl = new HideNavInputConsumer( + this, looper, inputEventReceiverFactory); + mInputConsumer = inputConsumerImpl; mInputMonitor.updateInputWindowsLw(true); - return mInputConsumer; + return inputConsumerImpl; } } @@ -9645,6 +9674,24 @@ public class WindowManagerService extends IWindowManager.Stub } } + public void createWallpaperInputConsumer(InputChannel inputChannel) { + synchronized (mWindowMap) { + mWallpaperInputConsumer = new InputConsumerImpl(this, "wallpaper input", inputChannel); + mWallpaperInputConsumer.mWindowHandle.hasWallpaper = true; + mInputMonitor.updateInputWindowsLw(true); + } + } + + public void removeWallpaperInputConsumer() { + synchronized (mWindowMap) { + if (mWallpaperInputConsumer != null) { + mWallpaperInputConsumer.disposeChannelsLw(); + mWallpaperInputConsumer = null; + mInputMonitor.updateInputWindowsLw(true); + } + } + } + @Override public boolean hasNavigationBar() { return mPolicy.hasNavigationBar(); diff --git a/services/core/java/com/android/server/wm/WindowSurfacePlacer.java b/services/core/java/com/android/server/wm/WindowSurfacePlacer.java index 3e5ddbce5a7b3..eda2f39480a8d 100644 --- a/services/core/java/com/android/server/wm/WindowSurfacePlacer.java +++ b/services/core/java/com/android/server/wm/WindowSurfacePlacer.java @@ -860,6 +860,10 @@ class WindowSurfacePlacer { mService.mInputConsumer.layout(dw, dh); } + if (mService.mWallpaperInputConsumer != null) { + mService.mWallpaperInputConsumer.layout(dw, dh); + } + final int N = windows.size(); int i;