1 /*
2 * Copyright (c) 2020-2021 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 "dfx/event_injector.h"
17
18 #if ENABLE_DEBUG
19 #include <climits>
20 #include <gtest/gtest.h>
21 #include <pthread.h>
22 #include <unistd.h>
23
24 #include "common/graphic_startup.h"
25 #include "common/input_device_manager.h"
26 #include "common/screen.h"
27 #include "common/task_manager.h"
28 #include "components/root_view.h"
29 #include "components/ui_label_button.h"
30 #include "components/ui_scroll_view.h"
31 #include "core/render_manager.h"
32 #include "dock/screen_device_proxy.h"
33 #include "font/ui_font.h"
34 #include "gfx_utils/file.h"
35 #include "gfx_utils/graphic_log.h"
36 #include "graphic_config.h"
37 #include "imgdecode/cache_manager.h"
38 #include "layout/grid_layout.h"
39 #include "window/window.h"
40
41 using namespace testing::ext;
42
43 enum TestEventInjectorFlag { FLAG0, FLAG1 };
44
45 namespace {
46 uint8_t REGISTER_POINT_FLAG = FLAG0;
47 uint8_t REGISTER_KEY_FLAG = FLAG0;
48 uint8_t UNREGISTER_POINT_FLAG = FLAG0;
49 uint8_t UNREGISTER_KEY_FLAG = FLAG0;
50 uint8_t CLICK_FLAG = FLAG0;
51 uint8_t LONG_PRESS_FLAG = FLAG0;
52 uint8_t DRAG_FLAG = FLAG0;
53 uint8_t KEY_FLAG = FLAG0;
54 uint8_t MAX_LOOP = 200;
55 } // namespace
56
57 namespace OHOS {
58 class TestEventInjectorView : public UIView, public RootView::OnKeyActListener {
59 public:
OnLongPressEvent(const LongPressEvent & event)60 bool OnLongPressEvent(const LongPressEvent& event) override
61 {
62 LONG_PRESS_FLAG = FLAG1;
63 return true;
64 }
65
OnClickEvent(const ClickEvent & event)66 bool OnClickEvent(const ClickEvent& event) override
67 {
68 CLICK_FLAG = FLAG1;
69 return true;
70 }
71
OnDragEvent(const DragEvent & event)72 bool OnDragEvent(const DragEvent& event) override
73 {
74 DRAG_FLAG = FLAG1;
75 return true;
76 }
77
OnKeyAct(UIView & view,const KeyEvent & event)78 bool OnKeyAct(UIView& view, const KeyEvent& event) override
79 {
80 KEY_FLAG = FLAG1;
81 return true;
82 }
83 };
84
85 class EventInjectorTest : public testing::Test {
86 public:
87 static void SetUpTestCase(void);
88 static void TearDownTestCase(void);
89 static void TestApp();
90 static void SetUpTestview(TestEventInjectorView* testView, bool touchable, bool draggable);
91 static void* MainTask(void* args);
92 static void DeleteChildren(UIView* view);
93
94 static pthread_t mainTaskThread_;
95 static bool isRepeat_;
96 static RootView* rootView_;
97 static GridLayout* layout_;
98 static TestEventInjectorView* clickView_;
99 static TestEventInjectorView* dragView_;
100 static TestEventInjectorView* longPressView_;
101 static TestEventInjectorView* keyView_;
102 static Window* window_;
103 };
104
105 pthread_t EventInjectorTest::mainTaskThread_ = -1;
106 bool EventInjectorTest::isRepeat_ = true;
107 RootView* EventInjectorTest::rootView_ = nullptr;
108 GridLayout* EventInjectorTest::layout_ = nullptr;
109 TestEventInjectorView* EventInjectorTest::clickView_ = nullptr;
110 TestEventInjectorView* EventInjectorTest::dragView_ = nullptr;
111 TestEventInjectorView* EventInjectorTest::longPressView_ = nullptr;
112 TestEventInjectorView* EventInjectorTest::keyView_ = nullptr;
113 Window* EventInjectorTest::window_ = nullptr;
114
SetUpTestCase(void)115 void EventInjectorTest::SetUpTestCase(void)
116 {
117 GraphicStartUp::Init();
118 TestApp();
119 if (pthread_create(&mainTaskThread_, nullptr, MainTask, nullptr) != 0) {
120 return;
121 }
122 }
123
MainTask(void * args)124 void* EventInjectorTest::MainTask(void* args)
125 {
126 while (isRepeat_) {
127 /* Periodically call TaskHandler(). It could be done in a timer interrupt or an OS task too. */
128 OHOS::TaskManager::GetInstance()->TaskHandler();
129 usleep(1000 * 10); /* 1000 * 10:10ms Just to let the system breathe */
130 }
131 return nullptr;
132 }
133
TestApp()134 void EventInjectorTest::TestApp()
135 {
136 WindowConfig config = {};
137 config.rect.SetRect(0, 0, Screen::GetInstance().GetWidth() - 1, Screen::GetInstance().GetHeight() - 1);
138 window_ = Window::CreateWindow(config);
139 if (window_ == nullptr) {
140 GRAPHIC_LOGE("Create window false!");
141 return;
142 }
143 window_->BindRootView(RootView::GetInstance());
144
145 if (EventInjector::GetInstance()->RegisterEventInjector(EventDataType::POINT_TYPE)) {
146 REGISTER_POINT_FLAG = FLAG1;
147 }
148 if (EventInjector::GetInstance()->RegisterEventInjector(EventDataType::KEY_TYPE)) {
149 REGISTER_KEY_FLAG = FLAG1;
150 }
151 EventInjector::GetInstance()->SetWindowId(window_->GetWindowId());
152 rootView_ = RootView::GetInstance();
153 rootView_->SetPosition(0, 0, Screen::GetInstance().GetWidth(), Screen::GetInstance().GetHeight());
154 layout_ = new GridLayout();
155 layout_->SetPosition(0, 0, Screen::GetInstance().GetWidth(), Screen::GetInstance().GetHeight());
156 rootView_->Add(layout_);
157 layout_->SetLayoutDirection(LAYOUT_VER);
158 layout_->SetRows(4); /* 4:rows */
159 layout_->SetCols(1);
160 clickView_ = new TestEventInjectorView();
161 SetUpTestview(clickView_, true, false);
162
163 longPressView_ = new TestEventInjectorView();
164 SetUpTestview(longPressView_, true, false);
165
166 dragView_ = new TestEventInjectorView();
167 SetUpTestview(dragView_, true, true);
168
169 keyView_ = new TestEventInjectorView();
170 RootView::GetInstance()->SetOnKeyActListener(keyView_);
171 SetUpTestview(keyView_, true, false);
172
173 layout_->LayoutChildren();
174 rootView_->Invalidate();
175 }
176
SetUpTestview(TestEventInjectorView * testView,bool touchable,bool draggable)177 void EventInjectorTest::SetUpTestview(TestEventInjectorView* testView, bool touchable, bool draggable)
178 {
179 layout_->Add(testView);
180 testView->Resize(HORIZONTAL_RESOLUTION, VERTICAL_RESOLUTION / 5); /* 5:ratio */
181 testView->SetTouchable(touchable);
182 testView->SetDraggable(draggable);
183 }
184
DeleteChildren(UIView * view)185 void EventInjectorTest::DeleteChildren(UIView* view)
186 {
187 if (view == nullptr) {
188 return;
189 }
190 while (view != nullptr) {
191 UIView* tempView = view;
192 view = view->GetNextSibling();
193 if (tempView->IsViewGroup()) {
194 DeleteChildren(static_cast<UIViewGroup*>(tempView)->GetChildrenHead());
195 }
196 if (tempView->GetParent()) {
197 static_cast<UIViewGroup*>(tempView->GetParent())->Remove(tempView);
198 }
199 delete tempView;
200 }
201 }
202
TearDownTestCase(void)203 void EventInjectorTest::TearDownTestCase(void)
204 {
205 isRepeat_ = false;
206 pthread_join(mainTaskThread_, nullptr);
207 Window::DestroyWindow(window_);
208 DeleteChildren(layout_);
209 layout_ = nullptr;
210
211 EventInjector::GetInstance()->UnregisterEventInjector(EventDataType::POINT_TYPE);
212 EventInjector::GetInstance()->UnregisterEventInjector(EventDataType::KEY_TYPE);
213 RootView::GetInstance()->ClearOnKeyActListener();
214 }
215
216 /**
217 * @tc.name: Graphic_EventInjectorTest_Test_RegisterEventInjector_001
218 * @tc.desc: Verify RegisterEventInjector function, equal.
219 * @tc.type: FUNC
220 * @tc.require: SR000F74SS
221 */
222 HWTEST_F(EventInjectorTest, Graphic_EventInjectorTest_Test_RegisterEventInjector_001, TestSize.Level0)
223 {
224 EXPECT_EQ(REGISTER_POINT_FLAG, FLAG1);
225 EXPECT_EQ(REGISTER_KEY_FLAG, FLAG1);
226 }
227
228 /**
229 * @tc.name: Graphic_EventInjectorTest_Test_SetClickEvent_001
230 * @tc.desc: Verify SetClickEvent function, equal.
231 * @tc.type: FUNC
232 * @tc.require: AR000F74ST
233 */
234 HWTEST_F(EventInjectorTest, Graphic_EventInjectorTest_Test_SetClickEvent_001, TestSize.Level2)
235 {
236 if (clickView_ == nullptr) {
237 ADD_FAILURE();
238 return;
239 }
240 CLICK_FLAG = FLAG0;
241 /* 2:ratio, 2:ratio */
242 Point clickPoint = {static_cast<int16_t>(clickView_->GetRect().GetX() + clickView_->GetWidth() / 2),
243 static_cast<int16_t>(clickView_->GetRect().GetY() + clickView_->GetHeight() / 2)};
244 bool ret = EventInjector::GetInstance()->SetClickEvent(clickPoint);
245 EXPECT_EQ(ret, true);
246 uint8_t loop = 0;
247 while ((loop < MAX_LOOP) && !CLICK_FLAG) {
248 loop++;
249 usleep(10000); /* 10000:10ms */
250 }
251 EXPECT_EQ(CLICK_FLAG, FLAG1);
252 }
253
254 /**
255 * @tc.name: Graphic_EventInjectorTest_Test_SetDragEvent_001
256 * @tc.desc: Verify SetDragEvent function, equal.
257 * @tc.type: FUNC
258 * @tc.require: AR000F74ST
259 */
260 HWTEST_F(EventInjectorTest, Graphic_EventInjectorTest_Test_SetDragEvent_001, TestSize.Level2)
261 {
262 if (dragView_ == nullptr) {
263 ADD_FAILURE();
264 return;
265 }
266 DRAG_FLAG = FLAG0;
267 /* 4:ratio, 2:ratio */
268 Point startPoint = {static_cast<int16_t>(dragView_->GetRect().GetX() + dragView_->GetWidth() / 4),
269 static_cast<int16_t>(dragView_->GetRect().GetY() + dragView_->GetHeight() / 2)};
270 /* 2:ratio, 2:ratio */
271 Point endPoint = {static_cast<int16_t>(dragView_->GetRect().GetX() + dragView_->GetWidth() / 2),
272 static_cast<int16_t>(dragView_->GetRect().GetY() + dragView_->GetHeight() / 2)};
273 bool ret = EventInjector::GetInstance()->SetDragEvent(startPoint, endPoint, 100); /* 100:drag time (ms) */
274 EXPECT_EQ(ret, true);
275 uint8_t loop = 0;
276 while ((loop < MAX_LOOP) && !DRAG_FLAG) {
277 loop++;
278 usleep(10000); /* 10000:10ms */
279 }
280 EXPECT_EQ(DRAG_FLAG, FLAG1);
281 }
282
283 /**
284 * @tc.name: Graphic_EventInjectorTest_Test_SetDragEvent_002
285 * @tc.desc: Verify SetDragEvent function, abnormal branch, SetDragEvent failure(dragTime is too short), equal.
286 * @tc.type: FUNC
287 * @tc.require: AR000F74ST
288 */
289 HWTEST_F(EventInjectorTest, Graphic_EventInjectorTest_Test_SetDragEvent_002, TestSize.Level0)
290 {
291 if (dragView_ == nullptr) {
292 ADD_FAILURE();
293 return;
294 }
295 /* 4:ratio, 2:ratio */
296 Point startPoint = {static_cast<int16_t>(dragView_->GetRect().GetX() + dragView_->GetWidth() / 4),
297 static_cast<int16_t>(dragView_->GetRect().GetY() + dragView_->GetHeight() / 2)};
298 /* 2:ratio, 2:ratio */
299 Point endPoint = {static_cast<int16_t>(dragView_->GetRect().GetX() + dragView_->GetWidth() / 2),
300 static_cast<int16_t>(dragView_->GetRect().GetY() + dragView_->GetHeight() / 2)};
301 bool ret = EventInjector::GetInstance()->SetDragEvent(startPoint, endPoint, INDEV_READ_PERIOD);
302 EXPECT_EQ(ret, false);
303 }
304
305 /**
306 * @tc.name: Graphic_EventInjectorTest_Test_SetDragEvent_003
307 * @tc.desc: Verify SetDragEvent function, abnormal branch, SetDragEvent failure(dragTime is too long), equal.
308 * @tc.type: FUNC
309 * @tc.require: AR000F74ST
310 */
311 HWTEST_F(EventInjectorTest, Graphic_EventInjectorTest_Test_SetDragEvent_003, TestSize.Level0)
312 {
313 if (dragView_ == nullptr) {
314 ADD_FAILURE();
315 return;
316 }
317 /* 4:ratio, 2:ratio */
318 Point startPoint = {static_cast<int16_t>(dragView_->GetRect().GetX() + dragView_->GetWidth() / 4),
319 static_cast<int16_t>(dragView_->GetRect().GetY() + dragView_->GetHeight() / 2)};
320 /* 2:ratio, 2:ratio */
321 Point endPoint = {static_cast<int16_t>(dragView_->GetRect().GetX() + dragView_->GetWidth() / 2),
322 static_cast<int16_t>(dragView_->GetRect().GetY() + dragView_->GetHeight() / 2)};
323 bool ret = EventInjector::GetInstance()->SetDragEvent(startPoint, endPoint, 6000); /* 6000:drag time (ms) */
324 EXPECT_EQ(ret, false);
325 }
326
327 /**
328 * @tc.name: Graphic_EventInjectorTest_Test_SetLongPressEvent_001
329 * @tc.desc: Verify SetLongPressEvent function, equal.
330 * @tc.type: FUNC
331 * @tc.require: AR000F74ST
332 */
333 HWTEST_F(EventInjectorTest, Graphic_EventInjectorTest_Test_SetLongPressEvent_001, TestSize.Level2)
334 {
335 if (longPressView_ == nullptr) {
336 ADD_FAILURE();
337 return;
338 }
339 sleep(2); /* 2:2s */
340 LONG_PRESS_FLAG = FLAG0;
341 /* 2:ratio, 2:ratio */
342 Point longPressPoint = {static_cast<int16_t>(longPressView_->GetRect().GetX() + longPressView_->GetWidth() / 2),
343 static_cast<int16_t>(longPressView_->GetRect().GetY() + longPressView_->GetHeight() / 2)};
344 bool ret = EventInjector::GetInstance()->SetLongPressEvent(longPressPoint);
345 EXPECT_EQ(ret, true);
346 uint8_t loop = 0;
347 while ((loop < MAX_LOOP) && !LONG_PRESS_FLAG) {
348 loop++;
349 usleep(10000); /* 10000:10ms */
350 }
351 EXPECT_EQ(LONG_PRESS_FLAG, FLAG1);
352 }
353
354 /**
355 * @tc.name: Graphic_EventInjectorTest_Test_SetLongPressEvent_002
356 * @tc.desc: Verify SetLongPressEvent function, abnormal branch, SetLongPressEvent failure, equal.
357 * @tc.type: FUNC
358 * @tc.require: AR000F74ST
359 */
360 HWTEST_F(EventInjectorTest, Graphic_EventInjectorTest_Test_SetLongPressEvent_002, TestSize.Level0)
361 {
362 if (longPressView_ == nullptr) {
363 ADD_FAILURE();
364 return;
365 }
366 /* 2:ratio, 2:ratio */
367 Point longPressPoint = {static_cast<int16_t>(longPressView_->GetRect().GetX() + longPressView_->GetWidth() / 2),
368 static_cast<int16_t>(longPressView_->GetRect().GetY() + longPressView_->GetHeight() / 2)};
369 /* 20:loop */
370 for (uint8_t i = 0; i < 20; i++) {
371 EventInjector::GetInstance()->SetLongPressEvent(longPressPoint);
372 }
373 bool ret = EventInjector::GetInstance()->SetLongPressEvent(longPressPoint);
374 EXPECT_EQ(ret, false);
375 }
376
377 /**
378 * @tc.name: Graphic_EventInjectorTest_Test_SetKeyEvent_001
379 * @tc.desc: Verify SetKeyEvent function, equal.
380 * @tc.type: FUNC
381 * @tc.require: AR000F74ST
382 */
383 HWTEST_F(EventInjectorTest, Graphic_EventInjectorTest_Test_SetKeyEvent_001, TestSize.Level2)
384 {
385 /* 26:keyId */
386 uint16_t keyId = 26;
387 EventInjector::GetInstance()->SetKeyEvent(keyId, InputDevice::STATE_PRESS);
388 uint8_t loop = 0;
389 while ((loop < MAX_LOOP) && !KEY_FLAG) {
390 loop++;
391 usleep(10000); /* 10000:10ms */
392 }
393 EXPECT_EQ(KEY_FLAG, FLAG1);
394 }
395
396 /**
397 * @tc.name: Graphic_EventInjectorTest_Test_SetKeyEvent_002
398 * @tc.desc: Verify SetKeyEvent function, abnormal branch, SetKeyEvent failure, equal.
399 * @tc.type: FUNC
400 * @tc.require: AR000F74ST
401 */
402 HWTEST_F(EventInjectorTest, Graphic_EventInjectorTest_Test_SetKeyEvent_002, TestSize.Level0)
403 {
404 /* 26:keyId */
405 uint16_t keyId = 26;
406 /* 200:loop */
407 for (uint8_t i = 0; i < 200; i++) {
408 EventInjector::GetInstance()->SetKeyEvent(keyId, InputDevice::STATE_PRESS);
409 }
410 bool ret = EventInjector::GetInstance()->SetKeyEvent(keyId, InputDevice::STATE_PRESS);
411 EXPECT_EQ(ret, false);
412 }
413
414 /**
415 * @tc.name: Graphic_EventInjectorTest_Test_UnregisterEventInjector_001
416 * @tc.desc: Verify UnregisterEventInjector function, equal.
417 * @tc.type: FUNC
418 * @tc.require: AR000F74ST
419 */
420 HWTEST_F(EventInjectorTest, Graphic_EventInjectorTest_Test_UnregisterEventInjector_001, TestSize.Level0)
421 {
422 isRepeat_ = false;
423 usleep(10000); /* 10000:10ms */
424 EventInjector::GetInstance()->UnregisterEventInjector(EventDataType::POINT_TYPE);
425 if (!EventInjector::GetInstance()->IsEventInjectorRegistered(EventDataType::POINT_TYPE)) {
426 UNREGISTER_POINT_FLAG = FLAG1;
427 }
428 EventInjector::GetInstance()->UnregisterEventInjector(EventDataType::KEY_TYPE);
429 if (!EventInjector::GetInstance()->IsEventInjectorRegistered(EventDataType::KEY_TYPE)) {
430 UNREGISTER_KEY_FLAG = FLAG1;
431 }
432 EXPECT_EQ(UNREGISTER_POINT_FLAG, FLAG1);
433 EXPECT_EQ(UNREGISTER_KEY_FLAG, FLAG1);
434 }
435 } // namespace OHOS
436 #endif // ENABLE_DEBUG
437