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

Commit 0a18c9b0 authored by Prabir Pradhan's avatar Prabir Pradhan Committed by Android (Google) Code Review
Browse files

Merge changes I7370ac64,If07fc359 into main

* changes:
  Use the cloned window's layer stack space for raw coordinates
  InputTarget: s/displayTransform/rawTransform
parents 89530059 72c6990e
Loading
Loading
Loading
Loading
+45 −17
Original line number Diff line number Diff line
@@ -59,6 +59,32 @@ std::ostream& operator<<(std::ostream& out, const Region& region) {
    return out;
}

status_t writeTransform(android::Parcel* parcel, const ui::Transform& transform) {
    return parcel->writeFloat(transform.dsdx()) ?:
            parcel->writeFloat(transform.dtdx()) ?:
            parcel->writeFloat(transform.tx()) ?:
            parcel->writeFloat(transform.dtdy()) ?:
            parcel->writeFloat(transform.dsdy()) ?:
            parcel->writeFloat(transform.ty());
}

status_t readTransform(const android::Parcel* parcel, ui::Transform& transform) {
    float dsdx, dtdx, tx, dtdy, dsdy, ty;

    const status_t status = parcel->readFloat(&dsdx) ?:
            parcel->readFloat(&dtdx) ?:
            parcel->readFloat(&tx) ?:
            parcel->readFloat(&dtdy) ?:
            parcel->readFloat(&dsdy) ?:
            parcel->readFloat(&ty);
    if (status != OK) {
        return status;
    }

    transform.set({dsdx, dtdx, tx, dtdy, dsdy, ty, 0, 0, 1});
    return OK;
}

} // namespace

void WindowInfo::setInputConfig(ftl::Flags<InputConfig> config, bool value) {
@@ -135,12 +161,7 @@ status_t WindowInfo::writeToParcel(android::Parcel* parcel) const {
        parcel->writeInt32(surfaceInset) ?:
        parcel->writeFloat(globalScaleFactor) ?:
        parcel->writeFloat(alpha) ?:
        parcel->writeFloat(transform.dsdx()) ?:
        parcel->writeFloat(transform.dtdx()) ?:
        parcel->writeFloat(transform.tx()) ?:
        parcel->writeFloat(transform.dtdy()) ?:
        parcel->writeFloat(transform.dsdy()) ?:
        parcel->writeFloat(transform.ty()) ?:
        writeTransform(parcel, transform) ?:
        parcel->writeInt32(static_cast<int32_t>(touchOcclusionMode)) ?:
        parcel->writeInt32(ownerPid.val()) ?:
        parcel->writeInt32(ownerUid.val()) ?:
@@ -153,8 +174,12 @@ status_t WindowInfo::writeToParcel(android::Parcel* parcel) const {
        parcel->writeStrongBinder(touchableRegionCropHandle.promote()) ?:
        parcel->writeStrongBinder(windowToken) ?:
        parcel->writeStrongBinder(focusTransferTarget) ?:
        parcel->writeBool(canOccludePresentation);
        parcel->writeBool(canOccludePresentation) ?:
        parcel->writeBool(cloneLayerStackTransform.has_value());
    // clang-format on
    if (cloneLayerStackTransform) {
        status = status ?: writeTransform(parcel, *cloneLayerStackTransform);
    }
    return status;
}

@@ -174,10 +199,10 @@ status_t WindowInfo::readFromParcel(const android::Parcel* parcel) {
        return status;
    }

    float dsdx, dtdx, tx, dtdy, dsdy, ty;
    int32_t lpFlags, lpType, touchOcclusionModeInt, inputConfigInt, ownerPidInt, ownerUidInt,
            displayIdInt;
    sp<IBinder> touchableRegionCropHandleSp;
    bool hasCloneLayerStackTransform = false;

    // clang-format off
    status = parcel->readInt32(&lpFlags) ?:
@@ -188,12 +213,7 @@ status_t WindowInfo::readFromParcel(const android::Parcel* parcel) {
        parcel->readInt32(&surfaceInset) ?:
        parcel->readFloat(&globalScaleFactor) ?:
        parcel->readFloat(&alpha) ?:
        parcel->readFloat(&dsdx) ?:
        parcel->readFloat(&dtdx) ?:
        parcel->readFloat(&tx) ?:
        parcel->readFloat(&dtdy) ?:
        parcel->readFloat(&dsdy) ?:
        parcel->readFloat(&ty) ?:
        readTransform(parcel, /*byRef*/ transform) ?:
        parcel->readInt32(&touchOcclusionModeInt) ?:
        parcel->readInt32(&ownerPidInt) ?:
        parcel->readInt32(&ownerUidInt) ?:
@@ -206,8 +226,8 @@ status_t WindowInfo::readFromParcel(const android::Parcel* parcel) {
        parcel->readNullableStrongBinder(&touchableRegionCropHandleSp) ?:
        parcel->readNullableStrongBinder(&windowToken) ?:
        parcel->readNullableStrongBinder(&focusTransferTarget) ?:
        parcel->readBool(&canOccludePresentation);

        parcel->readBool(&canOccludePresentation)?:
        parcel->readBool(&hasCloneLayerStackTransform);
    // clang-format on

    if (status != OK) {
@@ -216,7 +236,6 @@ status_t WindowInfo::readFromParcel(const android::Parcel* parcel) {

    layoutParamsFlags = ftl::Flags<Flag>(lpFlags);
    layoutParamsType = static_cast<Type>(lpType);
    transform.set({dsdx, dtdx, tx, dtdy, dsdy, ty, 0, 0, 1});
    touchOcclusionMode = static_cast<TouchOcclusionMode>(touchOcclusionModeInt);
    inputConfig = ftl::Flags<InputConfig>(inputConfigInt);
    ownerPid = Pid{ownerPidInt};
@@ -224,6 +243,15 @@ status_t WindowInfo::readFromParcel(const android::Parcel* parcel) {
    touchableRegionCropHandle = touchableRegionCropHandleSp;
    displayId = ui::LogicalDisplayId{displayIdInt};

    cloneLayerStackTransform =
            hasCloneLayerStackTransform ? std::make_optional<ui::Transform>() : std::nullopt;
    if (cloneLayerStackTransform) {
        status = readTransform(parcel, /*byRef*/ *cloneLayerStackTransform);
        if (status != OK) {
            return status;
        }
    }

    return OK;
}

+6 −1
Original line number Diff line number Diff line
@@ -220,9 +220,14 @@ struct WindowInfo : public Parcelable {
    // An alpha of 1.0 means fully opaque and 0.0 means fully transparent.
    float alpha;

    // Transform applied to individual windows.
    // Transform applied to individual windows for input.
    // Maps display coordinates to the window's input coordinate space.
    ui::Transform transform;

    // Transform applied to get to the layer stack space of the cloned window for input.
    // Maps display coordinates of the clone window to the layer stack space of the cloned window.
    std::optional<ui::Transform> cloneLayerStackTransform;

    /*
     * This is filled in by the WM relative to the frame and then translated
     * to absolute coordinates by SurfaceFlinger once the frame is computed.
+15 −1
Original line number Diff line number Diff line
@@ -40,7 +40,18 @@ TEST(WindowInfo, ParcellingWithoutToken) {
    ASSERT_EQ(OK, i.writeToParcel(&p));
    p.setDataPosition(0);
    i2.readFromParcel(&p);
    ASSERT_TRUE(i2.token == nullptr);
    ASSERT_EQ(i2.token, nullptr);
}

TEST(WindowInfo, ParcellingWithoutCloneTransform) {
    WindowInfo i, i2;
    i.cloneLayerStackTransform.reset();

    Parcel p;
    ASSERT_EQ(OK, i.writeToParcel(&p));
    p.setDataPosition(0);
    i2.readFromParcel(&p);
    ASSERT_EQ(i2.cloneLayerStackTransform, std::nullopt);
}

TEST(WindowInfo, Parcelling) {
@@ -71,6 +82,8 @@ TEST(WindowInfo, Parcelling) {
    i.applicationInfo.token = new BBinder();
    i.applicationInfo.dispatchingTimeoutMillis = 0x12345678ABCD;
    i.focusTransferTarget = new BBinder();
    i.cloneLayerStackTransform = ui::Transform();
    i.cloneLayerStackTransform->set({5, -1, 100, 4, 0, 40, 0, 0, 1});

    Parcel p;
    i.writeToParcel(&p);
@@ -100,6 +113,7 @@ TEST(WindowInfo, Parcelling) {
    ASSERT_EQ(i.touchableRegionCropHandle, i2.touchableRegionCropHandle);
    ASSERT_EQ(i.applicationInfo, i2.applicationInfo);
    ASSERT_EQ(i.focusTransferTarget, i2.focusTransferTarget);
    ASSERT_EQ(i.cloneLayerStackTransform, i2.cloneLayerStackTransform);
}

TEST(InputApplicationInfo, Parcelling) {
+10 −0
Original line number Diff line number Diff line
@@ -224,3 +224,13 @@ flag {
  description: "Allow cursor to transition across multiple connected displays"
  bug: "362719483"
}

flag {
  name: "use_cloned_screen_coordinates_as_raw"
  namespace: "input"
  description: "Use the cloned window's layer stack (screen) space as the raw coordinate space for input going to clones"
  bug: "377846505"
  metadata {
    purpose: PURPOSE_BUGFIX
  }
}
+32 −22
Original line number Diff line number Diff line
@@ -418,7 +418,7 @@ std::unique_ptr<DispatchEntry> createDispatchEntry(const IdGenerator& idGenerato
    if (inputTarget.useDefaultPointerTransform() && !zeroCoords) {
        const ui::Transform& transform = inputTarget.getDefaultPointerTransform();
        return std::make_unique<DispatchEntry>(eventEntry, inputTargetFlags, transform,
                                               inputTarget.displayTransform,
                                               inputTarget.rawTransform,
                                               inputTarget.globalScaleFactor, uid, vsyncId,
                                               windowId);
    }
@@ -439,7 +439,7 @@ std::unique_ptr<DispatchEntry> createDispatchEntry(const IdGenerator& idGenerato
        transform =
                &inputTarget.getTransformForPointer(firstMarkedBit(inputTarget.getPointerIds()));
        const ui::Transform inverseTransform = transform->inverse();
        displayTransform = &inputTarget.displayTransform;
        displayTransform = &inputTarget.rawTransform;

        // Iterate through all pointers in the event to normalize against the first.
        for (size_t i = 0; i < motionEntry.getPointerCount(); i++) {
@@ -929,7 +929,7 @@ InputTarget createInputTarget(const std::shared_ptr<Connection>& connection,
                              const sp<android::gui::WindowInfoHandle>& windowHandle,
                              InputTarget::DispatchMode dispatchMode,
                              ftl::Flags<InputTarget::Flags> targetFlags,
                              const ui::Transform& displayTransform,
                              const ui::Transform& rawTransform,
                              std::optional<nsecs_t> firstDownTimeInTarget) {
    LOG_ALWAYS_FATAL_IF(connection == nullptr);
    InputTarget inputTarget{connection};
@@ -937,7 +937,7 @@ InputTarget createInputTarget(const std::shared_ptr<Connection>& connection,
    inputTarget.dispatchMode = dispatchMode;
    inputTarget.flags = targetFlags;
    inputTarget.globalScaleFactor = windowHandle->getInfo()->globalScaleFactor;
    inputTarget.displayTransform = displayTransform;
    inputTarget.rawTransform = rawTransform;
    inputTarget.firstDownTimeInTarget = firstDownTimeInTarget;
    return inputTarget;
}
@@ -3013,10 +3013,9 @@ void InputDispatcher::addWindowTargetLocked(const sp<WindowInfoHandle>& windowHa
                  windowHandle->getName().c_str());
            return;
        }
        inputTargets.push_back(createInputTarget(connection, windowHandle, dispatchMode,
                                                 targetFlags,
                                                 mWindowInfos.getDisplayTransform(
                                                         windowHandle->getInfo()->displayId),
        inputTargets.push_back(
                createInputTarget(connection, windowHandle, dispatchMode, targetFlags,
                                  mWindowInfos.getRawTransform(*windowHandle->getInfo()),
                                  firstDownTimeInTarget));
        it = inputTargets.end() - 1;
    }
@@ -3068,10 +3067,9 @@ void InputDispatcher::addPointerWindowTargetLocked(
                  windowHandle->getName().c_str());
            return;
        }
        inputTargets.push_back(createInputTarget(connection, windowHandle, dispatchMode,
                                                 targetFlags,
                                                 mWindowInfos.getDisplayTransform(
                                                         windowHandle->getInfo()->displayId),
        inputTargets.push_back(
                createInputTarget(connection, windowHandle, dispatchMode, targetFlags,
                                  mWindowInfos.getRawTransform(*windowHandle->getInfo()),
                                  firstDownTimeInTarget));
        it = inputTargets.end() - 1;
    }
@@ -3104,9 +3102,10 @@ void InputDispatcher::addGlobalMonitoringTargetsLocked(std::vector<InputTarget>&
    for (const Monitor& monitor : selectResponsiveMonitorsLocked(monitorsIt->second)) {
        InputTarget target{monitor.connection};
        // target.firstDownTimeInTarget is not set for global monitors. It is only required in split
        // touch and global monitoring works as intended even without setting firstDownTimeInTarget
        target.displayTransform = mWindowInfos.getDisplayTransform(displayId);
        target.setDefaultPointerTransform(target.displayTransform);
        // touch and global monitoring works as intended even without setting firstDownTimeInTarget.
        // Since global monitors don't have windows, use the display transform as the raw transform.
        target.rawTransform = mWindowInfos.getDisplayTransform(displayId);
        target.setDefaultPointerTransform(target.rawTransform);
        inputTargets.push_back(target);
    }
}
@@ -4291,9 +4290,10 @@ void InputDispatcher::synthesizeCancelationEventsForConnectionLocked(
                                                 motionEntry.downTime, targets);
                } else {
                    targets.emplace_back(fallbackTarget);
                    // Since we don't have a window, use the display transform as the raw transform.
                    const ui::Transform displayTransform =
                            mWindowInfos.getDisplayTransform(motionEntry.displayId);
                    targets.back().displayTransform = displayTransform;
                    targets.back().rawTransform = displayTransform;
                    targets.back().setDefaultPointerTransform(displayTransform);
                }
                logOutboundMotionDetails("cancel - ", motionEntry);
@@ -4376,9 +4376,10 @@ void InputDispatcher::synthesizePointerDownEventsForConnectionLocked(
                                                 targets);
                } else {
                    targets.emplace_back(connection, targetFlags);
                    // Since we don't have a window, use the display transform as the raw transform.
                    const ui::Transform displayTransform =
                            mWindowInfos.getDisplayTransform(motionEntry.displayId);
                    targets.back().displayTransform = displayTransform;
                    targets.back().rawTransform = displayTransform;
                    targets.back().setDefaultPointerTransform(displayTransform);
                }
                logOutboundMotionDetails("down - ", motionEntry);
@@ -5289,6 +5290,16 @@ ui::Transform InputDispatcher::DispatcherWindowInfo::getDisplayTransform(
                                                : kIdentityTransform;
}

ui::Transform InputDispatcher::DispatcherWindowInfo::getRawTransform(
        const android::gui::WindowInfo& windowInfo) const {
    // If the window has a cloneLayerStackTransform, always use it as the transform for the "getRaw"
    // APIs. If not, fall back to using the DisplayInfo transform of the window's display.
    return (input_flags::use_cloned_screen_coordinates_as_raw() &&
            windowInfo.cloneLayerStackTransform)
            ? *windowInfo.cloneLayerStackTransform
            : getDisplayTransform(windowInfo.displayId);
}

std::string InputDispatcher::DispatcherWindowInfo::dumpDisplayAndWindowInfo() const {
    std::string dump;
    if (!mWindowHandlesByDisplay.empty()) {
@@ -6567,9 +6578,8 @@ void InputDispatcher::doDispatchCycleFinishedCommand(nsecs_t finishTime,
                                           createInputTarget(connection, windowHandle,
                                                             InputTarget::DispatchMode::AS_IS,
                                                             dispatchEntry->targetFlags,
                                                             mWindowInfos.getDisplayTransform(
                                                                     windowHandle->getInfo()
                                                                             ->displayId),
                                                             mWindowInfos.getRawTransform(
                                                                     *windowHandle->getInfo()),
                                                             downTime));
            }
        }
Loading