xref: /aosp_15_r20/frameworks/native/services/inputflinger/tests/FakeWindows.cpp (revision 38e8c45f13ce32b0dcecb25141ffecaf386fa17f)
1*38e8c45fSAndroid Build Coastguard Worker /*
2*38e8c45fSAndroid Build Coastguard Worker  * Copyright 2024 The Android Open Source Project
3*38e8c45fSAndroid Build Coastguard Worker  *
4*38e8c45fSAndroid Build Coastguard Worker  * Licensed under the Apache License, Version 2.0 (the "License");
5*38e8c45fSAndroid Build Coastguard Worker  * you may not use this file except in compliance with the License.
6*38e8c45fSAndroid Build Coastguard Worker  * You may obtain a copy of the License at
7*38e8c45fSAndroid Build Coastguard Worker  *
8*38e8c45fSAndroid Build Coastguard Worker  *      http://www.apache.org/licenses/LICENSE-2.0
9*38e8c45fSAndroid Build Coastguard Worker  *
10*38e8c45fSAndroid Build Coastguard Worker  * Unless required by applicable law or agreed to in writing, software
11*38e8c45fSAndroid Build Coastguard Worker  * distributed under the License is distributed on an "AS IS" BASIS,
12*38e8c45fSAndroid Build Coastguard Worker  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13*38e8c45fSAndroid Build Coastguard Worker  * See the License for the specific language governing permissions and
14*38e8c45fSAndroid Build Coastguard Worker  * limitations under the License.
15*38e8c45fSAndroid Build Coastguard Worker  */
16*38e8c45fSAndroid Build Coastguard Worker 
17*38e8c45fSAndroid Build Coastguard Worker #include "FakeWindows.h"
18*38e8c45fSAndroid Build Coastguard Worker 
19*38e8c45fSAndroid Build Coastguard Worker #include <gtest/gtest.h>
20*38e8c45fSAndroid Build Coastguard Worker 
21*38e8c45fSAndroid Build Coastguard Worker namespace android {
22*38e8c45fSAndroid Build Coastguard Worker 
23*38e8c45fSAndroid Build Coastguard Worker // --- FakeInputReceiver ---
24*38e8c45fSAndroid Build Coastguard Worker 
FakeInputReceiver(std::unique_ptr<InputChannel> clientChannel,const std::string name)25*38e8c45fSAndroid Build Coastguard Worker FakeInputReceiver::FakeInputReceiver(std::unique_ptr<InputChannel> clientChannel,
26*38e8c45fSAndroid Build Coastguard Worker                                      const std::string name)
27*38e8c45fSAndroid Build Coastguard Worker       : mConsumer(std::move(clientChannel)), mName(name) {}
28*38e8c45fSAndroid Build Coastguard Worker 
consume(std::chrono::milliseconds timeout,bool handled)29*38e8c45fSAndroid Build Coastguard Worker std::unique_ptr<InputEvent> FakeInputReceiver::consume(std::chrono::milliseconds timeout,
30*38e8c45fSAndroid Build Coastguard Worker                                                        bool handled) {
31*38e8c45fSAndroid Build Coastguard Worker     auto [consumeSeq, event] = receiveEvent(timeout);
32*38e8c45fSAndroid Build Coastguard Worker     if (!consumeSeq) {
33*38e8c45fSAndroid Build Coastguard Worker         return nullptr;
34*38e8c45fSAndroid Build Coastguard Worker     }
35*38e8c45fSAndroid Build Coastguard Worker     finishEvent(*consumeSeq, handled);
36*38e8c45fSAndroid Build Coastguard Worker     return std::move(event);
37*38e8c45fSAndroid Build Coastguard Worker }
38*38e8c45fSAndroid Build Coastguard Worker 
receiveEvent(std::chrono::milliseconds timeout)39*38e8c45fSAndroid Build Coastguard Worker std::pair<std::optional<uint32_t>, std::unique_ptr<InputEvent>> FakeInputReceiver::receiveEvent(
40*38e8c45fSAndroid Build Coastguard Worker         std::chrono::milliseconds timeout) {
41*38e8c45fSAndroid Build Coastguard Worker     uint32_t consumeSeq;
42*38e8c45fSAndroid Build Coastguard Worker     std::unique_ptr<InputEvent> event;
43*38e8c45fSAndroid Build Coastguard Worker 
44*38e8c45fSAndroid Build Coastguard Worker     std::chrono::time_point start = std::chrono::steady_clock::now();
45*38e8c45fSAndroid Build Coastguard Worker     status_t status = WOULD_BLOCK;
46*38e8c45fSAndroid Build Coastguard Worker     while (status == WOULD_BLOCK) {
47*38e8c45fSAndroid Build Coastguard Worker         InputEvent* rawEventPtr = nullptr;
48*38e8c45fSAndroid Build Coastguard Worker         status = mConsumer.consume(&mEventFactory, /*consumeBatches=*/true, -1, &consumeSeq,
49*38e8c45fSAndroid Build Coastguard Worker                                    &rawEventPtr);
50*38e8c45fSAndroid Build Coastguard Worker         event = std::unique_ptr<InputEvent>(rawEventPtr);
51*38e8c45fSAndroid Build Coastguard Worker         std::chrono::duration elapsed = std::chrono::steady_clock::now() - start;
52*38e8c45fSAndroid Build Coastguard Worker         if (elapsed > timeout) {
53*38e8c45fSAndroid Build Coastguard Worker             break;
54*38e8c45fSAndroid Build Coastguard Worker         }
55*38e8c45fSAndroid Build Coastguard Worker     }
56*38e8c45fSAndroid Build Coastguard Worker 
57*38e8c45fSAndroid Build Coastguard Worker     if (status == WOULD_BLOCK) {
58*38e8c45fSAndroid Build Coastguard Worker         // Just means there's no event available.
59*38e8c45fSAndroid Build Coastguard Worker         return std::make_pair(std::nullopt, nullptr);
60*38e8c45fSAndroid Build Coastguard Worker     }
61*38e8c45fSAndroid Build Coastguard Worker 
62*38e8c45fSAndroid Build Coastguard Worker     if (status != OK) {
63*38e8c45fSAndroid Build Coastguard Worker         ADD_FAILURE() << mName.c_str() << ": consumer consume should return OK.";
64*38e8c45fSAndroid Build Coastguard Worker         return std::make_pair(std::nullopt, nullptr);
65*38e8c45fSAndroid Build Coastguard Worker     }
66*38e8c45fSAndroid Build Coastguard Worker     if (event == nullptr) {
67*38e8c45fSAndroid Build Coastguard Worker         ADD_FAILURE() << "Consumed correctly, but received NULL event from consumer";
68*38e8c45fSAndroid Build Coastguard Worker     }
69*38e8c45fSAndroid Build Coastguard Worker     return std::make_pair(consumeSeq, std::move(event));
70*38e8c45fSAndroid Build Coastguard Worker }
71*38e8c45fSAndroid Build Coastguard Worker 
finishEvent(uint32_t consumeSeq,bool handled)72*38e8c45fSAndroid Build Coastguard Worker void FakeInputReceiver::finishEvent(uint32_t consumeSeq, bool handled) {
73*38e8c45fSAndroid Build Coastguard Worker     const status_t status = mConsumer.sendFinishedSignal(consumeSeq, handled);
74*38e8c45fSAndroid Build Coastguard Worker     ASSERT_EQ(OK, status) << mName.c_str() << ": consumer sendFinishedSignal should return OK.";
75*38e8c45fSAndroid Build Coastguard Worker }
76*38e8c45fSAndroid Build Coastguard Worker 
sendTimeline(int32_t inputEventId,std::array<nsecs_t,GraphicsTimeline::SIZE> timeline)77*38e8c45fSAndroid Build Coastguard Worker void FakeInputReceiver::sendTimeline(int32_t inputEventId,
78*38e8c45fSAndroid Build Coastguard Worker                                      std::array<nsecs_t, GraphicsTimeline::SIZE> timeline) {
79*38e8c45fSAndroid Build Coastguard Worker     const status_t status = mConsumer.sendTimeline(inputEventId, timeline);
80*38e8c45fSAndroid Build Coastguard Worker     ASSERT_EQ(OK, status);
81*38e8c45fSAndroid Build Coastguard Worker }
82*38e8c45fSAndroid Build Coastguard Worker 
consumeEvent(InputEventType expectedEventType,int32_t expectedAction,std::optional<ui::LogicalDisplayId> expectedDisplayId,std::optional<int32_t> expectedFlags)83*38e8c45fSAndroid Build Coastguard Worker void FakeInputReceiver::consumeEvent(InputEventType expectedEventType, int32_t expectedAction,
84*38e8c45fSAndroid Build Coastguard Worker                                      std::optional<ui::LogicalDisplayId> expectedDisplayId,
85*38e8c45fSAndroid Build Coastguard Worker                                      std::optional<int32_t> expectedFlags) {
86*38e8c45fSAndroid Build Coastguard Worker     std::unique_ptr<InputEvent> event = consume(CONSUME_TIMEOUT_EVENT_EXPECTED);
87*38e8c45fSAndroid Build Coastguard Worker 
88*38e8c45fSAndroid Build Coastguard Worker     ASSERT_NE(nullptr, event) << mName.c_str() << ": consumer should have returned non-NULL event.";
89*38e8c45fSAndroid Build Coastguard Worker     ASSERT_EQ(expectedEventType, event->getType())
90*38e8c45fSAndroid Build Coastguard Worker             << mName.c_str() << " expected " << ftl::enum_string(expectedEventType)
91*38e8c45fSAndroid Build Coastguard Worker             << " event, got " << *event;
92*38e8c45fSAndroid Build Coastguard Worker 
93*38e8c45fSAndroid Build Coastguard Worker     if (expectedDisplayId.has_value()) {
94*38e8c45fSAndroid Build Coastguard Worker         EXPECT_EQ(expectedDisplayId, event->getDisplayId());
95*38e8c45fSAndroid Build Coastguard Worker     }
96*38e8c45fSAndroid Build Coastguard Worker 
97*38e8c45fSAndroid Build Coastguard Worker     switch (expectedEventType) {
98*38e8c45fSAndroid Build Coastguard Worker         case InputEventType::KEY: {
99*38e8c45fSAndroid Build Coastguard Worker             const KeyEvent& keyEvent = static_cast<const KeyEvent&>(*event);
100*38e8c45fSAndroid Build Coastguard Worker             ASSERT_THAT(keyEvent, WithKeyAction(expectedAction));
101*38e8c45fSAndroid Build Coastguard Worker             if (expectedFlags.has_value()) {
102*38e8c45fSAndroid Build Coastguard Worker                 EXPECT_EQ(expectedFlags.value(), keyEvent.getFlags());
103*38e8c45fSAndroid Build Coastguard Worker             }
104*38e8c45fSAndroid Build Coastguard Worker             break;
105*38e8c45fSAndroid Build Coastguard Worker         }
106*38e8c45fSAndroid Build Coastguard Worker         case InputEventType::MOTION: {
107*38e8c45fSAndroid Build Coastguard Worker             const MotionEvent& motionEvent = static_cast<const MotionEvent&>(*event);
108*38e8c45fSAndroid Build Coastguard Worker             ASSERT_THAT(motionEvent, WithMotionAction(expectedAction));
109*38e8c45fSAndroid Build Coastguard Worker             if (expectedFlags.has_value()) {
110*38e8c45fSAndroid Build Coastguard Worker                 EXPECT_EQ(expectedFlags.value(), motionEvent.getFlags());
111*38e8c45fSAndroid Build Coastguard Worker             }
112*38e8c45fSAndroid Build Coastguard Worker             break;
113*38e8c45fSAndroid Build Coastguard Worker         }
114*38e8c45fSAndroid Build Coastguard Worker         case InputEventType::FOCUS: {
115*38e8c45fSAndroid Build Coastguard Worker             FAIL() << "Use 'consumeFocusEvent' for FOCUS events";
116*38e8c45fSAndroid Build Coastguard Worker         }
117*38e8c45fSAndroid Build Coastguard Worker         case InputEventType::CAPTURE: {
118*38e8c45fSAndroid Build Coastguard Worker             FAIL() << "Use 'consumeCaptureEvent' for CAPTURE events";
119*38e8c45fSAndroid Build Coastguard Worker         }
120*38e8c45fSAndroid Build Coastguard Worker         case InputEventType::TOUCH_MODE: {
121*38e8c45fSAndroid Build Coastguard Worker             FAIL() << "Use 'consumeTouchModeEvent' for TOUCH_MODE events";
122*38e8c45fSAndroid Build Coastguard Worker         }
123*38e8c45fSAndroid Build Coastguard Worker         case InputEventType::DRAG: {
124*38e8c45fSAndroid Build Coastguard Worker             FAIL() << "Use 'consumeDragEvent' for DRAG events";
125*38e8c45fSAndroid Build Coastguard Worker         }
126*38e8c45fSAndroid Build Coastguard Worker     }
127*38e8c45fSAndroid Build Coastguard Worker }
128*38e8c45fSAndroid Build Coastguard Worker 
consumeMotion()129*38e8c45fSAndroid Build Coastguard Worker std::unique_ptr<MotionEvent> FakeInputReceiver::consumeMotion() {
130*38e8c45fSAndroid Build Coastguard Worker     std::unique_ptr<InputEvent> event = consume(CONSUME_TIMEOUT_EVENT_EXPECTED);
131*38e8c45fSAndroid Build Coastguard Worker 
132*38e8c45fSAndroid Build Coastguard Worker     if (event == nullptr) {
133*38e8c45fSAndroid Build Coastguard Worker         ADD_FAILURE() << mName << ": expected a MotionEvent, but didn't get one.";
134*38e8c45fSAndroid Build Coastguard Worker         return nullptr;
135*38e8c45fSAndroid Build Coastguard Worker     }
136*38e8c45fSAndroid Build Coastguard Worker 
137*38e8c45fSAndroid Build Coastguard Worker     if (event->getType() != InputEventType::MOTION) {
138*38e8c45fSAndroid Build Coastguard Worker         ADD_FAILURE() << mName << " expected a MotionEvent, got " << *event;
139*38e8c45fSAndroid Build Coastguard Worker         return nullptr;
140*38e8c45fSAndroid Build Coastguard Worker     }
141*38e8c45fSAndroid Build Coastguard Worker     return std::unique_ptr<MotionEvent>(static_cast<MotionEvent*>(event.release()));
142*38e8c45fSAndroid Build Coastguard Worker }
143*38e8c45fSAndroid Build Coastguard Worker 
consumeMotionEvent(const::testing::Matcher<MotionEvent> & matcher)144*38e8c45fSAndroid Build Coastguard Worker void FakeInputReceiver::consumeMotionEvent(const ::testing::Matcher<MotionEvent>& matcher) {
145*38e8c45fSAndroid Build Coastguard Worker     std::unique_ptr<MotionEvent> motionEvent = consumeMotion();
146*38e8c45fSAndroid Build Coastguard Worker     ASSERT_NE(nullptr, motionEvent) << "Did not get a motion event, but expected " << matcher;
147*38e8c45fSAndroid Build Coastguard Worker     ASSERT_THAT(*motionEvent, matcher);
148*38e8c45fSAndroid Build Coastguard Worker }
149*38e8c45fSAndroid Build Coastguard Worker 
consumeFocusEvent(bool hasFocus,bool inTouchMode)150*38e8c45fSAndroid Build Coastguard Worker void FakeInputReceiver::consumeFocusEvent(bool hasFocus, bool inTouchMode) {
151*38e8c45fSAndroid Build Coastguard Worker     std::unique_ptr<InputEvent> event = consume(CONSUME_TIMEOUT_EVENT_EXPECTED);
152*38e8c45fSAndroid Build Coastguard Worker     ASSERT_NE(nullptr, event) << mName.c_str() << ": consumer should have returned non-NULL event.";
153*38e8c45fSAndroid Build Coastguard Worker     ASSERT_EQ(InputEventType::FOCUS, event->getType()) << "Instead of FocusEvent, got " << *event;
154*38e8c45fSAndroid Build Coastguard Worker 
155*38e8c45fSAndroid Build Coastguard Worker     ASSERT_EQ(ui::LogicalDisplayId::INVALID, event->getDisplayId())
156*38e8c45fSAndroid Build Coastguard Worker             << mName.c_str() << ": event displayId should always be NONE.";
157*38e8c45fSAndroid Build Coastguard Worker 
158*38e8c45fSAndroid Build Coastguard Worker     FocusEvent& focusEvent = static_cast<FocusEvent&>(*event);
159*38e8c45fSAndroid Build Coastguard Worker     EXPECT_EQ(hasFocus, focusEvent.getHasFocus());
160*38e8c45fSAndroid Build Coastguard Worker }
161*38e8c45fSAndroid Build Coastguard Worker 
consumeCaptureEvent(bool hasCapture)162*38e8c45fSAndroid Build Coastguard Worker void FakeInputReceiver::consumeCaptureEvent(bool hasCapture) {
163*38e8c45fSAndroid Build Coastguard Worker     std::unique_ptr<InputEvent> event = consume(CONSUME_TIMEOUT_EVENT_EXPECTED);
164*38e8c45fSAndroid Build Coastguard Worker     ASSERT_NE(nullptr, event) << mName.c_str() << ": consumer should have returned non-NULL event.";
165*38e8c45fSAndroid Build Coastguard Worker     ASSERT_EQ(InputEventType::CAPTURE, event->getType())
166*38e8c45fSAndroid Build Coastguard Worker             << "Instead of CaptureEvent, got " << *event;
167*38e8c45fSAndroid Build Coastguard Worker 
168*38e8c45fSAndroid Build Coastguard Worker     ASSERT_EQ(ui::LogicalDisplayId::INVALID, event->getDisplayId())
169*38e8c45fSAndroid Build Coastguard Worker             << mName.c_str() << ": event displayId should always be NONE.";
170*38e8c45fSAndroid Build Coastguard Worker 
171*38e8c45fSAndroid Build Coastguard Worker     const auto& captureEvent = static_cast<const CaptureEvent&>(*event);
172*38e8c45fSAndroid Build Coastguard Worker     EXPECT_EQ(hasCapture, captureEvent.getPointerCaptureEnabled());
173*38e8c45fSAndroid Build Coastguard Worker }
174*38e8c45fSAndroid Build Coastguard Worker 
consumeDragEvent(bool isExiting,float x,float y)175*38e8c45fSAndroid Build Coastguard Worker void FakeInputReceiver::consumeDragEvent(bool isExiting, float x, float y) {
176*38e8c45fSAndroid Build Coastguard Worker     std::unique_ptr<InputEvent> event = consume(CONSUME_TIMEOUT_EVENT_EXPECTED);
177*38e8c45fSAndroid Build Coastguard Worker     ASSERT_NE(nullptr, event) << mName.c_str() << ": consumer should have returned non-NULL event.";
178*38e8c45fSAndroid Build Coastguard Worker     ASSERT_EQ(InputEventType::DRAG, event->getType()) << "Instead of DragEvent, got " << *event;
179*38e8c45fSAndroid Build Coastguard Worker 
180*38e8c45fSAndroid Build Coastguard Worker     EXPECT_EQ(ui::LogicalDisplayId::INVALID, event->getDisplayId())
181*38e8c45fSAndroid Build Coastguard Worker             << mName.c_str() << ": event displayId should always be NONE.";
182*38e8c45fSAndroid Build Coastguard Worker 
183*38e8c45fSAndroid Build Coastguard Worker     const auto& dragEvent = static_cast<const DragEvent&>(*event);
184*38e8c45fSAndroid Build Coastguard Worker     EXPECT_EQ(isExiting, dragEvent.isExiting());
185*38e8c45fSAndroid Build Coastguard Worker     EXPECT_EQ(x, dragEvent.getX());
186*38e8c45fSAndroid Build Coastguard Worker     EXPECT_EQ(y, dragEvent.getY());
187*38e8c45fSAndroid Build Coastguard Worker }
188*38e8c45fSAndroid Build Coastguard Worker 
consumeTouchModeEvent(bool inTouchMode)189*38e8c45fSAndroid Build Coastguard Worker void FakeInputReceiver::consumeTouchModeEvent(bool inTouchMode) {
190*38e8c45fSAndroid Build Coastguard Worker     std::unique_ptr<InputEvent> event = consume(CONSUME_TIMEOUT_EVENT_EXPECTED);
191*38e8c45fSAndroid Build Coastguard Worker     ASSERT_NE(nullptr, event) << mName.c_str() << ": consumer should have returned non-NULL event.";
192*38e8c45fSAndroid Build Coastguard Worker     ASSERT_EQ(InputEventType::TOUCH_MODE, event->getType())
193*38e8c45fSAndroid Build Coastguard Worker             << "Instead of TouchModeEvent, got " << *event;
194*38e8c45fSAndroid Build Coastguard Worker 
195*38e8c45fSAndroid Build Coastguard Worker     ASSERT_EQ(ui::LogicalDisplayId::INVALID, event->getDisplayId())
196*38e8c45fSAndroid Build Coastguard Worker             << mName.c_str() << ": event displayId should always be NONE.";
197*38e8c45fSAndroid Build Coastguard Worker     const auto& touchModeEvent = static_cast<const TouchModeEvent&>(*event);
198*38e8c45fSAndroid Build Coastguard Worker     EXPECT_EQ(inTouchMode, touchModeEvent.isInTouchMode());
199*38e8c45fSAndroid Build Coastguard Worker }
200*38e8c45fSAndroid Build Coastguard Worker 
assertNoEvents(std::chrono::milliseconds timeout)201*38e8c45fSAndroid Build Coastguard Worker void FakeInputReceiver::assertNoEvents(std::chrono::milliseconds timeout) {
202*38e8c45fSAndroid Build Coastguard Worker     std::unique_ptr<InputEvent> event = consume(timeout);
203*38e8c45fSAndroid Build Coastguard Worker     if (event == nullptr) {
204*38e8c45fSAndroid Build Coastguard Worker         return;
205*38e8c45fSAndroid Build Coastguard Worker     }
206*38e8c45fSAndroid Build Coastguard Worker     if (event->getType() == InputEventType::KEY) {
207*38e8c45fSAndroid Build Coastguard Worker         KeyEvent& keyEvent = static_cast<KeyEvent&>(*event);
208*38e8c45fSAndroid Build Coastguard Worker         ADD_FAILURE() << "Received key event " << keyEvent;
209*38e8c45fSAndroid Build Coastguard Worker     } else if (event->getType() == InputEventType::MOTION) {
210*38e8c45fSAndroid Build Coastguard Worker         MotionEvent& motionEvent = static_cast<MotionEvent&>(*event);
211*38e8c45fSAndroid Build Coastguard Worker         ADD_FAILURE() << "Received motion event " << motionEvent;
212*38e8c45fSAndroid Build Coastguard Worker     } else if (event->getType() == InputEventType::FOCUS) {
213*38e8c45fSAndroid Build Coastguard Worker         FocusEvent& focusEvent = static_cast<FocusEvent&>(*event);
214*38e8c45fSAndroid Build Coastguard Worker         ADD_FAILURE() << "Received focus event, hasFocus = "
215*38e8c45fSAndroid Build Coastguard Worker                       << (focusEvent.getHasFocus() ? "true" : "false");
216*38e8c45fSAndroid Build Coastguard Worker     } else if (event->getType() == InputEventType::CAPTURE) {
217*38e8c45fSAndroid Build Coastguard Worker         const auto& captureEvent = static_cast<CaptureEvent&>(*event);
218*38e8c45fSAndroid Build Coastguard Worker         ADD_FAILURE() << "Received capture event, pointerCaptureEnabled = "
219*38e8c45fSAndroid Build Coastguard Worker                       << (captureEvent.getPointerCaptureEnabled() ? "true" : "false");
220*38e8c45fSAndroid Build Coastguard Worker     } else if (event->getType() == InputEventType::TOUCH_MODE) {
221*38e8c45fSAndroid Build Coastguard Worker         const auto& touchModeEvent = static_cast<TouchModeEvent&>(*event);
222*38e8c45fSAndroid Build Coastguard Worker         ADD_FAILURE() << "Received touch mode event, inTouchMode = "
223*38e8c45fSAndroid Build Coastguard Worker                       << (touchModeEvent.isInTouchMode() ? "true" : "false");
224*38e8c45fSAndroid Build Coastguard Worker     }
225*38e8c45fSAndroid Build Coastguard Worker     FAIL() << mName.c_str()
226*38e8c45fSAndroid Build Coastguard Worker            << ": should not have received any events, so consume() should return NULL";
227*38e8c45fSAndroid Build Coastguard Worker }
228*38e8c45fSAndroid Build Coastguard Worker 
getToken()229*38e8c45fSAndroid Build Coastguard Worker sp<IBinder> FakeInputReceiver::getToken() {
230*38e8c45fSAndroid Build Coastguard Worker     return mConsumer.getChannel()->getConnectionToken();
231*38e8c45fSAndroid Build Coastguard Worker }
232*38e8c45fSAndroid Build Coastguard Worker 
getChannelFd()233*38e8c45fSAndroid Build Coastguard Worker int FakeInputReceiver::getChannelFd() {
234*38e8c45fSAndroid Build Coastguard Worker     return mConsumer.getChannel()->getFd();
235*38e8c45fSAndroid Build Coastguard Worker }
236*38e8c45fSAndroid Build Coastguard Worker 
237*38e8c45fSAndroid Build Coastguard Worker // --- FakeWindowHandle ---
238*38e8c45fSAndroid Build Coastguard Worker 
239*38e8c45fSAndroid Build Coastguard Worker std::function<void(const std::unique_ptr<InputEvent>&, const gui::WindowInfo&)>
240*38e8c45fSAndroid Build Coastguard Worker         FakeWindowHandle::sOnEventReceivedCallback{};
241*38e8c45fSAndroid Build Coastguard Worker 
242*38e8c45fSAndroid Build Coastguard Worker std::atomic<int32_t> FakeWindowHandle::sId{1};
243*38e8c45fSAndroid Build Coastguard Worker 
FakeWindowHandle(const std::shared_ptr<InputApplicationHandle> & inputApplicationHandle,const std::unique_ptr<inputdispatcher::InputDispatcher> & dispatcher,const std::string name,ui::LogicalDisplayId displayId,bool createInputChannel)244*38e8c45fSAndroid Build Coastguard Worker FakeWindowHandle::FakeWindowHandle(
245*38e8c45fSAndroid Build Coastguard Worker         const std::shared_ptr<InputApplicationHandle>& inputApplicationHandle,
246*38e8c45fSAndroid Build Coastguard Worker         const std::unique_ptr<inputdispatcher::InputDispatcher>& dispatcher, const std::string name,
247*38e8c45fSAndroid Build Coastguard Worker         ui::LogicalDisplayId displayId, bool createInputChannel)
248*38e8c45fSAndroid Build Coastguard Worker       : mName(name) {
249*38e8c45fSAndroid Build Coastguard Worker     sp<IBinder> token;
250*38e8c45fSAndroid Build Coastguard Worker     if (createInputChannel) {
251*38e8c45fSAndroid Build Coastguard Worker         base::Result<std::unique_ptr<InputChannel>> channel = dispatcher->createInputChannel(name);
252*38e8c45fSAndroid Build Coastguard Worker         token = (*channel)->getConnectionToken();
253*38e8c45fSAndroid Build Coastguard Worker         mInputReceiver = std::make_unique<FakeInputReceiver>(std::move(*channel), name);
254*38e8c45fSAndroid Build Coastguard Worker     }
255*38e8c45fSAndroid Build Coastguard Worker 
256*38e8c45fSAndroid Build Coastguard Worker     inputApplicationHandle->updateInfo();
257*38e8c45fSAndroid Build Coastguard Worker     mInfo.applicationInfo = *inputApplicationHandle->getInfo();
258*38e8c45fSAndroid Build Coastguard Worker 
259*38e8c45fSAndroid Build Coastguard Worker     mInfo.token = token;
260*38e8c45fSAndroid Build Coastguard Worker     mInfo.id = sId++;
261*38e8c45fSAndroid Build Coastguard Worker     mInfo.name = name;
262*38e8c45fSAndroid Build Coastguard Worker     mInfo.dispatchingTimeout = DISPATCHING_TIMEOUT;
263*38e8c45fSAndroid Build Coastguard Worker     mInfo.alpha = 1.0;
264*38e8c45fSAndroid Build Coastguard Worker     mInfo.frame = Rect(0, 0, WIDTH, HEIGHT);
265*38e8c45fSAndroid Build Coastguard Worker     mInfo.transform.set(0, 0);
266*38e8c45fSAndroid Build Coastguard Worker     mInfo.globalScaleFactor = 1.0;
267*38e8c45fSAndroid Build Coastguard Worker     mInfo.touchableRegion.clear();
268*38e8c45fSAndroid Build Coastguard Worker     mInfo.addTouchableRegion(Rect(0, 0, WIDTH, HEIGHT));
269*38e8c45fSAndroid Build Coastguard Worker     mInfo.ownerPid = WINDOW_PID;
270*38e8c45fSAndroid Build Coastguard Worker     mInfo.ownerUid = WINDOW_UID;
271*38e8c45fSAndroid Build Coastguard Worker     mInfo.displayId = displayId;
272*38e8c45fSAndroid Build Coastguard Worker     mInfo.inputConfig = InputConfig::DEFAULT;
273*38e8c45fSAndroid Build Coastguard Worker }
274*38e8c45fSAndroid Build Coastguard Worker 
clone(ui::LogicalDisplayId displayId)275*38e8c45fSAndroid Build Coastguard Worker sp<FakeWindowHandle> FakeWindowHandle::clone(ui::LogicalDisplayId displayId) {
276*38e8c45fSAndroid Build Coastguard Worker     sp<FakeWindowHandle> handle = sp<FakeWindowHandle>::make(mInfo.name + "(Mirror)");
277*38e8c45fSAndroid Build Coastguard Worker     handle->mInfo = mInfo;
278*38e8c45fSAndroid Build Coastguard Worker     handle->mInfo.displayId = displayId;
279*38e8c45fSAndroid Build Coastguard Worker     handle->mInfo.id = sId++;
280*38e8c45fSAndroid Build Coastguard Worker     handle->mInputReceiver = mInputReceiver;
281*38e8c45fSAndroid Build Coastguard Worker     return handle;
282*38e8c45fSAndroid Build Coastguard Worker }
283*38e8c45fSAndroid Build Coastguard Worker 
consumeKey(bool handled)284*38e8c45fSAndroid Build Coastguard Worker std::unique_ptr<KeyEvent> FakeWindowHandle::consumeKey(bool handled) {
285*38e8c45fSAndroid Build Coastguard Worker     std::unique_ptr<InputEvent> event = consume(CONSUME_TIMEOUT_EVENT_EXPECTED, handled);
286*38e8c45fSAndroid Build Coastguard Worker     if (event == nullptr) {
287*38e8c45fSAndroid Build Coastguard Worker         ADD_FAILURE() << "No event";
288*38e8c45fSAndroid Build Coastguard Worker         return nullptr;
289*38e8c45fSAndroid Build Coastguard Worker     }
290*38e8c45fSAndroid Build Coastguard Worker     if (event->getType() != InputEventType::KEY) {
291*38e8c45fSAndroid Build Coastguard Worker         ADD_FAILURE() << "Instead of key event, got " << event;
292*38e8c45fSAndroid Build Coastguard Worker         return nullptr;
293*38e8c45fSAndroid Build Coastguard Worker     }
294*38e8c45fSAndroid Build Coastguard Worker     return std::unique_ptr<KeyEvent>(static_cast<KeyEvent*>(event.release()));
295*38e8c45fSAndroid Build Coastguard Worker }
296*38e8c45fSAndroid Build Coastguard Worker 
consumeMotionEvent(const::testing::Matcher<MotionEvent> & matcher)297*38e8c45fSAndroid Build Coastguard Worker std::unique_ptr<MotionEvent> FakeWindowHandle::consumeMotionEvent(
298*38e8c45fSAndroid Build Coastguard Worker         const ::testing::Matcher<MotionEvent>& matcher) {
299*38e8c45fSAndroid Build Coastguard Worker     std::unique_ptr<InputEvent> event = consume(CONSUME_TIMEOUT_EVENT_EXPECTED);
300*38e8c45fSAndroid Build Coastguard Worker     if (event == nullptr) {
301*38e8c45fSAndroid Build Coastguard Worker         std::ostringstream matcherDescription;
302*38e8c45fSAndroid Build Coastguard Worker         matcher.DescribeTo(&matcherDescription);
303*38e8c45fSAndroid Build Coastguard Worker         ADD_FAILURE() << "No event (expected " << matcherDescription.str() << ") on " << mName;
304*38e8c45fSAndroid Build Coastguard Worker         return nullptr;
305*38e8c45fSAndroid Build Coastguard Worker     }
306*38e8c45fSAndroid Build Coastguard Worker     if (event->getType() != InputEventType::MOTION) {
307*38e8c45fSAndroid Build Coastguard Worker         ADD_FAILURE() << "Instead of motion event, got " << *event << " on " << mName;
308*38e8c45fSAndroid Build Coastguard Worker         return nullptr;
309*38e8c45fSAndroid Build Coastguard Worker     }
310*38e8c45fSAndroid Build Coastguard Worker     std::unique_ptr<MotionEvent> motionEvent =
311*38e8c45fSAndroid Build Coastguard Worker             std::unique_ptr<MotionEvent>(static_cast<MotionEvent*>(event.release()));
312*38e8c45fSAndroid Build Coastguard Worker     if (motionEvent == nullptr) {
313*38e8c45fSAndroid Build Coastguard Worker         return nullptr;
314*38e8c45fSAndroid Build Coastguard Worker     }
315*38e8c45fSAndroid Build Coastguard Worker     EXPECT_THAT(*motionEvent, matcher) << " on " << mName;
316*38e8c45fSAndroid Build Coastguard Worker     return motionEvent;
317*38e8c45fSAndroid Build Coastguard Worker }
318*38e8c45fSAndroid Build Coastguard Worker 
assertNoEvents(std::optional<std::chrono::milliseconds> timeout)319*38e8c45fSAndroid Build Coastguard Worker void FakeWindowHandle::assertNoEvents(std::optional<std::chrono::milliseconds> timeout) {
320*38e8c45fSAndroid Build Coastguard Worker     if (mInputReceiver == nullptr && mInfo.inputConfig.test(InputConfig::NO_INPUT_CHANNEL)) {
321*38e8c45fSAndroid Build Coastguard Worker         return; // Can't receive events if the window does not have input channel
322*38e8c45fSAndroid Build Coastguard Worker     }
323*38e8c45fSAndroid Build Coastguard Worker     ASSERT_NE(nullptr, mInputReceiver)
324*38e8c45fSAndroid Build Coastguard Worker             << "Window without InputReceiver must specify feature NO_INPUT_CHANNEL";
325*38e8c45fSAndroid Build Coastguard Worker     mInputReceiver->assertNoEvents(timeout.value_or(CONSUME_TIMEOUT_NO_EVENT_EXPECTED));
326*38e8c45fSAndroid Build Coastguard Worker }
327*38e8c45fSAndroid Build Coastguard Worker 
consume(std::chrono::milliseconds timeout,bool handled)328*38e8c45fSAndroid Build Coastguard Worker std::unique_ptr<InputEvent> FakeWindowHandle::consume(std::chrono::milliseconds timeout,
329*38e8c45fSAndroid Build Coastguard Worker                                                       bool handled) {
330*38e8c45fSAndroid Build Coastguard Worker     if (mInputReceiver == nullptr) {
331*38e8c45fSAndroid Build Coastguard Worker         LOG(FATAL) << "Cannot consume event from a window with no input event receiver";
332*38e8c45fSAndroid Build Coastguard Worker     }
333*38e8c45fSAndroid Build Coastguard Worker     std::unique_ptr<InputEvent> event = mInputReceiver->consume(timeout, handled);
334*38e8c45fSAndroid Build Coastguard Worker     if (event == nullptr) {
335*38e8c45fSAndroid Build Coastguard Worker         ADD_FAILURE() << "Consume failed: no event";
336*38e8c45fSAndroid Build Coastguard Worker     }
337*38e8c45fSAndroid Build Coastguard Worker 
338*38e8c45fSAndroid Build Coastguard Worker     if (sOnEventReceivedCallback != nullptr) {
339*38e8c45fSAndroid Build Coastguard Worker         sOnEventReceivedCallback(event, mInfo);
340*38e8c45fSAndroid Build Coastguard Worker     }
341*38e8c45fSAndroid Build Coastguard Worker     return event;
342*38e8c45fSAndroid Build Coastguard Worker }
343*38e8c45fSAndroid Build Coastguard Worker 
344*38e8c45fSAndroid Build Coastguard Worker std::pair<std::optional<uint32_t /*seq*/>, std::unique_ptr<InputEvent>>
receive()345*38e8c45fSAndroid Build Coastguard Worker FakeWindowHandle::receive() {
346*38e8c45fSAndroid Build Coastguard Worker     if (mInputReceiver == nullptr) {
347*38e8c45fSAndroid Build Coastguard Worker         ADD_FAILURE() << "Invalid receive event on window with no receiver";
348*38e8c45fSAndroid Build Coastguard Worker         return std::make_pair(std::nullopt, nullptr);
349*38e8c45fSAndroid Build Coastguard Worker     }
350*38e8c45fSAndroid Build Coastguard Worker     auto out = mInputReceiver->receiveEvent(CONSUME_TIMEOUT_EVENT_EXPECTED);
351*38e8c45fSAndroid Build Coastguard Worker     const auto& [_, event] = out;
352*38e8c45fSAndroid Build Coastguard Worker 
353*38e8c45fSAndroid Build Coastguard Worker     if (sOnEventReceivedCallback != nullptr) {
354*38e8c45fSAndroid Build Coastguard Worker         sOnEventReceivedCallback(event, mInfo);
355*38e8c45fSAndroid Build Coastguard Worker     }
356*38e8c45fSAndroid Build Coastguard Worker     return out;
357*38e8c45fSAndroid Build Coastguard Worker }
358*38e8c45fSAndroid Build Coastguard Worker 
359*38e8c45fSAndroid Build Coastguard Worker } // namespace android
360