From c7df484a6f4265d20418fc64c46ead350f794a0c Mon Sep 17 00:00:00 2001 From: Linus Tufvesson Date: Fri, 4 Mar 2022 09:32:07 +0000 Subject: Allow windowhandles with NO_INPUT_CHANNEL - DO NOT MERGE 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 InputSurfacesTest Change-Id: Iacfc952139311363b914b1d6bffc2b4190133d02 (cherry picked from commit a18588206c240b34128bb27e3ac875af17fce7f2) --- libs/gui/tests/EndToEndNativeInputTest.cpp | 93 +++++++++++++++++++----------- services/surfaceflinger/Layer.cpp | 3 +- 2 files changed, 61 insertions(+), 35 deletions(-) diff --git a/libs/gui/tests/EndToEndNativeInputTest.cpp b/libs/gui/tests/EndToEndNativeInputTest.cpp index 8e42c688af..e3f4798019 100644 --- a/libs/gui/tests/EndToEndNativeInputTest.cpp +++ b/libs/gui/tests/EndToEndNativeInputTest.cpp @@ -66,17 +66,40 @@ static const int LAYER_BASE = INT32_MAX - 10; class InputSurface { public: - InputSurface(const sp &sc, int width, int height) { + InputSurface(const sp &sc, int width, int height, bool noInputChannel = false) { mSurfaceControl = sc; - InputChannel::openInputChannelPair("testchannels", mServerChannel, mClientChannel); - mInputFlinger = getInputFlinger(); - mInputFlinger->registerInputChannel(mServerChannel); + if (noInputChannel) { + mInputInfo.inputFeatures = InputWindowInfo::INPUT_FEATURE_NO_INPUT_CHANNEL; + } else { + InputChannel::openInputChannelPair("testchannels", mServerChannel, mClientChannel); + mInputFlinger->registerInputChannel(mServerChannel); + mInputInfo.token = mServerChannel->getConnectionToken(); + mInputConsumer = new InputConsumer(mClientChannel); + } - populateInputInfo(width, height); + mInputInfo.name = "Test info"; + mInputInfo.layoutParamsFlags = InputWindowInfo::FLAG_NOT_TOUCH_MODAL; + mInputInfo.layoutParamsType = InputWindowInfo::TYPE_BASE_APPLICATION; + mInputInfo.dispatchingTimeout = seconds_to_nanoseconds(5); + mInputInfo.globalScaleFactor = 1.0; + mInputInfo.canReceiveKeys = true; + mInputInfo.hasFocus = true; + mInputInfo.hasWallpaper = false; + mInputInfo.paused = false; + mInputInfo.touchableRegion.orSelf(Rect(0, 0, width, height)); + // TODO: Fill in from SF? + mInputInfo.ownerPid = 11111; + mInputInfo.ownerUid = 11111; + mInputInfo.inputFeatures = 0; + mInputInfo.displayId = 0; - mInputConsumer = new InputConsumer(mClientChannel); + InputApplicationInfo aInfo; + aInfo.token = new BBinder(); + aInfo.name = "Test app info"; + aInfo.dispatchingTimeout = seconds_to_nanoseconds(5); + mInputInfo.applicationInfo = aInfo; } static std::unique_ptr makeColorInputSurface(const sp &scc, @@ -105,6 +128,16 @@ public: return std::make_unique(surfaceControl, width, height); } + static std::unique_ptr makeContainerInputSurfaceNoInputChannel( + const sp &scc, int width, int height) { + sp surfaceControl = + scc->createSurface(String8("Test Container Surface"), 0 /* bufHeight */, + 0 /* bufWidth */, PIXEL_FORMAT_RGBA_8888, + ISurfaceComposerClient::eFXSurfaceContainer); + return std::make_unique(surfaceControl, width, height, + true /* noInputChannel */); + } + static std::unique_ptr makeCursorInputSurface( const sp &scc, int width, int height) { sp surfaceControl = @@ -173,7 +206,9 @@ public: } ~InputSurface() { - mInputFlinger->unregisterInputChannel(mServerChannel); + if (mInputInfo.token) { + mInputFlinger->unregisterInputChannel(mServerChannel); + } } void doTransaction(std::functiongetConnectionToken(); - mInputInfo.name = "Test info"; - mInputInfo.layoutParamsFlags = InputWindowInfo::FLAG_NOT_TOUCH_MODAL; - mInputInfo.layoutParamsType = InputWindowInfo::TYPE_BASE_APPLICATION; - mInputInfo.dispatchingTimeout = seconds_to_nanoseconds(5); - mInputInfo.globalScaleFactor = 1.0; - mInputInfo.canReceiveKeys = true; - mInputInfo.hasFocus = true; - mInputInfo.hasWallpaper = false; - mInputInfo.paused = false; - - mInputInfo.touchableRegion.orSelf(Rect(0, 0, width, height)); - - // TODO: Fill in from SF? - mInputInfo.ownerPid = 11111; - mInputInfo.ownerUid = 11111; - mInputInfo.inputFeatures = 0; - mInputInfo.displayId = 0; - - InputApplicationInfo aInfo; - aInfo.token = new BBinder(); - aInfo.name = "Test app info"; - aInfo.dispatchingTimeout = seconds_to_nanoseconds(5); - - mInputInfo.applicationInfo = aInfo; - } public: sp mSurfaceControl; sp mServerChannel, mClientChannel; @@ -589,6 +597,23 @@ TEST_F(InputSurfacesTest, input_ignores_cursor_layer) { surface->expectTap(1, 1); } +TEST_F(InputSurfacesTest, child_container_with_no_input_channel_blocks_parent) { + std::unique_ptr parent = makeSurface(100, 100); + parent->showAt(100, 100); + parent->assertFocusChange(true); + injectTap(101, 101); + parent->expectTap(1, 1); + + std::unique_ptr childContainerSurface = + InputSurface::makeContainerInputSurfaceNoInputChannel(mComposerClient, 100, 100); + childContainerSurface->showAt(0, 0); + childContainerSurface->doTransaction( + [&](auto &t, auto &sc) { t.reparent(sc, parent->mSurfaceControl->getHandle()); }); + injectTap(101, 101); + + EXPECT_EQ(parent->consumeEvent(100), nullptr); +} + TEST_F(InputSurfacesTest, drop_input_policy) { std::unique_ptr surface = makeSurface(100, 100); surface->doTransaction( diff --git a/services/surfaceflinger/Layer.cpp b/services/surfaceflinger/Layer.cpp index 0691418525..6fe5ce5931 100644 --- a/services/surfaceflinger/Layer.cpp +++ b/services/surfaceflinger/Layer.cpp @@ -2514,7 +2514,8 @@ sp Layer::getClonedRoot() { } bool Layer::hasInputInfo() const { - return mDrawingState.inputInfo.token != nullptr; + return mDrawingState.inputInfo.token != nullptr || + mDrawingState.inputInfo.inputFeatures & InputWindowInfo::INPUT_FEATURE_NO_INPUT_CHANNEL; } bool Layer::canReceiveInput() const { -- cgit v1.2.3-59-g8ed1b