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