Loading libs/gui/tests/EndToEndNativeInputTest.cpp +13 −0 Original line number Diff line number Diff line Loading @@ -410,6 +410,19 @@ TEST_F(InputSurfacesTest, input_respects_scaled_surface_insets) { bgSurface->expectTap(1, 1); } TEST_F(InputSurfacesTest, input_respects_scaled_surface_insets_overflow) { std::unique_ptr<InputSurface> fgSurface = makeSurface(100, 100); // In case we pass the very big inset without any checking. fgSurface->mInputInfo.surfaceInset = INT32_MAX; fgSurface->showAt(100, 100); fgSurface->doTransaction([&](auto &t, auto &sc) { t.setMatrix(sc, 2.0, 0, 0, 2.0); }); // expect no crash for overflow, and inset size to be clamped to surface size injectTap(202, 202); fgSurface->expectTap(1, 1); } // Ensure we ignore transparent region when getting screen bounds when positioning input frame. TEST_F(InputSurfacesTest, input_ignores_transparent_region) { std::unique_ptr<InputSurface> surface = makeSurface(100, 100); Loading services/surfaceflinger/Layer.cpp +11 −6 Original line number Diff line number Diff line Loading @@ -1975,14 +1975,14 @@ InputWindowInfo Layer::fillInputInfo() { ui::Transform t = getTransform(); const float xScale = t.sx(); const float yScale = t.sy(); float xSurfaceInset = info.surfaceInset; float ySurfaceInset = info.surfaceInset; int32_t xSurfaceInset = info.surfaceInset; int32_t ySurfaceInset = info.surfaceInset; if (xScale != 1.0f || yScale != 1.0f) { info.windowXScale *= 1.0f / xScale; info.windowYScale *= 1.0f / yScale; info.windowXScale *= (xScale != 0.0f) ? 1.0f / xScale : 0.0f; info.windowYScale *= (yScale != 0.0f) ? 1.0f / yScale : 0.0f; info.touchableRegion.scaleSelf(xScale, yScale); xSurfaceInset *= xScale; ySurfaceInset *= yScale; xSurfaceInset = std::round(xSurfaceInset * xScale); ySurfaceInset = std::round(ySurfaceInset * yScale); } // Transform layer size to screen space and inset it by surface insets. Loading @@ -1994,6 +1994,11 @@ InputWindowInfo Layer::fillInputInfo() { layerBounds = getCroppedBufferSize(getDrawingState()); } layerBounds = t.transform(layerBounds); // clamp inset to layer bounds xSurfaceInset = (xSurfaceInset >= 0) ? std::min(xSurfaceInset, layerBounds.getWidth() / 2) : 0; ySurfaceInset = (ySurfaceInset >= 0) ? std::min(ySurfaceInset, layerBounds.getHeight() / 2) : 0; layerBounds.inset(xSurfaceInset, ySurfaceInset, xSurfaceInset, ySurfaceInset); // Input coordinate should match the layer bounds. Loading Loading
libs/gui/tests/EndToEndNativeInputTest.cpp +13 −0 Original line number Diff line number Diff line Loading @@ -410,6 +410,19 @@ TEST_F(InputSurfacesTest, input_respects_scaled_surface_insets) { bgSurface->expectTap(1, 1); } TEST_F(InputSurfacesTest, input_respects_scaled_surface_insets_overflow) { std::unique_ptr<InputSurface> fgSurface = makeSurface(100, 100); // In case we pass the very big inset without any checking. fgSurface->mInputInfo.surfaceInset = INT32_MAX; fgSurface->showAt(100, 100); fgSurface->doTransaction([&](auto &t, auto &sc) { t.setMatrix(sc, 2.0, 0, 0, 2.0); }); // expect no crash for overflow, and inset size to be clamped to surface size injectTap(202, 202); fgSurface->expectTap(1, 1); } // Ensure we ignore transparent region when getting screen bounds when positioning input frame. TEST_F(InputSurfacesTest, input_ignores_transparent_region) { std::unique_ptr<InputSurface> surface = makeSurface(100, 100); Loading
services/surfaceflinger/Layer.cpp +11 −6 Original line number Diff line number Diff line Loading @@ -1975,14 +1975,14 @@ InputWindowInfo Layer::fillInputInfo() { ui::Transform t = getTransform(); const float xScale = t.sx(); const float yScale = t.sy(); float xSurfaceInset = info.surfaceInset; float ySurfaceInset = info.surfaceInset; int32_t xSurfaceInset = info.surfaceInset; int32_t ySurfaceInset = info.surfaceInset; if (xScale != 1.0f || yScale != 1.0f) { info.windowXScale *= 1.0f / xScale; info.windowYScale *= 1.0f / yScale; info.windowXScale *= (xScale != 0.0f) ? 1.0f / xScale : 0.0f; info.windowYScale *= (yScale != 0.0f) ? 1.0f / yScale : 0.0f; info.touchableRegion.scaleSelf(xScale, yScale); xSurfaceInset *= xScale; ySurfaceInset *= yScale; xSurfaceInset = std::round(xSurfaceInset * xScale); ySurfaceInset = std::round(ySurfaceInset * yScale); } // Transform layer size to screen space and inset it by surface insets. Loading @@ -1994,6 +1994,11 @@ InputWindowInfo Layer::fillInputInfo() { layerBounds = getCroppedBufferSize(getDrawingState()); } layerBounds = t.transform(layerBounds); // clamp inset to layer bounds xSurfaceInset = (xSurfaceInset >= 0) ? std::min(xSurfaceInset, layerBounds.getWidth() / 2) : 0; ySurfaceInset = (ySurfaceInset >= 0) ? std::min(ySurfaceInset, layerBounds.getHeight() / 2) : 0; layerBounds.inset(xSurfaceInset, ySurfaceInset, xSurfaceInset, ySurfaceInset); // Input coordinate should match the layer bounds. Loading