summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
author Linus Tufvesson <lus@google.com> 2022-03-04 09:32:07 +0000
committer Linus Tufvesson <lus@google.com> 2022-06-10 12:19:58 +0200
commit4c0e43192b7b9dda53e49fd3a41ba5efc1980366 (patch)
treea1177e68b2a5b8f4757b05afbd763c9d1b23c81b
parent04caf0c75b97edb1ae161eecaa01c7ac0e8da5c8 (diff)
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)
-rw-r--r--libs/gui/tests/EndToEndNativeInputTest.cpp90
-rw-r--r--services/surfaceflinger/Layer.cpp5
2 files changed, 61 insertions, 34 deletions
diff --git a/libs/gui/tests/EndToEndNativeInputTest.cpp b/libs/gui/tests/EndToEndNativeInputTest.cpp
index f60a58f60b..53e4af4454 100644
--- a/libs/gui/tests/EndToEndNativeInputTest.cpp
+++ b/libs/gui/tests/EndToEndNativeInputTest.cpp
@@ -69,16 +69,39 @@ static constexpr std::chrono::nanoseconds DISPATCHING_TIMEOUT = 5s;
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.inputFeatures = InputWindowInfo::Feature::NO_INPUT_CHANNEL;
+ } 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.flags = InputWindowInfo::Flag::NOT_TOUCH_MODAL;
+ mInputInfo.type = InputWindowInfo::Type::BASE_APPLICATION;
+ mInputInfo.focusable = true;
+ mInputInfo.hasWallpaper = false;
+ mInputInfo.paused = false;
+ // TODO: Fill in from SF?
+ mInputInfo.ownerPid = 11111;
+ mInputInfo.ownerUid = 11111;
+ mInputInfo.displayId = 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,
@@ -107,6 +130,16 @@ public:
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"), 0 /* bufHeight */,
+ 0 /* bufWidth */, 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 =
@@ -193,7 +226,9 @@ public:
}
virtual ~InputSurface() {
- mInputFlinger->removeInputChannel(mClientChannel->getConnectionToken());
+ if (mClientChannel) {
+ mInputFlinger->removeInputChannel(mClientChannel->getConnectionToken());
+ }
}
virtual void doTransaction(
@@ -237,32 +272,6 @@ private:
poll(&fd, 1, timeoutMs);
}
- void populateInputInfo(int width, int height) {
- mInputInfo.token = mClientChannel->getConnectionToken();
- mInputInfo.name = "Test info";
- mInputInfo.flags = InputWindowInfo::Flag::NOT_TOUCH_MODAL;
- mInputInfo.type = InputWindowInfo::Type::BASE_APPLICATION;
- mInputInfo.dispatchingTimeout = 5s;
- mInputInfo.globalScaleFactor = 1.0;
- mInputInfo.focusable = 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.displayId = 0;
-
- 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;
@@ -818,4 +827,21 @@ TEST_F(InputSurfacesTest, touch_not_obscured_with_zero_sized_blast) {
surface->expectTap(1, 1);
}
+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);
+}
+
} // namespace android::test
diff --git a/services/surfaceflinger/Layer.cpp b/services/surfaceflinger/Layer.cpp
index 71e4791fe9..6a967d2982 100644
--- a/services/surfaceflinger/Layer.cpp
+++ b/services/surfaceflinger/Layer.cpp
@@ -2151,7 +2151,7 @@ void Layer::writeToProtoCommonState(LayerProto* layerInfo, LayerVector::StateSet
layerInfo->set_owner_uid(mOwnerUid);
}
- if (traceFlags & SurfaceTracing::TRACE_INPUT) {
+ if (traceFlags & SurfaceTracing::TRACE_INPUT && needsInputInfo()) {
InputWindowInfo info;
if (useDrawing) {
info = fillInputInfo({nullptr});
@@ -2399,7 +2399,8 @@ sp<Layer> Layer::getClonedRoot() {
}
bool Layer::hasInputInfo() const {
- return mDrawingState.inputInfo.token != nullptr;
+ return mDrawingState.inputInfo.token != nullptr ||
+ mDrawingState.inputInfo.inputFeatures.test(InputWindowInfo::Feature::NO_INPUT_CHANNEL);
}
bool Layer::canReceiveInput() const {