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.

Re-landing I9d6d28a624f750ad48fc39f9b149dd1f989cceba after fixing build.

Bug:26688904
Change-Id: I89fdabd9c72cdd4a1d7ca626c33ddc99ddea97f9
This commit is contained in:
Vladislav Kaznacheev
2016-03-29 15:43:28 -07:00
parent 1b8189d825
commit 0d50d8660d
6 changed files with 101 additions and 31 deletions

View File

@@ -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();
}

View File

@@ -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();
}
}

View File

@@ -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);

View File

@@ -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();

View File

@@ -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;

View File

@@ -575,4 +575,10 @@ public class IWindowManagerImpl implements IWindowManager {
@Override
public void registerShortcutKey(long shortcutCode, IShortcutService service)
throws RemoteException {}
@Override
public void createWallpaperInputConsumer(InputChannel inputChannel) throws RemoteException {}
@Override
public void removeWallpaperInputConsumer() throws RemoteException {}
}