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 "accessible_ability_channel.h"
17 #include "accessible_ability_manager_service.h"
18 #include "accessibility_window_connection.h"
19 #include "accessibility_window_manager.h"
20 #include "accessible_ability_connection.h"
21 #include "hilog_wrapper.h"
22 #include "transaction/rs_interfaces.h"
23 
24 namespace OHOS {
25 namespace Accessibility {
26 namespace {
27     constexpr uint32_t TIME_OUT_OPERATOR = 5000;
28     constexpr int32_t WINDOW_ID_INVALID = -1;
29     constexpr int64_t ELEMENT_ID_INVALID = -1;
30     MMI::InputManager* inputManager_ = MMI::InputManager::GetInstance();
31     std::map<int32_t, std::pair<bool, std::pair<int32_t, int32_t>>> accessibleKeyCodeTable = {
32         {ActionType::ACCESSIBILITY_ACTION_HOME,
33             {false, {MMI::KeyEvent::KEYCODE_META_LEFT, MMI::KeyEvent::KEYCODE_D}}},
34         {ActionType::ACCESSIBILITY_ACTION_RECENTTASK,
35             {false, {MMI::KeyEvent::KEYCODE_META_LEFT, MMI::KeyEvent::KEYCODE_TAB}}},
36         {ActionType::ACCESSIBILITY_ACTION_BACK,
37             {true, {MMI::KeyEvent::KEYCODE_BACK, MMI::KeyEvent::KEYCODE_BACK}}},
38         {ActionType::ACCESSIBILITY_ACTION_NOTIFICATIONCENTER,
39             {true, {MMI::KeyEvent::KEYCODE_CALL_NOTIFICATION_CENTER, MMI::KeyEvent::KEYCODE_CALL_NOTIFICATION_CENTER}}},
40         {ActionType::ACCESSIBILITY_ACTION_CONTROLCENTER,
41             {true, {MMI::KeyEvent::KEYCODE_CALL_CONTROL_CENTER, MMI::KeyEvent::KEYCODE_CALL_CONTROL_CENTER}}}};
42 } // namespace
43 
AccessibleAbilityChannel(const int32_t accountId,const std::string & clientName)44 AccessibleAbilityChannel::AccessibleAbilityChannel(const int32_t accountId, const std::string &clientName)
45     : clientName_(clientName), accountId_(accountId)
46 {
47     eventHandler_ = std::make_shared<AppExecFwk::EventHandler>(
48         Singleton<AccessibleAbilityManagerService>::GetInstance().GetMainRunner());
49 }
50 
SearchElementInfoByAccessibilityId(const ElementBasicInfo elementBasicInfo,const int32_t requestId,const sptr<IAccessibilityElementOperatorCallback> & callback,const int32_t mode,bool isFilter)51 RetError AccessibleAbilityChannel::SearchElementInfoByAccessibilityId(const ElementBasicInfo elementBasicInfo,
52     const int32_t requestId, const sptr<IAccessibilityElementOperatorCallback> &callback,
53     const int32_t mode, bool isFilter)
54 {
55     int32_t treeId = elementBasicInfo.treeId;
56     int32_t windowId = elementBasicInfo.windowId;
57     int64_t elementId = elementBasicInfo.elementId;
58     HILOG_DEBUG("elementId:%{public}" PRId64 " winId: %{public}d treeId: %{public}d", elementId, windowId, treeId);
59     Singleton<AccessibleAbilityManagerService>::GetInstance().PostDelayUnloadTask();
60 
61     if (eventHandler_ == nullptr || callback == nullptr) {
62         HILOG_ERROR("eventHandler_ exist: %{public}d, callback exist: %{public}d.", eventHandler_ != nullptr,
63             callback != nullptr);
64         return RET_ERR_NULLPTR;
65     }
66 
67     int32_t accountId = accountId_;
68     std::string clientName = clientName_;
69     std::shared_ptr<ffrt::promise<RetError>> syncPromise = std::make_shared<ffrt::promise<RetError>>();
70     ffrt::future syncFuture = syncPromise->get_future();
71     eventHandler_->PostTask([accountId, clientName, syncPromise, windowId, elementId, treeId, requestId,
72         callback, mode, isFilter]() {
73         HILOG_DEBUG("search element accountId[%{public}d], name[%{public}s]", accountId, clientName.c_str());
74         sptr<IAccessibilityElementOperator> elementOperator = nullptr;
75         RetError ret = GetElementOperator(accountId, windowId, FOCUS_TYPE_INVALID, clientName,
76             elementOperator, treeId);
77         if (ret != RET_OK || !CheckWinFromAwm(windowId, ret)) {
78             HILOG_ERROR("Get elementOperator failed! accessibilityWindowId[%{public}d]", windowId);
79             std::vector<AccessibilityElementInfo> infos = {};
80             callback->SetSearchElementInfoByAccessibilityIdResult(infos, requestId);
81             syncPromise->set_value(ret);
82             return;
83         }
84 
85         auto& awm = Singleton<AccessibilityWindowManager>::GetInstance();
86         if (windowId == SCENE_BOARD_WINDOW_ID && awm.IsInnerWindowRootElement(elementId)) {
87             std::vector<AccessibilityElementInfo> infos = {};
88             callback->SetSearchElementInfoByAccessibilityIdResult(infos, requestId);
89             HILOG_DEBUG("IsInnerWindowRootElement elementId: %{public}" PRId64 "", elementId);
90         } else {
91             int64_t realElementId = awm.GetSceneBoardElementId(windowId, elementId);
92             Singleton<AccessibleAbilityManagerService>::GetInstance().AddRequestId(windowId, treeId,
93                 requestId, callback);
94             elementOperator->SearchElementInfoByAccessibilityId(realElementId, requestId, callback, mode, isFilter);
95             HILOG_DEBUG("AccessibleAbilityChannel::SearchElementInfoByAccessibilityId successfully");
96         }
97         syncPromise->set_value(RET_OK);
98         }, "SearchElementInfoByAccessibilityId");
99 
100     ffrt::future_status wait = syncFuture.wait_for(std::chrono::milliseconds(TIME_OUT_OPERATOR));
101     if (wait != ffrt::future_status::ready) {
102         HILOG_ERROR("Failed to wait SearchElementInfoByAccessibilityId result");
103         return RET_ERR_TIME_OUT;
104     }
105     return syncFuture.get();
106 }
107 
SearchElementInfosByText(const int32_t accessibilityWindowId,const int64_t elementId,const std::string & text,const int32_t requestId,const sptr<IAccessibilityElementOperatorCallback> & callback)108 RetError AccessibleAbilityChannel::SearchElementInfosByText(const int32_t accessibilityWindowId,
109     const int64_t elementId, const std::string &text, const int32_t requestId,
110     const sptr<IAccessibilityElementOperatorCallback> &callback)
111 {
112     HILOG_DEBUG("SearchElementInfosByText :channel SearchElementInfo elementId: %{public}" PRId64 " winId: %{public}d",
113         elementId, accessibilityWindowId);
114     Singleton<AccessibleAbilityManagerService>::GetInstance().PostDelayUnloadTask();
115 
116     if (eventHandler_ == nullptr) {
117         HILOG_ERROR("eventHandler_ is nullptr.");
118         return RET_ERR_NULLPTR;
119     }
120     if (callback == nullptr) {
121         HILOG_ERROR("callback is nullptr.");
122         return RET_ERR_NULLPTR;
123     }
124 
125     int32_t treeId = AccessibleAbilityManagerService::GetTreeIdBySplitElementId(elementId);
126     HILOG_DEBUG("SearchElementInfosByText :channel SearchElementInfo treeId: %{public}d", treeId);
127     int32_t accountId = accountId_;
128     std::string clientName = clientName_;
129     std::shared_ptr<ffrt::promise<RetError>> syncPromise = std::make_shared<ffrt::promise<RetError>>();
130     ffrt::future syncFuture = syncPromise->get_future();
131     eventHandler_->PostTask([accountId, clientName, syncPromise, accessibilityWindowId, elementId, treeId, text,
132         requestId, callback]() {
133         HILOG_DEBUG("accountId[%{public}d], name[%{public}s]", accountId, clientName.c_str());
134         sptr<IAccessibilityElementOperator> elementOperator = nullptr;
135         RetError ret = GetElementOperator(accountId, accessibilityWindowId, FOCUS_TYPE_INVALID,
136             clientName, elementOperator, treeId);
137         if (ret != RET_OK) {
138             HILOG_ERROR("Get elementOperator failed! accessibilityWindowId[%{public}d]", accessibilityWindowId);
139             std::vector<AccessibilityElementInfo> infos = {};
140             callback->SetSearchElementInfoByAccessibilityIdResult(infos, requestId);
141             syncPromise->set_value(ret);
142             return;
143         }
144 
145         auto& awm = Singleton<AccessibilityWindowManager>::GetInstance();
146         int64_t realElementId = awm.GetSceneBoardElementId(accessibilityWindowId, elementId);
147         Singleton<AccessibleAbilityManagerService>::GetInstance().AddRequestId(accessibilityWindowId, treeId,
148             requestId, callback);
149         elementOperator->SearchElementInfosByText(realElementId, text, requestId, callback);
150         syncPromise->set_value(RET_OK);
151         }, "SearchElementInfosByText");
152 
153     ffrt::future_status wait = syncFuture.wait_for(std::chrono::milliseconds(TIME_OUT_OPERATOR));
154     if (wait != ffrt::future_status::ready) {
155         HILOG_ERROR("Failed to wait SearchElementInfosByText result");
156         return RET_ERR_TIME_OUT;
157     }
158     return syncFuture.get();
159 }
160 
FindFocusedElementInfo(const int32_t accessibilityWindowId,const int64_t elementId,const int32_t focusType,const int32_t requestId,const sptr<IAccessibilityElementOperatorCallback> & callback)161 RetError AccessibleAbilityChannel::FindFocusedElementInfo(const int32_t accessibilityWindowId,
162     const int64_t elementId, const int32_t focusType, const int32_t requestId,
163     const sptr<IAccessibilityElementOperatorCallback> &callback)
164 {
165     HILOG_DEBUG("channel FindFocusedElementInfo elementId: %{public}" PRId64 " winId: %{public}d",
166         elementId, accessibilityWindowId);
167     Singleton<AccessibleAbilityManagerService>::GetInstance().PostDelayUnloadTask();
168 
169     if (eventHandler_== nullptr) {
170         HILOG_ERROR("eventHandler_ is nullptr.");
171         return RET_ERR_NULLPTR;
172     }
173     if (callback == nullptr) {
174         HILOG_ERROR("callback is nullptr.");
175         return RET_ERR_NULLPTR;
176     }
177 
178     std::shared_ptr<ffrt::promise<RetError>> syncPromise = std::make_shared<ffrt::promise<RetError>>();
179     ffrt::future syncFuture = syncPromise->get_future();
180     int32_t treeId = AccessibleAbilityManagerService::GetTreeIdBySplitElementId(elementId);
181     HILOG_DEBUG("FindFocusedElementInfo :channel FindFocusedElementInfo treeId: %{public}d", treeId);
182     int32_t accountId = accountId_;
183     std::string clientName = clientName_;
184     eventHandler_->PostTask([accountId, clientName, syncPromise, accessibilityWindowId, elementId, treeId,
185         focusType, requestId, callback]() {
186         HILOG_DEBUG("accountId[%{public}d], name[%{public}s]", accountId, clientName.c_str());
187         sptr<IAccessibilityElementOperator> elementOperator = nullptr;
188         RetError ret = GetElementOperator(accountId, accessibilityWindowId, focusType,
189             clientName, elementOperator, treeId);
190         if (ret != RET_OK) {
191             HILOG_ERROR("Get elementOperator failed! accessibilityWindowId[%{public}d]", accessibilityWindowId);
192             std::vector<AccessibilityElementInfo> infos = {};
193             callback->SetSearchElementInfoByAccessibilityIdResult(infos, requestId);
194             syncPromise->set_value(ret);
195             return;
196         }
197 
198         auto& awm = Singleton<AccessibilityWindowManager>::GetInstance();
199         int64_t realElementId = awm.GetSceneBoardElementId(accessibilityWindowId, elementId);
200         Singleton<AccessibleAbilityManagerService>::GetInstance().AddRequestId(accessibilityWindowId, treeId,
201             requestId, callback);
202         elementOperator->FindFocusedElementInfo(realElementId, focusType, requestId, callback);
203         syncPromise->set_value(RET_OK);
204         }, "FindFocusedElementInfo");
205 
206     ffrt::future_status wait = syncFuture.wait_for(std::chrono::milliseconds(TIME_OUT_OPERATOR));
207     if (wait != ffrt::future_status::ready) {
208         HILOG_ERROR("Failed to wait FindFocusedElementInfo result");
209         return RET_ERR_TIME_OUT;
210     }
211     return syncFuture.get();
212 }
213 
FocusMoveSearch(const int32_t accessibilityWindowId,const int64_t elementId,const int32_t direction,const int32_t requestId,const sptr<IAccessibilityElementOperatorCallback> & callback)214 RetError AccessibleAbilityChannel::FocusMoveSearch(const int32_t accessibilityWindowId, const int64_t elementId,
215     const int32_t direction, const int32_t requestId, const sptr<IAccessibilityElementOperatorCallback> &callback)
216 {
217     HILOG_DEBUG("FocusMoveSearch :channel FocusMoveSearch elementId: %{public}" PRId64 " winId: %{public}d",
218         elementId, accessibilityWindowId);
219     Singleton<AccessibleAbilityManagerService>::GetInstance().PostDelayUnloadTask();
220 
221     if (eventHandler_ == nullptr) {
222         HILOG_ERROR("eventHandler_ is nullptr.");
223         return RET_ERR_NULLPTR;
224     }
225     if (callback == nullptr) {
226         HILOG_ERROR("callback is nullptr.");
227         return RET_ERR_NULLPTR;
228     }
229 
230     std::shared_ptr<ffrt::promise<RetError>> syncPromise = std::make_shared<ffrt::promise<RetError>>();
231     ffrt::future syncFuture = syncPromise->get_future();
232     int32_t treeId = AccessibleAbilityManagerService::GetTreeIdBySplitElementId(elementId);
233     HILOG_DEBUG("FocusMoveSearch :channel FocusMoveSearch treeId: %{public}d", treeId);
234     int32_t accountId = accountId_;
235     std::string clientName = clientName_;
236     eventHandler_->PostTask([accountId, clientName, syncPromise, accessibilityWindowId,
237         elementId, treeId, direction, requestId, callback]() {
238         HILOG_DEBUG("accountId[%{public}d], name[%{public}s]", accountId, clientName.c_str());
239         sptr<IAccessibilityElementOperator> elementOperator = nullptr;
240         RetError ret = GetElementOperator(accountId, accessibilityWindowId, FOCUS_TYPE_INVALID,
241             clientName, elementOperator, treeId);
242         if (ret != RET_OK) {
243             HILOG_ERROR("Get elementOperator failed! accessibilityWindowId[%{public}d]", accessibilityWindowId);
244             std::vector<AccessibilityElementInfo> infos = {};
245             callback->SetSearchElementInfoByAccessibilityIdResult(infos, requestId);
246             syncPromise->set_value(ret);
247             return;
248         }
249 
250         auto& awm = Singleton<AccessibilityWindowManager>::GetInstance();
251         int64_t realElementId = awm.GetSceneBoardElementId(accessibilityWindowId, elementId);
252         Singleton<AccessibleAbilityManagerService>::GetInstance().AddRequestId(accessibilityWindowId, treeId,
253             requestId, callback);
254         elementOperator->FocusMoveSearch(realElementId, direction, requestId, callback);
255         syncPromise->set_value(RET_OK);
256         }, "FocusMoveSearch");
257 
258     ffrt::future_status wait = syncFuture.wait_for(std::chrono::milliseconds(TIME_OUT_OPERATOR));
259     if (wait != ffrt::future_status::ready) {
260         HILOG_ERROR("Failed to wait FocusMoveSearch result");
261         return RET_ERR_TIME_OUT;
262     }
263     return syncFuture.get();
264 }
265 
SetKeyCodeToMmi(std::shared_ptr<MMI::KeyEvent> & keyEvent,const bool isPress,const int32_t keyCode)266 void AccessibleAbilityChannel::SetKeyCodeToMmi(std::shared_ptr<MMI::KeyEvent>& keyEvent, const bool isPress,
267     const int32_t keyCode)
268 {
269     HILOG_DEBUG();
270     Singleton<AccessibleAbilityManagerService>::GetInstance().PostDelayUnloadTask();
271     if (keyEvent == nullptr) {
272         HILOG_ERROR("KeyEvent is nullptr");
273         return;
274     }
275     MMI::KeyEvent::KeyItem item;
276     item.SetPressed(isPress);
277     item.SetKeyCode(keyCode);
278     keyEvent->AddKeyItem(item);
279     keyEvent->SetKeyCode(keyCode);
280 }
281 
TransmitActionToMmi(const int32_t action)282 RetError AccessibleAbilityChannel::TransmitActionToMmi(const int32_t action)
283 {
284     HILOG_DEBUG("The action is %{public}d", action);
285     Singleton<AccessibleAbilityManagerService>::GetInstance().PostDelayUnloadTask();
286     std::shared_ptr<MMI::KeyEvent> keyEventUp = MMI::KeyEvent::Create();
287     std::shared_ptr<MMI::KeyEvent> keyEventDown = MMI::KeyEvent::Create();
288     if (keyEventUp == nullptr || keyEventDown == nullptr) {
289         HILOG_ERROR("KeyEvent is nullptr");
290         return RET_ERR_NULLPTR;
291     }
292 
293     if (!inputManager_) {
294         HILOG_ERROR("inputManager_ is nullptr");
295         return RET_ERR_NULLPTR;
296     }
297 
298     HILOG_INFO("Transmit keycode to MMI");
299 
300     if (accessibleKeyCodeTable.at(action).first) {
301         SetKeyCodeToMmi(keyEventDown, true, accessibleKeyCodeTable.at(action).second.first);
302         SetKeyCodeToMmi(keyEventUp, false, accessibleKeyCodeTable.at(action).second.first);
303     } else {
304         SetKeyCodeToMmi(keyEventDown, true, accessibleKeyCodeTable.at(action).second.first);
305         SetKeyCodeToMmi(keyEventUp, false, accessibleKeyCodeTable.at(action).second.first);
306         SetKeyCodeToMmi(keyEventDown, true, accessibleKeyCodeTable.at(action).second.second);
307     }
308     keyEventDown->SetKeyAction(MMI::KeyEvent::KEY_ACTION_DOWN);
309     keyEventUp->SetKeyAction(MMI::KeyEvent::KEY_ACTION_UP);
310     inputManager_->SimulateInputEvent(keyEventDown);
311     inputManager_->SimulateInputEvent(keyEventUp);
312 
313     return RET_OK;
314 }
315 
EnableScreenCurtain(bool isEnable)316 RetError AccessibleAbilityChannel::EnableScreenCurtain(bool isEnable)
317 {
318     HILOG_DEBUG();
319     auto& aams = Singleton<AccessibleAbilityManagerService>::GetInstance();
320     aams.PostDelayUnloadTask();
321     return aams.SetCurtainScreenUsingStatus(isEnable);
322 }
323 
ExecuteAction(const int32_t accessibilityWindowId,const int64_t elementId,const int32_t action,const std::map<std::string,std::string> & actionArguments,const int32_t requestId,const sptr<IAccessibilityElementOperatorCallback> & callback)324 RetError AccessibleAbilityChannel::ExecuteAction(const int32_t accessibilityWindowId, const int64_t elementId,
325     const int32_t action, const std::map<std::string, std::string> &actionArguments, const int32_t requestId,
326     const sptr<IAccessibilityElementOperatorCallback> &callback)
327 {
328     HILOG_DEBUG("ExecuteAction elementId:%{public}" PRId64 " winId:%{public}d, action:%{public}d, requestId:%{public}d",
329         elementId, accessibilityWindowId, action, requestId);
330     Singleton<AccessibleAbilityManagerService>::GetInstance().PostDelayUnloadTask();
331     if (eventHandler_ == nullptr || callback == nullptr) {
332         HILOG_ERROR("eventHandler_ exist: %{public}d, callback exist: %{public}d.", eventHandler_ != nullptr,
333             callback != nullptr);
334         return RET_ERR_NULLPTR;
335     }
336 
337     if (accessibleKeyCodeTable.find(action) != accessibleKeyCodeTable.end()) {
338         RetError ret = TransmitActionToMmi(action);
339         if (ret != RET_OK) {
340             HILOG_ERROR("Transmit Action To Mmi failed!");
341             callback->SetExecuteActionResult(false, requestId);
342             return RET_ERR_FAILED;
343         }
344         callback->SetExecuteActionResult(true, requestId);
345         return RET_OK;
346     }
347     SetFocusWindowIdAndElementId(accessibilityWindowId, elementId, action);
348     std::shared_ptr<ffrt::promise<RetError>> syncPromise = std::make_shared<ffrt::promise<RetError>>();
349     ffrt::future syncFuture = syncPromise->get_future();
350     int32_t treeId = AccessibleAbilityManagerService::GetTreeIdBySplitElementId(elementId);
351     int32_t accountId = accountId_;
352     std::string clientName = clientName_;
353     eventHandler_->PostTask([accountId, clientName, syncPromise, accessibilityWindowId, elementId, treeId, action,
354         actionArguments, requestId, callback]() {
355         sptr<IAccessibilityElementOperator> elementOperator = nullptr;
356         RetError ret = GetElementOperator(accountId, accessibilityWindowId, FOCUS_TYPE_INVALID, clientName,
357             elementOperator, treeId);
358         if (ret != RET_OK) {
359             HILOG_ERROR("Get elementOperator failed! accessibilityWindowId[%{public}d]", accessibilityWindowId);
360             syncPromise->set_value(ret);
361             return;
362         }
363 
364         auto& awm = Singleton<AccessibilityWindowManager>::GetInstance();
365         int64_t realElementId = awm.GetSceneBoardElementId(accessibilityWindowId, elementId);
366         Singleton<AccessibleAbilityManagerService>::GetInstance().AddRequestId(accessibilityWindowId, treeId,
367             requestId, callback);
368         elementOperator->ExecuteAction(realElementId, action, actionArguments, requestId, callback);
369         syncPromise->set_value(RET_OK);
370         }, "ExecuteAction");
371 
372     ffrt::future_status wait = syncFuture.wait_for(std::chrono::milliseconds(TIME_OUT_OPERATOR));
373     if (wait != ffrt::future_status::ready) {
374         HILOG_ERROR("Failed to wait ExecuteAction result");
375         return RET_ERR_TIME_OUT;
376     }
377     return syncFuture.get();
378 }
379 
SetFocusWindowIdAndElementId(const int32_t accessibilityWindowId,const int64_t elementId,const int32_t action)380 void AccessibleAbilityChannel::SetFocusWindowIdAndElementId(const int32_t accessibilityWindowId,
381     const int64_t elementId, const int32_t action)
382 {
383     auto& awm = Singleton<AccessibleAbilityManagerService>::GetInstance();
384     if ((action == ActionType::ACCESSIBILITY_ACTION_ACCESSIBILITY_FOCUS)) {
385         awm.SetFocusWindowId(accessibilityWindowId);
386         awm.SetFocusElementId(elementId);
387     } else if (action == ActionType::ACCESSIBILITY_ACTION_CLEAR_ACCESSIBILITY_FOCUS) {
388         awm.SetFocusWindowId(WINDOW_ID_INVALID);
389         awm.SetFocusElementId(ELEMENT_ID_INVALID);
390     }
391 }
392 
GetWindow(const int32_t windowId,AccessibilityWindowInfo & windowInfo)393 RetError AccessibleAbilityChannel::GetWindow(const int32_t windowId, AccessibilityWindowInfo &windowInfo)
394 {
395     HILOG_DEBUG("windowId:%{public}d", windowId);
396     Singleton<AccessibleAbilityManagerService>::GetInstance().PostDelayUnloadTask();
397     if (eventHandler_== nullptr) {
398         HILOG_ERROR("eventHandler_ is nullptr.");
399         return RET_ERR_NULLPTR;
400     }
401 
402     int32_t accountId = accountId_;
403     std::string clientName = clientName_;
404     std::shared_ptr<ffrt::promise<RetError>> syncPromise = std::make_shared<ffrt::promise<RetError>>();
405     std::shared_ptr<AccessibilityWindowInfo> tmpWindowInfo = std::make_shared<AccessibilityWindowInfo>(windowInfo);
406     ffrt::future syncFuture = syncPromise->get_future();
407     eventHandler_->PostTask([accountId, clientName, windowId, tmpWindowInfo, syncPromise]() {
408         HILOG_DEBUG("windowId:%{public}d", windowId);
409         sptr<AccessibleAbilityConnection> clientConnection = GetConnection(accountId, clientName);
410         if (!clientConnection) {
411             HILOG_ERROR("There is no client connection");
412             syncPromise->set_value(RET_ERR_NO_CONNECTION);
413             return;
414         }
415         if (!(clientConnection->GetAbilityInfo().GetCapabilityValues() & Capability::CAPABILITY_RETRIEVE)) {
416             HILOG_ERROR("AccessibleAbilityChannel::GetWindow failed: no capability");
417             syncPromise->set_value(RET_ERR_NO_CAPABILITY);
418             return;
419         }
420 
421         if (Singleton<AccessibilityWindowManager>::GetInstance().GetAccessibilityWindow(windowId, *tmpWindowInfo)) {
422             syncPromise->set_value(RET_OK);
423         } else {
424             syncPromise->set_value(RET_ERR_NO_WINDOW_CONNECTION);
425         }
426         }, "GetWindow");
427 
428     ffrt::future_status wait = syncFuture.wait_for(std::chrono::milliseconds(TIME_OUT_OPERATOR));
429     if (wait != ffrt::future_status::ready) {
430         HILOG_ERROR("Failed to wait GetWindow result");
431         return RET_ERR_TIME_OUT;
432     }
433 
434     windowInfo = *tmpWindowInfo;
435     return syncFuture.get();
436 }
437 
GetWindows(std::vector<AccessibilityWindowInfo> & windows)438 RetError AccessibleAbilityChannel::GetWindows(std::vector<AccessibilityWindowInfo> &windows)
439 {
440     HILOG_DEBUG();
441     Singleton<AccessibleAbilityManagerService>::GetInstance().PostDelayUnloadTask();
442 #ifdef OHOS_BUILD_ENABLE_DISPLAY_MANAGER
443     uint64_t displayId = Singleton<AccessibilityDisplayManager>::GetInstance().GetDefaultDisplayId();
444     HILOG_DEBUG("default display id is %{public}" PRIu64 "", displayId);
445     return GetWindows(displayId, windows);
446 #else
447     HILOG_DEBUG("not support display manager");
448     return GetWindows(0, windows);
449 #endif
450 }
451 
GetWindowsByDisplayId(const uint64_t displayId,std::vector<AccessibilityWindowInfo> & windows)452 RetError AccessibleAbilityChannel::GetWindowsByDisplayId(const uint64_t displayId,
453     std::vector<AccessibilityWindowInfo> &windows)
454 {
455     HILOG_DEBUG();
456     return GetWindows(displayId, windows);
457 }
458 
GetWindows(uint64_t displayId,std::vector<AccessibilityWindowInfo> & windows) const459 RetError AccessibleAbilityChannel::GetWindows(uint64_t displayId, std::vector<AccessibilityWindowInfo> &windows) const
460 {
461     if (eventHandler_== nullptr) {
462         HILOG_ERROR("eventHandler_ is nullptr.");
463         return RET_ERR_NULLPTR;
464     }
465 
466     std::shared_ptr<ffrt::promise<RetError>> syncPromise = std::make_shared<ffrt::promise<RetError>>();
467     auto tmpWindows = std::make_shared<std::vector<AccessibilityWindowInfo>>(windows);
468     int32_t accountId = accountId_;
469     std::string clientName = clientName_;
470     ffrt::future syncFuture = syncPromise->get_future();
471     eventHandler_->PostTask([accountId, clientName, displayId, tmpWindows, syncPromise]() {
472         HILOG_DEBUG();
473         sptr<AccessibleAbilityConnection> clientConnection = GetConnection(accountId, clientName);
474         if (!clientConnection) {
475             HILOG_ERROR("There is no client connection");
476             syncPromise->set_value(RET_ERR_NO_CONNECTION);
477             return;
478         }
479 
480         if (!(clientConnection->GetAbilityInfo().GetCapabilityValues() & Capability::CAPABILITY_RETRIEVE)) {
481             HILOG_ERROR("GetWindows failed: no capability");
482             syncPromise->set_value(RET_ERR_NO_CAPABILITY);
483             return;
484         }
485 
486         std::vector<AccessibilityWindowInfo> windowInfos =
487             Singleton<AccessibilityWindowManager>::GetInstance().GetAccessibilityWindows();
488 #ifdef OHOS_BUILD_ENABLE_DISPLAY_MANAGER
489         for (auto &window : windowInfos) {
490             if (window.GetDisplayId() == displayId) {
491                 tmpWindows->emplace_back(window);
492             }
493         }
494 #else
495         for (auto &window : windowInfos) {
496             tmpWindows->emplace_back(window);
497         }
498 #endif
499         syncPromise->set_value(RET_OK);
500         }, "GetWindows");
501 
502     ffrt::future_status wait = syncFuture.wait_for(std::chrono::milliseconds(TIME_OUT_OPERATOR));
503     if (wait != ffrt::future_status::ready) {
504         HILOG_ERROR("Failed to wait GetWindows result");
505         return RET_ERR_TIME_OUT;
506     }
507 
508     windows = *tmpWindows;
509     return syncFuture.get();
510 }
511 
SetOnKeyPressEventResult(const bool handled,const int32_t sequence)512 void AccessibleAbilityChannel::SetOnKeyPressEventResult(const bool handled, const int32_t sequence)
513 {
514     HILOG_DEBUG();
515     Singleton<AccessibleAbilityManagerService>::GetInstance().PostDelayUnloadTask();
516     if (eventHandler_== nullptr) {
517         HILOG_ERROR("eventHandler_ is nullptr.");
518         return;
519     }
520 
521     int32_t accountId = accountId_;
522     std::string clientName = clientName_;
523     eventHandler_->PostTask([accountId, clientName, handled, sequence]() {
524         sptr<KeyEventFilter> keyEventFilter =
525             Singleton<AccessibleAbilityManagerService>::GetInstance().GetKeyEventFilter();
526         if (!keyEventFilter) {
527             return;
528         }
529 
530         sptr<AccessibleAbilityConnection> clientConnection = GetConnection(accountId, clientName);
531         if (!clientConnection) {
532             HILOG_ERROR("There is no client connection");
533             return;
534         }
535         keyEventFilter->SetServiceOnKeyEventResult(*clientConnection, handled, sequence);
536         }, "SetOnKeyPressEventResult");
537 }
538 
GetCursorPosition(const int32_t accessibilityWindowId,const int64_t elementId,const int32_t requestId,const sptr<IAccessibilityElementOperatorCallback> & callback)539 RetError AccessibleAbilityChannel::GetCursorPosition(const int32_t accessibilityWindowId, const int64_t elementId,
540     const int32_t requestId, const sptr<IAccessibilityElementOperatorCallback> &callback)
541 {
542     HILOG_DEBUG("GetCursorPosition :channel GetCursorPosition elementId: %{public}" PRId64 " winId: %{public}d",
543         elementId, accessibilityWindowId);
544     Singleton<AccessibleAbilityManagerService>::GetInstance().PostDelayUnloadTask();
545     if (eventHandler_== nullptr) {
546         HILOG_ERROR("eventHandler_ is nullptr.");
547         return RET_ERR_NULLPTR;
548     }
549     std::shared_ptr<ffrt::promise<RetError>> syncPromise = std::make_shared<ffrt::promise<RetError>>();
550     ffrt::future syncFuture = syncPromise->get_future();
551     int32_t treeId = AccessibleAbilityManagerService::GetTreeIdBySplitElementId(elementId);
552     HILOG_DEBUG("GetCursorPosition :channel GetCursorPosition treeId: %{public}d", treeId);
553     int32_t accountId = accountId_;
554     std::string clientName = clientName_;
555     eventHandler_->PostTask([accountId, clientName, syncPromise, accessibilityWindowId, elementId, treeId,
556         requestId, callback]() {
557         HILOG_DEBUG("accountId[%{public}d], name[%{public}s]", accountId, clientName.c_str());
558         sptr<IAccessibilityElementOperator> elementOperator = nullptr;
559         RetError ret = GetElementOperator(accountId, accessibilityWindowId, FOCUS_TYPE_INVALID, clientName,
560             elementOperator, treeId);
561         if (ret != RET_OK) {
562             HILOG_ERROR("Get elementOperator failed! accessibilityWindowId[%{public}d]", accessibilityWindowId);
563             syncPromise->set_value(ret);
564             return;
565         }
566 
567         auto& awm = Singleton<AccessibilityWindowManager>::GetInstance();
568         int64_t realElementId = awm.GetSceneBoardElementId(accessibilityWindowId, elementId);
569         Singleton<AccessibleAbilityManagerService>::GetInstance().AddRequestId(accessibilityWindowId, treeId,
570             requestId, callback);
571         elementOperator->GetCursorPosition(realElementId, requestId, callback);
572         syncPromise->set_value(RET_OK);
573         }, "GetCursorPosition");
574 
575     ffrt::future_status wait = syncFuture.wait_for(std::chrono::milliseconds(TIME_OUT_OPERATOR));
576     if (wait != ffrt::future_status::ready) {
577         HILOG_ERROR("Failed to wait GetCursorPosition result");
578         return RET_ERR_TIME_OUT;
579     }
580     return syncFuture.get();
581 }
582 
SendSimulateGesture(const std::shared_ptr<AccessibilityGestureInjectPath> & gesturePath)583 RetError AccessibleAbilityChannel::SendSimulateGesture(
584     const std::shared_ptr<AccessibilityGestureInjectPath>& gesturePath)
585 {
586     HILOG_INFO();
587     Singleton<AccessibleAbilityManagerService>::GetInstance().PostDelayUnloadTask();
588     if (eventHandler_== nullptr) {
589         HILOG_ERROR("eventHandler_ is nullptr");
590         return RET_ERR_NULLPTR;
591     }
592 
593     int32_t accountId = accountId_;
594     std::string clientName = clientName_;
595     std::shared_ptr<ffrt::promise<RetError>> syncPromise = std::make_shared<ffrt::promise<RetError>>();
596     ffrt::future syncFuture = syncPromise->get_future();
597     eventHandler_->PostTask([accountId, clientName, gesturePath, syncPromise]() {
598         HILOG_DEBUG();
599         sptr<AccessibleAbilityConnection> clientConnection = GetConnection(accountId, clientName);
600         if (!clientConnection) {
601             HILOG_ERROR("There is no client connection");
602             syncPromise->set_value(RET_ERR_NO_CONNECTION);
603             return;
604         }
605 
606         if (!(clientConnection->GetAbilityInfo().GetCapabilityValues() & Capability::CAPABILITY_GESTURE)) {
607             HILOG_ERROR("AccessibleAbilityChannel::SendSimulateGesture failed: no capability");
608             syncPromise->set_value(RET_ERR_NO_CAPABILITY);
609             return;
610         }
611 
612         sptr<TouchEventInjector> touchEventInjector =
613             Singleton<AccessibleAbilityManagerService>::GetInstance().GetTouchEventInjector();
614         if (!touchEventInjector) {
615             HILOG_ERROR("touchEventInjector is null");
616             syncPromise->set_value(RET_ERR_NO_INJECTOR);
617             return;
618         }
619         touchEventInjector->InjectEvents(gesturePath);
620         syncPromise->set_value(RET_OK);
621         }, "SendSimulateGesture");
622 
623     ffrt::future_status wait = syncFuture.wait_for(std::chrono::milliseconds(TIME_OUT_OPERATOR));
624     if (wait != ffrt::future_status::ready) {
625         HILOG_ERROR("Failed to wait SendSimulateGesture result");
626         return RET_ERR_TIME_OUT;
627     }
628     return syncFuture.get();
629 }
630 
SetTargetBundleName(const std::vector<std::string> & targetBundleNames)631 RetError AccessibleAbilityChannel::SetTargetBundleName(const std::vector<std::string> &targetBundleNames)
632 {
633     HILOG_DEBUG();
634     Singleton<AccessibleAbilityManagerService>::GetInstance().PostDelayUnloadTask();
635     if (eventHandler_== nullptr) {
636         HILOG_ERROR("eventHandler_ is nullptr");
637         return RET_ERR_NULLPTR;
638     }
639 
640     int32_t accountId = accountId_;
641     std::string clientName = clientName_;
642     std::shared_ptr<ffrt::promise<RetError>> syncPromise = std::make_shared<ffrt::promise<RetError>>();
643     ffrt::future syncFuture = syncPromise->get_future();
644     eventHandler_->PostTask([accountId, clientName, targetBundleNames, syncPromise]() {
645         HILOG_DEBUG();
646         sptr<AccessibleAbilityConnection> clientConnection = GetConnection(accountId, clientName);
647         if (!clientConnection) {
648             HILOG_ERROR("There is no client connection");
649             syncPromise->set_value(RET_ERR_NO_CONNECTION);
650             return;
651         }
652 
653         clientConnection->SetAbilityInfoTargetBundleName(targetBundleNames);
654         syncPromise->set_value(RET_OK);
655         }, "SetTargetBundleName");
656 
657     ffrt::future_status wait = syncFuture.wait_for(std::chrono::milliseconds(TIME_OUT_OPERATOR));
658     if (wait != ffrt::future_status::ready) {
659         HILOG_ERROR("Failed to wait SetTargetBundleName result");
660         return RET_ERR_TIME_OUT;
661     }
662     return syncFuture.get();
663 }
664 
GetConnection(int32_t accountId,const std::string & clientName)665 sptr<AccessibleAbilityConnection> AccessibleAbilityChannel::GetConnection(
666     int32_t accountId, const std::string &clientName)
667 {
668     HILOG_DEBUG();
669     sptr<AccessibilityAccountData> accountData =
670         Singleton<AccessibleAbilityManagerService>::GetInstance().GetAccountData(accountId);
671     if (accountData == nullptr) {
672         HILOG_ERROR("accountData is nullptr");
673         return nullptr;
674     }
675 
676     HILOG_DEBUG("accountId[%{public}d] clientName[%{public}s]", accountId, clientName.c_str());
677     return accountData->GetAccessibleAbilityConnection(clientName);
678 }
679 
GetElementOperator(int32_t accountId,int32_t windowId,int32_t focusType,const std::string & clientName,sptr<IAccessibilityElementOperator> & elementOperator,const int32_t treeId)680 RetError AccessibleAbilityChannel::GetElementOperator(
681     int32_t accountId, int32_t windowId, int32_t focusType, const std::string &clientName,
682     sptr<IAccessibilityElementOperator> &elementOperator, const int32_t treeId)
683 {
684     HILOG_DEBUG();
685     elementOperator = nullptr;
686     sptr<AccessibleAbilityConnection> clientConnection = GetConnection(accountId, clientName);
687     if (!clientConnection) {
688         HILOG_ERROR("There is no client connection");
689         return RET_ERR_NO_CONNECTION;
690     }
691     if (!(clientConnection->GetAbilityInfo().GetCapabilityValues() & Capability::CAPABILITY_RETRIEVE)) {
692         HILOG_ERROR("the client has no retieve capability");
693         return RET_ERR_NO_CAPABILITY;
694     }
695 
696     sptr<AccessibilityAccountData> accountData =
697         Singleton<AccessibleAbilityManagerService>::GetInstance().GetAccountData(accountId);
698     if (!accountData) {
699         HILOG_ERROR("accountData is nullptr");
700         return RET_ERR_NULLPTR;
701     }
702     int32_t realId = Singleton<AccessibilityWindowManager>::GetInstance().ConvertToRealWindowId(windowId, focusType);
703     sptr<AccessibilityWindowConnection> connection =  nullptr;
704     connection = accountData->GetAccessibilityWindowConnection(realId);
705     if (connection == nullptr) {
706         HILOG_ERROR("windowId[%{public}d] has no connection", realId);
707         return RET_ERR_NO_WINDOW_CONNECTION;
708     }
709     if (treeId <= 0) {
710         elementOperator = connection->GetProxy();
711     } else {
712         elementOperator = connection->GetCardProxy(treeId);
713     }
714     if (!elementOperator) {
715         HILOG_ERROR("The proxy of window connection is nullptr");
716         return RET_ERR_NULLPTR;
717     }
718     return RET_OK;
719 }
720 
CheckWinFromAwm(const int32_t windowId,const int32_t getElementOperatorResult)721 bool AccessibleAbilityChannel::CheckWinFromAwm(const int32_t windowId, const int32_t getElementOperatorResult)
722 {
723     HILOG_DEBUG("CheckWinFromAwm window: %{public}d, ConnectResult: [%{public}d]", windowId, getElementOperatorResult);
724     if (windowId == SCENE_BOARD_WINDOW_ID && getElementOperatorResult == RET_OK) {
725         return true;
726     }
727     std::vector<AccessibilityWindowInfo> windows =
728         Singleton<AccessibilityWindowManager>::GetInstance().GetAccessibilityWindows();
729     if (!windows.empty()) {
730         for (const auto& window: windows) {
731             if (windowId == window.GetWindowId()) {
732                 return true;
733             }
734         }
735     }
736     return false;
737 }
738 } // namespace Accessibility
739 } // namespace OHOS
740