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: Winson Chung <winsonc@google.com>
diff --git a/core/java/android/view/IWindowManager.aidl b/core/java/android/view/IWindowManager.aidl
index 6e49bac..d62eab9 100644
--- a/core/java/android/view/IWindowManager.aidl
+++ b/core/java/android/view/IWindowManager.aidl
@@ -385,7 +385,7 @@
/**
* 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
diff --git a/packages/SystemUI/src/com/android/systemui/pip/phone/InputConsumerController.java b/packages/SystemUI/src/com/android/systemui/pip/phone/InputConsumerController.java
index e6d6c55..db4f988 100644
--- a/packages/SystemUI/src/com/android/systemui/pip/phone/InputConsumerController.java
+++ b/packages/SystemUI/src/com/android/systemui/pip/phone/InputConsumerController.java
@@ -18,6 +18,8 @@
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 @@
}
}
- private IWindowManager mWindowManager;
+ private final IWindowManager mWindowManager;
+ private final IBinder mToken;
private PipInputEventReceiver mInputEventReceiver;
private TouchListener mListener;
@@ -85,6 +88,7 @@
public InputConsumerController(IWindowManager windowManager) {
mWindowManager = windowManager;
+ mToken = new Binder();
registerInputConsumer();
}
@@ -122,7 +126,7 @@
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);
}
diff --git a/services/core/java/com/android/server/wm/InputConsumerImpl.java b/services/core/java/com/android/server/wm/InputConsumerImpl.java
index 36753b7..d40db8c 100644
--- a/services/core/java/com/android/server/wm/InputConsumerImpl.java
+++ b/services/core/java/com/android/server/wm/InputConsumerImpl.java
@@ -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 @@
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 @@
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);
}
}
diff --git a/services/core/java/com/android/server/wm/InputMonitor.java b/services/core/java/com/android/server/wm/InputMonitor.java
index 238cb9f..35f1cb4 100644
--- a/services/core/java/com/android/server/wm/InputMonitor.java
+++ b/services/core/java/com/android/server/wm/InputMonitor.java
@@ -25,6 +25,7 @@
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 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.InputEventReceiver;
import android.view.KeyEvent;
import android.view.WindowManager;
-
import android.view.WindowManagerPolicy;
import com.android.server.input.InputApplicationHandle;
@@ -106,8 +109,9 @@
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 @@
private void addInputConsumer(String name, InputConsumerImpl consumer) {
mInputConsumers.put(name, consumer);
+ consumer.linkToDeathRecipient();
updateInputWindowsLw(true /* force */);
}
@@ -166,17 +171,20 @@
}
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 @@
if (!inputConsumerKeys.isEmpty()) {
pw.println(prefix + "InputConsumers:");
for (String key : inputConsumerKeys) {
- pw.println(prefix + " name=" + key);
+ mInputConsumers.get(key).dump(pw, key, prefix);
}
}
}
diff --git a/services/core/java/com/android/server/wm/WindowManagerService.java b/services/core/java/com/android/server/wm/WindowManagerService.java
index ad6fc39..c7dac62 100644
--- a/services/core/java/com/android/server/wm/WindowManagerService.java
+++ b/services/core/java/com/android/server/wm/WindowManagerService.java
@@ -6253,9 +6253,10 @@
}
@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());
}
}