• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 "component_manager.h"
17 
18 #include "accessibility_ui_test_ability.h"
19 #include "multimode_manager.h"
20 #include "count_down_latch.h"
21 
22 namespace OHOS {
23 namespace WuKong {
24 namespace {
25 const std::string permissionBundleName = "com.ohos.permissionmanager";
26 const int DIV = 2;
27 const int DOWNTIME = 10;
28 const int ONESECOND = 1000000;
29 const int TWOSECONDS = 2000000;
30 const int OFFSET = 10;
31 }  // namespace
32 
33 class ComponentEventMonitor : public Accessibility::AccessibleAbilityListener {
34 public:
35     virtual ~ComponentEventMonitor() = default;
36 
37     void OnAbilityConnected() override;
38 
39     void OnAbilityDisconnected() override;
40 
41     void OnAccessibilityEvent(const Accessibility::AccessibilityEventInfo& eventInfo) override;
42 
43     void SetOnAbilityConnectCallback(std::function<void()> onConnectCb);
44 
45     void SetOnAbilityDisConnectCallback(std::function<void()> onDisConnectCb);
46 
OnKeyPressEvent(const std::shared_ptr<MMI::KeyEvent> & keyEvent)47     bool OnKeyPressEvent(const std::shared_ptr<MMI::KeyEvent>& keyEvent) override
48     {
49         return false;
50     }
51 
52     uint64_t GetLastEventMillis();
53 
54     bool WaitEventIdle(uint32_t idleThresholdMs, uint32_t timeoutMs);
55 
56 private:
57     std::function<void()> onConnectCallback_ = nullptr;
58     std::function<void()> onDisConnectCallback_ = nullptr;
59     std::atomic<uint64_t> lastEventMillis_ = 0;
60 };
61 
SetOnAbilityConnectCallback(std::function<void ()> onConnectCb)62 void ComponentEventMonitor::SetOnAbilityConnectCallback(std::function<void()> onConnectCb)
63 {
64     onConnectCallback_ = std::move(onConnectCb);
65 }
66 
SetOnAbilityDisConnectCallback(std::function<void ()> onDisConnectCb)67 void ComponentEventMonitor::SetOnAbilityDisConnectCallback(std::function<void()> onDisConnectCb)
68 {
69     onDisConnectCallback_ = std::move(onDisConnectCb);
70 }
71 
OnAbilityConnected()72 void ComponentEventMonitor::OnAbilityConnected()
73 {
74     if (onConnectCallback_ != nullptr) {
75         onConnectCallback_();
76     }
77 }
78 
OnAbilityDisconnected()79 void ComponentEventMonitor::OnAbilityDisconnected()
80 {
81     if (onDisConnectCallback_ != nullptr) {
82         onDisConnectCallback_();
83     }
84 }
85 
OnAccessibilityEvent(const Accessibility::AccessibilityEventInfo & eventInfo)86 void ComponentEventMonitor::OnAccessibilityEvent(const Accessibility::AccessibilityEventInfo& eventInfo)
87 {
88     auto cm = ComponentManager::GetInstance();
89     if (!cm->GetConnectStatus()) {
90         return;
91     }
92     TRACK_LOG_STR("OnAccessibilityEvent Start %u", eventInfo.GetEventType());
93     TRACK_LOG_STR("current bundle: %s", eventInfo.GetBundleName().c_str());
94     if (eventInfo.GetBundleName() == permissionBundleName) {
95         auto listenerlist = ComponentManager::GetInstance()->GetListenerList();
96         for (auto it : listenerlist) {
97             it->OnPermissionScreenShown();
98         }
99     }
100 }
101 
GetLastEventMillis()102 uint64_t ComponentEventMonitor::GetLastEventMillis()
103 {
104     return 0;
105 }
106 
WaitEventIdle(uint32_t idleThresholdMs,uint32_t timeoutMs)107 bool ComponentEventMonitor::WaitEventIdle(uint32_t idleThresholdMs, uint32_t timeoutMs)
108 {
109     return true;
110 }
111 
ComponentManager()112 ComponentManager::ComponentManager()
113 {
114     componentMap_ = {
115         {Accessibility::ACCESSIBILITY_ACTION_CLICK,
116         [this] (Accessibility::AccessibilityElementInfo& elementInfo) -> ErrCode {
117             return ComponentManager::ComponentTouchInput(elementInfo);
118         }},
119         {Accessibility::ACCESSIBILITY_ACTION_SCROLL_FORWARD,
120         [this] (Accessibility::AccessibilityElementInfo& elementInfo) -> ErrCode {
121             return ComponentManager::ComponentUpSwapInput(elementInfo);
122         }},
123         {Accessibility::ACCESSIBILITY_ACTION_SCROLL_BACKWARD,
124         [this] (Accessibility::AccessibilityElementInfo& elementInfo) -> ErrCode {
125             return ComponentManager::ComponentDownSwapInput(elementInfo);
126         }},
127         {Accessibility::ACCESSIBILITY_ACTION_SET_TEXT,
128         [this] (Accessibility::AccessibilityElementInfo& elementInfo) -> ErrCode {
129             return ComponentManager::ComponentMultikeyInput(elementInfo);
130         }},
131         {COMPONENT_LEFT_SWAP,
132         [this] (Accessibility::AccessibilityElementInfo& elementInfo) -> ErrCode {
133             return ComponentManager::ComponentLeftSwapInput(elementInfo);
134         }},
135     };
136 }
~ComponentManager()137 ComponentManager::~ComponentManager()
138 {
139 }
140 
Connect()141 bool ComponentManager::Connect()
142 {
143     if (connected_ == true) {
144         return true;
145     }
146     std::shared_ptr<ComponentEventMonitor> g_monitorInstance_ = std::make_shared<ComponentEventMonitor>();
147     CountDownLatch latch(1);
148     auto onConnectCallback = [&latch]() {
149         std::cout << "Success connect to AAMS" << std::endl;
150         latch.countDown();
151     };
152 
153     g_monitorInstance_->SetOnAbilityConnectCallback(onConnectCallback);
154     auto ability = Accessibility::AccessibilityUITestAbility::GetInstance();
155     if (ability->RegisterAbilityListener(g_monitorInstance_) != Accessibility::RET_OK) {
156         ERROR_LOG("Failed to register ComponentEventMonitor");
157         return false;
158     }
159     INFO_LOG("Start connect to AAMS");
160     if (ability->Connect() != Accessibility::RET_OK) {
161         ERROR_LOG("Failed to connect to AAMS");
162         return false;
163     }
164     const auto timeout = std::chrono::milliseconds(2000);
165     if (!latch.await(timeout)) {
166         Disconnect();
167         ERROR_LOG("Wait connection to AAMS timed out");
168         return false;
169     }
170     connected_ = true;
171     return true;
172 }
Disconnect()173 void ComponentManager::Disconnect()
174 {
175     auto auita = Accessibility::AccessibilityUITestAbility::GetInstance();
176     if (auita != nullptr) {
177         auita->Disconnect();
178     }
179     connected_ = false;
180 }
AddRegisterListener(std::shared_ptr<ComponentManagerListener> listener)181 uint32_t ComponentManager::AddRegisterListener(std::shared_ptr<ComponentManagerListener> listener)
182 {
183     TRACK_LOG_STD();
184     listenerList_.push_back(listener);
185     TRACK_LOG_STR("Add linstener count (%d)", listenerList_.size());
186     return listenerList_.size() - 1;
187 }
188 
DeleteRegisterListener(const uint32_t handle)189 void ComponentManager::DeleteRegisterListener(const uint32_t handle)
190 {
191     if (listenerList_.size() > handle) {
192         listenerList_.erase(listenerList_.begin() + handle);
193     }
194 }
195 
GetListenerList()196 std::vector<std::shared_ptr<ComponentManagerListener>> ComponentManager::GetListenerList()
197 {
198     return listenerList_;
199 }
200 
GetReportInfo(std::string & info)201 ErrCode ComponentManager::GetReportInfo(std::string& info)
202 {
203     ErrCode result = OHOS::ERR_OK;
204     return result;
205 }
206 
PermoissionInput()207 ErrCode ComponentManager::PermoissionInput()
208 {
209     DEBUG_LOG("handle permission window");
210     return OHOS::ERR_OK;
211 }
212 
CreateEventInputMap()213 ErrCode ComponentManager::CreateEventInputMap()
214 {
215     return OHOS::ERR_OK;
216 }
217 
ComponentEventInput(OHOS::Accessibility::AccessibilityElementInfo & elementInfo,const int actionType)218 ErrCode ComponentManager::ComponentEventInput(OHOS::Accessibility::AccessibilityElementInfo& elementInfo,
219                                               const int actionType)
220 {
221     CreateEventInputMap();
222     // get position of current component
223     GetComponentPosition(elementInfo);
224     auto componentRespond = componentMap_[actionType];
225     if (componentRespond == nullptr) {
226         componentRespond = componentMap_[Accessibility::ACCESSIBILITY_ACTION_CLICK];
227     }
228     ErrCode result = componentRespond(elementInfo);
229     return result;
230 }
231 
ComponentTouchInput(Accessibility::AccessibilityElementInfo & elementInfo)232 ErrCode ComponentManager::ComponentTouchInput(Accessibility::AccessibilityElementInfo& elementInfo)
233 {
234     ErrCode result;
235     auto touchInput = MultimodeManager::GetInstance();
236     // Calculate touch position
237     int32_t elementTouchX = startX_ + (endX_ - startX_) / DIV;
238     int32_t elementTouchY = startY_ + (endY_ - startY_) / DIV;
239     std::string type = elementInfo.GetContent();
240     INFO_LOG_STR("component Content: Touch Position: (%d, %d)", elementTouchX, elementTouchY);
241     DEBUG_LOG_STR("component Content: (%s), Touch Position: (%d, %d)", type.c_str(), elementTouchX, elementTouchY);
242     result = touchInput->PointerInput(elementTouchX, elementTouchY, MMI::PointerEvent::SOURCE_TYPE_TOUCHSCREEN,
243                                       MMI::PointerEvent::POINTER_ACTION_DOWN);
244     if (result == OHOS::ERR_OK) {
245         result = touchInput->PointerInput(elementTouchX, elementTouchY, MMI::PointerEvent::SOURCE_TYPE_TOUCHSCREEN,
246                                           MMI::PointerEvent::POINTER_ACTION_UP);
247     }
248     return result;
249 }
250 
BackToPrePage()251 ErrCode ComponentManager::BackToPrePage()
252 {
253     ErrCode result = ERR_OK;
254     int backKeyCode = OHOS::MMI::KeyEvent::KEYCODE_BACK;
255     result = MultimodeManager::GetInstance()->SingleKeyCodeInput(backKeyCode, DOWNTIME);
256     return result;
257 }
258 
BackToHome()259 ErrCode ComponentManager::BackToHome()
260 {
261     ErrCode result = ERR_OK;
262     int backKeyCode = OHOS::MMI::KeyEvent::KEYCODE_HOME;
263     result = MultimodeManager::GetInstance()->SingleKeyCodeInput(backKeyCode, DOWNTIME);
264     return result;
265 }
266 
ComponentUpSwapInput(Accessibility::AccessibilityElementInfo & elementInfo)267 ErrCode ComponentManager::ComponentUpSwapInput(Accessibility::AccessibilityElementInfo& elementInfo)
268 {
269     // Calculate swap position
270     int32_t componentUpSwapStartX = startX_ + (endX_ - startX_) / DIV;
271     int32_t componentUpSwapStartY = endY_ - OFFSET;
272     int32_t componentUpSwapEndX = componentUpSwapStartX;
273     int32_t componentUpSwapEndY = startY_ + OFFSET;
274     INFO_LOG_STR("Component Up Swap: (%d, %d) -> (%d, %d)", componentUpSwapStartX, componentUpSwapStartY,
275                  componentUpSwapEndX, componentUpSwapEndY);
276     ErrCode result = MultimodeManager::GetInstance()->IntervalSwap(componentUpSwapStartX, componentUpSwapStartY,
277                                                                    componentUpSwapEndX, componentUpSwapEndY);
278     usleep(TWOSECONDS);
279     return result;
280 }
281 
ComponentDownSwapInput(Accessibility::AccessibilityElementInfo & elementInfo)282 ErrCode ComponentManager::ComponentDownSwapInput(Accessibility::AccessibilityElementInfo& elementInfo)
283 {
284     // Calculate swap position
285     int32_t componentDownSwapStartX = startX_ + (endX_ - startX_) / DIV;
286     int32_t componentDownSwapStartY = startY_ + OFFSET;
287     int32_t componentDownSwapEndX = componentDownSwapStartX;
288     int32_t componentDownSwapEndY = endY_ - OFFSET;
289     INFO_LOG_STR("Component Down Swap: (%d, %d) -> (%d, %d)", componentDownSwapStartX, componentDownSwapStartY,
290                  componentDownSwapEndX, componentDownSwapEndY);
291     ErrCode result = MultimodeManager::GetInstance()->IntervalSwap(componentDownSwapStartX, componentDownSwapStartY,
292                                                                    componentDownSwapEndX, componentDownSwapEndY);
293     usleep(TWOSECONDS);
294     return result;
295 }
296 
ComponentMultikeyInput(Accessibility::AccessibilityElementInfo & elementInfo)297 ErrCode ComponentManager::ComponentMultikeyInput(Accessibility::AccessibilityElementInfo& elementInfo)
298 {
299     ErrCode result = ComponentTouchInput(elementInfo);
300     if (result != OHOS::ERR_OK) {
301         return result;
302     }
303     usleep(ONESECOND);
304     result = MultimodeManager::GetInstance()->MultiKeyCodeInput(DOWNTIME);
305     return result;
306 }
307 
ComponentLeftSwapInput(Accessibility::AccessibilityElementInfo & elementInfo)308 ErrCode ComponentManager::ComponentLeftSwapInput(Accessibility::AccessibilityElementInfo& elementInfo)
309 {
310     ErrCode result;
311     // Calculate swap position
312     int32_t leftSwapStartX = startX_ + OFFSET;
313     int32_t leftSwapEndX = endX_ + OFFSET;
314     int32_t leftSwapStartY = startY_ + (endY_ - startY_) / DIV;
315     int32_t leftSwapEndY = leftSwapStartY;
316     INFO_LOG_STR("Component Left Swap: (%d, %d) -> (%d, %d)", leftSwapStartX, leftSwapStartY, leftSwapEndX,
317                  leftSwapEndY);
318     result = MultimodeManager::GetInstance()->IntervalSwap(leftSwapStartX, leftSwapStartY, leftSwapEndX, leftSwapEndY);
319     return result;
320 }
321 
GetComponentPosition(Accessibility::AccessibilityElementInfo & elementInfo)322 void ComponentManager::GetComponentPosition(Accessibility::AccessibilityElementInfo& elementInfo)
323 {
324     Accessibility::Rect componentBounds = elementInfo.GetRectInScreen();
325     startX_ = componentBounds.GetLeftTopXScreenPostion();
326     startY_ = componentBounds.GetLeftTopYScreenPostion();
327     endX_ = componentBounds.GetRightBottomXScreenPostion();
328     endY_ = componentBounds.GetRightBottomYScreenPostion();
329 }
330 }  // namespace WuKong
331 }  // namespace OHOS
332