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

Commit 6463c362 authored by Winson Chung's avatar Winson Chung
Browse files

Cleaning up InputConsumers



- Log the pid and user handle for the client input consumer
- Pass token to WMS to ensure that it is notified when the client input
  consumer process is killed

Bug: 37309537
Test: android.server.am.ActivityManagerPinnedStackTests
Change-Id: I432d96b1f524ab34dbbad3eeb67d996abdd5f4ca
Signed-off-by: default avatarWinson Chung <winsonc@google.com>
parent 35c1a5d5
Loading
Loading
Loading
Loading
+1 −1
Original line number Diff line number Diff line
@@ -385,7 +385,7 @@ interface IWindowManager
    /**
     * Create an input consumer by name.
     */
    void createInputConsumer(String name, out InputChannel inputChannel);
    void createInputConsumer(IBinder token, String name, out InputChannel inputChannel);

    /**
     * Destroy an input consumer by name.  This method will also dispose the input channels
+6 −2
Original line number Diff line number Diff line
@@ -18,6 +18,8 @@ package com.android.systemui.pip.phone;

import static android.view.WindowManager.INPUT_CONSUMER_PIP;

import android.os.Binder;
import android.os.IBinder;
import android.os.Looper;
import android.os.RemoteException;
import android.util.Log;
@@ -77,7 +79,8 @@ public class InputConsumerController {
        }
    }

    private IWindowManager mWindowManager;
    private final IWindowManager mWindowManager;
    private final IBinder mToken;

    private PipInputEventReceiver mInputEventReceiver;
    private TouchListener mListener;
@@ -85,6 +88,7 @@ public class InputConsumerController {

    public InputConsumerController(IWindowManager windowManager) {
        mWindowManager = windowManager;
        mToken = new Binder();
        registerInputConsumer();
    }

@@ -122,7 +126,7 @@ public class InputConsumerController {
            final InputChannel inputChannel = new InputChannel();
            try {
                mWindowManager.destroyInputConsumer(INPUT_CONSUMER_PIP);
                mWindowManager.createInputConsumer(INPUT_CONSUMER_PIP, inputChannel);
                mWindowManager.createInputConsumer(mToken, INPUT_CONSUMER_PIP, inputChannel);
            } catch (RemoteException e) {
                Log.e(TAG, "Failed to create PIP input consumer", e);
            }
+51 −2
Original line number Diff line number Diff line
@@ -16,21 +16,36 @@

package com.android.server.wm;

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;
import com.android.server.input.InputWindowHandle;

class InputConsumerImpl {
import java.io.PrintWriter;

class InputConsumerImpl implements IBinder.DeathRecipient {
    final WindowManagerService mService;
    final InputChannel mServerChannel, mClientChannel;
    final InputApplicationHandle mApplicationHandle;
    final InputWindowHandle mWindowHandle;

    InputConsumerImpl(WindowManagerService service, String name, InputChannel inputChannel) {
    final IBinder mToken;
    final String mName;
    final int mClientPid;
    final UserHandle mClientUser;

    InputConsumerImpl(WindowManagerService service, IBinder token, String name,
            InputChannel inputChannel, int clientPid, UserHandle clientUser) {
        mService = service;
        mToken = token;
        mName = name;
        mClientPid = clientPid;
        mClientUser = clientUser;

        InputChannel[] channels = InputChannel.openInputChannelPair(name);
        mServerChannel = channels[0];
@@ -68,6 +83,26 @@ class InputConsumerImpl {
        mWindowHandle.scaleFactor = 1.0f;
    }

    void linkToDeathRecipient() {
        if (mToken == null) {
            return;
        }

        try {
            mToken.linkToDeath(this, 0);
        } catch (RemoteException e) {
            // Client died, do nothing
        }
    }

    void unlinkFromDeathRecipient() {
        if (mToken == null) {
            return;
        }

        mToken.unlinkToDeath(this, 0);
    }

    void layout(int dw, int dh) {
        mWindowHandle.touchableRegion.set(0, 0, dw, dh);
        mWindowHandle.frameLeft = 0;
@@ -86,5 +121,19 @@ class InputConsumerImpl {
        mService.mInputManager.unregisterInputChannel(mServerChannel);
        mClientChannel.dispose();
        mServerChannel.dispose();
        unlinkFromDeathRecipient();
    }

    @Override
    public void binderDied() {
        synchronized (mService.getWindowManagerLock()) {
            // Clean up the input consumer
            mService.mInputMonitor.destroyInputConsumer(mName);
            unlinkFromDeathRecipient();
        }
    }

    void dump(PrintWriter pw, String name, String prefix) {
        pw.println(prefix + "  name=" + name + " pid=" + mClientPid + " user=" + mClientUser);
    }
}
+15 −7
Original line number Diff line number Diff line
@@ -25,6 +25,7 @@ import static android.view.WindowManager.LayoutParams.PRIVATE_FLAG_DISABLE_WALLP
import static android.view.WindowManager.LayoutParams.PRIVATE_FLAG_KEYGUARD;
import static android.view.WindowManager.LayoutParams.TYPE_APPLICATION_OVERLAY;
import static android.view.WindowManager.LayoutParams.TYPE_WALLPAPER;

import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_DRAG;
import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_FOCUS_LIGHT;
import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_INPUT;
@@ -34,8 +35,11 @@ import static com.android.server.wm.WindowManagerDebugConfig.TAG_WM;
import android.app.ActivityManager;
import android.graphics.Rect;
import android.os.Debug;
import android.os.IBinder;
import android.os.Looper;
import android.os.Process;
import android.os.RemoteException;
import android.os.UserHandle;
import android.util.ArrayMap;
import android.util.Log;
import android.util.Slog;
@@ -43,7 +47,6 @@ import android.view.InputChannel;
import android.view.InputEventReceiver;
import android.view.KeyEvent;
import android.view.WindowManager;

import android.view.WindowManagerPolicy;

import com.android.server.input.InputApplicationHandle;
@@ -106,8 +109,9 @@ final class InputMonitor implements InputManagerService.WindowManagerCallbacks {

        EventReceiverInputConsumer(WindowManagerService service, InputMonitor monitor,
                                   Looper looper, String name,
                                   InputEventReceiver.Factory inputEventReceiverFactory) {
            super(service, name, null);
                                   InputEventReceiver.Factory inputEventReceiverFactory,
                                   int clientPid, UserHandle clientUser) {
            super(service, null /* token */, name, null /* inputChannel */, clientPid, clientUser);
            mInputMonitor = monitor;
            mInputEventReceiver = inputEventReceiverFactory.createInputEventReceiver(
                    mClientChannel, looper);
@@ -129,6 +133,7 @@ final class InputMonitor implements InputManagerService.WindowManagerCallbacks {

    private void addInputConsumer(String name, InputConsumerImpl consumer) {
        mInputConsumers.put(name, consumer);
        consumer.linkToDeathRecipient();
        updateInputWindowsLw(true /* force */);
    }

@@ -166,17 +171,20 @@ final class InputMonitor implements InputManagerService.WindowManagerCallbacks {
        }

        final EventReceiverInputConsumer consumer = new EventReceiverInputConsumer(mService,
                this, looper, name, inputEventReceiverFactory);
                this, looper, name, inputEventReceiverFactory, Process.myPid(),
                UserHandle.SYSTEM);
        addInputConsumer(name, consumer);
        return consumer;
    }

    void createInputConsumer(String name, InputChannel inputChannel) {
    void createInputConsumer(IBinder token, String name, InputChannel inputChannel, int clientPid,
            UserHandle clientUser) {
        if (mInputConsumers.containsKey(name)) {
            throw new IllegalStateException("Existing input consumer found with name: " + name);
        }

        final InputConsumerImpl consumer = new InputConsumerImpl(mService, name, inputChannel);
        final InputConsumerImpl consumer = new InputConsumerImpl(mService, token, name,
                inputChannel, clientPid, clientUser);
        switch (name) {
            case INPUT_CONSUMER_WALLPAPER:
                consumer.mWindowHandle.hasWallpaper = true;
@@ -592,7 +600,7 @@ final class InputMonitor implements InputManagerService.WindowManagerCallbacks {
        if (!inputConsumerKeys.isEmpty()) {
            pw.println(prefix + "InputConsumers:");
            for (String key : inputConsumerKeys) {
                pw.println(prefix + "  name=" + key);
                mInputConsumers.get(key).dump(pw, key, prefix);
            }
        }
    }
+3 −2
Original line number Diff line number Diff line
@@ -6253,9 +6253,10 @@ public class WindowManagerService extends IWindowManager.Stub
    }

    @Override
    public void createInputConsumer(String name, InputChannel inputChannel) {
    public void createInputConsumer(IBinder token, String name, InputChannel inputChannel) {
        synchronized (mWindowMap) {
            mInputMonitor.createInputConsumer(name, inputChannel);
            mInputMonitor.createInputConsumer(token, name, inputChannel, Binder.getCallingPid(),
                    Binder.getCallingUserHandle());
        }
    }