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

Commit 6013a558 authored by Vladislav Kaznacheev's avatar Vladislav Kaznacheev
Browse files

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
parent 09d77417
Loading
Loading
Loading
Loading
+10 −0
Original line number Original line Diff line number Diff line
@@ -400,4 +400,14 @@ interface IWindowManager
     * @hide
     * @hide
     */
     */
    void registerShortcutKey(in long shortcutCode, IShortcutService keySubscriber);
    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();
}
}
+16 −28
Original line number Original line Diff line number Diff line
@@ -16,38 +16,33 @@


package com.android.server.wm;
package com.android.server.wm;


import android.os.Looper;
import android.os.Process;
import android.os.Process;
import android.view.Display;
import android.view.Display;
import android.view.InputChannel;
import android.view.InputChannel;
import android.view.InputEventReceiver;
import android.view.WindowManager;
import android.view.WindowManager;
import android.view.WindowManagerPolicy;

import com.android.server.input.InputApplicationHandle;
import com.android.server.input.InputApplicationHandle;
import com.android.server.input.InputWindowHandle;
import com.android.server.input.InputWindowHandle;


public final class InputConsumerImpl implements WindowManagerPolicy.InputConsumer {
class InputConsumerImpl {
    final WindowManagerService mService;
    final WindowManagerService mService;
    final InputChannel mServerChannel, mClientChannel;
    final InputChannel mServerChannel, mClientChannel;
    final InputApplicationHandle mApplicationHandle;
    final InputApplicationHandle mApplicationHandle;
    final InputWindowHandle mWindowHandle;
    final InputWindowHandle mWindowHandle;
    final InputEventReceiver mInputEventReceiver;
    final int mWindowLayer;


    public InputConsumerImpl(WindowManagerService service, Looper looper,
    InputConsumerImpl(WindowManagerService service, String name, InputChannel inputChannel) {
            InputEventReceiver.Factory inputEventReceiverFactory) {
        String name = "input consumer";
        mService = service;
        mService = service;


        InputChannel[] channels = InputChannel.openInputChannelPair(name);
        InputChannel[] channels = InputChannel.openInputChannelPair(name);
        mServerChannel = channels[0];
        mServerChannel = channels[0];
        if (inputChannel != null) {
            channels[1].transferTo(inputChannel);
            channels[1].dispose();
            mClientChannel = inputChannel;
        } else {
            mClientChannel = channels[1];
            mClientChannel = channels[1];
        }
        mService.mInputManager.registerInputChannel(mServerChannel, null);
        mService.mInputManager.registerInputChannel(mServerChannel, null);


        mInputEventReceiver = inputEventReceiverFactory.createInputEventReceiver(
                mClientChannel, looper);

        mApplicationHandle = new InputApplicationHandle(null);
        mApplicationHandle = new InputApplicationHandle(null);
        mApplicationHandle.name = name;
        mApplicationHandle.name = name;
        mApplicationHandle.dispatchingTimeoutNanos =
        mApplicationHandle.dispatchingTimeoutNanos =
@@ -57,8 +52,7 @@ public final class InputConsumerImpl implements WindowManagerPolicy.InputConsume
        mWindowHandle.name = name;
        mWindowHandle.name = name;
        mWindowHandle.inputChannel = mServerChannel;
        mWindowHandle.inputChannel = mServerChannel;
        mWindowHandle.layoutParamsType = WindowManager.LayoutParams.TYPE_INPUT_CONSUMER;
        mWindowHandle.layoutParamsType = WindowManager.LayoutParams.TYPE_INPUT_CONSUMER;
        mWindowLayer = getLayerLw(mWindowHandle.layoutParamsType);
        mWindowHandle.layer = getLayerLw(mWindowHandle.layoutParamsType);
        mWindowHandle.layer = mWindowLayer;
        mWindowHandle.layoutParamsFlags = 0;
        mWindowHandle.layoutParamsFlags = 0;
        mWindowHandle.dispatchingTimeoutNanos =
        mWindowHandle.dispatchingTimeoutNanos =
                WindowManagerService.DEFAULT_INPUT_DISPATCHING_TIMEOUT_NANOS;
                WindowManagerService.DEFAULT_INPUT_DISPATCHING_TIMEOUT_NANOS;
@@ -81,21 +75,15 @@ public final class InputConsumerImpl implements WindowManagerPolicy.InputConsume
        mWindowHandle.frameBottom = dh;
        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) {
    private int getLayerLw(int windowType) {
        return mService.mPolicy.windowTypeToLayerLw(windowType)
        return mService.mPolicy.windowTypeToLayerLw(windowType)
                * WindowManagerService.TYPE_LAYER_MULTIPLIER
                * WindowManagerService.TYPE_LAYER_MULTIPLIER
                + WindowManagerService.TYPE_LAYER_OFFSET;
                + WindowManagerService.TYPE_LAYER_OFFSET;
    }
    }

    void disposeChannelsLw() {
        mService.mInputManager.unregisterInputChannel(mServerChannel);
        mClientChannel.dispose();
        mServerChannel.dispose();
    }
}
}
+15 −0
Original line number Original line Diff line number Diff line
@@ -282,6 +282,8 @@ final class InputMonitor implements InputManagerService.WindowManagerCallbacks {


        boolean addInputConsumerHandle = mService.mInputConsumer != null;
        boolean addInputConsumerHandle = mService.mInputConsumer != null;


        boolean addWallpaperInputConsumerHandle = mService.mWallpaperInputConsumer != null;

        // Add all windows on the default display.
        // Add all windows on the default display.
        final int numDisplays = mService.mDisplayContents.size();
        final int numDisplays = mService.mDisplayContents.size();
        final WallpaperController wallpaperController = mService.mWallpaperControllerLocked;
        final WallpaperController wallpaperController = mService.mWallpaperControllerLocked;
@@ -302,6 +304,14 @@ final class InputMonitor implements InputManagerService.WindowManagerCallbacks {
                    addInputConsumerHandle = false;
                    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 flags = child.mAttrs.flags;
                final int privateFlags = child.mAttrs.privateFlags;
                final int privateFlags = child.mAttrs.privateFlags;
                final int type = child.mAttrs.type;
                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.
        // Send windows to native code.
        mService.mInputManager.setInputWindows(mInputWindowHandles);
        mService.mInputManager.setInputWindows(mInputWindowHandles);


+50 −3
Original line number Original line Diff line number Diff line
@@ -406,6 +406,11 @@ public class WindowManagerService extends IWindowManager.Stub
     */
     */
    InputConsumerImpl mInputConsumer;
    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
     * Windows that are being resized.  Used so we can tell the client about
     * the resize after closing the transaction in which we resized the
     * 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
    @Override
    public InputConsumerImpl addInputConsumer(Looper looper,
    public WindowManagerPolicy.InputConsumer addInputConsumer(Looper looper,
            InputEventReceiver.Factory inputEventReceiverFactory) {
            InputEventReceiver.Factory inputEventReceiverFactory) {
        synchronized (mWindowMap) {
        synchronized (mWindowMap) {
            mInputConsumer = new InputConsumerImpl(this, looper, inputEventReceiverFactory);
            HideNavInputConsumer inputConsumerImpl = new HideNavInputConsumer(
                    this, looper, inputEventReceiverFactory);
            mInputConsumer = inputConsumerImpl;
            mInputMonitor.updateInputWindowsLw(true);
            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
    @Override
    public boolean hasNavigationBar() {
    public boolean hasNavigationBar() {
        return mPolicy.hasNavigationBar();
        return mPolicy.hasNavigationBar();
+4 −0
Original line number Original line Diff line number Diff line
@@ -860,6 +860,10 @@ class WindowSurfacePlacer {
            mService.mInputConsumer.layout(dw, dh);
            mService.mInputConsumer.layout(dw, dh);
        }
        }


        if (mService.mWallpaperInputConsumer != null) {
            mService.mWallpaperInputConsumer.layout(dw, dh);
        }

        final int N = windows.size();
        final int N = windows.size();
        int i;
        int i;