1 /*
2 * Copyright (C) 2022-2023 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_client_impl.h"
17
18 #include <chrono>
19 #include <cinttypes>
20 #include <thread>
21
22 #include "accessible_ability_client.h"
23 #include "hilog_wrapper.h"
24 #include "if_system_ability_manager.h"
25 #include "iservice_registry.h"
26 #include "parameter.h"
27 #include "system_ability_definition.h"
28
29 namespace OHOS {
30 namespace Accessibility {
31 // tmp: wait for window registing when client connect done
32 constexpr int WAIT_WINDOW_REGIST = 500;
33 namespace {
34 const std::string SYSTEM_PARAMETER_AAMS_NAME = "accessibility.config.ready";
35 constexpr int32_t CONFIG_PARAMETER_VALUE_SIZE = 10;
36 constexpr int32_t ROOT_NONE_ID = -1;
37 std::mutex g_Mutex;
38 sptr<AccessibleAbilityClientImpl> g_Instance = nullptr;
39 } // namespace
40
GetInstance()41 sptr<AccessibleAbilityClient> AccessibleAbilityClient::GetInstance()
42 {
43 HILOG_DEBUG();
44 std::lock_guard<std::mutex> lock(g_Mutex);
45 if (!g_Instance) {
46 g_Instance = new(std::nothrow) AccessibleAbilityClientImpl();
47 }
48 return g_Instance;
49 }
50
GetAbilityClientImplement()51 sptr<AccessibleAbilityClientImpl> AccessibleAbilityClientImpl::GetAbilityClientImplement()
52 {
53 HILOG_DEBUG();
54 std::lock_guard<std::mutex> lock(g_Mutex);
55 if (!g_Instance) {
56 g_Instance = new(std::nothrow) AccessibleAbilityClientImpl();
57 }
58 return g_Instance;
59 }
60
AccessibleAbilityClientImpl()61 AccessibleAbilityClientImpl::AccessibleAbilityClientImpl()
62 {
63 HILOG_DEBUG();
64 char value[CONFIG_PARAMETER_VALUE_SIZE] = "default";
65 int retSysParam = GetParameter(SYSTEM_PARAMETER_AAMS_NAME.c_str(), "false", value, CONFIG_PARAMETER_VALUE_SIZE);
66 if (retSysParam >= 0 && !std::strcmp(value, "true")) {
67 // Accessibility service is ready
68 if (!InitAccessibilityServiceProxy()) {
69 HILOG_ERROR("Init accessibility service proxy failed");
70 }
71 }
72
73 HILOG_DEBUG("Start watching accessibility service.");
74 retSysParam = WatchParameter(SYSTEM_PARAMETER_AAMS_NAME.c_str(),
75 &AccessibleAbilityClientImpl::OnParameterChanged, this);
76 if (retSysParam) {
77 HILOG_ERROR("Watch parameter failed, error = %{public}d", retSysParam);
78 }
79 }
80
~AccessibleAbilityClientImpl()81 AccessibleAbilityClientImpl::~AccessibleAbilityClientImpl()
82 {
83 HILOG_DEBUG();
84 std::lock_guard<std::mutex> lock(mutex_);
85 if (serviceProxy_ && serviceProxy_->AsObject()) {
86 HILOG_DEBUG("Remove service death recipient");
87 serviceProxy_->AsObject()->RemoveDeathRecipient(accessibilityServiceDeathRecipient_);
88 }
89 }
90
InitAccessibilityServiceProxy()91 bool AccessibleAbilityClientImpl::InitAccessibilityServiceProxy()
92 {
93 if (serviceProxy_) {
94 HILOG_DEBUG("Accessibility Service is connected");
95 return true;
96 }
97
98 sptr<ISystemAbilityManager> samgr = SystemAbilityManagerClient::GetInstance().GetSystemAbilityManager();
99 if (!samgr) {
100 HILOG_ERROR("Failed to get ISystemAbilityManager");
101 return false;
102 }
103 HILOG_DEBUG("ISystemAbilityManager obtained");
104
105 sptr<IRemoteObject> object = samgr->GetSystemAbility(ACCESSIBILITY_MANAGER_SERVICE_ID);
106 if (!object) {
107 HILOG_ERROR("Get IAccessibleAbilityManagerService object from samgr failed");
108 return false;
109 }
110 HILOG_DEBUG("Get remote object ok");
111
112 serviceProxy_ = iface_cast<IAccessibleAbilityManagerService>(object);
113 if (!serviceProxy_) {
114 HILOG_ERROR("Get aams proxy failed");
115 return false;
116 }
117
118 // Add death recipient
119 if (!accessibilityServiceDeathRecipient_) {
120 accessibilityServiceDeathRecipient_ = new(std::nothrow) AccessibilityServiceDeathRecipient(*this);
121 if (!accessibilityServiceDeathRecipient_) {
122 HILOG_ERROR("Failed to create service deathRecipient.");
123 return false;
124 }
125 }
126
127 if (serviceProxy_->AsObject()) {
128 HILOG_DEBUG("Add death recipient");
129 serviceProxy_->AsObject()->AddDeathRecipient(accessibilityServiceDeathRecipient_);
130 }
131 return true;
132 }
133
OnParameterChanged(const char * key,const char * value,void * context)134 void AccessibleAbilityClientImpl::OnParameterChanged(const char *key, const char *value, void *context)
135 {
136 HILOG_DEBUG("Parameter key = [%{public}s] value = [%{public}s]", key, value);
137
138 if (!key || std::strcmp(key, SYSTEM_PARAMETER_AAMS_NAME.c_str())) {
139 HILOG_WARN("not accessibility.config.ready callback");
140 return;
141 }
142
143 if (!value || std::strcmp(value, "true")) {
144 HILOG_WARN("accessibility.config.ready value not true");
145 return;
146 }
147
148 if (!context) {
149 HILOG_ERROR("accessibility.config.ready context NULL");
150 return;
151 }
152
153 AccessibleAbilityClientImpl* implPtr = static_cast<AccessibleAbilityClientImpl*>(context);
154 {
155 HILOG_DEBUG("ConnectToService start.");
156 std::lock_guard<std::mutex> lock(implPtr->mutex_);
157 if (implPtr->InitAccessibilityServiceProxy()) {
158 HILOG_DEBUG("ConnectToService Success");
159 }
160 }
161 }
162
GetRemoteObject()163 sptr<IRemoteObject> AccessibleAbilityClientImpl::GetRemoteObject()
164 {
165 HILOG_INFO();
166 return this->AsObject();
167 }
168
RegisterAbilityListener(const std::shared_ptr<AccessibleAbilityListener> & listener)169 RetError AccessibleAbilityClientImpl::RegisterAbilityListener(
170 const std::shared_ptr<AccessibleAbilityListener> &listener)
171 {
172 HILOG_INFO();
173 std::lock_guard<std::mutex> lock(mutex_);
174 if (listener_) {
175 HILOG_DEBUG("listener already exists.");
176 return RET_ERR_REGISTER_EXIST;
177 }
178
179 listener_ = listener;
180 return RET_OK;
181 }
182
Init(const sptr<IAccessibleAbilityChannel> & channel,const int32_t channelId)183 void AccessibleAbilityClientImpl::Init(const sptr<IAccessibleAbilityChannel> &channel, const int32_t channelId)
184 {
185 HILOG_INFO("channelId[%{public}d]", channelId);
186 if (!channel || channelId == INVALID_CHANNEL_ID) {
187 HILOG_ERROR("channel is nullptr, or channelId is invalid");
188 return;
189 }
190
191 std::shared_ptr<AccessibleAbilityListener> listener = nullptr;
192 {
193 std::lock_guard<std::mutex> lock(mutex_);
194 if (!listener_) {
195 HILOG_ERROR("listener_ is nullptr.");
196 return;
197 }
198 listener = listener_;
199 channelClient_ = std::make_shared<AccessibleAbilityChannelClient>(channelId, channel);
200
201 // Add death recipient
202 if (!deathRecipient_) {
203 deathRecipient_ = new(std::nothrow) AccessibleAbilityDeathRecipient(*this);
204 if (!deathRecipient_) {
205 HILOG_ERROR("Failed to create deathRecipient.");
206 return;
207 }
208 }
209
210 if (channel->AsObject()) {
211 HILOG_DEBUG("Add death recipient");
212 channel->AsObject()->AddDeathRecipient(deathRecipient_);
213 }
214 }
215
216 std::this_thread::sleep_for(std::chrono::milliseconds(WAIT_WINDOW_REGIST));
217 if (listener) {
218 listener->OnAbilityConnected();
219 }
220 }
221
Disconnect(const int32_t channelId)222 void AccessibleAbilityClientImpl::Disconnect(const int32_t channelId)
223 {
224 HILOG_INFO("channelId[%{public}d]", channelId);
225
226 std::shared_ptr<AccessibleAbilityListener> listener = nullptr;
227 {
228 std::lock_guard<std::mutex> lock(mutex_);
229 // Delete death recipient
230 if (channelClient_ && channelClient_->GetRemote()) {
231 HILOG_ERROR("Remove death recipient");
232 channelClient_->GetRemote()->RemoveDeathRecipient(deathRecipient_);
233 }
234
235 // Remove channel
236 channelClient_ = nullptr;
237 listener = listener_;
238 listener_ = nullptr;
239 }
240
241 if (listener) {
242 listener->OnAbilityDisconnected();
243 }
244 }
245
OnAccessibilityEvent(const AccessibilityEventInfo & eventInfo)246 void AccessibleAbilityClientImpl::OnAccessibilityEvent(const AccessibilityEventInfo &eventInfo)
247 {
248 HILOG_INFO();
249 std::shared_ptr<AccessibleAbilityListener> listener = nullptr;
250 {
251 std::lock_guard<std::mutex> lock(mutex_);
252 if (!channelClient_) {
253 HILOG_ERROR("The channel is invalid.");
254 return;
255 }
256 listener = listener_;
257 }
258 if (listener) {
259 listener->OnAccessibilityEvent(eventInfo);
260 }
261 }
262
OnKeyPressEvent(const MMI::KeyEvent & keyEvent,const int32_t sequence)263 void AccessibleAbilityClientImpl::OnKeyPressEvent(const MMI::KeyEvent &keyEvent, const int32_t sequence)
264 {
265 HILOG_INFO("sequence[%{public}d]", sequence);
266 std::shared_ptr<AccessibleAbilityListener> listener = nullptr;
267 std::shared_ptr<AccessibleAbilityChannelClient> channel = nullptr;
268 {
269 std::lock_guard<std::mutex> lock(mutex_);
270 listener = listener_;
271 channel = channelClient_;
272 }
273
274 if (!channel) {
275 HILOG_ERROR("The channel is invalid.");
276 return;
277 }
278 bool handled = false;
279 if (listener) {
280 std::shared_ptr<MMI::KeyEvent> tmp = std::make_shared<MMI::KeyEvent>(keyEvent);
281 handled = listener->OnKeyPressEvent(tmp);
282 }
283 channel->SetOnKeyPressEventResult(handled, sequence);
284 }
285
GetFocus(const int32_t focusType,AccessibilityElementInfo & elementInfo)286 RetError AccessibleAbilityClientImpl::GetFocus(const int32_t focusType, AccessibilityElementInfo &elementInfo)
287 {
288 HILOG_INFO("focusType[%{public}d]", focusType);
289 std::lock_guard<std::mutex> lock(mutex_);
290 if ((focusType != FOCUS_TYPE_INPUT) && (focusType != FOCUS_TYPE_ACCESSIBILITY)) {
291 HILOG_ERROR("focusType is not allowed.");
292 return RET_ERR_INVALID_PARAM;
293 }
294
295 if (!channelClient_) {
296 HILOG_ERROR("The channel is invalid.");
297 return RET_ERR_NO_CONNECTION;
298 }
299
300 return channelClient_->FindFocusedElementInfo(ANY_WINDOW_ID, ROOT_NODE_ID, focusType, elementInfo);
301 }
302
GetFocusByElementInfo(const AccessibilityElementInfo & sourceInfo,const int32_t focusType,AccessibilityElementInfo & elementInfo)303 RetError AccessibleAbilityClientImpl::GetFocusByElementInfo(const AccessibilityElementInfo &sourceInfo,
304 const int32_t focusType, AccessibilityElementInfo &elementInfo)
305 {
306 HILOG_INFO("focusType[%{public}d]", focusType);
307 std::lock_guard<std::mutex> lock(mutex_);
308 if ((focusType != FOCUS_TYPE_INPUT) && (focusType != FOCUS_TYPE_ACCESSIBILITY)) {
309 HILOG_ERROR("focusType is not allowed.");
310 return RET_ERR_INVALID_PARAM;
311 }
312
313 if (!channelClient_) {
314 HILOG_ERROR("The channel is invalid.");
315 return RET_ERR_NO_CONNECTION;
316 }
317
318 int32_t windowId = sourceInfo.GetWindowId();
319 int32_t elementId = sourceInfo.GetAccessibilityId();
320 HILOG_INFO("windowId[%{public}d], elementId[%{public}d], focusType[%{public}d]", windowId, elementId, focusType);
321
322 return channelClient_->FindFocusedElementInfo(windowId, elementId, focusType, elementInfo);
323 }
324
InjectGesture(const std::shared_ptr<AccessibilityGestureInjectPath> & gesturePath)325 RetError AccessibleAbilityClientImpl::InjectGesture(const std::shared_ptr<AccessibilityGestureInjectPath> &gesturePath)
326 {
327 HILOG_INFO();
328 std::lock_guard<std::mutex> lock(mutex_);
329
330 if (!gesturePath) {
331 HILOG_ERROR("The gesturePath is null.");
332 return RET_ERR_INVALID_PARAM;
333 }
334
335 std::vector<AccessibilityGesturePosition> positions = gesturePath->GetPositions();
336
337 if (positions.size() == 0) {
338 HILOG_ERROR("The number of gesture path position is not allowed.");
339 return RET_ERR_INVALID_PARAM;
340 }
341
342 if (!channelClient_) {
343 HILOG_ERROR("The channel is invalid.");
344 return RET_ERR_NO_CONNECTION;
345 }
346
347 return channelClient_->SendSimulateGesture(gesturePath);
348 }
349
GetRoot(AccessibilityElementInfo & elementInfo)350 RetError AccessibleAbilityClientImpl::GetRoot(AccessibilityElementInfo &elementInfo)
351 {
352 HILOG_DEBUG();
353 std::lock_guard<std::mutex> lock(mutex_);
354 if (!serviceProxy_) {
355 HILOG_ERROR("Failed to connect to aams");
356 return RET_ERR_SAMGR;
357 }
358
359 if (!channelClient_) {
360 HILOG_ERROR("The channel is invalid.");
361 return RET_ERR_NO_CONNECTION;
362 }
363
364 int32_t activeWindow = serviceProxy_->GetActiveWindow();
365 HILOG_INFO("activeWindow[%{public}d]", activeWindow);
366 if (GetCacheElementInfo(activeWindow, ROOT_NONE_ID, elementInfo)) {
367 HILOG_DEBUG("get element info from cache");
368 return RET_OK;
369 }
370
371 return SearchElementInfoFromAce(activeWindow, ROOT_NONE_ID, cacheMode_, elementInfo);
372 }
373
GetRootByWindow(const AccessibilityWindowInfo & windowInfo,AccessibilityElementInfo & elementInfo)374 RetError AccessibleAbilityClientImpl::GetRootByWindow(const AccessibilityWindowInfo &windowInfo,
375 AccessibilityElementInfo &elementInfo)
376 {
377 HILOG_DEBUG();
378 std::lock_guard<std::mutex> lock(mutex_);
379 if (!channelClient_) {
380 HILOG_ERROR("The channel is invalid.");
381 return RET_ERR_NO_CONNECTION;
382 }
383
384 int32_t windowId = windowInfo.GetWindowId();
385 HILOG_INFO("windowId[%{public}d]", windowId);
386 if (GetCacheElementInfo(windowId, ROOT_NONE_ID, elementInfo)) {
387 HILOG_DEBUG("get element info from cache");
388 return RET_OK;
389 }
390
391 return SearchElementInfoFromAce(windowId, ROOT_NONE_ID, cacheMode_, elementInfo);
392 }
393
GetWindow(const int32_t windowId,AccessibilityWindowInfo & windowInfo)394 RetError AccessibleAbilityClientImpl::GetWindow(const int32_t windowId, AccessibilityWindowInfo &windowInfo)
395 {
396 HILOG_INFO("windowId[%{public}d]", windowId);
397 std::lock_guard<std::mutex> lock(mutex_);
398 if (!channelClient_) {
399 HILOG_ERROR("The channel is invalid.");
400 return RET_ERR_NO_CONNECTION;
401 }
402 return channelClient_->GetWindow(windowId, windowInfo);
403 }
404
GetWindows(std::vector<AccessibilityWindowInfo> & windows)405 RetError AccessibleAbilityClientImpl::GetWindows(std::vector<AccessibilityWindowInfo> &windows)
406 {
407 HILOG_INFO();
408 std::lock_guard<std::mutex> lock(mutex_);
409 if (!channelClient_) {
410 HILOG_ERROR("The channel is invalid.");
411 return RET_ERR_NO_CONNECTION;
412 }
413 return channelClient_->GetWindows(windows);
414 }
415
GetWindows(const uint64_t displayId,std::vector<AccessibilityWindowInfo> & windows)416 RetError AccessibleAbilityClientImpl::GetWindows(const uint64_t displayId,
417 std::vector<AccessibilityWindowInfo> &windows)
418 {
419 HILOG_INFO("displayId[%{public}" PRIu64 "]", displayId);
420 std::lock_guard<std::mutex> lock(mutex_);
421 if (!channelClient_) {
422 HILOG_ERROR("The channel is invalid.");
423 return RET_ERR_NO_CONNECTION;
424 }
425 return channelClient_->GetWindows(displayId, windows);
426 }
427
GetNext(const AccessibilityElementInfo & elementInfo,const FocusMoveDirection direction,AccessibilityElementInfo & nextElementInfo)428 RetError AccessibleAbilityClientImpl::GetNext(const AccessibilityElementInfo &elementInfo,
429 const FocusMoveDirection direction, AccessibilityElementInfo &nextElementInfo)
430 {
431 HILOG_INFO("windowId[%{public}d], elementId[%{public}d], direction[%{public}d]",
432 elementInfo.GetWindowId(), elementInfo.GetAccessibilityId(), direction);
433 std::lock_guard<std::mutex> lock(mutex_);
434 if (!channelClient_) {
435 HILOG_ERROR("The channel is invalid.");
436 return RET_ERR_NO_CONNECTION;
437 }
438 if (direction == DIRECTION_INVALID) {
439 HILOG_ERROR("direction is invalid.");
440 return RET_ERR_INVALID_PARAM;
441 }
442 return channelClient_->FocusMoveSearch(elementInfo.GetWindowId(),
443 elementInfo.GetAccessibilityId(), direction, nextElementInfo);
444 }
445
GetChildElementInfo(const int32_t index,const AccessibilityElementInfo & parent,AccessibilityElementInfo & child)446 RetError AccessibleAbilityClientImpl::GetChildElementInfo(const int32_t index, const AccessibilityElementInfo &parent,
447 AccessibilityElementInfo &child)
448 {
449 HILOG_DEBUG();
450 std::lock_guard<std::mutex> lock(mutex_);
451 if (!channelClient_) {
452 HILOG_ERROR("The channel is invalid.");
453 return RET_ERR_NO_CONNECTION;
454 }
455
456 int32_t windowId = parent.GetWindowId();
457 int32_t childId = parent.GetChildId(index);
458 HILOG_INFO("windowId[%{public}d], childId[%{public}d]", windowId, childId);
459 if (childId == -1) {
460 HILOG_ERROR("childId[%{public}d] is invalid", childId);
461 return RET_ERR_INVALID_PARAM;
462 }
463 if (GetCacheElementInfo(windowId, childId, child)) {
464 HILOG_DEBUG("get element info from cache");
465 return RET_OK;
466 }
467
468 return SearchElementInfoFromAce(windowId, childId, cacheMode_, child);
469 }
470
GetChildren(const AccessibilityElementInfo & parent,std::vector<AccessibilityElementInfo> & children)471 RetError AccessibleAbilityClientImpl::GetChildren(const AccessibilityElementInfo &parent,
472 std::vector<AccessibilityElementInfo> &children)
473 {
474 HILOG_DEBUG();
475 std::lock_guard<std::mutex> lock(mutex_);
476 if (!channelClient_) {
477 HILOG_ERROR("The channel is invalid.");
478 return RET_ERR_NO_CONNECTION;
479 }
480
481 int32_t windowId = parent.GetWindowId();
482 std::vector<int32_t> childIds = parent.GetChildIds();
483 HILOG_INFO("windowId[%{public}d], childIds.size[%{public}zu]", windowId, childIds.size());
484 for (auto &childId : childIds) {
485 HILOG_DEBUG("childId[%{public}d]", childId);
486 if (childId == -1) {
487 HILOG_ERROR("childId is invalid");
488 return RET_ERR_INVALID_PARAM;
489 }
490
491 AccessibilityElementInfo child;
492 if (GetCacheElementInfo(windowId, childId, child)) {
493 HILOG_DEBUG("get element info from cache");
494 children.emplace_back(child);
495 continue;
496 }
497
498 RetError ret = SearchElementInfoFromAce(windowId, childId, cacheMode_, child);
499 if (ret != RET_OK) {
500 HILOG_ERROR("Get element info from ace failed");
501 return ret;
502 }
503 children.emplace_back(child);
504 }
505 return RET_OK;
506 }
507
GetByContent(const AccessibilityElementInfo & elementInfo,const std::string & text,std::vector<AccessibilityElementInfo> & elementInfos)508 RetError AccessibleAbilityClientImpl::GetByContent(const AccessibilityElementInfo &elementInfo,
509 const std::string &text, std::vector<AccessibilityElementInfo> &elementInfos)
510 {
511 HILOG_DEBUG();
512 std::lock_guard<std::mutex> lock(mutex_);
513 if (!channelClient_) {
514 HILOG_ERROR("The channel is invalid.");
515 return RET_ERR_NO_CONNECTION;
516 }
517 int32_t windowId = elementInfo.GetWindowId();
518 int32_t elementId = elementInfo.GetAccessibilityId();
519 HILOG_INFO("windowId[%{public}d], elementId[%{public}d], text[%{public}s]", windowId, elementId, text.c_str());
520 return channelClient_->SearchElementInfosByText(windowId, elementId, text, elementInfos);
521 }
522
GetSource(const AccessibilityEventInfo & eventInfo,AccessibilityElementInfo & elementInfo)523 RetError AccessibleAbilityClientImpl::GetSource(const AccessibilityEventInfo &eventInfo,
524 AccessibilityElementInfo &elementInfo)
525 {
526 HILOG_DEBUG();
527 std::lock_guard<std::mutex> lock(mutex_);
528 if (!channelClient_) {
529 HILOG_ERROR("The channel is invalid.");
530 return RET_ERR_NO_CONNECTION;
531 }
532 int32_t windowId = eventInfo.GetWindowId();
533 int32_t elementId = eventInfo.GetAccessibilityId();
534 HILOG_INFO("windowId[%{public}d], elementId[%{public}d]", windowId, elementId);
535 if (GetCacheElementInfo(windowId, elementId, elementInfo)) {
536 HILOG_DEBUG("get element info from cache");
537 return RET_OK;
538 }
539 return SearchElementInfoFromAce(windowId, elementId, cacheMode_, elementInfo);
540 }
541
GetParentElementInfo(const AccessibilityElementInfo & child,AccessibilityElementInfo & parent)542 RetError AccessibleAbilityClientImpl::GetParentElementInfo(const AccessibilityElementInfo &child,
543 AccessibilityElementInfo &parent)
544 {
545 HILOG_DEBUG();
546 std::lock_guard<std::mutex> lock(mutex_);
547 if (!channelClient_) {
548 HILOG_ERROR("The channel is invalid.");
549 return RET_ERR_NO_CONNECTION;
550 }
551 int32_t windowId = child.GetWindowId();
552 int32_t elementId = child.GetParentNodeId();
553 HILOG_INFO("windowId[%{public}d], parentId[%{public}d]", windowId, elementId);
554 if (GetCacheElementInfo(windowId, elementId, parent)) {
555 HILOG_DEBUG("get element info from cache");
556 return RET_OK;
557 }
558
559 return SearchElementInfoFromAce(windowId, elementId, cacheMode_, parent);
560 }
561
ExecuteAction(const AccessibilityElementInfo & elementInfo,const ActionType action,const std::map<std::string,std::string> & actionArguments)562 RetError AccessibleAbilityClientImpl::ExecuteAction(const AccessibilityElementInfo &elementInfo,
563 const ActionType action, const std::map<std::string, std::string> &actionArguments)
564 {
565 HILOG_DEBUG();
566 std::lock_guard<std::mutex> lock(mutex_);
567 if (!channelClient_) {
568 HILOG_ERROR("The channel is invalid.");
569 return RET_ERR_NO_CONNECTION;
570 }
571 if (action == ACCESSIBILITY_ACTION_INVALID) {
572 HILOG_ERROR("action is invalid.");
573 return RET_ERR_INVALID_PARAM;
574 }
575 int32_t windowId = elementInfo.GetWindowId();
576 int32_t elementId = elementInfo.GetAccessibilityId();
577 HILOG_INFO("windowId[%{public}d], elementId[%{public}d], action[%{public}d", windowId, elementId, action);
578 return channelClient_->ExecuteAction(windowId, elementId, action,
579 const_cast<std::map<std::string, std::string> &>(actionArguments));
580 }
581
SetTargetBundleName(const std::vector<std::string> & targetBundleNames)582 RetError AccessibleAbilityClientImpl::SetTargetBundleName(const std::vector<std::string> &targetBundleNames)
583 {
584 HILOG_INFO("targetBundleNames size[%{public}zu]", targetBundleNames.size());
585 std::lock_guard<std::mutex> lock(mutex_);
586 if (!channelClient_) {
587 HILOG_ERROR("The channel is invalid.");
588 return RET_ERR_NO_CONNECTION;
589 }
590 return channelClient_->SetTargetBundleName(targetBundleNames);
591 }
592
OnRemoteDied(const wptr<IRemoteObject> & remote)593 void AccessibleAbilityClientImpl::AccessibleAbilityDeathRecipient::OnRemoteDied(const wptr<IRemoteObject>& remote)
594 {
595 HILOG_ERROR();
596 client_.ResetAAClient(remote);
597 }
598
OnRemoteDied(const wptr<IRemoteObject> & remote)599 void AccessibleAbilityClientImpl::AccessibilityServiceDeathRecipient::OnRemoteDied(const wptr<IRemoteObject>& remote)
600 {
601 HILOG_ERROR();
602 client_.NotifyServiceDied(remote);
603 }
604
NotifyServiceDied(const wptr<IRemoteObject> & remote)605 void AccessibleAbilityClientImpl::NotifyServiceDied(const wptr<IRemoteObject> &remote)
606 {
607 std::shared_ptr<AccessibleAbilityListener> listener = nullptr;
608 {
609 std::lock_guard<std::mutex> lock(mutex_);
610 if (!serviceProxy_) {
611 HILOG_ERROR("serviceProxy_ is nullptr");
612 return;
613 }
614 sptr<IRemoteObject> object = serviceProxy_->AsObject();
615 if (object && (remote == object)) {
616 listener = listener_;
617 listener_ = nullptr;
618
619 object->RemoveDeathRecipient(accessibilityServiceDeathRecipient_);
620 serviceProxy_ = nullptr;
621 channelClient_ = nullptr;
622 HILOG_DEBUG("ResetAAClient OK");
623 }
624 }
625
626 if (listener) {
627 listener->OnAbilityDisconnected();
628 }
629 }
630
ResetAAClient(const wptr<IRemoteObject> & remote)631 void AccessibleAbilityClientImpl::ResetAAClient(const wptr<IRemoteObject> &remote)
632 {
633 HILOG_DEBUG();
634 std::lock_guard<std::mutex> lock(mutex_);
635 if (channelClient_) {
636 sptr<IRemoteObject> object = channelClient_->GetRemote();
637 if (object && (remote == object)) {
638 object->RemoveDeathRecipient(deathRecipient_);
639 channelClient_ = nullptr;
640 HILOG_DEBUG("ResetAAClient OK");
641 }
642 }
643 }
644
SetCacheMode(const int32_t cacheMode)645 RetError AccessibleAbilityClientImpl::SetCacheMode(const int32_t cacheMode)
646 {
647 HILOG_INFO("set cache mode: [%{public}d]", cacheMode);
648 std::lock_guard<std::mutex> lock(mutex_);
649 cacheWindowId_ = -1;
650 cacheElementInfos_.clear();
651 if (cacheMode < 0) {
652 cacheMode_ = 0;
653 } else {
654 uint32_t mode = static_cast<uint32_t>(cacheMode);
655 cacheMode_ = mode & static_cast<uint32_t>(GET_SOURCE_PREFETCH_MODE);
656 }
657 return RET_OK;
658 }
659
GetCacheElementInfo(const int32_t windowId,const int32_t elementId,AccessibilityElementInfo & elementInfo) const660 bool AccessibleAbilityClientImpl::GetCacheElementInfo(const int32_t windowId,
661 const int32_t elementId, AccessibilityElementInfo &elementInfo) const
662 {
663 HILOG_DEBUG();
664 if (cacheWindowId_ == -1 || cacheWindowId_ != windowId) {
665 HILOG_DEBUG("cacheWindowId[%{public}d], windowId[%{public}d]", cacheWindowId_, windowId);
666 return false;
667 }
668
669 auto iter = cacheElementInfos_.find(elementId);
670 if (iter == cacheElementInfos_.end()) {
671 HILOG_DEBUG("the element id[%{public}d] is not in cache", elementId);
672 return false;
673 }
674
675 elementInfo = iter->second;
676 return true;
677 }
678
SetCacheElementInfo(const int32_t windowId,const std::vector<OHOS::Accessibility::AccessibilityElementInfo> & elementInfos)679 void AccessibleAbilityClientImpl::SetCacheElementInfo(const int32_t windowId,
680 const std::vector<OHOS::Accessibility::AccessibilityElementInfo> &elementInfos)
681 {
682 HILOG_DEBUG("windowId[%{public}d], elementInfos size[%{public}zu]", windowId, elementInfos.size());
683 cacheElementInfos_.clear();
684 cacheWindowId_ = windowId;
685 for (auto &elementInfo : elementInfos) {
686 cacheElementInfos_.insert(std::make_pair(elementInfo.GetAccessibilityId(), elementInfo));
687 }
688 }
689
SearchElementInfoFromAce(const int32_t windowId,const int32_t elementId,const uint32_t mode,AccessibilityElementInfo & info)690 RetError AccessibleAbilityClientImpl::SearchElementInfoFromAce(const int32_t windowId, const int32_t elementId,
691 const uint32_t mode, AccessibilityElementInfo &info)
692 {
693 if (!channelClient_) {
694 HILOG_ERROR("The channel is invalid.");
695 return RET_ERR_NO_CONNECTION;
696 }
697
698 std::vector<AccessibilityElementInfo> elementInfos {};
699
700 RetError ret = channelClient_->SearchElementInfosByAccessibilityId(
701 windowId, elementId, static_cast<int32_t>(mode), elementInfos);
702 if (ret != RET_OK) {
703 HILOG_ERROR("search element info failed. windowId[%{public}d] elementId[%{public}d] mode[%{public}d]",
704 windowId, elementId, mode);
705 return ret;
706 }
707 if (elementInfos.empty()) {
708 HILOG_ERROR("elementInfos from ace is empty");
709 return RET_ERR_INVALID_ELEMENT_INFO_FROM_ACE;
710 }
711
712 HILOG_DEBUG("element [elementSize:%{public}zu]", elementInfos.size());
713 SetCacheElementInfo(windowId, elementInfos);
714 info = elementInfos.front();
715 return RET_OK;
716 }
717
Connect()718 RetError AccessibleAbilityClientImpl::Connect()
719 {
720 HILOG_DEBUG();
721 std::lock_guard<std::mutex> lock(mutex_);
722 if (!serviceProxy_) {
723 HILOG_ERROR("Failed to get aams service");
724 return RET_ERR_SAMGR;
725 }
726
727 return serviceProxy_->EnableUITestAbility(this->AsObject());
728 }
729
Disconnect()730 RetError AccessibleAbilityClientImpl::Disconnect()
731 {
732 HILOG_DEBUG();
733 std::lock_guard<std::mutex> lock(mutex_);
734 if (!serviceProxy_) {
735 HILOG_ERROR("Failed to get aams service");
736 return RET_ERR_SAMGR;
737 }
738 return serviceProxy_->DisableUITestAbility();
739 }
740 } // namespace Accessibility
741 } // namespace OHOS