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

Commit 6a0291e0 authored by Treehugger Robot's avatar Treehugger Robot Committed by Android (Google) Code Review
Browse files

Merge "InputTracer: Add tests for perfetto backend" into main

parents 599efb3e 9a9897d1
Loading
Loading
Loading
Loading
+30 −0
Original line number Diff line number Diff line
@@ -20,6 +20,9 @@ using namespace ::aidl::android::hardware::input;

namespace android {

const static ui::Transform kIdentityTransform;
const static std::array<uint8_t, 32> kInvalidHmac{};

static common::Source getSource(uint32_t source) {
    static_assert(static_cast<common::Source>(AINPUT_SOURCE_UNKNOWN) == common::Source::UNKNOWN,
                  "SOURCE_UNKNOWN mismatch");
@@ -337,4 +340,31 @@ common::MotionEvent notifyMotionArgsToHalMotionEvent(const NotifyMotionArgs& arg
    return event;
}

MotionEvent toMotionEvent(const NotifyMotionArgs& args, const ui::Transform* transform,
                          const ui::Transform* rawTransform, const std::array<uint8_t, 32>* hmac) {
    if (transform == nullptr) transform = &kIdentityTransform;
    if (rawTransform == nullptr) rawTransform = &kIdentityTransform;
    if (hmac == nullptr) hmac = &kInvalidHmac;

    MotionEvent event;
    event.initialize(args.id, args.deviceId, args.source, args.displayId, *hmac, args.action,
                     args.actionButton, args.flags, args.edgeFlags, args.metaState,
                     args.buttonState, args.classification, *transform, args.xPrecision,
                     args.yPrecision, args.xCursorPosition, args.yCursorPosition, *rawTransform,
                     args.downTime, args.eventTime, args.getPointerCount(),
                     args.pointerProperties.data(), args.pointerCoords.data());
    return event;
}

KeyEvent toKeyEvent(const NotifyKeyArgs& args, int32_t repeatCount,
                    const std::array<uint8_t, 32>* hmac) {
    if (hmac == nullptr) hmac = &kInvalidHmac;

    KeyEvent event;
    event.initialize(args.id, args.deviceId, args.source, args.displayId, *hmac, args.action,
                     args.flags, args.keyCode, args.scanCode, args.metaState, repeatCount,
                     args.downTime, args.eventTime);
    return event;
}

} // namespace android
+13 −4
Original line number Diff line number Diff line
@@ -16,16 +16,25 @@

#pragma once

#include "InputListener.h"

#include <aidl/android/hardware/input/common/Axis.h>
#include <aidl/android/hardware/input/common/MotionEvent.h>
#include "InputListener.h"
#include <input/Input.h>

namespace android {

/**
 * Convert from framework's NotifyMotionArgs to hidl's common::MotionEvent
 */
/** Convert from framework's NotifyMotionArgs to hidl's common::MotionEvent. */
::aidl::android::hardware::input::common::MotionEvent notifyMotionArgsToHalMotionEvent(
        const NotifyMotionArgs& args);

/** Convert from NotifyMotionArgs to MotionEvent. */
MotionEvent toMotionEvent(const NotifyMotionArgs&, const ui::Transform* transform = nullptr,
                          const ui::Transform* rawTransform = nullptr,
                          const std::array<uint8_t, 32>* hmac = nullptr);

/** Convert from NotifyKeyArgs to KeyEvent. */
KeyEvent toKeyEvent(const NotifyKeyArgs&, int32_t repeatCount = 0,
                    const std::array<uint8_t, 32>* hmac = nullptr);

} // namespace android
+13 −1
Original line number Diff line number Diff line
@@ -149,6 +149,8 @@ bool PerfettoBackend::InputEventDataSource::ruleMatches(const TraceRule& rule,

// --- PerfettoBackend ---

bool PerfettoBackend::sUseInProcessBackendForTest{false};

std::once_flag PerfettoBackend::sDataSourceRegistrationFlag{};

std::atomic<int32_t> PerfettoBackend::sNextInstanceId{1};
@@ -159,7 +161,8 @@ PerfettoBackend::PerfettoBackend(GetPackageUid getPackagesForUid)
    // we never unregister the InputEventDataSource.
    std::call_once(sDataSourceRegistrationFlag, []() {
        perfetto::TracingInitArgs args;
        args.backends = perfetto::kSystemBackend;
        args.backends = sUseInProcessBackendForTest ? perfetto::kInProcessBackend
                                                    : perfetto::kSystemBackend;
        perfetto::Tracing::Initialize(args);

        // Register our custom data source for input event tracing.
@@ -175,6 +178,9 @@ void PerfettoBackend::traceMotionEvent(const TracedMotionEvent& event,
                                       const TracedEventMetadata& metadata) {
    InputEventDataSource::Trace([&](InputEventDataSource::TraceContext ctx) {
        auto dataSource = ctx.GetDataSourceLocked();
        if (!dataSource.valid()) {
            return;
        }
        dataSource->initializeUidMap(mGetPackageUid);
        if (dataSource->shouldIgnoreTracedInputEvent(event.eventType)) {
            return;
@@ -196,6 +202,9 @@ void PerfettoBackend::traceKeyEvent(const TracedKeyEvent& event,
                                    const TracedEventMetadata& metadata) {
    InputEventDataSource::Trace([&](InputEventDataSource::TraceContext ctx) {
        auto dataSource = ctx.GetDataSourceLocked();
        if (!dataSource.valid()) {
            return;
        }
        dataSource->initializeUidMap(mGetPackageUid);
        if (dataSource->shouldIgnoreTracedInputEvent(event.eventType)) {
            return;
@@ -217,6 +226,9 @@ void PerfettoBackend::traceWindowDispatch(const WindowDispatchArgs& dispatchArgs
                                          const TracedEventMetadata& metadata) {
    InputEventDataSource::Trace([&](InputEventDataSource::TraceContext ctx) {
        auto dataSource = ctx.GetDataSourceLocked();
        if (!dataSource.valid()) {
            return;
        }
        dataSource->initializeUidMap(mGetPackageUid);
        if (!dataSource->getFlags().test(TraceFlag::TRACE_DISPATCHER_WINDOW_DISPATCH)) {
            return;
+3 −0
Original line number Diff line number Diff line
@@ -51,6 +51,8 @@ class PerfettoBackend : public InputTracingBackendInterface {
public:
    using GetPackageUid = std::function<gui::Uid(std::string)>;

    static bool sUseInProcessBackendForTest;

    explicit PerfettoBackend(GetPackageUid);
    ~PerfettoBackend() override = default;

@@ -61,6 +63,7 @@ public:
private:
    // Implementation of the perfetto data source.
    // Each instance of the InputEventDataSource represents a different tracing session.
    // Its lifecycle is controlled by perfetto.
    class InputEventDataSource : public perfetto::DataSource<InputEventDataSource> {
    public:
        explicit InputEventDataSource();
+35 −0
Original line number Diff line number Diff line
@@ -84,13 +84,18 @@ void ThreadedBackend<Backend>::threadLoop() {
        std::unique_lock lock(mLock);
        base::ScopedLockAssertion assumeLocked(mLock);

        setIdleStatus(true);

        // Wait until we need to process more events or exit.
        mThreadWakeCondition.wait(lock,
                                  [&]() REQUIRES(mLock) { return mThreadExit || !mQueue.empty(); });
        if (mThreadExit) {
            setIdleStatus(true);
            return;
        }

        setIdleStatus(false);

        mQueue.swap(entries);
    } // release lock

@@ -109,6 +114,36 @@ void ThreadedBackend<Backend>::threadLoop() {
    entries.clear();
}

template <typename Backend>
std::function<void()> ThreadedBackend<Backend>::getIdleWaiterForTesting() {
    std::scoped_lock lock(mLock);
    if (!mIdleWaiter) {
        mIdleWaiter = std::make_shared<IdleWaiter>();
    }

    // Return a lambda that holds a strong reference to the idle waiter, whose lifetime can extend
    // beyond this threaded backend object.
    return [idleWaiter = mIdleWaiter]() {
        std::unique_lock idleLock(idleWaiter->idleLock);
        base::ScopedLockAssertion assumeLocked(idleWaiter->idleLock);
        idleWaiter->threadIdleCondition.wait(idleLock, [&]() REQUIRES(idleWaiter->idleLock) {
            return idleWaiter->isIdle;
        });
    };
}

template <typename Backend>
void ThreadedBackend<Backend>::setIdleStatus(bool isIdle) {
    if (!mIdleWaiter) {
        return;
    }
    std::scoped_lock idleLock(mIdleWaiter->idleLock);
    mIdleWaiter->isIdle = isIdle;
    if (isIdle) {
        mIdleWaiter->threadIdleCondition.notify_all();
    }
}

// Explicit template instantiation for the PerfettoBackend.
template class ThreadedBackend<PerfettoBackend>;

Loading