blob: 25bc2276c94e69e2833deb975c145a431c40a91a [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 Pradhan47827682024-02-23 19:31:43 +000041 : mTracerThread(
42 "InputTracer", [this]() { threadLoop(); },
43 [this]() { mThreadWakeCondition.notify_all(); }),
44 mBackend(std::move(innerBackend)) {}
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>
56void ThreadedBackend<Backend>::traceMotionEvent(const TracedMotionEvent& event) {
57 std::scoped_lock lock(mLock);
58 mQueue.emplace_back(event);
59 mThreadWakeCondition.notify_all();
60}
61
62template <typename Backend>
63void ThreadedBackend<Backend>::traceKeyEvent(const TracedKeyEvent& event) {
64 std::scoped_lock lock(mLock);
65 mQueue.emplace_back(event);
66 mThreadWakeCondition.notify_all();
67}
68
69template <typename Backend>
70void ThreadedBackend<Backend>::traceWindowDispatch(const WindowDispatchArgs& dispatchArgs) {
71 std::scoped_lock lock(mLock);
72 mQueue.emplace_back(dispatchArgs);
73 mThreadWakeCondition.notify_all();
74}
75
76template <typename Backend>
77void ThreadedBackend<Backend>::threadLoop() {
Prabir Pradhan47827682024-02-23 19:31:43 +000078 std::vector<TraceEntry> entries;
Prabir Pradhanbb7a0202024-02-10 02:09:01 +000079
Prabir Pradhan47827682024-02-23 19:31:43 +000080 { // acquire lock
81 std::unique_lock lock(mLock);
82 base::ScopedLockAssertion assumeLocked(mLock);
Prabir Pradhanbb7a0202024-02-10 02:09:01 +000083
Prabir Pradhan47827682024-02-23 19:31:43 +000084 // Wait until we need to process more events or exit.
85 mThreadWakeCondition.wait(lock,
86 [&]() REQUIRES(mLock) { return mThreadExit || !mQueue.empty(); });
87 if (mThreadExit) {
88 return;
Prabir Pradhanbb7a0202024-02-10 02:09:01 +000089 }
Prabir Pradhan47827682024-02-23 19:31:43 +000090
91 mQueue.swap(entries);
92 } // release lock
93
94 // Trace the events into the backend without holding the lock to reduce the amount of
95 // work performed in the critical section.
96 for (const auto& entry : entries) {
97 std::visit(Visitor{[&](const TracedMotionEvent& e) { mBackend.traceMotionEvent(e); },
98 [&](const TracedKeyEvent& e) { mBackend.traceKeyEvent(e); },
99 [&](const WindowDispatchArgs& args) {
100 mBackend.traceWindowDispatch(args);
101 }},
102 entry);
Prabir Pradhanbb7a0202024-02-10 02:09:01 +0000103 }
Prabir Pradhan47827682024-02-23 19:31:43 +0000104 entries.clear();
Prabir Pradhanbb7a0202024-02-10 02:09:01 +0000105}
106
107// Explicit template instantiation for the PerfettoBackend.
108template class ThreadedBackend<PerfettoBackend>;
109
110} // namespace android::inputdispatcher::trace::impl