Use empty frame for input when layer bounds is invalid
Fixed a few issues:
1. Return INVALID_RECT for size if there's no buffer for BLAST. This was
already done in BufferQueueLayer. This ensures we don't assume the layer
has a valid size when there's no buffer
2. Don't transform invalid layer bounds in fillInputInfo since it could
result in sending a valid frame when the layer actually has no bounds.
Instead just set input frame to empty, reset the transform, and return
early.
Test: Window with no width or height doesn't get untrusted touch
Test: InputSurfacesTest
Fixes: 173297887
Change-Id: I191d411b0f83ce57b6fdc20a1def8070110d418b
diff --git a/libs/gui/tests/EndToEndNativeInputTest.cpp b/libs/gui/tests/EndToEndNativeInputTest.cpp
index c39b0b5..c75c46c 100644
--- a/libs/gui/tests/EndToEndNativeInputTest.cpp
+++ b/libs/gui/tests/EndToEndNativeInputTest.cpp
@@ -95,6 +95,15 @@
return std::make_unique<InputSurface>(surfaceControl, width, height);
}
+ static std::unique_ptr<InputSurface> makeBlastInputSurface(const sp<SurfaceComposerClient> &scc,
+ int width, int height) {
+ sp<SurfaceControl> surfaceControl =
+ scc->createSurface(String8("Test Buffer Surface"), width, height,
+ PIXEL_FORMAT_RGBA_8888,
+ ISurfaceComposerClient::eFXSurfaceBufferState);
+ return std::make_unique<InputSurface>(surfaceControl, width, height);
+ }
+
static std::unique_ptr<InputSurface> makeContainerInputSurface(
const sp<SurfaceComposerClient> &scc, int width, int height) {
sp<SurfaceControl> surfaceControl =
@@ -180,13 +189,13 @@
t.apply(true);
}
- void showAt(int x, int y) {
+ void showAt(int x, int y, Rect crop = Rect(0, 0, 100, 100)) {
SurfaceComposerClient::Transaction t;
t.show(mSurfaceControl);
t.setInputWindowInfo(mSurfaceControl, mInputInfo);
t.setLayer(mSurfaceControl, LAYER_BASE);
t.setPosition(mSurfaceControl, x, y);
- t.setCrop_legacy(mSurfaceControl, Rect(0, 0, 100, 100));
+ t.setCrop_legacy(mSurfaceControl, crop);
t.setAlpha(mSurfaceControl, 1);
t.apply(true);
}
@@ -684,4 +693,34 @@
surface->expectTap(1, 10);
}
+TEST_F(InputSurfacesTest, touch_not_obscured_with_zero_sized_bql) {
+ std::unique_ptr<InputSurface> surface = makeSurface(100, 100);
+
+ std::unique_ptr<InputSurface> bufferSurface =
+ InputSurface::makeBufferInputSurface(mComposerClient, 0, 0);
+ bufferSurface->mInputInfo.flags = InputWindowInfo::Flag::NOT_TOUCHABLE;
+ bufferSurface->mInputInfo.ownerUid = 22222;
+
+ surface->showAt(10, 10);
+ bufferSurface->showAt(50, 50, Rect::EMPTY_RECT);
+
+ injectTap(11, 11);
+ surface->expectTap(1, 1);
+}
+
+TEST_F(InputSurfacesTest, touch_not_obscured_with_zero_sized_blast) {
+ std::unique_ptr<InputSurface> surface = makeSurface(100, 100);
+
+ std::unique_ptr<InputSurface> bufferSurface =
+ InputSurface::makeBlastInputSurface(mComposerClient, 0, 0);
+ bufferSurface->mInputInfo.flags = InputWindowInfo::Flag::NOT_TOUCHABLE;
+ bufferSurface->mInputInfo.ownerUid = 22222;
+
+ surface->showAt(10, 10);
+ bufferSurface->showAt(50, 50, Rect::EMPTY_RECT);
+
+ injectTap(11, 11);
+ surface->expectTap(1, 1);
+}
+
} // namespace android::test