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
30 namespace OHOS {
31 namespace Accessibility {
32 // tmp: wait for window registing when client connect done
33 constexpr int WAIT_WINDOW_REGIST = 500;
34 constexpr int64_t ROOT_PARENT_ELEMENT_ID = -2100000;
35 const int32_t ROOT_TREE_ID = 0;
36 constexpr uint64_t ELEMENT_MOVE_BIT = 40;
37 namespace {
38 const std::string SYSTEM_PARAMETER_AAMS_SERVICE = "accessibility.config.ready";
39 constexpr int32_t CONFIG_PARAMETER_VALUE_SIZE = 10;
40 constexpr int64_t ROOT_NONE_ID = -1;
41 constexpr int64_t NODE_ID_MAX = 0x7FFFFFFE;
42 std::mutex g_Mutex;
43 sptr<AccessibleAbilityClientImpl> g_Instance = nullptr;
44 constexpr int32_t SA_CONNECT_TIMEOUT = 500; // ms
45 } // namespace
46
GetInstance()47 sptr<AccessibleAbilityClient> AccessibleAbilityClient::GetInstance()
48 {
49 HILOG_DEBUG();
50 std::lock_guard<std::mutex> lock(g_Mutex);
51 if (g_Instance == nullptr) {
52 g_Instance = new(std::nothrow) AccessibleAbilityClientImpl();
53 }
54 return g_Instance;
55 }
56
GetAbilityClientImplement()57 sptr<AccessibleAbilityClientImpl> AccessibleAbilityClientImpl::GetAbilityClientImplement()
58 {
59 HILOG_DEBUG();
60 std::lock_guard<std::mutex> lock(g_Mutex);
61 if (g_Instance == nullptr) {
62 g_Instance = new(std::nothrow) AccessibleAbilityClientImpl();
63 }
64 return g_Instance;
65 }
66
AccessibleAbilityClientImpl()67 AccessibleAbilityClientImpl::AccessibleAbilityClientImpl()
68 {
69 HILOG_DEBUG();
70 if (!InitAccessibilityServiceProxy()) {
71 HILOG_ERROR("Init accessibility service proxy failed");
72 }
73
74 int retSysParam = WatchParameter(SYSTEM_PARAMETER_AAMS_SERVICE.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_ != nullptr) {
94 HILOG_DEBUG("Accessibility Service is connected");
95 return true;
96 }
97
98 sptr<ISystemAbilityManager> samgr = SystemAbilityManagerClient::GetInstance().GetSystemAbilityManager();
99 if (samgr == nullptr) {
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 != nullptr) {
107 if (!accessibilityServiceDeathRecipient_) {
108 accessibilityServiceDeathRecipient_ = new(std::nothrow) AccessibilityServiceDeathRecipient(*this);
109 if (!accessibilityServiceDeathRecipient_) {
110 HILOG_ERROR("Failed to create service deathRecipient.");
111 return false;
112 }
113 }
114 serviceProxy_ = iface_cast<IAccessibleAbilityManagerService>(object);
115 if (serviceProxy_ == nullptr) {
116 HILOG_ERROR("InitAccessibilityServiceProxy failed.");
117 return false;
118 }
119 if (serviceProxy_->AsObject() &&
120 serviceProxy_->AsObject()->AddDeathRecipient(accessibilityServiceDeathRecipient_)) {
121 return true;
122 }
123 } else {
124 if (LoadAccessibilityService() == false) {
125 HILOG_ERROR("LoadAccessibilityService failed.");
126 return false;
127 } else {
128 return true;
129 }
130 }
131 return false;
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 if (key == nullptr || std::strcmp(key, SYSTEM_PARAMETER_AAMS_SERVICE.c_str())) {
137 return;
138 }
139 if (value == nullptr || std::strcmp(value, "true")) {
140 return;
141 }
142 if (context == nullptr) {
143 return;
144 }
145
146 AccessibleAbilityClientImpl *implPtr = static_cast<AccessibleAbilityClientImpl *>(context);
147 std::lock_guard<std::mutex> lock(implPtr->mutex_);
148 if (implPtr->InitAccessibilityServiceProxy()) {
149 HILOG_INFO("InitAccessibilityServiceProxy success");
150 }
151 }
152
GetServiceProxy()153 sptr<Accessibility::IAccessibleAbilityManagerService> AccessibleAbilityClientImpl::GetServiceProxy()
154 {
155 if (serviceProxy_ || LoadAccessibilityService()) {
156 return serviceProxy_;
157 }
158 return nullptr;
159 }
160
LoadAccessibilityService()161 bool AccessibleAbilityClientImpl::LoadAccessibilityService()
162 {
163 std::unique_lock<std::mutex> lock(conVarMutex_);
164 sptr<AccessibilityLoadCallback> loadCallback = new AccessibilityLoadCallback();
165 if (loadCallback == nullptr) {
166 return false;
167 }
168 auto samgr = SystemAbilityManagerClient::GetInstance().GetSystemAbilityManager();
169 if (samgr == nullptr) {
170 return false;
171 }
172 int32_t ret = samgr->LoadSystemAbility(ACCESSIBILITY_MANAGER_SERVICE_ID, loadCallback);
173 if (ret != 0) {
174 return false;
175 }
176 auto waitStatus = proxyConVar_.wait_for(lock, std::chrono::milliseconds(SA_CONNECT_TIMEOUT),
177 [this]() { return serviceProxy_ != nullptr; });
178 if (!waitStatus) {
179 return false;
180 }
181 return true;
182 }
183
LoadSystemAbilitySuccess(const sptr<IRemoteObject> & remoteObject)184 void AccessibleAbilityClientImpl::LoadSystemAbilitySuccess(const sptr<IRemoteObject> &remoteObject)
185 {
186 std::lock_guard<std::mutex> lock(conVarMutex_);
187 char value[CONFIG_PARAMETER_VALUE_SIZE] = "default";
188 int retSysParam = GetParameter(SYSTEM_PARAMETER_AAMS_SERVICE.c_str(), "false", value, CONFIG_PARAMETER_VALUE_SIZE);
189 if (retSysParam >= 0 && !std::strcmp(value, "true")) {
190 if (InitAccessibilityServiceProxy() == false) {
191 HILOG_ERROR("Init accessibility service proxy failed");
192 }
193 }
194 proxyConVar_.notify_one();
195 }
196
LoadSystemAbilityFail()197 void AccessibleAbilityClientImpl::LoadSystemAbilityFail()
198 {
199 std::lock_guard<std::mutex> lock(conVarMutex_);
200 HILOG_WARN("LoadSystemAbilityFail.");
201 proxyConVar_.notify_one();
202 }
203
GetRemoteObject()204 sptr<IRemoteObject> AccessibleAbilityClientImpl::GetRemoteObject()
205 {
206 HILOG_DEBUG();
207 return this->AsObject();
208 }
209
RegisterAbilityListener(const std::shared_ptr<AccessibleAbilityListener> & listener)210 RetError AccessibleAbilityClientImpl::RegisterAbilityListener(
211 const std::shared_ptr<AccessibleAbilityListener> &listener)
212 {
213 HILOG_DEBUG();
214 std::lock_guard<std::mutex> lock(mutex_);
215 if (listener_) {
216 HILOG_DEBUG("listener already exists.");
217 return RET_ERR_REGISTER_EXIST;
218 }
219
220 listener_ = listener;
221 return RET_OK;
222 }
223
Init(const sptr<IAccessibleAbilityChannel> & channel,const int32_t channelId)224 void AccessibleAbilityClientImpl::Init(const sptr<IAccessibleAbilityChannel> &channel, const int32_t channelId)
225 {
226 HILOG_DEBUG("channelId[%{public}d]", channelId);
227 if (!channel || channelId == INVALID_CHANNEL_ID) {
228 HILOG_ERROR("channel is nullptr, or channelId is invalid");
229 return;
230 }
231
232 std::shared_ptr<AccessibleAbilityListener> listener = nullptr;
233 {
234 std::lock_guard<std::mutex> lock(mutex_);
235 if (!listener_) {
236 HILOG_ERROR("listener_ is nullptr.");
237 return;
238 }
239 listener = listener_;
240 channelClient_ = std::make_shared<AccessibleAbilityChannelClient>(channelId, channel);
241
242 // Add death recipient
243 if (!deathRecipient_) {
244 deathRecipient_ = new(std::nothrow) AccessibleAbilityDeathRecipient(*this);
245 if (!deathRecipient_) {
246 HILOG_ERROR("Failed to create deathRecipient.");
247 return;
248 }
249 }
250
251 if (channel->AsObject()) {
252 HILOG_DEBUG("Add death recipient");
253 channel->AsObject()->AddDeathRecipient(deathRecipient_);
254 }
255 }
256
257 isConnected_ = true;
258 std::this_thread::sleep_for(std::chrono::milliseconds(WAIT_WINDOW_REGIST));
259 if (listener) {
260 listener->OnAbilityConnected();
261 }
262 }
263
Disconnect(const int32_t channelId)264 void AccessibleAbilityClientImpl::Disconnect(const int32_t channelId)
265 {
266 HILOG_DEBUG("channelId[%{public}d]", channelId);
267
268 std::shared_ptr<AccessibleAbilityListener> listener = nullptr;
269 {
270 isConnected_ = false;
271 std::lock_guard<std::mutex> lock(mutex_);
272 // Delete death recipient
273 if (channelClient_ && channelClient_->GetRemote()) {
274 HILOG_ERROR("Remove death recipient");
275 channelClient_->GetRemote()->RemoveDeathRecipient(deathRecipient_);
276 }
277
278 // Remove channel
279 channelClient_ = nullptr;
280 listener = listener_;
281 listener_ = nullptr;
282 }
283
284 if (listener) {
285 listener->OnAbilityDisconnected();
286 }
287 }
288
OnAccessibilityEvent(const AccessibilityEventInfo & eventInfo)289 void AccessibleAbilityClientImpl::OnAccessibilityEvent(const AccessibilityEventInfo &eventInfo)
290 {
291 HILOG_DEBUG();
292 std::shared_ptr<AccessibleAbilityListener> listener = nullptr;
293 {
294 std::lock_guard<std::mutex> lock(mutex_);
295 if (!channelClient_) {
296 HILOG_ERROR("The channel is invalid.");
297 return;
298 }
299 listener = listener_;
300 }
301 if (listener) {
302 listener->OnAccessibilityEvent(eventInfo);
303 }
304 }
305
OnKeyPressEvent(const MMI::KeyEvent & keyEvent,const int32_t sequence)306 void AccessibleAbilityClientImpl::OnKeyPressEvent(const MMI::KeyEvent &keyEvent, const int32_t sequence)
307 {
308 HILOG_DEBUG("sequence[%{public}d]", sequence);
309 std::shared_ptr<AccessibleAbilityListener> listener = nullptr;
310 std::shared_ptr<AccessibleAbilityChannelClient> channel = nullptr;
311 {
312 std::lock_guard<std::mutex> lock(mutex_);
313 listener = listener_;
314 channel = channelClient_;
315 }
316
317 if (!channel) {
318 HILOG_ERROR("The channel is invalid.");
319 return;
320 }
321 bool handled = false;
322 if (listener) {
323 std::shared_ptr<MMI::KeyEvent> tmp = std::make_shared<MMI::KeyEvent>(keyEvent);
324 handled = listener->OnKeyPressEvent(tmp);
325 }
326 channel->SetOnKeyPressEventResult(handled, sequence);
327 }
328
GetFocus(const int32_t focusType,AccessibilityElementInfo & elementInfo)329 RetError AccessibleAbilityClientImpl::GetFocus(const int32_t focusType, AccessibilityElementInfo &elementInfo)
330 {
331 HILOG_DEBUG("focusType[%{public}d]", focusType);
332 if (!isConnected_) {
333 HILOG_ERROR("connection is broken");
334 return RET_ERR_NO_CONNECTION;
335 }
336
337 std::lock_guard<std::mutex> lock(mutex_);
338 if ((focusType != FOCUS_TYPE_INPUT) && (focusType != FOCUS_TYPE_ACCESSIBILITY)) {
339 HILOG_ERROR("focusType is not allowed.");
340 return RET_ERR_INVALID_PARAM;
341 }
342
343 if (!channelClient_) {
344 HILOG_ERROR("The channel is invalid.");
345 return RET_ERR_NO_CONNECTION;
346 }
347
348 return channelClient_->FindFocusedElementInfo(ANY_WINDOW_ID, ROOT_NODE_ID, focusType, elementInfo);
349 }
350
GetFocusByElementInfo(const AccessibilityElementInfo & sourceInfo,const int32_t focusType,AccessibilityElementInfo & elementInfo)351 RetError AccessibleAbilityClientImpl::GetFocusByElementInfo(const AccessibilityElementInfo &sourceInfo,
352 const int32_t focusType, AccessibilityElementInfo &elementInfo)
353 {
354 HILOG_DEBUG("focusType[%{public}d]", focusType);
355 if (!isConnected_) {
356 HILOG_ERROR("connection is broken");
357 return RET_ERR_NO_CONNECTION;
358 }
359
360 std::lock_guard<std::mutex> lock(mutex_);
361 if ((focusType != FOCUS_TYPE_INPUT) && (focusType != FOCUS_TYPE_ACCESSIBILITY)) {
362 HILOG_ERROR("focusType is not allowed.");
363 return RET_ERR_INVALID_PARAM;
364 }
365
366 if (!channelClient_) {
367 HILOG_ERROR("The channel is invalid.");
368 return RET_ERR_NO_CONNECTION;
369 }
370
371 int32_t windowId = sourceInfo.GetWindowId();
372 int64_t elementId = sourceInfo.GetAccessibilityId();
373 HILOG_DEBUG("windowId[%{public}d], elementId[%{public}" PRId64 "], focusType[%{public}d]",
374 windowId, elementId, focusType);
375
376 return channelClient_->FindFocusedElementInfo(windowId, elementId, focusType, elementInfo);
377 }
378
InjectGesture(const std::shared_ptr<AccessibilityGestureInjectPath> & gesturePath)379 RetError AccessibleAbilityClientImpl::InjectGesture(const std::shared_ptr<AccessibilityGestureInjectPath> &gesturePath)
380 {
381 HILOG_DEBUG();
382 if (!isConnected_) {
383 HILOG_ERROR("connection is broken");
384 return RET_ERR_NO_CONNECTION;
385 }
386
387 std::lock_guard<std::mutex> lock(mutex_);
388 if (!gesturePath) {
389 HILOG_ERROR("The gesturePath is null.");
390 return RET_ERR_INVALID_PARAM;
391 }
392
393 std::vector<AccessibilityGesturePosition> positions = gesturePath->GetPositions();
394
395 if (positions.size() == 0) {
396 HILOG_ERROR("The number of gesture path position is not allowed.");
397 return RET_ERR_INVALID_PARAM;
398 }
399
400 if (!channelClient_) {
401 HILOG_ERROR("The channel is invalid.");
402 return RET_ERR_NO_CONNECTION;
403 }
404
405 return channelClient_->SendSimulateGesture(gesturePath);
406 }
407
GetRoot(AccessibilityElementInfo & elementInfo)408 RetError AccessibleAbilityClientImpl::GetRoot(AccessibilityElementInfo &elementInfo)
409 {
410 HILOG_DEBUG();
411 if (!isConnected_) {
412 HILOG_ERROR("connection is broken");
413 return RET_ERR_NO_CONNECTION;
414 }
415
416 std::lock_guard<std::mutex> lock(mutex_);
417 if (serviceProxy_ == nullptr && !LoadAccessibilityService()) {
418 HILOG_ERROR("Failed to connect to aams");
419 return RET_ERR_SAMGR;
420 }
421
422 if (serviceProxy_ == nullptr) {
423 HILOG_ERROR("Failed to connect to aams");
424 return RET_ERR_SAMGR;
425 }
426
427 if (!channelClient_) {
428 HILOG_ERROR("The channel is invalid.");
429 return RET_ERR_NO_CONNECTION;
430 }
431
432 int32_t activeWindow = serviceProxy_->GetActiveWindow();
433 HILOG_DEBUG("activeWindow[%{public}d]", activeWindow);
434 if (GetCacheElementInfo(activeWindow, ROOT_NONE_ID, elementInfo)) {
435 HILOG_DEBUG("get element info from cache");
436 return RET_OK;
437 }
438
439 return SearchElementInfoFromAce(activeWindow, ROOT_NONE_ID, cacheMode_, elementInfo);
440 }
441
GetRootByWindow(const AccessibilityWindowInfo & windowInfo,AccessibilityElementInfo & elementInfo)442 RetError AccessibleAbilityClientImpl::GetRootByWindow(const AccessibilityWindowInfo &windowInfo,
443 AccessibilityElementInfo &elementInfo)
444 {
445 HILOG_DEBUG();
446 if (!isConnected_) {
447 HILOG_ERROR("connection is broken");
448 return RET_ERR_NO_CONNECTION;
449 }
450
451 std::lock_guard<std::mutex> lock(mutex_);
452 if (!channelClient_) {
453 HILOG_ERROR("The channel is invalid.");
454 return RET_ERR_NO_CONNECTION;
455 }
456
457 int32_t windowId = windowInfo.GetWindowId();
458 HILOG_DEBUG("windowId[%{public}d]", windowId);
459 if (GetCacheElementInfo(windowId, ROOT_NONE_ID, elementInfo)) {
460 HILOG_DEBUG("get element info from cache");
461 return RET_OK;
462 }
463
464 return SearchElementInfoFromAce(windowId, ROOT_NONE_ID, cacheMode_, elementInfo);
465 }
466
GetWindow(const int32_t windowId,AccessibilityWindowInfo & windowInfo)467 RetError AccessibleAbilityClientImpl::GetWindow(const int32_t windowId, AccessibilityWindowInfo &windowInfo)
468 {
469 HILOG_DEBUG("windowId[%{public}d]", windowId);
470 if (!isConnected_) {
471 HILOG_ERROR("connection is broken");
472 return RET_ERR_NO_CONNECTION;
473 }
474
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 return channelClient_->GetWindow(windowId, windowInfo);
481 }
482
GetRootBatch(std::vector<AccessibilityElementInfo> & elementInfos)483 RetError AccessibleAbilityClientImpl::GetRootBatch(std::vector<AccessibilityElementInfo>& elementInfos)
484 {
485 HILOG_DEBUG();
486 if (!isConnected_) {
487 HILOG_ERROR("connection is broken");
488 return RET_ERR_NO_CONNECTION;
489 }
490
491 std::lock_guard<std::mutex> lock(mutex_);
492 if (!channelClient_) {
493 HILOG_ERROR("channel is invalid.");
494 return RET_ERR_NO_CONNECTION;
495 }
496
497 if (serviceProxy_ == nullptr && !LoadAccessibilityService()) {
498 HILOG_ERROR("failed to connect to aams");
499 return RET_ERR_SAMGR;
500 }
501
502 if (serviceProxy_ == nullptr) {
503 HILOG_ERROR("Failed to connect to aams");
504 return RET_ERR_SAMGR;
505 }
506
507 int32_t windowId = serviceProxy_->GetActiveWindow();
508 int64_t elementId = ROOT_NONE_ID;
509 RetError ret = SearchElementInfoRecursiveByWinid(windowId, elementId, PREFETCH_RECURSIVE_CHILDREN,
510 elementInfos, ROOT_TREE_ID);
511 if (ret != RET_OK) {
512 HILOG_ERROR("get window element failed.");
513 return ret;
514 }
515 return RET_OK;
516 }
517
SortElementInfosIfNecessary(std::vector<AccessibilityElementInfo> & elementInfos)518 void AccessibleAbilityClientImpl::SortElementInfosIfNecessary(std::vector<AccessibilityElementInfo> &elementInfos)
519 {
520 HILOG_DEBUG();
521 std::map<int64_t, std::shared_ptr<AccessibilityElementInfo>> elementInfosMap;
522 std::vector<AccessibilityElementInfo> sortedElementInfos;
523 int64_t nodeId = NODE_ID_MAX;
524 int32_t count = 1;
525 AccessibilityElementInfo virtualRoot = elementInfos.front();
526 if (virtualRoot.GetAccessibilityId() != NODE_ID_MAX) {
527 return;
528 }
529 elementInfos.erase(elementInfos.begin());
530 for (auto &element : elementInfos) {
531 if (element.GetAccessibilityId() == NODE_ID_MAX) {
532 nodeId = NODE_ID_MAX - count;
533 element.SetAccessibilityId(nodeId);
534 element.SetParent(NODE_ID_MAX);
535 virtualRoot.AddChild(nodeId);
536 count += 1;
537 }
538 nodeId = element.GetAccessibilityId();
539 elementInfosMap[nodeId] = std::make_shared<AccessibilityElementInfo>(element);
540 }
541 elementInfosMap[NODE_ID_MAX] = std::make_shared<AccessibilityElementInfo>(virtualRoot);
542
543 std::vector<int64_t> elementList;
544 elementList.push_back(NODE_ID_MAX);
545 uint32_t index = 0;
546 while (index < elementList.size()) {
547 auto iter = elementInfosMap.find(elementList[index]);
548 if (iter == elementInfosMap.end()) {
549 sortedElementInfos.clear();
550 elementInfos.insert(elementInfos.begin(), virtualRoot);
551 return;
552 }
553 sortedElementInfos.push_back(*(iter->second));
554 std::vector<int64_t> childNodeIds = iter->second->GetChildIds();
555 for (auto &id : childNodeIds) {
556 if (std::find(elementList.begin(), elementList.end(), id) == elementList.end()) {
557 elementList.push_back(id);
558 }
559 }
560 index++;
561 }
562
563 if (static_cast<int32_t>(sortedElementInfos.size()) > 0) {
564 elementInfos = sortedElementInfos;
565 }
566 elementInfosMap.clear();
567 }
568
GetRootByWindowBatch(const AccessibilityWindowInfo & windowInfo,std::vector<AccessibilityElementInfo> & elementInfos,bool isFilter)569 RetError AccessibleAbilityClientImpl::GetRootByWindowBatch(const AccessibilityWindowInfo &windowInfo,
570 std::vector<AccessibilityElementInfo>& elementInfos, bool isFilter)
571 {
572 HILOG_DEBUG("GetRootByWindowBatch %{public}d", windowInfo.GetWindowId());
573 if (!isConnected_) {
574 HILOG_ERROR("connection is broken");
575 return RET_ERR_NO_CONNECTION;
576 }
577
578 std::lock_guard<std::mutex> lock(mutex_);
579 if (serviceProxy_ == nullptr && !LoadAccessibilityService()) {
580 HILOG_ERROR("failed to connect to aams");
581 return RET_ERR_SAMGR;
582 }
583
584 if (!channelClient_) {
585 HILOG_ERROR("channel is invalid.");
586 return RET_ERR_NO_CONNECTION;
587 }
588
589 int32_t windowId = windowInfo.GetWindowId();
590 int64_t elementId = ROOT_NONE_ID;
591 RetError ret = SearchElementInfoRecursiveByWinid(windowId, elementId,
592 PREFETCH_RECURSIVE_CHILDREN, elementInfos, ROOT_TREE_ID, isFilter);
593 if (ret != RET_OK) {
594 HILOG_ERROR("get window element failed");
595 return ret;
596 }
597 return RET_OK;
598 }
599
GetWindows(std::vector<AccessibilityWindowInfo> & windows)600 RetError AccessibleAbilityClientImpl::GetWindows(std::vector<AccessibilityWindowInfo> &windows)
601 {
602 HILOG_DEBUG();
603 if (!isConnected_) {
604 HILOG_ERROR("connection is broken");
605 return RET_ERR_NO_CONNECTION;
606 }
607
608 std::lock_guard<std::mutex> lock(mutex_);
609 if (!channelClient_) {
610 HILOG_ERROR("The channel is invalid.");
611 return RET_ERR_NO_CONNECTION;
612 }
613 return channelClient_->GetWindows(windows);
614 }
615
GetWindows(const uint64_t displayId,std::vector<AccessibilityWindowInfo> & windows)616 RetError AccessibleAbilityClientImpl::GetWindows(const uint64_t displayId,
617 std::vector<AccessibilityWindowInfo> &windows)
618 {
619 HILOG_DEBUG("displayId[%{public}" PRIu64 "]", displayId);
620 if (!isConnected_) {
621 HILOG_ERROR("connection is broken");
622 return RET_ERR_NO_CONNECTION;
623 }
624
625 std::lock_guard<std::mutex> lock(mutex_);
626 if (!channelClient_) {
627 HILOG_ERROR("The channel is invalid.");
628 return RET_ERR_NO_CONNECTION;
629 }
630 return channelClient_->GetWindows(displayId, windows);
631 }
632
GetNext(const AccessibilityElementInfo & elementInfo,const FocusMoveDirection direction,AccessibilityElementInfo & nextElementInfo)633 RetError AccessibleAbilityClientImpl::GetNext(const AccessibilityElementInfo &elementInfo,
634 const FocusMoveDirection direction, AccessibilityElementInfo &nextElementInfo)
635 {
636 HILOG_DEBUG("windowId[%{public}d], elementId[%{public}" PRId64 "], direction[%{public}d]",
637 elementInfo.GetWindowId(), elementInfo.GetAccessibilityId(), direction);
638 if (!isConnected_) {
639 HILOG_ERROR("connection is broken");
640 return RET_ERR_NO_CONNECTION;
641 }
642
643 std::lock_guard<std::mutex> lock(mutex_);
644 if (!channelClient_) {
645 HILOG_ERROR("The channel is invalid.");
646 return RET_ERR_NO_CONNECTION;
647 }
648 if (direction == DIRECTION_INVALID) {
649 HILOG_ERROR("direction is invalid.");
650 return RET_ERR_INVALID_PARAM;
651 }
652 return channelClient_->FocusMoveSearch(elementInfo.GetWindowId(),
653 elementInfo.GetAccessibilityId(), direction, nextElementInfo);
654 }
655
GetChildElementInfo(const int32_t index,const AccessibilityElementInfo & parent,AccessibilityElementInfo & child)656 RetError AccessibleAbilityClientImpl::GetChildElementInfo(const int32_t index, const AccessibilityElementInfo &parent,
657 AccessibilityElementInfo &child)
658 {
659 HILOG_DEBUG();
660 if (!isConnected_) {
661 HILOG_ERROR("connection is broken");
662 return RET_ERR_NO_CONNECTION;
663 }
664
665 std::lock_guard<std::mutex> lock(mutex_);
666 if (!channelClient_) {
667 HILOG_ERROR("The channel is invalid.");
668 return RET_ERR_NO_CONNECTION;
669 }
670
671 int32_t windowId = parent.GetWindowId();
672 int64_t childId = parent.GetChildId(index);
673 HILOG_DEBUG("windowId[%{public}d], childId[%{public}" PRId64 "]", windowId, childId);
674 if (childId == -1) {
675 HILOG_ERROR("childId[%{public}" PRId64 "] is invalid", childId);
676 return RET_ERR_INVALID_PARAM;
677 }
678 if (GetCacheElementInfo(windowId, childId, child)) {
679 HILOG_DEBUG("get element info from cache");
680 return RET_OK;
681 }
682
683 return SearchElementInfoFromAce(windowId, childId, cacheMode_, child);
684 }
685
GetChildren(const AccessibilityElementInfo & parent,std::vector<AccessibilityElementInfo> & children)686 RetError AccessibleAbilityClientImpl::GetChildren(const AccessibilityElementInfo &parent,
687 std::vector<AccessibilityElementInfo> &children)
688 {
689 HILOG_DEBUG();
690 if (!isConnected_) {
691 HILOG_ERROR("connection is broken");
692 return RET_ERR_NO_CONNECTION;
693 }
694 std::lock_guard<std::mutex> lock(mutex_);
695 if (!channelClient_) {
696 HILOG_ERROR("The channel is invalid.");
697 return RET_ERR_NO_CONNECTION;
698 }
699 int32_t windowId = parent.GetWindowId();
700 std::vector<int64_t> childIds = parent.GetChildIds();
701 RetError ret = RET_OK;
702 HILOG_DEBUG("windowId[%{public}d], childIds.size[%{public}zu] childTreeId:%{public}d",
703 windowId, childIds.size(), parent.GetChildTreeId());
704 if ((childIds.size() == 0) && (parent.GetChildWindowId() > 0 || parent.GetChildTreeId() > 0)) {
705 std::vector<AccessibilityElementInfo> elementInfos {};
706 if (parent.GetChildWindowId() > 0 && (parent.GetChildWindowId() != windowId)) {
707 ret = channelClient_->SearchElementInfosByAccessibilityId(parent.GetChildWindowId(), ROOT_NONE_ID,
708 GET_SOURCE_MODE, elementInfos, parent.GetChildTreeId());
709 } else if (parent.GetChildTreeId() > 0) {
710 ret = channelClient_->SearchElementInfosByAccessibilityId(parent.GetWindowId(), ROOT_NONE_ID,
711 GET_SOURCE_MODE, elementInfos, parent.GetChildTreeId());
712 }
713
714 if (ret != RET_OK) {
715 HILOG_ERROR("Get element info from ace failed");
716 return ret;
717 }
718 if (elementInfos.empty()) {
719 HILOG_ERROR("elementInfos from ace is empty");
720 return RET_ERR_INVALID_ELEMENT_INFO_FROM_ACE;
721 }
722 SortElementInfosIfNecessary(elementInfos);
723 children.emplace_back(elementInfos.front());
724 }
725 ret = GetChildrenWork(windowId, childIds, children);
726 return ret;
727 }
728
GetChildrenWork(const int32_t windowId,std::vector<int64_t> childIds,std::vector<AccessibilityElementInfo> & children)729 RetError AccessibleAbilityClientImpl::GetChildrenWork(const int32_t windowId, std::vector<int64_t> childIds,
730 std::vector<AccessibilityElementInfo> &children)
731 {
732 for (auto &childId : childIds) {
733 HILOG_DEBUG("childId[%{public}" PRId64 "]", childId);
734 if (childId == -1) {
735 HILOG_ERROR("childId is invalid");
736 return RET_ERR_INVALID_PARAM;
737 }
738 AccessibilityElementInfo child;
739 if (GetCacheElementInfo(windowId, childId, child)) {
740 HILOG_DEBUG("get element info from cache");
741 children.emplace_back(child);
742 continue;
743 }
744 RetError ret = SearchElementInfoFromAce(windowId, childId, cacheMode_, child);
745 if (ret != RET_OK) {
746 HILOG_ERROR("Get element info from ace failed");
747 return ret;
748 }
749 children.emplace_back(child);
750 }
751 return RET_OK;
752 }
753
GetByContent(const AccessibilityElementInfo & elementInfo,const std::string & text,std::vector<AccessibilityElementInfo> & elementInfos)754 RetError AccessibleAbilityClientImpl::GetByContent(const AccessibilityElementInfo &elementInfo,
755 const std::string &text, std::vector<AccessibilityElementInfo> &elementInfos)
756 {
757 HILOG_DEBUG();
758 if (!isConnected_) {
759 HILOG_ERROR("connection is broken");
760 return RET_ERR_NO_CONNECTION;
761 }
762
763 std::lock_guard<std::mutex> lock(mutex_);
764 if (!channelClient_) {
765 HILOG_ERROR("The channel is invalid.");
766 return RET_ERR_NO_CONNECTION;
767 }
768
769 int32_t windowId = elementInfo.GetWindowId();
770 int64_t elementId = elementInfo.GetAccessibilityId();
771 int32_t treeId = (static_cast<uint64_t>(elementId) >> ELEMENT_MOVE_BIT);
772 HILOG_DEBUG("windowId %{public}d, elementId %{public}" PRId64 ", text %{public}s",
773 windowId, elementId, text.c_str());
774 if (text != "") { // find element condition is null, so we will search all element info
775 RetError ret = channelClient_->SearchElementInfosByText(windowId, elementId, text, elementInfos);
776 if (ret != RET_OK) {
777 HILOG_ERROR("SearchElementInfosByText failed ret:%{public}d, windowId:%{public}d, text:%{public}s",
778 ret, windowId, text.c_str());
779 }
780 if (elementInfos.empty()) {
781 HILOG_DEBUG("SearchElementInfosByText get resilt size 0, begin SearchElementInfoRecursiveByWinid");
782 ret = SearchElementInfoRecursiveByContent(serviceProxy_->GetActiveWindow(),
783 elementId, GET_SOURCE_MODE, elementInfos, text, ROOT_TREE_ID);
784 if (ret != RET_OK) {
785 HILOG_ERROR("get window element info failed ret:%{public}d", ret);
786 return ret;
787 }
788 HILOG_DEBUG("get resilt size:%{public}zu", elementInfos.size());
789 }
790 return RET_OK;
791 }
792 RetError ret = SearchElementInfoRecursiveByWinid(windowId, elementId, GET_SOURCE_MODE, elementInfos, treeId);
793 if (ret != RET_OK) {
794 HILOG_ERROR("get window element info failed");
795 return ret;
796 }
797 return RET_OK;
798 }
799
SearchElementInfoRecursiveByContent(const int32_t windowId,const int64_t elementId,uint32_t mode,std::vector<AccessibilityElementInfo> & elementInfos,const std::string text,int32_t treeId,bool isFilter)800 RetError AccessibleAbilityClientImpl::SearchElementInfoRecursiveByContent(const int32_t windowId,
801 const int64_t elementId, uint32_t mode, std::vector<AccessibilityElementInfo> &elementInfos,
802 const std::string text, int32_t treeId, bool isFilter)
803 {
804 HILOG_DEBUG();
805 HILOG_INFO("windowId %{public}d}, elementId %{public}" PRId64 "", windowId, elementId);
806 if (windowId <= 0) {
807 return RET_ERR_INVALID_ELEMENT_INFO_FROM_ACE;
808 }
809 std::vector<AccessibilityElementInfo> vecElementInfos = {};
810 std::vector<AccessibilityElementInfo> vecTextElementInfos = {};
811 RetError ret = channelClient_->SearchElementInfosByAccessibilityId(windowId, ROOT_NONE_ID,
812 mode, vecElementInfos, treeId, isFilter);
813 if (ret != RET_OK) {
814 HILOG_ERROR("search element info failed. windowId %{public}d}", windowId);
815 return ret;
816 }
817 if (vecElementInfos.empty()) {
818 HILOG_ERROR("elementInfos from ace is empty");
819 return RET_ERR_INVALID_ELEMENT_INFO_FROM_ACE;
820 }
821 HILOG_DEBUG("vecElementInfos Search ok");
822 for (auto info : vecElementInfos) {
823 HILOG_DEBUG("search element info success. windowId %{public}d}",
824 info.GetChildWindowId());
825 if (info.GetParentNodeId() == ROOT_PARENT_ELEMENT_ID) {
826 ret = channelClient_->SearchElementInfosByText(windowId, info.GetAccessibilityId(),
827 text, vecTextElementInfos);
828 if (ret != RET_OK) {
829 HILOG_ERROR("SearchElementInfosByText WindowId %{public}d} ret:%{public}d text:%{public}s",
830 windowId, ret, text.c_str());
831 return ret;
832 }
833 if (!vecTextElementInfos.empty()) {
834 elementInfos.insert(elementInfos.end(), vecTextElementInfos.begin(), vecTextElementInfos.end());
835 }
836 HILOG_DEBUG("SearchByText get result size:%{public}zu windowId %{public}d elementId %{public}" PRId64 "",
837 vecTextElementInfos.size(), windowId, info.GetAccessibilityId());
838 }
839 if (info.GetChildWindowId() > 0 && info.GetChildWindowId() != info.GetWindowId()) {
840 ret = SearchElementInfoRecursiveByContent(info.GetChildWindowId(),
841 elementId, mode, elementInfos, text, info.GetChildTreeId(), isFilter);
842 } else if (info.GetChildTreeId() > 0) {
843 ret = SearchElementInfoRecursiveByContent(info.GetWindowId(),
844 elementId, mode, elementInfos, text, info.GetChildTreeId(), isFilter);
845 }
846 if (ret != RET_OK) {
847 HILOG_ERROR("search element info failed.ChildWindowId %{public}d},ChildTreeId %{public}d},ret:%{public}d",
848 info.GetChildWindowId(), info.GetChildTreeId(), ret);
849 }
850 }
851 return RET_OK;
852 }
853
GetSource(const AccessibilityEventInfo & eventInfo,AccessibilityElementInfo & elementInfo)854 RetError AccessibleAbilityClientImpl::GetSource(const AccessibilityEventInfo &eventInfo,
855 AccessibilityElementInfo &elementInfo)
856 {
857 HILOG_DEBUG();
858 if (!isConnected_) {
859 HILOG_ERROR("connection is broken");
860 return RET_ERR_NO_CONNECTION;
861 }
862
863 std::lock_guard<std::mutex> lock(mutex_);
864 if (!channelClient_) {
865 HILOG_ERROR("The channel is invalid.");
866 return RET_ERR_NO_CONNECTION;
867 }
868 int32_t windowId = eventInfo.GetWindowId();
869 int64_t elementId = eventInfo.GetAccessibilityId();
870 HILOG_DEBUG("windowId[%{public}d], elementId[%{public}" PRId64 "]", windowId, elementId);
871 if (GetCacheElementInfo(windowId, elementId, elementInfo)) {
872 HILOG_DEBUG("get element info from cache");
873 return RET_OK;
874 }
875 return SearchElementInfoFromAce(windowId, elementId, cacheMode_, elementInfo);
876 }
877
GetParentElementInfo(const AccessibilityElementInfo & child,AccessibilityElementInfo & parent)878 RetError AccessibleAbilityClientImpl::GetParentElementInfo(const AccessibilityElementInfo &child,
879 AccessibilityElementInfo &parent)
880 {
881 HILOG_DEBUG();
882 if (!isConnected_) {
883 HILOG_ERROR("connection is broken");
884 return RET_ERR_NO_CONNECTION;
885 }
886
887 std::lock_guard<std::mutex> lock(mutex_);
888 if (!channelClient_) {
889 HILOG_ERROR("The channel is invalid.");
890 return RET_ERR_NO_CONNECTION;
891 }
892 int32_t windowId = child.GetWindowId();
893 int64_t parentElementId = child.GetParentNodeId();
894 int32_t parentWindowId = child.GetParentWindowId();
895 int32_t treeId = (static_cast<uint64_t>(child.GetAccessibilityId()) >> ELEMENT_MOVE_BIT);
896 HILOG_DEBUG("windowId[%{public}d], parentWindowId[%{public}d], parentId[%{public}" PRId64 "]",
897 windowId, parentWindowId, parentElementId);
898 if (GetCacheElementInfo(windowId, parentElementId, parent)) {
899 HILOG_DEBUG("get element info from cache");
900 return RET_OK;
901 }
902 if ((parentElementId == ROOT_PARENT_ELEMENT_ID) && (parentWindowId > 0)) {
903 parentElementId = serviceProxy_->GetRootParentId(windowId, treeId);
904 if (parentElementId > 0) {
905 treeId = (static_cast<uint64_t>(parentElementId) >> ELEMENT_MOVE_BIT);
906 HILOG_DEBUG("find root parentId and search parentElementId [%{public}" PRId64 "] treeId[%{public}d]",
907 parentElementId, treeId);
908 return SearchElementInfoByElementId(child.GetParentWindowId(), parentElementId, cacheMode_, parent, treeId);
909 } else {
910 HILOG_DEBUG("GetRootParentId faild, parentElement:%{public}" PRId64 "", parentElementId);
911 return RET_ERR_INVALID_ELEMENT_INFO_FROM_ACE;
912 }
913 }
914
915 return SearchElementInfoByElementId(windowId, parentElementId, cacheMode_, parent, treeId);
916 }
917
GetByElementId(const int64_t elementId,const int32_t windowId,AccessibilityElementInfo & targetElementInfo)918 RetError AccessibleAbilityClientImpl::GetByElementId(const int64_t elementId, const int32_t windowId,
919 AccessibilityElementInfo &targetElementInfo)
920 {
921 HILOG_DEBUG();
922 if (!isConnected_) {
923 HILOG_ERROR("connection is broken");
924 return RET_ERR_NO_CONNECTION;
925 }
926
927 std::lock_guard<std::mutex> lock(mutex_);
928 if (serviceProxy_ == nullptr && !LoadAccessibilityService()) {
929 HILOG_ERROR("failed to connect to aams");
930 return RET_ERR_SAMGR;
931 }
932
933 if (serviceProxy_ == nullptr) {
934 HILOG_ERROR("Failed to connect to aams");
935 return RET_ERR_SAMGR;
936 }
937
938 if (!channelClient_) {
939 HILOG_ERROR("channel is invalid.");
940 return RET_ERR_NO_CONNECTION;
941 }
942
943 int32_t treeId = (static_cast<uint64_t>(elementId) >> ELEMENT_MOVE_BIT);
944 HILOG_DEBUG("window:[%{public}d],treeId:%{public}d,elementId:%{public}" PRId64 "",
945 windowId, treeId, elementId);
946 if (GetCacheElementInfo(windowId, elementId, targetElementInfo)) {
947 HILOG_DEBUG("get element info from cache");
948 return RET_OK;
949 }
950
951 return SearchElementInfoByElementId(windowId, elementId, cacheMode_, targetElementInfo, treeId);
952 }
953
GetCursorPosition(const AccessibilityElementInfo & elementInfo,int32_t & position)954 RetError AccessibleAbilityClientImpl::GetCursorPosition(const AccessibilityElementInfo &elementInfo, int32_t &position)
955 {
956 HILOG_DEBUG();
957 if (!isConnected_) {
958 HILOG_ERROR("connection is broken");
959 return RET_ERR_NO_CONNECTION;
960 }
961
962 std::lock_guard<std::mutex> lock(mutex_);
963 if (!channelClient_) {
964 HILOG_ERROR("The channel is invalid.");
965 return RET_ERR_NO_CONNECTION;
966 }
967 int32_t windowId = elementInfo.GetWindowId();
968 int64_t elementId = elementInfo.GetAccessibilityId();
969 HILOG_DEBUG("windowId[%{public}d], elementId[%{public}" PRId64 "]d", windowId, elementId);
970 return channelClient_->GetCursorPosition(windowId, elementId, position);
971 }
972
ExecuteAction(const AccessibilityElementInfo & elementInfo,const ActionType action,const std::map<std::string,std::string> & actionArguments)973 RetError AccessibleAbilityClientImpl::ExecuteAction(const AccessibilityElementInfo &elementInfo,
974 const ActionType action, const std::map<std::string, std::string> &actionArguments)
975 {
976 HILOG_DEBUG();
977 if (!isConnected_) {
978 HILOG_ERROR("connection is broken");
979 return RET_ERR_NO_CONNECTION;
980 }
981
982 std::lock_guard<std::mutex> lock(mutex_);
983 if (!channelClient_) {
984 HILOG_ERROR("The channel is invalid.");
985 return RET_ERR_NO_CONNECTION;
986 }
987 if (action == ACCESSIBILITY_ACTION_INVALID) {
988 HILOG_ERROR("action is invalid.");
989 return RET_ERR_INVALID_PARAM;
990 }
991 int32_t windowId = elementInfo.GetWindowId();
992 int64_t elementId = elementInfo.GetAccessibilityId();
993 HILOG_DEBUG("windowId[%{public}d], elementId[%{public}" PRId64 "], action[%{public}d", windowId, elementId, action);
994 return channelClient_->ExecuteAction(windowId, elementId, action,
995 const_cast<std::map<std::string, std::string> &>(actionArguments));
996 }
997
EnableScreenCurtain(bool isEnable)998 RetError AccessibleAbilityClientImpl::EnableScreenCurtain(bool isEnable)
999 {
1000 if (!channelClient_) {
1001 HILOG_ERROR("The channel is invalid.");
1002 return RET_ERR_NO_CONNECTION;
1003 }
1004
1005 return channelClient_->EnableScreenCurtain(isEnable);
1006 }
1007
SetTargetBundleName(const std::vector<std::string> & targetBundleNames)1008 RetError AccessibleAbilityClientImpl::SetTargetBundleName(const std::vector<std::string> &targetBundleNames)
1009 {
1010 HILOG_DEBUG("targetBundleNames size[%{public}zu]", targetBundleNames.size());
1011 if (!isConnected_) {
1012 HILOG_ERROR("connection is broken");
1013 return RET_ERR_NO_CONNECTION;
1014 }
1015
1016 std::lock_guard<std::mutex> lock(mutex_);
1017 if (!channelClient_) {
1018 HILOG_ERROR("The channel is invalid.");
1019 return RET_ERR_NO_CONNECTION;
1020 }
1021 return channelClient_->SetTargetBundleName(targetBundleNames);
1022 }
1023
OnRemoteDied(const wptr<IRemoteObject> & remote)1024 void AccessibleAbilityClientImpl::AccessibleAbilityDeathRecipient::OnRemoteDied(const wptr<IRemoteObject>& remote)
1025 {
1026 HILOG_ERROR();
1027 client_.ResetAAClient(remote);
1028 }
1029
OnRemoteDied(const wptr<IRemoteObject> & remote)1030 void AccessibleAbilityClientImpl::AccessibilityServiceDeathRecipient::OnRemoteDied(const wptr<IRemoteObject>& remote)
1031 {
1032 HILOG_ERROR();
1033 client_.NotifyServiceDied(remote);
1034 }
1035
NotifyServiceDied(const wptr<IRemoteObject> & remote)1036 void AccessibleAbilityClientImpl::NotifyServiceDied(const wptr<IRemoteObject> &remote)
1037 {
1038 std::shared_ptr<AccessibleAbilityListener> listener = nullptr;
1039 {
1040 std::lock_guard<std::mutex> lock(mutex_);
1041 if (!serviceProxy_) {
1042 HILOG_ERROR("serviceProxy_ is nullptr");
1043 return;
1044 }
1045 sptr<IRemoteObject> object = serviceProxy_->AsObject();
1046 if (object && (remote == object)) {
1047 listener = listener_;
1048 listener_ = nullptr;
1049 object->RemoveDeathRecipient(accessibilityServiceDeathRecipient_);
1050 serviceProxy_ = nullptr;
1051 channelClient_ = nullptr;
1052 HILOG_INFO("NotifyServiceDied OK");
1053 }
1054 }
1055
1056 isConnected_ = false;
1057 if (listener) {
1058 listener->OnAbilityDisconnected();
1059 }
1060 }
1061
ResetAAClient(const wptr<IRemoteObject> & remote)1062 void AccessibleAbilityClientImpl::ResetAAClient(const wptr<IRemoteObject> &remote)
1063 {
1064 HILOG_DEBUG();
1065 std::lock_guard<std::mutex> lock(mutex_);
1066 if (channelClient_) {
1067 sptr<IRemoteObject> object = channelClient_->GetRemote();
1068 if (object && (remote == object)) {
1069 object->RemoveDeathRecipient(deathRecipient_);
1070 channelClient_ = nullptr;
1071 HILOG_INFO("ResetAAClient OK");
1072 }
1073 }
1074
1075 isConnected_ = false;
1076 }
1077
SetCacheMode(const int32_t cacheMode)1078 RetError AccessibleAbilityClientImpl::SetCacheMode(const int32_t cacheMode)
1079 {
1080 HILOG_DEBUG("set cache mode: [%{public}d]", cacheMode);
1081 std::lock_guard<std::mutex> lock(mutex_);
1082 cacheWindowId_ = -1;
1083 cacheElementInfos_.clear();
1084 if (cacheMode < 0) {
1085 cacheMode_ = 0;
1086 } else {
1087 uint32_t mode = static_cast<uint32_t>(cacheMode);
1088 cacheMode_ = mode & static_cast<uint32_t>(GET_SOURCE_PREFETCH_MODE);
1089 }
1090 return RET_OK;
1091 }
1092
GetCacheElementInfo(const int32_t windowId,const int64_t elementId,AccessibilityElementInfo & elementInfo) const1093 bool AccessibleAbilityClientImpl::GetCacheElementInfo(const int32_t windowId,
1094 const int64_t elementId, AccessibilityElementInfo &elementInfo) const
1095 {
1096 HILOG_DEBUG();
1097 if (cacheWindowId_ == -1 || cacheWindowId_ != windowId) {
1098 HILOG_DEBUG("cacheWindowId[%{public}d], windowId[%{public}d]", cacheWindowId_, windowId);
1099 return false;
1100 }
1101
1102 auto iter = cacheElementInfos_.find(elementId);
1103 if (iter == cacheElementInfos_.end()) {
1104 HILOG_DEBUG("the element id[%{public}" PRId64 "] is not in cache", elementId);
1105 return false;
1106 }
1107
1108 elementInfo = iter->second;
1109 return true;
1110 }
1111
SetCacheElementInfo(const int32_t windowId,const std::vector<OHOS::Accessibility::AccessibilityElementInfo> & elementInfos)1112 void AccessibleAbilityClientImpl::SetCacheElementInfo(const int32_t windowId,
1113 const std::vector<OHOS::Accessibility::AccessibilityElementInfo> &elementInfos)
1114 {
1115 HILOG_DEBUG("windowId[%{public}d], elementInfos size[%{public}zu]", windowId, elementInfos.size());
1116 cacheElementInfos_.clear();
1117 cacheWindowId_ = windowId;
1118 for (auto &elementInfo : elementInfos) {
1119 cacheElementInfos_.insert(std::make_pair(elementInfo.GetAccessibilityId(), elementInfo));
1120 }
1121 }
1122
SearchElementInfoByElementId(const int32_t windowId,const int64_t elementId,const uint32_t mode,AccessibilityElementInfo & info,int32_t treeId)1123 RetError AccessibleAbilityClientImpl::SearchElementInfoByElementId(const int32_t windowId, const int64_t elementId,
1124 const uint32_t mode, AccessibilityElementInfo &info, int32_t treeId)
1125 {
1126 if (channelClient_ == nullptr) {
1127 HILOG_ERROR("The channel is invalid.");
1128 return RET_ERR_NO_CONNECTION;
1129 }
1130
1131 HILOG_INFO("windowId %{public}d}, elementId %{public}" PRId64 "", windowId, elementId);
1132 std::vector<AccessibilityElementInfo> elementInfos {};
1133 RetError ret = channelClient_->SearchElementInfosByAccessibilityId(
1134 windowId, elementId, static_cast<int32_t>(mode), elementInfos, treeId);
1135 if (ret != RET_OK) {
1136 HILOG_ERROR("SearchElementInfosByAccessibilityId failed. windowId[%{public}d] ", windowId);
1137 return ret;
1138 }
1139 if (elementInfos.empty()) {
1140 HILOG_ERROR("elementInfos from ace is empty");
1141 return RET_ERR_INVALID_ELEMENT_INFO_FROM_ACE;
1142 }
1143
1144 HILOG_DEBUG("element [elementSize:%{public}zu]", elementInfos.size());
1145 SetCacheElementInfo(windowId, elementInfos);
1146 info = elementInfos.front();
1147 return RET_OK;
1148 }
1149
SearchElementInfoFromAce(const int32_t windowId,const int64_t elementId,const uint32_t mode,AccessibilityElementInfo & info)1150 RetError AccessibleAbilityClientImpl::SearchElementInfoFromAce(const int32_t windowId, const int64_t elementId,
1151 const uint32_t mode, AccessibilityElementInfo &info)
1152 {
1153 if (channelClient_ == nullptr) {
1154 HILOG_ERROR("The channel is invalid.");
1155 return RET_ERR_NO_CONNECTION;
1156 }
1157 HILOG_INFO("windowId %{public}d}, elementId %{public}" PRId64 "", windowId, elementId);
1158 std::vector<AccessibilityElementInfo> elementInfos {};
1159 int32_t treeId = 0;
1160 if (elementId != ROOT_NONE_ID) {
1161 treeId = (static_cast<uint64_t>(elementId) >> ELEMENT_MOVE_BIT);
1162 }
1163 RetError ret = channelClient_->SearchElementInfosByAccessibilityId(windowId, elementId,
1164 static_cast<int32_t>(mode), elementInfos, treeId);
1165 if (ret != RET_OK) {
1166 HILOG_ERROR("search element info failed. windowId[%{public}d] elementId[%{public}" PRId64 "] mode[%{public}d]",
1167 windowId, elementId, mode);
1168 return ret;
1169 }
1170 if (!elementInfos.empty()) {
1171 HILOG_DEBUG("element [elementSize:%{public}zu]", elementInfos.size());
1172 SetCacheElementInfo(windowId, elementInfos);
1173 info = elementInfos.front();
1174 HILOG_DEBUG("elementId:%{public}" PRId64 ", windowId:%{public}d, treeId:%{public}d",
1175 info.GetAccessibilityId(), info.GetWindowId(), info.GetBelongTreeId());
1176 return RET_OK;
1177 }
1178
1179 HILOG_DEBUG("elementInfos from ace is empty find all element");
1180 ret = SearchElementInfoRecursiveByWinid(windowId, ROOT_NONE_ID, GET_SOURCE_MODE, elementInfos, ROOT_TREE_ID);
1181 if (ret != RET_OK) {
1182 HILOG_ERROR("SearchElementInfoRecursiveByWinid failed. windowId[%{public}d]", windowId);
1183 return ret;
1184 }
1185 HILOG_DEBUG("SetCacheElementInfo windowId:%{public}d, element [elementSize:%{public}zu]",
1186 windowId, elementInfos.size());
1187 SetCacheElementInfo(windowId, elementInfos);
1188 if (!GetCacheElementInfo(windowId, elementId, info)) {
1189 return RET_ERR_INVALID_ELEMENT_INFO_FROM_ACE;
1190 }
1191 HILOG_DEBUG("elementId:%{public}" PRId64 ", windowId:%{public}d, treeId:%{public}d",
1192 info.GetAccessibilityId(), info.GetWindowId(), info.GetBelongTreeId());
1193 return RET_OK;
1194 }
1195
SearchElementInfoByInspectorKey(const std::string & inspectorKey,AccessibilityElementInfo & elementInfo)1196 RetError AccessibleAbilityClientImpl::SearchElementInfoByInspectorKey(const std::string &inspectorKey,
1197 AccessibilityElementInfo &elementInfo)
1198 {
1199 HILOG_DEBUG();
1200 if (!isConnected_) {
1201 HILOG_ERROR("connection is broken");
1202 return RET_ERR_NO_CONNECTION;
1203 }
1204
1205 std::lock_guard<std::mutex> lock(mutex_);
1206 if (serviceProxy_ == nullptr && !LoadAccessibilityService()) {
1207 HILOG_ERROR("Failed to connect to aams");
1208 return RET_ERR_SAMGR;
1209 }
1210
1211 if (!channelClient_) {
1212 HILOG_ERROR("The channel is invalid.");
1213 return RET_ERR_NO_CONNECTION;
1214 }
1215
1216 if (serviceProxy_ == nullptr) {
1217 HILOG_ERROR("Failed to connect to aams");
1218 return RET_ERR_SAMGR;
1219 }
1220
1221 int32_t windowId = serviceProxy_->GetActiveWindow();
1222 HILOG_DEBUG("windowId[%{public}d]", windowId);
1223 std::vector<AccessibilityElementInfo> elementInfos {};
1224
1225 RetError ret = channelClient_->SearchElementInfosByAccessibilityId(windowId, ROOT_NONE_ID,
1226 static_cast<int32_t>(GET_SOURCE_MODE), elementInfos, ROOT_TREE_ID);
1227 if (ret != RET_OK) {
1228 HILOG_ERROR("search element info failed.");
1229 return ret;
1230 }
1231
1232 ret = SearchElementInfoRecursiveByWinid(windowId, ROOT_NONE_ID, GET_SOURCE_MODE, elementInfos, ROOT_TREE_ID);
1233 if (ret != RET_OK) {
1234 HILOG_ERROR("get window element failed.");
1235 return ret;
1236 }
1237
1238 if (elementInfos.empty()) {
1239 HILOG_ERROR("elementInfos from ace is empty");
1240 return RET_ERR_INVALID_ELEMENT_INFO_FROM_ACE;
1241 }
1242 SortElementInfosIfNecessary(elementInfos);
1243 for (auto &info : elementInfos) {
1244 if (info.GetInspectorKey() == inspectorKey) {
1245 HILOG_INFO("find elementInfo by inspectorKey success");
1246 elementInfo = info;
1247 return RET_OK;
1248 }
1249 }
1250 return RET_ERR_FAILED;
1251 }
1252
Connect()1253 RetError AccessibleAbilityClientImpl::Connect()
1254 {
1255 HILOG_DEBUG();
1256 std::lock_guard<std::mutex> lock(mutex_);
1257 if (serviceProxy_ == nullptr && !LoadAccessibilityService()) {
1258 HILOG_ERROR("Failed to get aams service");
1259 return RET_ERR_SAMGR;
1260 }
1261 if (serviceProxy_ == nullptr) {
1262 HILOG_ERROR("Failed to connect to aams");
1263 return RET_ERR_SAMGR;
1264 }
1265
1266 return serviceProxy_->EnableUITestAbility(this->AsObject());
1267 }
1268
Disconnect()1269 RetError AccessibleAbilityClientImpl::Disconnect()
1270 {
1271 HILOG_DEBUG();
1272 std::lock_guard<std::mutex> lock(mutex_);
1273 if (serviceProxy_ == nullptr && !LoadAccessibilityService()) {
1274 HILOG_ERROR("Failed to get aams service");
1275 return RET_ERR_SAMGR;
1276 }
1277 if (serviceProxy_ == nullptr) {
1278 HILOG_ERROR("Failed to connect to aams");
1279 return RET_ERR_SAMGR;
1280 }
1281 return serviceProxy_->DisableUITestAbility();
1282 }
1283
SetConnectionState(bool state)1284 void AccessibleAbilityClientImpl::SetConnectionState(bool state)
1285 {
1286 isConnected_ = state;
1287 }
1288
AddWindowElementMapByWMS(int32_t windowId,int64_t elementId)1289 void AccessibleAbilityClientImpl::AddWindowElementMapByWMS(int32_t windowId, int64_t elementId)
1290 {
1291 // only used for scene board window, non scene board window not need window element map
1292 int32_t realWindowId = windowId;
1293 int64_t realElementId = elementId;
1294 serviceProxy_->GetRealWindowAndElementId(realWindowId, realElementId);
1295 HILOG_DEBUG("windowId %{public}d, real windowId %{public}d, real elementId %{public}" PRId64 "",
1296 windowId, realWindowId, realElementId);
1297 if (windowId != realElementId) {
1298 windowElementMap_.AddWindowElementIdPair(windowId, realElementId);
1299 }
1300 }
1301
AddWindowElementMapByAce(int32_t windowId,int64_t elementId)1302 void AccessibleAbilityClientImpl::AddWindowElementMapByAce(int32_t windowId, int64_t elementId)
1303 {
1304 // only used for scene board window, non scene board window not need window element map
1305 if (windowId == SCENE_BOARD_WINDOW_ID) {
1306 int32_t innerWid = INVALID_SCENE_BOARD_INNER_WINDOW_ID;
1307 serviceProxy_->GetSceneBoardInnerWinId(windowId, elementId, innerWid);
1308 HILOG_DEBUG("windowId %{public}d, elementId %{public}" PRId64 ", innerWid %{public}d",
1309 windowId, elementId, innerWid);
1310 if (innerWid != INVALID_SCENE_BOARD_INNER_WINDOW_ID) {
1311 windowElementMap_.AddWindowElementIdPair(innerWid, elementId);
1312 }
1313 }
1314 }
1315
GetElementInfoFromCache(int32_t windowId,int64_t elementId,std::vector<AccessibilityElementInfo> & elementInfos)1316 RetError AccessibleAbilityClientImpl::GetElementInfoFromCache(int32_t windowId, int64_t elementId,
1317 std::vector<AccessibilityElementInfo> &elementInfos)
1318 {
1319 if (windowId == SCENE_BOARD_WINDOW_ID) { // sceneboard window id
1320 if (elementCacheInfo_.GetElementByWindowId(windowId, elementId, elementInfos)) {
1321 HILOG_DEBUG("get element info from cache");
1322 return RET_OK;
1323 }
1324
1325 std::vector<int32_t> windowsList = windowElementMap_.GetWindowIdList();
1326 for (auto tmpWindowId : windowsList) {
1327 if (elementCacheInfo_.GetElementByWindowId(tmpWindowId, elementId, elementInfos)) {
1328 HILOG_DEBUG("get element info from cache");
1329 return RET_OK;
1330 }
1331 }
1332 } else {
1333 if (elementCacheInfo_.GetElementByWindowId(windowId, elementId, elementInfos)) {
1334 HILOG_DEBUG("get element info from cache");
1335 return RET_OK;
1336 }
1337 }
1338
1339 return RET_ERR_FAILED;
1340 }
1341
SearchElementInfoRecursive(int32_t windowId,int64_t elementId,uint32_t mode,std::vector<AccessibilityElementInfo> & elementInfos,bool isFilter)1342 RetError AccessibleAbilityClientImpl::SearchElementInfoRecursive(int32_t windowId, int64_t elementId, uint32_t mode,
1343 std::vector<AccessibilityElementInfo> &elementInfos, bool isFilter)
1344 {
1345 HILOG_INFO("windowId %{public}d}, elementId %{public}" PRId64 "", windowId, elementId);
1346 RetError ret = channelClient_->SearchElementInfosByAccessibilityId(windowId, elementId,
1347 mode, elementInfos, ROOT_TREE_ID, isFilter);
1348 if (ret != RET_OK) {
1349 HILOG_ERROR("search element info failed. windowId %{public}d elementId %{public}" PRId64 "",
1350 windowId, elementId);
1351 return ret;
1352 }
1353
1354 if (elementInfos.empty()) {
1355 HILOG_ERROR("elementInfos from ace is empty");
1356 return RET_ERR_INVALID_ELEMENT_INFO_FROM_ACE;
1357 }
1358
1359 return RET_OK;
1360 }
1361
SearchElementInfoRecursiveByWinid(const int32_t windowId,const int64_t elementId,uint32_t mode,std::vector<AccessibilityElementInfo> & elementInfos,int32_t treeId,bool isFilter,AccessibilityElementInfo * parentInfo)1362 RetError AccessibleAbilityClientImpl::SearchElementInfoRecursiveByWinid(const int32_t windowId,
1363 const int64_t elementId, uint32_t mode, std::vector<AccessibilityElementInfo> &elementInfos,
1364 int32_t treeId, bool isFilter, AccessibilityElementInfo *parentInfo)
1365 {
1366 HILOG_DEBUG();
1367 if (windowId <= 0) {
1368 HILOG_ERROR("window Id is failed windowId %{public}d}", windowId);
1369 return RET_ERR_INVALID_ELEMENT_INFO_FROM_ACE;
1370 }
1371 HILOG_INFO("window Id is success windowId %{public}d}, elementId %{public}" PRId64 "", windowId, elementId);
1372 std::vector<AccessibilityElementInfo> vecElementInfos = {};
1373 RetError ret = channelClient_->SearchElementInfosByAccessibilityId(windowId, elementId,
1374 mode, vecElementInfos, treeId, isFilter);
1375 if (ret != RET_OK) {
1376 HILOG_ERROR("search element info failed. windowId %{public}d}", windowId);
1377 return ret;
1378 }
1379 if (vecElementInfos.empty()) {
1380 HILOG_ERROR("elementInfos from ace is empty");
1381 return RET_ERR_INVALID_ELEMENT_INFO_FROM_ACE;
1382 }
1383 HILOG_DEBUG("SearchElementInfoRecursiveByWinid : vecElementInfos Search ok");
1384 SortElementInfosIfNecessary(vecElementInfos);
1385 uint64_t elementInfosCountAdded = 0;
1386 uint64_t elementInfosCount = elementInfos.size();
1387 for (auto info : vecElementInfos) {
1388 if ((info.GetParentNodeId() == ROOT_PARENT_ELEMENT_ID) && (parentInfo != nullptr)) {
1389 parentInfo->AddChild(info.GetAccessibilityId());
1390 info.SetParent(parentInfo->GetAccessibilityId());
1391 HILOG_DEBUG("Give the father a child. %{public}" PRId64 ",Give the child a father. %{public}" PRId64 "",
1392 info.GetAccessibilityId(), parentInfo->GetAccessibilityId());
1393 }
1394 elementInfos.push_back(info);
1395 elementInfosCountAdded++;
1396 }
1397 for (uint64_t i = elementInfosCount; i < elementInfosCount + elementInfosCountAdded; i++) {
1398 HILOG_DEBUG("SearchElementInfoRecursiveByWinid :search element info success. windowId %{public}d}",
1399 elementInfos[i].GetChildWindowId());
1400 if ((elementInfos[i].GetChildWindowId() > 0) &&
1401 (elementInfos[i].GetChildWindowId() != elementInfos[i].GetWindowId())) {
1402 ret = SearchElementInfoRecursiveByWinid(elementInfos[i].GetChildWindowId(),
1403 elementId, mode, elementInfos, elementInfos[i].GetChildTreeId(), isFilter, &elementInfos[i]);
1404 HILOG_DEBUG("ChildWindowId %{public}d}. ret:%{public}d", elementInfos[i].GetChildWindowId(), ret);
1405 } else if (elementInfos[i].GetChildTreeId() > 0) {
1406 ret = SearchElementInfoRecursiveByWinid(elementInfos[i].GetWindowId(),
1407 elementId, mode, elementInfos, elementInfos[i].GetChildTreeId(), isFilter, &elementInfos[i]);
1408 HILOG_DEBUG("windowId %{public}d}.treeId:%{public}d. ret:%{public}d",
1409 elementInfos[i].GetWindowId(), elementInfos[i].GetChildTreeId(), ret);
1410 }
1411 }
1412 return RET_OK;
1413 }
1414
RemoveCacheData(const AccessibilityEventInfo & eventInfo)1415 void AccessibleAbilityClientImpl::RemoveCacheData(const AccessibilityEventInfo& eventInfo)
1416 {
1417 EventType type = eventInfo.GetEventType();
1418 if (type == TYPE_VIEW_TEXT_UPDATE_EVENT || type == TYPE_PAGE_STATE_UPDATE ||
1419 type == TYPE_NOTIFICATION_UPDATE_EVENT || type == TYPE_PAGE_CONTENT_UPDATE ||
1420 type == TYPE_VIEW_TEXT_SELECTION_UPDATE_EVENT || type == TYPE_WINDOW_UPDATE) {
1421 int32_t windowId = eventInfo.GetWindowId();
1422 HILOG_DEBUG("RemoveCacheData windowId %{public}d", windowId);
1423 if (windowId == SCENE_BOARD_WINDOW_ID) {
1424 elementCacheInfo_.RemoveElementByWindowId(windowId);
1425 windowElementMap_.RemovePairByWindowId(windowId);
1426
1427 auto windowList = windowElementMap_.GetWindowIdList();
1428 windowElementMap_.RemovePairByWindowIdList(windowList);
1429 for (auto window: windowList) {
1430 elementCacheInfo_.RemoveElementByWindowId(window);
1431 }
1432 } else {
1433 elementCacheInfo_.RemoveElementByWindowId(windowId);
1434 windowElementMap_.RemovePairByWindowId(windowId);
1435 }
1436 }
1437 }
1438
AddCacheByWMS(int32_t windowId,int64_t elementId,std::vector<AccessibilityElementInfo> & elementInfos)1439 void AccessibleAbilityClientImpl::AddCacheByWMS(int32_t windowId, int64_t elementId,
1440 std::vector<AccessibilityElementInfo>& elementInfos)
1441 {
1442 HILOG_DEBUG("elementSize %{public}zu", elementInfos.size());
1443 AddWindowElementMapByWMS(windowId, elementId);
1444 elementCacheInfo_.AddElementCache(windowId, elementInfos);
1445 }
1446
AddCacheByAce(int32_t windowId,int64_t elementId,std::vector<AccessibilityElementInfo> & elementInfos)1447 void AccessibleAbilityClientImpl::AddCacheByAce(int32_t windowId, int64_t elementId,
1448 std::vector<AccessibilityElementInfo>& elementInfos)
1449 {
1450 AddWindowElementMapByAce(windowId, elementId);
1451 HILOG_DEBUG("elementSize %{public}zu", elementInfos.size());
1452 if (windowId == SCENE_BOARD_WINDOW_ID) {
1453 windowId = windowElementMap_.GetWindowIdByElementId(elementId);
1454 HILOG_DEBUG("windowId convert to %{public}d", windowId);
1455 if (windowId == INVALID_SCENE_BOARD_INNER_WINDOW_ID) {
1456 elementCacheInfo_.AddElementCache(SCENE_BOARD_WINDOW_ID, elementInfos);
1457 } else {
1458 elementCacheInfo_.AddElementCache(windowId, elementInfos);
1459 }
1460 } else {
1461 elementCacheInfo_.AddElementCache(windowId, elementInfos);
1462 }
1463 }
1464
SearchElementInfoByAccessibilityId(const int32_t windowId,const int64_t elementId,const uint32_t mode,AccessibilityElementInfo & info,bool isFilter)1465 RetError AccessibleAbilityClientImpl::SearchElementInfoByAccessibilityId(const int32_t windowId,
1466 const int64_t elementId, const uint32_t mode, AccessibilityElementInfo &info, bool isFilter)
1467 {
1468 HILOG_DEBUG();
1469 if (isConnected_ == false) {
1470 HILOG_ERROR("connection is broken.");
1471 return RET_ERR_NO_CONNECTION;
1472 }
1473
1474 std::lock_guard<std::mutex> lock(mutex_);
1475 if (serviceProxy_ == nullptr) {
1476 HILOG_ERROR("failed to connect aams.");
1477 return RET_ERR_SAMGR;
1478 }
1479 if (channelClient_ == nullptr) {
1480 HILOG_ERROR("the channel is invalid.");
1481 return RET_ERR_NO_CONNECTION;
1482 }
1483 std::vector<AccessibilityElementInfo> elementInfos {};
1484 int32_t treeId = 0;
1485 if (elementId > 0) {
1486 treeId = (static_cast<uint64_t>(elementId) >> ELEMENT_MOVE_BIT);
1487 }
1488 RetError ret = channelClient_->SearchElementInfosByAccessibilityId(windowId,
1489 elementId, static_cast<int32_t>(mode), elementInfos, treeId, isFilter);
1490 if (ret != RET_OK) {
1491 HILOG_ERROR("search element info failed, ret = %{public}d.", ret);
1492 return ret;
1493 }
1494 if (elementInfos.empty()) {
1495 HILOG_ERROR("elementInfos from ace is empty.");
1496 return RET_ERR_INVALID_ELEMENT_INFO_FROM_ACE;
1497 }
1498
1499 SetCacheElementInfo(windowId, elementInfos);
1500 info = elementInfos.front();
1501 return RET_OK;
1502 }
1503
AddElementCache(const int32_t windowId,const std::vector<AccessibilityElementInfo> & elementInfos)1504 void AccessibleAbilityClientImpl::ElementCacheInfo::AddElementCache(const int32_t windowId,
1505 const std::vector<AccessibilityElementInfo>& elementInfos)
1506 {
1507 std::lock_guard<std::mutex> lock(elementCacheMutex_);
1508 if (windowIdSet_.size() >= MAX_CACHE_WINDOW_SIZE) {
1509 auto winId = windowIdSet_.front();
1510 windowIdSet_.pop_front();
1511 elementCache_.erase(winId);
1512 }
1513
1514 elementCache_.erase(windowId);
1515
1516 std::map<int32_t, std::shared_ptr<AccessibilityElementInfo>> cache;
1517 for (auto& elementInfo : elementInfos) {
1518 int64_t elementId = elementInfo.GetAccessibilityId();
1519 cache[elementId] = std::make_shared<AccessibilityElementInfo>(elementInfo);
1520 }
1521
1522 elementCache_[windowId] = std::move(cache);
1523 windowIdSet_.push_back(windowId);
1524 }
1525
GetElementByWindowIdBFS(const int64_t realElementId,std::vector<AccessibilityElementInfo> & elementInfos,std::map<int32_t,std::shared_ptr<AccessibilityElementInfo>> & cache)1526 bool AccessibleAbilityClientImpl::ElementCacheInfo::GetElementByWindowIdBFS(const int64_t realElementId,
1527 std::vector<AccessibilityElementInfo>& elementInfos,
1528 std::map<int32_t, std::shared_ptr<AccessibilityElementInfo>>& cache)
1529 {
1530 std::vector<int64_t> elementList;
1531 elementList.push_back(realElementId);
1532 uint32_t index = 0;
1533 while (index < elementList.size()) {
1534 auto iter = cache.find(elementList[index]);
1535 if (iter == cache.end()) {
1536 elementInfos.clear();
1537 HILOG_DEBUG("element data abnormal, clear elementInfos");
1538 return false;
1539 }
1540
1541 elementInfos.push_back(*(iter->second));
1542 std::vector<int64_t> childrenNode = iter->second->GetChildIds();
1543 for (auto& node : childrenNode) {
1544 elementList.push_back(node);
1545 }
1546 index++;
1547 }
1548 return true;
1549 }
1550
1551 // window id is true, element id is true
GetElementByWindowId(const int32_t windowId,const int64_t elementId,std::vector<AccessibilityElementInfo> & elementInfos)1552 bool AccessibleAbilityClientImpl::ElementCacheInfo::GetElementByWindowId(const int32_t windowId,
1553 const int64_t elementId, std::vector<AccessibilityElementInfo>& elementInfos)
1554 {
1555 elementInfos.clear(); // clear
1556 std::lock_guard<std::mutex> lock(elementCacheMutex_);
1557 if (elementCache_.find(windowId) == elementCache_.end()) {
1558 HILOG_DEBUG("windowId %{public}d is not existed", windowId);
1559 return false;
1560 }
1561
1562 auto& cache = elementCache_.find(windowId)->second;
1563 if (cache.size() == 0) {
1564 HILOG_DEBUG("windowId %{public}d element is null", windowId);
1565 return false;
1566 }
1567
1568 if (cache.find(elementId) == cache.end() && elementId != ROOT_NONE_ID) {
1569 HILOG_DEBUG("elementId %{public}" PRId64 " is not existed", elementId);
1570 return false;
1571 }
1572
1573 int64_t realElementId = elementId;
1574 if (realElementId == ROOT_NONE_ID) {
1575 for (auto iter = cache.begin(); iter != cache.end(); iter++) {
1576 if (iter->second->GetComponentType() == "root") {
1577 realElementId = iter->first;
1578 HILOG_DEBUG("find realElementId %{public}" PRId64 "", realElementId);
1579 break;
1580 }
1581 }
1582 }
1583
1584 if (realElementId == ROOT_NONE_ID) {
1585 HILOG_ERROR("elementId %{public}" PRId64 " is not existed", realElementId);
1586 return false;
1587 }
1588
1589 if (!GetElementByWindowIdBFS(realElementId, elementInfos, cache)) {
1590 HILOG_DEBUG("get window element fail");
1591 return false;
1592 }
1593
1594 HILOG_DEBUG("get element info success, element size %{public}zu", elementInfos.size());
1595 return true;
1596 }
1597
RemoveElementByWindowId(const int32_t windowId)1598 void AccessibleAbilityClientImpl::ElementCacheInfo::RemoveElementByWindowId(const int32_t windowId)
1599 {
1600 std::lock_guard<std::mutex> lock(elementCacheMutex_);
1601 HILOG_DEBUG("erase windowId %{public}d cache", windowId);
1602 for (auto iter = windowIdSet_.begin(); iter != windowIdSet_.end(); iter++) {
1603 if (*iter == windowId) {
1604 windowIdSet_.erase(iter);
1605 break;
1606 }
1607 }
1608
1609 elementCache_.erase(windowId);
1610 }
1611
IsExistWindowId(int32_t windowId)1612 bool AccessibleAbilityClientImpl::ElementCacheInfo::IsExistWindowId(int32_t windowId)
1613 {
1614 std::lock_guard<std::mutex> lock(elementCacheMutex_);
1615 for (auto iter = windowIdSet_.begin(); iter != windowIdSet_.end(); iter++) {
1616 if (*iter == windowId) {
1617 return true;
1618 }
1619 }
1620
1621 return false;
1622 }
1623
IsExistWindowId(int32_t windowId)1624 bool AccessibleAbilityClientImpl::SceneBoardWindowElementMap::IsExistWindowId(int32_t windowId)
1625 {
1626 std::lock_guard<std::mutex> lock(mapMutex_);
1627 if (windowElementMap_.find(windowId) != windowElementMap_.end()) {
1628 return true;
1629 }
1630
1631 return false;
1632 }
1633
AddWindowElementIdPair(int32_t windowId,int64_t elementId)1634 void AccessibleAbilityClientImpl::SceneBoardWindowElementMap::AddWindowElementIdPair(int32_t windowId,
1635 int64_t elementId)
1636 {
1637 std::lock_guard<std::mutex> lock(mapMutex_);
1638 windowElementMap_[windowId] = elementId;
1639 }
1640
GetWindowIdList()1641 std::vector<int32_t> AccessibleAbilityClientImpl::SceneBoardWindowElementMap::GetWindowIdList()
1642 {
1643 std::lock_guard<std::mutex> lock(mapMutex_);
1644 std::vector<int32_t> windowList;
1645 for (auto iter = windowElementMap_.begin(); iter != windowElementMap_.end(); iter++) {
1646 windowList.push_back(iter->first);
1647 }
1648
1649 return windowList;
1650 }
1651
GetWindowIdByElementId(int64_t elementId)1652 int32_t AccessibleAbilityClientImpl::SceneBoardWindowElementMap::GetWindowIdByElementId(int64_t elementId)
1653 {
1654 std::lock_guard<std::mutex> lock(mapMutex_);
1655 for (auto iter = windowElementMap_.begin(); iter != windowElementMap_.end(); iter++) {
1656 if (iter->second == elementId) {
1657 return iter->first;
1658 }
1659 }
1660
1661 return INVALID_SCENE_BOARD_INNER_WINDOW_ID;
1662 }
1663
RemovePairByWindowIdList(std::vector<int32_t> & windowIdList)1664 void AccessibleAbilityClientImpl::SceneBoardWindowElementMap::RemovePairByWindowIdList(
1665 std::vector<int32_t>& windowIdList)
1666 {
1667 std::lock_guard<std::mutex> lock(mapMutex_);
1668 for (auto windowId : windowIdList) {
1669 windowElementMap_.erase(windowId);
1670 }
1671 }
1672
RemovePairByWindowId(int32_t windowId)1673 void AccessibleAbilityClientImpl::SceneBoardWindowElementMap::RemovePairByWindowId(int32_t windowId)
1674 {
1675 std::lock_guard<std::mutex> lock(mapMutex_);
1676 windowElementMap_.erase(windowId);
1677 }
1678
OnLoadSystemAbilitySuccess(int32_t systemAbilityId,const sptr<IRemoteObject> & remoteObject)1679 void AccessibleAbilityClientImpl::AccessibilityLoadCallback::OnLoadSystemAbilitySuccess(int32_t systemAbilityId,
1680 const sptr<IRemoteObject> &remoteObject)
1681 {
1682 if (AccessibleAbilityClientImpl::GetAbilityClientImplement()) {
1683 AccessibleAbilityClientImpl::GetAbilityClientImplement()->LoadSystemAbilitySuccess(remoteObject);
1684 }
1685 }
1686
OnLoadSystemAbilityFail(int32_t systemAbilityId)1687 void AccessibleAbilityClientImpl::AccessibilityLoadCallback::OnLoadSystemAbilityFail(int32_t systemAbilityId)
1688 {
1689 if (AccessibleAbilityClientImpl::GetAbilityClientImplement()) {
1690 AccessibleAbilityClientImpl::GetAbilityClientImplement()->LoadSystemAbilityFail();
1691 }
1692 }
1693 } // namespace Accessibility
1694 } // namespace OHOS