blob: f4a06f7d286d8dbc2dfa9fb17ab3d964274fe5d0 [file] [log] [blame]
Prabir Pradhandc3a2ad2024-02-05 19:03:51 +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#include "FakeInputTracingBackend.h"
18
19#include <android-base/logging.h>
20#include <utils/Errors.h>
21
22namespace android::inputdispatcher {
23
24namespace {
25
Prabir Pradhana2d3cf12024-02-05 23:02:01 +000026// Use a larger timeout while waiting for events to be traced, compared to the timeout used while
27// waiting to receive events through the input channel. Events are traced from a separate thread,
28// which does not have the same high thread priority as the InputDispatcher's thread, so the tracer
29// is expected to lag behind the Dispatcher at times.
30constexpr auto TRACE_TIMEOUT = std::chrono::seconds(5);
Prabir Pradhandc3a2ad2024-02-05 19:03:51 +000031
32base::ResultError<> error(const std::ostringstream& ss) {
33 return base::ResultError(ss.str(), BAD_VALUE);
34}
35
Prabir Pradhan4497c862023-12-15 07:13:30 +000036inline auto getId(const trace::TracedEvent& v) {
37 return std::visit([](const auto& event) { return event.id; }, v);
38}
39
Prabir Pradhandc3a2ad2024-02-05 19:03:51 +000040} // namespace
41
42// --- VerifyingTrace ---
43
Prabir Pradhan4497c862023-12-15 07:13:30 +000044void VerifyingTrace::expectKeyDispatchTraced(const KeyEvent& event, int32_t windowId) {
Prabir Pradhandc3a2ad2024-02-05 19:03:51 +000045 std::scoped_lock lock(mLock);
Prabir Pradhan4497c862023-12-15 07:13:30 +000046 mExpectedEvents.emplace_back(event, windowId);
Prabir Pradhandc3a2ad2024-02-05 19:03:51 +000047}
48
Prabir Pradhan4497c862023-12-15 07:13:30 +000049void VerifyingTrace::expectMotionDispatchTraced(const MotionEvent& event, int32_t windowId) {
Prabir Pradhandc3a2ad2024-02-05 19:03:51 +000050 std::scoped_lock lock(mLock);
Prabir Pradhan4497c862023-12-15 07:13:30 +000051 mExpectedEvents.emplace_back(event, windowId);
Prabir Pradhandc3a2ad2024-02-05 19:03:51 +000052}
53
54void VerifyingTrace::verifyExpectedEventsTraced() {
55 std::unique_lock lock(mLock);
56 base::ScopedLockAssertion assumeLocked(mLock);
57
58 base::Result<void> result;
59 mEventTracedCondition.wait_for(lock, TRACE_TIMEOUT, [&]() REQUIRES(mLock) {
Prabir Pradhan4497c862023-12-15 07:13:30 +000060 for (const auto& [expectedEvent, windowId] : mExpectedEvents) {
Prabir Pradhandc3a2ad2024-02-05 19:03:51 +000061 std::visit([&](const auto& event)
Prabir Pradhan4497c862023-12-15 07:13:30 +000062 REQUIRES(mLock) { result = verifyEventTraced(event, windowId); },
Prabir Pradhandc3a2ad2024-02-05 19:03:51 +000063 expectedEvent);
64 if (!result.ok()) {
65 return false;
66 }
67 }
68 return true;
69 });
70
71 EXPECT_TRUE(result.ok())
72 << "Timed out waiting for all expected events to be traced successfully: "
73 << result.error().message();
74}
75
76void VerifyingTrace::reset() {
77 std::scoped_lock lock(mLock);
78 mTracedEvents.clear();
Prabir Pradhan4497c862023-12-15 07:13:30 +000079 mTracedWindowDispatches.clear();
Prabir Pradhandc3a2ad2024-02-05 19:03:51 +000080 mExpectedEvents.clear();
81}
82
83template <typename Event>
Prabir Pradhan4497c862023-12-15 07:13:30 +000084base::Result<void> VerifyingTrace::verifyEventTraced(const Event& expectedEvent,
85 int32_t expectedWindowId) const {
Prabir Pradhandc3a2ad2024-02-05 19:03:51 +000086 std::ostringstream msg;
87
88 auto tracedEventsIt = mTracedEvents.find(expectedEvent.getId());
89 if (tracedEventsIt == mTracedEvents.end()) {
90 msg << "Expected event with ID 0x" << std::hex << expectedEvent.getId()
91 << " to be traced, but it was not.\n"
92 << "Expected event: " << expectedEvent;
93 return error(msg);
94 }
95
Prabir Pradhan4497c862023-12-15 07:13:30 +000096 auto tracedDispatchesIt =
97 std::find_if(mTracedWindowDispatches.begin(), mTracedWindowDispatches.end(),
98 [&](const WindowDispatchArgs& args) {
99 return args.windowId == expectedWindowId &&
100 getId(args.eventEntry) == expectedEvent.getId();
101 });
102 if (tracedDispatchesIt == mTracedWindowDispatches.end()) {
103 msg << "Expected dispatch of event with ID 0x" << std::hex << expectedEvent.getId()
104 << " to window with ID 0x" << expectedWindowId << " to be traced, but it was not."
105 << "\nExpected event: " << expectedEvent;
106 return error(msg);
107 }
108
Prabir Pradhandc3a2ad2024-02-05 19:03:51 +0000109 return {};
110}
111
112// --- FakeInputTracingBackend ---
113
114void FakeInputTracingBackend::traceKeyEvent(const trace::TracedKeyEvent& event) const {
115 {
116 std::scoped_lock lock(mTrace->mLock);
117 mTrace->mTracedEvents.emplace(event.id);
118 }
119 mTrace->mEventTracedCondition.notify_all();
120}
121
122void FakeInputTracingBackend::traceMotionEvent(const trace::TracedMotionEvent& event) const {
123 {
124 std::scoped_lock lock(mTrace->mLock);
125 mTrace->mTracedEvents.emplace(event.id);
126 }
127 mTrace->mEventTracedCondition.notify_all();
128}
129
Prabir Pradhan4497c862023-12-15 07:13:30 +0000130void FakeInputTracingBackend::traceWindowDispatch(const WindowDispatchArgs& args) const {
131 {
132 std::scoped_lock lock(mTrace->mLock);
133 mTrace->mTracedWindowDispatches.push_back(args);
134 }
135 mTrace->mEventTracedCondition.notify_all();
136}
137
Prabir Pradhandc3a2ad2024-02-05 19:03:51 +0000138} // namespace android::inputdispatcher