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