blob: d7762493c359ff08895d7f175b0510a5fb957817 [file] [log] [blame]
Prabir Pradhandae52792023-12-15 07:36:40 +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 "InputTracer.h"
20
21#include <android-base/logging.h>
22
23namespace android::inputdispatcher::trace::impl {
24
25namespace {
26
Prabir Pradhanbb7a0202024-02-10 02:09:01 +000027// Helper to std::visit with lambdas.
28template <typename... V>
29struct Visitor : V... {
30 using V::operator()...;
31};
32
Prabir Pradhan4c49aad2024-02-08 20:42:35 +000033TracedEvent createTracedEvent(const MotionEntry& e, EventType type) {
Prabir Pradhandae52792023-12-15 07:36:40 +000034 return TracedMotionEvent{e.id,
35 e.eventTime,
36 e.policyFlags,
37 e.deviceId,
38 e.source,
39 e.displayId,
40 e.action,
41 e.actionButton,
42 e.flags,
43 e.metaState,
44 e.buttonState,
45 e.classification,
46 e.edgeFlags,
47 e.xPrecision,
48 e.yPrecision,
49 e.xCursorPosition,
50 e.yCursorPosition,
51 e.downTime,
52 e.pointerProperties,
Prabir Pradhan4c49aad2024-02-08 20:42:35 +000053 e.pointerCoords,
54 type};
Prabir Pradhandae52792023-12-15 07:36:40 +000055}
56
Prabir Pradhan4c49aad2024-02-08 20:42:35 +000057TracedEvent createTracedEvent(const KeyEntry& e, EventType type) {
Prabir Pradhandae52792023-12-15 07:36:40 +000058 return TracedKeyEvent{e.id, e.eventTime, e.policyFlags, e.deviceId, e.source,
59 e.displayId, e.action, e.keyCode, e.scanCode, e.metaState,
Prabir Pradhan4c49aad2024-02-08 20:42:35 +000060 e.downTime, e.flags, e.repeatCount, type};
Prabir Pradhandae52792023-12-15 07:36:40 +000061}
62
Prabir Pradhan8c3b1432024-02-09 23:34:16 +000063void writeEventToBackend(const TracedEvent& event, const TracedEventArgs args,
64 InputTracingBackendInterface& backend) {
65 std::visit(Visitor{[&](const TracedMotionEvent& e) { backend.traceMotionEvent(e, args); },
66 [&](const TracedKeyEvent& e) { backend.traceKeyEvent(e, args); }},
Prabir Pradhana67623c2024-02-21 06:57:36 +000067 event);
68}
69
Prabir Pradhand6b2b052024-02-21 23:25:15 +000070inline auto getId(const trace::TracedEvent& v) {
71 return std::visit([](const auto& event) { return event.id; }, v);
72}
73
Prabir Pradhandae52792023-12-15 07:36:40 +000074} // namespace
75
76// --- InputTracer ---
77
78InputTracer::InputTracer(std::unique_ptr<InputTracingBackendInterface> backend)
Prabir Pradhanbb7a0202024-02-10 02:09:01 +000079 : mBackend(std::move(backend)) {}
Prabir Pradhandae52792023-12-15 07:36:40 +000080
81std::unique_ptr<EventTrackerInterface> InputTracer::traceInboundEvent(const EventEntry& entry) {
Prabir Pradhana67623c2024-02-21 06:57:36 +000082 // This is a newly traced inbound event. Create a new state to track it and its derived events.
83 auto eventState = std::make_shared<EventState>(*this);
Prabir Pradhandae52792023-12-15 07:36:40 +000084
85 if (entry.type == EventEntry::Type::MOTION) {
86 const auto& motion = static_cast<const MotionEntry&>(entry);
Prabir Pradhan4c49aad2024-02-08 20:42:35 +000087 eventState->events.emplace_back(createTracedEvent(motion, EventType::INBOUND));
Prabir Pradhandae52792023-12-15 07:36:40 +000088 } else if (entry.type == EventEntry::Type::KEY) {
89 const auto& key = static_cast<const KeyEntry&>(entry);
Prabir Pradhan4c49aad2024-02-08 20:42:35 +000090 eventState->events.emplace_back(createTracedEvent(key, EventType::INBOUND));
Prabir Pradhandae52792023-12-15 07:36:40 +000091 } else {
92 LOG(FATAL) << "Cannot trace EventEntry of type: " << ftl::enum_string(entry.type);
93 }
94
Prabir Pradhana67623c2024-02-21 06:57:36 +000095 return std::make_unique<EventTrackerImpl>(std::move(eventState), /*isDerived=*/false);
Prabir Pradhandae52792023-12-15 07:36:40 +000096}
97
Prabir Pradhand6b2b052024-02-21 23:25:15 +000098std::unique_ptr<EventTrackerInterface> InputTracer::createTrackerForSyntheticEvent() {
99 // Create a new EventState to track events derived from this tracker.
100 return std::make_unique<EventTrackerImpl>(std::make_shared<EventState>(*this),
101 /*isDerived=*/false);
102}
103
Prabir Pradhandae52792023-12-15 07:36:40 +0000104void InputTracer::dispatchToTargetHint(const EventTrackerInterface& cookie,
105 const InputTarget& target) {
Prabir Pradhan1ea04a32024-02-10 03:02:59 +0000106 auto& eventState = getState(cookie);
Prabir Pradhana67623c2024-02-21 06:57:36 +0000107 if (eventState->isEventProcessingComplete) {
108 // TODO(b/210460522): Disallow adding new targets after eventProcessingComplete() is called.
109 return;
Prabir Pradhandae52792023-12-15 07:36:40 +0000110 }
Prabir Pradhanb95d4aa2024-03-11 22:48:04 +0000111 if (isDerivedCookie(cookie)) {
112 // TODO(b/210460522): Disallow adding new targets from a derived cookie.
113 return;
114 }
Prabir Pradhan8c3b1432024-02-09 23:34:16 +0000115 if (target.windowHandle != nullptr) {
116 eventState->isSecure |= target.windowHandle->getInfo()->layoutParamsFlags.test(
117 gui::WindowInfo::Flag::SECURE);
118 // TODO(b/210460522): Set events as sensitive when the IME connection is active.
119 }
Prabir Pradhandae52792023-12-15 07:36:40 +0000120}
121
122void InputTracer::eventProcessingComplete(const EventTrackerInterface& cookie) {
Prabir Pradhana67623c2024-02-21 06:57:36 +0000123 if (isDerivedCookie(cookie)) {
124 LOG(FATAL) << "Event processing cannot be set from a derived cookie.";
125 }
Prabir Pradhan1ea04a32024-02-10 03:02:59 +0000126 auto& eventState = getState(cookie);
Prabir Pradhana67623c2024-02-21 06:57:36 +0000127 if (eventState->isEventProcessingComplete) {
Prabir Pradhanbb7a0202024-02-10 02:09:01 +0000128 LOG(FATAL) << "Traced event was already logged. "
129 "eventProcessingComplete() was likely called more than once.";
130 }
Prabir Pradhane7701642024-02-22 04:06:53 +0000131 eventState->onEventProcessingComplete();
Prabir Pradhana67623c2024-02-21 06:57:36 +0000132}
133
134std::unique_ptr<EventTrackerInterface> InputTracer::traceDerivedEvent(
135 const EventEntry& entry, const EventTrackerInterface& originalEventCookie) {
136 // This is an event derived from an already-established event. Use the same state to track
137 // this event too.
138 auto eventState = getState(originalEventCookie);
139
140 if (entry.type == EventEntry::Type::MOTION) {
141 const auto& motion = static_cast<const MotionEntry&>(entry);
Prabir Pradhan4c49aad2024-02-08 20:42:35 +0000142 eventState->events.emplace_back(createTracedEvent(motion, EventType::SYNTHESIZED));
Prabir Pradhana67623c2024-02-21 06:57:36 +0000143 } else if (entry.type == EventEntry::Type::KEY) {
144 const auto& key = static_cast<const KeyEntry&>(entry);
Prabir Pradhan4c49aad2024-02-08 20:42:35 +0000145 eventState->events.emplace_back(createTracedEvent(key, EventType::SYNTHESIZED));
Prabir Pradhana67623c2024-02-21 06:57:36 +0000146 } else {
147 LOG(FATAL) << "Cannot trace EventEntry of type: " << ftl::enum_string(entry.type);
148 }
149
150 if (eventState->isEventProcessingComplete) {
151 // It is possible for a derived event to be dispatched some time after the original event
152 // is dispatched, such as in the case of key fallback events. To account for these cases,
153 // derived events can be traced after the processing is complete for the original event.
Prabir Pradhan4c49aad2024-02-08 20:42:35 +0000154 const auto& event = eventState->events.back();
Prabir Pradhan8c3b1432024-02-09 23:34:16 +0000155 const TracedEventArgs traceArgs{.isSecure = eventState->isSecure};
Prabir Pradhan4c49aad2024-02-08 20:42:35 +0000156 writeEventToBackend(event, traceArgs, *mBackend);
Prabir Pradhana67623c2024-02-21 06:57:36 +0000157 }
158 return std::make_unique<EventTrackerImpl>(std::move(eventState), /*isDerived=*/true);
Prabir Pradhandae52792023-12-15 07:36:40 +0000159}
160
161void InputTracer::traceEventDispatch(const DispatchEntry& dispatchEntry,
Prabir Pradhand6b2b052024-02-21 23:25:15 +0000162 const EventTrackerInterface& cookie) {
163 auto& eventState = getState(cookie);
Prabir Pradhanbb7a0202024-02-10 02:09:01 +0000164 const EventEntry& entry = *dispatchEntry.eventEntry;
Prabir Pradhan4c49aad2024-02-08 20:42:35 +0000165 const int32_t eventId = entry.id;
Prabir Pradhan560d0d12024-03-07 18:08:27 +0000166 // TODO(b/328618922): Remove resolved key repeats after making repeatCount non-mutable.
167 // The KeyEntry's repeatCount is mutable and can be modified after an event is initially traced,
168 // so we need to find the repeatCount at the time of dispatching to trace it accurately.
169 int32_t resolvedKeyRepeatCount = 0;
Prabir Pradhan4c49aad2024-02-08 20:42:35 +0000170 if (entry.type == EventEntry::Type::KEY) {
171 resolvedKeyRepeatCount = static_cast<const KeyEntry&>(entry).repeatCount;
Prabir Pradhanbb7a0202024-02-10 02:09:01 +0000172 }
Prabir Pradhanadc59b42023-12-15 05:34:11 +0000173
Prabir Pradhand6b2b052024-02-21 23:25:15 +0000174 auto tracedEventIt =
175 std::find_if(eventState->events.begin(), eventState->events.end(),
Prabir Pradhan4c49aad2024-02-08 20:42:35 +0000176 [eventId](const auto& event) { return eventId == getId(event); });
Prabir Pradhand6b2b052024-02-21 23:25:15 +0000177 if (tracedEventIt == eventState->events.end()) {
178 LOG(FATAL)
179 << __func__
180 << ": Failed to find a previously traced event that matches the dispatched event";
Prabir Pradhanbb7a0202024-02-10 02:09:01 +0000181 }
Prabir Pradhanadc59b42023-12-15 05:34:11 +0000182
Prabir Pradhanbb7a0202024-02-10 02:09:01 +0000183 // The vsyncId only has meaning if the event is targeting a window.
184 const int32_t windowId = dispatchEntry.windowId.value_or(0);
185 const int32_t vsyncId = dispatchEntry.windowId.has_value() ? dispatchEntry.vsyncId : 0;
Prabir Pradhanadc59b42023-12-15 05:34:11 +0000186
Prabir Pradhan8c3b1432024-02-09 23:34:16 +0000187 // TODO(b/210460522): Pass HMAC into traceEventDispatch.
Prabir Pradhan4c49aad2024-02-08 20:42:35 +0000188 const WindowDispatchArgs windowDispatchArgs{*tracedEventIt,
Prabir Pradhan52ec3ff2024-02-22 03:26:38 +0000189 dispatchEntry.deliveryTime,
190 dispatchEntry.resolvedFlags,
191 dispatchEntry.targetUid,
192 vsyncId,
193 windowId,
194 dispatchEntry.transform,
195 dispatchEntry.rawTransform,
196 /*hmac=*/{},
197 resolvedKeyRepeatCount};
198 if (eventState->isEventProcessingComplete) {
Prabir Pradhan8c3b1432024-02-09 23:34:16 +0000199 mBackend->traceWindowDispatch(std::move(windowDispatchArgs),
200 TracedEventArgs{.isSecure = eventState->isSecure});
Prabir Pradhan52ec3ff2024-02-22 03:26:38 +0000201 } else {
202 eventState->pendingDispatchArgs.emplace_back(std::move(windowDispatchArgs));
203 }
Prabir Pradhanadc59b42023-12-15 05:34:11 +0000204}
Prabir Pradhandae52792023-12-15 07:36:40 +0000205
Prabir Pradhana67623c2024-02-21 06:57:36 +0000206std::shared_ptr<InputTracer::EventState>& InputTracer::getState(
207 const EventTrackerInterface& cookie) {
Prabir Pradhanbb7a0202024-02-10 02:09:01 +0000208 return static_cast<const EventTrackerImpl&>(cookie).mState;
Prabir Pradhandae52792023-12-15 07:36:40 +0000209}
210
Prabir Pradhana67623c2024-02-21 06:57:36 +0000211bool InputTracer::isDerivedCookie(const EventTrackerInterface& cookie) {
212 return static_cast<const EventTrackerImpl&>(cookie).mIsDerived;
213}
Prabir Pradhandae52792023-12-15 07:36:40 +0000214
Prabir Pradhana67623c2024-02-21 06:57:36 +0000215// --- InputTracer::EventState ---
Prabir Pradhandae52792023-12-15 07:36:40 +0000216
Prabir Pradhane7701642024-02-22 04:06:53 +0000217void InputTracer::EventState::onEventProcessingComplete() {
218 // Write all of the events known so far to the trace.
219 for (const auto& event : events) {
Prabir Pradhan4c49aad2024-02-08 20:42:35 +0000220 const TracedEventArgs traceArgs{.isSecure = isSecure};
Prabir Pradhan8c3b1432024-02-09 23:34:16 +0000221 writeEventToBackend(event, traceArgs, *tracer.mBackend);
Prabir Pradhane7701642024-02-22 04:06:53 +0000222 }
Prabir Pradhan52ec3ff2024-02-22 03:26:38 +0000223 // Write all pending dispatch args to the trace.
224 for (const auto& windowDispatchArgs : pendingDispatchArgs) {
Prabir Pradhan4c49aad2024-02-08 20:42:35 +0000225 auto tracedEventIt =
226 std::find_if(events.begin(), events.end(),
227 [id = getId(windowDispatchArgs.eventEntry)](const auto& event) {
228 return id == getId(event);
229 });
230 if (tracedEventIt == events.end()) {
231 LOG(FATAL) << __func__
232 << ": Failed to find a previously traced event that matches the dispatched "
233 "event";
234 }
235 const TracedEventArgs traceArgs{.isSecure = isSecure};
Prabir Pradhan8c3b1432024-02-09 23:34:16 +0000236 tracer.mBackend->traceWindowDispatch(windowDispatchArgs, traceArgs);
Prabir Pradhan52ec3ff2024-02-22 03:26:38 +0000237 }
238 pendingDispatchArgs.clear();
239
Prabir Pradhane7701642024-02-22 04:06:53 +0000240 isEventProcessingComplete = true;
241}
242
Prabir Pradhana67623c2024-02-21 06:57:36 +0000243InputTracer::EventState::~EventState() {
244 if (isEventProcessingComplete) {
Prabir Pradhanbb7a0202024-02-10 02:09:01 +0000245 // This event has already been written to the trace as expected.
246 return;
247 }
Prabir Pradhan1ea04a32024-02-10 03:02:59 +0000248 // The event processing was never marked as complete, so do it now.
Prabir Pradhane7701642024-02-22 04:06:53 +0000249 // We should never end up here in normal operation. However, in tests, it's possible that we
250 // stop and destroy InputDispatcher without waiting for it to finish processing events, at
251 // which point an event (and thus its EventState) may be destroyed before processing finishes.
252 onEventProcessingComplete();
Prabir Pradhandae52792023-12-15 07:36:40 +0000253}
254
255} // namespace android::inputdispatcher::trace::impl