1 /*
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 "../InputCommonConverter.h"
18 #include "../dispatcher/InputDispatcher.h"
19 #include "../dispatcher/trace/InputTracingPerfettoBackend.h"
20 #include "../dispatcher/trace/ThreadedBackend.h"
21 #include "FakeApplicationHandle.h"
22 #include "FakeInputDispatcherPolicy.h"
23 #include "FakeWindows.h"
24 #include "InputTraceSession.h"
25 #include "TestEventMatchers.h"
26 
27 #include <NotifyArgsBuilders.h>
28 #include <android-base/logging.h>
29 #include <android/content/pm/IPackageManagerNative.h>
30 #include <gtest/gtest.h>
31 #include <input/Input.h>
32 #include <perfetto/trace/android/android_input_event.pbzero.h>
33 #include <perfetto/trace/android/winscope_extensions.pbzero.h>
34 #include <perfetto/trace/android/winscope_extensions_impl.pbzero.h>
35 #include <perfetto/trace/trace.pbzero.h>
36 #include <private/android_filesystem_config.h>
37 #include <map>
38 #include <vector>
39 
40 namespace android::inputdispatcher::trace {
41 
42 using perfetto::protos::pbzero::AndroidInputEventConfig;
43 
44 namespace {
45 
46 constexpr ui::LogicalDisplayId DISPLAY_ID = ui::LogicalDisplayId::DEFAULT;
47 
48 // Ensure common actions are interchangeable between keys and motions for convenience.
49 static_assert(static_cast<int32_t>(AMOTION_EVENT_ACTION_DOWN) ==
50               static_cast<int32_t>(AKEY_EVENT_ACTION_DOWN));
51 static_assert(static_cast<int32_t>(AMOTION_EVENT_ACTION_UP) ==
52               static_cast<int32_t>(AKEY_EVENT_ACTION_UP));
53 constexpr int32_t ACTION_DOWN = AMOTION_EVENT_ACTION_DOWN;
54 constexpr int32_t ACTION_MOVE = AMOTION_EVENT_ACTION_MOVE;
55 constexpr int32_t ACTION_UP = AMOTION_EVENT_ACTION_UP;
56 constexpr int32_t ACTION_CANCEL = AMOTION_EVENT_ACTION_CANCEL;
57 
58 constexpr gui::Pid PID{1};
59 
60 constexpr gui::Uid ALLOWED_UID_1{10012};
61 constexpr gui::Uid ALLOWED_UID_2{10013};
62 constexpr gui::Uid DISALLOWED_UID_1{1};
63 constexpr gui::Uid DISALLOWED_UID_2{99};
64 constexpr gui::Uid UNLISTED_UID{12345};
65 
66 const std::string ALLOWED_PKG_1{"allowed.pkg.1"};
67 const std::string ALLOWED_PKG_2{"allowed.pkg.2"};
68 const std::string DISALLOWED_PKG_1{"disallowed.pkg.1"};
69 const std::string DISALLOWED_PKG_2{"disallowed.pkg.2"};
70 
71 const std::map<std::string, gui::Uid> kPackageUidMap{
72         {ALLOWED_PKG_1, ALLOWED_UID_1},
73         {ALLOWED_PKG_2, ALLOWED_UID_2},
74         {DISALLOWED_PKG_1, DISALLOWED_UID_1},
75         {DISALLOWED_PKG_2, DISALLOWED_UID_2},
76 };
77 
78 class FakePackageManager : public content::pm::IPackageManagerNativeDefault {
79 public:
getPackageUid(const::std::string & pkg,int64_t flags,int32_t userId,int32_t * outUid)80     binder::Status getPackageUid(const ::std::string& pkg, int64_t flags, int32_t userId,
81             int32_t* outUid) override {
82         auto it = kPackageUidMap.find(pkg);
83         *outUid = it != kPackageUidMap.end() ? static_cast<int32_t>(it->second.val()) : -1;
84         return binder::Status::ok();
85     }
86 };
87 
88 const sp<testing::NiceMock<FakePackageManager>> kPackageManager =
89         sp<testing::NiceMock<FakePackageManager>>::make();
90 
91 const std::shared_ptr<FakeApplicationHandle> APP = std::make_shared<FakeApplicationHandle>();
92 
93 } // namespace
94 
95 // --- InputTracingTest ---
96 
97 class InputTracingTest : public testing::Test {
98 protected:
99     std::unique_ptr<FakeInputDispatcherPolicy> mFakePolicy;
100     std::unique_ptr<InputDispatcher> mDispatcher;
101 
SetUp()102     void SetUp() override {
103         impl::PerfettoBackend::sUseInProcessBackendForTest = true;
104         impl::PerfettoBackend::sPackageManagerProvider = []() { return kPackageManager; };
105         mFakePolicy = std::make_unique<FakeInputDispatcherPolicy>();
106 
107         auto tracingBackend = std::make_unique<impl::ThreadedBackend<impl::PerfettoBackend>>(
108                 impl::PerfettoBackend());
109         mRequestTracerIdle = tracingBackend->getIdleWaiterForTesting();
110         mDispatcher = std::make_unique<InputDispatcher>(*mFakePolicy, std::move(tracingBackend));
111 
112         mDispatcher->setInputDispatchMode(/*enabled=*/true, /*frozen=*/false);
113         ASSERT_EQ(OK, mDispatcher->start());
114     }
115 
TearDown()116     void TearDown() override {
117         ASSERT_EQ(OK, mDispatcher->stop());
118         mDispatcher.reset();
119         mFakePolicy.reset();
120     }
121 
waitForTracerIdle()122     void waitForTracerIdle() {
123         mDispatcher->waitForIdle();
124         mRequestTracerIdle();
125     }
126 
setFocusedWindow(const sp<gui::WindowInfoHandle> & window)127     void setFocusedWindow(const sp<gui::WindowInfoHandle>& window) {
128         gui::FocusRequest request;
129         request.token = window->getToken();
130         request.windowName = window->getName();
131         request.timestamp = systemTime(SYSTEM_TIME_MONOTONIC);
132         request.displayId = window->getInfo()->displayId.val();
133         mDispatcher->setFocusedWindow(request);
134     }
135 
tapAndExpect(const std::vector<const sp<FakeWindowHandle>> & windows,Level inboundTraceLevel,Level dispatchTraceLevel,InputTraceSession & s)136     void tapAndExpect(const std::vector<const sp<FakeWindowHandle>>& windows,
137                       Level inboundTraceLevel, Level dispatchTraceLevel, InputTraceSession& s) {
138         const auto down = MotionArgsBuilder(ACTION_DOWN, AINPUT_SOURCE_TOUCHSCREEN)
139                                   .pointer(PointerBuilder(0, ToolType::FINGER).x(100).y(110))
140                                   .build();
141         mDispatcher->notifyMotion(down);
142         s.expectMotionTraced(inboundTraceLevel, toMotionEvent(down));
143         for (const auto& window : windows) {
144             auto consumed = window->consumeMotionEvent(WithMotionAction(ACTION_DOWN));
145             s.expectDispatchTraced(dispatchTraceLevel, {*consumed, window});
146         }
147 
148         const auto up = MotionArgsBuilder(ACTION_UP, AINPUT_SOURCE_TOUCHSCREEN)
149                                 .pointer(PointerBuilder(0, ToolType::FINGER).x(100).y(110))
150                                 .build();
151         mDispatcher->notifyMotion(up);
152         s.expectMotionTraced(inboundTraceLevel, toMotionEvent(up));
153         for (const auto& window : windows) {
154             auto consumed = window->consumeMotionEvent(WithMotionAction(ACTION_UP));
155             s.expectDispatchTraced(dispatchTraceLevel, {*consumed, window});
156         }
157     }
158 
keypressAndExpect(const std::vector<const sp<FakeWindowHandle>> & windows,Level inboundTraceLevel,Level dispatchTraceLevel,InputTraceSession & s)159     void keypressAndExpect(const std::vector<const sp<FakeWindowHandle>>& windows,
160                            Level inboundTraceLevel, Level dispatchTraceLevel,
161                            InputTraceSession& s) {
162         const auto down = KeyArgsBuilder(ACTION_DOWN, AINPUT_SOURCE_KEYBOARD).build();
163         mDispatcher->notifyKey(down);
164         s.expectKeyTraced(inboundTraceLevel, toKeyEvent(down));
165         for (const auto& window : windows) {
166             auto consumed = window->consumeKeyEvent(WithKeyAction(ACTION_DOWN));
167             s.expectDispatchTraced(dispatchTraceLevel, {*consumed, window});
168         }
169 
170         const auto up = KeyArgsBuilder(ACTION_UP, AINPUT_SOURCE_KEYBOARD).build();
171         mDispatcher->notifyKey(up);
172         s.expectKeyTraced(inboundTraceLevel, toKeyEvent(up));
173         for (const auto& window : windows) {
174             auto consumed = window->consumeKeyEvent(WithKeyAction(ACTION_UP));
175             s.expectDispatchTraced(dispatchTraceLevel, {*consumed, window});
176         }
177     }
178 
179 private:
180     std::function<void()> mRequestTracerIdle;
181 };
182 
TEST_F(InputTracingTest,EmptyConfigTracesNothing)183 TEST_F(InputTracingTest, EmptyConfigTracesNothing) {
184     InputTraceSession s{[](auto& config) {}};
185 
186     auto window = sp<FakeWindowHandle>::make(APP, mDispatcher, "Window", DISPLAY_ID);
187     mDispatcher->onWindowInfosChanged({{*window->getInfo()}, {}, 0, 0});
188     setFocusedWindow(window);
189     window->consumeFocusEvent(true);
190 
191     tapAndExpect({window}, Level::NONE, Level::NONE, s);
192     keypressAndExpect({window}, Level::NONE, Level::NONE, s);
193 
194     waitForTracerIdle();
195 }
196 
TEST_F(InputTracingTest,TraceAll)197 TEST_F(InputTracingTest, TraceAll) {
198     InputTraceSession s{
199             [](auto& config) { config->set_mode(AndroidInputEventConfig::TRACE_MODE_TRACE_ALL); }};
200 
201     auto window = sp<FakeWindowHandle>::make(APP, mDispatcher, "Window", DISPLAY_ID);
202     mDispatcher->onWindowInfosChanged({{*window->getInfo()}, {}, 0, 0});
203     setFocusedWindow(window);
204     window->consumeFocusEvent(true);
205 
206     tapAndExpect({window}, Level::COMPLETE, Level::COMPLETE, s);
207     keypressAndExpect({window}, Level::COMPLETE, Level::COMPLETE, s);
208 
209     waitForTracerIdle();
210 }
211 
TEST_F(InputTracingTest,NoRulesTracesNothing)212 TEST_F(InputTracingTest, NoRulesTracesNothing) {
213     InputTraceSession s{[](auto& config) {
214         config->set_trace_dispatcher_input_events(true);
215         config->set_trace_dispatcher_window_dispatch(true);
216         config->set_mode(AndroidInputEventConfig::TRACE_MODE_USE_RULES);
217     }};
218 
219     auto window = sp<FakeWindowHandle>::make(APP, mDispatcher, "Window", DISPLAY_ID);
220     mDispatcher->onWindowInfosChanged({{*window->getInfo()}, {}, 0, 0});
221     setFocusedWindow(window);
222     window->consumeFocusEvent(true);
223 
224     tapAndExpect({window}, Level::NONE, Level::NONE, s);
225     keypressAndExpect({window}, Level::NONE, Level::NONE, s);
226 
227     waitForTracerIdle();
228 }
229 
TEST_F(InputTracingTest,EmptyRuleMatchesEverything)230 TEST_F(InputTracingTest, EmptyRuleMatchesEverything) {
231     InputTraceSession s{[](auto& config) {
232         config->set_trace_dispatcher_input_events(true);
233         config->set_trace_dispatcher_window_dispatch(true);
234         config->set_mode(AndroidInputEventConfig::TRACE_MODE_USE_RULES);
235         // Rule: Match everything as COMPLETE
236         auto rule = config->add_rules();
237         rule->set_trace_level(AndroidInputEventConfig::TRACE_LEVEL_COMPLETE);
238     }};
239 
240     auto window = sp<FakeWindowHandle>::make(APP, mDispatcher, "Window", DISPLAY_ID);
241     mDispatcher->onWindowInfosChanged({{*window->getInfo()}, {}, 0, 0});
242     setFocusedWindow(window);
243     window->consumeFocusEvent(true);
244 
245     tapAndExpect({window}, Level::COMPLETE, Level::COMPLETE, s);
246     keypressAndExpect({window}, Level::COMPLETE, Level::COMPLETE, s);
247 
248     waitForTracerIdle();
249 }
250 
TEST_F(InputTracingTest,UnspecifiedTracelLevel)251 TEST_F(InputTracingTest, UnspecifiedTracelLevel) {
252     InputTraceSession s{[](auto& config) {
253         config->set_trace_dispatcher_input_events(true);
254         config->set_trace_dispatcher_window_dispatch(true);
255         config->set_mode(AndroidInputEventConfig::TRACE_MODE_USE_RULES);
256         // Rule: Match everything, trace level unspecified
257         auto rule = config->add_rules();
258     }};
259 
260     auto window = sp<FakeWindowHandle>::make(APP, mDispatcher, "Window", DISPLAY_ID);
261     mDispatcher->onWindowInfosChanged({{*window->getInfo()}, {}, 0, 0});
262     setFocusedWindow(window);
263     window->consumeFocusEvent(true);
264 
265     // Event is not traced by default if trace level is unspecified
266     tapAndExpect({window}, Level::NONE, Level::NONE, s);
267     keypressAndExpect({window}, Level::NONE, Level::NONE, s);
268 
269     waitForTracerIdle();
270 }
271 
TEST_F(InputTracingTest,MatchSecureWindow)272 TEST_F(InputTracingTest, MatchSecureWindow) {
273     InputTraceSession s{[](auto& config) {
274         config->set_trace_dispatcher_input_events(true);
275         config->set_trace_dispatcher_window_dispatch(true);
276         config->set_mode(AndroidInputEventConfig::TRACE_MODE_USE_RULES);
277         // Rule: Match secure windows as COMPLETE
278         auto rule = config->add_rules();
279         rule->set_trace_level(AndroidInputEventConfig::TRACE_LEVEL_COMPLETE);
280         rule->set_match_secure(true);
281     }};
282 
283     // Add a normal window and a spy window.
284     auto window = sp<FakeWindowHandle>::make(APP, mDispatcher, "Window", DISPLAY_ID);
285     auto spy = sp<FakeWindowHandle>::make(APP, mDispatcher, "Spy", DISPLAY_ID);
286     spy->setSpy(true);
287     spy->setTrustedOverlay(true);
288     mDispatcher->onWindowInfosChanged({{*spy->getInfo(), *window->getInfo()}, {}, 0, 0});
289 
290     // Since neither are secure windows, events should not be traced.
291     tapAndExpect({spy, window}, Level::NONE, Level::NONE, s);
292 
293     // Events should be matched as secure if any of the target windows is marked as secure.
294     spy->setSecure(true);
295     mDispatcher->onWindowInfosChanged({{*spy->getInfo(), *window->getInfo()}, {}, 0, 0});
296     tapAndExpect({spy, window}, Level::COMPLETE, Level::COMPLETE, s);
297 
298     spy->setSecure(false);
299     window->setSecure(true);
300     mDispatcher->onWindowInfosChanged({{*spy->getInfo(), *window->getInfo()}, {}, 0, 0});
301     tapAndExpect({spy, window}, Level::COMPLETE, Level::COMPLETE, s);
302 
303     spy->setSecure(true);
304     window->setSecure(true);
305     mDispatcher->onWindowInfosChanged({{*spy->getInfo(), *window->getInfo()}, {}, 0, 0});
306     tapAndExpect({spy, window}, Level::COMPLETE, Level::COMPLETE, s);
307 
308     spy->setSecure(false);
309     window->setSecure(false);
310     mDispatcher->onWindowInfosChanged({{*spy->getInfo(), *window->getInfo()}, {}, 0, 0});
311     tapAndExpect({spy, window}, Level::NONE, Level::NONE, s);
312 
313     waitForTracerIdle();
314 }
315 
TEST_F(InputTracingTest,MatchImeConnectionActive)316 TEST_F(InputTracingTest, MatchImeConnectionActive) {
317     InputTraceSession s{[](auto& config) {
318         config->set_trace_dispatcher_input_events(true);
319         config->set_trace_dispatcher_window_dispatch(true);
320         config->set_mode(AndroidInputEventConfig::TRACE_MODE_USE_RULES);
321         // Rule: Match IME Connection Active as COMPLETE
322         auto rule = config->add_rules();
323         rule->set_trace_level(AndroidInputEventConfig::TRACE_LEVEL_COMPLETE);
324         rule->set_match_ime_connection_active(true);
325     }};
326 
327     // Add a normal window and a spy window.
328     auto window = sp<FakeWindowHandle>::make(APP, mDispatcher, "Window", DISPLAY_ID);
329     auto spy = sp<FakeWindowHandle>::make(APP, mDispatcher, "Spy", DISPLAY_ID);
330     spy->setSpy(true);
331     spy->setTrustedOverlay(true);
332     mDispatcher->onWindowInfosChanged({{*spy->getInfo(), *window->getInfo()}, {}, 0, 0});
333 
334     // Since IME connection is not active, events should not be traced.
335     tapAndExpect({spy, window}, Level::NONE, Level::NONE, s);
336 
337     mDispatcher->setInputMethodConnectionIsActive(true);
338     tapAndExpect({spy, window}, Level::COMPLETE, Level::COMPLETE, s);
339 
340     mDispatcher->setInputMethodConnectionIsActive(false);
341     tapAndExpect({spy, window}, Level::NONE, Level::NONE, s);
342 
343     waitForTracerIdle();
344 }
345 
TEST_F(InputTracingTest,MatchAllPackages)346 TEST_F(InputTracingTest, MatchAllPackages) {
347     InputTraceSession s{[](auto& config) {
348         config->set_trace_dispatcher_input_events(true);
349         config->set_trace_dispatcher_window_dispatch(true);
350         config->set_mode(AndroidInputEventConfig::TRACE_MODE_USE_RULES);
351         // Rule: Match all package as COMPLETE
352         auto rule = config->add_rules();
353         rule->set_trace_level(AndroidInputEventConfig::TRACE_LEVEL_COMPLETE);
354         rule->add_match_all_packages(ALLOWED_PKG_1);
355         rule->add_match_all_packages(ALLOWED_PKG_2);
356     }};
357 
358     // All windows are allowlisted.
359     auto window = sp<FakeWindowHandle>::make(APP, mDispatcher, "Window", DISPLAY_ID);
360     window->setOwnerInfo(PID, ALLOWED_UID_1);
361     auto spy = sp<FakeWindowHandle>::make(APP, mDispatcher, "Spy", DISPLAY_ID);
362     spy->setOwnerInfo(PID, ALLOWED_UID_2);
363     spy->setSpy(true);
364     spy->setTrustedOverlay(true);
365     auto systemSpy = sp<FakeWindowHandle>::make(APP, mDispatcher, "Spy", DISPLAY_ID);
366     systemSpy->setOwnerInfo(PID, gui::Uid{AID_SYSTEM});
367     systemSpy->setSpy(true);
368     systemSpy->setTrustedOverlay(true);
369     mDispatcher->onWindowInfosChanged(
370             {{*systemSpy->getInfo(), *spy->getInfo(), *window->getInfo()}, {}, 0, 0});
371 
372     tapAndExpect({systemSpy, spy, window}, Level::COMPLETE, Level::COMPLETE, s);
373 
374     // Add a disallowed spy. This will result in the event not being traced for all windows.
375     auto disallowedSpy = sp<FakeWindowHandle>::make(APP, mDispatcher, "Spy", DISPLAY_ID);
376     disallowedSpy->setOwnerInfo(PID, DISALLOWED_UID_1);
377     disallowedSpy->setSpy(true);
378     disallowedSpy->setTrustedOverlay(true);
379     mDispatcher->onWindowInfosChanged({{*systemSpy->getInfo(), *spy->getInfo(),
380                                         *disallowedSpy->getInfo(), *window->getInfo()},
381                                        {},
382                                        0,
383                                        0});
384 
385     tapAndExpect({systemSpy, spy, disallowedSpy, window}, Level::NONE, Level::NONE, s);
386 
387     // Change the owner of the disallowed spy to one for which we don't have a package mapping.
388     disallowedSpy->setOwnerInfo(PID, UNLISTED_UID);
389     mDispatcher->onWindowInfosChanged({{*systemSpy->getInfo(), *spy->getInfo(),
390                                         *disallowedSpy->getInfo(), *window->getInfo()},
391                                        {},
392                                        0,
393                                        0});
394 
395     tapAndExpect({systemSpy, spy, disallowedSpy, window}, Level::NONE, Level::NONE, s);
396 
397     // Remove the disallowed spy. Events are traced again.
398     mDispatcher->onWindowInfosChanged(
399             {{*systemSpy->getInfo(), *spy->getInfo(), *window->getInfo()}, {}, 0, 0});
400 
401     tapAndExpect({systemSpy, spy, window}, Level::COMPLETE, Level::COMPLETE, s);
402 
403     waitForTracerIdle();
404 }
405 
TEST_F(InputTracingTest,MatchAnyPackages)406 TEST_F(InputTracingTest, MatchAnyPackages) {
407     InputTraceSession s{[](auto& config) {
408         config->set_trace_dispatcher_input_events(true);
409         config->set_trace_dispatcher_window_dispatch(true);
410         config->set_mode(AndroidInputEventConfig::TRACE_MODE_USE_RULES);
411         // Rule: Match any package as COMPLETE
412         auto rule = config->add_rules();
413         rule->set_trace_level(AndroidInputEventConfig::TRACE_LEVEL_COMPLETE);
414         rule->add_match_any_packages(ALLOWED_PKG_1);
415         rule->add_match_any_packages(ALLOWED_PKG_2);
416     }};
417 
418     // Just a disallowed window. Events are not traced.
419     auto window = sp<FakeWindowHandle>::make(APP, mDispatcher, "Window", DISPLAY_ID);
420     window->setOwnerInfo(PID, DISALLOWED_UID_1);
421     mDispatcher->onWindowInfosChanged({{*window->getInfo()}, {}, 0, 0});
422 
423     tapAndExpect({window}, Level::NONE, Level::NONE, s);
424 
425     // Add a spy for which we don't have a package mapping. Events are still not traced.
426     auto disallowedSpy = sp<FakeWindowHandle>::make(APP, mDispatcher, "Spy", DISPLAY_ID);
427     disallowedSpy->setOwnerInfo(PID, UNLISTED_UID);
428     disallowedSpy->setSpy(true);
429     disallowedSpy->setTrustedOverlay(true);
430     mDispatcher->onWindowInfosChanged({{*disallowedSpy->getInfo(), *window->getInfo()}, {}, 0, 0});
431 
432     tapAndExpect({disallowedSpy, window}, Level::NONE, Level::NONE, s);
433 
434     // Add an allowed spy. Events are now traced for all packages.
435     auto spy = sp<FakeWindowHandle>::make(APP, mDispatcher, "Spy", DISPLAY_ID);
436     spy->setOwnerInfo(PID, ALLOWED_UID_1);
437     spy->setSpy(true);
438     spy->setTrustedOverlay(true);
439     mDispatcher->onWindowInfosChanged(
440             {{*disallowedSpy->getInfo(), *spy->getInfo(), *window->getInfo()}, {}, 0, 0});
441 
442     tapAndExpect({disallowedSpy, spy, window}, Level::COMPLETE, Level::COMPLETE, s);
443 
444     // Add another disallowed spy. Events are still traced.
445     auto disallowedSpy2 = sp<FakeWindowHandle>::make(APP, mDispatcher, "Spy", DISPLAY_ID);
446     disallowedSpy2->setOwnerInfo(PID, DISALLOWED_UID_2);
447     disallowedSpy2->setSpy(true);
448     disallowedSpy2->setTrustedOverlay(true);
449     mDispatcher->onWindowInfosChanged({{*disallowedSpy->getInfo(), *disallowedSpy2->getInfo(),
450                                         *spy->getInfo(), *window->getInfo()},
451                                        {},
452                                        0,
453                                        0});
454 
455     tapAndExpect({disallowedSpy, disallowedSpy2, spy, window}, Level::COMPLETE, Level::COMPLETE, s);
456 
457     waitForTracerIdle();
458 }
459 
TEST_F(InputTracingTest,MultipleMatchersInOneRule)460 TEST_F(InputTracingTest, MultipleMatchersInOneRule) {
461     InputTraceSession s{[](auto& config) {
462         config->set_trace_dispatcher_input_events(true);
463         config->set_trace_dispatcher_window_dispatch(true);
464         config->set_mode(AndroidInputEventConfig::TRACE_MODE_USE_RULES);
465         // Rule: Match all of the following conditions as COMPLETE
466         auto rule = config->add_rules();
467         rule->set_trace_level(AndroidInputEventConfig::TRACE_LEVEL_COMPLETE);
468         rule->add_match_all_packages(ALLOWED_PKG_1);
469         rule->add_match_all_packages(ALLOWED_PKG_2);
470         rule->add_match_any_packages(ALLOWED_PKG_1);
471         rule->add_match_any_packages(DISALLOWED_PKG_1);
472         rule->set_match_secure(false);
473         rule->set_match_ime_connection_active(false);
474     }};
475 
476     // A single window into an allowed UID. Matches all matchers.
477     auto window = sp<FakeWindowHandle>::make(APP, mDispatcher, "Window", DISPLAY_ID);
478     window->setOwnerInfo(PID, ALLOWED_UID_1);
479     mDispatcher->onWindowInfosChanged({{*window->getInfo()}, {}, 0, 0});
480 
481     tapAndExpect({window}, Level::COMPLETE, Level::COMPLETE, s);
482 
483     // Secure window does not match.
484     window->setSecure(true);
485     mDispatcher->onWindowInfosChanged({{*window->getInfo()}, {}, 0, 0});
486 
487     tapAndExpect({window}, Level::NONE, Level::NONE, s);
488 
489     // IME Connection Active does not match.
490     window->setSecure(false);
491     mDispatcher->onWindowInfosChanged({{*window->getInfo()}, {}, 0, 0});
492     mDispatcher->setInputMethodConnectionIsActive(true);
493 
494     tapAndExpect({window}, Level::NONE, Level::NONE, s);
495 
496     // Event going to DISALLOWED_PKG_1 does not match because it's not listed in match_all_packages.
497     mDispatcher->setInputMethodConnectionIsActive(false);
498     auto disallowedSpy = sp<FakeWindowHandle>::make(APP, mDispatcher, "Spy", DISPLAY_ID);
499     disallowedSpy->setOwnerInfo(PID, DISALLOWED_UID_1);
500     disallowedSpy->setSpy(true);
501     disallowedSpy->setTrustedOverlay(true);
502     mDispatcher->onWindowInfosChanged({{*disallowedSpy->getInfo(), *window->getInfo()}, {}, 0, 0});
503 
504     tapAndExpect({disallowedSpy, window}, Level::NONE, Level::NONE, s);
505 
506     // Event going to ALLOWED_PKG_1 does not match because it's not listed in match_any_packages.
507     window->setOwnerInfo(PID, ALLOWED_UID_2);
508     mDispatcher->onWindowInfosChanged({{*window->getInfo()}, {}, 0, 0});
509 
510     tapAndExpect({window}, Level::NONE, Level::NONE, s);
511 
512     // All conditions match.
513     auto spy = sp<FakeWindowHandle>::make(APP, mDispatcher, "Spy", DISPLAY_ID);
514     spy->setOwnerInfo(PID, ALLOWED_UID_1);
515     spy->setSpy(true);
516     spy->setTrustedOverlay(true);
517     mDispatcher->onWindowInfosChanged({{*spy->getInfo(), *window->getInfo()}, {}, 0, 0});
518 
519     tapAndExpect({spy, window}, Level::COMPLETE, Level::COMPLETE, s);
520 
521     waitForTracerIdle();
522 }
523 
TEST_F(InputTracingTest,MultipleRulesMatchInOrder)524 TEST_F(InputTracingTest, MultipleRulesMatchInOrder) {
525     InputTraceSession s{[](auto& config) {
526         config->set_trace_dispatcher_input_events(true);
527         config->set_trace_dispatcher_window_dispatch(true);
528         config->set_mode(AndroidInputEventConfig::TRACE_MODE_USE_RULES);
529         // Rule: Don't trace secure events
530         auto rule1 = config->add_rules();
531         rule1->set_trace_level(AndroidInputEventConfig::TRACE_LEVEL_NONE);
532         rule1->set_match_secure(true);
533         // Rule: Trace matched packages as COMPLETE when IME inactive
534         auto rule2 = config->add_rules();
535         rule2->set_trace_level(AndroidInputEventConfig::TRACE_LEVEL_COMPLETE);
536         rule2->add_match_all_packages(ALLOWED_PKG_1);
537         rule2->add_match_all_packages(ALLOWED_PKG_2);
538         rule2->set_match_ime_connection_active(false);
539         // Rule: Trace the rest of the events as REDACTED
540         auto rule3 = config->add_rules();
541         rule3->set_trace_level(AndroidInputEventConfig::TRACE_LEVEL_REDACTED);
542     }};
543 
544     auto window = sp<FakeWindowHandle>::make(APP, mDispatcher, "Window", DISPLAY_ID);
545     window->setOwnerInfo(PID, ALLOWED_UID_1);
546     mDispatcher->onWindowInfosChanged({{*window->getInfo()}, {}, 0, 0});
547 
548     tapAndExpect({window}, Level::COMPLETE, Level::COMPLETE, s);
549 
550     // Verify that the first rule that matches in the order that they are specified is the
551     // one that applies to the event.
552     mDispatcher->setInputMethodConnectionIsActive(true);
553     tapAndExpect({window}, Level::REDACTED, Level::REDACTED, s);
554 
555     mDispatcher->setInputMethodConnectionIsActive(false);
556     auto spy = sp<FakeWindowHandle>::make(APP, mDispatcher, "Spy", DISPLAY_ID);
557     spy->setOwnerInfo(PID, ALLOWED_UID_2);
558     spy->setSpy(true);
559     spy->setTrustedOverlay(true);
560     spy->setSecure(true);
561     mDispatcher->onWindowInfosChanged({{*spy->getInfo(), *window->getInfo()}, {}, 0, 0});
562 
563     tapAndExpect({spy, window}, Level::NONE, Level::NONE, s);
564 
565     spy->setSecure(false);
566     mDispatcher->onWindowInfosChanged({{*spy->getInfo(), *window->getInfo()}, {}, 0, 0});
567 
568     tapAndExpect({spy, window}, Level::COMPLETE, Level::COMPLETE, s);
569 
570     spy->setOwnerInfo(PID, DISALLOWED_UID_1);
571     mDispatcher->onWindowInfosChanged({{*spy->getInfo(), *window->getInfo()}, {}, 0, 0});
572 
573     tapAndExpect({spy, window}, Level::REDACTED, Level::REDACTED, s);
574 
575     waitForTracerIdle();
576 }
577 
TEST_F(InputTracingTest,TraceInboundEvents)578 TEST_F(InputTracingTest, TraceInboundEvents) {
579     InputTraceSession s{[](auto& config) {
580         // Only trace inbounds events - don't trace window dispatch
581         config->set_trace_dispatcher_input_events(true);
582         config->set_mode(AndroidInputEventConfig::TRACE_MODE_USE_RULES);
583         // Rule: Trace everything as REDACTED
584         auto rule1 = config->add_rules();
585         rule1->set_trace_level(AndroidInputEventConfig::TRACE_LEVEL_REDACTED);
586     }};
587 
588     auto window = sp<FakeWindowHandle>::make(APP, mDispatcher, "Window", DISPLAY_ID);
589     window->setOwnerInfo(PID, ALLOWED_UID_1);
590     mDispatcher->onWindowInfosChanged({{*window->getInfo()}, {}, 0, 0});
591 
592     // Only the inbound events are traced. No dispatch events are traced.
593     tapAndExpect({window}, Level::REDACTED, Level::NONE, s);
594 
595     // Notify a down event, which should be traced.
596     const auto down = MotionArgsBuilder(ACTION_DOWN, AINPUT_SOURCE_TOUCHSCREEN)
597                               .pointer(PointerBuilder(0, ToolType::FINGER).x(100).y(110))
598                               .build();
599     s.expectMotionTraced(Level::REDACTED, toMotionEvent(down));
600     mDispatcher->notifyMotion(down);
601     auto consumed = window->consumeMotionEvent(WithMotionAction(ACTION_DOWN));
602     s.expectDispatchTraced(Level::NONE, {*consumed, window});
603 
604     // Force a cancel event to be synthesized. This should not be traced, because only inbound
605     // events are requested.
606     mDispatcher->cancelCurrentTouch();
607     consumed = window->consumeMotionEvent(WithMotionAction(ACTION_CANCEL));
608     s.expectMotionTraced(Level::NONE, *consumed);
609     s.expectDispatchTraced(Level::NONE, {*consumed, window});
610 
611     waitForTracerIdle();
612 }
613 
TEST_F(InputTracingTest,TraceWindowDispatch)614 TEST_F(InputTracingTest, TraceWindowDispatch) {
615     InputTraceSession s{[](auto& config) {
616         // Only trace window dispatch - don't trace event details
617         config->set_trace_dispatcher_window_dispatch(true);
618         config->set_mode(AndroidInputEventConfig::TRACE_MODE_USE_RULES);
619         // Rule: Trace everything as REDACTED
620         auto rule1 = config->add_rules();
621         rule1->set_trace_level(AndroidInputEventConfig::TRACE_LEVEL_REDACTED);
622     }};
623 
624     auto window = sp<FakeWindowHandle>::make(APP, mDispatcher, "Window", DISPLAY_ID);
625     window->setOwnerInfo(PID, ALLOWED_UID_1);
626     mDispatcher->onWindowInfosChanged({{*window->getInfo()}, {}, 0, 0});
627 
628     // Only dispatch events are traced. No inbound events are traced.
629     tapAndExpect({window}, Level::NONE, Level::REDACTED, s);
630 
631     // Notify a down event; the dispatch should be traced.
632     const auto down = MotionArgsBuilder(ACTION_DOWN, AINPUT_SOURCE_TOUCHSCREEN)
633                               .pointer(PointerBuilder(0, ToolType::FINGER).x(100).y(110))
634                               .build();
635     s.expectMotionTraced(Level::NONE, toMotionEvent(down));
636     mDispatcher->notifyMotion(down);
637     auto consumed = window->consumeMotionEvent(WithMotionAction(ACTION_DOWN));
638     s.expectDispatchTraced(Level::REDACTED, {*consumed, window});
639 
640     // Force a cancel event to be synthesized. All events that are dispatched should be traced.
641     mDispatcher->cancelCurrentTouch();
642     consumed = window->consumeMotionEvent(WithMotionAction(ACTION_CANCEL));
643     s.expectMotionTraced(Level::NONE, *consumed);
644     s.expectDispatchTraced(Level::REDACTED, {*consumed, window});
645 
646     waitForTracerIdle();
647 }
648 
649 // TODO(b/336097719): Investigate flakiness and re-enable this test.
TEST_F(InputTracingTest,DISABLED_SimultaneousTracingSessions)650 TEST_F(InputTracingTest, DISABLED_SimultaneousTracingSessions) {
651     auto s1 = std::make_unique<InputTraceSession>(
652             [](auto& config) { config->set_mode(AndroidInputEventConfig::TRACE_MODE_TRACE_ALL); });
653 
654     auto window = sp<FakeWindowHandle>::make(APP, mDispatcher, "Window", DISPLAY_ID);
655     mDispatcher->onWindowInfosChanged({{*window->getInfo()}, {}, 0, 0});
656     setFocusedWindow(window);
657     window->consumeFocusEvent(true);
658 
659     tapAndExpect({window}, Level::COMPLETE, Level::COMPLETE, *s1);
660     keypressAndExpect({window}, Level::COMPLETE, Level::COMPLETE, *s1);
661 
662     auto s2 = std::make_unique<InputTraceSession>([](auto& config) {
663         config->set_trace_dispatcher_input_events(true);
664         config->set_trace_dispatcher_window_dispatch(true);
665         config->set_mode(AndroidInputEventConfig::TRACE_MODE_USE_RULES);
666         // Rule: Trace all events as REDACTED when IME inactive
667         auto rule = config->add_rules();
668         rule->set_trace_level(AndroidInputEventConfig::TRACE_LEVEL_REDACTED);
669         rule->set_match_ime_connection_active(false);
670     });
671 
672     auto s3 = std::make_unique<InputTraceSession>([](auto& config) {
673         // Only trace window dispatch
674         config->set_trace_dispatcher_window_dispatch(true);
675         config->set_mode(AndroidInputEventConfig::TRACE_MODE_USE_RULES);
676         // Rule: Trace non-secure events as COMPLETE
677         auto rule = config->add_rules();
678         rule->set_trace_level(AndroidInputEventConfig::TRACE_LEVEL_COMPLETE);
679         rule->set_match_secure(false);
680     });
681 
682     // Down event should be recorded on all traces.
683     const auto down = MotionArgsBuilder(ACTION_DOWN, AINPUT_SOURCE_TOUCHSCREEN)
684                               .pointer(PointerBuilder(0, ToolType::FINGER).x(100).y(110))
685                               .build();
686     mDispatcher->notifyMotion(down);
687     s1->expectMotionTraced(Level::COMPLETE, toMotionEvent(down));
688     s2->expectMotionTraced(Level::REDACTED, toMotionEvent(down));
689     s3->expectMotionTraced(Level::NONE, toMotionEvent(down));
690     auto consumed = window->consumeMotionEvent(WithMotionAction(ACTION_DOWN));
691     s1->expectDispatchTraced(Level::COMPLETE, {*consumed, window});
692     s2->expectDispatchTraced(Level::REDACTED, {*consumed, window});
693     s3->expectDispatchTraced(Level::COMPLETE, {*consumed, window});
694 
695     // Move event when IME is active.
696     mDispatcher->setInputMethodConnectionIsActive(true);
697     const auto move1 = MotionArgsBuilder(ACTION_MOVE, AINPUT_SOURCE_TOUCHSCREEN)
698                                .pointer(PointerBuilder(0, ToolType::FINGER).x(100).y(110))
699                                .build();
700     mDispatcher->notifyMotion(move1);
701     s1->expectMotionTraced(Level::COMPLETE, toMotionEvent(move1));
702     s2->expectMotionTraced(Level::NONE, toMotionEvent(move1));
703     s3->expectMotionTraced(Level::NONE, toMotionEvent(move1));
704     consumed = window->consumeMotionEvent(WithMotionAction(ACTION_MOVE));
705     s1->expectDispatchTraced(Level::COMPLETE, {*consumed, window});
706     s2->expectDispatchTraced(Level::NONE, {*consumed, window});
707     s3->expectDispatchTraced(Level::COMPLETE, {*consumed, window});
708 
709     // Move event after window became secure.
710     mDispatcher->setInputMethodConnectionIsActive(false);
711     window->setSecure(true);
712     mDispatcher->onWindowInfosChanged({{*window->getInfo()}, {}, 0, 0});
713     const auto move2 = MotionArgsBuilder(ACTION_MOVE, AINPUT_SOURCE_TOUCHSCREEN)
714                                .pointer(PointerBuilder(0, ToolType::FINGER).x(100).y(110))
715                                .build();
716     mDispatcher->notifyMotion(move2);
717     s1->expectMotionTraced(Level::COMPLETE, toMotionEvent(move2));
718     s2->expectMotionTraced(Level::REDACTED, toMotionEvent(move2));
719     s3->expectMotionTraced(Level::NONE, toMotionEvent(move2));
720     consumed = window->consumeMotionEvent(WithMotionAction(ACTION_MOVE));
721     s1->expectDispatchTraced(Level::COMPLETE, {*consumed, window});
722     s2->expectDispatchTraced(Level::REDACTED, {*consumed, window});
723     s3->expectDispatchTraced(Level::NONE, {*consumed, window});
724 
725     waitForTracerIdle();
726     s2.reset();
727 
728     // Up event.
729     window->setSecure(false);
730     mDispatcher->onWindowInfosChanged({{*window->getInfo()}, {}, 0, 0});
731     const auto up = MotionArgsBuilder(ACTION_UP, AINPUT_SOURCE_TOUCHSCREEN)
732                             .pointer(PointerBuilder(0, ToolType::FINGER).x(100).y(110))
733                             .build();
734     mDispatcher->notifyMotion(up);
735     s1->expectMotionTraced(Level::COMPLETE, toMotionEvent(up));
736     s3->expectMotionTraced(Level::NONE, toMotionEvent(up));
737     consumed = window->consumeMotionEvent(WithMotionAction(ACTION_UP));
738     s1->expectDispatchTraced(Level::COMPLETE, {*consumed, window});
739     s3->expectDispatchTraced(Level::COMPLETE, {*consumed, window});
740 
741     waitForTracerIdle();
742     s3.reset();
743 
744     tapAndExpect({window}, Level::COMPLETE, Level::COMPLETE, *s1);
745     keypressAndExpect({window}, Level::COMPLETE, Level::COMPLETE, *s1);
746 
747     waitForTracerIdle();
748     s1.reset();
749 }
750 
751 } // namespace android::inputdispatcher::trace
752