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