1 /*
2 * Copyright (c) 2022 Huawei Device Co., Ltd.
3 * Licensed under the Apache License, Version 2.0 (the "License");
4 * you may not use this file except in compliance with the License.
5 * You may obtain a copy of the License at
6 *
7 * http://www.apache.org/licenses/LICENSE-2.0
8 *
9 * Unless required by applicable law or agreed to in writing, software
10 * distributed under the License is distributed on an "AS IS" BASIS,
11 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 * See the License for the specific language governing permissions and
13 * limitations under the License.
14 */
15
16 #include "event_util_test.h"
17
18 #include <iomanip>
19
20 #include "mmi_log.h"
21
22 #undef MMI_LOG_TAG
23 #define MMI_LOG_TAG "EventUtilTest"
24
25 namespace OHOS {
26 namespace MMI {
27 namespace {
28 constexpr int32_t TIME_WAIT_FOR_EVENT { 1000 };
29 constexpr int32_t SEC_TO_NANOSEC { 1000000000 };
30 } // namespace
31
OnInputEvent(std::shared_ptr<KeyEvent> keyEvent) const32 void InputEventConsumer::OnInputEvent(std::shared_ptr<KeyEvent> keyEvent) const
33 {
34 CALL_DEBUG_ENTER;
35 RECV_FLAG flag = TestUtil->GetRecvFlag();
36 if (flag == RECV_FLAG::RECV_FOCUS || flag == RECV_FLAG::RECV_MARK_CONSUMED) {
37 keyEvent->MarkProcessed();
38 ASSERT_TRUE(keyEvent != nullptr);
39 TestUtil->AddEventDump(TestUtil->DumpInputEvent(keyEvent));
40 }
41 }
42
OnInputEvent(std::shared_ptr<PointerEvent> pointerEvent) const43 void InputEventConsumer::OnInputEvent(std::shared_ptr<PointerEvent> pointerEvent) const
44 {
45 CALL_DEBUG_ENTER;
46 RECV_FLAG flag = TestUtil->GetRecvFlag();
47 if (flag == RECV_FLAG::RECV_FOCUS || flag == RECV_FLAG::RECV_MARK_CONSUMED) {
48 pointerEvent->MarkProcessed();
49 ASSERT_TRUE(pointerEvent != nullptr);
50 auto pointerAction = pointerEvent->GetPointerAction();
51 if (pointerAction != PointerEvent::POINTER_ACTION_ENTER_WINDOW &&
52 pointerAction != PointerEvent::POINTER_ACTION_LEAVE_WINDOW &&
53 pointerAction != PointerEvent::POINTER_ACTION_PULL_IN_WINDOW &&
54 pointerAction != PointerEvent::POINTER_ACTION_PULL_OUT_WINDOW) {
55 TestUtil->AddEventDump(TestUtil->DumpInputEvent(pointerEvent));
56 }
57 }
58 }
59
OnInputEvent(std::shared_ptr<PointerEvent> pointerEvent) const60 void InputEventCallback::OnInputEvent(std::shared_ptr<PointerEvent> pointerEvent) const
61 {
62 CALL_DEBUG_ENTER;
63 if (TestUtil->GetRecvFlag() != RECV_FLAG::RECV_MARK_CONSUMED) {
64 TestUtil->SetRecvFlag(RECV_FLAG::RECV_MONITOR);
65 ASSERT_TRUE(pointerEvent != nullptr);
66 TestUtil->AddEventDump(TestUtil->DumpInputEvent(pointerEvent));
67 lastPointerEventId_ = pointerEvent->GetId();
68 }
69 }
70
OnInputEvent(std::shared_ptr<KeyEvent> keyEvent) const71 void InputEventCallback::OnInputEvent(std::shared_ptr<KeyEvent> keyEvent) const
72 {
73 CALL_DEBUG_ENTER;
74 if (TestUtil->GetRecvFlag() != RECV_FLAG::RECV_MARK_CONSUMED) {
75 TestUtil->SetRecvFlag(RECV_FLAG::RECV_MONITOR);
76 ASSERT_TRUE(keyEvent != nullptr);
77 TestUtil->AddEventDump(TestUtil->DumpInputEvent(keyEvent));
78 }
79 }
80
OnInputEvent(std::shared_ptr<PointerEvent> pointerEvent) const81 void PriorityMiddleCallback::OnInputEvent(std::shared_ptr<PointerEvent> pointerEvent) const
82 {
83 CALL_DEBUG_ENTER;
84 if (TestUtil->GetRecvFlag() != RECV_FLAG::RECV_MARK_CONSUMED) {
85 TestUtil->SetRecvFlag(RECV_FLAG::RECV_INTERCEPT);
86 TestUtil->AddEventDump("Call middle interceptor");
87 }
88 }
89
OnInputEvent(std::shared_ptr<KeyEvent> keyEvent) const90 void PriorityMiddleCallback::OnInputEvent(std::shared_ptr<KeyEvent> keyEvent) const
91 {
92 CALL_DEBUG_ENTER;
93 if (TestUtil->GetRecvFlag() != RECV_FLAG::RECV_MARK_CONSUMED) {
94 TestUtil->SetRecvFlag(RECV_FLAG::RECV_INTERCEPT);
95 TestUtil->AddEventDump("Call middle interceptor");
96 }
97 }
98
OnInputEvent(std::shared_ptr<PointerEvent> pointerEvent) const99 void PriorityHighCallback::OnInputEvent(std::shared_ptr<PointerEvent> pointerEvent) const
100 {
101 CALL_DEBUG_ENTER;
102 if (TestUtil->GetRecvFlag() != RECV_FLAG::RECV_MARK_CONSUMED) {
103 TestUtil->SetRecvFlag(RECV_FLAG::RECV_INTERCEPT);
104 TestUtil->AddEventDump("Call high interceptor");
105 }
106 }
107
OnInputEvent(std::shared_ptr<KeyEvent> keyEvent) const108 void PriorityHighCallback::OnInputEvent(std::shared_ptr<KeyEvent> keyEvent) const
109 {
110 CALL_DEBUG_ENTER;
111 if (TestUtil->GetRecvFlag() != RECV_FLAG::RECV_MARK_CONSUMED) {
112 TestUtil->SetRecvFlag(RECV_FLAG::RECV_INTERCEPT);
113 TestUtil->AddEventDump("Call high interceptor");
114 }
115 }
116
OnInputEvent(std::shared_ptr<KeyEvent> keyEvent) const117 void WindowEventConsumer::OnInputEvent(std::shared_ptr<KeyEvent> keyEvent) const
118 {
119 threadId_ = GetThisThreadId();
120 MMI_HILOGD("Consumer callback keyEvent is threadId:%{public}" PRIu64, threadId_);
121 }
122
OnInputEvent(std::shared_ptr<PointerEvent> pointerEvent) const123 void WindowEventConsumer::OnInputEvent(std::shared_ptr<PointerEvent> pointerEvent) const
124 {
125 threadId_ = GetThisThreadId();
126 MMI_HILOGD("Consumer callback pointerEvent is threadId:%{public}" PRIu64, threadId_);
127 }
128
GetConsumerThreadId()129 uint64_t WindowEventConsumer::GetConsumerThreadId()
130 {
131 return threadId_;
132 }
133
EventUtilTest()134 EventUtilTest::EventUtilTest() {}
~EventUtilTest()135 EventUtilTest::~EventUtilTest() {}
136
AddEventDump(std::string eventDump)137 void EventUtilTest::AddEventDump(std::string eventDump)
138 {
139 CALL_DEBUG_ENTER;
140 std::lock_guard<std::mutex> lockGuard(mutex_);
141 if (eventDump.empty()) {
142 strEventDump_.clear();
143 return;
144 }
145 strEventDump_.push_back(eventDump);
146 MMI_HILOGD("Setting the Dump event, strEventDump_:%{public}s", eventDump.c_str());
147 conditionVariable_.notify_one();
148 }
149
GetEventDump()150 std::string EventUtilTest::GetEventDump()
151 {
152 CALL_DEBUG_ENTER;
153 std::unique_lock<std::mutex> uniqueLock(mutex_);
154 std::string str = "";
155 if (strEventDump_.empty()) {
156 MMI_HILOGD("Waiting for an event to fire");
157 if (conditionVariable_.wait_for(uniqueLock,
158 std::chrono::milliseconds(TIME_WAIT_FOR_EVENT)) == std::cv_status::timeout) {
159 MMI_HILOGD("Timeout");
160 return str;
161 }
162 }
163 str = strEventDump_.front();
164 strEventDump_.pop_front();
165 return str;
166 }
167
Init()168 bool EventUtilTest::Init()
169 {
170 CALL_DEBUG_ENTER;
171 if (!WindowUtilsTest::GetInstance()->DrawTestWindow()) {
172 return false;
173 }
174 auto listener_ = GetPtr<InputEventConsumer>();
175 CHKPF(listener_);
176 const std::string threadTest = "EventUtilTest";
177 auto runner = AppExecFwk::EventRunner::Create(threadTest);
178 CHKPF(runner);
179 auto eventHandler = std::make_shared<AppExecFwk::EventHandler>(runner);
180 MMI::InputManager::GetInstance()->SetWindowInputEventConsumer(listener_, eventHandler);
181 return true;
182 }
183
DumpInputEvent(const std::shared_ptr<PointerEvent> & pointerEvent)184 std::string EventUtilTest::DumpInputEvent(const std::shared_ptr<PointerEvent>& pointerEvent)
185 {
186 const int precision = 2;
187 std::ostringstream ostream;
188 std::vector<int32_t> pointerIds { pointerEvent->GetPointerIds() };
189 std::string str;
190 std::vector<uint8_t> buffer = pointerEvent->GetBuffer();
191 for (const auto& buff : buffer) {
192 str += std::to_string(buff);
193 }
194 ostream << "ClientMsgHandler: in OnPointerEvent"
195 << ",EventType:" << pointerEvent->GetEventType()
196 << ",ActionTime:" << pointerEvent->GetActionTime()
197 << ",Action:" << pointerEvent->GetAction()
198 << ",ActionStartTime:" << pointerEvent->GetActionStartTime()
199 << ",Flag:" << pointerEvent->GetFlag()
200 << ",PointerAction:" << pointerEvent->DumpPointerAction()
201 << ",SourceType:" << pointerEvent->DumpSourceType()
202 << ",ButtonId:" << pointerEvent->GetButtonId()
203 << ",DeviceId:" << pointerEvent->GetDeviceId()
204 << ",VerticalAxisValue:" << std::fixed << std::setprecision(precision)
205 << pointerEvent->GetAxisValue(PointerEvent::AXIS_TYPE_SCROLL_VERTICAL)
206 << ",HorizontalAxisValue:" << std::fixed << std::setprecision(precision)
207 << pointerEvent->GetAxisValue(PointerEvent::AXIS_TYPE_SCROLL_HORIZONTAL)
208 <<",BufferCount:" << buffer.size()
209 <<",Buffer:" << str.c_str();
210 for (const auto &pointerId : pointerIds) {
211 PointerEvent::PointerItem item;
212 if (!pointerEvent->GetPointerItem(pointerId, item)) {
213 MMI_HILOGE("Invalid pointer:%{public}d.", pointerId);
214 return ostream.str();
215 }
216 ostream << ",pointerId:" << pointerId << ",DownTime:" << item.GetDownTime()
217 << ",IsPressed:" << std::boolalpha << item.IsPressed()
218 << ",DisplayX:" << item.GetDisplayX() << ",DisplayY:" << item.GetDisplayY()
219 << ",Width:" << item.GetWidth() << ",Height:" << item.GetHeight()
220 << ",TiltX:" << std::fixed << std::setprecision(precision) << item.GetTiltX()
221 << ",TiltY:" << std::fixed << std::setprecision(precision) << item.GetTiltY()
222 << ",ToolDisplayX:" << item.GetToolDisplayX() << ",ToolDisplayY:" << item.GetToolDisplayY()
223 << ",ToolWindowX:" << item.GetToolWindowX() << ",ToolWindowY:" << item.GetToolWindowY()
224 << ",ToolWidth:" << item.GetToolWidth() << ",ToolHeight:" << item.GetToolHeight()
225 << ",Pressure:" << item.GetPressure() << ",ToolType:" << item.GetToolType()
226 << ",LongAxis:" << item.GetLongAxis() << ",ShortAxis:" << item.GetShortAxis()
227 << ",DeviceId:" << item.GetDeviceId() << ",RawDx:" << item.GetRawDx()
228 << ",RawDy:" << item.GetRawDy();
229 }
230
231 return ostream.str();
232 }
233
DumpInputEvent(const std::shared_ptr<KeyEvent> & keyEvent)234 std::string EventUtilTest::DumpInputEvent(const std::shared_ptr<KeyEvent>& keyEvent)
235 {
236 std::ostringstream strm;
237 strm << "InputManagerTest: in OnKeyEvent"
238 << ", KeyCode:" << keyEvent->GetKeyCode()
239 << ", ActionTime:" << keyEvent->GetActionTime()
240 << ", Action:" << keyEvent->GetAction()
241 << ", ActionStartTime:" << keyEvent->GetActionStartTime()
242 << ", EventType:" << keyEvent->GetEventType()
243 << ", KeyAction:" << keyEvent->GetKeyAction();
244 std::vector<int32_t> pressedKeys = keyEvent->GetPressedKeys();
245 for (const int32_t &key : pressedKeys) {
246 std::optional<KeyEvent::KeyItem> keyItem = keyEvent->GetKeyItem(key);
247 if (!keyItem) {
248 MMI_HILOGE("keyItem is nullopt");
249 return "";
250 }
251 strm << ", KeyCode:" << keyItem->GetKeyCode()
252 << ", DeviceId:" << keyItem->GetDeviceId()
253 << ", Unicode:" << keyItem->GetUnicode();
254 }
255 return strm.str();
256 }
257
CompareDump(const std::shared_ptr<PointerEvent> & pointerEvent)258 bool EventUtilTest::CompareDump(const std::shared_ptr<PointerEvent>& pointerEvent)
259 {
260 CALL_DEBUG_ENTER;
261 std::string before = DumpInputEvent(pointerEvent);
262 MMI_HILOGD("The before:%{private}s", before.c_str());
263 strEventDump_.clear();
264 InputManager::GetInstance()->SimulateInputEvent(pointerEvent);
265 std::string after = GetEventDump();
266 MMI_HILOGD("The after:%{public}s", after.c_str());
267 pointerEvent->AddFlag(InputEvent::EVENT_FLAG_SIMULATE);
268 std::string result = DumpInputEvent(pointerEvent);
269 MMI_HILOGD("result:%{private}s", result.c_str());
270 return result == after;
271 }
272
CompareDump(const std::shared_ptr<KeyEvent> & keyEvent)273 bool EventUtilTest::CompareDump(const std::shared_ptr<KeyEvent>& keyEvent)
274 {
275 CALL_DEBUG_ENTER;
276 std::string before = DumpInputEvent(keyEvent);
277 MMI_HILOGD("The before:%{public}s", before.c_str());
278 strEventDump_.clear();
279 InputManager::GetInstance()->SimulateInputEvent(keyEvent);
280 std::string after = GetEventDump();
281 MMI_HILOGD("The after:%{public}s", after.c_str());
282 keyEvent->AddFlag(InputEvent::EVENT_FLAG_SIMULATE);
283 std::string result = DumpInputEvent(keyEvent);
284 MMI_HILOGD("result:%{public}s", result.c_str());
285 return result == after;
286 }
287
GetNanoTime()288 int64_t GetNanoTime()
289 {
290 struct timespec time = { 0 };
291 clock_gettime(CLOCK_MONOTONIC, &time);
292 return static_cast<int64_t>(time.tv_sec) * SEC_TO_NANOSEC + time.tv_nsec;
293 }
294
DumpWindowData(const std::shared_ptr<PointerEvent> & pointerEvent)295 void DumpWindowData(const std::shared_ptr<PointerEvent>& pointerEvent)
296 {
297 CALL_DEBUG_ENTER;
298 pointerEvent->GetAxes();
299 pointerEvent->GetPressedKeys();
300 pointerEvent->GetPressedButtons();
301 PointerEvent::PointerItem item;
302 item.GetDisplayX();
303 item.GetDisplayY();
304 item.GetTargetWindowId();
305 }
306 } // namespace MMI
307 } // namespace OHOS