• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1  /*
2   * Copyright (c) 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  #include "basic_tdd_test.h"
16  #include <cstring>
17  #include <sys/prctl.h>
18  #include "async_task_manager.h"
19  #include "common/graphic_startup.h"
20  #include "common/task_manager.h"
21  #include "component_utils.h"
22  #include "core/render_manager.h"
23  #include "descriptor_utils.h"
24  #include "dock/screen_device_proxy.h"
25  #include "event_injector.h"
26  #include "js_app_context.h"
27  #include "js_app_environment.h"
28  #include "module_manager.h"
29  #include "root_view.h"
30  
31  namespace OHOS {
32  namespace ACELite {
BasicTddTest()33  BasicTddTest::BasicTddTest() : rootComponent_(nullptr) {}
~BasicTddTest()34  BasicTddTest::~BasicTddTest() {}
35  
36  ScreenDevice *BasicTddTest::display_ = nullptr;
37  Window *BasicTddTest::window_ = nullptr;
38  pthread_t BasicTddTest::tickThread_ = -1;
39  bool BasicTddTest::isTickTaskRunning_ = false;
40  
41  // 10ms a tick
42  constexpr uint16_t TICK = 10000;
43  constexpr uint32_t SWIPE_TIME = 100;
44  
45  constexpr uint8_t NUMBER_TWO = 2;
46  
SetUpTestCase(void)47  void BasicTddTest::SetUpTestCase(void)
48  {
49      GraphicStartUp::Init();
50      isTickTaskRunning_ = true;
51  
52      display_ = new ScreenDevice();
53      ScreenDeviceProxy::GetInstance()->SetDevice(display_);
54      ScreenDeviceProxy::GetInstance()->SetScreenSize(HORIZONTAL_RESOLUTION, VERTICAL_RESOLUTION);
55  
56      WindowConfig config = {};
57      uint16_t width = GetHorizontalResolution();
58      uint16_t height = GetVerticalResolution();
59      config.rect.SetRect(0, 0, width - 1, height - 1);
60      window_ = Window::CreateWindow(config);
61      RootView *rootView = RootView::GetInstance();
62      rootView->SetPosition(0, 0);
63      rootView->SetWidth(width);
64      rootView->SetHeight(height);
65      window_->BindRootView(rootView);
66      TaskManager::GetInstance()->Remove(&RenderManager::GetInstance());
67      if (pthread_create(&tickThread_, nullptr, TickHandler, nullptr) == 0) {
68          pthread_detach(tickThread_);
69          HILOG_DEBUG(HILOG_MODULE_ACE, "[BasicTddTest::SetUpTestCase]: Success to fork tick thread.");
70      } else {
71          HILOG_ERROR(HILOG_MODULE_ACE, "[BasicTddTest::SetUpTestCase]: Failed to fork tick thread.");
72      }
73  }
74  
TearDownTestCase(void)75  void BasicTddTest::TearDownTestCase(void)
76  {
77      isTickTaskRunning_ = false;
78      if (window_ != nullptr) {
79          Window::DestroyWindow(window_);
80          window_ = nullptr;
81      }
82      if (display_ != nullptr) {
83          delete display_;
84          display_ = nullptr;
85      }
86  }
87  
SetUp()88  void BasicTddTest::SetUp()
89  {
90      JsAppContext *appContext = JsAppContext::GetInstance();
91      const int32_t apiVersion = 6;
92      appContext->SetCompatibleApi(apiVersion);
93      appContext->SetTargetApi(apiVersion);
94      JsAppEnvironment::GetInstance()->InitJsFramework();
95      EventInjector *injector = EventInjector::GetInstance();
96      if (!injector->IsEventInjectorRegistered(EventDataType::POINT_TYPE)) {
97          injector->RegisterEventInjector(EventDataType::POINT_TYPE);
98      }
99      injector->SetWindowId(window_->GetWindowId());
100      AsyncTaskManager::GetInstance().SetFront(true);
101  }
102  
TearDown()103  void BasicTddTest::TearDown()
104  {
105      ModuleManager::GetInstance()->CleanUpModule();
106      JsAppEnvironment::GetInstance()->Cleanup();
107  
108      EventInjector *injector = EventInjector::GetInstance();
109      if (injector->IsEventInjectorRegistered(EventDataType::POINT_TYPE)) {
110          injector->UnregisterEventInjector(EventDataType::POINT_TYPE);
111      }
112      AsyncTaskManager::GetInstance().SetFront(false);
113  }
114  
RunJS(const char * bundle,const uint32_t size) const115  JSValue BasicTddTest::RunJS(const char *bundle, const uint32_t size) const
116  {
117      return jerry_eval(reinterpret_cast<const jerry_char_t *>(bundle), size, JERRY_PARSE_NO_OPTS);
118  }
119  
CreatePage(const char * bundle,const uint32_t size)120  JSValue BasicTddTest::CreatePage(const char *bundle, const uint32_t size)
121  {
122      JSValue page = RunJS(bundle, size);
123      if (JSError::Is(page)) {
124          return JSUndefined::Create();
125      }
126      JSGlobal::Set("$root", page);
127      CallLifecycle(page, "onInit");
128      JSValue rootEl = JSObject::Call(page, "$render");
129      if (JSUndefined::Is(rootEl) || JSError::Is(rootEl)) {
130          HILOG_ERROR(HILOG_MODULE_ACE, "[BasicTddTest::CreatePage]: Failed to render page.");
131          JSRelease(rootEl);
132          JSRelease(page);
133          return JSUndefined::Create();
134      }
135      CallLifecycle(page, "onReady");
136      rootComponent_ = ComponentUtils::GetComponentFromBindingObject(rootEl);
137      if (rootComponent_ == nullptr) {
138          HILOG_ERROR(HILOG_MODULE_ACE, "[BasicTddTest::CreatePage]: Failed to get root component.");
139          JSRelease(rootEl);
140          JSRelease(page);
141          return JSUndefined::Create();
142      }
143      uint16_t horizontalResolution = GetHorizontalResolution();
144      uint16_t verticalResolution = GetVerticalResolution();
145      ConstrainedParameter rootViewParam(horizontalResolution, verticalResolution);
146      Component::BuildViewTree(rootComponent_, nullptr, rootViewParam);
147      rootComponent_->OnViewAttached();
148      UIView *view = rootComponent_->GetComponentRootView();
149      if (view == nullptr) {
150          HILOG_ERROR(HILOG_MODULE_ACE, "[BasicTddTest::CreatePage]: Failed to get page root view.");
151          JSRelease(rootEl);
152          JSRelease(page);
153          return JSUndefined::Create();
154      }
155      RootView *rootView = RootView::GetInstance();
156      rootView->Add(view);
157      rootView->Invalidate();
158      CallLifecycle(page, "onShow");
159      return page;
160  }
161  
DestroyPage(JSValue page)162  void BasicTddTest::DestroyPage(JSValue page)
163  {
164      RootView *rootView = RootView::GetInstance();
165      rootView->RemoveAll();
166      rootView->Invalidate();
167      CallLifecycle(page, "onHide");
168      CallLifecycle(page, "onDestroy");
169      ComponentUtils::ReleaseComponents(rootComponent_);
170      rootComponent_ = nullptr;
171      JsAppContext::GetInstance()->ReleaseStyles();
172      JSGlobal::Del("$root");
173      JSRelease(page);
174  }
175  
GetViewByRef(JSValue page,const char * ref) const176  UIView *BasicTddTest::GetViewByRef(JSValue page, const char *ref) const
177  {
178      JSValue refs = JSObject::Get(page, "$refs");
179      if (JSUndefined::Is(refs)) {
180          JSRelease(refs);
181          return nullptr;
182      }
183      JSValue dom = JSObject::Get(refs, ref);
184      if (JSUndefined::Is(dom)) {
185          JSRelease(refs);
186          JSRelease(dom);
187          return nullptr;
188      }
189      UIView *view = ComponentUtils::GetViewFromBindingObject(dom);
190      JSRelease(refs);
191      JSRelease(dom);
192      return view;
193  }
194  
ClickByRef(JSValue page,const char * ref,uint8_t sleepTicks) const195  void BasicTddTest::ClickByRef(JSValue page, const char *ref, uint8_t sleepTicks) const
196  {
197      return Click(GetViewByRef(page, ref), sleepTicks);
198  }
199  
LongPressByRef(JSValue page,const char * ref,uint8_t sleepTicks) const200  void BasicTddTest::LongPressByRef(JSValue page, const char *ref, uint8_t sleepTicks) const
201  {
202      return LongPress(GetViewByRef(page, ref), sleepTicks);
203  }
204  
Click(const UIView * view,uint8_t sleepTicks) const205  void BasicTddTest::Click(const UIView *view, uint8_t sleepTicks) const
206  {
207      if (view == nullptr) {
208          HILOG_ERROR(HILOG_MODULE_ACE, "[BasicTddTest::Click]: Failed to click because view is nullptr");
209          return;
210      }
211      Rect rect = view->GetOrigRect();
212      int16_t x = rect.GetLeft() + rect.GetWidth() / NUMBER_TWO;
213      int16_t y = rect.GetTop() + rect.GetHeight() / NUMBER_TWO;
214      return Click(x, y, sleepTicks);
215  }
216  
LongPress(const UIView * view,uint8_t sleepTicks) const217  void BasicTddTest::LongPress(const UIView *view, uint8_t sleepTicks) const
218  {
219      if (view == nullptr) {
220          HILOG_ERROR(HILOG_MODULE_ACE, "[BasicTddTest::LongPress]: Failed to long press because view is nullptr");
221          return;
222      }
223      Rect rect = view->GetOrigRect();
224      int16_t x = rect.GetLeft() + rect.GetWidth() / NUMBER_TWO;
225      int16_t y = rect.GetTop() + rect.GetHeight() / NUMBER_TWO;
226      return LongPress(x, y, sleepTicks);
227  }
228  
Click(int16_t x,int16_t y,uint8_t sleepTicks) const229  void BasicTddTest::Click(int16_t x, int16_t y, uint8_t sleepTicks) const
230  {
231      Point point = {x, y};
232      EventInjector *injector = EventInjector::GetInstance();
233      if (injector->SetClickEvent(point)) {
234          HILOG_DEBUG(HILOG_MODULE_ACE,
235                      "[BasicTddTest::Click]: Success to inject CLICK event on (%{public}d, %{public}d)\n", x, y);
236      } else {
237          HILOG_ERROR(HILOG_MODULE_ACE,
238                      "[BasicTddTest::Click]: Failed to inject CLICK event on (%{public}d, %{public}d)\n", x, y);
239      }
240      // Waiting for tick breath.
241      usleep(sleepTicks * TICK);
242  }
243  
LongPress(int16_t x,int16_t y,uint8_t sleepTicks) const244  void BasicTddTest::LongPress(int16_t x, int16_t y, uint8_t sleepTicks) const
245  {
246      Point point = {x, y};
247      EventInjector *injector = EventInjector::GetInstance();
248      if (injector->SetLongPressEvent(point)) {
249          HILOG_DEBUG(HILOG_MODULE_ACE,
250                      "[BasicTddTest::LongPress]: Success to inject LONGPRESS event on (%{public}d, %{public}d)\n", x, y);
251      } else {
252          HILOG_ERROR(HILOG_MODULE_ACE,
253                      "[BasicTddTest::LongPress]: Failed to inject LONGPRESS event on (%{public}d, %{public}d)\n", x, y);
254      }
255      // Waiting for tick breath.
256      usleep(sleepTicks * TICK);
257  }
258  
Swipe(int16_t startX,int16_t startY,int16_t endX,int16_t endY,uint8_t sleepTicks) const259  void BasicTddTest::Swipe(int16_t startX, int16_t startY, int16_t endX, int16_t endY, uint8_t sleepTicks) const
260  {
261      Point startPoint = {startX, startY};
262      Point endPoint = {endX, endY};
263      EventInjector *injector = EventInjector::GetInstance();
264      if (injector->SetDragEvent(startPoint, endPoint, SWIPE_TIME)) {
265          HILOG_DEBUG(HILOG_MODULE_ACE,
266                      "[BasicTddTest::Swipe]: Success to inject SWIPE event from (%{public}d, %{public}d) to "
267                      "(%{public}d, %{public}d)\n",
268                      startX, startY, endX, endY);
269      } else {
270          HILOG_ERROR(
271              HILOG_MODULE_ACE,
272              "[BasicTddTest::Swipe]: Failed to inject SWIPE from (%{public}d, %{public}d) to (%{public}d, %{public}d)\n",
273              startX, startY, endX, endY);
274      }
275  
276      // Waiting for tick breath.
277      usleep(sleepTicks * TICK);
278  }
279  
GetChildrenSize(const UIViewGroup & grop) const280  uint8_t BasicTddTest::GetChildrenSize(const UIViewGroup &grop) const
281  {
282      UIView *child = grop.GetChildrenHead();
283      uint8_t size = 0;
284      while (child != nullptr) {
285          ++size;
286          child = child->GetNextSibling();
287      }
288      return size;
289  }
290  
TickHandler(void * args)291  void *BasicTddTest::TickHandler(void *args)
292  {
293      (void)args;
294      prctl(PR_SET_NAME, "TickTask");
295      while (isTickTaskRunning_) {
296          // Periodically call TaskHandler(). It could be done in a timer interrupt or an OS task too.
297          TaskManager::GetInstance()->TaskHandler();
298          // Just to let the system breathe
299          usleep(TICK);
300      }
301      return nullptr;
302  }
303  
CallLifecycle(JSValue page,const char * lifecycle) const304  void BasicTddTest::CallLifecycle(JSValue page, const char *lifecycle) const
305  {
306      JSValue func = JSObject::Get(page, lifecycle);
307      if (JSFunction::Is(func)) {
308          JSRelease(JSFunction::Call(func, page, nullptr, 0));
309      }
310      JSRelease(func);
311  }
312  } // namespace ACELite
313  } // namespace OHOS
314