Add uniqueId to Virtual Display and pass through to inputflinger (1/2)

This CL adds:
1) Adds uniqueId (protected via system/sig permission) to virtual
displays.
2) Add support for N virtual display viewports into inputflinger.
3) Set the virtual display's viewports in inputflinger if it has the
uniqueId value set to non-null. (a) Moving the new viewport from java to
native inputflinger and (b) adding "uniqueId" value to viewports makes
up the great majority of this change.
4) From the inputflinger side, we also read in a new value from the
input device configuration files called 'touch.displayId'.
5) When touch.displayId and the virtual display's uniqueId match,
inputflinger links the two.

Test: Start VR and ensure that the virtual viewport shows up when running
'adb shell dump input".  Run a VR app, and ensure that the virtual input
device is associated with the new virtual viewport.
Test: com.android.server.display.DisplayManagerServiceTest

Bug: 36051620
Change-Id: Ic2117eb8e19f7f3c59687160591f8bc6692c1f12
diff --git a/services/core/jni/com_android_server_input_InputManagerService.cpp b/services/core/jni/com_android_server_input_InputManagerService.cpp
index 14a2381..41f86c9 100644
--- a/services/core/jni/com_android_server_input_InputManagerService.cpp
+++ b/services/core/jni/com_android_server_input_InputManagerService.cpp
@@ -58,6 +58,7 @@
 #include "com_android_server_power_PowerManagerService.h"
 #include "com_android_server_input_InputApplicationHandle.h"
 #include "com_android_server_input_InputWindowHandle.h"
+#include "android_hardware_display_DisplayViewport.h"
 
 #define INDENT "  "
 
@@ -196,7 +197,8 @@
 
     void dump(String8& dump);
 
-    void setDisplayViewport(bool external, const DisplayViewport& viewport);
+    void setVirtualDisplayViewports(JNIEnv* env, jobjectArray viewportObjArray);
+    void setDisplayViewport(int32_t viewportType, const DisplayViewport& viewport);
 
     status_t registerInputChannel(JNIEnv* env, const sp<InputChannel>& inputChannel,
             const sp<InputWindowHandle>& inputWindowHandle, bool monitor);
@@ -271,6 +273,7 @@
         // Display size information.
         DisplayViewport internalViewport;
         DisplayViewport externalViewport;
+        Vector<DisplayViewport> virtualViewports;
 
         // System UI visibility.
         int32_t systemUiVisibility;
@@ -375,17 +378,53 @@
     return false;
 }
 
-void NativeInputManager::setDisplayViewport(bool external, const DisplayViewport& viewport) {
+void NativeInputManager::setVirtualDisplayViewports(JNIEnv* env, jobjectArray viewportObjArray) {
+    Vector<DisplayViewport> viewports;
+
+    if (viewportObjArray) {
+        jsize length = env->GetArrayLength(viewportObjArray);
+        for (jsize i = 0; i < length; i++) {
+            jobject viewportObj = env->GetObjectArrayElement(viewportObjArray, i);
+            if (! viewportObj) {
+                break; // found null element indicating end of used portion of the array
+            }
+
+            DisplayViewport viewport;
+            android_hardware_display_DisplayViewport_toNative(env, viewportObj, &viewport);
+            ALOGI("Viewport [%d] to add: %s", (int) length, viewport.uniqueId.c_str());
+            viewports.push(viewport);
+
+            env->DeleteLocalRef(viewportObj);
+        }
+    }
+
+    {
+        AutoMutex _l(mLock);
+        mLocked.virtualViewports = viewports;
+    }
+
+    mInputManager->getReader()->requestRefreshConfiguration(
+            InputReaderConfiguration::CHANGE_DISPLAY_INFO);
+}
+
+void NativeInputManager::setDisplayViewport(int32_t type, const DisplayViewport& viewport) {
     bool changed = false;
     {
         AutoMutex _l(mLock);
 
-        DisplayViewport& v = external ? mLocked.externalViewport : mLocked.internalViewport;
-        if (v != viewport) {
-            changed = true;
-            v = viewport;
+        ViewportType viewportType = static_cast<ViewportType>(type);
+        DisplayViewport* v = NULL;
+        if (viewportType == ViewportType::VIEWPORT_EXTERNAL) {
+            v = &mLocked.externalViewport;
+        } else if (viewportType == ViewportType::VIEWPORT_INTERNAL) {
+            v = &mLocked.internalViewport;
+        }
 
-            if (!external) {
+        if (v != NULL && *v != viewport) {
+            changed = true;
+            *v = viewport;
+
+            if (viewportType == ViewportType::VIEWPORT_INTERNAL) {
                 sp<PointerController> controller = mLocked.pointerController.promote();
                 if (controller != NULL) {
                     controller->setDisplayViewport(
@@ -478,8 +517,11 @@
 
         outConfig->pointerCapture = mLocked.pointerCapture;
 
-        outConfig->setDisplayInfo(false /*external*/, mLocked.internalViewport);
-        outConfig->setDisplayInfo(true /*external*/, mLocked.externalViewport);
+        outConfig->setPhysicalDisplayViewport(ViewportType::VIEWPORT_INTERNAL,
+                mLocked.internalViewport);
+        outConfig->setPhysicalDisplayViewport(ViewportType::VIEWPORT_EXTERNAL,
+                mLocked.externalViewport);
+        outConfig->setVirtualDisplayViewports(mLocked.virtualViewports);
 
         outConfig->disabledDevices = mLocked.disabledInputDevices;
     } // release lock
@@ -1183,11 +1225,17 @@
     }
 }
 
-static void nativeSetDisplayViewport(JNIEnv* /* env */, jclass /* clazz */, jlong ptr,
-        jboolean external, jint displayId, jint orientation,
+static void nativeSetVirtualDisplayViewports(JNIEnv* env, jclass /* clazz */, jlong ptr,
+        jobjectArray viewportObjArray) {
+    NativeInputManager* im = reinterpret_cast<NativeInputManager*>(ptr);
+    im->setVirtualDisplayViewports(env, viewportObjArray);
+}
+
+static void nativeSetDisplayViewport(JNIEnv* env, jclass /* clazz */, jlong ptr,
+        jint viewportType, jint displayId, jint orientation,
         jint logicalLeft, jint logicalTop, jint logicalRight, jint logicalBottom,
         jint physicalLeft, jint physicalTop, jint physicalRight, jint physicalBottom,
-        jint deviceWidth, jint deviceHeight) {
+        jint deviceWidth, jint deviceHeight, jstring uniqueId) {
     NativeInputManager* im = reinterpret_cast<NativeInputManager*>(ptr);
 
     DisplayViewport v;
@@ -1203,7 +1251,11 @@
     v.physicalBottom = physicalBottom;
     v.deviceWidth = deviceWidth;
     v.deviceHeight = deviceHeight;
-    im->setDisplayViewport(external, v);
+    if (uniqueId != nullptr) {
+        v.uniqueId.setTo(ScopedUtfChars(env, uniqueId).c_str());
+    }
+
+    im->setDisplayViewport(viewportType, v);
 }
 
 static jint nativeGetScanCodeState(JNIEnv* /* env */, jclass /* clazz */,
@@ -1574,7 +1626,9 @@
             (void*) nativeInit },
     { "nativeStart", "(J)V",
             (void*) nativeStart },
-    { "nativeSetDisplayViewport", "(JZIIIIIIIIIIII)V",
+    { "nativeSetVirtualDisplayViewports", "(J[Landroid/hardware/display/DisplayViewport;)V",
+            (void*) nativeSetVirtualDisplayViewports },
+    { "nativeSetDisplayViewport", "(JIIIIIIIIIIIIILjava/lang/String;)V",
             (void*) nativeSetDisplayViewport },
     { "nativeGetScanCodeState", "(JIII)I",
             (void*) nativeGetScanCodeState },