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();