Loading services/inputflinger/InputCommonConverter.cpp +30 −0 Original line number Diff line number Diff line Loading @@ -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"); Loading Loading @@ -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 services/inputflinger/InputCommonConverter.h +13 −4 Original line number Diff line number Diff line Loading @@ -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 services/inputflinger/dispatcher/trace/InputTracingPerfettoBackend.cpp +13 −1 Original line number Diff line number Diff line Loading @@ -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}; Loading @@ -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. Loading @@ -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; Loading @@ -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; Loading @@ -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; Loading services/inputflinger/dispatcher/trace/InputTracingPerfettoBackend.h +3 −0 Original line number Diff line number Diff line Loading @@ -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; Loading @@ -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(); Loading services/inputflinger/dispatcher/trace/ThreadedBackend.cpp +35 −0 Original line number Diff line number Diff line Loading @@ -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 Loading @@ -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 Loading
services/inputflinger/InputCommonConverter.cpp +30 −0 Original line number Diff line number Diff line Loading @@ -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"); Loading Loading @@ -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
services/inputflinger/InputCommonConverter.h +13 −4 Original line number Diff line number Diff line Loading @@ -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
services/inputflinger/dispatcher/trace/InputTracingPerfettoBackend.cpp +13 −1 Original line number Diff line number Diff line Loading @@ -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}; Loading @@ -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. Loading @@ -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; Loading @@ -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; Loading @@ -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; Loading
services/inputflinger/dispatcher/trace/InputTracingPerfettoBackend.h +3 −0 Original line number Diff line number Diff line Loading @@ -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; Loading @@ -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(); Loading
services/inputflinger/dispatcher/trace/ThreadedBackend.cpp +35 −0 Original line number Diff line number Diff line Loading @@ -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 Loading @@ -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