• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2022-2025 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 #ifdef OHOS_BUILD_ENABLE_HITRACE
22 #include <hitrace_meter.h>
23 #endif // OHOS_BUILD_ENABLE_HITRACE
24 
25 #include "accessible_ability_client.h"
26 #include "hilog_wrapper.h"
27 #include "if_system_ability_manager.h"
28 #include "iservice_registry.h"
29 #include "parameter.h"
30 #include "system_ability_definition.h"
31 #include "api_reporter_helper.h"
32 
33 namespace OHOS {
34 namespace Accessibility {
35 // tmp: wait for window registing when client connect done
36 constexpr int WAIT_WINDOW_REGIST = 500;
37 constexpr int64_t ROOT_PARENT_ELEMENT_ID = -2100000;
38 const int32_t ROOT_TREE_ID = 0;
39 constexpr uint64_t ELEMENT_MOVE_BIT = 40;
40 namespace {
41     const std::string SYSTEM_PARAMETER_AAMS_SERVICE = "accessibility.config.ready";
42     constexpr int32_t CONFIG_PARAMETER_VALUE_SIZE = 10;
43     constexpr int64_t ROOT_NONE_ID = -1;
44     constexpr int64_t NODE_ID_MAX = 0x7FFFFFFE;
45     ffrt::mutex g_Mutex;
46     sptr<AccessibleAbilityClientImpl> g_Instance = nullptr;
47     constexpr int32_t SA_CONNECT_TIMEOUT = 6 * 1000; // ms
48 } // namespace
49 
GetInstance()50 sptr<AccessibleAbilityClient> AccessibleAbilityClient::GetInstance()
51 {
52     HILOG_DEBUG();
53     std::lock_guard<ffrt::mutex> lock(g_Mutex);
54     if (g_Instance == nullptr) {
55         g_Instance = new(std::nothrow) AccessibleAbilityClientImpl();
56     }
57     return g_Instance;
58 }
59 
GetAbilityClientImplement()60 sptr<AccessibleAbilityClientImpl> AccessibleAbilityClientImpl::GetAbilityClientImplement()
61 {
62     HILOG_DEBUG();
63     std::lock_guard<ffrt::mutex> lock(g_Mutex);
64     if (g_Instance == nullptr) {
65         g_Instance = new(std::nothrow) AccessibleAbilityClientImpl();
66     }
67     return g_Instance;
68 }
69 
AccessibleAbilityClientImpl()70 AccessibleAbilityClientImpl::AccessibleAbilityClientImpl()
71 {
72     HILOG_DEBUG();
73     if (!InitAccessibilityServiceProxy()) {
74         HILOG_ERROR("Init accessibility service proxy failed");
75     }
76 #ifndef ACCESSIBILITY_WATCH_FEATURE
77     int retSysParam = WatchParameter(SYSTEM_PARAMETER_AAMS_SERVICE.c_str(),
78         &AccessibleAbilityClientImpl::OnParameterChanged, this);
79     if (retSysParam) {
80         HILOG_ERROR("Watch parameter failed, error = %{public}d", retSysParam);
81     }
82 #endif // ACCESSIBILITY_WATCH_FEATURE
83 }
84 
~AccessibleAbilityClientImpl()85 AccessibleAbilityClientImpl::~AccessibleAbilityClientImpl()
86 {
87     HILOG_DEBUG();
88     std::unique_lock<ffrt::shared_mutex> wLock(rwLock_);
89     if (serviceProxy_ && serviceProxy_->AsObject()) {
90         HILOG_DEBUG("Remove service death recipient");
91         serviceProxy_->AsObject()->RemoveDeathRecipient(accessibilityServiceDeathRecipient_);
92     }
93 }
94 
InitAccessibilityServiceProxy()95 bool AccessibleAbilityClientImpl::InitAccessibilityServiceProxy()
96 {
97     if (serviceProxy_ != nullptr) {
98         HILOG_DEBUG("Accessibility Service is connected");
99         return true;
100     }
101 
102     sptr<ISystemAbilityManager> samgr = SystemAbilityManagerClient::GetInstance().GetSystemAbilityManager();
103     if (samgr == nullptr) {
104         HILOG_ERROR("Failed to get ISystemAbilityManager");
105         return false;
106     }
107     HILOG_DEBUG("ISystemAbilityManager obtained");
108 
109     sptr<IRemoteObject> object = samgr->GetSystemAbility(ACCESSIBILITY_MANAGER_SERVICE_ID);
110     if (object != nullptr) {
111         if (accessibilityServiceDeathRecipient_ == nullptr) {
112             accessibilityServiceDeathRecipient_ = new(std::nothrow) AccessibilityServiceDeathRecipient(*this);
113             if (accessibilityServiceDeathRecipient_ == nullptr) {
114                 HILOG_ERROR("Failed to create service deathRecipient.");
115                 return false;
116             }
117         }
118         serviceProxy_ = iface_cast<IAccessibleAbilityManagerService>(object);
119         if (serviceProxy_ == nullptr) {
120             HILOG_ERROR("InitAccessibilityServiceProxy failed.");
121             return false;
122         }
123         if (serviceProxy_->AsObject() &&
124             serviceProxy_->AsObject()->AddDeathRecipient(accessibilityServiceDeathRecipient_)) {
125             return true;
126         }
127     } else {
128         if (LoadAccessibilityService() == false) {
129             HILOG_ERROR("LoadSystemAbilityService failed.");
130             return false;
131         } else {
132             return true;
133         }
134     }
135     return false;
136 }
137 
OnParameterChanged(const char * key,const char * value,void * context)138 void AccessibleAbilityClientImpl::OnParameterChanged(const char *key, const char *value, void *context)
139 {
140     if (key == nullptr || std::strcmp(key, SYSTEM_PARAMETER_AAMS_SERVICE.c_str())) {
141         return;
142     }
143     if (value == nullptr || std::strcmp(value, "true")) {
144         return;
145     }
146     if (context == nullptr) {
147         return;
148     }
149 
150     AccessibleAbilityClientImpl *implPtr = static_cast<AccessibleAbilityClientImpl *>(context);
151     std::unique_lock<ffrt::shared_mutex> wLock(implPtr->rwLock_);
152     if (implPtr->InitAccessibilityServiceProxy()) {
153         HILOG_INFO("InitAccessibilityServiceProxy success");
154     }
155 }
156 
CheckServiceProxy()157 bool AccessibleAbilityClientImpl::CheckServiceProxy()
158 {
159     if (serviceProxy_ != nullptr || LoadAccessibilityService() == true) {
160         return true;
161     }
162     return false;
163 }
164 
CheckConnection()165 RetError AccessibleAbilityClientImpl::CheckConnection()
166 {
167     if (!isConnected_) {
168         HILOG_ERROR("connection is broken");
169         return RET_ERR_NO_CONNECTION;
170     }
171     if (!channelClient_) {
172         HILOG_ERROR("connection is broken");
173         return RET_ERR_NO_CONNECTION;
174     }
175     return RET_OK;
176 }
177 
LoadAccessibilityService()178 bool AccessibleAbilityClientImpl::LoadAccessibilityService()
179 {
180     std::unique_lock<ffrt::mutex> lock(conVarMutex_);
181     sptr<AccessibilityLoadCallback> loadCallback = new AccessibilityLoadCallback();
182     if (loadCallback == nullptr) {
183         return false;
184     }
185     auto samgr = SystemAbilityManagerClient::GetInstance().GetSystemAbilityManager();
186     if (samgr == nullptr) {
187         return false;
188     }
189     int32_t ret = samgr->LoadSystemAbility(ACCESSIBILITY_MANAGER_SERVICE_ID, loadCallback);
190     if (ret != 0) {
191         return false;
192     }
193     auto waitStatus = proxyConVar_.wait_for(lock, std::chrono::milliseconds(SA_CONNECT_TIMEOUT),
194         [this]() { return serviceProxy_ != nullptr; });
195     if (!waitStatus) {
196         return false;
197     }
198     return true;
199 }
200 
LoadSystemAbilitySuccess(const sptr<IRemoteObject> & remoteObject)201 void AccessibleAbilityClientImpl::LoadSystemAbilitySuccess(const sptr<IRemoteObject> &remoteObject)
202 {
203     std::lock_guard<ffrt::mutex> lock(conVarMutex_);
204     char value[CONFIG_PARAMETER_VALUE_SIZE] = "default";
205     do
206     {
207         if (serviceProxy_ != nullptr) {
208             break;
209         }
210         sptr<ISystemAbilityManager> samgr = SystemAbilityManagerClient::GetInstance().GetSystemAbilityManager();
211         if (samgr == nullptr) {
212             break;
213         }
214         sptr<IRemoteObject> object = samgr->GetSystemAbility(ACCESSIBILITY_MANAGER_SERVICE_ID);
215         if (object == nullptr) {
216             break;
217         }
218         serviceProxy_ = iface_cast<IAccessibleAbilityManagerService>(object);
219         if (serviceProxy_ == nullptr) {
220             break;
221         }
222         if (accessibilityServiceDeathRecipient_ == nullptr) {
223             accessibilityServiceDeathRecipient_ = new(std::nothrow) AccessibilityServiceDeathRecipient(*this);
224         }
225         if (accessibilityServiceDeathRecipient_ == nullptr) {
226             break;
227         }
228         if (serviceProxy_->AsObject() != nullptr) {
229             serviceProxy_->AsObject()->AddDeathRecipient(accessibilityServiceDeathRecipient_);
230         }
231     } while (0);
232     proxyConVar_.notify_one();
233 }
234 
LoadSystemAbilityFail()235 void AccessibleAbilityClientImpl::LoadSystemAbilityFail()
236 {
237     std::lock_guard<ffrt::mutex> lock(conVarMutex_);
238     HILOG_WARN("LoadSystemAbilityFail.");
239     proxyConVar_.notify_one();
240 }
241 
GetRemoteObject()242 sptr<IRemoteObject> AccessibleAbilityClientImpl::GetRemoteObject()
243 {
244     HILOG_DEBUG();
245     return this->AsObject();
246 }
247 
CheckExtensionAbilityPermission()248 RetError AccessibleAbilityClientImpl::CheckExtensionAbilityPermission()
249 {
250     HILOG_DEBUG();
251     std::shared_lock<ffrt::shared_mutex> rLock(rwLock_);
252     if (CheckServiceProxy() == false) {
253         HILOG_ERROR("failed to connect to aams!");
254         return RET_ERR_SAMGR;
255     }
256     std::string processName = "";
257     auto ret = serviceProxy_->CheckExtensionAbilityPermission(processName);
258     if (ret != 0) {
259         HILOG_ERROR("check permission failed!");
260         return static_cast<RetError>(ret);
261     }
262     return RET_OK;
263 }
264 
RegisterAbilityListener(const std::shared_ptr<AccessibleAbilityListener> & listener)265 RetError AccessibleAbilityClientImpl::RegisterAbilityListener(
266     const std::shared_ptr<AccessibleAbilityListener> &listener)
267 {
268     HILOG_DEBUG();
269     std::unique_lock<ffrt::shared_mutex> wLock(rwLock_);
270     if (listener_) {
271         HILOG_DEBUG("listener already exists.");
272         return RET_ERR_REGISTER_EXIST;
273     }
274 
275     listener_ = listener;
276     return RET_OK;
277 }
278 
Init(const sptr<IAccessibleAbilityChannel> & channel,const int32_t channelId)279 void AccessibleAbilityClientImpl::Init(const sptr<IAccessibleAbilityChannel> &channel, const int32_t channelId)
280 {
281     HILOG_DEBUG("channelId[%{public}d]", channelId);
282     if (!channel || channelId == INVALID_CHANNEL_ID) {
283         HILOG_ERROR("channel is nullptr, or channelId is invalid");
284         return;
285     }
286 
287     std::shared_ptr<AccessibleAbilityListener> listener = nullptr;
288     {
289         std::unique_lock<ffrt::shared_mutex> wLock(rwLock_);
290         if (!listener_) {
291             HILOG_ERROR("listener_ is nullptr.");
292             return;
293         }
294         listener = listener_;
295         channelClient_ = std::make_shared<AccessibleAbilityChannelClient>(channelId, channel);
296 
297         // Add death recipient
298         if (deathRecipient_ == nullptr) {
299             deathRecipient_ = new(std::nothrow) AccessibleAbilityDeathRecipient(*this);
300             if (deathRecipient_ == nullptr) {
301                 HILOG_ERROR("Failed to create deathRecipient.");
302                 return;
303             }
304         }
305 
306         if (channel->AsObject()) {
307             HILOG_DEBUG("Add death recipient");
308             channel->AsObject()->AddDeathRecipient(deathRecipient_);
309         }
310     }
311 
312     isConnected_ = true;
313 #ifndef ACCESSIBILITY_WATCH_FEATURE
314     std::this_thread::sleep_for(std::chrono::milliseconds(WAIT_WINDOW_REGIST));
315 #endif // ACCESSIBILITY_WATCH_FEATURE
316     if (listener) {
317         listener->OnAbilityConnected();
318     }
319 }
320 
Disconnect(const int32_t channelId)321 void AccessibleAbilityClientImpl::Disconnect(const int32_t channelId)
322 {
323     HILOG_DEBUG("channelId[%{public}d]", channelId);
324 
325     std::shared_ptr<AccessibleAbilityListener> listener = listener_;
326     {
327         isConnected_ = false;
328         std::unique_lock<ffrt::shared_mutex> wLock(rwLock_);
329         if (callbackList_.empty()) {
330             // Delete death recipient
331             if (channelClient_ && channelClient_->GetRemote()) {
332                 HILOG_ERROR("Remove death recipient");
333                 channelClient_->GetRemote()->RemoveDeathRecipient(deathRecipient_);
334             }
335 
336             // Remove channel
337             channelClient_ = nullptr;
338             listener_ = nullptr;
339         } else {
340             isDisconnectCallbackExecute_ = true;
341         }
342     }
343 
344     if (listener) {
345         listener->OnAbilityDisconnected();
346     }
347     std::unique_lock<ffrt::mutex> lock(callbackListMutex_);
348     for (auto &callback : callbackList_) {
349         callback->NotifyJS();
350     }
351 }
352 
OnAccessibilityEvent(const AccessibilityEventInfo & eventInfo)353 void AccessibleAbilityClientImpl::OnAccessibilityEvent(const AccessibilityEventInfo &eventInfo)
354 {
355     HILOG_DEBUG();
356     std::shared_ptr<AccessibleAbilityListener> listener = nullptr;
357     {
358         std::shared_lock<ffrt::shared_mutex> rLock(rwLock_);
359         if (!channelClient_) {
360             HILOG_ERROR("The channel is invalid.");
361             return;
362         }
363         listener = listener_;
364     }
365     if (listener) {
366         listener->OnAccessibilityEvent(eventInfo);
367     }
368 }
369 
OnKeyPressEvent(const MMI::KeyEvent & keyEvent,const int32_t sequence)370 void AccessibleAbilityClientImpl::OnKeyPressEvent(const MMI::KeyEvent &keyEvent, const int32_t sequence)
371 {
372     HILOG_DEBUG("sequence[%{public}d]", sequence);
373     std::shared_ptr<AccessibleAbilityListener> listener = nullptr;
374     std::shared_ptr<AccessibleAbilityChannelClient> channel = nullptr;
375     {
376         std::shared_lock<ffrt::shared_mutex> rLock(rwLock_);
377         listener = listener_;
378         channel = channelClient_;
379     }
380 
381     if (!channel) {
382         HILOG_ERROR("The channel is invalid.");
383         return;
384     }
385     bool handled = false;
386     if (listener) {
387         std::shared_ptr<MMI::KeyEvent> tmp = std::make_shared<MMI::KeyEvent>(keyEvent);
388         handled = listener->OnKeyPressEvent(tmp);
389     }
390     channel->SetOnKeyPressEventResult(handled, sequence);
391 }
392 
GetFocus(const int32_t focusType,AccessibilityElementInfo & elementInfo,bool systemApi)393 RetError AccessibleAbilityClientImpl::GetFocus(
394     const int32_t focusType, AccessibilityElementInfo& elementInfo, bool systemApi)
395 {
396     HILOG_DEBUG("focusType[%{public}d]", focusType);
397 #ifdef ACCESSIBILITY_EMULATOR_DEFINED
398     ApiReportHelper reporter("AccessibleAbilityClientImpl.GetFocus");
399 #endif // ACCESSIBILITY_EMULATOR_DEFINED
400     if (!isConnected_) {
401         HILOG_ERROR("connection is broken");
402         return RET_ERR_NO_CONNECTION;
403     }
404 
405     std::shared_lock<ffrt::shared_mutex> rLock(rwLock_);
406     if ((focusType != FOCUS_TYPE_INPUT) && (focusType != FOCUS_TYPE_ACCESSIBILITY)) {
407         HILOG_ERROR("focusType is not allowed.");
408         return RET_ERR_INVALID_PARAM;
409     }
410 
411     if (!channelClient_) {
412         HILOG_ERROR("The channel is invalid.");
413         return RET_ERR_NO_CONNECTION;
414     }
415 
416     Accessibility::RetError ret = channelClient_->FindFocusedElementInfo(
417         ANY_WINDOW_ID, ROOT_NODE_ID, focusType, elementInfo, systemApi);
418 #ifdef ACCESSIBILITY_EMULATOR_DEFINED
419     reporter.setResult(ret);
420 #endif // ACCESSIBILITY_EMULATOR_DEFINED
421     return ret;
422 }
423 
GetFocusByElementInfo(const AccessibilityElementInfo & sourceInfo,const int32_t focusType,AccessibilityElementInfo & elementInfo)424 RetError AccessibleAbilityClientImpl::GetFocusByElementInfo(const AccessibilityElementInfo &sourceInfo,
425     const int32_t focusType, AccessibilityElementInfo &elementInfo)
426 {
427     HILOG_DEBUG("focusType[%{public}d]", focusType);
428 #ifdef ACCESSIBILITY_EMULATOR_DEFINED
429     ApiReportHelper reporter("AccessibleAbilityClientImpl.GetFocusByElementInfo");
430 #endif // ACCESSIBILITY_EMULATOR_DEFINED
431     if (!isConnected_) {
432         HILOG_ERROR("connection is broken");
433         return RET_ERR_NO_CONNECTION;
434     }
435 
436     std::shared_lock<ffrt::shared_mutex> rLock(rwLock_);
437     if ((focusType != FOCUS_TYPE_INPUT) && (focusType != FOCUS_TYPE_ACCESSIBILITY)) {
438         HILOG_ERROR("focusType is not allowed.");
439         return RET_ERR_INVALID_PARAM;
440     }
441 
442     if (!channelClient_) {
443         HILOG_ERROR("The channel is invalid.");
444         return RET_ERR_NO_CONNECTION;
445     }
446 
447     int32_t windowId = sourceInfo.GetWindowId();
448     int64_t elementId = sourceInfo.GetAccessibilityId();
449     HILOG_DEBUG("windowId[%{public}d], elementId[%{public}" PRId64 "], focusType[%{public}d]",
450         windowId, elementId, focusType);
451 
452     RetError ret = channelClient_->FindFocusedElementInfo(windowId, elementId, focusType, elementInfo);
453     if (ret == RET_OK) {
454         elementInfo.SetMainWindowId(sourceInfo.GetMainWindowId());
455     }
456 #ifdef ACCESSIBILITY_EMULATOR_DEFINED
457     reporter.setResult(ret);
458 #endif // ACCESSIBILITY_EMULATOR_DEFINED
459     return ret;
460 }
461 
InjectGesture(const std::shared_ptr<AccessibilityGestureInjectPath> & gesturePath)462 RetError AccessibleAbilityClientImpl::InjectGesture(const std::shared_ptr<AccessibilityGestureInjectPath> &gesturePath)
463 {
464     HILOG_DEBUG();
465     if (!isConnected_) {
466         HILOG_ERROR("connection is broken");
467         return RET_ERR_NO_CONNECTION;
468     }
469 
470     std::shared_lock<ffrt::shared_mutex> rLock(rwLock_);
471     if (!gesturePath) {
472         HILOG_ERROR("The gesturePath is null.");
473         return RET_ERR_INVALID_PARAM;
474     }
475 
476     std::vector<AccessibilityGesturePosition> positions = gesturePath->GetPositions();
477 
478     if (positions.size() == 0) {
479         HILOG_ERROR("The number of gesture path position is not allowed.");
480         return RET_ERR_INVALID_PARAM;
481     }
482 
483     if (!channelClient_) {
484         HILOG_ERROR("The channel is invalid.");
485         return RET_ERR_NO_CONNECTION;
486     }
487 
488     Accessibility::RetError ret = channelClient_->SendSimulateGesture(gesturePath);
489     return ret;
490 }
491 
GetRoot(AccessibilityElementInfo & elementInfo,bool systemApi)492 RetError AccessibleAbilityClientImpl::GetRoot(AccessibilityElementInfo &elementInfo, bool systemApi)
493 {
494     HILOG_DEBUG();
495 #ifdef ACCESSIBILITY_EMULATOR_DEFINED
496     ApiReportHelper reporter("AccessibleAbilityClientImpl.GetRoot");
497 #endif // ACCESSIBILITY_EMULATOR_DEFINED
498     if (!isConnected_) {
499         HILOG_ERROR("connection is broken");
500         return RET_ERR_NO_CONNECTION;
501     }
502 
503     std::shared_lock<ffrt::shared_mutex> rLock(rwLock_);
504     if (CheckServiceProxy() == false) {
505         HILOG_ERROR("failed to connect to aams.");
506         return RET_ERR_SAMGR;
507     }
508 
509     if (!channelClient_) {
510         HILOG_ERROR("The channel is invalid.");
511         return RET_ERR_NO_CONNECTION;
512     }
513 
514     int32_t activeWindow = INVALID_WINDOW_ID;
515     RetError ret = static_cast<RetError>(serviceProxy_->GetActiveWindow(activeWindow, systemApi));
516     if (ret == RET_ERR_NO_PERMISSION) {
517         HILOG_ERROR("no permission");
518         return ret;
519     }
520     HILOG_DEBUG("activeWindow[%{public}d]", activeWindow);
521     if (GetCacheElementInfo(activeWindow, ROOT_NONE_ID, elementInfo)) {
522         HILOG_DEBUG("get element info from cache");
523         return RET_OK;
524     }
525 
526     ret = SearchElementInfoFromAce(activeWindow, ROOT_NONE_ID, cacheMode_, elementInfo, systemApi);
527     if (ret == RET_OK) {
528         elementInfo.SetMainWindowId(activeWindow);
529     }
530 #ifdef ACCESSIBILITY_EMULATOR_DEFINED
531     reporter.setResult(ret);
532 #endif // ACCESSIBILITY_EMULATOR_DEFINED
533     return ret;
534 }
535 
GetRootByWindow(const AccessibilityWindowInfo & windowInfo,AccessibilityElementInfo & elementInfo,bool systemApi)536 RetError AccessibleAbilityClientImpl::GetRootByWindow(const AccessibilityWindowInfo &windowInfo,
537     AccessibilityElementInfo &elementInfo, bool systemApi)
538 {
539     HILOG_DEBUG();
540     if (!isConnected_) {
541         HILOG_ERROR("connection is broken");
542         return RET_ERR_NO_CONNECTION;
543     }
544 
545     std::shared_lock<ffrt::shared_mutex> rLock(rwLock_);
546     if (!channelClient_) {
547         HILOG_ERROR("The channel is invalid.");
548         return RET_ERR_NO_CONNECTION;
549     }
550 
551     int32_t windowId = windowInfo.GetWindowId();
552     HILOG_DEBUG("windowId[%{public}d]", windowId);
553     if (GetCacheElementInfo(windowId, ROOT_NONE_ID, elementInfo)) {
554         HILOG_DEBUG("get element info from cache");
555         return RET_OK;
556     }
557 
558     RetError ret = SearchElementInfoFromAce(windowId, ROOT_NONE_ID, cacheMode_, elementInfo, systemApi);
559     if (ret == RET_OK) {
560         elementInfo.SetMainWindowId(windowId);
561     }
562     return ret;
563 }
564 
GetWindow(const int32_t windowId,AccessibilityWindowInfo & windowInfo)565 RetError AccessibleAbilityClientImpl::GetWindow(const int32_t windowId, AccessibilityWindowInfo &windowInfo)
566 {
567     HILOG_DEBUG("windowId[%{public}d]", windowId);
568 #ifdef ACCESSIBILITY_EMULATOR_DEFINED
569     ApiReportHelper reporter("AccessibleAbilityClientImpl.GetWindow");
570 #endif // ACCESSIBILITY_EMULATOR_DEFINED
571     if (!isConnected_) {
572         HILOG_ERROR("connection is broken");
573         return RET_ERR_NO_CONNECTION;
574     }
575 
576     std::shared_lock<ffrt::shared_mutex> rLock(rwLock_);
577     if (!channelClient_) {
578         HILOG_ERROR("The channel is invalid.");
579         return RET_ERR_NO_CONNECTION;
580     }
581     Accessibility::RetError ret = channelClient_->GetWindow(windowId, windowInfo);
582 #ifdef ACCESSIBILITY_EMULATOR_DEFINED
583     reporter.setResult(ret);
584 #endif // ACCESSIBILITY_EMULATOR_DEFINED
585     return ret;
586 }
587 
GetRootBatch(std::vector<AccessibilityElementInfo> & elementInfos)588 RetError AccessibleAbilityClientImpl::GetRootBatch(std::vector<AccessibilityElementInfo>& elementInfos)
589 {
590     HILOG_DEBUG();
591     if (!isConnected_) {
592         HILOG_ERROR("connection is broken");
593         return RET_ERR_NO_CONNECTION;
594     }
595 
596     std::shared_lock<ffrt::shared_mutex> rLock(rwLock_);
597     if (!channelClient_) {
598         HILOG_ERROR("channel is invalid.");
599         return RET_ERR_NO_CONNECTION;
600     }
601 
602     if (CheckServiceProxy() == false) {
603         HILOG_ERROR("failed to connect to aams.");
604         return RET_ERR_SAMGR;
605     }
606 
607     int32_t windowId = 0;
608     serviceProxy_->GetActiveWindow(windowId);
609     int64_t elementId = ROOT_NONE_ID;
610     RetError ret = SearchElementInfoRecursiveByWinid(windowId, elementId, PREFETCH_RECURSIVE_CHILDREN,
611         elementInfos, ROOT_TREE_ID);
612     if (ret != RET_OK) {
613         HILOG_ERROR("get window element failed.");
614         return ret;
615     }
616     return RET_OK;
617 }
618 
SortElementInfosIfNecessary(std::vector<AccessibilityElementInfo> & elementInfos)619 void AccessibleAbilityClientImpl::SortElementInfosIfNecessary(std::vector<AccessibilityElementInfo> &elementInfos)
620 {
621     HILOG_DEBUG();
622     std::map<int64_t, std::shared_ptr<AccessibilityElementInfo>> elementInfosMap;
623     std::vector<AccessibilityElementInfo> sortedElementInfos;
624     int64_t nodeId = NODE_ID_MAX;
625     int32_t count = 1;
626     AccessibilityElementInfo virtualRoot = elementInfos.front();
627     if (virtualRoot.GetAccessibilityId() != NODE_ID_MAX) {
628         return;
629     }
630     elementInfos.erase(elementInfos.begin());
631     for (auto &element : elementInfos) {
632         if (element.GetAccessibilityId() == NODE_ID_MAX) {
633             nodeId = NODE_ID_MAX - count;
634             element.SetAccessibilityId(nodeId);
635             element.SetParent(NODE_ID_MAX);
636             virtualRoot.AddChild(nodeId);
637             count += 1;
638         }
639         nodeId = element.GetAccessibilityId();
640         elementInfosMap[nodeId] = std::make_shared<AccessibilityElementInfo>(element);
641     }
642     elementInfosMap[NODE_ID_MAX] = std::make_shared<AccessibilityElementInfo>(virtualRoot);
643 
644     std::vector<int64_t> elementList;
645     elementList.push_back(NODE_ID_MAX);
646     uint32_t index = 0;
647     while (index < elementList.size()) {
648         auto iter = elementInfosMap.find(elementList[index]);
649         if (iter == elementInfosMap.end()) {
650             sortedElementInfos.clear();
651             elementInfos.insert(elementInfos.begin(), virtualRoot);
652             return;
653         }
654         sortedElementInfos.push_back(*(iter->second));
655         std::vector<int64_t> childNodeIds = iter->second->GetChildIds();
656         for (auto &id : childNodeIds) {
657             if (std::find(elementList.begin(), elementList.end(), id) == elementList.end()) {
658                 elementList.push_back(id);
659             }
660         }
661         index++;
662     }
663 
664     if (static_cast<int32_t>(sortedElementInfos.size()) > 0) {
665         elementInfos = sortedElementInfos;
666     }
667     elementInfosMap.clear();
668 }
669 
GetRootByWindowBatch(const AccessibilityWindowInfo & windowInfo,std::vector<AccessibilityElementInfo> & elementInfos,bool isFilter,bool needCut)670 RetError AccessibleAbilityClientImpl::GetRootByWindowBatch(const AccessibilityWindowInfo &windowInfo,
671     std::vector<AccessibilityElementInfo>& elementInfos, bool isFilter, bool needCut)
672 {
673     HILOG_DEBUG("GetRootByWindowBatch %{public}d", windowInfo.GetWindowId());
674     if (!isConnected_) {
675         HILOG_ERROR("connection is broken");
676         return RET_ERR_NO_CONNECTION;
677     }
678 
679     std::shared_lock<ffrt::shared_mutex> rLock(rwLock_);
680     if (CheckServiceProxy() == false) {
681         HILOG_ERROR("failed to connect to aams.");
682         return RET_ERR_SAMGR;
683     }
684 
685     if (!channelClient_) {
686         HILOG_ERROR("channel is invalid.");
687         return RET_ERR_NO_CONNECTION;
688     }
689 
690     int32_t windowId = windowInfo.GetWindowId();
691     int64_t elementId = ROOT_NONE_ID;
692     int32_t mode = needCut ? PREFETCH_RECURSIVE_CHILDREN_REDUCED : PREFETCH_RECURSIVE_CHILDREN;
693     RetError ret = SearchElementInfoRecursiveByWinid(windowId, elementId,
694         mode, elementInfos, ROOT_TREE_ID, isFilter);
695     if (ret != RET_OK) {
696         HILOG_ERROR("get window element failed");
697         return ret;
698     }
699     SortElementInfosIfNecessary(elementInfos);
700     return RET_OK;
701 }
702 
GetWindows(std::vector<AccessibilityWindowInfo> & windows,bool systemApi)703 RetError AccessibleAbilityClientImpl::GetWindows(std::vector<AccessibilityWindowInfo> &windows, bool systemApi)
704 {
705     HILOG_DEBUG();
706 #ifdef ACCESSIBILITY_EMULATOR_DEFINED
707     ApiReportHelper reporter("AccessibleAbilityClientImpl.GetWindows");
708 #endif // ACCESSIBILITY_EMULATOR_DEFINED
709     if (!isConnected_) {
710         HILOG_ERROR("connection is broken");
711         return RET_ERR_NO_CONNECTION;
712     }
713 
714     std::shared_lock<ffrt::shared_mutex> rLock(rwLock_);
715     if (!channelClient_) {
716         HILOG_ERROR("The channel is invalid.");
717         return RET_ERR_NO_CONNECTION;
718     }
719     Accessibility::RetError ret = channelClient_->GetWindows(windows, systemApi);
720 #ifdef ACCESSIBILITY_EMULATOR_DEFINED
721     reporter.setResult(ret);
722 #endif // ACCESSIBILITY_EMULATOR_DEFINED
723     return ret;
724 }
725 
GetWindows(const uint64_t displayId,std::vector<AccessibilityWindowInfo> & windows,bool systemApi)726 RetError AccessibleAbilityClientImpl::GetWindows(const uint64_t displayId,
727     std::vector<AccessibilityWindowInfo> &windows, bool systemApi)
728 {
729     HILOG_DEBUG("displayId[%{public}" PRIu64 "]", displayId);
730 #ifdef ACCESSIBILITY_EMULATOR_DEFINED
731     ApiReportHelper reporter("AccessibleAbilityClientImpl.GetWindows");
732 #endif // ACCESSIBILITY_EMULATOR_DEFINED
733     if (!isConnected_) {
734         HILOG_ERROR("connection is broken");
735         return RET_ERR_NO_CONNECTION;
736     }
737 
738     std::shared_lock<ffrt::shared_mutex> rLock(rwLock_);
739     if (!channelClient_) {
740         HILOG_ERROR("The channel is invalid.");
741         return RET_ERR_NO_CONNECTION;
742     }
743     Accessibility::RetError ret = channelClient_->GetWindows(displayId, windows, systemApi);
744 #ifdef ACCESSIBILITY_EMULATOR_DEFINED
745     reporter.setResult(ret);
746 #endif // ACCESSIBILITY_EMULATOR_DEFINED
747     return ret;
748 }
749 
GetNext(const AccessibilityElementInfo & elementInfo,const FocusMoveDirection direction,AccessibilityElementInfo & nextElementInfo,bool systemApi)750 RetError AccessibleAbilityClientImpl::GetNext(const AccessibilityElementInfo& elementInfo,
751     const FocusMoveDirection direction, AccessibilityElementInfo& nextElementInfo, bool systemApi)
752 {
753     HILOG_DEBUG("windowId[%{public}d], elementId[%{public}" PRId64 "], direction[%{public}d]",
754         elementInfo.GetWindowId(), elementInfo.GetAccessibilityId(), direction);
755 #ifdef ACCESSIBILITY_EMULATOR_DEFINED
756     ApiReportHelper reporter("AccessibleAbilityClientImpl.GetNext");
757 #endif // ACCESSIBILITY_EMULATOR_DEFINED
758     if (!isConnected_) {
759         HILOG_ERROR("connection is broken");
760         return RET_ERR_NO_CONNECTION;
761     }
762 
763     std::shared_lock<ffrt::shared_mutex> rLock(rwLock_);
764     if (!channelClient_) {
765         HILOG_ERROR("The channel is invalid.");
766         return RET_ERR_NO_CONNECTION;
767     }
768     if (direction == DIRECTION_INVALID) {
769         HILOG_ERROR("direction is invalid.");
770         return RET_ERR_INVALID_PARAM;
771     }
772     RetError ret = channelClient_->FocusMoveSearch(elementInfo.GetWindowId(),
773         elementInfo.GetAccessibilityId(), direction, nextElementInfo, systemApi);
774     if (ret == RET_OK) {
775         nextElementInfo.SetMainWindowId(elementInfo.GetMainWindowId());
776     }
777 #ifdef ACCESSIBILITY_EMULATOR_DEFINED
778     reporter.setResult(ret);
779 #endif // ACCESSIBILITY_EMULATOR_DEFINED
780     return ret;
781 }
782 
GetChildElementInfo(const int32_t index,const AccessibilityElementInfo & parent,AccessibilityElementInfo & child)783 RetError AccessibleAbilityClientImpl::GetChildElementInfo(const int32_t index, const AccessibilityElementInfo &parent,
784     AccessibilityElementInfo &child)
785 {
786     HILOG_DEBUG();
787 #ifdef ACCESSIBILITY_EMULATOR_DEFINED
788     ApiReportHelper reporter("AccessibleAbilityClientImpl.GetChildElementInfo");
789 #endif // ACCESSIBILITY_EMULATOR_DEFINED
790     if (!isConnected_) {
791         HILOG_ERROR("connection is broken");
792         return RET_ERR_NO_CONNECTION;
793     }
794 
795     std::shared_lock<ffrt::shared_mutex> rLock(rwLock_);
796     if (!channelClient_) {
797         HILOG_ERROR("The channel is invalid.");
798         return RET_ERR_NO_CONNECTION;
799     }
800 
801     int32_t windowId = parent.GetWindowId();
802     int64_t childId = parent.GetChildId(index);
803     HILOG_DEBUG("windowId[%{public}d], childId[%{public}" PRId64 "]", windowId, childId);
804     if (childId == -1) {
805         HILOG_ERROR("childId[%{public}" PRId64 "] is invalid", childId);
806         return RET_ERR_INVALID_PARAM;
807     }
808     if (GetCacheElementInfo(windowId, childId, child)) {
809         HILOG_DEBUG("get element info from cache");
810         return RET_OK;
811     }
812 #ifdef ACCESSIBILITY_EMULATOR_DEFINED
813     Accessibility::RetError ret = SearchElementInfoFromAce(windowId, childId, cacheMode_, child);
814     reporter.setResult(ret);
815 #endif // ACCESSIBILITY_EMULATOR_DEFINED
816     return ret;
817 }
818 
GetChildren(const AccessibilityElementInfo & parent,std::vector<AccessibilityElementInfo> & children,bool systemApi)819 RetError AccessibleAbilityClientImpl::GetChildren(const AccessibilityElementInfo &parent,
820     std::vector<AccessibilityElementInfo> &children, bool systemApi)
821 {
822     std::shared_lock<ffrt::shared_mutex> rLock(rwLock_);
823     RetError ret = CheckConnection();
824     if (ret != RET_OK) {
825         return ret;
826     }
827     int32_t windowId = parent.GetWindowId();
828     std::vector<int64_t> childIds =  parent.GetChildIds();
829     HILOG_DEBUG("windowId[%{public}d], childIds.size[%{public}zu] childTreeId:%{public}d",
830         windowId, childIds.size(), parent.GetChildTreeId());
831     std::vector<AccessibilityElementInfo> elementInfos {};
832     if ((childIds.size() == 0) && (parent.GetChildWindowId() > 0 || parent.GetChildTreeId() > 0)) {
833         if (parent.GetChildWindowId() > 0 && (parent.GetChildWindowId() != windowId)) {
834             ret = channelClient_->SearchElementInfosByAccessibilityId(parent.GetChildWindowId(), ROOT_NONE_ID,
835             GET_SOURCE_MODE, elementInfos, parent.GetChildTreeId(), false, systemApi);
836         } else if (parent.GetChildTreeId() > 0) {
837             ret = channelClient_->SearchElementInfosByAccessibilityId(parent.GetWindowId(), ROOT_NONE_ID,
838             GET_SOURCE_MODE, elementInfos, parent.GetChildTreeId(), false, systemApi);
839         }
840         if (ret != RET_OK) {
841             HILOG_ERROR("Get element info from ace failed");
842             return ret;
843         }
844         if (elementInfos.empty()) {
845             HILOG_ERROR("elementInfos from ace is empty");
846             return RET_ERR_INVALID_ELEMENT_INFO_FROM_ACE;
847         }
848         SortElementInfosIfNecessary(elementInfos);
849         children.emplace_back(elementInfos.front());
850     } else if (childIds.size() > 0 && parent.GetChildTreeId() > 0) {
851         ret = channelClient_->SearchElementInfosByAccessibilityId(parent.GetWindowId(), ROOT_NONE_ID,
852             GET_SOURCE_MODE, elementInfos, parent.GetChildTreeId(), false, systemApi);
853         if (ret != RET_OK) {
854             HILOG_ERROR("Get element info from ace failed");
855             return ret;
856         }
857         if (!elementInfos.empty()) {
858             children.emplace_back(elementInfos.front());
859         }
860     } else if (systemApi) {
861         ret = channelClient_->SearchElementInfosByAccessibilityId(parent.GetWindowId(), ROOT_NONE_ID,
862             GET_SOURCE_MODE, elementInfos, parent.GetChildTreeId(), false, systemApi);
863         if (ret == RET_ERR_NO_PERMISSION) {
864             return ret;
865         }
866     }
867     ret = GetChildrenWork(windowId, childIds, children, systemApi);
868     return ret;
869 }
870 
GetChildrenWork(const int32_t windowId,std::vector<int64_t> childIds,std::vector<AccessibilityElementInfo> & children,bool systemApi)871 RetError AccessibleAbilityClientImpl::GetChildrenWork(const int32_t windowId, std::vector<int64_t> childIds,
872     std::vector<AccessibilityElementInfo> &children, bool systemApi)
873 {
874     // at this moment, children has at most one child element from GetChildren Cross-subtree
875     // filter the element id already in children
876     int64_t crossSubtreeChildId = -1;
877     if (children.size() > 0) {
878         crossSubtreeChildId = children.front().GetAccessibilityId();
879     }
880     for (auto &childId : childIds) {
881         HILOG_DEBUG("childId[%{public}" PRId64 "]", childId);
882         if (childId == -1) {
883             HILOG_ERROR("childId is invalid");
884             return RET_ERR_INVALID_PARAM;
885         }
886         if (childId == crossSubtreeChildId) {
887             continue;
888         }
889         AccessibilityElementInfo child;
890         if (GetCacheElementInfo(windowId, childId, child)) {
891             HILOG_DEBUG("get element info from cache");
892             children.emplace_back(child);
893             continue;
894         }
895         RetError ret = SearchElementInfoFromAce(windowId, childId, cacheMode_, child, systemApi);
896         if (ret != RET_OK) {
897             HILOG_ERROR("Get element info from ace failed");
898             continue;
899         }
900         children.emplace_back(child);
901     }
902     return RET_OK;
903 }
904 
GetByContent(const AccessibilityElementInfo & elementInfo,const std::string & text,std::vector<AccessibilityElementInfo> & elementInfos,bool systemApi)905 RetError AccessibleAbilityClientImpl::GetByContent(const AccessibilityElementInfo &elementInfo,
906     const std::string &text, std::vector<AccessibilityElementInfo> &elementInfos, bool systemApi)
907 {
908     HILOG_DEBUG();
909     if (!isConnected_) {
910         HILOG_ERROR("connection is broken");
911         return RET_ERR_NO_CONNECTION;
912     }
913 
914     std::shared_lock<ffrt::shared_mutex> rLock(rwLock_);
915     if (!channelClient_) {
916         HILOG_ERROR("The channel is invalid.");
917         return RET_ERR_NO_CONNECTION;
918     }
919 
920     int32_t windowId = elementInfo.GetWindowId();
921     int64_t elementId = elementInfo.GetAccessibilityId();
922     int32_t treeId = (static_cast<uint64_t>(elementId) >> ELEMENT_MOVE_BIT);
923 
924     RetError ret = RET_ERR_FAILED;
925     if (text != "") { // find element condition is null, so we will search all element info
926         ret = channelClient_->SearchElementInfosByText(windowId, elementId, text, elementInfos, systemApi);
927         if (ret == RET_ERR_NO_PERMISSION) {
928             HILOG_ERROR("no permission");
929             return ret;
930         }
931         if (elementInfos.empty()) {
932             int32_t activeWindowId = 0;
933             serviceProxy_->GetActiveWindow(activeWindowId, systemApi);
934             ret = SearchElementInfoRecursiveByContent(activeWindowId, elementId, GET_SOURCE_MODE, elementInfos, text,
935                 ROOT_TREE_ID, systemApi);
936         }
937     } else {
938         ret = SearchElementInfoRecursiveByWinid(windowId, elementId, GET_SOURCE_MODE, elementInfos, treeId, systemApi);
939     }
940     if (!elementInfos.empty()) {
941         for (auto &element : elementInfos) {
942             element.SetMainWindowId(elementInfo.GetMainWindowId());
943         }
944     }
945     HILOG_INFO("ret:%{public}d, windowId:%{public}d, text:%{public}s", ret, windowId, text.c_str());
946     return ret;
947 }
948 
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,bool systemApi)949 RetError AccessibleAbilityClientImpl::SearchElementInfoRecursiveByContent(const int32_t windowId,
950     const int64_t elementId, uint32_t mode, std::vector<AccessibilityElementInfo> &elementInfos,
951     const std::string text, int32_t treeId, bool isFilter, bool systemApi)
952 {
953     HILOG_INFO("windowId %{public}d}, elementId %{public}" PRId64 "", windowId, elementId);
954     if (windowId <= 0) {
955         return RET_ERR_INVALID_ELEMENT_INFO_FROM_ACE;
956     }
957     std::vector<AccessibilityElementInfo> vecElementInfos = {};
958     std::vector<AccessibilityElementInfo> vecTextElementInfos = {};
959     RetError ret = channelClient_->SearchElementInfosByAccessibilityId(windowId, ROOT_NONE_ID,
960         mode, vecElementInfos, treeId, isFilter, systemApi);
961     if (ret != RET_OK) {
962         HILOG_ERROR("search element info failed. windowId %{public}d}", windowId);
963         return ret;
964     }
965     if (vecElementInfos.empty()) {
966         HILOG_ERROR("elementInfos from ace is empty");
967         return RET_ERR_INVALID_ELEMENT_INFO_FROM_ACE;
968     }
969     HILOG_DEBUG("vecElementInfos Search ok");
970     for (auto info : vecElementInfos) {
971         HILOG_DEBUG("search element info success. windowId %{public}d}",
972             info.GetChildWindowId());
973         if (info.GetParentNodeId() == ROOT_PARENT_ELEMENT_ID) {
974             ret = channelClient_->SearchElementInfosByText(windowId, info.GetAccessibilityId(),
975                 text, vecTextElementInfos, systemApi);
976             if (ret != RET_OK) {
977                 HILOG_ERROR("SearchElementInfosByText WindowId %{public}d} ret:%{public}d text:%{public}s",
978                     windowId, ret, text.c_str());
979                 return ret;
980             }
981             if (!vecTextElementInfos.empty()) {
982                 elementInfos.insert(elementInfos.end(), vecTextElementInfos.begin(), vecTextElementInfos.end());
983             }
984             HILOG_DEBUG("SearchByText get result size:%{public}zu windowId %{public}d elementId %{public}" PRId64 "",
985                 vecTextElementInfos.size(), windowId, info.GetAccessibilityId());
986         }
987         if (info.GetChildWindowId() > 0 && info.GetChildWindowId() != info.GetWindowId()) {
988             ret = SearchElementInfoRecursiveByContent(info.GetChildWindowId(),
989                 elementId, mode, elementInfos, text, info.GetChildTreeId(), isFilter, systemApi);
990         } else if (info.GetChildTreeId() > 0) {
991             ret = SearchElementInfoRecursiveByContent(info.GetWindowId(),
992                 elementId, mode, elementInfos, text, info.GetChildTreeId(), isFilter, systemApi);
993         }
994         if (ret != RET_OK) {
995             HILOG_ERROR("search element info failed.ChildWindowId %{public}d},ChildTreeId %{public}d},ret:%{public}d",
996                 info.GetChildWindowId(), info.GetChildTreeId(), ret);
997         }
998     }
999     return RET_OK;
1000 }
1001 
GetSource(const AccessibilityEventInfo & eventInfo,AccessibilityElementInfo & elementInfo)1002 RetError AccessibleAbilityClientImpl::GetSource(const AccessibilityEventInfo &eventInfo,
1003     AccessibilityElementInfo &elementInfo)
1004 {
1005     HILOG_DEBUG();
1006     if (!isConnected_) {
1007         HILOG_ERROR("connection is broken");
1008         return RET_ERR_NO_CONNECTION;
1009     }
1010 
1011     std::shared_lock<ffrt::shared_mutex> rLock(rwLock_);
1012     if (!channelClient_) {
1013         HILOG_ERROR("The channel is invalid.");
1014         return RET_ERR_NO_CONNECTION;
1015     }
1016     int32_t windowId = eventInfo.GetWindowId();
1017     int64_t elementId = eventInfo.GetAccessibilityId();
1018     HILOG_DEBUG("windowId[%{public}d], elementId[%{public}" PRId64 "]", windowId, elementId);
1019     if (GetCacheElementInfo(windowId, elementId, elementInfo)) {
1020         HILOG_DEBUG("get element info from cache");
1021         return RET_OK;
1022     }
1023     return SearchElementInfoFromAce(windowId, elementId, cacheMode_, elementInfo);
1024 }
1025 
GetParentElementInfo(const AccessibilityElementInfo & child,AccessibilityElementInfo & parent,bool systemApi)1026 RetError AccessibleAbilityClientImpl::GetParentElementInfo(const AccessibilityElementInfo &child,
1027     AccessibilityElementInfo &parent, bool systemApi)
1028 {
1029     HILOG_DEBUG("systemApi=%{public}d", systemApi);
1030     if (!isConnected_) {
1031         HILOG_ERROR("connection is broken");
1032         return RET_ERR_NO_CONNECTION;
1033     }
1034 
1035     std::shared_lock<ffrt::shared_mutex> rLock(rwLock_);
1036     if (!channelClient_) {
1037         HILOG_ERROR("The channel is invalid.");
1038         return RET_ERR_NO_CONNECTION;
1039     }
1040     int32_t windowId = child.GetWindowId();
1041     int64_t parentElementId = child.GetParentNodeId();
1042     int32_t parentWindowId = child.GetParentWindowId();
1043     int32_t treeId = 0;
1044     HILOG_DEBUG("windowId[%{public}d], parentWindowId[%{public}d], parentId[%{public}" PRId64 "]",
1045         windowId, parentWindowId, parentElementId);
1046     if (GetCacheElementInfo(windowId, parentElementId, parent)) {
1047         HILOG_DEBUG("get element info from cache");
1048         return RET_OK;
1049     }
1050     RetError ret = RET_ERR_FAILED;
1051     if ((parentElementId == ROOT_PARENT_ELEMENT_ID) && (parentWindowId > 0)) {
1052         //Get the element id of the parent by children tree id.
1053         treeId = (static_cast<uint64_t>(child.GetAccessibilityId()) >> ELEMENT_MOVE_BIT);
1054         ret = static_cast<RetError>(serviceProxy_->GetRootParentId(windowId, treeId, parentElementId, systemApi));
1055         if (ret == RET_ERR_NO_PERMISSION) {
1056             HILOG_ERROR("no permission");
1057             return ret;
1058         }
1059         if (parentElementId > 0) {
1060             treeId = (static_cast<uint64_t>(parentElementId) >> ELEMENT_MOVE_BIT);
1061             HILOG_DEBUG("find root parentId and search parentElementId [%{public}" PRId64 "] treeId[%{public}d]",
1062                 parentElementId, treeId);
1063             ret = SearchElementInfoByElementId(
1064                 child.GetParentWindowId(), parentElementId, cacheMode_, parent, treeId, systemApi);
1065             parent.SetMainWindowId(child.GetMainWindowId());
1066             return ret;
1067         } else {
1068             HILOG_DEBUG("GetRootParentId faild, parentElement:%{public}" PRId64 "", parentElementId);
1069             return RET_ERR_INVALID_ELEMENT_INFO_FROM_ACE;
1070         }
1071     }
1072     //In the same layer rendering scenario, parentElementId is not equal to ROOT_PARENT_ELEMENT_ID.
1073     //Search the parent elementId need to use the tree is of the parent node.
1074     treeId = (static_cast<uint64_t>(parentElementId) >> ELEMENT_MOVE_BIT);
1075     ret = SearchElementInfoByElementId(windowId, parentElementId, cacheMode_, parent, treeId, systemApi);
1076     parent.SetMainWindowId(child.GetMainWindowId());
1077     return ret;
1078 }
1079 
GetByElementId(const int64_t elementId,const int32_t windowId,AccessibilityElementInfo & targetElementInfo,bool systemApi)1080 RetError AccessibleAbilityClientImpl::GetByElementId(const int64_t elementId, const int32_t windowId,
1081     AccessibilityElementInfo &targetElementInfo, bool systemApi)
1082 {
1083     HILOG_DEBUG();
1084 #ifdef ACCESSIBILITY_EMULATOR_DEFINED
1085     ApiReportHelper reporter("AccessibleAbilityClientImpl.GetByElementId");
1086 #endif // ACCESSIBILITY_EMULATOR_DEFINED
1087     if (!isConnected_) {
1088         HILOG_ERROR("connection is broken");
1089         return RET_ERR_NO_CONNECTION;
1090     }
1091 
1092     std::shared_lock<ffrt::shared_mutex> rLock(rwLock_);
1093     if (CheckServiceProxy() == false) {
1094         HILOG_ERROR("failed to connect to aams.");
1095         return RET_ERR_SAMGR;
1096     }
1097 
1098     if (!channelClient_) {
1099         HILOG_ERROR("channel is invalid.");
1100         return RET_ERR_NO_CONNECTION;
1101     }
1102 
1103     int32_t treeId = (static_cast<uint64_t>(elementId) >> ELEMENT_MOVE_BIT);
1104     int32_t wid = 0;
1105     RetError ret = static_cast<RetError>(serviceProxy_->GetActiveWindow(wid, systemApi));
1106     if (ret == RET_ERR_NO_PERMISSION) {
1107         HILOG_ERROR("no permission");
1108         return ret;
1109     }
1110     wid = windowId > 0 ? windowId : wid;
1111     HILOG_DEBUG("window:[%{public}d],treeId:%{public}d,elementId:%{public}" PRId64 "",
1112         wid, treeId, elementId);
1113     if (GetCacheElementInfo(wid, elementId, targetElementInfo)) {
1114         HILOG_DEBUG("get element info from cache");
1115         return RET_OK;
1116     }
1117 
1118     ret = SearchElementInfoByElementId(wid, elementId, cacheMode_, targetElementInfo, treeId, systemApi);
1119 #ifdef ACCESSIBILITY_EMULATOR_DEFINED
1120     reporter.setResult(ret);
1121 #endif // ACCESSIBILITY_EMULATOR_DEFINED
1122     return ret;
1123 }
1124 
GetCursorPosition(const AccessibilityElementInfo & elementInfo,int32_t & position)1125 RetError AccessibleAbilityClientImpl::GetCursorPosition(const AccessibilityElementInfo &elementInfo, int32_t &position)
1126 {
1127     HILOG_DEBUG();
1128 #ifdef ACCESSIBILITY_EMULATOR_DEFINED
1129     ApiReportHelper reporter("AccessibleAbilityClientImpl.GetCursorPosition");
1130 #endif // ACCESSIBILITY_EMULATOR_DEFINED
1131     if (!isConnected_) {
1132         HILOG_ERROR("connection is broken");
1133         return RET_ERR_NO_CONNECTION;
1134     }
1135 
1136     std::shared_lock<ffrt::shared_mutex> rLock(rwLock_);
1137     if (!channelClient_) {
1138         HILOG_ERROR("The channel is invalid.");
1139         return RET_ERR_NO_CONNECTION;
1140     }
1141     int32_t windowId = elementInfo.GetWindowId();
1142     int64_t elementId = elementInfo.GetAccessibilityId();
1143     HILOG_DEBUG("windowId[%{public}d], elementId[%{public}" PRId64 "]d", windowId, elementId);
1144     Accessibility::RetError ret = channelClient_->GetCursorPosition(windowId, elementId, position);
1145 #ifdef ACCESSIBILITY_EMULATOR_DEFINED
1146     reporter.setResult(ret);
1147 #endif // ACCESSIBILITY_EMULATOR_DEFINED
1148     return ret;
1149 }
1150 
ExecuteAction(const AccessibilityElementInfo & elementInfo,const ActionType action,const std::map<std::string,std::string> & actionArguments)1151 RetError AccessibleAbilityClientImpl::ExecuteAction(const AccessibilityElementInfo &elementInfo,
1152     const ActionType action, const std::map<std::string, std::string> &actionArguments)
1153 {
1154     HILOG_DEBUG();
1155 #ifdef ACCESSIBILITY_EMULATOR_DEFINED
1156     ApiReportHelper reporter("AccessibleAbilityClientImpl.ExecuteAction");
1157 #endif // ACCESSIBILITY_EMULATOR_DEFINED
1158     if (!isConnected_) {
1159         HILOG_ERROR("connection is broken");
1160         return RET_ERR_NO_CONNECTION;
1161     }
1162 
1163     std::unique_lock<ffrt::shared_mutex> wLock(rwLock_);
1164     if (!channelClient_) {
1165         HILOG_ERROR("The channel is invalid.");
1166         return RET_ERR_NO_CONNECTION;
1167     }
1168     if (action == ACCESSIBILITY_ACTION_INVALID) {
1169         HILOG_ERROR("action is invalid.");
1170         return RET_ERR_INVALID_PARAM;
1171     }
1172     int32_t windowId = elementInfo.GetWindowId();
1173     int64_t elementId = elementInfo.GetAccessibilityId();
1174     HILOG_DEBUG("windowId[%{public}d], elementId[%{public}" PRId64 "], action[%{public}d", windowId, elementId, action);
1175     Accessibility::RetError ret = channelClient_->ExecuteAction(windowId, elementId, action,
1176         const_cast<std::map<std::string, std::string> &>(actionArguments));
1177 #ifdef ACCESSIBILITY_EMULATOR_DEFINED
1178     reporter.setResult(ret);
1179 #endif // ACCESSIBILITY_EMULATOR_DEFINED
1180     return ret;
1181 }
1182 
EnableScreenCurtain(bool isEnable)1183 RetError AccessibleAbilityClientImpl::EnableScreenCurtain(bool isEnable)
1184 {
1185 #ifdef ACCESSIBILITY_EMULATOR_DEFINED
1186     ApiReportHelper reporter("AccessibleAbilityClientImpl.EnableScreenCurtain");
1187 #endif // ACCESSIBILITY_EMULATOR_DEFINED
1188     std::shared_lock<ffrt::shared_mutex> rLock(rwLock_);
1189     if (!channelClient_) {
1190         HILOG_ERROR("The channel is invalid.");
1191         return RET_ERR_NO_CONNECTION;
1192     }
1193 
1194     Accessibility::RetError ret = channelClient_->EnableScreenCurtain(isEnable);
1195 #ifdef ACCESSIBILITY_EMULATOR_DEFINED
1196     reporter.setResult(ret);
1197 #endif // ACCESSIBILITY_EMULATOR_DEFINED
1198     return ret;
1199 }
1200 
SetTargetBundleName(const std::vector<std::string> & targetBundleNames)1201 RetError AccessibleAbilityClientImpl::SetTargetBundleName(const std::vector<std::string> &targetBundleNames)
1202 {
1203     HILOG_DEBUG("targetBundleNames size[%{public}zu]", targetBundleNames.size());
1204 #ifdef ACCESSIBILITY_EMULATOR_DEFINED
1205     ApiReportHelper reporter("AccessibleAbilityClientImpl.SetTargetBundleName");
1206 #endif // ACCESSIBILITY_EMULATOR_DEFINED
1207     if (!isConnected_) {
1208         HILOG_ERROR("connection is broken");
1209         return RET_ERR_NO_CONNECTION;
1210     }
1211 
1212     std::shared_lock<ffrt::shared_mutex> rLock(rwLock_);
1213     if (!channelClient_) {
1214         HILOG_ERROR("The channel is invalid.");
1215         return RET_ERR_NO_CONNECTION;
1216     }
1217     Accessibility::RetError ret = channelClient_->SetTargetBundleName(targetBundleNames);
1218 #ifdef ACCESSIBILITY_EMULATOR_DEFINED
1219     reporter.setResult(ret);
1220 #endif // ACCESSIBILITY_EMULATOR_DEFINED
1221     return ret;
1222 }
1223 
OnRemoteDied(const wptr<IRemoteObject> & remote)1224 void AccessibleAbilityClientImpl::AccessibleAbilityDeathRecipient::OnRemoteDied(const wptr<IRemoteObject>& remote)
1225 {
1226     HILOG_ERROR();
1227     client_.ResetAAClient(remote);
1228 }
1229 
OnRemoteDied(const wptr<IRemoteObject> & remote)1230 void AccessibleAbilityClientImpl::AccessibilityServiceDeathRecipient::OnRemoteDied(const wptr<IRemoteObject>& remote)
1231 {
1232     HILOG_ERROR();
1233     client_.NotifyServiceDied(remote);
1234 }
1235 
NotifyServiceDied(const wptr<IRemoteObject> & remote)1236 void AccessibleAbilityClientImpl::NotifyServiceDied(const wptr<IRemoteObject> &remote)
1237 {
1238     std::shared_ptr<AccessibleAbilityListener> listener = nullptr;
1239     {
1240         std::unique_lock<ffrt::shared_mutex> wLock(rwLock_);
1241         if (!serviceProxy_) {
1242             HILOG_ERROR("serviceProxy_ is nullptr");
1243             return;
1244         }
1245         sptr<IRemoteObject> object = serviceProxy_->AsObject();
1246         if (object && (remote == object)) {
1247             listener = listener_;
1248             listener_ = nullptr;
1249             object->RemoveDeathRecipient(accessibilityServiceDeathRecipient_);
1250             serviceProxy_ = nullptr;
1251             channelClient_ = nullptr;
1252             HILOG_INFO("NotifyServiceDied OK");
1253         }
1254     }
1255 
1256     isConnected_ = false;
1257     if (listener) {
1258         listener->OnAbilityDisconnected();
1259     }
1260 }
1261 
ResetAAClient(const wptr<IRemoteObject> & remote)1262 void AccessibleAbilityClientImpl::ResetAAClient(const wptr<IRemoteObject> &remote)
1263 {
1264     HILOG_DEBUG();
1265     std::unique_lock<ffrt::shared_mutex> wLock(rwLock_);
1266     if (channelClient_) {
1267         sptr<IRemoteObject> object = channelClient_->GetRemote();
1268         if (object && (remote == object)) {
1269             object->RemoveDeathRecipient(deathRecipient_);
1270             channelClient_ = nullptr;
1271             HILOG_INFO("ResetAAClient OK");
1272         }
1273     }
1274 
1275     isConnected_ = false;
1276 }
1277 
SetCacheMode(const int32_t cacheMode)1278 RetError AccessibleAbilityClientImpl::SetCacheMode(const int32_t cacheMode)
1279 {
1280     HILOG_DEBUG("set cache mode: [%{public}d]", cacheMode);
1281     std::unique_lock<ffrt::shared_mutex> wLock(rwLock_);
1282     cacheWindowId_ = -1;
1283     cacheElementInfos_.Clear();
1284     if (cacheMode < 0) {
1285         cacheMode_ = 0;
1286     } else {
1287         uint32_t mode = static_cast<uint32_t>(cacheMode);
1288         cacheMode_ = mode & static_cast<uint32_t>(GET_SOURCE_PREFETCH_MODE);
1289     }
1290     return RET_OK;
1291 }
1292 
GetCacheElementInfo(const int32_t windowId,const int64_t elementId,AccessibilityElementInfo & elementInfo)1293 bool AccessibleAbilityClientImpl::GetCacheElementInfo(const int32_t windowId,
1294     const int64_t elementId, AccessibilityElementInfo &elementInfo)
1295 {
1296     HILOG_DEBUG();
1297     if (cacheWindowId_ == -1 || cacheWindowId_ != windowId) {
1298         HILOG_DEBUG("cacheWindowId[%{public}d], windowId[%{public}d]", cacheWindowId_, windowId);
1299         return false;
1300     }
1301 
1302     bool ret = cacheElementInfos_.Find(elementId, elementInfo);
1303     return ret;
1304 }
1305 
SetCacheElementInfo(const int32_t windowId,const std::vector<OHOS::Accessibility::AccessibilityElementInfo> & elementInfos)1306 void AccessibleAbilityClientImpl::SetCacheElementInfo(const int32_t windowId,
1307     const std::vector<OHOS::Accessibility::AccessibilityElementInfo> &elementInfos)
1308 {
1309     HILOG_DEBUG("windowId[%{public}d], elementInfos size[%{public}zu]", windowId, elementInfos.size());
1310     cacheElementInfos_.Clear();
1311     cacheWindowId_ = windowId;
1312     for (auto &elementInfo : elementInfos) {
1313         cacheElementInfos_.EnsureInsert(elementInfo.GetAccessibilityId(), elementInfo);
1314     }
1315 }
1316 
SearchElementInfoByElementId(const int32_t windowId,const int64_t elementId,const uint32_t mode,AccessibilityElementInfo & info,int32_t treeId,bool systemApi)1317 RetError AccessibleAbilityClientImpl::SearchElementInfoByElementId(const int32_t windowId, const int64_t elementId,
1318     const uint32_t mode, AccessibilityElementInfo &info, int32_t treeId, bool systemApi)
1319 {
1320     if (channelClient_ == nullptr) {
1321         HILOG_ERROR("The channel is invalid.");
1322         return RET_ERR_NO_CONNECTION;
1323     }
1324 
1325     HILOG_INFO("windowId %{public}d}, elementId %{public}" PRId64 "", windowId, elementId);
1326     std::vector<AccessibilityElementInfo> elementInfos {};
1327     RetError ret = channelClient_->SearchElementInfosByAccessibilityId(
1328         windowId, elementId, static_cast<int32_t>(mode), elementInfos, treeId, false, systemApi);
1329     if (ret != RET_OK) {
1330         HILOG_ERROR("SearchElementInfosByAccessibilityId failed. windowId[%{public}d] ", windowId);
1331         return ret;
1332     }
1333     if (elementInfos.empty()) {
1334         HILOG_ERROR("elementInfos from ace is empty");
1335         return RET_ERR_INVALID_ELEMENT_INFO_FROM_ACE;
1336     }
1337 
1338     HILOG_DEBUG("element [elementSize:%{public}zu]", elementInfos.size());
1339     SetCacheElementInfo(windowId, elementInfos);
1340     info = elementInfos.front();
1341     return RET_OK;
1342 }
1343 
SearchElementInfoFromAce(const int32_t windowId,const int64_t elementId,const uint32_t mode,AccessibilityElementInfo & info,bool systemApi)1344 RetError AccessibleAbilityClientImpl::SearchElementInfoFromAce(const int32_t windowId, const int64_t elementId,
1345     const uint32_t mode, AccessibilityElementInfo &info, bool systemApi)
1346 {
1347     if (channelClient_ == nullptr) {
1348         HILOG_ERROR("The channel is invalid.");
1349         return RET_ERR_NO_CONNECTION;
1350     }
1351     HILOG_INFO("windowId %{public}d}, elementId %{public}" PRId64 "", windowId, elementId);
1352     std::vector<AccessibilityElementInfo> elementInfos {};
1353     int32_t treeId = 0;
1354     if (elementId != ROOT_NONE_ID) {
1355         treeId = (static_cast<uint64_t>(elementId) >> ELEMENT_MOVE_BIT);
1356     }
1357     RetError ret = channelClient_->SearchElementInfosByAccessibilityId(windowId, elementId,
1358         static_cast<int32_t>(mode), elementInfos, treeId, false, systemApi);
1359     if (ret != RET_OK) {
1360         HILOG_ERROR("search element info failed. windowId[%{public}d] elementId[%{public}" PRId64 "] mode[%{public}d]",
1361             windowId, elementId, mode);
1362         return ret;
1363     }
1364     if (!elementInfos.empty()) {
1365         HILOG_DEBUG("element [elementSize:%{public}zu]", elementInfos.size());
1366         SetCacheElementInfo(windowId, elementInfos);
1367         info = elementInfos.front();
1368         HILOG_DEBUG("elementId:%{public}" PRId64 ", windowId:%{public}d, treeId:%{public}d",
1369             info.GetAccessibilityId(), info.GetWindowId(), info.GetBelongTreeId());
1370         return RET_OK;
1371     }
1372 
1373     HILOG_DEBUG("elementInfos from ace is empty find all element");
1374     ret = SearchElementInfoRecursiveByWinid(
1375         windowId, ROOT_NONE_ID, GET_SOURCE_MODE, elementInfos, ROOT_TREE_ID, systemApi);
1376     if (ret != RET_OK) {
1377         HILOG_ERROR("SearchElementInfoRecursiveByWinid failed. windowId[%{public}d]", windowId);
1378         return ret;
1379     }
1380     HILOG_DEBUG("SetCacheElementInfo windowId:%{public}d, element [elementSize:%{public}zu]", windowId,
1381         elementInfos.size());
1382     SetCacheElementInfo(windowId, elementInfos);
1383     if (!GetCacheElementInfo(windowId, elementId, info)) {
1384         return RET_ERR_INVALID_ELEMENT_INFO_FROM_ACE;
1385     }
1386     info.SetMainWindowId(windowId);
1387     HILOG_DEBUG("elementId:%{public}" PRId64 ", windowId:%{public}d, treeId:%{public}d",
1388         info.GetAccessibilityId(), info.GetWindowId(), info.GetBelongTreeId());
1389     return RET_OK;
1390 }
1391 
SearchElementInfoByInspectorKey(const std::string & inspectorKey,AccessibilityElementInfo & elementInfo)1392 RetError AccessibleAbilityClientImpl::SearchElementInfoByInspectorKey(const std::string &inspectorKey,
1393     AccessibilityElementInfo &elementInfo)
1394 {
1395     HILOG_DEBUG();
1396     if (!isConnected_) {
1397         HILOG_ERROR("connection is broken");
1398         return RET_ERR_NO_CONNECTION;
1399     }
1400 
1401     std::shared_lock<ffrt::shared_mutex> rLock(rwLock_);
1402     if (!channelClient_) {
1403         HILOG_ERROR("The channel is invalid.");
1404         return RET_ERR_NO_CONNECTION;
1405     }
1406 
1407     if (CheckServiceProxy() == false) {
1408         HILOG_ERROR("failed to connect to aams.");
1409         return RET_ERR_SAMGR;
1410     }
1411 
1412     int32_t windowId = 0;
1413     serviceProxy_->GetActiveWindow(windowId);
1414     HILOG_DEBUG("windowId[%{public}d]", windowId);
1415     std::vector<AccessibilityElementInfo> infos {};
1416     std::vector<AccessibilityElementInfo> elementInfos {};
1417 
1418     SpecificPropertyParam param;
1419     param.propertyTarget = inspectorKey;
1420     param.propertyType = SEARCH_TYPE::CUSTOMID;
1421 
1422     RetError ret = channelClient_->SearchElementInfosBySpecificProperty(windowId, ROOT_NONE_ID, param,
1423         infos, elementInfos, ROOT_TREE_ID);
1424     if (ret != RET_OK) {
1425         HILOG_ERROR("search element info failed.");
1426         return ret;
1427     }
1428 
1429     if (!infos.empty()) {
1430         HILOG_INFO("find elementInfo by inspectorKey success in infos (single element), inspectorKey: %{public}s",
1431             inspectorKey.c_str());
1432         elementInfo = infos.front();
1433         elementInfo.SetMainWindowId(windowId);
1434         HILOG_DEBUG("DEBUG: returned elementInfo inspectorKey: %{public}s", elementInfo.GetInspectorKey().c_str());
1435         return RET_OK;
1436     }
1437 
1438     if (!elementInfos.empty()) {
1439         HILOG_DEBUG("Found elements in elementInfos, searching with recursive logic. Size: %{public}zu",
1440             elementInfos.size());
1441         for (auto& treeParentInfo : elementInfos) {
1442             std::vector<AccessibilityElementInfo> newInfos {};
1443             HILOG_DEBUG("SearchElementInfoRecursiveByWinid :search element info success. windowId %{public}d}",
1444                 treeParentInfo.GetChildWindowId());
1445             if (treeParentInfo.GetChildTreeId() > 0) {
1446                 ret = SearchElementInfoRecursiveBySpecificProperty(treeParentInfo.GetChildWindowId(),
1447                     ROOT_NONE_ID, newInfos, treeParentInfo.GetChildTreeId(), 0, param);
1448                 HILOG_DEBUG("ChildWindowId %{public}d}. ret:%{public}d, GetChildTreeId %{public}d",
1449                     treeParentInfo.GetChildWindowId(), ret, treeParentInfo.GetChildTreeId());
1450                 if (!newInfos.empty()) {
1451                     HILOG_INFO("find elementInfo1 by inspectorKey success in infos, inspectorKey: %{public}s",
1452                         inspectorKey.c_str());
1453                     elementInfo = newInfos.front();
1454                     elementInfo.SetMainWindowId(windowId);
1455                     return RET_OK;
1456                 }
1457             }
1458         }
1459     }
1460 
1461     HILOG_INFO("SearchElementInfoByInspectorKey failed, inspectorKey: %{public}s", inspectorKey.c_str());
1462     return RET_ERR_FAILED;
1463 }
1464 
Connect()1465 RetError AccessibleAbilityClientImpl::Connect()
1466 {
1467     HILOG_DEBUG();
1468     std::shared_lock<ffrt::shared_mutex> rLock(rwLock_);
1469     if (CheckServiceProxy() == false) {
1470         HILOG_ERROR("failed to connect to aams.");
1471         return RET_ERR_SAMGR;
1472     }
1473 
1474     return static_cast<RetError>(serviceProxy_->EnableUITestAbility(this->AsObject()));
1475 }
1476 
Disconnect()1477 RetError AccessibleAbilityClientImpl::Disconnect()
1478 {
1479     HILOG_DEBUG();
1480     std::shared_lock<ffrt::shared_mutex> rLock(rwLock_);
1481     if (CheckServiceProxy() == false) {
1482         HILOG_ERROR("failed to connect to aams.");
1483         return RET_ERR_SAMGR;
1484     }
1485     return static_cast<RetError>(serviceProxy_->DisableUITestAbility());
1486 }
1487 
SetConnectionState(bool state)1488 void AccessibleAbilityClientImpl::SetConnectionState(bool state)
1489 {
1490     isConnected_ = state;
1491 }
1492 
AddWindowElementMapByWMS(int32_t windowId,int64_t elementId)1493 void AccessibleAbilityClientImpl::AddWindowElementMapByWMS(int32_t windowId, int64_t elementId)
1494 {
1495     // only used for scene board window, non scene board window not need window element map
1496     int32_t realWindowId = windowId;
1497     int64_t realElementId = elementId;
1498     serviceProxy_->GetRealWindowAndElementId(realWindowId, realElementId);
1499     HILOG_DEBUG("windowId %{public}d, real windowId %{public}d, real elementId %{public}" PRId64 "",
1500         windowId, realWindowId, realElementId);
1501     if (windowId != realElementId) {
1502         windowElementMap_.AddWindowElementIdPair(windowId, realElementId);
1503     }
1504 }
1505 
AddWindowElementMapByAce(int32_t windowId,int64_t elementId)1506 void AccessibleAbilityClientImpl::AddWindowElementMapByAce(int32_t windowId, int64_t elementId)
1507 {
1508     // only used for scene board window, non scene board window not need window element map
1509     if (windowId == SCENE_BOARD_WINDOW_ID) {
1510         int32_t innerWid = INVALID_SCENE_BOARD_INNER_WINDOW_ID;
1511         serviceProxy_->GetSceneBoardInnerWinId(windowId, elementId, innerWid);
1512         HILOG_DEBUG("windowId %{public}d, elementId %{public}" PRId64 ", innerWid %{public}d",
1513             windowId, elementId, innerWid);
1514         if (innerWid != INVALID_SCENE_BOARD_INNER_WINDOW_ID) {
1515             windowElementMap_.AddWindowElementIdPair(innerWid, elementId);
1516         }
1517     }
1518 }
1519 
GetElementInfoFromCache(int32_t windowId,int64_t elementId,std::vector<AccessibilityElementInfo> & elementInfos)1520 RetError AccessibleAbilityClientImpl::GetElementInfoFromCache(int32_t windowId, int64_t elementId,
1521     std::vector<AccessibilityElementInfo> &elementInfos)
1522 {
1523     if (windowId == SCENE_BOARD_WINDOW_ID) { // sceneboard window id
1524         if (elementCacheInfo_.GetElementByWindowId(windowId, elementId, elementInfos)) {
1525             HILOG_DEBUG("get element info from cache");
1526             return RET_OK;
1527         }
1528 
1529         std::vector<int32_t> windowsList = windowElementMap_.GetWindowIdList();
1530         for (auto tmpWindowId : windowsList) {
1531             if (elementCacheInfo_.GetElementByWindowId(tmpWindowId, elementId, elementInfos)) {
1532                 HILOG_DEBUG("get element info from cache");
1533                 return RET_OK;
1534             }
1535         }
1536     } else {
1537         if (elementCacheInfo_.GetElementByWindowId(windowId, elementId, elementInfos)) {
1538             HILOG_DEBUG("get element info from cache");
1539             return RET_OK;
1540         }
1541     }
1542 
1543     return RET_ERR_FAILED;
1544 }
1545 
SearchElementInfoRecursive(int32_t windowId,int64_t elementId,uint32_t mode,std::vector<AccessibilityElementInfo> & elementInfos,bool isFilter)1546 RetError AccessibleAbilityClientImpl::SearchElementInfoRecursive(int32_t windowId, int64_t elementId, uint32_t mode,
1547     std::vector<AccessibilityElementInfo> &elementInfos, bool isFilter)
1548 {
1549     HILOG_INFO("windowId %{public}d}, elementId %{public}" PRId64 "", windowId, elementId);
1550     RetError ret = channelClient_->SearchElementInfosByAccessibilityId(windowId, elementId,
1551         mode, elementInfos, ROOT_TREE_ID, isFilter);
1552     if (ret != RET_OK) {
1553         HILOG_ERROR("search element info failed. windowId %{public}d elementId %{public}" PRId64 "",
1554             windowId, elementId);
1555         return ret;
1556     }
1557 
1558     if (elementInfos.empty()) {
1559         HILOG_ERROR("elementInfos from ace is empty");
1560         return RET_ERR_INVALID_ELEMENT_INFO_FROM_ACE;
1561     }
1562 
1563     return RET_OK;
1564 }
1565 
SearchElementInfoRecursiveByWinid(const int32_t windowId,const int64_t elementId,uint32_t mode,std::vector<AccessibilityElementInfo> & elementInfos,int32_t treeId,bool isFilter,uint64_t parentIndex,bool systemApi)1566 RetError AccessibleAbilityClientImpl::SearchElementInfoRecursiveByWinid(const int32_t windowId,
1567     const int64_t elementId, uint32_t mode, std::vector<AccessibilityElementInfo> &elementInfos,
1568     int32_t treeId, bool isFilter, uint64_t parentIndex, bool systemApi)
1569 {
1570     HILOG_INFO("windowId %{public}d}, elementId %{public}" PRId64 ", treeId %{public}d, mode %{public}d",
1571         windowId, elementId, treeId, mode);
1572     if (windowId <= 0) {
1573         HILOG_ERROR("window Id is failed windowId %{public}d", windowId);
1574         return RET_ERR_INVALID_ELEMENT_INFO_FROM_ACE;
1575     }
1576     std::vector<AccessibilityElementInfo> vecElementInfos {};
1577     RetError ret = channelClient_->SearchElementInfosByAccessibilityId(windowId, elementId,
1578         mode, vecElementInfos, treeId, isFilter, systemApi);
1579     if (ret != RET_OK) {
1580         HILOG_ERROR("search element info failed. windowId %{public}d}", windowId);
1581         return ret;
1582     }
1583     if (vecElementInfos.empty()) {
1584         HILOG_ERROR("elementInfos from ace is empty");
1585         return RET_ERR_INVALID_ELEMENT_INFO_FROM_ACE;
1586     }
1587     SortElementInfosIfNecessary(vecElementInfos);
1588     uint64_t elementInfosCountAdded = 0;
1589     uint64_t elementInfosCount = elementInfos.size();
1590     for (auto info : vecElementInfos) {
1591         if ((info.GetParentNodeId() == ROOT_PARENT_ELEMENT_ID) && parentIndex >=0 &&
1592             parentIndex < elementInfos.size()) {
1593             elementInfos[parentIndex].AddChild(info.GetAccessibilityId());
1594             info.SetParent(elementInfos[parentIndex].GetAccessibilityId());
1595             HILOG_DEBUG("Give the father a child. %{public}" PRId64 ",Give the child a father.  %{public}" PRId64 "",
1596                 info.GetAccessibilityId(), elementInfos[parentIndex].GetAccessibilityId());
1597         }
1598         elementInfos.push_back(info);
1599         elementInfosCountAdded++;
1600     }
1601     for (uint64_t i = elementInfosCount; i < elementInfosCount + elementInfosCountAdded; i++) {
1602         HILOG_DEBUG("SearchElementInfoRecursiveByWinid :search element info success. windowId %{public}d",
1603             elementInfos[i].GetChildWindowId());
1604         if ((elementInfos[i].GetChildWindowId() > 0) &&
1605             (elementInfos[i].GetChildWindowId() != elementInfos[i].GetWindowId())) {
1606             ret = SearchElementInfoRecursiveByWinid(elementInfos[i].GetChildWindowId(),
1607                 ROOT_NONE_ID, mode, elementInfos, elementInfos[i].GetChildTreeId(), isFilter, i, systemApi);
1608             HILOG_INFO("ChildWindowId %{public}d}. ret:%{public}d, GetChildTreeId %{public}d",
1609                 elementInfos[i].GetChildWindowId(), ret, elementInfos[i].GetChildTreeId());
1610         } else if (elementInfos[i].GetChildTreeId() > 0 && elementInfos[i].GetChildTreeId() != treeId) {
1611             ret = SearchElementInfoRecursiveByWinid(elementInfos[i].GetWindowId(),
1612                 ROOT_NONE_ID, mode, elementInfos, elementInfos[i].GetChildTreeId(), isFilter, i, systemApi);
1613             HILOG_INFO("windowId %{public}d}.treeId:%{public}d. ret:%{public}d",
1614                 elementInfos[i].GetWindowId(), elementInfos[i].GetChildTreeId(), ret);
1615         }
1616     }
1617     return RET_OK;
1618 }
1619 
RemoveCacheData(const AccessibilityEventInfo & eventInfo)1620 void AccessibleAbilityClientImpl::RemoveCacheData(const AccessibilityEventInfo& eventInfo)
1621 {
1622     EventType type = eventInfo.GetEventType();
1623     if (type == TYPE_VIEW_TEXT_UPDATE_EVENT || type == TYPE_PAGE_STATE_UPDATE ||
1624         type == TYPE_NOTIFICATION_UPDATE_EVENT || type == TYPE_PAGE_CONTENT_UPDATE ||
1625         type == TYPE_VIEW_TEXT_SELECTION_UPDATE_EVENT || type == TYPE_WINDOW_UPDATE) {
1626         int32_t windowId = eventInfo.GetWindowId();
1627         HILOG_DEBUG("RemoveCacheData windowId %{public}d", windowId);
1628         if (windowId == SCENE_BOARD_WINDOW_ID) {
1629             elementCacheInfo_.RemoveElementByWindowId(windowId);
1630             windowElementMap_.RemovePairByWindowId(windowId);
1631 
1632             auto windowList = windowElementMap_.GetWindowIdList();
1633             windowElementMap_.RemovePairByWindowIdList(windowList);
1634             for (auto window: windowList) {
1635                 elementCacheInfo_.RemoveElementByWindowId(window);
1636             }
1637         } else {
1638             elementCacheInfo_.RemoveElementByWindowId(windowId);
1639             windowElementMap_.RemovePairByWindowId(windowId);
1640         }
1641     }
1642 }
1643 
AddCacheByWMS(int32_t windowId,int64_t elementId,std::vector<AccessibilityElementInfo> & elementInfos)1644 void AccessibleAbilityClientImpl::AddCacheByWMS(int32_t windowId, int64_t elementId,
1645     std::vector<AccessibilityElementInfo>& elementInfos)
1646 {
1647     HILOG_DEBUG("elementSize %{public}zu", elementInfos.size());
1648     AddWindowElementMapByWMS(windowId, elementId);
1649     elementCacheInfo_.AddElementCache(windowId, elementInfos);
1650 }
1651 
AddCacheByAce(int32_t windowId,int64_t elementId,std::vector<AccessibilityElementInfo> & elementInfos)1652 void AccessibleAbilityClientImpl::AddCacheByAce(int32_t windowId, int64_t elementId,
1653     std::vector<AccessibilityElementInfo>& elementInfos)
1654 {
1655     AddWindowElementMapByAce(windowId, elementId);
1656     HILOG_DEBUG("elementSize %{public}zu", elementInfos.size());
1657     if (windowId == SCENE_BOARD_WINDOW_ID) {
1658         windowId = windowElementMap_.GetWindowIdByElementId(elementId);
1659         HILOG_DEBUG("windowId convert to %{public}d", windowId);
1660         if (windowId == INVALID_SCENE_BOARD_INNER_WINDOW_ID) {
1661             elementCacheInfo_.AddElementCache(SCENE_BOARD_WINDOW_ID, elementInfos);
1662         } else {
1663             elementCacheInfo_.AddElementCache(windowId, elementInfos);
1664         }
1665     } else {
1666         elementCacheInfo_.AddElementCache(windowId, elementInfos);
1667     }
1668 }
1669 
SearchElementInfoByAccessibilityId(const int32_t windowId,const int64_t elementId,const uint32_t mode,AccessibilityElementInfo & info,bool isFilter)1670 RetError AccessibleAbilityClientImpl::SearchElementInfoByAccessibilityId(const int32_t windowId,
1671     const int64_t elementId, const uint32_t mode, AccessibilityElementInfo &info, bool isFilter)
1672 {
1673     HILOG_DEBUG();
1674     if (isConnected_ == false) {
1675         HILOG_ERROR("connection is broken.");
1676         return RET_ERR_NO_CONNECTION;
1677     }
1678 
1679     std::shared_lock<ffrt::shared_mutex> rLock(rwLock_);
1680     if (CheckServiceProxy() == false) {
1681         HILOG_ERROR("failed to connect to aams.");
1682         return RET_ERR_SAMGR;
1683     }
1684     if (channelClient_ == nullptr) {
1685         HILOG_ERROR("the channel is invalid.");
1686         return RET_ERR_NO_CONNECTION;
1687     }
1688     std::vector<AccessibilityElementInfo> elementInfos {};
1689     int32_t treeId = 0;
1690     if (elementId > 0) {
1691         treeId = (static_cast<uint64_t>(elementId) >> ELEMENT_MOVE_BIT);
1692     }
1693     RetError ret = channelClient_->SearchElementInfosByAccessibilityId(windowId,
1694         elementId, static_cast<int32_t>(mode), elementInfos, treeId, isFilter);
1695     if (ret != RET_OK) {
1696         HILOG_ERROR("search element info failed, ret = %{public}d.", ret);
1697         return ret;
1698     }
1699     if (elementInfos.empty()) {
1700         HILOG_ERROR("elementInfos from ace is empty.");
1701         return RET_ERR_INVALID_ELEMENT_INFO_FROM_ACE;
1702     }
1703 
1704     SetCacheElementInfo(windowId, elementInfos);
1705     info = elementInfos.front();
1706     info.SetMainWindowId(windowId);
1707     return RET_OK;
1708 }
1709 
AddElementCache(const int32_t windowId,const std::vector<AccessibilityElementInfo> & elementInfos)1710 void AccessibleAbilityClientImpl::ElementCacheInfo::AddElementCache(const int32_t windowId,
1711     const std::vector<AccessibilityElementInfo>& elementInfos)
1712 {
1713     std::lock_guard<ffrt::mutex> lock(elementCacheMutex_);
1714     if (windowIdSet_.size() >= MAX_CACHE_WINDOW_SIZE) {
1715         auto winId = windowIdSet_.front();
1716         windowIdSet_.pop_front();
1717         elementCache_.erase(winId);
1718     }
1719 
1720     elementCache_.erase(windowId);
1721 
1722     std::map<int32_t, std::shared_ptr<AccessibilityElementInfo>> cache;
1723     for (auto& elementInfo : elementInfos) {
1724         int64_t elementId = elementInfo.GetAccessibilityId();
1725         cache[elementId] = std::make_shared<AccessibilityElementInfo>(elementInfo);
1726     }
1727 
1728     elementCache_[windowId] = std::move(cache);
1729     windowIdSet_.push_back(windowId);
1730 }
1731 
GetElementByWindowIdBFS(const int64_t realElementId,std::vector<AccessibilityElementInfo> & elementInfos,std::map<int32_t,std::shared_ptr<AccessibilityElementInfo>> & cache)1732 bool AccessibleAbilityClientImpl::ElementCacheInfo::GetElementByWindowIdBFS(const int64_t realElementId,
1733     std::vector<AccessibilityElementInfo>& elementInfos,
1734     std::map<int32_t, std::shared_ptr<AccessibilityElementInfo>>& cache)
1735 {
1736     std::vector<int64_t> elementList;
1737     elementList.push_back(realElementId);
1738     uint32_t index = 0;
1739     while (index < elementList.size()) {
1740         auto iter = cache.find(elementList[index]);
1741         if (iter == cache.end()) {
1742             elementInfos.clear();
1743             HILOG_DEBUG("element data abnormal, clear elementInfos");
1744             return false;
1745         }
1746 
1747         elementInfos.push_back(*(iter->second));
1748         std::vector<int64_t> childrenNode = iter->second->GetChildIds();
1749         for (auto& node : childrenNode) {
1750             elementList.push_back(node);
1751         }
1752         index++;
1753     }
1754     return true;
1755 }
1756 
1757 // window id is true, element id is true
GetElementByWindowId(const int32_t windowId,const int64_t elementId,std::vector<AccessibilityElementInfo> & elementInfos)1758 bool AccessibleAbilityClientImpl::ElementCacheInfo::GetElementByWindowId(const int32_t windowId,
1759     const int64_t elementId, std::vector<AccessibilityElementInfo>& elementInfos)
1760 {
1761     elementInfos.clear(); // clear
1762     std::lock_guard<ffrt::mutex> lock(elementCacheMutex_);
1763     if (elementCache_.find(windowId) == elementCache_.end()) {
1764         HILOG_DEBUG("windowId %{public}d is not existed", windowId);
1765         return false;
1766     }
1767 
1768     auto& cache = elementCache_.find(windowId)->second;
1769     if (cache.size() == 0) {
1770         HILOG_DEBUG("windowId %{public}d element is null", windowId);
1771         return false;
1772     }
1773 
1774     if (cache.find(elementId) == cache.end() && elementId != ROOT_NONE_ID) {
1775         HILOG_DEBUG("elementId %{public}" PRId64 " is not existed", elementId);
1776         return false;
1777     }
1778 
1779     int64_t realElementId = elementId;
1780     if (realElementId == ROOT_NONE_ID) {
1781         for (auto iter = cache.begin(); iter != cache.end(); iter++) {
1782             if (iter->second->GetComponentType() == "root") {
1783                 realElementId = iter->first;
1784                 HILOG_DEBUG("find realElementId %{public}" PRId64 "", realElementId);
1785                 break;
1786             }
1787         }
1788     }
1789 
1790     if (realElementId == ROOT_NONE_ID) {
1791         HILOG_ERROR("elementId %{public}" PRId64 " is not existed", realElementId);
1792         return false;
1793     }
1794 
1795     if (!GetElementByWindowIdBFS(realElementId, elementInfos, cache)) {
1796         HILOG_DEBUG("get window element fail");
1797         return false;
1798     }
1799 
1800     HILOG_DEBUG("get element info success, element size %{public}zu", elementInfos.size());
1801     return true;
1802 }
1803 
RemoveElementByWindowId(const int32_t windowId)1804 void AccessibleAbilityClientImpl::ElementCacheInfo::RemoveElementByWindowId(const int32_t windowId)
1805 {
1806     std::lock_guard<ffrt::mutex> lock(elementCacheMutex_);
1807     HILOG_DEBUG("erase windowId %{public}d cache", windowId);
1808     for (auto iter = windowIdSet_.begin(); iter != windowIdSet_.end(); iter++) {
1809         if (*iter == windowId) {
1810             windowIdSet_.erase(iter);
1811             break;
1812         }
1813     }
1814 
1815     elementCache_.erase(windowId);
1816 }
1817 
IsExistWindowId(int32_t windowId)1818 bool AccessibleAbilityClientImpl::ElementCacheInfo::IsExistWindowId(int32_t windowId)
1819 {
1820     std::lock_guard<ffrt::mutex> lock(elementCacheMutex_);
1821     for (auto iter = windowIdSet_.begin(); iter != windowIdSet_.end(); iter++) {
1822         if (*iter == windowId) {
1823             return true;
1824         }
1825     }
1826 
1827     return false;
1828 }
1829 
IsExistWindowId(int32_t windowId)1830 bool AccessibleAbilityClientImpl::SceneBoardWindowElementMap::IsExistWindowId(int32_t windowId)
1831 {
1832     std::lock_guard<ffrt::mutex> lock(mapMutex_);
1833     if (windowElementMap_.find(windowId) != windowElementMap_.end()) {
1834         return true;
1835     }
1836 
1837     return false;
1838 }
1839 
AddWindowElementIdPair(int32_t windowId,int64_t elementId)1840 void AccessibleAbilityClientImpl::SceneBoardWindowElementMap::AddWindowElementIdPair(int32_t windowId,
1841     int64_t elementId)
1842 {
1843     std::lock_guard<ffrt::mutex> lock(mapMutex_);
1844     windowElementMap_[windowId] = elementId;
1845 }
1846 
GetWindowIdList()1847 std::vector<int32_t> AccessibleAbilityClientImpl::SceneBoardWindowElementMap::GetWindowIdList()
1848 {
1849     std::lock_guard<ffrt::mutex> lock(mapMutex_);
1850     std::vector<int32_t> windowList;
1851     for (auto iter = windowElementMap_.begin(); iter != windowElementMap_.end(); iter++) {
1852         windowList.push_back(iter->first);
1853     }
1854 
1855     return windowList;
1856 }
1857 
GetWindowIdByElementId(int64_t elementId)1858 int32_t AccessibleAbilityClientImpl::SceneBoardWindowElementMap::GetWindowIdByElementId(int64_t elementId)
1859 {
1860     std::lock_guard<ffrt::mutex> lock(mapMutex_);
1861     for (auto iter = windowElementMap_.begin(); iter != windowElementMap_.end(); iter++) {
1862         if (iter->second == elementId) {
1863             return iter->first;
1864         }
1865     }
1866 
1867     return INVALID_SCENE_BOARD_INNER_WINDOW_ID;
1868 }
1869 
RemovePairByWindowIdList(std::vector<int32_t> & windowIdList)1870 void AccessibleAbilityClientImpl::SceneBoardWindowElementMap::RemovePairByWindowIdList(
1871     std::vector<int32_t>& windowIdList)
1872 {
1873     std::lock_guard<ffrt::mutex> lock(mapMutex_);
1874     for (auto windowId : windowIdList) {
1875         windowElementMap_.erase(windowId);
1876     }
1877 }
1878 
RemovePairByWindowId(int32_t windowId)1879 void AccessibleAbilityClientImpl::SceneBoardWindowElementMap::RemovePairByWindowId(int32_t windowId)
1880 {
1881     std::lock_guard<ffrt::mutex> lock(mapMutex_);
1882     windowElementMap_.erase(windowId);
1883 }
1884 
OnLoadSystemAbilitySuccess(int32_t systemAbilityId,const sptr<IRemoteObject> & remoteObject)1885 void AccessibleAbilityClientImpl::AccessibilityLoadCallback::OnLoadSystemAbilitySuccess(int32_t systemAbilityId,
1886     const sptr<IRemoteObject> &remoteObject)
1887 {
1888     if (AccessibleAbilityClientImpl::GetAbilityClientImplement()) {
1889         AccessibleAbilityClientImpl::GetAbilityClientImplement()->LoadSystemAbilitySuccess(remoteObject);
1890     }
1891 }
1892 
OnLoadSystemAbilityFail(int32_t systemAbilityId)1893 void AccessibleAbilityClientImpl::AccessibilityLoadCallback::OnLoadSystemAbilityFail(int32_t systemAbilityId)
1894 {
1895     if (AccessibleAbilityClientImpl::GetAbilityClientImplement()) {
1896         AccessibleAbilityClientImpl::GetAbilityClientImplement()->LoadSystemAbilityFail();
1897     }
1898 }
1899 
GetElements(const int32_t windowId,const int64_t elementId,std::vector<AccessibilityElementInfo> & elementInfos)1900 RetError AccessibleAbilityClientImpl::GetElements(const int32_t windowId, const int64_t elementId,
1901     std::vector<AccessibilityElementInfo> &elementInfos)
1902 {
1903 #ifdef OHOS_BUILD_ENABLE_HITRACE
1904     HITRACE_METER_NAME(HITRACE_TAG_ACCESSIBILITY_MANAGER, "GetElements");
1905 #endif // OHOS_BUILD_ENABLE_HITRACE
1906     if (windowId <= 0 || elementId < -1) {
1907         HILOG_ERROR("invalid param.");
1908         return RET_ERR_INVALID_PARAM;
1909     }
1910     if (!isConnected_) {
1911         HILOG_ERROR("connection is broken");
1912         return RET_ERR_NO_CONNECTION;
1913     }
1914 
1915     std::shared_lock<ffrt::shared_mutex> rLock(rwLock_);
1916     if (!channelClient_) {
1917         HILOG_ERROR("The channel is invalid.");
1918         return RET_ERR_NO_CONNECTION;
1919     }
1920 
1921     if (CheckServiceProxy() == false) {
1922         HILOG_ERROR("failed to connect to aams.");
1923         return RET_ERR_SAMGR;
1924     }
1925 
1926     int32_t treeId = ROOT_TREE_ID;
1927     if (elementId > 0) {
1928         treeId = (static_cast<uint64_t>(elementId) >> ELEMENT_MOVE_BIT);
1929     }
1930 
1931     RetError ret = SearchElementInfoRecursiveByWinid(windowId, elementId, GET_SOURCE_MODE, elementInfos, treeId);
1932     if (!elementInfos.empty() && elementInfos[0].GetAccessibilityId() == elementId) {
1933         elementInfos.erase(elementInfos.begin());
1934     }
1935     HILOG_INFO("windowId: %{public}d, elementId: %{public}" PRId64 ", ret: %{public}d, size: %{public}zu",
1936         windowId, elementId, ret, elementInfos.size());
1937     return ret;
1938 }
1939 
GetDefaultFocusedElementIds(const int32_t windowId,std::vector<AccessibilityElementInfo> & elementInfos)1940 RetError AccessibleAbilityClientImpl::GetDefaultFocusedElementIds(const int32_t windowId,
1941     std::vector<AccessibilityElementInfo> &elementInfos)
1942 {
1943     HITRACE_METER_NAME(HITRACE_TAG_ACCESSIBILITY_MANAGER, "GetDefaultFocusedElementIds");
1944     if (windowId <= 0) {
1945         HILOG_ERROR("invalid param.");
1946         return RET_ERR_INVALID_PARAM;
1947     }
1948     if (!isConnected_) {
1949         HILOG_ERROR("connection is broken");
1950         return RET_ERR_NO_CONNECTION;
1951     }
1952 
1953     std::shared_lock<ffrt::shared_mutex> rLock(rwLock_);
1954     if (!channelClient_) {
1955         HILOG_ERROR("The channel is invalid.");
1956         return RET_ERR_NO_CONNECTION;
1957     }
1958 
1959     return channelClient_->SearchDefaultFocusedByWindowId(windowId, ROOT_NONE_ID,
1960         GET_SOURCE_MODE, elementInfos, ROOT_TREE_ID);
1961 }
1962 
HoldRunningLock()1963 RetError AccessibleAbilityClientImpl::HoldRunningLock()
1964 {
1965 #ifdef ACCESSIBILITY_EMULATOR_DEFINED
1966     ApiReportHelper reporter("AccessibleAbilityClientImpl.HoldRunningLock");
1967 #endif // ACCESSIBILITY_EMULATOR_DEFINED
1968     std::shared_lock<ffrt::shared_mutex> rLock(rwLock_);
1969     if (!channelClient_) {
1970         HILOG_ERROR("The channel is invalid.");
1971         return RET_ERR_NO_CONNECTION;
1972     }
1973 
1974     Accessibility::RetError ret = channelClient_->HoldRunningLock();
1975 #ifdef ACCESSIBILITY_EMULATOR_DEFINED
1976     reporter.setResult(ret);
1977 #endif // ACCESSIBILITY_EMULATOR_DEFINED
1978     return ret;
1979 }
1980 
UnholdRunningLock()1981 RetError AccessibleAbilityClientImpl::UnholdRunningLock()
1982 {
1983 #ifdef ACCESSIBILITY_EMULATOR_DEFINED
1984     ApiReportHelper reporter("AccessibleAbilityClientImpl.UnholdRunningLock");
1985 #endif // ACCESSIBILITY_EMULATOR_DEFINED
1986     std::shared_lock<ffrt::shared_mutex> rLock(rwLock_);
1987     if (!channelClient_) {
1988         HILOG_ERROR("The channel is invalid.");
1989         return RET_ERR_NO_CONNECTION;
1990     }
1991 
1992     Accessibility::RetError ret = channelClient_->UnholdRunningLock();
1993 #ifdef ACCESSIBILITY_EMULATOR_DEFINED
1994     reporter.setResult(ret);
1995 #endif // ACCESSIBILITY_EMULATOR_DEFINED
1996     return ret;
1997 }
1998 
RegisterDisconnectCallback(std::shared_ptr<DisconnectCallback> & callback)1999 RetError AccessibleAbilityClientImpl::RegisterDisconnectCallback(std::shared_ptr<DisconnectCallback> &callback)
2000 {
2001     HILOG_INFO();
2002     if (callback == nullptr) {
2003         HILOG_INFO("callback IS NULLPTR");
2004         return RET_ERR_INVALID_PARAM;
2005     }
2006     std::shared_lock<ffrt::shared_mutex> rLock(rwLock_);
2007     if (channelClient_ == nullptr) {
2008         HILOG_ERROR("the channel is invalid.");
2009         return RET_ERR_NO_CONNECTION;
2010     }
2011     std::unique_lock<ffrt::mutex> lock(callbackListMutex_);
2012     if (callbackList_.empty()) {
2013         callbackList_.push_back(callback);
2014         return channelClient_->SetIsRegisterDisconnectCallback(true);
2015     }
2016     bool exist = false;
2017     for (auto &cb : callbackList_) {
2018         if (*cb == *callback) {
2019             exist = true;
2020         }
2021     }
2022     if (!exist) {
2023         callbackList_.push_back(callback);
2024     }
2025     return RET_OK;
2026 }
2027 
UnRegisterDisconnectCallback(std::shared_ptr<DisconnectCallback> & callback)2028 RetError AccessibleAbilityClientImpl::UnRegisterDisconnectCallback(std::shared_ptr<DisconnectCallback> &callback)
2029 {
2030     HILOG_INFO();
2031     std::shared_lock<ffrt::shared_mutex> rLock(rwLock_);
2032     if (channelClient_ == nullptr) {
2033         HILOG_ERROR("the channel is invalid.");
2034         return RET_ERR_NO_CONNECTION;
2035     }
2036     std::unique_lock<ffrt::mutex> lock(callbackListMutex_);
2037     if (callback->handlerRef_ == nullptr) {
2038         callbackList_.clear();
2039     } else {
2040         for (auto it = callbackList_.begin(); it != callbackList_.end();) {
2041             if (**it == *callback) {
2042                 HILOG_INFO("UnRegister exist callback");
2043                 it = callbackList_.erase(it);
2044             } else {
2045                 ++it;
2046             }
2047         }
2048     }
2049     if (callbackList_.empty()) {
2050         return channelClient_->SetIsRegisterDisconnectCallback(false);
2051     }
2052     return RET_OK;
2053 }
2054 
NotifyDisconnect()2055 RetError AccessibleAbilityClientImpl::NotifyDisconnect()
2056 {
2057     HILOG_INFO();
2058     std::unique_lock<ffrt::mutex> lock(callbackListMutex_);
2059     if (callbackList_.empty()) {
2060         HILOG_INFO("callbackList_ is empty");
2061         return RET_OK;
2062     }
2063     if (!isDisconnectCallbackExecute_) {
2064         HILOG_INFO("callback has not executed");
2065         return RET_OK;
2066     }
2067 
2068     std::shared_lock<ffrt::shared_mutex> rLock(rwLock_);
2069     // NotifyDisconnect and Delete death recipient
2070     if (channelClient_ && channelClient_->GetRemote()) {
2071         channelClient_->NotifyDisconnect();
2072         HILOG_ERROR("Remove death recipient");
2073         channelClient_->GetRemote()->RemoveDeathRecipient(deathRecipient_);
2074     }
2075 
2076     // Remove channel
2077     channelClient_ = nullptr;
2078 
2079     return RET_OK;
2080 }
2081 
ConfigureEvents(const std::vector<uint32_t> needEvents)2082 RetError AccessibleAbilityClientImpl::ConfigureEvents(const std::vector<uint32_t> needEvents)
2083 {
2084     HILOG_DEBUG();
2085     if (!isConnected_) {
2086         HILOG_ERROR("connection is broken");
2087         return RET_ERR_NO_CONNECTION;
2088     }
2089 
2090     std::shared_lock<ffrt::shared_mutex> rLock(rwLock_);
2091     if (CheckServiceProxy() == false) {
2092         HILOG_ERROR("failed to connect to aams.");
2093         return RET_ERR_SAMGR;
2094     }
2095 
2096     if (!channelClient_) {
2097         HILOG_ERROR("channel is invalid.");
2098         return RET_ERR_NO_CONNECTION;
2099     }
2100 
2101     RetError ret = channelClient_->ConfigureEvents(needEvents);
2102     if (ret != RET_OK) {
2103         HILOG_ERROR("config need events failed");
2104         return ret;
2105     }
2106     return RET_OK;
2107 }
2108 
SearchElementInfoRecursiveBySpecificProperty(const int32_t windowId,const int64_t elementId,std::vector<AccessibilityElementInfo> & elementInfos,int32_t treeId,uint64_t parentIndex,const SpecificPropertyParam & param)2109 RetError AccessibleAbilityClientImpl::SearchElementInfoRecursiveBySpecificProperty(const int32_t windowId,
2110     const int64_t elementId, std::vector<AccessibilityElementInfo> &elementInfos,
2111     int32_t treeId, uint64_t parentIndex, const SpecificPropertyParam& param)
2112 {
2113     HILOG_INFO("windowId %{public}d}, elementId %{public}" PRId64 ", treeId %{public}d", windowId, elementId, treeId);
2114     if (windowId <= 0) {
2115         HILOG_ERROR("window Id is failed windowId %{public}d}", windowId);
2116         return RET_ERR_INVALID_ELEMENT_INFO_FROM_ACE;
2117     }
2118     std::vector<AccessibilityElementInfo> vecElementInfos {};
2119     if (!channelClient_) {
2120         HILOG_ERROR("The channel is invalid.");
2121         return RET_ERR_NO_CONNECTION;
2122     }
2123     std::vector<AccessibilityElementInfo> infos;
2124     RetError ret = channelClient_->SearchElementInfosBySpecificProperty(windowId, elementId, param, infos,
2125         vecElementInfos, treeId);
2126     if (ret != RET_OK) {
2127         HILOG_ERROR("search element info failed. windowId %{public}d}", windowId);
2128         return ret;
2129     }
2130     if (!infos.empty()) {
2131         HILOG_INFO("search element info find front");
2132         elementInfos.push_back(infos.front());
2133         return RET_OK;
2134     }
2135     for (auto& treeParentInfo : vecElementInfos) {
2136         std::vector<AccessibilityElementInfo> newInfos {};
2137         HILOG_INFO("search element info success. windowId %{public}d}",
2138             treeParentInfo.GetChildWindowId());
2139         if (treeParentInfo.GetChildTreeId() > 0) {
2140             ret = SearchElementInfoRecursiveBySpecificProperty(treeParentInfo.GetChildWindowId(),
2141                 ROOT_NONE_ID, newInfos, treeParentInfo.GetChildTreeId(), 0, param);
2142             HILOG_INFO("ChildWindowId %{public}d}. ret:%{public}d, GetChildTreeId %{public}d",
2143                 treeParentInfo.GetChildWindowId(), ret, treeParentInfo.GetChildTreeId());
2144             if (!newInfos.empty()) {
2145                 HILOG_INFO("search element info find: find front");
2146                 elementInfos.push_back(newInfos.front());
2147                 return RET_OK;
2148             }
2149         }
2150     }
2151     return RET_ERR_FAILED;
2152 }
2153 } // namespace Accessibility
2154 } // namespace OHOS