Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit e98acad7 authored by TreeHugger Robot's avatar TreeHugger Robot Committed by Android (Google) Code Review
Browse files

Merge "SF: Calculate WindowInfo frame correctly for all layers"

parents e713b77b 6fa425a8
Loading
Loading
Loading
Loading
+2 −1
Original line number Diff line number Diff line
@@ -52,7 +52,8 @@ bool WindowInfo::interceptsStylus() const {
}

bool WindowInfo::overlaps(const WindowInfo* other) const {
    return frameLeft < other->frameRight && frameRight > other->frameLeft &&
    const bool nonEmpty = (frameRight - frameLeft > 0) || (frameBottom - frameTop > 0);
    return nonEmpty && frameLeft < other->frameRight && frameRight > other->frameLeft &&
            frameTop < other->frameBottom && frameBottom > other->frameTop;
}

+76 −0
Original line number Diff line number Diff line
@@ -987,6 +987,82 @@ TEST_F(InputSurfacesTest, drop_input_policy) {
    EXPECT_EQ(surface->consumeEvent(100), nullptr);
}

/**
 * If a cropped layer's touchable region is replaced with a null crop, it should receive input in
 * its own crop.
 */
TEST_F(InputSurfacesTest, cropped_container_replaces_touchable_region_with_null_crop) {
    std::unique_ptr<InputSurface> parentContainer =
            InputSurface::makeContainerInputSurface(mComposerClient, 0, 0);
    std::unique_ptr<InputSurface> containerSurface =
            InputSurface::makeContainerInputSurface(mComposerClient, 100, 100);
    containerSurface->doTransaction(
            [&](auto &t, auto &sc) { t.reparent(sc, parentContainer->mSurfaceControl); });
    containerSurface->mInputInfo.replaceTouchableRegionWithCrop = true;
    containerSurface->mInputInfo.touchableRegionCropHandle = nullptr;
    parentContainer->showAt(10, 10, Rect(0, 0, 20, 20));
    containerSurface->showAt(10, 10, Rect(0, 0, 5, 5));

    // Receives events inside its own crop
    injectTap(21, 21);
    containerSurface->expectTap(1, 1); // Event is in layer space

    // Does not receive events outside its crop
    injectTap(26, 26);
    EXPECT_EQ(containerSurface->consumeEvent(100), nullptr);
}

/**
 * If an un-cropped layer's touchable region is replaced with a null crop, it should receive input
 * in its parent's touchable region. The input events should be in the layer's coordinate space.
 */
TEST_F(InputSurfacesTest, uncropped_container_replaces_touchable_region_with_null_crop) {
    std::unique_ptr<InputSurface> parentContainer =
            InputSurface::makeContainerInputSurface(mComposerClient, 0, 0);
    std::unique_ptr<InputSurface> containerSurface =
            InputSurface::makeContainerInputSurface(mComposerClient, 100, 100);
    containerSurface->doTransaction(
            [&](auto &t, auto &sc) { t.reparent(sc, parentContainer->mSurfaceControl); });
    containerSurface->mInputInfo.replaceTouchableRegionWithCrop = true;
    containerSurface->mInputInfo.touchableRegionCropHandle = nullptr;
    parentContainer->showAt(10, 10, Rect(0, 0, 20, 20));
    containerSurface->showAt(10, 10, Rect::INVALID_RECT);

    // Receives events inside parent bounds
    injectTap(21, 21);
    containerSurface->expectTap(1, 1); // Event is in layer space

    // Does not receive events outside parent bounds
    injectTap(31, 31);
    EXPECT_EQ(containerSurface->consumeEvent(100), nullptr);
}

/**
 * If a layer's touchable region is replaced with a layer crop, it should receive input in the crop
 * layer's bounds. The input events should be in the layer's coordinate space.
 */
TEST_F(InputSurfacesTest, replace_touchable_region_with_crop) {
    std::unique_ptr<InputSurface> cropLayer =
            InputSurface::makeContainerInputSurface(mComposerClient, 0, 0);
    cropLayer->showAt(50, 50, Rect(0, 0, 20, 20));

    std::unique_ptr<InputSurface> containerSurface =
            InputSurface::makeContainerInputSurface(mComposerClient, 100, 100);
    containerSurface->mInputInfo.replaceTouchableRegionWithCrop = true;
    containerSurface->mInputInfo.touchableRegionCropHandle =
            cropLayer->mSurfaceControl->getHandle();
    containerSurface->showAt(10, 10, Rect::INVALID_RECT);

    // Receives events inside crop layer bounds
    injectTap(51, 51);
    containerSurface->expectTap(41, 41); // Event is in layer space

    // Does not receive events outside crop layer bounds
    injectTap(21, 21);
    injectTap(71, 71);
    EXPECT_EQ(containerSurface->consumeEvent(100), nullptr);
}

class MultiDisplayTests : public InputSurfacesTest {
public:
    MultiDisplayTests() : InputSurfacesTest() { ProcessState::self()->startThreadPool(); }
+7 −17
Original line number Diff line number Diff line
@@ -2161,25 +2161,15 @@ Rect Layer::getInputBounds() const {
}

void Layer::fillInputFrameInfo(WindowInfo& info, const ui::Transform& displayTransform) {
    // Transform layer size to screen space and inset it by surface insets.
    // If this is a portal window, set the touchableRegion to the layerBounds.
    Rect layerBounds = info.portalToDisplayId == ADISPLAY_ID_NONE
            ? getInputBounds()
            : info.touchableRegion.getBounds();
    Rect layerBounds = getInputBounds();
    if (!layerBounds.isValid()) {
        layerBounds = getInputBounds();
    }

    if (!layerBounds.isValid()) {
        // If the layer bounds is empty, set the frame to empty and clear the transform
        info.frameLeft = 0;
        info.frameTop = 0;
        info.frameRight = 0;
        info.frameBottom = 0;
        info.transform.reset();
        info.touchableRegion = Region();
        info.flags = WindowInfo::Flag::NOT_TOUCH_MODAL | WindowInfo::Flag::NOT_FOCUSABLE;
        return;
        info.touchableRegion.clear();
        // A layer could have invalid input bounds and still expect to receive touch input if it has
        // replaceTouchableRegionWithCrop. For that case, the input transform needs to be calculated
        // correctly to determine the coordinate space for input events. Use an empty rect so that
        // the layer will receive input in its own layer space.
        layerBounds = Rect::EMPTY_RECT;
    }

    const ui::Transform layerTransform = getInputTransform();
+13 −0
Original line number Diff line number Diff line
@@ -959,6 +959,19 @@ protected:
    bool usingRelativeZ(LayerVector::StateSet) const;

    virtual ui::Transform getInputTransform() const;
    /**
     * Get the bounds in layer space within which this layer can receive input.
     *
     * These bounds are used to:
     * - Determine the input frame for the layer to be used for occlusion detection; and
     * - Determine the coordinate space within which the layer will receive input. The top-left of
     *   this rect will be the origin of the coordinate space that the input events sent to the
     *   layer will be in (prior to accounting for surface insets).
     *
     * The layer can still receive touch input if these bounds are invalid if
     * "replaceTouchableRegionWithCrop" is specified. In this case, the layer will receive input
     * in this layer's space, regardless of the specified crop layer.
     */
    virtual Rect getInputBounds() const;

    // constant