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

Commit adc59b44 authored by Prabir Pradhan's avatar Prabir Pradhan
Browse files

InputTracer: Trace an event being dispatched to a window

Bug: 210460522
Test: manual with perfetto
Change-Id: Ie161726da294bc5c660d5062af85c9cd621c1b4c
parent dae52792
Loading
Loading
Loading
Loading
+6 −2
Original line number Diff line number Diff line
@@ -284,7 +284,8 @@ volatile int32_t DispatchEntry::sNextSeqAtomic;
DispatchEntry::DispatchEntry(std::shared_ptr<const EventEntry> eventEntry,
                             ftl::Flags<InputTarget::Flags> targetFlags,
                             const ui::Transform& transform, const ui::Transform& rawTransform,
                             float globalScaleFactor)
                             float globalScaleFactor, gui::Uid targetUid, int64_t vsyncId,
                             std::optional<int32_t> windowId)
      : seq(nextSeq()),
        eventEntry(std::move(eventEntry)),
        targetFlags(targetFlags),
@@ -292,7 +293,10 @@ DispatchEntry::DispatchEntry(std::shared_ptr<const EventEntry> eventEntry,
        rawTransform(rawTransform),
        globalScaleFactor(globalScaleFactor),
        deliveryTime(0),
        resolvedFlags(0) {
        resolvedFlags(0),
        targetUid(targetUid),
        vsyncId(vsyncId),
        windowId(windowId) {
    switch (this->eventEntry->type) {
        case EventEntry::Type::KEY: {
            const KeyEntry& keyEntry = static_cast<const KeyEntry&>(*this->eventEntry);
+11 −1
Original line number Diff line number Diff line
@@ -227,9 +227,19 @@ struct DispatchEntry {

    int32_t resolvedFlags;

    // Information about the dispatch window used for tracing. We avoid holding a window handle
    // here because information in a window handle may be dynamically updated within the lifespan
    // of this dispatch entry.
    gui::Uid targetUid;
    int64_t vsyncId;
    // The window that this event is targeting. The only case when this windowId is not populated
    // is when dispatching an event to a global monitor.
    std::optional<int32_t> windowId;

    DispatchEntry(std::shared_ptr<const EventEntry> eventEntry,
                  ftl::Flags<InputTarget::Flags> targetFlags, const ui::Transform& transform,
                  const ui::Transform& rawTransform, float globalScaleFactor);
                  const ui::Transform& rawTransform, float globalScaleFactor, gui::Uid targetUid,
                  int64_t vsyncId, std::optional<int32_t> windowId);
    DispatchEntry(const DispatchEntry&) = delete;
    DispatchEntry& operator=(const DispatchEntry&) = delete;

+17 −7
Original line number Diff line number Diff line
@@ -35,6 +35,7 @@
#include <input/PrintTools.h>
#include <input/TraceTools.h>
#include <openssl/mem.h>
#include <private/android_filesystem_config.h>
#include <unistd.h>
#include <utils/Trace.h>

@@ -369,14 +370,22 @@ size_t firstMarkedBit(T set) {
    return i;
}

std::unique_ptr<DispatchEntry> createDispatchEntry(
        const InputTarget& inputTarget, std::shared_ptr<const EventEntry> eventEntry,
        ftl::Flags<InputTarget::Flags> inputTargetFlags) {
std::unique_ptr<DispatchEntry> createDispatchEntry(const InputTarget& inputTarget,
                                                   std::shared_ptr<const EventEntry> eventEntry,
                                                   ftl::Flags<InputTarget::Flags> inputTargetFlags,
                                                   int64_t vsyncId) {
    const sp<WindowInfoHandle> win = inputTarget.windowHandle;
    const std::optional<int32_t> windowId =
            win ? std::make_optional(win->getInfo()->id) : std::nullopt;
    // Assume the only targets that are not associated with a window are global monitors, and use
    // the system UID for global monitors for tracing purposes.
    const gui::Uid uid = win ? win->getInfo()->ownerUid : gui::Uid(AID_SYSTEM);
    if (inputTarget.useDefaultPointerTransform()) {
        const ui::Transform& transform = inputTarget.getDefaultPointerTransform();
        return std::make_unique<DispatchEntry>(eventEntry, inputTargetFlags, transform,
                                               inputTarget.displayTransform,
                                               inputTarget.globalScaleFactor);
                                               inputTarget.globalScaleFactor, uid, vsyncId,
                                               windowId);
    }

    ALOG_ASSERT(eventEntry->type == EventEntry::Type::MOTION);
@@ -423,7 +432,7 @@ std::unique_ptr<DispatchEntry> createDispatchEntry(
    std::unique_ptr<DispatchEntry> dispatchEntry =
            std::make_unique<DispatchEntry>(std::move(combinedMotionEntry), inputTargetFlags,
                                            firstPointerTransform, inputTarget.displayTransform,
                                            inputTarget.globalScaleFactor);
                                            inputTarget.globalScaleFactor, uid, vsyncId, windowId);
    return dispatchEntry;
}

@@ -3345,10 +3354,11 @@ void InputDispatcher::enqueueDispatchEntryAndStartDispatchCycleLocked(
void InputDispatcher::enqueueDispatchEntryLocked(const std::shared_ptr<Connection>& connection,
                                                 std::shared_ptr<const EventEntry> eventEntry,
                                                 const InputTarget& inputTarget) {
    // TODO(b/210460522): Verify all targets excluding global monitors are associated with a window.
    // This is a new event.
    // Enqueue a new dispatch entry onto the outbound queue for this connection.
    std::unique_ptr<DispatchEntry> dispatchEntry =
            createDispatchEntry(inputTarget, eventEntry, inputTarget.flags);
            createDispatchEntry(inputTarget, eventEntry, inputTarget.flags, mWindowInfosVsyncId);

    // Use the eventEntry from dispatchEntry since the entry may have changed and can now be a
    // different EventEntry than what was passed in.
@@ -3467,7 +3477,7 @@ void InputDispatcher::enqueueDispatchEntryLocked(const std::shared_ptr<Connectio
                          << cancelEvent->getDescription();
                std::unique_ptr<DispatchEntry> cancelDispatchEntry =
                        createDispatchEntry(inputTarget, std::move(cancelEvent),
                                            ftl::Flags<InputTarget::Flags>());
                                            ftl::Flags<InputTarget::Flags>(), mWindowInfosVsyncId);

                // Send these cancel events to the queue before sending the event from the new
                // device.
+35 −0
Original line number Diff line number Diff line
@@ -71,4 +71,39 @@ void AndroidInputEventProtoConverter::toProtoKeyEvent(const TracedKeyEvent& even
    outProto.set_policy_flags(event.policyFlags);
}

void AndroidInputEventProtoConverter::toProtoWindowDispatchEvent(
        const InputTracingBackendInterface::WindowDispatchArgs& args,
        proto::AndroidWindowInputDispatchEvent& outProto) {
    std::visit([&](auto entry) { outProto.set_event_id(entry.id); }, args.eventEntry);
    outProto.set_vsync_id(args.vsyncId);
    outProto.set_window_id(args.windowId);
    outProto.set_resolved_flags(args.resolvedFlags);

    if (auto* motion = std::get_if<TracedMotionEvent>(&args.eventEntry); motion != nullptr) {
        for (size_t i = 0; i < motion->pointerProperties.size(); i++) {
            auto* pointerProto = outProto.add_dispatched_pointer();
            pointerProto->set_pointer_id(motion->pointerProperties[i].id);
            const auto rawXY =
                    MotionEvent::calculateTransformedXY(motion->source, args.rawTransform,
                                                        motion->pointerCoords[i].getXYValue());
            pointerProto->set_x_in_display(rawXY.x);
            pointerProto->set_y_in_display(rawXY.y);

            const auto& coords = motion->pointerCoords[i];
            const auto coordsInWindow =
                    MotionEvent::calculateTransformedCoords(motion->source, args.transform, coords);
            auto bits = BitSet64(coords.bits);
            for (int32_t axisIndex = 0; !bits.isEmpty(); axisIndex++) {
                const uint32_t axis = bits.clearFirstMarkedBit();
                const float axisValueInWindow = coordsInWindow.values[axisIndex];
                if (coords.values[axisIndex] != axisValueInWindow) {
                    auto* axisEntry = pointerProto->add_axis_value_in_window();
                    axisEntry->set_axis(axis);
                    axisEntry->set_value(axisValueInWindow);
                }
            }
        }
    }
}

} // namespace android::inputdispatcher::trace
+2 −0
Original line number Diff line number Diff line
@@ -32,6 +32,8 @@ public:
    static void toProtoMotionEvent(const TracedMotionEvent& event,
                                   proto::AndroidMotionEvent& outProto);
    static void toProtoKeyEvent(const TracedKeyEvent& event, proto::AndroidKeyEvent& outProto);
    static void toProtoWindowDispatchEvent(const InputTracingBackendInterface::WindowDispatchArgs&,
                                           proto::AndroidWindowInputDispatchEvent& outProto);
};

} // namespace android::inputdispatcher::trace
Loading