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

Commit 6fabeece authored by Vishnu Nair's avatar Vishnu Nair
Browse files

Input: Override touchable region bounds with surface bounds 2/2

Take advantage of the surface flinger layer hierarchy to set touchable
region.

- Let a client set a surface touchable region to its own bounds.
- Let a client set a surface touchable region to another surface bounds.
- Let a client bound its touchable region to a surface.

Test: go/wm-smoke
Test: existing tests

Change-Id: I447c93353d067a296007ba8f8341d2420b941d71
parent 9f166127
Loading
Loading
Loading
Loading
+3 −1
Original line number Diff line number Diff line
@@ -165,6 +165,8 @@ struct InputWindowInfo {
    int32_t displayId;
    int32_t portalToDisplayId = ADISPLAY_ID_NONE;
    InputApplicationInfo applicationInfo;
    bool replaceTouchableRegionWithCrop;
    wp<IBinder> touchableRegionCropHandle;

    void addTouchableRegion(const Rect& region);

+4 −1
Original line number Diff line number Diff line
@@ -98,7 +98,8 @@ status_t InputWindowInfo::write(Parcel& output) const {
    output.writeInt32(portalToDisplayId);
    applicationInfo.write(output);
    output.write(touchableRegion);

    output.writeBool(replaceTouchableRegionWithCrop);
    output.writeWeakBinder(touchableRegionCropHandle);
    return OK;
}

@@ -140,6 +141,8 @@ InputWindowInfo InputWindowInfo::read(const Parcel& from) {
    ret.portalToDisplayId = from.readInt32();
    ret.applicationInfo = InputApplicationInfo::read(from);
    from.read(ret.touchableRegion);
    ret.replaceTouchableRegionWithCrop = from.readBool();
    ret.touchableRegionCropHandle = from.readWeakBinder();

    return ret;
}
+5 −0
Original line number Diff line number Diff line
@@ -37,6 +37,7 @@ TEST(InputWindowInfo, ParcellingWithoutToken) {
}

TEST(InputWindowInfo, Parcelling) {
    sp<IBinder> touchableRegionCropHandle = new BBinder();
    InputWindowInfo i;
    i.token = new BBinder();
    i.name = "Foobar";
@@ -62,6 +63,8 @@ TEST(InputWindowInfo, Parcelling) {
    i.inputFeatures = 29;
    i.displayId = 34;
    i.portalToDisplayId = 2;
    i.replaceTouchableRegionWithCrop = true;
    i.touchableRegionCropHandle = touchableRegionCropHandle;

    Parcel p;
    i.write(p);
@@ -92,6 +95,8 @@ TEST(InputWindowInfo, Parcelling) {
    ASSERT_EQ(i.inputFeatures, i2.inputFeatures);
    ASSERT_EQ(i.displayId, i2.displayId);
    ASSERT_EQ(i.portalToDisplayId, i2.portalToDisplayId);
    ASSERT_EQ(i.replaceTouchableRegionWithCrop, i2.replaceTouchableRegionWithCrop);
    ASSERT_EQ(i.touchableRegionCropHandle, i2.touchableRegionCropHandle);
}

} // namespace test
+28 −0
Original line number Diff line number Diff line
@@ -2009,8 +2009,24 @@ void Layer::commitChildList() {
    mDrawingParent = mCurrentParent;
}

static wp<Layer> extractLayerFromBinder(const wp<IBinder>& weakBinderHandle) {
    if (weakBinderHandle == nullptr) {
        return nullptr;
    }
    sp<IBinder> binderHandle = weakBinderHandle.promote();
    if (binderHandle == nullptr) {
        return nullptr;
    }
    sp<Layer::Handle> handle = static_cast<Layer::Handle*>(binderHandle.get());
    if (handle == nullptr) {
        return nullptr;
    }
    return handle->owner;
}

void Layer::setInputInfo(const InputWindowInfo& info) {
    mCurrentState.inputInfo = info;
    mCurrentState.touchableRegionCrop = extractLayerFromBinder(info.touchableRegionCropHandle);
    mCurrentState.modified = true;
    mCurrentState.inputInfoChanged = true;
    setTransactionFlags(eTransactionNeeded);
@@ -2199,6 +2215,18 @@ InputWindowInfo Layer::fillInputInfo() {
    // bounds.
    info.touchableRegion = info.touchableRegion.translate(info.frameLeft, info.frameTop);
    info.visible = canReceiveInput();

    auto cropLayer = mDrawingState.touchableRegionCrop.promote();
    if (info.replaceTouchableRegionWithCrop) {
        if (cropLayer == nullptr) {
            info.touchableRegion = Region(Rect{mScreenBounds});
        } else {
            info.touchableRegion = Region(Rect{cropLayer->mScreenBounds});
        }
    } else if (cropLayer != nullptr) {
        info.touchableRegion = info.touchableRegion.intersect(Rect{cropLayer->mScreenBounds});
    }

    return info;
}

+1 −0
Original line number Diff line number Diff line
@@ -181,6 +181,7 @@ public:

        bool inputInfoChanged;
        InputWindowInfo inputInfo;
        wp<Layer> touchableRegionCrop;

        // The fields below this point are only used by BufferStateLayer
        Geometry active;