• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2022-2025 Huawei Device Co., Ltd.
3  * Licensed under the Apache License, Version 2.0 (the "License");
4  * you may not use this file except in compliance with the License.
5  * You may obtain a copy of the License at
6  *
7  *     http://www.apache.org/licenses/LICENSE-2.0
8  *
9  * Unless required by applicable law or agreed to in writing, software
10  * distributed under the License is distributed on an "AS IS" BASIS,
11  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12  * See the License for the specific language governing permissions and
13  * limitations under the License.
14  */
15 
16 #include <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