Allow windowhandles with NO_INPUT_CHANNEL

This allows container surfaces to be considered visible in
InputDispatcher and prevent touches from passing through them. In
particular this is used by ActivityRecordInputSink to block touches that
would otherwise pass through the area available to the activity.

Bug: 194480991
Bug: 222292477
Test: Manually tested that blocking still works
Test: atest android.server.wm.WindowUntrustedTouchTest
Test: atest InputSurfacesTest
Change-Id: Icb419d6c61d63eeeda4b6a9ad725cd4829fd6fc8
diff --git a/libs/gui/tests/EndToEndNativeInputTest.cpp b/libs/gui/tests/EndToEndNativeInputTest.cpp
index fcfe21b..e69fc78 100644
--- a/libs/gui/tests/EndToEndNativeInputTest.cpp
+++ b/libs/gui/tests/EndToEndNativeInputTest.cpp
@@ -76,16 +76,30 @@
 
 class InputSurface {
 public:
-    InputSurface(const sp<SurfaceControl> &sc, int width, int height) {
+    InputSurface(const sp<SurfaceControl> &sc, int width, int height, bool noInputChannel = false) {
         mSurfaceControl = sc;
 
         mInputFlinger = getInputFlinger();
-        mClientChannel = std::make_shared<InputChannel>();
-        mInputFlinger->createInputChannel("testchannels", mClientChannel.get());
+        if (noInputChannel) {
+            mInputInfo.setInputConfig(WindowInfo::InputConfig::NO_INPUT_CHANNEL, true);
+        } else {
+            mClientChannel = std::make_shared<InputChannel>();
+            mInputFlinger->createInputChannel("testchannels", mClientChannel.get());
+            mInputInfo.token = mClientChannel->getConnectionToken();
+            mInputConsumer = new InputConsumer(mClientChannel);
+        }
 
-        populateInputInfo(width, height);
+        mInputInfo.name = "Test info";
+        mInputInfo.dispatchingTimeout = 5s;
+        mInputInfo.globalScaleFactor = 1.0;
+        mInputInfo.touchableRegion.orSelf(Rect(0, 0, width, height));
 
-        mInputConsumer = new InputConsumer(mClientChannel);
+        InputApplicationInfo aInfo;
+        aInfo.token = new BBinder();
+        aInfo.name = "Test app info";
+        aInfo.dispatchingTimeoutMillis =
+                std::chrono::duration_cast<std::chrono::milliseconds>(DISPATCHING_TIMEOUT).count();
+        mInputInfo.applicationInfo = aInfo;
     }
 
     static std::unique_ptr<InputSurface> makeColorInputSurface(const sp<SurfaceComposerClient> &scc,
@@ -114,6 +128,16 @@
         return std::make_unique<InputSurface>(surfaceControl, width, height);
     }
 
+    static std::unique_ptr<InputSurface> makeContainerInputSurfaceNoInputChannel(
+            const sp<SurfaceComposerClient> &scc, int width, int height) {
+        sp<SurfaceControl> surfaceControl =
+                scc->createSurface(String8("Test Container Surface"), 100 /* height */,
+                                   100 /* width */, PIXEL_FORMAT_RGBA_8888,
+                                   ISurfaceComposerClient::eFXSurfaceContainer);
+        return std::make_unique<InputSurface>(surfaceControl, width, height,
+                                              true /* noInputChannel */);
+    }
+
     static std::unique_ptr<InputSurface> makeCursorInputSurface(
             const sp<SurfaceComposerClient> &scc, int width, int height) {
         sp<SurfaceControl> surfaceControl =
@@ -219,7 +243,9 @@
     }
 
     virtual ~InputSurface() {
-        mInputFlinger->removeInputChannel(mClientChannel->getConnectionToken());
+        if (mClientChannel) {
+            mInputFlinger->removeInputChannel(mClientChannel->getConnectionToken());
+        }
     }
 
     virtual void doTransaction(
@@ -263,21 +289,6 @@
         poll(&fd, 1, timeoutMs);
     }
 
-    void populateInputInfo(int width, int height) {
-        mInputInfo.token = mClientChannel->getConnectionToken();
-        mInputInfo.name = "Test info";
-        mInputInfo.dispatchingTimeout = 5s;
-        mInputInfo.globalScaleFactor = 1.0;
-        mInputInfo.touchableRegion.orSelf(Rect(0, 0, width, height));
-
-        InputApplicationInfo aInfo;
-        aInfo.token = new BBinder();
-        aInfo.name = "Test app info";
-        aInfo.dispatchingTimeoutMillis =
-                std::chrono::duration_cast<std::chrono::milliseconds>(DISPATCHING_TIMEOUT).count();
-
-        mInputInfo.applicationInfo = aInfo;
-    }
 public:
     sp<SurfaceControl> mSurfaceControl;
     std::shared_ptr<InputChannel> mClientChannel;
@@ -1085,6 +1096,23 @@
     EXPECT_EQ(containerSurface->consumeEvent(100), nullptr);
 }
 
+TEST_F(InputSurfacesTest, child_container_with_no_input_channel_blocks_parent) {
+    std::unique_ptr<InputSurface> parent = makeSurface(100, 100);
+
+    parent->showAt(100, 100);
+    injectTap(101, 101);
+    parent->expectTap(1, 1);
+
+    std::unique_ptr<InputSurface> childContainerSurface =
+            InputSurface::makeContainerInputSurfaceNoInputChannel(mComposerClient, 100, 100);
+    childContainerSurface->showAt(0, 0);
+    childContainerSurface->doTransaction(
+            [&](auto &t, auto &sc) { t.reparent(sc, parent->mSurfaceControl); });
+    injectTap(101, 101);
+
+    EXPECT_EQ(parent->consumeEvent(100), nullptr);
+}
+
 class MultiDisplayTests : public InputSurfacesTest {
 public:
     MultiDisplayTests() : InputSurfacesTest() { ProcessState::self()->startThreadPool(); }