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 25namespace OHOS { 26namespace MMI { 27namespace { 28constexpr int32_t TIME_WAIT_FOR_EVENT { 1000 }; 29constexpr int32_t SEC_TO_NANOSEC { 1000000000 }; 30} // namespace 31 32void 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 43void 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 60void 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 71void 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 81void 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 ASSERT_TRUE(pointerEvent != nullptr); 87 TestUtil->AddEventDump("Call middle interceptor"); 88 } 89} 90 91void PriorityMiddleCallback::OnInputEvent(std::shared_ptr<KeyEvent> keyEvent) const 92{ 93 CALL_DEBUG_ENTER; 94 if (TestUtil->GetRecvFlag() != RECV_FLAG::RECV_MARK_CONSUMED) { 95 TestUtil->SetRecvFlag(RECV_FLAG::RECV_INTERCEPT); 96 ASSERT_TRUE(keyEvent != nullptr); 97 TestUtil->AddEventDump("Call middle interceptor"); 98 } 99} 100 101void PriorityHighCallback::OnInputEvent(std::shared_ptr<PointerEvent> pointerEvent) const 102{ 103 CALL_DEBUG_ENTER; 104 if (TestUtil->GetRecvFlag() != RECV_FLAG::RECV_MARK_CONSUMED) { 105 TestUtil->SetRecvFlag(RECV_FLAG::RECV_INTERCEPT); 106 ASSERT_TRUE(pointerEvent != nullptr); 107 TestUtil->AddEventDump("Call high interceptor"); 108 } 109} 110 111void PriorityHighCallback::OnInputEvent(std::shared_ptr<KeyEvent> keyEvent) const 112{ 113 CALL_DEBUG_ENTER; 114 if (TestUtil->GetRecvFlag() != RECV_FLAG::RECV_MARK_CONSUMED) { 115 TestUtil->SetRecvFlag(RECV_FLAG::RECV_INTERCEPT); 116 ASSERT_TRUE(keyEvent != nullptr); 117 TestUtil->AddEventDump("Call high interceptor"); 118 } 119} 120 121void WindowEventConsumer::OnInputEvent(std::shared_ptr<KeyEvent> keyEvent) const 122{ 123 threadId_ = GetThisThreadId(); 124 MMI_HILOGD("Consumer callback keyEvent is threadId:%{public}" PRIu64, threadId_); 125} 126 127void WindowEventConsumer::OnInputEvent(std::shared_ptr<PointerEvent> pointerEvent) const 128{ 129 threadId_ = GetThisThreadId(); 130 MMI_HILOGD("Consumer callback pointerEvent is threadId:%{public}" PRIu64, threadId_); 131} 132 133uint64_t WindowEventConsumer::GetConsumerThreadId() 134{ 135 return threadId_; 136} 137 138EventUtilTest::EventUtilTest() {} 139EventUtilTest::~EventUtilTest() {} 140 141void EventUtilTest::AddEventDump(std::string eventDump) 142{ 143 CALL_DEBUG_ENTER; 144 std::lock_guard<std::mutex> lockGuard(mutex_); 145 if (eventDump.empty()) { 146 strEventDump_.clear(); 147 return; 148 } 149 strEventDump_.push_back(eventDump); 150 MMI_HILOGD("Setting the Dump event, strEventDump_:%{public}s", eventDump.c_str()); 151 conditionVariable_.notify_one(); 152} 153 154std::string EventUtilTest::GetEventDump() 155{ 156 CALL_DEBUG_ENTER; 157 std::unique_lock<std::mutex> uniqueLock(mutex_); 158 std::string str = ""; 159 if (strEventDump_.empty()) { 160 MMI_HILOGD("Waiting for an event to fire"); 161 if (conditionVariable_.wait_for(uniqueLock, 162 std::chrono::milliseconds(TIME_WAIT_FOR_EVENT)) == std::cv_status::timeout) { 163 MMI_HILOGD("Timeout"); 164 return str; 165 } 166 } 167 str = strEventDump_.front(); 168 strEventDump_.pop_front(); 169 return str; 170} 171 172bool EventUtilTest::Init() 173{ 174 CALL_DEBUG_ENTER; 175 if (!WindowUtilsTest::GetInstance()->DrawTestWindow()) { 176 return false; 177 } 178 sptr<Rosen::Window> window_ = WindowUtilsTest::GetInstance()->GetWindow(); 179 CHKPF(window_); 180 auto listener_ = GetPtr<InputEventConsumer>(); 181 CHKPF(listener_); 182 const std::string threadTest = "EventUtilTest"; 183 auto runner = AppExecFwk::EventRunner::Create(threadTest); 184 CHKPF(runner); 185 auto eventHandler = std::make_shared<AppExecFwk::EventHandler>(runner); 186 MMI::InputManager::GetInstance()->SetWindowInputEventConsumer(listener_, eventHandler); 187 return true; 188} 189 190std::string EventUtilTest::DumpInputEvent(const std::shared_ptr<PointerEvent>& pointerEvent) 191{ 192 const int precision = 2; 193 std::ostringstream ostream; 194 std::vector<int32_t> pointerIds { pointerEvent->GetPointerIds() }; 195 std::string str; 196 std::vector<uint8_t> buffer = pointerEvent->GetBuffer(); 197 for (const auto& buff : buffer) { 198 str += std::to_string(buff); 199 } 200 ostream << "ClientMsgHandler: in OnPointerEvent" 201 << ",EventType:" << pointerEvent->GetEventType() 202 << ",ActionTime:" << pointerEvent->GetActionTime() 203 << ",Action:" << pointerEvent->GetAction() 204 << ",ActionStartTime:" << pointerEvent->GetActionStartTime() 205 << ",Flag:" << pointerEvent->GetFlag() 206 << ",PointerAction:" << pointerEvent->DumpPointerAction() 207 << ",SourceType:" << pointerEvent->DumpSourceType() 208 << ",ButtonId:" << pointerEvent->GetButtonId() 209 << ",DeviceId:" << pointerEvent->GetDeviceId() 210 << ",VerticalAxisValue:" << std::fixed << std::setprecision(precision) 211 << pointerEvent->GetAxisValue(PointerEvent::AXIS_TYPE_SCROLL_VERTICAL) 212 << ",HorizontalAxisValue:" << std::fixed << std::setprecision(precision) 213 << pointerEvent->GetAxisValue(PointerEvent::AXIS_TYPE_SCROLL_HORIZONTAL) 214 <<",BufferCount:" << buffer.size() 215 <<",Buffer:" << str.c_str(); 216 for (const auto &pointerId : pointerIds) { 217 PointerEvent::PointerItem item; 218 if (!pointerEvent->GetPointerItem(pointerId, item)) { 219 MMI_HILOGE("Invalid pointer:%{public}d.", pointerId); 220 return ostream.str(); 221 } 222 ostream << ",pointerId:" << pointerId << ",DownTime:" << item.GetDownTime() 223 << ",IsPressed:" << std::boolalpha << item.IsPressed() 224 << ",DisplayX:" << item.GetDisplayX() << ",DisplayY:" << item.GetDisplayY() 225 << ",Width:" << item.GetWidth() << ",Height:" << item.GetHeight() 226 << ",TiltX:" << std::fixed << std::setprecision(precision) << item.GetTiltX() 227 << ",TiltY:" << std::fixed << std::setprecision(precision) << item.GetTiltY() 228 << ",ToolDisplayX:" << item.GetToolDisplayX() << ",ToolDisplayY:" << item.GetToolDisplayY() 229 << ",ToolWindowX:" << item.GetToolWindowX() << ",ToolWindowY:" << item.GetToolWindowY() 230 << ",ToolWidth:" << item.GetToolWidth() << ",ToolHeight:" << item.GetToolHeight() 231 << ",Pressure:" << item.GetPressure() << ",ToolType:" << item.GetToolType() 232 << ",LongAxis:" << item.GetLongAxis() << ",ShortAxis:" << item.GetShortAxis() 233 << ",DeviceId:" << item.GetDeviceId() << ",RawDx:" << item.GetRawDx() 234 << ",RawDy:" << item.GetRawDy(); 235 } 236 237 return ostream.str(); 238} 239 240std::string EventUtilTest::DumpInputEvent(const std::shared_ptr<KeyEvent>& keyEvent) 241{ 242 std::ostringstream strm; 243 strm << "InputManagerTest: in OnKeyEvent" 244 << ", KeyCode:" << keyEvent->GetKeyCode() 245 << ", ActionTime:" << keyEvent->GetActionTime() 246 << ", Action:" << keyEvent->GetAction() 247 << ", ActionStartTime:" << keyEvent->GetActionStartTime() 248 << ", EventType:" << keyEvent->GetEventType() 249 << ", KeyAction:" << keyEvent->GetKeyAction(); 250 std::vector<int32_t> pressedKeys = keyEvent->GetPressedKeys(); 251 for (const int32_t &key : pressedKeys) { 252 std::optional<KeyEvent::KeyItem> keyItem = keyEvent->GetKeyItem(key); 253 if (!keyItem) { 254 MMI_HILOGE("keyItem is nullopt"); 255 return ""; 256 } 257 strm << ", KeyCode:" << keyItem->GetKeyCode() 258 << ", DeviceId:" << keyItem->GetDeviceId() 259 << ", Unicode:" << keyItem->GetUnicode(); 260 } 261 return strm.str(); 262} 263 264bool EventUtilTest::CompareDump(const std::shared_ptr<PointerEvent>& pointerEvent) 265{ 266 CALL_DEBUG_ENTER; 267 std::string before = DumpInputEvent(pointerEvent); 268 MMI_HILOGD("before:%{public}s", before.c_str()); 269 strEventDump_.clear(); 270 InputManager::GetInstance()->SimulateInputEvent(pointerEvent); 271 std::string after = GetEventDump(); 272 MMI_HILOGD("after:%{public}s", after.c_str()); 273 pointerEvent->AddFlag(InputEvent::EVENT_FLAG_SIMULATE); 274 std::string result = DumpInputEvent(pointerEvent); 275 MMI_HILOGD("result:%{public}s", result.c_str()); 276 return result == after; 277} 278 279bool EventUtilTest::CompareDump(const std::shared_ptr<KeyEvent>& keyEvent) 280{ 281 CALL_DEBUG_ENTER; 282 std::string before = DumpInputEvent(keyEvent); 283 MMI_HILOGD("before:%{public}s", before.c_str()); 284 strEventDump_.clear(); 285 InputManager::GetInstance()->SimulateInputEvent(keyEvent); 286 std::string after = GetEventDump(); 287 MMI_HILOGD("after:%{public}s", after.c_str()); 288 keyEvent->AddFlag(InputEvent::EVENT_FLAG_SIMULATE); 289 std::string result = DumpInputEvent(keyEvent); 290 MMI_HILOGD("result:%{public}s", result.c_str()); 291 return result == after; 292} 293 294int64_t GetNanoTime() 295{ 296 struct timespec time = { 0 }; 297 clock_gettime(CLOCK_MONOTONIC, &time); 298 return static_cast<int64_t>(time.tv_sec) * SEC_TO_NANOSEC + time.tv_nsec; 299} 300 301void DumpWindowData(const std::shared_ptr<PointerEvent>& pointerEvent) 302{ 303 CALL_DEBUG_ENTER; 304 pointerEvent->GetAxes(); 305 pointerEvent->GetPressedKeys(); 306 pointerEvent->GetPressedButtons(); 307 PointerEvent::PointerItem item; 308 item.GetDisplayX(); 309 item.GetDisplayY(); 310 item.GetTargetWindowId(); 311} 312} // namespace MMI 313} // namespace OHOS