1 /*
2 * Copyright (C) 2022-2025 Huawei Device Co., Ltd.
3 * Licensed under the Apache License, Version 2.0 (the "License");
4 * you may not use this file except in compliance with the License.
5 * You may obtain a copy of the License at
6 *
7 * http://www.apache.org/licenses/LICENSE-2.0
8 *
9 * Unless required by applicable law or agreed to in writing, software
10 * distributed under the License is distributed on an "AS IS" BASIS,
11 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 * See the License for the specific language governing permissions and
13 * limitations under the License.
14 */
15
16 #include <cinttypes>
17 #include "accessibility_system_ability_client_impl.h"
18 #include "hilog_wrapper.h"
19 #include "if_system_ability_manager.h"
20 #include "iservice_registry.h"
21 #include "parameter.h"
22 #include "system_ability_definition.h"
23 #include "api_reporter_helper.h"
24
25 namespace OHOS {
26 namespace Accessibility {
27 namespace {
28 constexpr int32_t CONFIG_PARAMETER_VALUE_SIZE = 10;
29 const std::string SYSTEM_PARAMETER_AAMS_NAME = "accessibility.config.ready";
30 constexpr int32_t SA_CONNECT_TIMEOUT = 500; // ms
31 constexpr int32_t ABILITY_SIZE_MAX = 10000;
32 } // namespaces
33
34 static ffrt::mutex g_Mutex;
35 static std::shared_ptr<AccessibilitySystemAbilityClientImpl> g_Instance = nullptr;
GetInstance()36 std::shared_ptr<AccessibilitySystemAbilityClient> AccessibilitySystemAbilityClient::GetInstance()
37 {
38 HILOG_DEBUG();
39 std::lock_guard<ffrt::mutex> lock(g_Mutex);
40 if (!g_Instance) {
41 g_Instance = std::make_shared<AccessibilitySystemAbilityClientImpl>();
42 } else {
43 HILOG_DEBUG("AccessibilitySystemAbilityClient had construct instance");
44 }
45
46 return g_Instance;
47 }
48
AccessibilitySystemAbilityClientImpl()49 AccessibilitySystemAbilityClientImpl::AccessibilitySystemAbilityClientImpl()
50 {
51 HILOG_DEBUG();
52
53 stateHandler_.Reset();
54 char value[CONFIG_PARAMETER_VALUE_SIZE] = "default";
55 int retSysParam = GetParameter(SYSTEM_PARAMETER_AAMS_NAME.c_str(), "false", value, CONFIG_PARAMETER_VALUE_SIZE);
56 if (retSysParam >= 0 && !std::strcmp(value, "true")) {
57 HILOG_ERROR("accessibility service is ready");
58 if (!ConnectToService()) {
59 HILOG_ERROR("Failed to connect to aams service");
60 return;
61 }
62 Init();
63 }
64
65 retSysParam = WatchParameter(SYSTEM_PARAMETER_AAMS_NAME.c_str(), &OnParameterChanged, this);
66 if (retSysParam) {
67 HILOG_ERROR("Watch parameter failed, error = %{public}d", retSysParam);
68 }
69 }
70
~AccessibilitySystemAbilityClientImpl()71 AccessibilitySystemAbilityClientImpl::~AccessibilitySystemAbilityClientImpl()
72 {
73 HILOG_DEBUG();
74 if (stateObserver_ != nullptr) {
75 stateObserver_->OnClientDeleted();
76 }
77 }
78
ConnectToService()79 bool AccessibilitySystemAbilityClientImpl::ConnectToService()
80 {
81 HILOG_DEBUG();
82
83 if (serviceProxy_) {
84 HILOG_DEBUG("AAMS Service is connected");
85 return true;
86 }
87
88 auto samgr = SystemAbilityManagerClient::GetInstance().GetSystemAbilityManager();
89 if (!samgr) {
90 HILOG_ERROR("Failed to get ISystemAbilityManager");
91 return false;
92 }
93
94 sptr<IRemoteObject> object = samgr->GetSystemAbility(ACCESSIBILITY_MANAGER_SERVICE_ID);
95 if (object == nullptr) {
96 HILOG_ERROR("Get IAccessibleAbilityManagerService object from samgr failed");
97 return false;
98 }
99
100 if (deathRecipient_ == nullptr) {
101 deathRecipient_ = new(std::nothrow) DeathRecipient(*this);
102 if (deathRecipient_ == nullptr) {
103 HILOG_ERROR("Failed to create deathRecipient.");
104 return false;
105 }
106 }
107 if ((object->IsProxyObject()) && (!object->AddDeathRecipient(deathRecipient_))) {
108 HILOG_ERROR("Failed to add death recipient");
109 }
110 HILOG_DEBUG("Get remote object ok");
111 serviceProxy_ = iface_cast<IAccessibleAbilityManagerService>(object);
112 if (serviceProxy_ == nullptr) {
113 HILOG_ERROR("IAccessibleAbilityManagerService iface_cast failed");
114 return false;
115 }
116
117 return true;
118 }
119
OnParameterChanged(const char * key,const char * value,void * context)120 void AccessibilitySystemAbilityClientImpl::OnParameterChanged(const char *key, const char *value, void *context)
121 {
122 HILOG_DEBUG("Parameter key = [%{public}s] value = [%{public}s]", key, value);
123
124 if (!key || std::strcmp(key, SYSTEM_PARAMETER_AAMS_NAME.c_str())) {
125 HILOG_WARN("not accessibility.config.ready callback");
126 return;
127 }
128
129 if (!value || std::strcmp(value, "true")) {
130 HILOG_WARN("accessibility.config.ready value not true");
131 return;
132 }
133
134 if (!context) {
135 HILOG_WARN("accessibility.config.ready context NULL");
136 return;
137 }
138
139 AccessibilitySystemAbilityClientImpl* implPtr = static_cast<AccessibilitySystemAbilityClientImpl*>(context);
140 {
141 HILOG_DEBUG("ConnectToService start.");
142 std::lock_guard<ffrt::mutex> lock(implPtr->mutex_);
143 if (implPtr->serviceProxy_) {
144 HILOG_DEBUG("service is already started.");
145 return;
146 }
147 if (!implPtr->ConnectToService()) {
148 HILOG_ERROR("Failed to connect to aams service");
149 return;
150 }
151 implPtr->Init();
152 }
153 }
154
LoadAccessibilityService()155 bool AccessibilitySystemAbilityClientImpl::LoadAccessibilityService()
156 {
157 std::unique_lock<ffrt::mutex> lock(conVarMutex_);
158 sptr<AccessibilityLoadCallback> loadCallback = new AccessibilityLoadCallback();
159 if (loadCallback == nullptr) {
160 return false;
161 }
162 auto samgr = SystemAbilityManagerClient::GetInstance().GetSystemAbilityManager();
163 if (samgr == nullptr) {
164 return false;
165 }
166 int32_t ret = samgr->LoadSystemAbility(ACCESSIBILITY_MANAGER_SERVICE_ID, loadCallback);
167 if (ret != 0) {
168 return false;
169 }
170 auto waitStatus = proxyConVar_.wait_for(lock, std::chrono::milliseconds(SA_CONNECT_TIMEOUT),
171 [this]() { return serviceProxy_ != nullptr; });
172 if (!waitStatus) {
173 return false;
174 }
175 return true;
176 }
177
LoadSystemAbilitySuccess(const sptr<IRemoteObject> & remoteObject)178 void AccessibilitySystemAbilityClientImpl::LoadSystemAbilitySuccess(const sptr<IRemoteObject> &remoteObject)
179 {
180 std::lock_guard<ffrt::mutex> lock(conVarMutex_);
181 if (serviceProxy_ != nullptr) {
182 HILOG_INFO("serviceProxy_ isn't nullptr");
183 proxyConVar_.notify_one();
184 return;
185 }
186 if (remoteObject != nullptr) {
187 serviceProxy_ = iface_cast<IAccessibleAbilityManagerService>(remoteObject);
188 if (deathRecipient_ == nullptr) {
189 deathRecipient_ = new(std::nothrow) DeathRecipient(*this);
190 if (deathRecipient_ == nullptr) {
191 HILOG_ERROR("create deathRecipient_ fail.");
192 }
193 }
194 if (deathRecipient_ && remoteObject->IsProxyObject() && remoteObject->AddDeathRecipient(deathRecipient_)) {
195 HILOG_INFO("successed to add death recipient");
196 }
197 } else {
198 HILOG_WARN("remoteObject is nullptr.");
199 }
200 proxyConVar_.notify_one();
201 }
202
LoadSystemAbilityFail()203 void AccessibilitySystemAbilityClientImpl::LoadSystemAbilityFail()
204 {
205 std::lock_guard<ffrt::mutex> lock(conVarMutex_);
206 HILOG_WARN("LoadSystemAbilityFail.");
207 proxyConVar_.notify_one();
208 }
209
Init()210 void AccessibilitySystemAbilityClientImpl::Init()
211 {
212 HILOG_DEBUG();
213 stateHandler_.Reset();
214 if (!stateObserver_) {
215 stateObserver_ = new(std::nothrow) AccessibleAbilityManagerStateObserverImpl(*this);
216 if (!stateObserver_) {
217 HILOG_ERROR("Failed to create stateObserver.");
218 return;
219 }
220 }
221 if (serviceProxy_ == nullptr) {
222 return;
223 }
224 uint32_t stateType = 0;
225 serviceProxy_->RegisterStateObserver(stateObserver_, stateType);
226 if (stateType & STATE_ACCESSIBILITY_ENABLED) {
227 stateHandler_.SetState(AccessibilityStateEventType::EVENT_ACCESSIBILITY_STATE_CHANGED, true);
228 }
229 if (stateType & STATE_EXPLORATION_ENABLED) {
230 stateHandler_.SetState(AccessibilityStateEventType::EVENT_TOUCH_GUIDE_STATE_CHANGED, true);
231 }
232 if (stateType & STATE_KEYEVENT_ENABLED) {
233 stateHandler_.SetState(AccessibilityStateEventType::EVENT_KEVEVENT_STATE_CHANGED, true);
234 }
235 if (stateType & STATE_GESTURE_ENABLED) {
236 stateHandler_.SetState(AccessibilityStateEventType::EVENT_GESTURE_STATE_CHANGED, true);
237 }
238 if (stateType & STATE_SCREENREADER_ENABLED) {
239 stateHandler_.SetState(AccessibilityStateEventType::EVENT_SCREEN_READER_STATE_CHANGED, true);
240 }
241 if (stateType & STATE_SINGLE_CLICK_MODE_ENABLED) {
242 stateHandler_.SetState(AccessibilityStateEventType::EVENT_TOUCH_MODE_CHANGED, true);
243 }
244 if (stateType & STATE_CONFIG_EVENT_CHANGE) {
245 stateHandler_.SetState(AccessibilityStateEventType::EVENT_CONFIG_EVENT_CHANGED, true);
246 }
247 }
248
ResetService(const wptr<IRemoteObject> & remote)249 void AccessibilitySystemAbilityClientImpl::ResetService(const wptr<IRemoteObject> &remote)
250 {
251 HILOG_DEBUG();
252 {
253 // there is lock(mutex_) in OnStateChanged, so make sure no deadlock
254 std::lock_guard<ffrt::mutex> lock(mutex_);
255 if (serviceProxy_ != nullptr) {
256 sptr<IRemoteObject> object = serviceProxy_->AsObject();
257 if (object && (remote == object)) {
258 object->RemoveDeathRecipient(deathRecipient_);
259 serviceProxy_ = nullptr;
260 HILOG_INFO("ResetService OK");
261 }
262 }
263 }
264 // notify observer when SA died
265 OnAccessibleAbilityManagerStateChanged(0);
266 stateHandler_.Reset();
267 }
268
RegisterElementOperator(const int32_t windowId,const std::shared_ptr<AccessibilityElementOperator> & operation)269 RetError AccessibilitySystemAbilityClientImpl::RegisterElementOperator(
270 const int32_t windowId, const std::shared_ptr<AccessibilityElementOperator> &operation)
271 {
272 HILOG_INFO("Register windowId[%{public}d] start", windowId);
273 std::lock_guard<ffrt::mutex> lock(mutex_);
274 if (!operation) {
275 HILOG_ERROR("Input operation is null");
276 return RET_ERR_INVALID_PARAM;
277 }
278 if (serviceProxy_ == nullptr) {
279 HILOG_ERROR("Failed to get aams service");
280 return RET_ERR_SAMGR;
281 }
282
283 auto iter = elementOperators_.find(windowId);
284 if (iter != elementOperators_.end()) {
285 HILOG_ERROR("windowID[%{public}d] is exited", windowId);
286 return RET_ERR_CONNECTION_EXIST;
287 }
288
289 sptr<AccessibilityElementOperatorImpl> aamsInteractionOperator =
290 new(std::nothrow) AccessibilityElementOperatorImpl(windowId, operation, *this);
291 if (aamsInteractionOperator == nullptr) {
292 HILOG_ERROR("Failed to create aamsInteractionOperator.");
293 return RET_ERR_NULLPTR;
294 }
295 elementOperators_[windowId] = aamsInteractionOperator;
296 return static_cast<RetError>(serviceProxy_->RegisterElementOperatorByWindowId(windowId, aamsInteractionOperator));
297 }
298
RegisterElementOperator(Registration parameter,const std::shared_ptr<AccessibilityElementOperator> & operation)299 RetError AccessibilitySystemAbilityClientImpl::RegisterElementOperator(Registration parameter,
300 const std::shared_ptr<AccessibilityElementOperator> &operation)
301 {
302 HILOG_DEBUG("parentWindowId:%{public}d, parentTreeId:%{public}d, windowId:%{public}d,nodeId:%{public}" PRId64 "",
303 parameter.parentWindowId, parameter.parentTreeId, parameter.windowId, parameter.elementId);
304
305 std::lock_guard<ffrt::mutex> lock(mutex_);
306 if (parameter.windowId < 0 || parameter.elementId < 0 ||
307 parameter.parentTreeId < 0 || parameter.parentWindowId < 0) {
308 return RET_ERR_INVALID_PARAM;
309 }
310
311 if (!operation) {
312 HILOG_ERROR("Input operation is null");
313 return RET_ERR_INVALID_PARAM;
314 }
315
316 if (serviceProxy_ == nullptr) {
317 HILOG_ERROR("Failed to get aams service");
318 return RET_ERR_SAMGR;
319 }
320
321 sptr<AccessibilityElementOperatorImpl> aamsInteractionOperator =
322 new(std::nothrow) AccessibilityElementOperatorImpl(parameter.windowId, operation, *this);
323 if (aamsInteractionOperator == nullptr) {
324 HILOG_ERROR("Failed to create aamsInteractionOperator.");
325 return RET_ERR_NULLPTR;
326 }
327 elementOperators_[parameter.windowId] = aamsInteractionOperator;
328 RegistrationPara registrationPara {
329 .windowId = parameter.windowId,
330 .parentWindowId = parameter.parentWindowId,
331 .parentTreeId = parameter.parentTreeId,
332 .elementId = parameter.elementId,
333 };
334 return static_cast<RetError>(serviceProxy_->RegisterElementOperatorByParameter(registrationPara,
335 aamsInteractionOperator));
336 }
337
ReregisterElementOperator()338 void AccessibilitySystemAbilityClientImpl::ReregisterElementOperator()
339 {
340 HILOG_DEBUG();
341
342 if (serviceProxy_ == nullptr) {
343 HILOG_ERROR("serviceProxy_ is null.");
344 return;
345 }
346 for (auto iter = elementOperators_.begin(); iter != elementOperators_.end(); iter++) {
347 serviceProxy_->RegisterElementOperatorByWindowId(iter->first, iter->second);
348 }
349 }
350
DeregisterElementOperator(const int32_t windowId)351 RetError AccessibilitySystemAbilityClientImpl::DeregisterElementOperator(const int32_t windowId)
352 {
353 HILOG_INFO("Deregister windowId[%{public}d] start", windowId);
354 std::lock_guard<ffrt::mutex> lock(mutex_);
355
356 if (serviceProxy_ == nullptr) {
357 HILOG_ERROR("Failed to get aams service");
358 return RET_ERR_SAMGR;
359 }
360 auto iter = elementOperators_.find(windowId);
361 if (iter != elementOperators_.end()) {
362 HILOG_DEBUG("windowID[%{public}d] is erase", windowId);
363 elementOperators_.erase(iter);
364 } else {
365 HILOG_WARN("Not find windowID[%{public}d]", windowId);
366 return RET_ERR_NO_REGISTER;
367 }
368 return static_cast<RetError>(serviceProxy_->DeregisterElementOperatorByWindowId(windowId));
369 }
370
DeregisterElementOperator(const int32_t windowId,const int32_t treeId)371 RetError AccessibilitySystemAbilityClientImpl::DeregisterElementOperator(const int32_t windowId, const int32_t treeId)
372 {
373 HILOG_INFO("Deregister windowId[%{public}d] treeId[%{public}d] start", windowId, treeId);
374 std::lock_guard<ffrt::mutex> lock(mutex_);
375
376 if (serviceProxy_ == nullptr) {
377 HILOG_ERROR("Failed to get aams service");
378 return RET_ERR_SAMGR;
379 }
380
381 return static_cast<RetError>(serviceProxy_->DeregisterElementOperatorByWindowIdAndTreeId(windowId, treeId));
382 }
383
IsScreenReaderEnabled(bool & isEnabled)384 RetError AccessibilitySystemAbilityClientImpl::IsScreenReaderEnabled(bool &isEnabled)
385 {
386 HILOG_DEBUG();
387 #ifdef ACCESSIBILITY_EMULATOR_DEFINED
388 ApiReportHelper reporter("AccessibilitySystemAbilityClientImpl.IsScreenReaderEnabled");
389 #endif // ACCESSIBILITY_EMULATOR_DEFINED
390 std::lock_guard<ffrt::mutex> lock(mutex_);
391
392 if (serviceProxy_ == nullptr) {
393 HILOG_ERROR("Failed to get aams service");
394 return RET_ERR_SAMGR;
395 }
396 serviceProxy_->GetScreenReaderState(isEnabled);
397 return RET_OK;
398 }
399
IsEnabled(bool & isEnabled)400 RetError AccessibilitySystemAbilityClientImpl::IsEnabled(bool &isEnabled)
401 {
402 HILOG_DEBUG();
403 std::lock_guard<ffrt::mutex> lock(mutex_);
404 isEnabled = stateHandler_.GetState(AccessibilityStateEventType::EVENT_ACCESSIBILITY_STATE_CHANGED);
405 return RET_OK;
406 }
407
IsTouchExplorationEnabled(bool & isEnabled)408 RetError AccessibilitySystemAbilityClientImpl::IsTouchExplorationEnabled(bool &isEnabled)
409 {
410 HILOG_DEBUG();
411 std::lock_guard<ffrt::mutex> lock(mutex_);
412 isEnabled = stateHandler_.GetState(AccessibilityStateEventType::EVENT_TOUCH_GUIDE_STATE_CHANGED);
413 return RET_OK;
414 }
415
GetTouchMode(std::string & touchMode)416 void AccessibilitySystemAbilityClientImpl::GetTouchMode(std::string &touchMode)
417 {
418 HILOG_DEBUG();
419 std::lock_guard<ffrt::mutex> lock(mutex_);
420 bool isTouchExploration = stateHandler_.GetState(AccessibilityStateEventType::EVENT_TOUCH_GUIDE_STATE_CHANGED);
421 if (!isTouchExploration) {
422 touchMode = "none";
423 return;
424 }
425
426 bool isSingleClickMode = stateHandler_.GetState(AccessibilityStateEventType::EVENT_TOUCH_MODE_CHANGED);
427 if (isSingleClickMode) {
428 touchMode = "singleTouchMode";
429 } else {
430 touchMode = "doubleTouchMode";
431 }
432 }
433
GetAbilityList(const uint32_t accessibilityAbilityTypes,const AbilityStateType stateType,std::vector<AccessibilityAbilityInfo> & infos)434 RetError AccessibilitySystemAbilityClientImpl::GetAbilityList(const uint32_t accessibilityAbilityTypes,
435 const AbilityStateType stateType, std::vector<AccessibilityAbilityInfo> &infos)
436 {
437 HILOG_DEBUG();
438 std::lock_guard<ffrt::mutex> lock(mutex_);
439 bool check = false;
440 if ((accessibilityAbilityTypes & AccessibilityAbilityTypes::ACCESSIBILITY_ABILITY_TYPE_SPOKEN) ||
441 (accessibilityAbilityTypes & AccessibilityAbilityTypes::ACCESSIBILITY_ABILITY_TYPE_HAPTIC) ||
442 (accessibilityAbilityTypes & AccessibilityAbilityTypes::ACCESSIBILITY_ABILITY_TYPE_AUDIBLE) ||
443 (accessibilityAbilityTypes & AccessibilityAbilityTypes::ACCESSIBILITY_ABILITY_TYPE_VISUAL) ||
444 (accessibilityAbilityTypes & AccessibilityAbilityTypes::ACCESSIBILITY_ABILITY_TYPE_GENERIC)) {
445 check = true;
446 }
447 if (stateType == ABILITY_STATE_INVALID) {
448 check = false;
449 }
450 if (!check) {
451 HILOG_ERROR("Invalid params: accessibilityAbilityTypes[%{public}d] stateType[%{public}d]",
452 accessibilityAbilityTypes, stateType);
453 return RET_ERR_INVALID_PARAM;
454 }
455 if (serviceProxy_ == nullptr) {
456 HILOG_ERROR("Failed to get aams service");
457 return RET_ERR_SAMGR;
458 }
459 std::vector<AccessibilityAbilityInfoParcel> infosParcel = {};
460 RetError ret = static_cast<RetError>(serviceProxy_->GetAbilityList(accessibilityAbilityTypes, stateType,
461 infosParcel));
462 if (infosParcel.size() < 0 || infosParcel.size() > ABILITY_SIZE_MAX) {
463 HILOG_ERROR("abilityInfoSize is invalid");
464 return RET_ERR_INVALID_PARAM;
465 }
466 for (auto& infoParcel : infosParcel) {
467 infos.push_back(infoParcel);
468 }
469 return ret;
470 }
471
CheckEventType(EventType eventType)472 bool AccessibilitySystemAbilityClientImpl::CheckEventType(EventType eventType)
473 {
474 #ifdef ACCESSIBILITY_EMULATOR_DEFINED
475 ApiReportHelper reporter("AccessibilitySystemAbilityClientImpl.CheckEventType");
476 #endif // ACCESSIBILITY_EMULATOR_DEFINED
477 if ((eventType < EventType::TYPE_VIEW_CLICKED_EVENT) ||
478 ((eventType >= EventType::TYPE_MAX_NUM) && (eventType != EventType::TYPES_ALL_MASK))) {
479 HILOG_ERROR("event type is invalid");
480 return false;
481 } else {
482 return true;
483 }
484 }
485
SendEvent(const EventType eventType,const int64_t componentId)486 RetError AccessibilitySystemAbilityClientImpl::SendEvent(const EventType eventType, const int64_t componentId)
487 {
488 HILOG_DEBUG("componentId[%{public}" PRId64 "], eventType[%{public}d]", componentId, eventType);
489 std::lock_guard<ffrt::mutex> lock(mutex_);
490 if (!CheckEventType(eventType)) {
491 return RET_ERR_INVALID_PARAM;
492 }
493 AccessibilityEventInfo event;
494 event.SetEventType(eventType);
495 event.SetSource(componentId);
496 if (serviceProxy_ == nullptr) {
497 HILOG_ERROR("Failed to get aams service");
498 return RET_ERR_SAMGR;
499 }
500 AccessibilityEventInfoParcel eventInfoParcel(event);
501 return static_cast<RetError>(serviceProxy_->SendEvent(eventInfoParcel, 1));
502 }
503
SendEvent(const AccessibilityEventInfo & event)504 RetError AccessibilitySystemAbilityClientImpl::SendEvent(const AccessibilityEventInfo &event)
505 {
506 HILOG_DEBUG("EventType[%{public}d]", event.GetEventType());
507 std::lock_guard<ffrt::mutex> lock(mutex_);
508 if (!CheckEventType(event.GetEventType())) {
509 return RET_ERR_INVALID_PARAM;
510 }
511 if (serviceProxy_ == nullptr) {
512 HILOG_ERROR("Failed to get aams service");
513 return RET_ERR_SAMGR;
514 }
515 AccessibilityEventInfoParcel eventInfoParcel(event);
516 return static_cast<RetError>(serviceProxy_->SendEvent(eventInfoParcel, 1));
517 }
518
SubscribeStateObserver(const std::shared_ptr<AccessibilityStateObserver> & observer,const uint32_t eventType)519 RetError AccessibilitySystemAbilityClientImpl::SubscribeStateObserver(
520 const std::shared_ptr<AccessibilityStateObserver> &observer, const uint32_t eventType)
521 {
522 HILOG_DEBUG();
523 std::lock_guard<ffrt::mutex> lock(mutex_);
524 #ifdef ACCESSIBILITY_EMULATOR_DEFINED
525 ApiReportHelper reporter("AccessibilitySystemAbilityClientImpl.SubscribeStateObserver");
526 #endif // ACCESSIBILITY_EMULATOR_DEFINED
527 if (eventType >= AccessibilityStateEventType::EVENT_TYPE_MAX) {
528 HILOG_ERROR("Input eventType is out of scope");
529 return RET_ERR_INVALID_PARAM;
530 }
531 if (!observer) {
532 HILOG_ERROR("Input observer is null");
533 return RET_ERR_INVALID_PARAM;
534 }
535
536 StateObserverVector &observerVector = stateObserversArray_[eventType];
537 for (auto iter = observerVector.begin(); iter != observerVector.end(); ++iter) {
538 if (*iter == observer) {
539 HILOG_INFO("Observer has subscribed!");
540 return RET_ERR_REGISTER_EXIST;
541 }
542 }
543 observerVector.push_back(observer);
544 return RET_OK;
545 }
546
UnsubscribeStateObserver(const std::shared_ptr<AccessibilityStateObserver> & observer,const uint32_t eventType)547 RetError AccessibilitySystemAbilityClientImpl::UnsubscribeStateObserver(
548 const std::shared_ptr<AccessibilityStateObserver> &observer, const uint32_t eventType)
549 {
550 HILOG_DEBUG("eventType is [%{public}d]", eventType);
551 std::lock_guard<ffrt::mutex> lock(mutex_);
552 #ifdef ACCESSIBILITY_EMULATOR_DEFINED
553 ApiReportHelper reporter("AccessibilitySystemAbilityClientImpl.UnsubscribeStateObserver");
554 #endif // ACCESSIBILITY_EMULATOR_DEFINED
555 if (eventType >= AccessibilityStateEventType::EVENT_TYPE_MAX) {
556 HILOG_ERROR("Input eventType is out of scope");
557 return RET_ERR_INVALID_PARAM;
558 }
559 if (!observer) {
560 HILOG_ERROR("Input observer is null");
561 return RET_ERR_INVALID_PARAM;
562 }
563
564 StateObserverVector &observerVector = stateObserversArray_[eventType];
565 for (auto iter = observerVector.begin(); iter != observerVector.end(); ++iter) {
566 if (*iter == observer) {
567 observerVector.erase(iter);
568 return RET_OK;
569 }
570 }
571 HILOG_ERROR("The observer has not subscribed.");
572 return RET_ERR_NO_REGISTER;
573 }
574
NotifyStateChanged(uint32_t eventType,bool value)575 void AccessibilitySystemAbilityClientImpl::NotifyStateChanged(uint32_t eventType, bool value)
576 {
577 HILOG_DEBUG("EventType is %{public}d, value is %{public}d", eventType, value);
578 if (eventType >= AccessibilityStateEventType::EVENT_TYPE_MAX) {
579 HILOG_ERROR("EventType is invalid");
580 return;
581 }
582
583 if (eventType != EVENT_CONFIG_EVENT_CHANGED) {
584 if (stateHandler_.GetState(static_cast<AccessibilityStateEventType>(eventType)) == value) {
585 HILOG_DEBUG("State value is not changed");
586 return;
587 }
588 }
589
590 stateHandler_.SetState(static_cast<AccessibilityStateEventType>(eventType), value);
591 StateObserverVector &observers = stateObserversArray_[eventType];
592 for (auto &observer : observers) {
593 if (observer) {
594 observer->OnStateChanged(value);
595 } else {
596 HILOG_ERROR("end stateObserversArray[%{public}d] is null", eventType);
597 }
598 }
599 HILOG_DEBUG("end");
600 }
601
NotifyTouchModeChanged(bool touchExplorationState,bool isSingleTouchMode)602 void AccessibilitySystemAbilityClientImpl::NotifyTouchModeChanged(bool touchExplorationState, bool isSingleTouchMode)
603 {
604 HILOG_DEBUG("touchExplorationState = %{public}d, isSingleTouchMode = %{public}d", touchExplorationState,
605 isSingleTouchMode);
606
607 bool originalTouchMode = stateHandler_.GetState(EVENT_TOUCH_MODE_CHANGED);
608 stateHandler_.SetState(EVENT_TOUCH_MODE_CHANGED, isSingleTouchMode);
609
610 if (!touchExplorationState) {
611 HILOG_DEBUG("touch guide state is false");
612 return;
613 }
614
615 if ((originalTouchMode == isSingleTouchMode) &&
616 (stateHandler_.GetState(EVENT_TOUCH_GUIDE_STATE_CHANGED) == touchExplorationState)) {
617 HILOG_DEBUG("touch mode is not changed");
618 return;
619 }
620
621 StateObserverVector &observers = stateObserversArray_[EVENT_TOUCH_MODE_CHANGED];
622 for (auto &observer : observers) {
623 if (observer) {
624 observer->OnStateChanged(isSingleTouchMode);
625 } else {
626 HILOG_ERROR("touch mode observer is null!");
627 }
628 }
629 }
630
GetEnabledAbilities(std::vector<std::string> & enabledAbilities)631 RetError AccessibilitySystemAbilityClientImpl::GetEnabledAbilities(std::vector<std::string> &enabledAbilities)
632 {
633 HILOG_DEBUG();
634 std::lock_guard<ffrt::mutex> lock(mutex_);
635 if (serviceProxy_ == nullptr) {
636 HILOG_ERROR("Failed to get aams service");
637 return RET_ERR_SAMGR;
638 }
639 RetError ret = static_cast<RetError>(serviceProxy_->GetEnabledAbilities(enabledAbilities));
640 if (enabledAbilities.size() < 0 || enabledAbilities.size() > ABILITY_SIZE_MAX) {
641 HILOG_ERROR("dev_num is invalid");
642 return RET_ERR_INVALID_PARAM;
643 }
644 return ret;
645 }
646
OnAccessibleAbilityManagerStateChanged(const uint32_t stateType)647 void AccessibilitySystemAbilityClientImpl::OnAccessibleAbilityManagerStateChanged(const uint32_t stateType)
648 {
649 HILOG_DEBUG("stateType[%{public}d}", stateType);
650 SetAccessibilityState(stateType);
651 std::lock_guard<ffrt::mutex> lock(mutex_);
652 // the notification of the single click mode must be earlier than the notification of the touch exploration state;
653 NotifyTouchModeChanged(!!(stateType & STATE_EXPLORATION_ENABLED), !!(stateType & STATE_SINGLE_CLICK_MODE_ENABLED));
654
655 NotifyStateChanged(AccessibilityStateEventType::EVENT_ACCESSIBILITY_STATE_CHANGED,
656 !!(stateType & STATE_ACCESSIBILITY_ENABLED));
657
658 NotifyStateChanged(AccessibilityStateEventType::EVENT_TOUCH_GUIDE_STATE_CHANGED,
659 !!(stateType & STATE_EXPLORATION_ENABLED));
660
661 NotifyStateChanged(AccessibilityStateEventType::EVENT_KEVEVENT_STATE_CHANGED,
662 !!(stateType & STATE_KEYEVENT_ENABLED));
663
664 NotifyStateChanged(AccessibilityStateEventType::EVENT_GESTURE_STATE_CHANGED,
665 !!(stateType & STATE_GESTURE_ENABLED));
666
667 NotifyStateChanged(AccessibilityStateEventType::EVENT_SCREEN_READER_STATE_CHANGED,
668 !!(stateType & STATE_SCREENREADER_ENABLED));
669
670 NotifyStateChanged(AccessibilityStateEventType::EVENT_CONFIG_EVENT_CHANGED,
671 !!(stateType & STATE_CONFIG_EVENT_CHANGE));
672 }
673
SetSearchElementInfoByAccessibilityIdResult(const std::list<AccessibilityElementInfo> & infos,const int32_t requestId)674 void AccessibilitySystemAbilityClientImpl::SetSearchElementInfoByAccessibilityIdResult(
675 const std::list<AccessibilityElementInfo> &infos, const int32_t requestId)
676 {
677 std::lock_guard<ffrt::mutex> lock(mutex_);
678 HILOG_DEBUG("search element requestId[%{public}d]", requestId);
679 if (serviceProxy_ == nullptr) {
680 HILOG_ERROR("serviceProxy_ is nullptr");
681 return;
682 }
683 std::vector<AccessibilityElementInfo> filterInfos(infos.begin(), infos.end());
684 sptr<IAccessibilityElementOperatorCallback> callback =
685 AccessibilityElementOperatorImpl::GetCallbackByRequestId(requestId);
686 if (requestId < 0) {
687 HILOG_ERROR("requestId is invalid");
688 return;
689 }
690 if (callback != nullptr) {
691 if (callback->GetFilter()) {
692 AccessibilityElementOperatorImpl::SetFiltering(filterInfos);
693 }
694 serviceProxy_->RemoveRequestId(requestId);
695 callback->SetSearchElementInfoByAccessibilityIdResult(filterInfos, requestId);
696 AccessibilityElementOperatorImpl::EraseCallback(requestId);
697 } else {
698 HILOG_INFO("callback is nullptr");
699 }
700 }
701
SetSearchDefaultFocusByWindowIdResult(const std::list<AccessibilityElementInfo> & infos,const int32_t requestId)702 void AccessibilitySystemAbilityClientImpl::SetSearchDefaultFocusByWindowIdResult(
703 const std::list<AccessibilityElementInfo> &infos, const int32_t requestId)
704 {
705 std::lock_guard<ffrt::mutex> lock(mutex_);
706 HILOG_DEBUG("search element requestId[%{public}d]", requestId);
707 if (serviceProxy_ == nullptr) {
708 HILOG_ERROR("serviceProxy_ is nullptr");
709 return;
710 }
711 std::vector<AccessibilityElementInfo> filterInfos(infos.begin(), infos.end());
712 sptr<IAccessibilityElementOperatorCallback> callback =
713 AccessibilityElementOperatorImpl::GetCallbackByRequestId(requestId);
714 if (requestId < 0) {
715 HILOG_ERROR("requestId is invalid");
716 return;
717 }
718 if (callback != nullptr) {
719 if (callback->GetFilter()) {
720 AccessibilityElementOperatorImpl::SetFiltering(filterInfos);
721 }
722 serviceProxy_->RemoveRequestId(requestId);
723 callback->SetSearchDefaultFocusByWindowIdResult(filterInfos, requestId);
724 AccessibilityElementOperatorImpl::EraseCallback(requestId);
725 } else {
726 HILOG_ERROR("callback is nullptr");
727 }
728 }
729
SetSearchElementInfoByTextResult(const std::list<AccessibilityElementInfo> & infos,const int32_t requestId)730 void AccessibilitySystemAbilityClientImpl::SetSearchElementInfoByTextResult(
731 const std::list<AccessibilityElementInfo> &infos, const int32_t requestId)
732 {
733 std::lock_guard<ffrt::mutex> lock(mutex_);
734 HILOG_DEBUG("requestId[%{public}d]", requestId);
735 if (serviceProxy_ == nullptr) {
736 HILOG_ERROR("serviceProxy_ is nullptr");
737 return;
738 }
739 std::vector<AccessibilityElementInfo> filterInfos(infos.begin(), infos.end());
740 sptr<IAccessibilityElementOperatorCallback> callback =
741 AccessibilityElementOperatorImpl::GetCallbackByRequestId(requestId);
742 if (requestId >= 0) {
743 if (callback != nullptr) {
744 serviceProxy_->RemoveRequestId(requestId);
745 callback->SetSearchElementInfoByTextResult(filterInfos, requestId);
746 AccessibilityElementOperatorImpl::EraseCallback(requestId);
747 } else {
748 HILOG_INFO("callback is nullptr");
749 }
750 }
751 }
752
SetFindFocusedElementInfoResult(const AccessibilityElementInfo & info,const int32_t requestId)753 void AccessibilitySystemAbilityClientImpl::SetFindFocusedElementInfoResult(
754 const AccessibilityElementInfo &info, const int32_t requestId)
755 {
756 std::lock_guard<ffrt::mutex> lock(mutex_);
757 HILOG_DEBUG("requestId[%{public}d]", requestId);
758 if (serviceProxy_ == nullptr) {
759 HILOG_ERROR("serviceProxy_ is nullptr");
760 return;
761 }
762 sptr<IAccessibilityElementOperatorCallback> callback =
763 AccessibilityElementOperatorImpl::GetCallbackByRequestId(requestId);
764 if (requestId >= 0) {
765 if (callback != nullptr) {
766 serviceProxy_->RemoveRequestId(requestId);
767 callback->SetFindFocusedElementInfoResult(info, requestId);
768 AccessibilityElementOperatorImpl::EraseCallback(requestId);
769 } else {
770 HILOG_INFO("callback is nullptr");
771 }
772 }
773 }
774
SetFocusMoveSearchResult(const AccessibilityElementInfo & info,const int32_t requestId)775 void AccessibilitySystemAbilityClientImpl::SetFocusMoveSearchResult(
776 const AccessibilityElementInfo &info, const int32_t requestId)
777 {
778 std::lock_guard<ffrt::mutex> lock(mutex_);
779 HILOG_DEBUG("requestId[%{public}d]", requestId);
780 if (serviceProxy_ == nullptr) {
781 HILOG_ERROR("serviceProxy_ is nullptr");
782 return;
783 }
784 sptr<IAccessibilityElementOperatorCallback> callback =
785 AccessibilityElementOperatorImpl::GetCallbackByRequestId(requestId);
786 if (requestId >= 0) {
787 if (callback != nullptr) {
788 serviceProxy_->RemoveRequestId(requestId);
789 callback->SetFocusMoveSearchResult(info, requestId);
790 AccessibilityElementOperatorImpl::EraseCallback(requestId);
791 } else {
792 HILOG_INFO("callback is nullptr");
793 }
794 }
795 }
796
SetExecuteActionResult(const bool succeeded,const int32_t requestId)797 void AccessibilitySystemAbilityClientImpl::SetExecuteActionResult(
798 const bool succeeded, const int32_t requestId)
799 {
800 std::lock_guard<ffrt::mutex> lock(mutex_);
801 HILOG_DEBUG("requestId[%{public}d]", requestId);
802 if (serviceProxy_ == nullptr) {
803 HILOG_ERROR("serviceProxy_ is nullptr");
804 return;
805 }
806 sptr<IAccessibilityElementOperatorCallback> callback =
807 AccessibilityElementOperatorImpl::GetCallbackByRequestId(requestId);
808 if (requestId >= 0) {
809 if (callback != nullptr) {
810 serviceProxy_->RemoveRequestId(requestId);
811 callback->SetExecuteActionResult(succeeded, requestId);
812 AccessibilityElementOperatorImpl::EraseCallback(requestId);
813 } else {
814 HILOG_INFO("callback is nullptr");
815 }
816 }
817 }
818
SetCursorPositionResult(const int32_t cursorPosition,const int32_t requestId)819 void AccessibilitySystemAbilityClientImpl::SetCursorPositionResult(
820 const int32_t cursorPosition, const int32_t requestId)
821 {
822 std::lock_guard<ffrt::mutex> lock(mutex_);
823 HILOG_DEBUG("requestId[%{public}d] cursorPosition[%{public}d]", requestId, cursorPosition);
824 if (serviceProxy_ == nullptr) {
825 HILOG_ERROR("serviceProxy_ is nullptr");
826 return;
827 }
828 sptr<IAccessibilityElementOperatorCallback> callback =
829 AccessibilityElementOperatorImpl::GetCallbackByRequestId(requestId);
830 if (requestId >= 0) {
831 if (callback != nullptr) {
832 serviceProxy_->RemoveRequestId(requestId);
833 callback->SetCursorPositionResult(cursorPosition, requestId);
834 AccessibilityElementOperatorImpl::EraseCallback(requestId);
835 } else {
836 HILOG_INFO("callback is nullptr");
837 }
838 }
839 }
840
SetAccessibilityState(const uint32_t stateType)841 void AccessibilitySystemAbilityClientImpl::SetAccessibilityState(const uint32_t stateType)
842 {
843 HILOG_DEBUG();
844 state_ = stateType;
845 }
846
GetAccessibilityState()847 uint32_t AccessibilitySystemAbilityClientImpl::GetAccessibilityState()
848 {
849 HILOG_DEBUG();
850 return state_;
851 }
852
SetFindAccessibilityNodeInfosResult(const std::list<AccessibilityElementInfo> elementInfos,const int32_t requestId,const int32_t requestCode)853 void AccessibilitySystemAbilityClientImpl::SetFindAccessibilityNodeInfosResult(
854 const std::list<AccessibilityElementInfo> elementInfos, const int32_t requestId, const int32_t requestCode)
855 {
856 HILOG_DEBUG();
857 switch (static_cast<SET_AA_CALLBACK_RESULT>(requestCode)) {
858 case FIND_ACCESSIBILITY_NODE_BY_ACCESSIBILITY_ID:
859 SetSearchElementInfoByAccessibilityIdResult(elementInfos, requestId);
860 break;
861 case FIND_ACCESSIBILITY_NODE_BY_TEXT:
862 SetSearchElementInfoByTextResult(elementInfos, requestId);
863 break;
864 default:
865 break;
866 }
867 }
868
SetFindAccessibilityNodeInfoResult(const AccessibilityElementInfo elementInfo,const int32_t requestId,const int32_t requestCode)869 void AccessibilitySystemAbilityClientImpl::SetFindAccessibilityNodeInfoResult(
870 const AccessibilityElementInfo elementInfo, const int32_t requestId, const int32_t requestCode)
871 {
872 HILOG_DEBUG();
873 switch (static_cast<SET_AA_CALLBACK_RESULT>(requestCode)) {
874 case FIND_ACCESSIBILITY_NODE_BY_ACCESSIBILITY_ID:
875 {
876 std::list<AccessibilityElementInfo> elementInfos = {};
877 elementInfos.push_back(elementInfo);
878 SetSearchElementInfoByAccessibilityIdResult(elementInfos, requestId);
879 }
880 break;
881 case FIND_FOCUS:
882 SetFindFocusedElementInfoResult(elementInfo, requestId);
883 break;
884 case FIND_FOCUS_SEARCH:
885 SetFocusMoveSearchResult(elementInfo, requestId);
886 break;
887 default:
888 break;
889 }
890 }
891
SetPerformActionResult(const bool succeeded,const int32_t requestId)892 void AccessibilitySystemAbilityClientImpl::SetPerformActionResult(const bool succeeded, const int32_t requestId)
893 {
894 HILOG_DEBUG();
895 SetExecuteActionResult(succeeded, requestId);
896 }
897
GetFocusedWindowId(int32_t & focusedWindowId)898 RetError AccessibilitySystemAbilityClientImpl::GetFocusedWindowId(int32_t &focusedWindowId)
899 {
900 HILOG_DEBUG();
901 std::lock_guard<ffrt::mutex> lock(mutex_);
902 if (serviceProxy_ == nullptr) {
903 HILOG_ERROR("Failed to get aams service");
904 return RET_ERR_SAMGR;
905 }
906 return static_cast<RetError>(serviceProxy_->GetFocusedWindowId(focusedWindowId));
907 }
908
OnLoadSystemAbilitySuccess(int32_t systemAbilityId,const sptr<IRemoteObject> & remoteObject)909 void AccessibilitySystemAbilityClientImpl::AccessibilityLoadCallback::OnLoadSystemAbilitySuccess(
910 int32_t systemAbilityId, const sptr<IRemoteObject> &remoteObject)
911 {
912 HILOG_DEBUG();
913 if (g_Instance) {
914 g_Instance->LoadSystemAbilitySuccess(remoteObject);
915 }
916 }
917
OnLoadSystemAbilityFail(int32_t systemAbilityId)918 void AccessibilitySystemAbilityClientImpl::AccessibilityLoadCallback::OnLoadSystemAbilityFail(int32_t systemAbilityId)
919 {
920 HILOG_DEBUG();
921 if (g_Instance) {
922 g_Instance->LoadSystemAbilityFail();
923 }
924 }
925
SearchNeedEvents(std::vector<uint32_t> & needEvents)926 RetError AccessibilitySystemAbilityClientImpl::SearchNeedEvents(std::vector<uint32_t> &needEvents)
927 {
928 HILOG_DEBUG();
929 std::lock_guard<ffrt::mutex> lock(mutex_);
930 if (serviceProxy_ == nullptr) {
931 HILOG_ERROR("Failed to get aams service");
932 return RET_ERR_SAMGR;
933 }
934 return static_cast<RetError>(serviceProxy_->SearchNeedEvents(needEvents));
935 }
936
SetSearchElementInfoBySpecificPropertyResult(const std::list<AccessibilityElementInfo> & infos,const std::list<AccessibilityElementInfo> & treeInfos,const int32_t requestId)937 void AccessibilitySystemAbilityClientImpl::SetSearchElementInfoBySpecificPropertyResult(
938 const std::list<AccessibilityElementInfo> &infos, const std::list<AccessibilityElementInfo> &treeInfos,
939 const int32_t requestId)
940 {
941 std::lock_guard<ffrt::mutex> lock(mutex_);
942 HILOG_DEBUG("search element requestId[%{public}d]", requestId);
943 if (serviceProxy_ == nullptr) {
944 HILOG_ERROR("serviceProxy_ is nullptr");
945 return;
946 }
947 std::vector<AccessibilityElementInfo> filterInfos(infos.begin(), infos.end());
948 sptr<IAccessibilityElementOperatorCallback> callback =
949 AccessibilityElementOperatorImpl::GetCallbackByRequestId(requestId);
950 if (requestId < 0) {
951 HILOG_ERROR("requestId is invalid");
952 return;
953 }
954 if (callback != nullptr) {
955 if (callback->GetFilter()) {
956 AccessibilityElementOperatorImpl::SetFiltering(filterInfos);
957 }
958 serviceProxy_->RemoveRequestId(requestId);
959 callback->SetSearchElementInfoBySpecificPropertyResult(infos, treeInfos, requestId);
960 AccessibilityElementOperatorImpl::EraseCallback(requestId);
961 } else {
962 HILOG_INFO("callback is nullptr");
963 }
964 }
965
StateArrayHandler()966 AccessibilitySystemAbilityClientImpl::StateArrayHandler::StateArrayHandler()
967 {
968 std::unique_lock<ffrt::shared_mutex> wLock(rwLock_);
969 stateArray_.fill(false);
970 }
971
SetState(AccessibilityStateEventType type,bool state)972 void AccessibilitySystemAbilityClientImpl::StateArrayHandler::SetState(AccessibilityStateEventType type, bool state)
973 {
974 std::unique_lock<ffrt::shared_mutex> wLock(rwLock_);
975 stateArray_[type] = state;
976 }
977
GetState(AccessibilityStateEventType type)978 bool AccessibilitySystemAbilityClientImpl::StateArrayHandler::GetState(AccessibilityStateEventType type)
979 {
980 std::shared_lock<ffrt::shared_mutex> rLock(rwLock_);
981 return stateArray_[type];
982 }
983
Reset()984 void AccessibilitySystemAbilityClientImpl::StateArrayHandler::Reset()
985 {
986 std::unique_lock<ffrt::shared_mutex> wLock(rwLock_);
987 stateArray_.fill(false);
988 }
989 } // namespace Accessibility
990 } // namespace OHOS