blob: 161478992743766392464b065131e93287ff27bc [file] [log] [blame]
Prabir Pradhanbb7a0202024-02-10 02:09:01 +00001/*
2 * Copyright 2024 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17#define LOG_TAG "InputTracer"
18
19#include "ThreadedBackend.h"
20
21#include "InputTracingPerfettoBackend.h"
22
23#include <android-base/logging.h>
Prabir Pradhanbb7a0202024-02-10 02:09:01 +000024
25namespace android::inputdispatcher::trace::impl {
26
27namespace {
28
29// Helper to std::visit with lambdas.
30template <typename... V>
31struct Visitor : V... {
32 using V::operator()...;
33};
34
35} // namespace
36
37// --- ThreadedBackend ---
38
39template <typename Backend>
40ThreadedBackend<Backend>::ThreadedBackend(Backend&& innerBackend)
Prabir Pradhan1cdb2fa2024-03-19 17:21:45 +000041 : mBackend(std::move(innerBackend)),
42 mTracerThread(
Prabir Pradhan47827682024-02-23 19:31:43 +000043 "InputTracer", [this]() { threadLoop(); },
Prabir Pradhan1cdb2fa2024-03-19 17:21:45 +000044 [this]() { mThreadWakeCondition.notify_all(); }) {}
Prabir Pradhanbb7a0202024-02-10 02:09:01 +000045
46template <typename Backend>
47ThreadedBackend<Backend>::~ThreadedBackend() {
48 {
49 std::scoped_lock lock(mLock);
50 mThreadExit = true;
51 }
52 mThreadWakeCondition.notify_all();
Prabir Pradhanbb7a0202024-02-10 02:09:01 +000053}
54
55template <typename Backend>
Prabir Pradhan8c3b1432024-02-09 23:34:16 +000056void ThreadedBackend<Backend>::traceMotionEvent(const TracedMotionEvent& event,
57 const TracedEventArgs& traceArgs) {
Prabir Pradhanbb7a0202024-02-10 02:09:01 +000058 std::scoped_lock lock(mLock);
Prabir Pradhan8c3b1432024-02-09 23:34:16 +000059 mQueue.emplace_back(event, traceArgs);
Prabir Pradhanbb7a0202024-02-10 02:09:01 +000060 mThreadWakeCondition.notify_all();
61}
62
63template <typename Backend>
Prabir Pradhan8c3b1432024-02-09 23:34:16 +000064void ThreadedBackend<Backend>::traceKeyEvent(const TracedKeyEvent& event,
65 const TracedEventArgs& traceArgs) {
Prabir Pradhanbb7a0202024-02-10 02:09:01 +000066 std::scoped_lock lock(mLock);
Prabir Pradhan8c3b1432024-02-09 23:34:16 +000067 mQueue.emplace_back(event, traceArgs);
Prabir Pradhanbb7a0202024-02-10 02:09:01 +000068 mThreadWakeCondition.notify_all();
69}
70
71template <typename Backend>
Prabir Pradhan8c3b1432024-02-09 23:34:16 +000072void ThreadedBackend<Backend>::traceWindowDispatch(const WindowDispatchArgs& dispatchArgs,
73 const TracedEventArgs& traceArgs) {
Prabir Pradhanbb7a0202024-02-10 02:09:01 +000074 std::scoped_lock lock(mLock);
Prabir Pradhan8c3b1432024-02-09 23:34:16 +000075 mQueue.emplace_back(dispatchArgs, traceArgs);
Prabir Pradhanbb7a0202024-02-10 02:09:01 +000076 mThreadWakeCondition.notify_all();
77}
78
79template <typename Backend>
80void ThreadedBackend<Backend>::threadLoop() {
Prabir Pradhan47827682024-02-23 19:31:43 +000081 std::vector<TraceEntry> entries;
Prabir Pradhanbb7a0202024-02-10 02:09:01 +000082
Prabir Pradhan47827682024-02-23 19:31:43 +000083 { // acquire lock
84 std::unique_lock lock(mLock);
85 base::ScopedLockAssertion assumeLocked(mLock);
Prabir Pradhanbb7a0202024-02-10 02:09:01 +000086
Prabir Pradhan47827682024-02-23 19:31:43 +000087 // Wait until we need to process more events or exit.
88 mThreadWakeCondition.wait(lock,
89 [&]() REQUIRES(mLock) { return mThreadExit || !mQueue.empty(); });
90 if (mThreadExit) {
91 return;
Prabir Pradhanbb7a0202024-02-10 02:09:01 +000092 }
Prabir Pradhan47827682024-02-23 19:31:43 +000093
94 mQueue.swap(entries);
95 } // release lock
96
97 // Trace the events into the backend without holding the lock to reduce the amount of
98 // work performed in the critical section.
Prabir Pradhan8c3b1432024-02-09 23:34:16 +000099 for (const auto& [entry, traceArgs] : entries) {
100 std::visit(Visitor{[&](const TracedMotionEvent& e) {
101 mBackend.traceMotionEvent(e, traceArgs);
102 },
103 [&](const TracedKeyEvent& e) { mBackend.traceKeyEvent(e, traceArgs); },
Prabir Pradhan47827682024-02-23 19:31:43 +0000104 [&](const WindowDispatchArgs& args) {
Prabir Pradhan8c3b1432024-02-09 23:34:16 +0000105 mBackend.traceWindowDispatch(args, traceArgs);
Prabir Pradhan47827682024-02-23 19:31:43 +0000106 }},
107 entry);
Prabir Pradhanbb7a0202024-02-10 02:09:01 +0000108 }
Prabir Pradhan47827682024-02-23 19:31:43 +0000109 entries.clear();
Prabir Pradhanbb7a0202024-02-10 02:09:01 +0000110}
111
112// Explicit template instantiation for the PerfettoBackend.
113template class ThreadedBackend<PerfettoBackend>;
114
115} // namespace android::inputdispatcher::trace::impl