From b4a2d3a77ab2fc8b7e3d88c528c71269651f0ddb Mon Sep 17 00:00:00 2001 From: Robin Lee Date: Fri, 10 Sep 2021 12:03:42 +0000 Subject: Initialize DrawingState::trustedOverlay to false in constructor To avoid it being initialised to true randomly. Bug: 199483370 Bug: 196389741 Bug: 218605327 Change-Id: I75be2b1d305e22f8a71532b9f5b8ea6c469baaaa Merged-In: I75be2b1d305e22f8a71532b9f5b8ea6c469baaaa (cherry picked from commit edb375df82f6b48688d85c11dbca91adef088bc8) --- services/surfaceflinger/Layer.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/services/surfaceflinger/Layer.cpp b/services/surfaceflinger/Layer.cpp index e4a777f3c7..75dd51c992 100644 --- a/services/surfaceflinger/Layer.cpp +++ b/services/surfaceflinger/Layer.cpp @@ -134,6 +134,7 @@ Layer::Layer(const LayerCreationArgs& args) mDrawingState.frameTimelineInfo = {}; mDrawingState.postTime = -1; mDrawingState.destinationFrame.makeInvalid(); + mDrawingState.isTrustedOverlay = false; if (args.flags & ISurfaceComposerClient::eNoColorFill) { // Set an invalid color so there is no color fill. -- cgit v1.2.3 From 8f4e41d679d67436ee3868cab8785a35b3cc613f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Maciej=20=C5=BBenczykowski?= Date: Wed, 8 Jun 2022 21:38:21 +0000 Subject: add explicit 32-bits of padding to UidTrackingInfo struct MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit (fixes 32-bit arch) Bug: 235386871 Test: TreeHugger Signed-off-by: Maciej Żenczykowski Change-Id: I9c37483eca17011f3f6d9755427c5a380166228e --- services/gpuservice/gpuwork/bpfprogs/include/gpuwork/gpu_work.h | 2 ++ 1 file changed, 2 insertions(+) diff --git a/services/gpuservice/gpuwork/bpfprogs/include/gpuwork/gpu_work.h b/services/gpuservice/gpuwork/bpfprogs/include/gpuwork/gpu_work.h index 57338f4c91..2affb60a0c 100644 --- a/services/gpuservice/gpuwork/bpfprogs/include/gpuwork/gpu_work.h +++ b/services/gpuservice/gpuwork/bpfprogs/include/gpuwork/gpu_work.h @@ -49,6 +49,8 @@ typedef struct { // negative duration. uint32_t error_count; + // Needed to make 32-bit arch struct size match 64-bit BPF arch struct size. + uint32_t padding0; } UidTrackingInfo; typedef struct { -- cgit v1.2.3 From 8758cd1030dc9fd73cc98c09ce7b9c356757a659 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 | 91 +++++++++++++++++++----------- services/surfaceflinger/Layer.cpp | 7 ++- 2 files changed, 63 insertions(+), 35 deletions(-) diff --git a/libs/gui/tests/EndToEndNativeInputTest.cpp b/libs/gui/tests/EndToEndNativeInputTest.cpp index 5daef0df28..cdd8ea65c7 100644 --- a/libs/gui/tests/EndToEndNativeInputTest.cpp +++ b/libs/gui/tests/EndToEndNativeInputTest.cpp @@ -74,16 +74,39 @@ static constexpr std::chrono::nanoseconds DISPATCHING_TIMEOUT = 5s; class InputSurface { public: - InputSurface(const sp &sc, int width, int height) { + InputSurface(const sp &sc, int width, int height, bool noInputChannel = false) { mSurfaceControl = sc; mInputFlinger = getInputFlinger(); - mClientChannel = std::make_shared(); - mInputFlinger->createInputChannel("testchannels", mClientChannel.get()); + if (noInputChannel) { + mInputInfo.inputFeatures = WindowInfo::Feature::NO_INPUT_CHANNEL; + } else { + mClientChannel = std::make_shared(); + 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 = WindowInfo::Flag::NOT_TOUCH_MODAL; + mInputInfo.type = WindowInfo::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(DISPATCHING_TIMEOUT).count(); + mInputInfo.applicationInfo = aInfo; } static std::unique_ptr makeColorInputSurface(const sp &scc, @@ -112,6 +135,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 = @@ -198,7 +231,9 @@ public: } virtual ~InputSurface() { - mInputFlinger->removeInputChannel(mClientChannel->getConnectionToken()); + if (mClientChannel) { + mInputFlinger->removeInputChannel(mClientChannel->getConnectionToken()); + } } virtual void doTransaction( @@ -242,32 +277,6 @@ private: poll(&fd, 1, timeoutMs); } - void populateInputInfo(int width, int height) { - mInputInfo.token = mClientChannel->getConnectionToken(); - mInputInfo.name = "Test info"; - mInputInfo.flags = WindowInfo::Flag::NOT_TOUCH_MODAL; - mInputInfo.type = WindowInfo::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(DISPATCHING_TIMEOUT).count(); - - mInputInfo.applicationInfo = aInfo; - } public: sp mSurfaceControl; std::shared_ptr mClientChannel; @@ -960,4 +969,22 @@ TEST_F(InputSurfacesTest, drop_input_policy) { injectKey(AKEYCODE_V); EXPECT_EQ(surface->consumeEvent(100), nullptr); } + +TEST_F(InputSurfacesTest, child_container_with_no_input_channel_blocks_parent) { + std::unique_ptr parent = makeSurface(100, 100); + + parent->showAt(100, 100); + 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); }); + 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 4d804fa670..7d7e31d1d2 100644 --- a/services/surfaceflinger/Layer.cpp +++ b/services/surfaceflinger/Layer.cpp @@ -2164,7 +2164,7 @@ void Layer::writeToProtoCommonState(LayerProto* layerInfo, LayerVector::StateSet layerInfo->set_owner_uid(mOwnerUid); } - if (traceFlags & SurfaceTracing::TRACE_INPUT) { + if (traceFlags & SurfaceTracing::TRACE_INPUT && needsInputInfo()) { WindowInfo info; if (useDrawing) { info = fillInputInfo({nullptr}); @@ -2214,7 +2214,7 @@ void Layer::fillInputFrameInfo(WindowInfo& info, const ui::Transform& toNonRotat info.frameBottom = 0; info.transform.reset(); info.touchableRegion = Region(); - info.flags = WindowInfo::Flag::NOT_TOUCH_MODAL | WindowInfo::Flag::NOT_FOCUSABLE; + info.flags |= WindowInfo::Flag::NOT_TOUCH_MODAL | WindowInfo::Flag::NOT_FOCUSABLE; return; } @@ -2468,7 +2468,8 @@ sp Layer::getClonedRoot() { } bool Layer::hasInputInfo() const { - return mDrawingState.inputInfo.token != nullptr; + return mDrawingState.inputInfo.token != nullptr || + mDrawingState.inputInfo.inputFeatures.test(WindowInfo::Feature::NO_INPUT_CHANNEL); } bool Layer::canReceiveInput() const { -- cgit v1.2.3 From 4c0e43192b7b9dda53e49fd3a41ba5efc1980366 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 | 90 +++++++++++++++++++----------- services/surfaceflinger/Layer.cpp | 5 +- 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 &sc, int width, int height) { + InputSurface(const sp &sc, int width, int height, bool noInputChannel = false) { mSurfaceControl = sc; mInputFlinger = getInputFlinger(); - mClientChannel = std::make_shared(); - mInputFlinger->createInputChannel("testchannels", mClientChannel.get()); + if (noInputChannel) { + mInputInfo.inputFeatures = InputWindowInfo::Feature::NO_INPUT_CHANNEL; + } else { + mClientChannel = std::make_shared(); + 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(DISPATCHING_TIMEOUT).count(); + mInputInfo.applicationInfo = aInfo; } static std::unique_ptr makeColorInputSurface(const sp &scc, @@ -107,6 +130,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 = @@ -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(DISPATCHING_TIMEOUT).count(); - - mInputInfo.applicationInfo = aInfo; - } public: sp mSurfaceControl; std::shared_ptr 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 parent = makeSurface(100, 100); + + parent->showAt(100, 100); + 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); }); + 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::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 { -- cgit v1.2.3 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 From 33da9468354b9b530712d4157298a8e0479cf2e5 Mon Sep 17 00:00:00 2001 From: Prabir Pradhan Date: Tue, 14 Jun 2022 14:55:57 +0000 Subject: Layer: Guard against Region offset overflows When applying a transform to a Region, if the Region is translated to bounds that overlow the int32_t type, the process crashes. For now, we guard against process crashes by manually applying the offset to the Region and checking for overflows. If we detect an overflow in one of the Rects in a Region, we remove the Rect from the resulting Region. Bug: 234247210 Test: atest libgui_test Change-Id: Icd47539accae2e59a7dbd9c9621201bd040fc402 --- libs/gui/tests/EndToEndNativeInputTest.cpp | 49 ++++++++++++++++++++++++++++++ services/surfaceflinger/Layer.cpp | 34 ++++++++++++++++++++- 2 files changed, 82 insertions(+), 1 deletion(-) diff --git a/libs/gui/tests/EndToEndNativeInputTest.cpp b/libs/gui/tests/EndToEndNativeInputTest.cpp index 262987fd27..c6cdeb7706 100644 --- a/libs/gui/tests/EndToEndNativeInputTest.cpp +++ b/libs/gui/tests/EndToEndNativeInputTest.cpp @@ -566,6 +566,55 @@ TEST_F(InputSurfacesTest, input_respects_scaled_surface_insets_overflow) { bgSurface->expectTap(12, 24); } +TEST_F(InputSurfacesTest, touchable_region) { + std::unique_ptr surface = makeSurface(100, 100); + + surface->mInputInfo.touchableRegion.set(Rect{19, 29, 21, 31}); + + surface->showAt(11, 22); + + // A tap within the surface but outside the touchable region should not be sent to the surface. + injectTap(20, 30); + EXPECT_EQ(surface->consumeEvent(200 /*timeoutMs*/), nullptr); + + injectTap(31, 52); + surface->expectTap(20, 30); +} + +TEST_F(InputSurfacesTest, input_respects_touchable_region_offset_overflow) { + std::unique_ptr bgSurface = makeSurface(100, 100); + std::unique_ptr fgSurface = makeSurface(100, 100); + bgSurface->showAt(100, 100); + + // Set the touchable region to the values at the limit of its corresponding type. + // Since the surface is offset from the origin, the touchable region will be transformed into + // display space, which would trigger an overflow or an underflow. Ensure that we are protected + // against such a situation. + fgSurface->mInputInfo.touchableRegion.orSelf(Rect{INT32_MIN, INT32_MIN, INT32_MAX, INT32_MAX}); + + fgSurface->showAt(100, 100); + + // Expect no crash for overflow. The overflowed touchable region is ignored, so the background + // surface receives touch. + injectTap(112, 124); + bgSurface->expectTap(12, 24); +} + +TEST_F(InputSurfacesTest, input_respects_scaled_touchable_region_overflow) { + std::unique_ptr bgSurface = makeSurface(100, 100); + std::unique_ptr fgSurface = makeSurface(100, 100); + bgSurface->showAt(0, 0); + + fgSurface->mInputInfo.touchableRegion.orSelf(Rect{INT32_MIN, INT32_MIN, INT32_MAX, INT32_MAX}); + fgSurface->showAt(0, 0); + + fgSurface->doTransaction([&](auto &t, auto &sc) { t.setMatrix(sc, 2.0, 0, 0, 2.0); }); + + // Expect no crash for overflow. + injectTap(12, 24); + fgSurface->expectTap(6, 12); +} + // Ensure we ignore transparent region when getting screen bounds when positioning input frame. TEST_F(InputSurfacesTest, input_ignores_transparent_region) { std::unique_ptr surface = makeSurface(100, 100); diff --git a/services/surfaceflinger/Layer.cpp b/services/surfaceflinger/Layer.cpp index 6ed4a94f25..be16942d40 100644 --- a/services/surfaceflinger/Layer.cpp +++ b/services/surfaceflinger/Layer.cpp @@ -2194,6 +2194,37 @@ Rect Layer::getInputBounds() const { return getCroppedBufferSize(getDrawingState()); } +// Applies the given transform to the region, while protecting against overflows caused by any +// offsets. If applying the offset in the transform to any of the Rects in the region would result +// in an overflow, they are not added to the output Region. +static Region transformTouchableRegionSafely(const ui::Transform& t, const Region& r, + const std::string& debugWindowName) { + // Round the translation using the same rounding strategy used by ui::Transform. + const auto tx = static_cast(t.tx() + 0.5); + const auto ty = static_cast(t.ty() + 0.5); + + ui::Transform transformWithoutOffset = t; + transformWithoutOffset.set(0.f, 0.f); + + const Region transformed = transformWithoutOffset.transform(r); + + // Apply the translation to each of the Rects in the region while discarding any that overflow. + Region ret; + for (const auto& rect : transformed) { + Rect newRect; + if (__builtin_add_overflow(rect.left, tx, &newRect.left) || + __builtin_add_overflow(rect.top, ty, &newRect.top) || + __builtin_add_overflow(rect.right, tx, &newRect.right) || + __builtin_add_overflow(rect.bottom, ty, &newRect.bottom)) { + ALOGE("Applying transform to touchable region of window '%s' resulted in an overflow.", + debugWindowName.c_str()); + continue; + } + ret.orSelf(newRect); + } + return ret; +} + void Layer::fillInputFrameInfo(WindowInfo& info, const ui::Transform& screenToDisplay) { Rect tmpBounds = getInputBounds(); if (!tmpBounds.isValid()) { @@ -2256,7 +2287,8 @@ void Layer::fillInputFrameInfo(WindowInfo& info, const ui::Transform& screenToDi info.transform = inputToDisplay.inverse(); // The touchable region is specified in the input coordinate space. Change it to display space. - info.touchableRegion = inputToDisplay.transform(info.touchableRegion); + info.touchableRegion = + transformTouchableRegionSafely(inputToDisplay, info.touchableRegion, mName); } void Layer::fillTouchOcclusionMode(WindowInfo& info) { -- cgit v1.2.3 From d5b5f5acb6f447ea2c72bad4f8bcc2a146f0531a Mon Sep 17 00:00:00 2001 From: Kalesh Singh Date: Thu, 16 Jun 2022 01:45:53 -0700 Subject: atrace: Remove persisitent rss_stat_throttled trigger It was found that the persistent rss_stat_throttled event trigger causes a 8% incease in kswapd CPU usage. So remove this persistent trigger, instead perfetto will dynamically create the trigger when needed. Test: adb push test/configs/rss_stat.cfg /data/local/tmp/ && cf-adb shell 'cat /data/local/tmp/rss_stat.cfg | perfetto --txt -c - -o /data/misc/perfetto-traces/trace Bug: 236172293 Change-Id: I70a978de1fbf2ed538bb869edc715e61aee7efa4 Merged-In: I70a978de1fbf2ed538bb869edc715e61aee7efa4 --- cmds/atrace/atrace.rc | 7 ++----- 1 file changed, 2 insertions(+), 5 deletions(-) diff --git a/cmds/atrace/atrace.rc b/cmds/atrace/atrace.rc index 32ffe142cf..5267b0294c 100644 --- a/cmds/atrace/atrace.rc +++ b/cmds/atrace/atrace.rc @@ -294,12 +294,9 @@ on late-init write /sys/kernel/tracing/synthetic_events "rss_stat_throttled unsigned int mm_id; unsigned int curr; int member; long size" write /sys/kernel/debug/tracing/synthetic_events "rss_stat_throttled unsigned int mm_id; unsigned int curr; int member; long size" -# Set up histogram triggers - # rss_stat_throttled (bucket size == 512KB) - chmod 0666 /sys/kernel/tracing/events/kmem/rss_stat/trigger + # allow creating event triggers chmod 0666 /sys/kernel/debug/tracing/events/kmem/rss_stat/trigger - write /sys/kernel/tracing/events/kmem/rss_stat/trigger "hist:keys=mm_id,member:bucket=size/0x80000:onchange($$bucket).rss_stat_throttled(mm_id,curr,member,size)" - write /sys/kernel/debug/tracing/events/kmem/rss_stat/trigger "hist:keys=mm_id,member:bucket=size/0x80000:onchange($$bucket).rss_stat_throttled(mm_id,curr,member,size)" + chmod 0666 /sys/kernel/tracing/events/kmem/rss_stat/trigger # Only create the tracing instance if persist.mm_events.enabled # Attempting to remove the tracing instance after it has been created -- cgit v1.2.3 From c621d8d2be904c516f811acee52d049b41662931 Mon Sep 17 00:00:00 2001 From: Ady Abraham Date: Wed, 22 Jun 2022 17:01:25 +0000 Subject: SF: Add missing ATRACE_TAG to VsyncSchedule.cpp Enable ATRACE logging from VsyncSchedule.cpp which is needed for debugging. Test: collect systraces with debug.sf.show_predicted_vsync set to true and observe VSYNC-predicted track Change-Id: Id23fa2f0004319f4ee592e19dc34a6b74cdb644f Bug: 235566681 --- services/surfaceflinger/Scheduler/VsyncSchedule.cpp | 2 ++ 1 file changed, 2 insertions(+) diff --git a/services/surfaceflinger/Scheduler/VsyncSchedule.cpp b/services/surfaceflinger/Scheduler/VsyncSchedule.cpp index e611658bfd..3a918a1660 100644 --- a/services/surfaceflinger/Scheduler/VsyncSchedule.cpp +++ b/services/surfaceflinger/Scheduler/VsyncSchedule.cpp @@ -14,6 +14,8 @@ * limitations under the License. */ +#define ATRACE_TAG ATRACE_TAG_GRAPHICS + #include #include -- cgit v1.2.3 From b645049d01ef72653dc8fc363b9af18f4678f1e8 Mon Sep 17 00:00:00 2001 From: Robert Carr Date: Thu, 23 Jun 2022 11:17:16 -0700 Subject: SurfaceFlinger: Disable early release optimization Starting a few weeks ago a crop of issues started showing up on a subset of devices, related to the early release optimization (which landed much earlier). Attempts to fix them unfortunately introduced another regression. The fact that the optimization is only triggering visible errors on a subset of devices is somewhat of a mystery. A CL is prepared which fixes all issues observed to date. Howeverthis mystery about device specific behavior implies the full implications of the optimization are not yet understood. It's better to disable the optimization for the current release and take time to fully understand what is happening. Removing the optimization may have some impact on jank, but I expect it's unlikely to be large. I only expect the optimization to reduce jank in cases where: 1. The app is backpressured 2. SurfaceFlinger is repeatedly missing frames producing long dequeues 3. The app has UI + RenderThread time >= vsync interval and is only able to achieve steady production with render ahead and pipelining. If SurfaceFlinger were to begin regular frame production again, early release could help the steady production pipeline recover faster by unblocking the app sooner. This represents a small amount of edge cases. Continued work on preventing SF from missing frames, makes this probably even a smaller amount than when the early release optimization first landed. Bug: 236120925 Bug: 234753489 Test: Existing tests pass. Verify that early release is disabled. Change-Id: I6a9a34331edb752d51c9d2d0b6826942d0545e3d --- services/surfaceflinger/BufferStateLayer.cpp | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/services/surfaceflinger/BufferStateLayer.cpp b/services/surfaceflinger/BufferStateLayer.cpp index fecf5ae059..3875f151cb 100644 --- a/services/surfaceflinger/BufferStateLayer.cpp +++ b/services/surfaceflinger/BufferStateLayer.cpp @@ -34,6 +34,8 @@ #include "FrameTracer/FrameTracer.h" #include "TimeStats/TimeStats.h" +#define EARLY_RELEASE_ENABLED false + namespace android { using PresentState = frametimeline::SurfaceFrame::PresentState; @@ -373,7 +375,7 @@ bool BufferStateLayer::setBuffer(std::shared_ptr& addSurfaceFrameDroppedForBuffer(mDrawingState.bufferSurfaceFrameTX); mDrawingState.bufferSurfaceFrameTX.reset(); } - } else if (mLastClientCompositionFence != nullptr) { + } else if (EARLY_RELEASE_ENABLED && mLastClientCompositionFence != nullptr) { callReleaseBufferCallback(mDrawingState.releaseBufferListener, mDrawingState.buffer->getBuffer(), mDrawingState.frameNumber, mLastClientCompositionFence, -- cgit v1.2.3 From c1359ac51c970666691ef4d07a6969c434062037 Mon Sep 17 00:00:00 2001 From: Michael Wright Date: Fri, 1 Jul 2022 02:42:10 +0100 Subject: Reconcile native and Java parcel code for WorkSource. Prior to this change, native work sources didn't read or write any information concerning WorkChains, but Java ones did. This lead to a mismatch when Java code, such as PowerManagerService, unparceled the WorkSource as it read the whatever the next 4 bytes happened to be as the WorkChain count, but it was actually reading whatever the next item in the transaction happened to have written. Note that this change does _not_ attempt to add a WorkChain implementation to native. It instead makes it so that WorkSources written from native to Java, or Java to native with no WorkChains, are correctly and symmetrically parceled. In addition, if a Java WorkSource is sent to native with a non-zero amount of WorkChains associated, then it will return an error when unparceling rather than continuing but leaving in the Parcel in an undefined state. Bug: 234429395 Test: atest WorkSourceTest.cpp Test: Write sample native app that grabs wakelock, validate display ID Change-Id: Id1a5f29f4ccf2996e37ec99014ce392599b6b725 --- services/powermanager/WorkSource.cpp | 12 +++++-- services/powermanager/tests/Android.bp | 1 + services/powermanager/tests/WorkSourceTest.cpp | 46 ++++++++++++++++++++++++++ 3 files changed, 57 insertions(+), 2 deletions(-) create mode 100644 services/powermanager/tests/WorkSourceTest.cpp diff --git a/services/powermanager/WorkSource.cpp b/services/powermanager/WorkSource.cpp index 1006a0666f..64a5499084 100644 --- a/services/powermanager/WorkSource.cpp +++ b/services/powermanager/WorkSource.cpp @@ -28,9 +28,16 @@ status_t WorkSource::readFromParcel(const android::Parcel *parcel) { return BAD_VALUE; } int32_t num; + int32_t workChainCount; status_t ret = parcel->readInt32(&num) ?: parcel->readInt32Vector(&mUids) - ?: parcel->readString16Vector(&mNames); + ?: parcel->readString16Vector(&mNames) + ?: parcel->readInt32(&workChainCount); + + if (ret == OK && workChainCount > 0) { + // We don't yet support WorkChains in native WorkSources. + return BAD_VALUE; + } return ret; } @@ -43,7 +50,8 @@ status_t WorkSource::writeToParcel(android::Parcel *parcel) const { return parcel->writeInt32(mUids.size()) ?: parcel->writeInt32Vector(mUids) - ?: parcel->writeString16Vector(mNames); + ?: parcel->writeString16Vector(mNames) + ?: parcel->writeInt32(-1); } } // namespace android::os diff --git a/services/powermanager/tests/Android.bp b/services/powermanager/tests/Android.bp index 2d1558a33f..962784cbae 100644 --- a/services/powermanager/tests/Android.bp +++ b/services/powermanager/tests/Android.bp @@ -31,6 +31,7 @@ cc_test { "PowerHalWrapperAidlTest.cpp", "PowerHalWrapperHidlV1_0Test.cpp", "PowerHalWrapperHidlV1_1Test.cpp", + "WorkSourceTest.cpp", ], cflags: [ "-Wall", diff --git a/services/powermanager/tests/WorkSourceTest.cpp b/services/powermanager/tests/WorkSourceTest.cpp new file mode 100644 index 0000000000..bb9164ac57 --- /dev/null +++ b/services/powermanager/tests/WorkSourceTest.cpp @@ -0,0 +1,46 @@ +/* + * Copyright (C) 2022 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include +#define LOG_TAG "PowerHalLoaderTest" + +#include +#include +#include +#include + +#include + +using namespace android; +using namespace testing; + +TEST(WorkSourceTest, Parcel) { + std::vector uids = {1, 2}; + using Names = std::vector>; + std::optional names = std::make_optional({std::make_optional(String16("name"))}); + os::WorkSource ws{uids, names}; + + Parcel p; + ws.writeToParcel(&p); + p.setDataPosition(0); + + os::WorkSource otherWs; + otherWs.readFromParcel(&p); + + EXPECT_EQ(ws, otherWs); + EXPECT_EQ(uids, otherWs.getUids()); + EXPECT_EQ(names, otherWs.getNames()); +} -- cgit v1.2.3