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

Commit 0d50d866 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.

Re-landing I9d6d28a624f750ad48fc39f9b149dd1f989cceba after fixing build.

Bug:26688904
Change-Id: I89fdabd9c72cdd4a1d7ca626c33ddc99ddea97f9
parent 1b8189d8
Loading
Loading
Loading
Loading
+10 −0
Original line number Diff line number Diff line
@@ -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();
}
+16 −28
Original line number Diff line number Diff line
@@ -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];
        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();
    }
}
+15 −0
Original line number Diff line number Diff line
@@ -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);

+50 −3
Original line number Diff line number Diff line
@@ -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();
+4 −0
Original line number Diff line number Diff line
@@ -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;

Loading