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