• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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