DO NOT MERGE: WM: Only allow system to use NO_INPUT_CHANNEL.

NO_INPUT_CHANNEL is a hidden WM flag that allows creation of a window
without an input channel. Unfortunately in releases prior to Android R
this would allow creation of a Window which will not be known to the
InputDispatcher at all. This means that the logic generating
FLAG_OBSCURED will work and a window will be able to overlay another
window without the overlayed window being notified. In Android R and
later this isn't a problem as the InputDispatcher is informed of all
windows, input channel or not. For past Android releases, this patch
disables NO_INPUT_CHANNEL for use outside of the WM.

Bug: 152064592
Test: Existing tests pass
Change-Id: I7e1f45cba139eab92e7df88d1e052baba0ae2cc6
(cherry picked from commit 514b3297768f4a7469117a7005556663124040f9)
diff --git a/core/java/android/view/InputChannel.java b/core/java/android/view/InputChannel.java
index ecb727c..346628b 100644
--- a/core/java/android/view/InputChannel.java
+++ b/core/java/android/view/InputChannel.java
@@ -111,6 +111,13 @@
     }
 
     /**
+     * @hide
+     */
+    public boolean isValid() {
+        return mPtr != 0;
+    }
+
+    /**
      * Disposes the input channel.
      * Explicitly releases the reference this object is holding on the input channel.
      * When all references are released, the input channel will be closed.
diff --git a/core/java/android/view/ViewRootImpl.java b/core/java/android/view/ViewRootImpl.java
index aceb276..735678c 100644
--- a/core/java/android/view/ViewRootImpl.java
+++ b/core/java/android/view/ViewRootImpl.java
@@ -851,10 +851,7 @@
                 // manager, to make sure we do the relayout before receiving
                 // any other events from the system.
                 requestLayout();
-                if ((mWindowAttributes.inputFeatures
-                        & WindowManager.LayoutParams.INPUT_FEATURE_NO_INPUT_CHANNEL) == 0) {
-                    mInputChannel = new InputChannel();
-                }
+		mInputChannel = new InputChannel();
                 mForceDecorViewVisibility = (mWindowAttributes.privateFlags
                         & PRIVATE_FLAG_FORCE_DECOR_VIEW_VISIBILITY) != 0;
                 try {
@@ -947,7 +944,7 @@
                     mInputQueueCallback =
                         ((RootViewSurfaceTaker)view).willYouTakeTheInputQueue();
                 }
-                if (mInputChannel != null) {
+                if (mInputChannel.isValid()) {
                     if (mInputQueueCallback != null) {
                         mInputQueue = new InputQueue();
                         mInputQueueCallback.onInputQueueCreated(mInputQueue);
diff --git a/services/core/java/com/android/server/wm/WindowManagerService.java b/services/core/java/com/android/server/wm/WindowManagerService.java
index 2de8ae1..11e89fb 100644
--- a/services/core/java/com/android/server/wm/WindowManagerService.java
+++ b/services/core/java/com/android/server/wm/WindowManagerService.java
@@ -1441,8 +1441,13 @@
                 return res;
             }
 
-            final boolean openInputChannels = (outInputChannel != null
-                    && (attrs.inputFeatures & INPUT_FEATURE_NO_INPUT_CHANNEL) == 0);
+            boolean openInputChannels = (outInputChannel != null
+                && (attrs.inputFeatures & INPUT_FEATURE_NO_INPUT_CHANNEL) == 0);
+            if (callingUid != SYSTEM_UID) {
+                Slog.e(TAG_WM,
+                    "App trying to use insecure INPUT_FEATURE_NO_INPUT_CHANNEL flag. Ignoring");
+                openInputChannels = true;
+            }
             if  (openInputChannels) {
                 win.openInputChannel(outInputChannel);
             }