diff options
| -rw-r--r-- | libs/gui/tests/EndToEndNativeInputTest.cpp | 13 | ||||
| -rw-r--r-- | services/surfaceflinger/Layer.cpp | 17 | 
2 files changed, 24 insertions, 6 deletions
diff --git a/libs/gui/tests/EndToEndNativeInputTest.cpp b/libs/gui/tests/EndToEndNativeInputTest.cpp index ff1ba0ad17..386f731d23 100644 --- a/libs/gui/tests/EndToEndNativeInputTest.cpp +++ b/libs/gui/tests/EndToEndNativeInputTest.cpp @@ -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); diff --git a/services/surfaceflinger/Layer.cpp b/services/surfaceflinger/Layer.cpp index f4284fead7..efc989e554 100644 --- a/services/surfaceflinger/Layer.cpp +++ b/services/surfaceflinger/Layer.cpp @@ -2046,14 +2046,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. @@ -2065,6 +2065,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.  |