diff options
| author | 2021-09-24 07:14:54 -0700 | |
|---|---|---|
| committer | 2021-09-24 20:26:43 +0000 | |
| commit | 16a938f8da032c60e5e243838c1fa214d78908c5 (patch) | |
| tree | 5cae71c7178a5fe2a660fc00e23ce050799e85c1 | |
| parent | 1293c3598b51839bc3625fd1879e16c00184e298 (diff) | |
SurfaceFlinger: Drop input for blacked out layers
If the window will be blacked out on a display because
the display does not have the secure flag and the layer
has the secure flag set, then drop input.
Test: atest libgui_test
Fixes: 200842159
Change-Id: Idfe245b0f0091e0cafc15c83b25a9d0fd7364174
| -rw-r--r-- | libs/gui/tests/EndToEndNativeInputTest.cpp | 101 | ||||
| -rw-r--r-- | services/surfaceflinger/Layer.cpp | 10 | ||||
| -rw-r--r-- | services/surfaceflinger/Layer.h | 2 | ||||
| -rw-r--r-- | services/surfaceflinger/SurfaceFlinger.cpp | 19 |
4 files changed, 108 insertions, 24 deletions
diff --git a/libs/gui/tests/EndToEndNativeInputTest.cpp b/libs/gui/tests/EndToEndNativeInputTest.cpp index 78a8b429c1..16208a7773 100644 --- a/libs/gui/tests/EndToEndNativeInputTest.cpp +++ b/libs/gui/tests/EndToEndNativeInputTest.cpp @@ -220,7 +220,7 @@ public: t.apply(true); } - void requestFocus() { + void requestFocus(int displayId = ADISPLAY_ID_DEFAULT) { SurfaceComposerClient::Transaction t; FocusRequest request; request.token = mInputInfo.token; @@ -228,7 +228,7 @@ public: request.focusedToken = nullptr; request.focusedWindowName = ""; request.timestamp = systemTime(SYSTEM_TIME_MONOTONIC); - request.displayId = 0; + request.displayId = displayId; t.setFocusedWindow(request); t.apply(true); } @@ -255,11 +255,6 @@ private: 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"; @@ -373,23 +368,33 @@ public: int32_t mBufferPostDelay; }; -void injectTap(int x, int y) { - char *buf1, *buf2; +void injectTapOnDisplay(int x, int y, int displayId) { + char *buf1, *buf2, *bufDisplayId; asprintf(&buf1, "%d", x); asprintf(&buf2, "%d", y); + asprintf(&bufDisplayId, "%d", displayId); if (fork() == 0) { - execlp("input", "input", "tap", buf1, buf2, NULL); + execlp("input", "input", "-d", bufDisplayId, "tap", buf1, buf2, NULL); } } -void injectKey(uint32_t keycode) { - char *buf1; +void injectTap(int x, int y) { + injectTapOnDisplay(x, y, ADISPLAY_ID_DEFAULT); +} + +void injectKeyOnDisplay(uint32_t keycode, int displayId) { + char *buf1, *bufDisplayId; asprintf(&buf1, "%d", keycode); + asprintf(&bufDisplayId, "%d", displayId); if (fork() == 0) { - execlp("input", "input", "keyevent", buf1, NULL); + execlp("input", "input", "-d", bufDisplayId, "keyevent", buf1, NULL); } } +void injectKey(uint32_t keycode) { + injectKeyOnDisplay(keycode, ADISPLAY_ID_NONE); +} + TEST_F(InputSurfacesTest, can_receive_input) { std::unique_ptr<InputSurface> surface = makeSurface(100, 100); surface->showAt(100, 100); @@ -946,4 +951,74 @@ TEST_F(InputSurfacesTest, drop_input_policy) { injectKey(AKEYCODE_V); EXPECT_EQ(surface->consumeEvent(100), nullptr); } + +class MultiDisplayTests : public InputSurfacesTest { +public: + MultiDisplayTests() : InputSurfacesTest() { ProcessState::self()->startThreadPool(); } + void TearDown() { + if (mVirtualDisplay) { + SurfaceComposerClient::destroyDisplay(mVirtualDisplay); + } + InputSurfacesTest::TearDown(); + } + + void createDisplay(int32_t width, int32_t height, bool isSecure, ui::LayerStack layerStack) { + sp<IGraphicBufferConsumer> consumer; + BufferQueue::createBufferQueue(&mProducer, &consumer); + consumer->setConsumerName(String8("Virtual disp consumer")); + consumer->setDefaultBufferSize(width, height); + + mVirtualDisplay = SurfaceComposerClient::createDisplay(String8("VirtualDisplay"), isSecure); + SurfaceComposerClient::Transaction t; + t.setDisplaySurface(mVirtualDisplay, mProducer); + t.setDisplayFlags(mVirtualDisplay, 0x01 /* DisplayDevice::eReceivesInput */); + t.setDisplayLayerStack(mVirtualDisplay, layerStack); + t.apply(true); + } + + sp<IBinder> mVirtualDisplay; + sp<IGraphicBufferProducer> mProducer; +}; + +TEST_F(MultiDisplayTests, drop_input_for_secure_layer_on_nonsecure_display) { + ui::LayerStack layerStack = ui::LayerStack::fromValue(42); + createDisplay(1000, 1000, false /*isSecure*/, layerStack); + std::unique_ptr<InputSurface> surface = makeSurface(100, 100); + surface->doTransaction([&](auto &t, auto &sc) { + t.setFlags(sc, layer_state_t::eLayerSecure, layer_state_t::eLayerSecure); + t.setLayerStack(sc, layerStack); + }); + surface->showAt(100, 100); + + injectTap(101, 101); + + EXPECT_EQ(surface->consumeEvent(100), nullptr); + + surface->requestFocus(layerStack.id); + surface->assertFocusChange(true); + injectKeyOnDisplay(AKEYCODE_V, layerStack.id); + EXPECT_EQ(surface->consumeEvent(100), nullptr); +} + +TEST_F(MultiDisplayTests, dont_drop_input_for_secure_layer_on_secure_display) { + ui::LayerStack layerStack = ui::LayerStack::fromValue(42); + createDisplay(1000, 1000, true /*isSecure*/, layerStack); + std::unique_ptr<InputSurface> surface = makeSurface(100, 100); + surface->doTransaction([&](auto &t, auto &sc) { + t.setFlags(sc, layer_state_t::eLayerSecure, layer_state_t::eLayerSecure); + t.setLayerStack(sc, layerStack); + }); + surface->showAt(100, 100); + + injectTapOnDisplay(101, 101, layerStack.id); + EXPECT_NE(surface->consumeEvent(), nullptr); + EXPECT_NE(surface->consumeEvent(), nullptr); + + surface->requestFocus(layerStack.id); + surface->assertFocusChange(true); + injectKeyOnDisplay(AKEYCODE_V, layerStack.id); + + surface->expectKey(AKEYCODE_V); +} + } // namespace android::test diff --git a/services/surfaceflinger/Layer.cpp b/services/surfaceflinger/Layer.cpp index 10391a2b1f..87afa222e8 100644 --- a/services/surfaceflinger/Layer.cpp +++ b/services/surfaceflinger/Layer.cpp @@ -2154,7 +2154,7 @@ void Layer::writeToProtoCommonState(LayerProto* layerInfo, LayerVector::StateSet if (traceFlags & SurfaceTracing::TRACE_INPUT) { WindowInfo info; if (useDrawing) { - info = fillInputInfo(ui::Transform()); + info = fillInputInfo(ui::Transform(), /* displayIsSecure */ true); } else { info = state.inputInfo; } @@ -2356,7 +2356,7 @@ void Layer::handleDropInputMode(gui::WindowInfo& info) const { } } -WindowInfo Layer::fillInputInfo(const ui::Transform& displayTransform) { +WindowInfo Layer::fillInputInfo(const ui::Transform& displayTransform, bool displayIsSecure) { if (!hasInputInfo()) { mDrawingState.inputInfo.name = getName(); mDrawingState.inputInfo.ownerUid = mOwnerUid; @@ -2385,6 +2385,12 @@ WindowInfo Layer::fillInputInfo(const ui::Transform& displayTransform) { fillTouchOcclusionMode(info); handleDropInputMode(info); + // If the window will be blacked out on a display because the display does not have the secure + // flag and the layer has the secure flag set, then drop input. + if (!displayIsSecure && isSecure()) { + info.inputFeatures |= WindowInfo::Feature::DROP_INPUT; + } + auto cropLayer = mDrawingState.touchableRegionCrop.promote(); if (info.replaceTouchableRegionWithCrop) { const Rect bounds(cropLayer ? cropLayer->mScreenBounds : mScreenBounds); diff --git a/services/surfaceflinger/Layer.h b/services/surfaceflinger/Layer.h index 7b9303fa58..8c281d53e4 100644 --- a/services/surfaceflinger/Layer.h +++ b/services/surfaceflinger/Layer.h @@ -854,7 +854,7 @@ public: bool getPremultipledAlpha() const; void setInputInfo(const gui::WindowInfo& info); - gui::WindowInfo fillInputInfo(const ui::Transform& displayTransform); + gui::WindowInfo fillInputInfo(const ui::Transform& displayTransform, bool displayIsSecure); /** * Returns whether this layer has an explicitly set input-info. diff --git a/services/surfaceflinger/SurfaceFlinger.cpp b/services/surfaceflinger/SurfaceFlinger.cpp index d4db33c3e6..88715e36aa 100644 --- a/services/surfaceflinger/SurfaceFlinger.cpp +++ b/services/surfaceflinger/SurfaceFlinger.cpp @@ -3089,16 +3089,19 @@ void SurfaceFlinger::notifyWindowInfos() { mDrawingState.traverseInReverseZOrder([&](Layer* layer) { if (!layer->needsInputInfo()) return; - const DisplayDevice* display = nullptr; + const DisplayDevice* display = ON_MAIN_THREAD(getDisplayWithInputByLayer(layer)).get(); + ui::Transform displayTransform = ui::Transform(); + if (enablePerWindowInputRotation()) { - display = ON_MAIN_THREAD(getDisplayWithInputByLayer(layer)).get(); + // When calculating the screen bounds we ignore the transparent region since it may + // result in an unwanted offset. + const auto it = displayTransforms.find(display); + if (it != displayTransforms.end()) { + displayTransform = it->second; + } } - - // When calculating the screen bounds we ignore the transparent region since it may - // result in an unwanted offset. - const auto it = displayTransforms.find(display); - windowInfos.push_back( - layer->fillInputInfo(it != displayTransforms.end() ? it->second : ui::Transform())); + const bool displayIsSecure = !display || display->isSecure(); + windowInfos.push_back(layer->fillInputInfo(displayTransform, displayIsSecure)); }); mWindowInfosListenerInvoker->windowInfosChanged(windowInfos, displayInfos, mInputWindowCommands.syncInputWindows); |