VirtualDisplay wrapper with input forwarding
New version of ActivityView that doesn't use expensive
ActivityContainer, but utilizes VirtualDisplays instead.
Creation of this view is only allowed for callers who have
android.Manifest.permission.INJECT_EVENTS permission.
Launching activities into this container is restricted by
the same rules that apply to launching on VirtualDisplays:
- Owner is allowed to launch its own activities.
- If activity that's being launched is not from the same
app, then it must be embeddable and launcher must have
permission to embed.
Bug: 63338670
Test: go/wm-smoke
Change-Id: Id9a25752367ebe8e59d2fc21c5d9de5cf597ea01
diff --git a/services/core/java/com/android/server/input/InputManagerService.java b/services/core/java/com/android/server/input/InputManagerService.java
index 717efbf..fa9b107 100644
--- a/services/core/java/com/android/server/input/InputManagerService.java
+++ b/services/core/java/com/android/server/input/InputManagerService.java
@@ -37,6 +37,7 @@
import org.xmlpull.v1.XmlPullParser;
import android.Manifest;
+import android.app.IInputForwarder;
import android.app.Notification;
import android.app.NotificationManager;
import android.app.PendingIntent;
@@ -57,6 +58,7 @@
import android.content.res.TypedArray;
import android.content.res.XmlResourceParser;
import android.database.ContentObserver;
+import android.hardware.display.DisplayManager;
import android.hardware.display.DisplayViewport;
import android.hardware.input.IInputDevicesChangedListener;
import android.hardware.input.IInputManager;
@@ -85,6 +87,7 @@
import android.util.Slog;
import android.util.SparseArray;
import android.util.Xml;
+import android.view.Display;
import android.view.IInputFilter;
import android.view.IInputFilterHost;
import android.view.IWindow;
@@ -1862,6 +1865,29 @@
nativeMonitor(mPtr);
}
+ // Binder call
+ @Override
+ public IInputForwarder createInputForwarder(int displayId) throws RemoteException {
+ if (!checkCallingPermission(android.Manifest.permission.INJECT_EVENTS,
+ "createInputForwarder()")) {
+ throw new SecurityException("Requires INJECT_EVENTS permission");
+ }
+ final DisplayManager displayManager = mContext.getSystemService(DisplayManager.class);
+ final Display display = displayManager.getDisplay(displayId);
+ if (display == null) {
+ throw new IllegalArgumentException(
+ "Can't create input forwarder for non-existent displayId: " + displayId);
+ }
+ final int callingUid = Binder.getCallingUid();
+ final int displayOwnerUid = display.getOwnerUid();
+ if (callingUid != displayOwnerUid) {
+ throw new SecurityException(
+ "Only owner of the display can forward input events to it.");
+ }
+
+ return new InputForwarder(displayId);
+ }
+
// Native callback.
private void notifyConfigurationChanged(long whenNanos) {
mWindowManagerCallbacks.notifyConfigurationChanged();